From ff349f392a4e6817e056ae4402e99c83bf4efa8b Mon Sep 17 00:00:00 2001 From: Kevin van Zonneveld Date: Wed, 26 Nov 2025 20:23:58 +0100 Subject: [PATCH] Sync alphalib 2025 11 26 --- .cursor/rules/coding-style.mdc | 1 + package.json | 1 + src/alphalib/lib/nativeGlobby.ts | 244 ++++++++++++++++++ src/alphalib/mcache.ts | 184 +++++++++++++ .../types/robots/_instructions-primitives.ts | 21 +- .../types/robots/assembly-savejson.ts | 1 + src/alphalib/types/robots/audio-artwork.ts | 1 + src/alphalib/types/robots/audio-concat.ts | 1 + src/alphalib/types/robots/audio-encode.ts | 1 + src/alphalib/types/robots/audio-loop.ts | 1 + src/alphalib/types/robots/audio-merge.ts | 1 + src/alphalib/types/robots/audio-waveform.ts | 1 + src/alphalib/types/robots/azure-import.ts | 1 + src/alphalib/types/robots/azure-store.ts | 1 + src/alphalib/types/robots/backblaze-import.ts | 1 + src/alphalib/types/robots/backblaze-store.ts | 1 + .../types/robots/cloudfiles-import.ts | 1 + src/alphalib/types/robots/cloudfiles-store.ts | 1 + .../types/robots/cloudflare-import.ts | 1 + src/alphalib/types/robots/cloudflare-store.ts | 1 + .../types/robots/digitalocean-import.ts | 1 + .../types/robots/digitalocean-store.ts | 1 + .../types/robots/document-autorotate.ts | 1 + src/alphalib/types/robots/document-convert.ts | 1 + src/alphalib/types/robots/document-merge.ts | 1 + src/alphalib/types/robots/document-ocr.ts | 1 + src/alphalib/types/robots/document-split.ts | 1 + src/alphalib/types/robots/document-thumbs.ts | 1 + src/alphalib/types/robots/dropbox-import.ts | 1 + src/alphalib/types/robots/dropbox-store.ts | 1 + src/alphalib/types/robots/edgly-deliver.ts | 1 + src/alphalib/types/robots/file-compress.ts | 1 + src/alphalib/types/robots/file-decompress.ts | 7 +- src/alphalib/types/robots/file-filter.ts | 1 + src/alphalib/types/robots/file-hash.ts | 1 + src/alphalib/types/robots/file-preview.ts | 1 + src/alphalib/types/robots/file-read.ts | 1 + src/alphalib/types/robots/file-serve.ts | 1 + src/alphalib/types/robots/file-verify.ts | 1 + src/alphalib/types/robots/file-virusscan.ts | 1 + src/alphalib/types/robots/file-watermark.ts | 1 + src/alphalib/types/robots/ftp-import.ts | 1 + src/alphalib/types/robots/ftp-store.ts | 1 + src/alphalib/types/robots/google-import.ts | 1 + src/alphalib/types/robots/google-store.ts | 1 + src/alphalib/types/robots/html-convert.ts | 1 + src/alphalib/types/robots/http-import.ts | 1 + src/alphalib/types/robots/image-bgremove.ts | 1 + src/alphalib/types/robots/image-describe.ts | 1 + src/alphalib/types/robots/image-facedetect.ts | 1 + src/alphalib/types/robots/image-generate.ts | 1 + src/alphalib/types/robots/image-merge.ts | 1 + src/alphalib/types/robots/image-ocr.ts | 1 + src/alphalib/types/robots/image-optimize.ts | 1 + src/alphalib/types/robots/image-resize.ts | 27 ++ src/alphalib/types/robots/meta-read.ts | 1 + src/alphalib/types/robots/meta-write.ts | 1 + src/alphalib/types/robots/minio-import.ts | 1 + src/alphalib/types/robots/minio-store.ts | 1 + .../types/robots/progress-simulate.ts | 1 + src/alphalib/types/robots/s3-import.ts | 1 + src/alphalib/types/robots/s3-store.ts | 1 + src/alphalib/types/robots/script-run.ts | 1 + src/alphalib/types/robots/sftp-import.ts | 1 + src/alphalib/types/robots/sftp-store.ts | 1 + .../types/robots/speech-transcribe.ts | 1 + src/alphalib/types/robots/supabase-import.ts | 1 + src/alphalib/types/robots/supabase-store.ts | 1 + src/alphalib/types/robots/swift-import.ts | 1 + src/alphalib/types/robots/swift-store.ts | 1 + src/alphalib/types/robots/text-speak.ts | 1 + src/alphalib/types/robots/text-translate.ts | 1 + src/alphalib/types/robots/tigris-import.ts | 1 + src/alphalib/types/robots/tigris-store.ts | 1 + src/alphalib/types/robots/tlcdn-deliver.ts | 1 + src/alphalib/types/robots/tus-store.ts | 1 + src/alphalib/types/robots/upload-handle.ts | 1 + src/alphalib/types/robots/video-adaptive.ts | 1 + src/alphalib/types/robots/video-concat.ts | 1 + src/alphalib/types/robots/video-encode.ts | 1 + src/alphalib/types/robots/video-merge.ts | 1 + src/alphalib/types/robots/video-ondemand.ts | 1 + src/alphalib/types/robots/video-subtitle.ts | 1 + src/alphalib/types/robots/video-thumbs.ts | 1 + src/alphalib/types/robots/vimeo-import.ts | 1 + src/alphalib/types/robots/vimeo-store.ts | 1 + src/alphalib/types/robots/wasabi-import.ts | 1 + src/alphalib/types/robots/wasabi-store.ts | 1 + src/alphalib/types/robots/youtube-store.ts | 1 + src/alphalib/types/template.ts | 16 ++ yarn.lock | 8 + 91 files changed, 586 insertions(+), 5 deletions(-) create mode 100644 src/alphalib/lib/nativeGlobby.ts create mode 100644 src/alphalib/mcache.ts diff --git a/.cursor/rules/coding-style.mdc b/.cursor/rules/coding-style.mdc index 0e26fb66..5fc81a22 100644 --- a/.cursor/rules/coding-style.mdc +++ b/.cursor/rules/coding-style.mdc @@ -29,3 +29,4 @@ Coding style: - Use descriptive names: PascalCase for components/types, camelCase for variables/methods/schemas - Alphabetize imports, group by source type (built-in/external/internal) - Favor US English over UK English, so `summarizeError` over `summarise Error` +- Favor `.replaceAll('a', 'b)` over `.replace(/a/g, 'b')` or `.replace(new RegExp('a', 'g'), 'b')` when the only need for regeses was replacing all strings. That's usually both easier to read and more performant. diff --git a/package.json b/package.json index 16aa9c5c..88b4fa42 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "dependencies": { "@aws-sdk/client-s3": "^3.891.0", "@aws-sdk/s3-request-presigner": "^3.891.0", + "@transloadit/sev-logger": "^0.0.15", "debug": "^4.4.3", "form-data": "^4.0.4", "got": "14.4.9", diff --git a/src/alphalib/lib/nativeGlobby.ts b/src/alphalib/lib/nativeGlobby.ts new file mode 100644 index 00000000..61d0dcd3 --- /dev/null +++ b/src/alphalib/lib/nativeGlobby.ts @@ -0,0 +1,244 @@ +import type { GlobOptionsWithoutFileTypes } from 'node:fs' +import * as fs from 'node:fs' +import { glob as fsGlob, stat as statAsync } from 'node:fs/promises' +import path from 'node:path' + +type PatternInput = string | readonly string[] +const { globSync: fsGlobSync } = fs + +export interface NativeGlobbyOptions { + cwd?: string + absolute?: boolean + onlyFiles?: boolean + ignore?: readonly string[] +} + +interface NormalizedOptions { + cwd?: string + absolute: boolean + onlyFiles: boolean + ignore?: readonly string[] +} + +interface Candidate { + rawPath: string + absolutePath: string +} + +const normalizeSlashes = (value: string) => value.replace(/\\/g, '/') + +const toAbsolutePath = (rawPath: string, cwd?: string): string => { + if (path.isAbsolute(rawPath)) { + return rawPath + } + if (cwd) { + return path.join(cwd, rawPath) + } + return path.resolve(rawPath) +} + +const normalizeOptions = (options: NativeGlobbyOptions = {}): NormalizedOptions => ({ + cwd: options.cwd ? path.resolve(options.cwd) : undefined, + absolute: options.absolute ?? false, + onlyFiles: options.onlyFiles ?? true, + ignore: options.ignore && options.ignore.length > 0 ? options.ignore : undefined, +}) + +const hasGlobMagic = (pattern: string) => /[*?[\]{}()!]/.test(pattern) + +const expandPatternAsync = async (pattern: string, options: NormalizedOptions) => { + if (hasGlobMagic(pattern)) { + return [pattern] + } + + try { + const absolute = toAbsolutePath(pattern, options.cwd) + const stats = await statAsync(absolute) + if (stats.isDirectory()) { + const expanded = normalizeSlashes(path.join(pattern, '**/*')) + return [expanded] + } + } catch { + // ignore missing paths; fall back to original pattern + } + + return [pattern] +} + +const expandPatternSync = (pattern: string, options: NormalizedOptions) => { + if (hasGlobMagic(pattern)) { + return [pattern] + } + + try { + const absolute = toAbsolutePath(pattern, options.cwd) + const stats = fs.statSync(absolute) + if (stats.isDirectory()) { + const expanded = normalizeSlashes(path.join(pattern, '**/*')) + return [expanded] + } + } catch { + // ignore missing paths; fall back to original pattern + } + + return [pattern] +} + +const splitPatterns = (patterns: PatternInput) => { + const list = Array.isArray(patterns) ? patterns : [patterns] + const positive: string[] = [] + const negative: string[] = [] + + for (const pattern of list) { + if (pattern.startsWith('!')) { + const negated = pattern.slice(1) + if (negated) { + negative.push(negated) + } + } else { + positive.push(pattern) + } + } + + return { positive, negative } +} + +const toGlobOptions = (options: NormalizedOptions): GlobOptionsWithoutFileTypes => { + const globOptions: GlobOptionsWithoutFileTypes = { withFileTypes: false } + if (options.cwd) { + globOptions.cwd = options.cwd + } + if (options.ignore) { + // Node's glob implementation uses `exclude` for ignore patterns + globOptions.exclude = options.ignore + } + return globOptions +} + +const filterFilesAsync = async (candidates: Candidate[], requireFiles: boolean) => { + if (!requireFiles) { + return candidates + } + + const filtered = await Promise.all( + candidates.map(async (candidate) => { + try { + const stats = await statAsync(candidate.absolutePath) + return stats.isFile() ? candidate : null + } catch { + return null + } + }), + ) + + return filtered.filter(Boolean) as Candidate[] +} + +const filterFilesSync = (candidates: Candidate[], requireFiles: boolean) => { + if (!requireFiles) { + return candidates + } + + const filtered: Candidate[] = [] + for (const candidate of candidates) { + try { + const stats = fs.statSync(candidate.absolutePath) + if (stats.isFile()) { + filtered.push(candidate) + } + } catch { + // Ignore files that cannot be stat'ed + } + } + return filtered +} + +const formatResult = (candidate: Candidate, options: NormalizedOptions) => { + const output = options.absolute ? candidate.absolutePath : candidate.rawPath + return normalizeSlashes(output) +} + +const collectMatchesAsync = async (pattern: string, options: NormalizedOptions) => { + const matches: Candidate[] = [] + for await (const match of fsGlob(pattern, toGlobOptions(options))) { + matches.push({ + rawPath: match as string, + absolutePath: toAbsolutePath(match as string, options.cwd), + }) + } + const filtered = await filterFilesAsync(matches, options.onlyFiles) + return filtered.map((candidate) => formatResult(candidate, options)) +} + +const collectMatchesSync = (pattern: string, options: NormalizedOptions) => { + const matches = (fsGlobSync(pattern, toGlobOptions(options)) as string[]).map((match) => ({ + rawPath: match, + absolutePath: toAbsolutePath(match, options.cwd), + })) + const filtered = filterFilesSync(matches, options.onlyFiles) + return filtered.map((candidate) => formatResult(candidate, options)) +} + +type GlobbyLike = { + (patterns: PatternInput, options?: NativeGlobbyOptions): Promise + sync(patterns: PatternInput, options?: NativeGlobbyOptions): string[] +} + +export const nativeGlobby: GlobbyLike = Object.assign( + async (patterns: PatternInput, options?: NativeGlobbyOptions) => { + const normalized = normalizeOptions(options) + const { positive, negative } = splitPatterns(patterns) + const expandedPositives = ( + await Promise.all(positive.map((pattern) => expandPatternAsync(pattern, normalized))) + ).flat() + const expandedNegatives = ( + await Promise.all(negative.map((pattern) => expandPatternAsync(pattern, normalized))) + ).flat() + const results = new Set() + + for (const pattern of expandedPositives) { + const matches = await collectMatchesAsync(pattern, normalized) + for (const match of matches) { + results.add(match) + } + } + + for (const pattern of expandedNegatives) { + const matches = await collectMatchesAsync(pattern, normalized) + for (const match of matches) { + results.delete(match) + } + } + + return Array.from(results) + }, + { + sync(patterns: PatternInput, options?: NativeGlobbyOptions) { + const normalized = normalizeOptions(options) + const { positive, negative } = splitPatterns(patterns) + const expandedPositives = positive.flatMap((pattern) => + expandPatternSync(pattern, normalized), + ) + const expandedNegatives = negative.flatMap((pattern) => + expandPatternSync(pattern, normalized), + ) + const results = new Set() + + for (const pattern of expandedPositives) { + const matches = collectMatchesSync(pattern, normalized) + for (const match of matches) { + results.add(match) + } + } + + for (const pattern of expandedNegatives) { + const matches = collectMatchesSync(pattern, normalized) + for (const match of matches) { + results.delete(match) + } + } + + return Array.from(results) + }, + }, +) diff --git a/src/alphalib/mcache.ts b/src/alphalib/mcache.ts new file mode 100644 index 00000000..0bd0c45b --- /dev/null +++ b/src/alphalib/mcache.ts @@ -0,0 +1,184 @@ +import type { SevLogger } from '@transloadit/sev-logger' +import type { Schema } from 'zod' + +export interface McacheOpts { + ttlMs?: number + zodSchema?: Schema + logger?: SevLogger + /** + * Maximum number of entries in the cache. When exceeded, oldest entries are removed. + * Defaults to 10,000 entries. + */ + maxSize?: number + /** + * Custom key generator function. If not provided, uses JSON.stringify. + */ + keyFn?: (...args: unknown[]) => string +} + +interface CacheEntry { + value: T + timestamp: number +} + +/** + * Memory cache abstraction to help cache function results in-process. + * + * Example: + * + * const cache = new Mcache({ ttlMs: 1000 * 60 * 10 }) + * + * async function fetchInstances(region: string): Promise { + * return cache.get(region, async () => { + * // Do work, e.g. fetch instances from AWS + * return await this._fetchInstances(region) + * }) + * } + */ +export class Mcache { + #cache: Map> + #opts: Required, 'logger' | 'zodSchema' | 'keyFn'>> & + Pick, 'logger' | 'zodSchema' | 'keyFn'> + + constructor(opts: McacheOpts = {}) { + this.#cache = new Map() + this.#opts = { + ttlMs: opts.ttlMs ?? Number.POSITIVE_INFINITY, + maxSize: opts.maxSize ?? 10_000, + zodSchema: opts.zodSchema, + logger: opts.logger, + keyFn: opts.keyFn, + } + } + + /** + * Get a value from cache, or compute it using the provided function. + * The cache key is generated from the args using JSON.stringify by default, + * or using the custom keyFn if provided. + */ + async get(producer: () => Promise | T, ...args: unknown[]): Promise { + const key = this.#opts.keyFn ? this.#opts.keyFn(...args) : JSON.stringify(args) + const cached = this.#cache.get(key) + + if (cached) { + const age = Date.now() - cached.timestamp + if (age <= this.#opts.ttlMs || this.#opts.ttlMs === Number.POSITIVE_INFINITY) { + this.#opts.logger?.debug(`Cache hit for key ${key} (age: ${age}ms)`) + return cached.value + } + + this.#opts.logger?.debug( + `Cache expired for key ${key} (age: ${age}ms > ${this.#opts.ttlMs}ms)`, + ) + this.#cache.delete(key) + } + + this.#opts.logger?.debug(`Cache miss for key ${key}, computing value`) + const value = await producer() + + // Validate if schema provided + if (this.#opts.zodSchema) { + this.#opts.zodSchema.parse(value) + } + + this.#set(key, value) + return value + } + + /** + * Set a value in the cache directly. + */ + set(value: T, ...args: unknown[]): void { + const key = this.#opts.keyFn ? this.#opts.keyFn(...args) : JSON.stringify(args) + + // Validate if schema provided + if (this.#opts.zodSchema) { + this.#opts.zodSchema.parse(value) + } + + this.#set(key, value) + } + + /** + * Check if a key exists in cache and is not expired. + */ + has(...args: unknown[]): boolean { + const key = this.#opts.keyFn ? this.#opts.keyFn(...args) : JSON.stringify(args) + const cached = this.#cache.get(key) + + if (!cached) { + return false + } + + const age = Date.now() - cached.timestamp + if (age > this.#opts.ttlMs && this.#opts.ttlMs !== Number.POSITIVE_INFINITY) { + this.#cache.delete(key) + return false + } + + return true + } + + /** + * Clear all entries from the cache. + */ + clear(): void { + this.#cache.clear() + } + + /** + * Delete a specific entry from the cache. + */ + delete(...args: unknown[]): boolean { + const key = this.#opts.keyFn ? this.#opts.keyFn(...args) : JSON.stringify(args) + return this.#cache.delete(key) + } + + /** + * Get the current size of the cache. + */ + get size(): number { + return this.#cache.size + } + + /** + * Clean up expired entries and enforce size limit. + */ + cleanup(): void { + const now = Date.now() + + // Remove expired entries + if (this.#opts.ttlMs !== Number.POSITIVE_INFINITY) { + for (const [key, entry] of this.#cache.entries()) { + if (now - entry.timestamp > this.#opts.ttlMs) { + this.#cache.delete(key) + } + } + } + + // Enforce size limit by removing oldest entries + if (this.#cache.size > this.#opts.maxSize) { + const entries = Array.from(this.#cache.entries()) + entries.sort((a, b) => a[1].timestamp - b[1].timestamp) + const toRemove = entries.slice(0, this.#cache.size - this.#opts.maxSize) + for (const [key] of toRemove) { + this.#cache.delete(key) + } + this.#opts.logger?.debug( + `Cache size limit reached, removed ${toRemove.length} oldest entries`, + ) + } + } + + #set(key: string, value: T): void { + this.#cache.set(key, { + value, + timestamp: Date.now(), + }) + + // Trigger cleanup if we're over size limit + if (this.#cache.size > this.#opts.maxSize) { + this.cleanup() + } + } +} diff --git a/src/alphalib/types/robots/_instructions-primitives.ts b/src/alphalib/types/robots/_instructions-primitives.ts index 9231eb84..166738e9 100644 --- a/src/alphalib/types/robots/_instructions-primitives.ts +++ b/src/alphalib/types/robots/_instructions-primitives.ts @@ -118,6 +118,7 @@ export const robotMetaSchema = z.object({ trackOutputFileSize: z.boolean().optional(), isInternal: z.boolean(), numDaemons: z.number().optional(), + stage: z.enum(['alpha', 'beta', 'ga', 'deprecated', 'removed']), importRanges: z.array(z.string()).optional(), extraChargeForImageResize: z.number().optional(), @@ -473,6 +474,20 @@ example, will happily ignore input images. With the \`force_accept\` parameter set to \`true\`, you can force Robots to accept all files thrown at them. This will typically lead to errors and should only be used for debugging or combatting edge cases. +`), + + ignore_errors: z + .union([z.boolean(), z.array(z.enum(['meta', 'execute']))]) + .transform((value) => (value === true ? ['meta', 'execute'] : value === false ? [] : value)) + .default([]) + .describe(` +Ignore errors during specific phases of processing. + +Setting this to \`["meta"]\` will cause the Robot to ignore errors during metadata extraction. + +Setting this to \`["execute"]\` will cause the Robot to ignore errors during the main execution phase. + +Setting this to \`true\` is equivalent to \`["meta", "execute"]\` and will ignore errors in both phases. `), }) .strict() @@ -1190,8 +1205,10 @@ export const robotImport = z 'Custom name for the imported file(s). By default file names are derived from the source.', ), ignore_errors: z - .union([z.boolean(), z.array(z.enum(['meta', 'import']))]) - .transform((value) => (value === true ? ['meta', 'import'] : value === false ? [] : value)) + .union([z.boolean(), z.array(z.enum(['meta', 'import', 'execute']))]) + .transform((value) => + value === true ? ['meta', 'import', 'execute'] : value === false ? [] : value, + ) .default([]), }) .strict() diff --git a/src/alphalib/types/robots/assembly-savejson.ts b/src/alphalib/types/robots/assembly-savejson.ts index 59c9038b..99428241 100644 --- a/src/alphalib/types/robots/assembly-savejson.ts +++ b/src/alphalib/types/robots/assembly-savejson.ts @@ -10,6 +10,7 @@ export const meta: RobotMetaInput = { isAllowedForUrlTransform: true, trackOutputFileSize: false, isInternal: true, + stage: 'ga', removeJobResultFilesFromDiskRightAfterStoringOnS3: false, } diff --git a/src/alphalib/types/robots/audio-artwork.ts b/src/alphalib/types/robots/audio-artwork.ts index f5579e72..e57096f5 100644 --- a/src/alphalib/types/robots/audio-artwork.ts +++ b/src/alphalib/types/robots/audio-artwork.ts @@ -45,6 +45,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotAudioArtworkInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/audio-concat.ts b/src/alphalib/types/robots/audio-concat.ts index 7512573f..2d223372 100644 --- a/src/alphalib/types/robots/audio-concat.ts +++ b/src/alphalib/types/robots/audio-concat.ts @@ -66,6 +66,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotAudioConcatInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/audio-encode.ts b/src/alphalib/types/robots/audio-encode.ts index a037daa2..2476cee8 100644 --- a/src/alphalib/types/robots/audio-encode.ts +++ b/src/alphalib/types/robots/audio-encode.ts @@ -48,6 +48,7 @@ export const meta: RobotMetaInput = { isAllowedForUrlTransform: false, trackOutputFileSize: true, isInternal: false, + stage: 'ga', removeJobResultFilesFromDiskRightAfterStoringOnS3: false, } diff --git a/src/alphalib/types/robots/audio-loop.ts b/src/alphalib/types/robots/audio-loop.ts index c429a880..d0f4b872 100644 --- a/src/alphalib/types/robots/audio-loop.ts +++ b/src/alphalib/types/robots/audio-loop.ts @@ -49,6 +49,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotAudioLoopInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/audio-merge.ts b/src/alphalib/types/robots/audio-merge.ts index 6be7fd86..e1059540 100644 --- a/src/alphalib/types/robots/audio-merge.ts +++ b/src/alphalib/types/robots/audio-merge.ts @@ -67,6 +67,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotAudioMergeInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/audio-waveform.ts b/src/alphalib/types/robots/audio-waveform.ts index f5de78f9..2fe5e372 100644 --- a/src/alphalib/types/robots/audio-waveform.ts +++ b/src/alphalib/types/robots/audio-waveform.ts @@ -56,6 +56,7 @@ Here is an example waveform image: trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotAudioWaveformInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/azure-import.ts b/src/alphalib/types/robots/azure-import.ts index 197a6155..806277d2 100644 --- a/src/alphalib/types/robots/azure-import.ts +++ b/src/alphalib/types/robots/azure-import.ts @@ -49,6 +49,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: true, + stage: 'ga', } export const robotAzureImportInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/azure-store.ts b/src/alphalib/types/robots/azure-store.ts index 25788c0c..dcb1e678 100644 --- a/src/alphalib/types/robots/azure-store.ts +++ b/src/alphalib/types/robots/azure-store.ts @@ -39,6 +39,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotAzureStoreInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/backblaze-import.ts b/src/alphalib/types/robots/backblaze-import.ts index 6225053e..1062f462 100644 --- a/src/alphalib/types/robots/backblaze-import.ts +++ b/src/alphalib/types/robots/backblaze-import.ts @@ -49,6 +49,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: true, + stage: 'ga', } export const robotBackblazeImportInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/backblaze-store.ts b/src/alphalib/types/robots/backblaze-store.ts index c1a3a9a2..84bbd13e 100644 --- a/src/alphalib/types/robots/backblaze-store.ts +++ b/src/alphalib/types/robots/backblaze-store.ts @@ -44,6 +44,7 @@ Your Backblaze buckets need to have the \`listBuckets\` (to obtain a bucket ID f trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotBackblazeStoreInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/cloudfiles-import.ts b/src/alphalib/types/robots/cloudfiles-import.ts index e5d9efa8..3f380511 100644 --- a/src/alphalib/types/robots/cloudfiles-import.ts +++ b/src/alphalib/types/robots/cloudfiles-import.ts @@ -48,6 +48,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: true, + stage: 'ga', } export const robotCloudfilesImportInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/cloudfiles-store.ts b/src/alphalib/types/robots/cloudfiles-store.ts index 384ee17c..eec34b63 100644 --- a/src/alphalib/types/robots/cloudfiles-store.ts +++ b/src/alphalib/types/robots/cloudfiles-store.ts @@ -53,6 +53,7 @@ The storage container URL for this file is always available via \`file.meta.stor trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotCloudfilesStoreInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/cloudflare-import.ts b/src/alphalib/types/robots/cloudflare-import.ts index 73626b9d..3ac9036c 100644 --- a/src/alphalib/types/robots/cloudflare-import.ts +++ b/src/alphalib/types/robots/cloudflare-import.ts @@ -51,6 +51,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: true, + stage: 'ga', } export const robotCloudflareImportInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/cloudflare-store.ts b/src/alphalib/types/robots/cloudflare-store.ts index 8268830c..905ba306 100644 --- a/src/alphalib/types/robots/cloudflare-store.ts +++ b/src/alphalib/types/robots/cloudflare-store.ts @@ -47,6 +47,7 @@ The URL to the result file will be returned in the Assembly Status JSONRobot also detects and handles any of the following before evalu For security reasons, archives that contain symlinks to outside the archived dir, will error out the Assembly. Decompressing password-protected archives (encrypted archives) is currently not fully supported but will not cause an Assembly to fail. `), ignore_errors: z - .union([z.boolean(), z.array(z.enum(['meta']))]) - .transform((ignoreErrors): 'meta'[] => - ignoreErrors === true ? ['meta'] : ignoreErrors === false ? [] : ignoreErrors, + .union([z.boolean(), z.array(z.enum(['meta', 'execute']))]) + .transform((ignoreErrors): ('meta' | 'execute')[] => + ignoreErrors === true ? ['meta', 'execute'] : ignoreErrors === false ? [] : ignoreErrors, ) .default([]) .describe(` diff --git a/src/alphalib/types/robots/file-filter.ts b/src/alphalib/types/robots/file-filter.ts index 2256cc44..0bf6f8c9 100644 --- a/src/alphalib/types/robots/file-filter.ts +++ b/src/alphalib/types/robots/file-filter.ts @@ -46,6 +46,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotFileFilterInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/file-hash.ts b/src/alphalib/types/robots/file-hash.ts index fbef86fe..50058e66 100644 --- a/src/alphalib/types/robots/file-hash.ts +++ b/src/alphalib/types/robots/file-hash.ts @@ -36,6 +36,7 @@ export const meta: RobotMetaInput = { isAllowedForUrlTransform: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotFileHashInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/file-preview.ts b/src/alphalib/types/robots/file-preview.ts index f9607520..a4307225 100644 --- a/src/alphalib/types/robots/file-preview.ts +++ b/src/alphalib/types/robots/file-preview.ts @@ -51,6 +51,7 @@ export const meta: RobotMetaInput = { importRanges: ['0-19999999', '-1000000'], isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'beta', } export const robotFilePreviewInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/file-read.ts b/src/alphalib/types/robots/file-read.ts index 71aada5b..4fabd6c7 100644 --- a/src/alphalib/types/robots/file-read.ts +++ b/src/alphalib/types/robots/file-read.ts @@ -27,6 +27,7 @@ export const meta: RobotMetaInput = { isAllowedForUrlTransform: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotFileReadInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/file-serve.ts b/src/alphalib/types/robots/file-serve.ts index 322ece47..7c4e2a63 100644 --- a/src/alphalib/types/robots/file-serve.ts +++ b/src/alphalib/types/robots/file-serve.ts @@ -27,6 +27,7 @@ export const meta: RobotMetaInput = { isAllowedForUrlTransform: true, trackOutputFileSize: false, isInternal: false, + stage: 'ga', removeJobResultFilesFromDiskRightAfterStoringOnS3: false, } diff --git a/src/alphalib/types/robots/file-verify.ts b/src/alphalib/types/robots/file-verify.ts index aa6d64eb..15b55908 100644 --- a/src/alphalib/types/robots/file-verify.ts +++ b/src/alphalib/types/robots/file-verify.ts @@ -41,6 +41,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotFileVerifyInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/file-virusscan.ts b/src/alphalib/types/robots/file-virusscan.ts index 72fded72..11e7d886 100644 --- a/src/alphalib/types/robots/file-virusscan.ts +++ b/src/alphalib/types/robots/file-virusscan.ts @@ -46,6 +46,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotFileVirusscanInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/file-watermark.ts b/src/alphalib/types/robots/file-watermark.ts index 01bd3374..70e03dd8 100644 --- a/src/alphalib/types/robots/file-watermark.ts +++ b/src/alphalib/types/robots/file-watermark.ts @@ -12,6 +12,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotFileWatermarkInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/ftp-import.ts b/src/alphalib/types/robots/ftp-import.ts index 56b515ec..5791c338 100644 --- a/src/alphalib/types/robots/ftp-import.ts +++ b/src/alphalib/types/robots/ftp-import.ts @@ -45,6 +45,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: true, + stage: 'ga', } export const robotFtpImportInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/ftp-store.ts b/src/alphalib/types/robots/ftp-store.ts index 5bcf26e3..85c33773 100644 --- a/src/alphalib/types/robots/ftp-store.ts +++ b/src/alphalib/types/robots/ftp-store.ts @@ -39,6 +39,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotFtpStoreInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/google-import.ts b/src/alphalib/types/robots/google-import.ts index 5661ce1b..b031fbd3 100644 --- a/src/alphalib/types/robots/google-import.ts +++ b/src/alphalib/types/robots/google-import.ts @@ -49,6 +49,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: true, + stage: 'ga', } export const robotGoogleImportInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/google-store.ts b/src/alphalib/types/robots/google-store.ts index 8a323bbf..9101626b 100644 --- a/src/alphalib/types/robots/google-store.ts +++ b/src/alphalib/types/robots/google-store.ts @@ -39,6 +39,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotGoogleStoreInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/html-convert.ts b/src/alphalib/types/robots/html-convert.ts index accf4efa..2960a07f 100644 --- a/src/alphalib/types/robots/html-convert.ts +++ b/src/alphalib/types/robots/html-convert.ts @@ -44,6 +44,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotHtmlConvertInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/http-import.ts b/src/alphalib/types/robots/http-import.ts index 498d6bfe..1dec3319 100644 --- a/src/alphalib/types/robots/http-import.ts +++ b/src/alphalib/types/robots/http-import.ts @@ -41,6 +41,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: true, + stage: 'ga', } export const robotHttpImportInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/image-bgremove.ts b/src/alphalib/types/robots/image-bgremove.ts index 0c5276fa..522fd1a3 100644 --- a/src/alphalib/types/robots/image-bgremove.ts +++ b/src/alphalib/types/robots/image-bgremove.ts @@ -37,6 +37,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotImageBgremoveInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/image-describe.ts b/src/alphalib/types/robots/image-describe.ts index 3f62b3f8..d6a618c8 100644 --- a/src/alphalib/types/robots/image-describe.ts +++ b/src/alphalib/types/robots/image-describe.ts @@ -49,6 +49,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotImageDescribeInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/image-facedetect.ts b/src/alphalib/types/robots/image-facedetect.ts index ad99ab85..fad9a026 100644 --- a/src/alphalib/types/robots/image-facedetect.ts +++ b/src/alphalib/types/robots/image-facedetect.ts @@ -47,6 +47,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotImageFacedetectInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/image-generate.ts b/src/alphalib/types/robots/image-generate.ts index 1a81d3c5..7aea1b3b 100644 --- a/src/alphalib/types/robots/image-generate.ts +++ b/src/alphalib/types/robots/image-generate.ts @@ -27,6 +27,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotImageGenerateInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/image-merge.ts b/src/alphalib/types/robots/image-merge.ts index 2b9748f0..535d05ba 100644 --- a/src/alphalib/types/robots/image-merge.ts +++ b/src/alphalib/types/robots/image-merge.ts @@ -46,6 +46,7 @@ export const meta: RobotMetaInput = { isAllowedForUrlTransform: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotImageMergeInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/image-ocr.ts b/src/alphalib/types/robots/image-ocr.ts index 78eb984c..e4d4a862 100644 --- a/src/alphalib/types/robots/image-ocr.ts +++ b/src/alphalib/types/robots/image-ocr.ts @@ -49,6 +49,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotImageOcrInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/image-optimize.ts b/src/alphalib/types/robots/image-optimize.ts index fe8c1cb6..f4d027c5 100644 --- a/src/alphalib/types/robots/image-optimize.ts +++ b/src/alphalib/types/robots/image-optimize.ts @@ -41,6 +41,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotImageOptimizeInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/image-resize.ts b/src/alphalib/types/robots/image-resize.ts index 0945b5ec..ff632d2f 100644 --- a/src/alphalib/types/robots/image-resize.ts +++ b/src/alphalib/types/robots/image-resize.ts @@ -53,6 +53,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const oneTextSchema = z.object({ @@ -479,6 +480,32 @@ For the \`"min_fit"\` resize strategy, the watermark is scaled so that the short For the \`"stretch"\` resize strategy, the watermark is stretched (meaning, it is resized without keeping its aspect ratio in mind) so that both sides take up 25% of the corresponding image side. Since our image is 800×800 pixels, for a watermark size of 25% the watermark would be resized to 200×200 pixels. Its height would appear stretched, because keeping the aspect ratio in mind it would be resized to 200×150 pixels instead. For the \`"area"\` resize strategy, the watermark is resized (keeping its aspect ratio in check) so that it covers \`"xx%"\` of the image's surface area. The value from \`watermark_size\` is used for the percentage area size. +`), + watermark_opacity: z + .number() + .min(0) + .max(1) + .default(1.0) + .describe(` +The opacity of the watermark, where \`0.0\` is fully transparent and \`1.0\` is fully opaque. + +For example, a value of \`0.5\` means the watermark will be 50% transparent, allowing the underlying image to show through. This is useful for subtle branding or when you want the watermark to be less obtrusive. +`), + watermark_repeat_x: z + .boolean() + .default(false) + .describe(` +When set to \`true\`, the watermark will be repeated horizontally across the entire width of the image. + +This is useful for creating tiled watermark patterns that cover the full image and make it more difficult to crop out the watermark. +`), + watermark_repeat_y: z + .boolean() + .default(false) + .describe(` +When set to \`true\`, the watermark will be repeated vertically across the entire height of the image. + +This is useful for creating tiled watermark patterns that cover the full image. Can be combined with \`watermark_repeat_x\` to tile in both directions. `), text: z .union([ diff --git a/src/alphalib/types/robots/meta-read.ts b/src/alphalib/types/robots/meta-read.ts index 3de1dcdb..544c578a 100644 --- a/src/alphalib/types/robots/meta-read.ts +++ b/src/alphalib/types/robots/meta-read.ts @@ -10,6 +10,7 @@ export const meta: RobotMetaInput = { isAllowedForUrlTransform: true, trackOutputFileSize: false, isInternal: true, + stage: 'ga', removeJobResultFilesFromDiskRightAfterStoringOnS3: false, } diff --git a/src/alphalib/types/robots/meta-write.ts b/src/alphalib/types/robots/meta-write.ts index 09871ad4..eca0cfc4 100644 --- a/src/alphalib/types/robots/meta-write.ts +++ b/src/alphalib/types/robots/meta-write.ts @@ -42,6 +42,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotMetaWriteInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/minio-import.ts b/src/alphalib/types/robots/minio-import.ts index 58d0fd5b..617f6990 100644 --- a/src/alphalib/types/robots/minio-import.ts +++ b/src/alphalib/types/robots/minio-import.ts @@ -51,6 +51,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: true, + stage: 'ga', } export const robotMinioImportInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/minio-store.ts b/src/alphalib/types/robots/minio-store.ts index 5e05a718..6003f609 100644 --- a/src/alphalib/types/robots/minio-store.ts +++ b/src/alphalib/types/robots/minio-store.ts @@ -39,6 +39,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotMinioStoreInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/progress-simulate.ts b/src/alphalib/types/robots/progress-simulate.ts index 70f5430f..350f2bc5 100644 --- a/src/alphalib/types/robots/progress-simulate.ts +++ b/src/alphalib/types/robots/progress-simulate.ts @@ -11,6 +11,7 @@ export const meta: RobotMetaInput = { isAllowedForUrlTransform: false, trackOutputFileSize: true, isInternal: true, + stage: 'ga', removeJobResultFilesFromDiskRightAfterStoringOnS3: false, } diff --git a/src/alphalib/types/robots/s3-import.ts b/src/alphalib/types/robots/s3-import.ts index 4d78e4a4..5d435821 100644 --- a/src/alphalib/types/robots/s3-import.ts +++ b/src/alphalib/types/robots/s3-import.ts @@ -51,6 +51,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: true, + stage: 'ga', } export const robotS3ImportInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/s3-store.ts b/src/alphalib/types/robots/s3-store.ts index 5228a573..69946f32 100644 --- a/src/alphalib/types/robots/s3-store.ts +++ b/src/alphalib/types/robots/s3-store.ts @@ -38,6 +38,7 @@ export const meta: RobotMetaInput = { isAllowedForUrlTransform: true, trackOutputFileSize: false, isInternal: false, + stage: 'ga', removeJobResultFilesFromDiskRightAfterStoringOnS3: false, } diff --git a/src/alphalib/types/robots/script-run.ts b/src/alphalib/types/robots/script-run.ts index 96e9a83f..1cabe774 100644 --- a/src/alphalib/types/robots/script-run.ts +++ b/src/alphalib/types/robots/script-run.ts @@ -27,6 +27,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotScriptRunInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/sftp-import.ts b/src/alphalib/types/robots/sftp-import.ts index 9fbfaaea..8ea81bbb 100644 --- a/src/alphalib/types/robots/sftp-import.ts +++ b/src/alphalib/types/robots/sftp-import.ts @@ -39,6 +39,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: true, + stage: 'ga', } export const robotSftpImportInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/sftp-store.ts b/src/alphalib/types/robots/sftp-store.ts index d6614a3f..11c4f53c 100644 --- a/src/alphalib/types/robots/sftp-store.ts +++ b/src/alphalib/types/robots/sftp-store.ts @@ -38,6 +38,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotSftpStoreInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/speech-transcribe.ts b/src/alphalib/types/robots/speech-transcribe.ts index 27c95dbf..2922cc5d 100644 --- a/src/alphalib/types/robots/speech-transcribe.ts +++ b/src/alphalib/types/robots/speech-transcribe.ts @@ -54,6 +54,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotSpeechTranscribeInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/supabase-import.ts b/src/alphalib/types/robots/supabase-import.ts index 44886308..3081d9be 100644 --- a/src/alphalib/types/robots/supabase-import.ts +++ b/src/alphalib/types/robots/supabase-import.ts @@ -51,6 +51,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: true, + stage: 'ga', } export const robotSupabaseImportInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/supabase-store.ts b/src/alphalib/types/robots/supabase-store.ts index e47d3455..53a60bac 100644 --- a/src/alphalib/types/robots/supabase-store.ts +++ b/src/alphalib/types/robots/supabase-store.ts @@ -38,6 +38,7 @@ export const meta: RobotMetaInput = { isAllowedForUrlTransform: true, trackOutputFileSize: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', isInternal: false, } diff --git a/src/alphalib/types/robots/swift-import.ts b/src/alphalib/types/robots/swift-import.ts index aea698c5..505f7126 100644 --- a/src/alphalib/types/robots/swift-import.ts +++ b/src/alphalib/types/robots/swift-import.ts @@ -51,6 +51,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: true, + stage: 'ga', } export const robotSwiftImportInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/swift-store.ts b/src/alphalib/types/robots/swift-store.ts index befc9084..de032bd3 100644 --- a/src/alphalib/types/robots/swift-store.ts +++ b/src/alphalib/types/robots/swift-store.ts @@ -39,6 +39,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotSwiftStoreInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/text-speak.ts b/src/alphalib/types/robots/text-speak.ts index 83986684..bf7a7710 100644 --- a/src/alphalib/types/robots/text-speak.ts +++ b/src/alphalib/types/robots/text-speak.ts @@ -74,6 +74,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotTextSpeakInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/text-translate.ts b/src/alphalib/types/robots/text-translate.ts index 820da0f4..a4ea2b5c 100644 --- a/src/alphalib/types/robots/text-translate.ts +++ b/src/alphalib/types/robots/text-translate.ts @@ -60,6 +60,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } const translatableLanguages = z diff --git a/src/alphalib/types/robots/tigris-import.ts b/src/alphalib/types/robots/tigris-import.ts index 50176f3c..5004c3c4 100644 --- a/src/alphalib/types/robots/tigris-import.ts +++ b/src/alphalib/types/robots/tigris-import.ts @@ -51,6 +51,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: true, + stage: 'ga', } export const robotTigrisImportInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/tigris-store.ts b/src/alphalib/types/robots/tigris-store.ts index f6dbd140..28f0a0f1 100644 --- a/src/alphalib/types/robots/tigris-store.ts +++ b/src/alphalib/types/robots/tigris-store.ts @@ -39,6 +39,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotTigrisStoreInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/tlcdn-deliver.ts b/src/alphalib/types/robots/tlcdn-deliver.ts index fe4b6833..b327f51e 100644 --- a/src/alphalib/types/robots/tlcdn-deliver.ts +++ b/src/alphalib/types/robots/tlcdn-deliver.ts @@ -28,6 +28,7 @@ export const meta: RobotMetaInput = { isAllowedForUrlTransform: false, trackOutputFileSize: false, isInternal: true, + stage: 'ga', removeJobResultFilesFromDiskRightAfterStoringOnS3: false, } diff --git a/src/alphalib/types/robots/tus-store.ts b/src/alphalib/types/robots/tus-store.ts index 36108fc3..8681b732 100644 --- a/src/alphalib/types/robots/tus-store.ts +++ b/src/alphalib/types/robots/tus-store.ts @@ -37,6 +37,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotTusStoreInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/upload-handle.ts b/src/alphalib/types/robots/upload-handle.ts index d278c6c1..b4167015 100644 --- a/src/alphalib/types/robots/upload-handle.ts +++ b/src/alphalib/types/robots/upload-handle.ts @@ -43,6 +43,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotUploadHandleInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/video-adaptive.ts b/src/alphalib/types/robots/video-adaptive.ts index 75bde4b4..1afdbd66 100644 --- a/src/alphalib/types/robots/video-adaptive.ts +++ b/src/alphalib/types/robots/video-adaptive.ts @@ -70,6 +70,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotVideoAdaptiveInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/video-concat.ts b/src/alphalib/types/robots/video-concat.ts index f919c52e..492ce2d6 100644 --- a/src/alphalib/types/robots/video-concat.ts +++ b/src/alphalib/types/robots/video-concat.ts @@ -61,6 +61,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotVideoConcatInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/video-encode.ts b/src/alphalib/types/robots/video-encode.ts index 2e3be2b0..e34e4f09 100644 --- a/src/alphalib/types/robots/video-encode.ts +++ b/src/alphalib/types/robots/video-encode.ts @@ -43,6 +43,7 @@ export const meta: RobotMetaInput = { isAllowedForUrlTransform: false, trackOutputFileSize: true, isInternal: false, + stage: 'ga', removeJobResultFilesFromDiskRightAfterStoringOnS3: false, } diff --git a/src/alphalib/types/robots/video-merge.ts b/src/alphalib/types/robots/video-merge.ts index fa1c1621..2858703e 100644 --- a/src/alphalib/types/robots/video-merge.ts +++ b/src/alphalib/types/robots/video-merge.ts @@ -36,6 +36,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotVideoMergeInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/video-ondemand.ts b/src/alphalib/types/robots/video-ondemand.ts index f684c368..8f4356b8 100644 --- a/src/alphalib/types/robots/video-ondemand.ts +++ b/src/alphalib/types/robots/video-ondemand.ts @@ -68,6 +68,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'beta', } export const robotVideoOndemandInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/video-subtitle.ts b/src/alphalib/types/robots/video-subtitle.ts index 1e32a863..760c5ee7 100644 --- a/src/alphalib/types/robots/video-subtitle.ts +++ b/src/alphalib/types/robots/video-subtitle.ts @@ -61,6 +61,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotVideoSubtitleInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/video-thumbs.ts b/src/alphalib/types/robots/video-thumbs.ts index 31fb4979..77bc03b7 100644 --- a/src/alphalib/types/robots/video-thumbs.ts +++ b/src/alphalib/types/robots/video-thumbs.ts @@ -48,6 +48,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: true, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotVideoThumbsInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/vimeo-import.ts b/src/alphalib/types/robots/vimeo-import.ts index 3f139848..9a160ae7 100644 --- a/src/alphalib/types/robots/vimeo-import.ts +++ b/src/alphalib/types/robots/vimeo-import.ts @@ -48,6 +48,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: true, + stage: 'ga', } export const robotVimeoImportInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/vimeo-store.ts b/src/alphalib/types/robots/vimeo-store.ts index ad6fc3f8..9d3c89c5 100644 --- a/src/alphalib/types/robots/vimeo-store.ts +++ b/src/alphalib/types/robots/vimeo-store.ts @@ -40,6 +40,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotVimeoStoreInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/wasabi-import.ts b/src/alphalib/types/robots/wasabi-import.ts index 87a9eb86..5cf2a8a3 100644 --- a/src/alphalib/types/robots/wasabi-import.ts +++ b/src/alphalib/types/robots/wasabi-import.ts @@ -51,6 +51,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: true, + stage: 'ga', } export const robotWasabiImportInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/wasabi-store.ts b/src/alphalib/types/robots/wasabi-store.ts index 8f45ad2d..e714cee3 100644 --- a/src/alphalib/types/robots/wasabi-store.ts +++ b/src/alphalib/types/robots/wasabi-store.ts @@ -39,6 +39,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotWasabiStoreInstructionsSchema = robotBase diff --git a/src/alphalib/types/robots/youtube-store.ts b/src/alphalib/types/robots/youtube-store.ts index 7d0b708a..83f0e040 100644 --- a/src/alphalib/types/robots/youtube-store.ts +++ b/src/alphalib/types/robots/youtube-store.ts @@ -42,6 +42,7 @@ export const meta: RobotMetaInput = { trackOutputFileSize: false, isInternal: false, removeJobResultFilesFromDiskRightAfterStoringOnS3: false, + stage: 'ga', } export const robotYoutubeStoreInstructionsSchema = robotBase diff --git a/src/alphalib/types/template.ts b/src/alphalib/types/template.ts index 0c339b0b..d237b809 100644 --- a/src/alphalib/types/template.ts +++ b/src/alphalib/types/template.ts @@ -240,6 +240,22 @@ export const assemblyInstructionsWithHiddenSchema = assemblyInstructionsSchema.e mediainfo_stack: z.string().optional(), ffmpeg_stack: z.string().optional(), usage_tags: z.string().optional(), + response_headers: z + .object({ + cors: z + .object({ + 'Access-Control-Allow-Methods': z.string(), + 'Access-Control-Allow-Origin': z.string(), + 'Access-Control-Allow-Headers': z.string(), + 'Access-Control-Expose-Headers': z.string(), + 'Access-Control-Allow-Credentials': z.boolean(), + 'Access-Control-Max-Age': z.number(), + 'Access-Control-Allow-Private-Network': z.boolean(), + 'Access-Control-Allow-Public-Network': z.boolean(), + }) + .optional(), + }) + .optional(), randomize_watermarks: z.boolean().optional(), await: z .union([ diff --git a/yarn.lock b/yarn.lock index 94c98b9f..f42faea1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1929,6 +1929,13 @@ __metadata: languageName: node linkType: hard +"@transloadit/sev-logger@npm:^0.0.15": + version: 0.0.15 + resolution: "@transloadit/sev-logger@npm:0.0.15" + checksum: 10c0/1aa26ab5d6c8dab425ea85832f2094d59285963bc368b64990f23420ddc3a5bedea8ca70f91abb068d447479f4fca88cb1a9b2cd49ccc4093294daa7cf8e2ae1 + languageName: node + linkType: hard + "@types/chai@npm:^5.2.2": version: 5.2.2 resolution: "@types/chai@npm:5.2.2" @@ -5233,6 +5240,7 @@ __metadata: "@aws-sdk/client-s3": "npm:^3.891.0" "@aws-sdk/s3-request-presigner": "npm:^3.891.0" "@biomejs/biome": "npm:^2.2.4" + "@transloadit/sev-logger": "npm:^0.0.15" "@types/debug": "npm:^4.1.12" "@types/temp": "npm:^0.9.4" "@vitest/coverage-v8": "npm:^3.2.4"