diff --git a/.cursor/rules/coding-style.mdc b/.cursor/rules/coding-style.mdc index be212e23..7fda7a28 100644 --- a/.cursor/rules/coding-style.mdc +++ b/.cursor/rules/coding-style.mdc @@ -3,7 +3,6 @@ description: globs: alwaysApply: true --- - Coding style: - Favor `async run() {` over `run = async () => {` inside ES6 classes @@ -15,6 +14,6 @@ Coding style: - Do not wrap each function body and function call in `try`/`catch` blocks. It pollutes the code. Assume we will always have an e.g. `main().catch((err) => { console.error(err); process.exit(1) })` to catch us. I repeat: Avoid over-use of try-catch such as `try { // foo } catch (err) { console.error('error while foo'); throw err }`, assume we catch errors on a higher level and do not need the extra explananation. - Before creating new files and new code, see if we can leverage existing work, maybe slighty adapt that without breaking BC, to keep things DRY. - Favor early exits, so quickly `continue`, `return false` (or `throw` if needed), over nesting everything in positive conditions, creating christmas trees. -- Use Biome with 100 char line width, single quotes for JS/TS, semi: false +- Use Prettier with 100 char line width, single quotes for JS/TS, semi: false - Use descriptive names: PascalCase for components/types, camelCase for variables/methods/schemas - Alphabetize imports, group by source type (built-in/external/internal) diff --git a/src/alphalib/types/robots/_instructions-primitives.ts b/src/alphalib/types/robots/_instructions-primitives.ts index d51dbea3..222426ac 100644 --- a/src/alphalib/types/robots/_instructions-primitives.ts +++ b/src/alphalib/types/robots/_instructions-primitives.ts @@ -378,18 +378,21 @@ export function interpolateRecursive( */ const uninterpolatableKeys = ['robot', 'use'] as const -type InterpolatableRobot> = - Schema extends z.ZodObject - ? z.ZodObject< - { - [Key in keyof T]: Key extends (typeof uninterpolatableKeys)[number] - ? T[Key] - : InterpolatableSchema - }, - UnknownKeys, - Catchall - > - : never +type InterpolatableRobot> = Schema extends z.ZodObject< + infer T, + infer UnknownKeys, + infer Catchall +> + ? z.ZodObject< + { + [Key in keyof T]: Key extends (typeof uninterpolatableKeys)[number] + ? T[Key] + : InterpolatableSchema + }, + UnknownKeys, + Catchall + > + : never export function interpolateRobot>( schema: Schema, @@ -416,7 +419,9 @@ export function interpolateRobot>( export type RobotBase = z.infer export const robotBase = z .object({ - output_meta: z.union([z.record(z.boolean()), z.boolean(), z.array(z.string())]).optional() + output_meta: z + .union([z.record(z.boolean()), z.boolean(), z.array(z.string())]) + .optional() .describe(` Allows you to specify a set of metadata that is more expensive on CPU power to calculate, and thus is disabled by default to keep your Assemblies processing fast. @@ -441,7 +446,9 @@ You can also set this to \`false\` to skip metadata extraction and speed up tran `Setting the queue to 'batch', manually downgrades the priority of jobs for this step to avoid consuming Priority job slots for jobs that don't need zero queue waiting times`, ), - force_accept: z.boolean().default(false) + force_accept: z + .boolean() + .default(false) .describe(`Force a Robot to accept a file type it would have ignored. By default, Robots ignore files they are not familiar with. @@ -475,7 +482,10 @@ export const useParamObjectOfStepsSchema = z steps: useParamStepsSchema, bundle_steps: z.boolean().optional(), group_by_original: z.boolean().optional(), - fields: z.array(z.string()).optional().describe(` + fields: z + .array(z.string()) + .optional() + .describe(` Array of field names to filter input files by when using steps. `), }) @@ -499,7 +509,10 @@ export const useParamObjectOfStepsWithHiddenFieldsSchema = z steps: useParamStepsWithHiddenFieldsSchema, bundle_steps: z.boolean().optional(), group_by_original: z.boolean().optional(), - fields: z.array(z.string()).optional().describe(` + fields: z + .array(z.string()) + .optional() + .describe(` Array of field names to filter input files by when using steps. `), }) @@ -571,8 +584,8 @@ export const complexWidthSchema = z.preprocess((val) => { return val } if (typeof val === 'string') { - const num = parseInt(val, 10) - if (isNaN(num) || val.includes('x')) { + const num = Number.parseInt(val, 10) + if (Number.isNaN(num) || val.includes('x')) { return val } return num @@ -585,8 +598,8 @@ export const complexHeightSchema = z.preprocess((val) => { return val } if (typeof val === 'string') { - const num = parseInt(val, 10) - if (isNaN(num) || val.includes('x')) { + const num = Number.parseInt(val, 10) + if (Number.isNaN(num) || val.includes('x')) { return val } return num @@ -706,14 +719,16 @@ export const robotFFmpeg = z.object({ vbr: z.union([z.string(), z.number()]).optional(), }) .passthrough() - .optional().describe(` + .optional() + .describe(` A parameter object to be passed to FFmpeg. If a preset is used, the options specified are merged on top of the ones from the preset. For available options, see the [FFmpeg documentation](https://ffmpeg.org/ffmpeg-doc.html). Options specified here take precedence over the preset options. `), ffmpeg_stack: z // Any semver in range is allowed and normalized. The enum is used for editor completions. .union([z.enum(['v5', 'v6', 'v7']), z.string().regex(/^v?[567](\.\d+)?(\.\d+)?$/)]) - .default('v5.0.0').describe(` + .default('v5.0.0') + .describe(` Selects the FFmpeg stack version to use for encoding. These versions reflect real FFmpeg versions. We currently recommend to use "v6.0.0". `), }) @@ -815,7 +830,11 @@ const audioPresets = createPresets([ export type FFmpegAudio = z.infer export const robotFFmpegAudio = robotFFmpeg .extend({ - preset: z.enum(audioPresets).transform(transformPreset).optional().describe(` + preset: z + .enum(audioPresets) + .transform(transformPreset) + .optional() + .describe(` Performs conversion using pre-configured settings. If you specify your own FFmpeg parameters using the Robot's \`ffmpeg\` parameter and you have not specified a preset, then the default \`mp3\` preset is not applied. This is to prevent you from having to override each of the MP3 preset's values manually. @@ -831,12 +850,22 @@ For a list of audio presets, see [audio presets](/docs/presets/audio/). export type FFmpegVideo = z.infer export const robotFFmpegVideo = robotFFmpeg .extend({ - width: z.number().int().min(1).nullish().describe(` + width: z + .number() + .int() + .min(1) + .nullish() + .describe(` Width of the new video, in pixels. If the value is not specified and the \`preset\` parameter is available, the \`preset\`'s [supplied width](/docs/presets/video/) will be implemented. `), - height: z.number().int().min(1).nullish().describe(` + height: z + .number() + .int() + .min(1) + .nullish() + .describe(` Height of the new video, in pixels. If the value is not specified and the \`preset\` parameter is available, the \`preset\`'s [supplied height](/docs/presets/video/) will be implemented. @@ -939,7 +968,8 @@ If the value is not specified and the \`preset\` parameter is available, the \`p ...audioPresets, ]) .transform(transformPreset) - .optional().describe(` + .optional() + .describe(` Converts a video according to [pre-configured settings](/docs/presets/video/). If you specify your own FFmpeg parameters using the Robot's and/or do not not want Transloadit to set any encoding setting, starting \`ffmpeg_stack: "${stackVersions.ffmpeg.recommendedVersion}"\`, you can use the value \`'empty'\` here. @@ -947,17 +977,19 @@ If you specify your own FFmpeg parameters using the Robot's and/or do }) .strict() -export const unsafeCoordinatesSchema = z.union([ - z - .object({ - x1: z.union([z.string(), z.number()]).nullish(), - y1: z.union([z.string(), z.number()]).nullish(), - x2: z.union([z.string(), z.number()]).nullish(), - y2: z.union([z.string(), z.number()]).nullish(), - }) - .strict(), - z.string(), -]).describe(` +export const unsafeCoordinatesSchema = z + .union([ + z + .object({ + x1: z.union([z.string(), z.number()]).nullish(), + y1: z.union([z.string(), z.number()]).nullish(), + x2: z.union([z.string(), z.number()]).nullish(), + y2: z.union([z.string(), z.number()]).nullish(), + }) + .strict(), + z.string(), + ]) + .describe(` Coordinates for watermarking. `) export type UnsafeCoordinates = z.infer @@ -1114,7 +1146,13 @@ export const colorspaceSchema = z.enum([ ]) // TODO: add before and after images to the description. -export const imageQualitySchema = z.number().int().min(1).max(100).default(92).describe(` +export const imageQualitySchema = z + .number() + .int() + .min(1) + .max(100) + .default(92) + .describe(` Controls the image compression for JPG and PNG images. Please also take a look at [🤖/image/optimize](/docs/robots/image-optimize/). `) @@ -1145,7 +1183,10 @@ export const robotImport = z export type AzureBase = z.infer export const azureBase = z .object({ - credentials: z.string().optional().describe(` + credentials: z + .string() + .optional() + .describe(` Please create your associated Template Credentials in your Transloadit account and use the name of your [Template Credentials](/c/template-credentials/) as this parameter's value. They will contain the values for your Azure Container, Account and Key. While we recommend to use Template Credentials at all times, some use cases demand dynamic credentials for which using Template Credentials is too unwieldy because of their static nature. If you have this requirement, feel free to use the following parameters instead: \`"account"\`, \`"key"\`, \`"container"\`. @@ -1159,7 +1200,10 @@ While we recommend to use Template Credentials at all times, some use export type BackblazeBase = z.infer export const backblazeBase = z .object({ - credentials: z.string().optional().describe(` + credentials: z + .string() + .optional() + .describe(` Please create your associated Template Credentials in your Transloadit account and use the name of your Template Credentials as this parameter's value. They will contain the values for your Backblaze Bucket Name, App Key ID, and App Key. To create your credential information, head over to Backblaze, sign in to your account, and select "Create a Bucket". Save the name of your bucket, and click on the "App Keys" tab, scroll to the bottom of the page then select “Add a New Application Key”. Allow access to your recently created bucket, select “Read and Write” as your type of access, and tick the “Allow List All Bucket Names” option. @@ -1179,7 +1223,10 @@ While we recommend to use Template Credentials at all times, some use export type CloudfilesBase = z.infer export const cloudfilesBase = z .object({ - credentials: z.string().optional().describe(` + credentials: z + .string() + .optional() + .describe(` Please create your associated Template Credentials in your Transloadit account and use the name of your [Template Credentials](/c/template-credentials/) as this parameter's value. They will contain the values for your Cloud Files Container, User, Key, Account type and Data center. While we recommend to use Template Credentials at all times, some use cases demand dynamic credentials for which using Template Credentials is too unwieldy because of their static nature. If you have this requirement, feel free to use the following parameters instead: \`"account_type"\` ("us" or "uk"), \`"data_center"\` ("dfw" for Dallas or "ord" for Chicago for example), \`"user"\`, \`"key"\`, \`"container"\`. @@ -1195,7 +1242,10 @@ While we recommend to use Template Credentials at all times, some use export type CloudflareBase = z.infer export const cloudflareBase = z .object({ - credentials: z.string().optional().describe(` + credentials: z + .string() + .optional() + .describe(` Please create your associated Template Credentials in your Transloadit account and use the name of your Template Credentials as this parameter's value. They will contain the values for your cloudflare bucket, Key, Secret and Bucket region. While we recommend to use Template Credentials at all times, some use cases demand dynamic credentials for which using Template Credentials is too unwieldy because of their static nature. If you have this requirement, feel free to use the following parameters instead: \`"bucket"\`, \`"host"\`, \`"key"\`, \`"secret"\`. @@ -1210,7 +1260,10 @@ While we recommend to use Template Credentials at all times, some use export type DigitalOceanBase = z.infer export const digitalOceanBase = z .object({ - credentials: z.string().optional().describe(` + credentials: z + .string() + .optional() + .describe(` Please create your associated Template Credentials in your Transloadit account and use the name of your [Template Credentials](/c/template-credentials/) as this parameter's value. They will contain the values for your DigitalOcean Space, Key, Secret and Region. While we recommend to use Template Credentials at all times, some use cases demand dynamic credentials for which using Template Credentials is too unwieldy because of their static nature. If you have this requirement, feel free to use the following parameters instead: \`"space"\`, \`"region"\` (for example: \`"fra1"\` or \`"nyc3"\`), \`"key"\`, \`"secret"\`. @@ -1225,7 +1278,10 @@ While we recommend to use Template Credentials at all times, some use export type DropboxBase = z.infer export const dropboxBase = z .object({ - credentials: z.string().optional().describe(` + credentials: z + .string() + .optional() + .describe(` Please create your associated Template Credentials in your Transloadit account and use the name of your Template Credentials as this parameter's value. They will contain the values for your Dropbox access token. `), }) @@ -1234,7 +1290,10 @@ Please create your associated Template Credentials in your Transloadi export type VimeoBase = z.infer export const vimeoBase = z .object({ - credentials: z.string().optional().describe(` + credentials: z + .string() + .optional() + .describe(` Please create your associated Template Credentials in your Transloadit account and use the name of your Template Credentials as this parameter's value. They will contain the values for your Vimeo access token. `), }) @@ -1243,7 +1302,10 @@ Please create your associated Template Credentials in your Transloadi export type FtpBase = z.infer export const ftpBase = z .object({ - credentials: z.string().optional().describe(` + credentials: z + .string() + .optional() + .describe(` Please create your associated Template Credentials in your Transloadit account and use the name of your Template Credentials as this parameter's value. They will contain the values for your FTP host, user and password. While we recommend to use Template Credentials at all times, some use cases demand dynamic credentials for which using Template Credentials with their static nature is too unwieldy. If you have this requirement, feel free to use the following parameters instead: \`"host"\`, \`"user"\`, \`"password"\`. @@ -1258,7 +1320,10 @@ While we recommend to use Template Credentials at all times, some use export type GoogleBase = z.infer export const googleBase = z .object({ - credentials: z.string().optional().describe(` + credentials: z + .string() + .optional() + .describe(` Create a new [Google service account](https://cloud.google.com/storage/docs/authentication). Set its role to "Storage Object Creator". Choose "JSON" for the key file format and download it to your computer. You will need to upload this file when creating your Template Credentials. Go back to your Google credentials project and enable the "Google Cloud Storage JSON API" for it. Wait around ten minutes for the action to propagate through the Google network. Grab the project ID from the dropdown menu in the header bar on the Google site. You will also need it later on. @@ -1277,7 +1342,10 @@ Then, create your associated [Template Credentials](/c/template-credentials/) in export type MinioBase = z.infer export const minioBase = z .object({ - credentials: z.string().optional().describe(` + credentials: z + .string() + .optional() + .describe(` Please create your associated Template Credentials in your Transloadit account and use the name of your Template Credentials as this parameter's value. They will contain the values for your MinIO bucket, Key, Secret and Bucket region. While we recommend to use Template Credentials at all times, some use cases demand dynamic credentials for which using Template Credentials is too unwieldy because of their static nature. If you have this requirement, feel free to use the following parameters instead: \`"bucket"\`, \`"host"\`, \`"key"\`, \`"secret"\`. @@ -1292,7 +1360,10 @@ While we recommend to use Template Credentials at all times, some use export type S3Base = z.infer export const s3Base = z .object({ - credentials: z.string().optional().describe(` + credentials: z + .string() + .optional() + .describe(` Please create your associated Template Credentials in your Transloadit account and use the name of your Template Credentials as this parameter's value. They will contain the values for your S3 bucket, Key, Secret and Bucket region. While we recommend to use Template Credentials at all times, some use cases demand dynamic credentials for which using Template Credentials is too unwieldy because of their static nature. If you have this requirement, feel free to use the following parameters instead: \`"bucket"\`, \`"bucket_region"\` (for example: \`"us-east-1"\` or \`"eu-west-2"\`), \`"key"\`, \`"secret"\`. @@ -1307,7 +1378,10 @@ While we recommend to use Template Credentials at all times, some use export type SftpBase = z.infer export const sftpBase = z .object({ - credentials: z.string().optional().describe(` + credentials: z + .string() + .optional() + .describe(` Please create your associated Template Credentials in your Transloadit account and use the name of your Template Credentials as this parameter's value. They will contain the values for your SFTP host, user and optional custom public key. While we recommend to use Template Credentials at all times, some use cases demand dynamic credentials for which using Template Credentials is too unwieldy because of their static nature. If you have this requirement, feel free to use the following parameters instead: \`"host"\`, \`"port"\`, \`"user"\`, \`"public_key"\` (optional). @@ -1322,7 +1396,10 @@ While we recommend to use Template Credentials at all times, some use export type SupabaseBase = z.infer export const supabaseBase = z .object({ - credentials: z.string().optional().describe(` + credentials: z + .string() + .optional() + .describe(` Please create your associated Template Credentials in your Transloadit account and use the name of your Template Credentials as this parameter's value. They will contain the values for your Supabase bucket, Key, Secret and Bucket region. While we recommend to use Template Credentials at all times, some use cases demand dynamic credentials for which using Template Credentials is too unwieldy because of their static nature. If you have this requirement, feel free to use the following parameters instead: \`"bucket"\`, \`"host"\`, \`"key"\`, \`"secret"\`. @@ -1330,7 +1407,10 @@ While we recommend to use Template Credentials at all times, some use If you do use these parameters, make sure to use the **Endpoint** value under \`Storage > S3 Connection\` in the Supabase console for the \`"host"\` value, and the values under **S3 Access Keys** on the same page for your \`"key"\` and \`"secret"\`. `), bucket: z.string().optional(), - bucket_region: z.string().optional().describe(` + bucket_region: z + .string() + .optional() + .describe(` The region where the bucket is located. `), host: z.string().optional(), @@ -1342,13 +1422,19 @@ The region where the bucket is located. export type SwiftBase = z.infer export const swiftBase = z .object({ - credentials: z.string().optional().describe(` + credentials: z + .string() + .optional() + .describe(` Please create your associated Template Credentials in your Transloadit account and use the name of your Template Credentials as this parameter's value. They will contain the values for your Swift bucket, Key, Secret and Bucket region. While we recommend to use Template Credentials at all times, some use cases demand dynamic credentials for which using Template Credentials is too unwieldy because of their static nature. If you have this requirement, feel free to use the following parameters instead: \`"bucket"\`, \`"host"\`, \`"key"\`, \`"secret"\`. `), bucket: z.string().optional(), - bucket_region: z.string().optional().describe(` + bucket_region: z + .string() + .optional() + .describe(` The region where the bucket is located. `), host: z.string().optional(), @@ -1360,13 +1446,19 @@ The region where the bucket is located. export type TigrisBase = z.infer export const tigrisBase = z .object({ - credentials: z.string().optional().describe(` + credentials: z + .string() + .optional() + .describe(` Please create your associated Template Credentials in your Transloadit account and use the name of your Template Credentials as this parameter's value. They will contain the values for your MinIO bucket, Key, Secret and Bucket region. While we recommend to use Template Credentials at all times, some use cases demand dynamic credentials for which using Template Credentials is too unwieldy because of their static nature. If you have this requirement, feel free to use the following parameters instead: \`"bucket"\`, \`"host"\`, \`"key"\`, \`"secret"\`. `), bucket: z.string().optional(), - bucket_region: z.string().optional().describe(` + bucket_region: z + .string() + .optional() + .describe(` The region where the bucket is located. `), host: z.string().optional(), @@ -1378,13 +1470,19 @@ The region where the bucket is located. export type WasabiBase = z.infer export const wasabiBase = z .object({ - credentials: z.string().optional().describe(` + credentials: z + .string() + .optional() + .describe(` Please create your associated Template Credentials in your Transloadit account and use the name of your Template Credentials as this parameter's value. They will contain the values for your Wasabi bucket, Key, Secret and Bucket region. While we recommend to use Template Credentials at all times, some use cases demand dynamic credentials for which using Template Credentials is too unwieldy because of their static nature. If you have this requirement, feel free to use the following parameters instead: \`"bucket"\`, \`"host"\`, \`"key"\`, \`"secret"\`. `), bucket: z.string().optional(), - bucket_region: z.string().optional().describe(` + bucket_region: z + .string() + .optional() + .describe(` The region where the bucket is located. `), host: z.string().optional(), @@ -1462,7 +1560,10 @@ export const videoEncodeSpecificInstructionsSchema = robotFFmpegVideo resize_strategy: resize_strategy.describe(` See the [available resize strategies](/docs/topics/resize-strategies/). `), - zoom: z.boolean().default(true).describe(` + zoom: z + .boolean() + .default(true) + .describe(` If this is set to \`false\`, smaller videos will not be stretched to the desired width and height. For details about the impact of zooming for your preferred resize strategy, see the list of available [resize strategies](/docs/topics/resize-strategies/). `), crop: unsafeCoordinatesSchema.optional().describe(` @@ -1501,22 +1602,39 @@ The background color of the resulting video the \`"rrggbbaa"\` format (red, gree z.literal(360), z.literal(false), ]) - .optional().describe(` + .optional() + .describe(` Forces the video to be rotated by the specified degree integer. Currently, only multiples of \`90\` are supported. We automatically correct the orientation of many videos when the orientation is provided by the camera. This option is only useful for videos requiring rotation because it was not detected by the camera. If you set \`rotate\` to \`false\` no rotation is performed, even if the metadata contains such instructions. `), - hint: z.boolean().default(false).describe(` + hint: z + .boolean() + .default(false) + .describe(` Enables hinting for mp4 files, for RTP/RTSP streaming. `), - turbo: z.boolean().default(false).describe(` + turbo: z + .boolean() + .default(false) + .describe(` Splits the video into multiple chunks so that each chunk can be encoded in parallel before all encoded chunks are stitched back together to form the result video. This comes at the expense of extra Priority Job Slots and may prove to be counter-productive for very small video files. `), - chunk_duration: z.number().int().min(1).optional().describe(` + chunk_duration: z + .number() + .int() + .min(1) + .optional() + .describe(` Allows you to specify the duration of each chunk when \`turbo\` is set to \`true\`. This means you can take advantage of that feature while using fewer Priority Job Slots. For instance, the longer each chunk is, the fewer Encoding Jobs will need to be used. `), - watermark_url: z.string().default('').describe(` + watermark_url: z + .string() + .default('') + .describe(` A URL indicating a PNG image to be overlaid above this image. You can also [supply the watermark via another Assembly Step](/docs/topics/use-parameter/#supplying-the-watermark-via-an-assembly-step). `), - watermark_position: z.union([positionSchema, z.array(positionSchema)]).default('center') + watermark_position: z + .union([positionSchema, z.array(positionSchema)]) + .default('center') .describe(` The position at which the watermark is placed. @@ -1524,12 +1642,20 @@ An array of possible values can also be specified, in which case one value will This setting puts the watermark in the specified corner. To use a specific pixel offset for the watermark, you will need to add the padding to the image itself. `), - watermark_x_offset: z.number().int().default(0).describe(` + watermark_x_offset: z + .number() + .int() + .default(0) + .describe(` The x-offset in number of pixels at which the watermark will be placed in relation to the position it has due to \`watermark_position\`. Values can be both positive and negative and yield different results depending on the \`watermark_position\` parameter. Positive values move the watermark closer to the image's center point, whereas negative values move the watermark further away from the image's center point. `), - watermark_y_offset: z.number().int().default(0).describe(` + watermark_y_offset: z + .number() + .int() + .default(0) + .describe(` The y-offset in number of pixels at which the watermark will be placed in relation to the position it has due to \`watermark_position\`. Values can be both positive and negative and yield different results depending on the \`watermark_position\` parameter. Positive values move the watermark closer to the image's center point, whereas negative values move the watermark further away from the image's center point. @@ -1537,7 +1663,10 @@ Values can be both positive and negative and yield different results depending o watermark_size: percentageSchema.optional().describe(` The size of the watermark, as a percentage, such as \`"50%"\`. How the watermark is resized greatly depends on the \`watermark_resize_strategy\`. `), - watermark_resize_strategy: z.enum(['area', 'fit', 'stretch']).default('fit').describe(` + watermark_resize_strategy: z + .enum(['area', 'fit', 'stretch']) + .default('fit') + .describe(` To explain how the resize strategies work, let's assume our target video size is 800×800 pixels and our watermark image is 400×300 pixels. Let's also assume, the \`watermark_size\` parameter is set to \`"25%"\`. For the \`"fit"\` resize strategy, the watermark is scaled so that the longer side of the watermark takes up 25% of the corresponding video side. And the other side is scaled according to the aspect ratio of the watermark image. So with our watermark, the width is the longer side, and 25% of the video size would be 200px. Hence, the watermark would be resized to 200×150 pixels. If the \`watermark_size\` was set to \`"50%"\`", it would be resized to 400×300 pixels (so just left at its original size). @@ -1546,28 +1675,56 @@ For the \`"stretch"\` resize strategy, the watermark image is stretched (meaning For the \`"area"\` resize strategy, the watermark is resized (keeping its aspect ratio in check) so that it covers \`"xx%"\` of the video's surface area. The value from \`watermark_size\` is used for the percentage area size. `), - watermark_start_time: z.number().default(0).describe(` + watermark_start_time: z + .number() + .default(0) + .describe(` The delay in seconds from the start of the video for the watermark to appear. By default the watermark is immediately shown. `), - watermark_duration: z.number().default(-1).describe(` + watermark_duration: z + .number() + .default(-1) + .describe(` The duration in seconds for the watermark to be shown. Can be used together with \`watermark_start_time\` to create nice effects. The default value is \`-1.0\`, which means that the watermark is shown for the entire duration of the video. `), - watermark_opacity: z.number().min(0).max(1).default(1).describe(` + watermark_opacity: z + .number() + .min(0) + .max(1) + .default(1) + .describe(` The opacity of the watermark. Valid values are between \`0\` (invisible) and \`1.0\` (full visibility). `), - segment: z.boolean().default(false).describe(` + segment: z + .boolean() + .default(false) + .describe(` Splits the file into multiple parts, to be used for Apple's [HTTP Live Streaming](https://developer.apple.com/resources/http-streaming/). `), - segment_duration: z.number().int().min(1).default(10).describe(` + segment_duration: z + .number() + .int() + .min(1) + .default(10) + .describe(` Specifies the length of each HTTP segment. This is optional, and the default value as recommended by Apple is \`10\`. Do not change this value unless you have a good reason. `), - segment_prefix: z.string().default('').describe(` + segment_prefix: z + .string() + .default('') + .describe(` The prefix used for the naming. For example, a prefix of \`"segment_"\` would produce files named \`"segment_0.ts"\`, \`"segment_1.ts"\` and so on. This is optional, and defaults to the base name of the input file. Also see the related \`segment_name\` parameter. `), - segment_name: z.string().default('').describe(` + segment_name: z + .string() + .default('') + .describe(` The name used for the final segment. Available variables are \`\${segment_prefix}\`, \`\${segment_number}\` and \`\${segment_id}\` (which is a UUIDv4 without dashes). `), - segment_time_delta: z.number().optional().describe(` + segment_time_delta: z + .number() + .optional() + .describe(` Delta to apply to segment duration. This is optional and allows fine-tuning of segment boundaries. `), }) diff --git a/src/alphalib/types/robots/audio-artwork.ts b/src/alphalib/types/robots/audio-artwork.ts index 3c45813a..f806d522 100644 --- a/src/alphalib/types/robots/audio-artwork.ts +++ b/src/alphalib/types/robots/audio-artwork.ts @@ -58,10 +58,16 @@ If you need the image in a different format, pipe the result of this Robot< The \`method\` parameter determines whether to extract or insert. `), - method: z.enum(['extract', 'insert']).default('extract').describe(` + method: z + .enum(['extract', 'insert']) + .default('extract') + .describe(` What should be done with the audio file. A value of \`"extract"\` means audio artwork will be extracted. A value of \`"insert"\` means the provided image will be inserted as audio artwork. `), - change_format_if_necessary: z.boolean().default(false).describe(` + change_format_if_necessary: z + .boolean() + .default(false) + .describe(` Whether the original file should be transcoded into a new format if there is an issue with the original file. `), }) diff --git a/src/alphalib/types/robots/audio-concat.ts b/src/alphalib/types/robots/audio-concat.ts index 8310495d..f70ab7a8 100644 --- a/src/alphalib/types/robots/audio-concat.ts +++ b/src/alphalib/types/robots/audio-concat.ts @@ -84,12 +84,18 @@ Bit rate of the resulting audio file, in bits per second. If not specified will sample_rate: sampleRateSchema.optional().describe(` Sample rate of the resulting audio file, in Hertz. If not specified will default to the sample rate of the input audio file. `), - audio_fade_seconds: z.number().default(1).describe(` + audio_fade_seconds: z + .number() + .default(1) + .describe(` When used this adds an audio fade in and out effect between each section of your concatenated audio file. The float value is used, so if you want an audio delay effect of 500 milliseconds between each video section, you would select 0.5. Integer values can also be represented. This parameter does not add an audio fade effect at the beginning or end of your result audio file. If you want to do so, create an additional [🤖/audio/encode](/docs/robots/audio-encode/) Step and use our \`ffmpeg\` parameter as shown in this [demo](/demos/audio-encoding/ffmpeg-fade-in-and-out/). `), - crossfade: z.boolean().default(false).describe(` + crossfade: z + .boolean() + .default(false) + .describe(` When set to \`true\`, this parameter enables crossfading between concatenated audio files using FFmpeg's \`acrossfade\` filter. This creates a smooth transition where the end of one audio file overlaps and blends with the beginning of the next file. The duration of the crossfade is controlled by the \`audio_fade_seconds\` parameter (defaults to 1 second if \`audio_fade_seconds\` is 0). diff --git a/src/alphalib/types/robots/audio-loop.ts b/src/alphalib/types/robots/audio-loop.ts index 37d395e7..81210db3 100644 --- a/src/alphalib/types/robots/audio-loop.ts +++ b/src/alphalib/types/robots/audio-loop.ts @@ -62,7 +62,10 @@ Bit rate of the resulting audio file, in bits per second. If not specified will sample_rate: sampleRateSchema.optional().describe(` Sample rate of the resulting audio file, in Hertz. If not specified will default to the sample rate of the input audio file. `), - duration: z.number().default(60).describe(` + duration: z + .number() + .default(60) + .describe(` Target duration for the whole process in seconds. The Robot will loop the input audio file for as long as this target duration is not reached yet. `), }) diff --git a/src/alphalib/types/robots/audio-merge.ts b/src/alphalib/types/robots/audio-merge.ts index 214174d9..76975750 100644 --- a/src/alphalib/types/robots/audio-merge.ts +++ b/src/alphalib/types/robots/audio-merge.ts @@ -79,13 +79,22 @@ Bit rate of the resulting audio file, in bits per second. If not specified will sample_rate: sampleRateSchema.optional().describe(` Sample rate of the resulting audio file, in Hertz. If not specified will default to the sample rate of the input audio file. `), - duration: z.enum(['first', 'longest', 'shortest']).default('longest').describe(` + duration: z + .enum(['first', 'longest', 'shortest']) + .default('longest') + .describe(` Duration of the output file compared to the duration of all merged audio files. Can be \`"first"\` (duration of the first input file), \`"shortest"\` (duration of the shortest audio file) or \`"longest"\` for the duration of the longest input file. `), - loop: z.boolean().default(false).describe(` + loop: z + .boolean() + .default(false) + .describe(` Specifies if any input files that do not match the target duration should be looped to match it. Useful for audio merging where your overlay file is typically much shorter than the main audio file. `), - volume: z.enum(['average', 'sum']).default('average').describe(` + volume: z + .enum(['average', 'sum']) + .default('average') + .describe(` Valid values are \`"average"\` and \`"sum"\` here. \`"average"\` means each input is scaled 1/n (n is the number of inputs) or \`"sum"\` which means each individual audio stays on the same volume, but since we merge tracks 'on top' of each other, this could result in very loud output. `), }) diff --git a/src/alphalib/types/robots/audio-waveform.ts b/src/alphalib/types/robots/audio-waveform.ts index 35a8e632..c62ed220 100644 --- a/src/alphalib/types/robots/audio-waveform.ts +++ b/src/alphalib/types/robots/audio-waveform.ts @@ -66,19 +66,38 @@ We recommend that you use an [🤖/audio/encode](/docs/robots/audio-encode/) Robot into [🤖/image/resize](/docs/robots/image-resize/). `), - format: z.enum(['image', 'json']).default('image').describe(` + format: z + .enum(['image', 'json']) + .default('image') + .describe(` The format of the result file. Can be \`"image"\` or \`"json"\`. If \`"image"\` is supplied, a PNG image will be created, otherwise a JSON file. `), - width: z.number().int().min(1).default(256).describe(` + width: z + .number() + .int() + .min(1) + .default(256) + .describe(` The width of the resulting image if the format \`"image"\` was selected. `), - height: z.number().int().min(1).default(64).describe(` + height: z + .number() + .int() + .min(1) + .default(64) + .describe(` The height of the resulting image if the format \`"image"\` was selected. `), - style: z.union([z.literal(0), z.literal(1)]).default(0).describe(` + style: z + .union([z.literal(0), z.literal(1)]) + .default(0) + .describe(` Either a value of \`0\` or \`1\`, corresponding to using either the legacy waveform tool, or the new tool respectively, with the new tool offering an improved style. Other Robot parameters still function as described, with either tool. `), - antialiasing: z.union([z.literal(0), z.literal(1), z.boolean()]).default(0).describe(` + antialiasing: z + .union([z.literal(0), z.literal(1), z.boolean()]) + .default(0) + .describe(` Either a value of \`0\` or \`1\`, or \`true\`/\`false\`, corresponding to if you want to enable antialiasing to achieve smoother edges in the waveform graph or not. `), background_color: color_with_alpha.default('#00000000').describe(` diff --git a/src/alphalib/types/robots/azure-store.ts b/src/alphalib/types/robots/azure-store.ts index bed75d76..de107d3d 100644 --- a/src/alphalib/types/robots/azure-store.ts +++ b/src/alphalib/types/robots/azure-store.ts @@ -46,29 +46,55 @@ export const robotAzureStoreInstructionsSchema = robotBase .merge(azureBase) .extend({ robot: z.literal('/azure/store'), - path: z.string().default('${unique_prefix}/${file.url_name}').describe(` + path: z + .string() + .default('${unique_prefix}/${file.url_name}') + .describe(` The path at which the file is to be stored. This may include any available [Assembly variables](/docs/topics/assembly-instructions/#assembly-variables). `), - content_type: z.string().optional().describe(` + content_type: z + .string() + .optional() + .describe(` The content type with which to store the file. By default this will be guessed by Azure. `), - content_encoding: z.string().optional().describe(` + content_encoding: z + .string() + .optional() + .describe(` The content encoding with which to store the file. By default this will be guessed by Azure. `), - content_language: z.string().optional().describe(` + content_language: z + .string() + .optional() + .describe(` The content language with which to store the file. By default this will be guessed by Azure. `), - content_disposition: z.string().optional().describe(` + content_disposition: z + .string() + .optional() + .describe(` The content disposition with which to store the file. By default this will be guessed by Azure. `), - cache_control: z.string().optional().describe(` + cache_control: z + .string() + .optional() + .describe(` The cache control header with which to store the file. `), // TODO: verify if this is correct. - metadata: z.record(z.string()).default({}).describe(` + metadata: z + .record(z.string()) + .default({}) + .describe(` A JavaScript object containing a list of metadata to be set for this file on Azure, such as \`{ FileURL: "\${file.url_name}" }\`. This can also include any available [Assembly variables](/docs/topics/assembly-instructions/#assembly-variables). `), - sas_expires_in: z.number().int().min(0).optional().describe(` + sas_expires_in: z + .number() + .int() + .min(0) + .optional() + .describe(` Set this to a number to enable shared access signatures for your stored object. This reflects the number of seconds that the signature will be valid for once the object is stored. Enabling this will attach the shared access signature (SAS) to the result URL of your object. `), sas_permissions: z @@ -76,7 +102,8 @@ Set this to a number to enable shared access signatures for your stored object. .regex(/^[rdw]+$/) .min(0) .max(3) - .optional().describe(` + .optional() + .describe(` Set this to a combination of \`r\` (read), \`w\` (write) and \`d\` (delete) for your shared access signatures (SAS) permissions. `), }) diff --git a/src/alphalib/types/robots/backblaze-import.ts b/src/alphalib/types/robots/backblaze-import.ts index 77d60b15..a9fee98a 100644 --- a/src/alphalib/types/robots/backblaze-import.ts +++ b/src/alphalib/types/robots/backblaze-import.ts @@ -71,7 +71,10 @@ Setting this to \`true\` will enable importing files from subdirectories and sub Please use the pagination parameters \`start_file_name\` and \`files_per_page\` wisely here. `), - start_file_name: z.string().default('').describe(` + start_file_name: z + .string() + .default('') + .describe(` The name of the last file from the previous paging call. This tells the Robot to ignore all files up to and including this file. `), files_per_page: files_per_page.describe(` diff --git a/src/alphalib/types/robots/backblaze-store.ts b/src/alphalib/types/robots/backblaze-store.ts index 09158a9d..d0c499ba 100644 --- a/src/alphalib/types/robots/backblaze-store.ts +++ b/src/alphalib/types/robots/backblaze-store.ts @@ -51,10 +51,16 @@ export const robotBackblazeStoreInstructionsSchema = robotBase .merge(backblazeBase) .extend({ robot: z.literal('/backblaze/store'), - path: z.string().default('${unique_prefix}/${file.url_name}').describe(` + path: z + .string() + .default('${unique_prefix}/${file.url_name}') + .describe(` The path at which the file is to be stored. This may include any available [Assembly variables](/docs/topics/assembly-instructions/#assembly-variables). `), - headers: z.record(z.string()).default({}).describe(` + headers: z + .record(z.string()) + .default({}) + .describe(` An object containing a list of headers to be set for this file on backblaze, such as \`{ FileURL: "\${file.url_name}" }\`. This can also include any available [Assembly Variables](/docs/topics/assembly-instructions/#assembly-variables). [Here](https://www.backblaze.com/b2/docs/b2_upload_file.html) you can find a list of available headers. diff --git a/src/alphalib/types/robots/cloudfiles-import.ts b/src/alphalib/types/robots/cloudfiles-import.ts index 6d5f1ca2..a8147f10 100644 --- a/src/alphalib/types/robots/cloudfiles-import.ts +++ b/src/alphalib/types/robots/cloudfiles-import.ts @@ -63,7 +63,10 @@ Directories are **not** imported recursively. If you want to import files from s You can also use an array of path strings here to import multiple paths in the same Robot's Step. `), - recursive: z.boolean().default(false).describe(` + recursive: z + .boolean() + .default(false) + .describe(` Setting this to \`true\` will enable importing files from subdirectories and sub-subdirectories (etc.) of the given path. Please use the pagination parameters \`page_number\` and \`files_per_page\`wisely here. diff --git a/src/alphalib/types/robots/cloudfiles-store.ts b/src/alphalib/types/robots/cloudfiles-store.ts index d65c0c30..3f6440bf 100644 --- a/src/alphalib/types/robots/cloudfiles-store.ts +++ b/src/alphalib/types/robots/cloudfiles-store.ts @@ -60,7 +60,10 @@ export const robotCloudfilesStoreInstructionsSchema = robotBase .merge(cloudfilesBase) .extend({ robot: z.literal('/cloudfiles/store'), - path: z.string().default('${unique_prefix}/${file.url_name}').describe(` + path: z + .string() + .default('${unique_prefix}/${file.url_name}') + .describe(` The path at which to store the file. This value can also contain [Assembly variables](/docs/topics/assembly-instructions/#assembly-variables). `), }) diff --git a/src/alphalib/types/robots/cloudflare-store.ts b/src/alphalib/types/robots/cloudflare-store.ts index 8f3ea35c..e1573f81 100644 --- a/src/alphalib/types/robots/cloudflare-store.ts +++ b/src/alphalib/types/robots/cloudflare-store.ts @@ -54,18 +54,32 @@ export const robotCloudflareStoreInstructionsSchema = robotBase .merge(cloudflareBase) .extend({ robot: z.literal('/cloudflare/store'), - path: z.string().default('${unique_prefix}/${file.url_name}').describe(` + path: z + .string() + .default('${unique_prefix}/${file.url_name}') + .describe(` The path at which the file is to be stored. This may include any available [Assembly variables](/docs/topics/assembly-instructions/#assembly-variables). The path must not be a directory. `), - headers: z.record(z.string()).default({ 'Content-Type': '${file.mime}' }).describe(` + headers: z + .record(z.string()) + .default({ 'Content-Type': '${file.mime}' }) + .describe(` An object containing a list of headers to be set for this file on cloudflare Spaces, such as \`{ FileURL: "\${file.url_name}" }\`. This can also include any available [Assembly Variables](/docs/topics/assembly-instructions/#assembly-variables). Object Metadata can be specified using \`x-amz-meta-*\` headers. Note that these headers [do not support non-ASCII metadata values](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html#UserMetadata). `), - sign_urls_for: z.number().int().min(0).optional().describe(` + sign_urls_for: z + .number() + .int() + .min(0) + .optional() + .describe(` This parameter provides signed URLs in the result JSON (in the \`signed_ssl_url\` property). The number that you set this parameter to is the URL expiry time in seconds. If this parameter is not used, no URL signing is done. `), - url_prefix: z.string().optional().describe(` + url_prefix: z + .string() + .optional() + .describe(` The URL prefix used for accessing files from your Cloudflare R2 bucket. This is typically the custom public URL access host set up in your Cloudflare account. `), }) diff --git a/src/alphalib/types/robots/digitalocean-store.ts b/src/alphalib/types/robots/digitalocean-store.ts index a0cdbfd6..4111013d 100644 --- a/src/alphalib/types/robots/digitalocean-store.ts +++ b/src/alphalib/types/robots/digitalocean-store.ts @@ -51,23 +51,40 @@ export const robotDigitaloceanStoreInstructionsSchema = robotBase .merge(digitalOceanBase) .extend({ robot: z.literal('/digitalocean/store'), - path: z.string().default('${unique_prefix}/${file.url_name}').describe(` + path: z + .string() + .default('${unique_prefix}/${file.url_name}') + .describe(` The path at which the file is to be stored. This may include any available [Assembly variables](/docs/topics/assembly-instructions/#assembly-variables). The path must not be a directory. `), - url_prefix: z.string().default('https://{space}.{region}.digitaloceanspaces.com/').describe(` + url_prefix: z + .string() + .default('https://{space}.{region}.digitaloceanspaces.com/') + .describe(` The URL prefix used for the returned URL, such as \`"https://my.cdn.com/some/path"\`. `), - acl: z.enum(['private', 'public-read']).default('public-read').describe(` + acl: z + .enum(['private', 'public-read']) + .default('public-read') + .describe(` The permissions used for this file. `), - headers: z.record(z.string()).default({ 'Content-Type': '${file.mime}' }).describe(` + headers: z + .record(z.string()) + .default({ 'Content-Type': '${file.mime}' }) + .describe(` An object containing a list of headers to be set for this file on DigitalOcean Spaces, such as \`{ FileURL: "\${file.url_name}" }\`. This can also include any available [Assembly Variables](/docs/topics/assembly-instructions/#assembly-variables). [Here](https://developers.digitalocean.com/documentation/spaces/#object) you can find a list of available headers. Object Metadata can be specified using \`x-amz-meta-*\` headers. Note that these headers [do not support non-ASCII metadata values](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html#UserMetadata). `), - sign_urls_for: z.number().int().min(0).optional().describe(` + sign_urls_for: z + .number() + .int() + .min(0) + .optional() + .describe(` This parameter provides signed URLs in the result JSON (in the \`signed_ssl_url\` property). The number that you set this parameter to is the URL expiry time in seconds. If this parameter is not used, no URL signing is done. `), }) diff --git a/src/alphalib/types/robots/document-convert.ts b/src/alphalib/types/robots/document-convert.ts index 705e9ff5..49a43a23 100644 --- a/src/alphalib/types/robots/document-convert.ts +++ b/src/alphalib/types/robots/document-convert.ts @@ -141,75 +141,96 @@ The following file formats can be converted from: - \`xlsx\` - \`xml\` `), - format: z.enum([ - 'ai', - 'csv', - 'doc', - 'docx', - 'eps', - 'gif', - 'html', - 'jpeg', - 'jpg', - 'latex', - 'oda', - 'odd', - 'odt', - 'ott', - 'pdf', - 'png', - 'pot', - 'pps', - 'ppt', - 'pptx', - 'ppz', - 'ps', - 'rtf', - 'rtx', - 'srt', - 'svg', - 'text', - 'txt', - 'vtt', - 'xhtml', - 'xla', - 'xls', - 'xlsx', - 'xml', - ]).describe(` + format: z + .enum([ + 'ai', + 'csv', + 'doc', + 'docx', + 'eps', + 'gif', + 'html', + 'jpeg', + 'jpg', + 'latex', + 'oda', + 'odd', + 'odt', + 'ott', + 'pdf', + 'png', + 'pot', + 'pps', + 'ppt', + 'pptx', + 'ppz', + 'ps', + 'rtf', + 'rtx', + 'srt', + 'svg', + 'text', + 'txt', + 'vtt', + 'xhtml', + 'xla', + 'xls', + 'xlsx', + 'xml', + ]) + .describe(` The desired format for document conversion. `), - markdown_format: z.enum(['commonmark', 'gfm']).default('gfm').describe(` + markdown_format: z + .enum(['commonmark', 'gfm']) + .default('gfm') + .describe(` Markdown can be represented in several [variants](https://www.iana.org/assignments/markdown-variants/markdown-variants.xhtml), so when using this Robot to transform Markdown into HTML please specify which revision is being used. `), - markdown_theme: z.enum(['bare', 'github']).default('github').describe(` + markdown_theme: z + .enum(['bare', 'github']) + .default('github') + .describe(` This parameter overhauls your Markdown files styling based on several canned presets. `), - pdf_margin: z.string().default('6.25mm,6.25mm,14.11mm,6.25mm').describe(` + pdf_margin: z + .string() + .default('6.25mm,6.25mm,14.11mm,6.25mm') + .describe(` PDF Paper margins, separated by \`,\` and with units. We support the following unit values: \`px\`, \`in\`, \`cm\`, \`mm\`. Currently this parameter is only supported when converting from \`html\`. `), - pdf_print_background: z.boolean().default(true).describe(` + pdf_print_background: z + .boolean() + .default(true) + .describe(` Print PDF background graphics. Currently this parameter is only supported when converting from \`html\`. `), pdf_format: z .enum(['A0', 'A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'Ledger', 'Legal', 'Letter', 'Tabloid']) - .default('Letter').describe(` + .default('Letter') + .describe(` PDF paper format. Currently this parameter is only supported when converting from \`html\`. `), - pdf_display_header_footer: z.boolean().default(false).describe(` + pdf_display_header_footer: z + .boolean() + .default(false) + .describe(` Display PDF header and footer. Currently this parameter is only supported when converting from \`html\`. `), - pdf_header_template: z.string().optional().describe(` + pdf_header_template: z + .string() + .optional() + .describe(` HTML template for the PDF print header. Should be valid HTML markup with following classes used to inject printing values into them: @@ -227,7 +248,10 @@ To change the formatting of the HTML element, the \`font-size\` must be specifie
\`\`\` `), - pdf_footer_template: z.string().optional().describe(` + pdf_footer_template: z + .string() + .optional() + .describe(` HTML template for the PDF print footer. Should use the same format as the \`pdf_header_template\`. diff --git a/src/alphalib/types/robots/document-merge.ts b/src/alphalib/types/robots/document-merge.ts index df315baf..9f905ee4 100644 --- a/src/alphalib/types/robots/document-merge.ts +++ b/src/alphalib/types/robots/document-merge.ts @@ -61,14 +61,20 @@ export const robotDocumentMergeInstructionsSchema = robotBase .merge(robotUse) .extend({ robot: z.literal('/document/merge'), - input_passwords: z.array(z.string()).default([]).describe(` + input_passwords: z + .array(z.string()) + .default([]) + .describe(` An array of passwords for the input documents, in case they are encrypted. The order of passwords must match the order of the documents as they are passed to the /document/merge step. This can be achieved via our as-syntax using "document_1", "document_2", etc if provided. See the demos below. If the as-syntax is not used in the "use" parameter, the documents are sorted alphanumerically based on their filename, and in that order input passwords should be provided. `), - output_password: z.string().optional().describe(` + output_password: z + .string() + .optional() + .describe(` If not empty, encrypts the output file and makes it accessible only by typing in this password. `), }) diff --git a/src/alphalib/types/robots/document-ocr.ts b/src/alphalib/types/robots/document-ocr.ts index 9ea30a2e..f8245174 100644 --- a/src/alphalib/types/robots/document-ocr.ts +++ b/src/alphalib/types/robots/document-ocr.ts @@ -74,7 +74,10 @@ AWS supports detection for the following languages: English, Arabic, Russian, Ge granularity: granularitySchema.describe(` Whether to return a full response including coordinates for the text (\`"full"\`), or a flat list of the extracted phrases (\`"list"\`). This parameter has no effect if the \`format\` parameter is set to \`"text"\`. `), - format: z.enum(['json', 'meta', 'text']).default('json').describe(` + format: z + .enum(['json', 'meta', 'text']) + .default('json') + .describe(` In what format to return the extracted text. - \`"json"\` returns a JSON file. - \`"meta"\` does not return a file, but stores the data inside Transloadit's file object (under \`\${file.meta.recognized_text}\`, which is an array of strings) that's passed around between encoding Steps, so that you can use the values to burn the data into videos, filter on them, etc. diff --git a/src/alphalib/types/robots/document-thumbs.ts b/src/alphalib/types/robots/document-thumbs.ts index e7117ea9..e9096f23 100644 --- a/src/alphalib/types/robots/document-thumbs.ts +++ b/src/alphalib/types/robots/document-thumbs.ts @@ -60,37 +60,70 @@ export const robotDocumentThumbsInstructionsSchema = robotBase - If you convert a multi-page PDF file into several images, all result images will be sorted with the first image being the thumbnail of the first document page, etc. - You can also check the \`meta.thumb_index\` key of each result image to find out which page it corresponds to. Keep in mind that these thumb indices **start at 0,** not at 1. `), - page: z.number().int().nullable().default(null).describe(` + page: z + .number() + .int() + .nullable() + .default(null) + .describe(` The PDF page that you want to convert to an image. By default the value is \`null\` which means that all pages will be converted into images. `), - format: z.enum(['gif', 'jpeg', 'jpg', 'png']).default('png').describe(` + format: z + .enum(['gif', 'jpeg', 'jpg', 'png']) + .default('png') + .describe(` The format of the extracted image(s). If you specify the value \`"gif"\`, then an animated gif cycling through all pages is created. Please check out [this demo](/demos/document-processing/convert-all-pages-of-a-document-into-an-animated-gif/) to learn more about this. `), - delay: z.number().int().min(0).optional().describe(` + delay: z + .number() + .int() + .min(0) + .optional() + .describe(` If your output format is \`"gif"\` then this parameter sets the number of 100th seconds to pass before the next frame is shown in the animation. Set this to \`100\` for example to allow 1 second to pass between the frames of the animated gif. If your output format is not \`"gif"\`, then this parameter does not have any effect. `), - width: z.number().int().min(1).max(5000).optional().describe(` + width: z + .number() + .int() + .min(1) + .max(5000) + .optional() + .describe(` Width of the new image, in pixels. If not specified, will default to the width of the input image `), - height: z.number().int().min(1).max(5000).optional().describe(` + height: z + .number() + .int() + .min(1) + .max(5000) + .optional() + .describe(` Height of the new image, in pixels. If not specified, will default to the height of the input image `), - resize_strategy: z.enum(['crop', 'fillcrop', 'fit', 'min_fit', 'pad', 'stretch']).default('pad') + resize_strategy: z + .enum(['crop', 'fillcrop', 'fit', 'min_fit', 'pad', 'stretch']) + .default('pad') .describe(` One of the [available resize strategies](/docs/topics/resize-strategies/). `), // TODO: Determine the allowed colors - background: z.string().default('#FFFFFF').describe(` + background: z + .string() + .default('#FFFFFF') + .describe(` Either the hexadecimal code or [name](https://www.imagemagick.org/script/color.php#color_names) of the color used to fill the background (only used for the pad resize strategy). By default, the background of transparent images is changed to white. For details about how to preserve transparency across all image types, see [this demo](/demos/image-manipulation/properly-preserve-transparency-across-all-image-types/). `), // TODO: Update options list. Why are they capitalized? They are lowercase in th ImageMagick docs. - alpha: z.enum(['Remove', 'Set']).optional().describe(` + alpha: z + .enum(['Remove', 'Set']) + .optional() + .describe(` Change how the alpha channel of the resulting image should work. Valid values are \`"Set"\` to enable transparency and \`"Remove"\` to remove transparency. For a list of all valid values please check the ImageMagick documentation [here](http://www.imagemagick.org/script/command-line-options.php#alpha). @@ -98,14 +131,18 @@ For a list of all valid values please check the ImageMagick documentation [here] density: z .string() .regex(/\d+(x\d+)?/) - .optional().describe(` + .optional() + .describe(` While in-memory quality and file format depth specifies the color resolution, the density of an image is the spatial (space) resolution of the image. That is the density (in pixels per inch) of an image and defines how far apart (or how big) the individual pixels are. It defines the size of the image in real world terms when displayed on devices or printed. You can set this value to a specific \`width\` or in the format \`width\`x\`height\`. If your converted image has a low resolution, please try using the density parameter to resolve that. `), - antialiasing: z.boolean().default(false).describe(` + antialiasing: z + .boolean() + .default(false) + .describe(` Controls whether or not antialiasing is used to remove jagged edges from text or images in a document. `), colorspace: colorspaceSchema.optional().describe(` @@ -113,12 +150,18 @@ Sets the image colorspace. For details about the available values, see the [Imag Please note that if you were using \`"RGB"\`, we recommend using \`"sRGB"\`. ImageMagick might try to find the most efficient \`colorspace\` based on the color of an image, and default to e.g. \`"Gray"\`. To force colors, you might then have to use this parameter. `), - trim_whitespace: z.boolean().default(true).describe(` + trim_whitespace: z + .boolean() + .default(true) + .describe(` This determines if additional whitespace around the PDF should first be trimmed away before it is converted to an image. If you set this to \`true\` only the real PDF page contents will be shown in the image. If you need to reflect the PDF's dimensions in your image, it is generally a good idea to set this to \`false\`. `), - pdf_use_cropbox: z.boolean().default(true).describe(` + pdf_use_cropbox: z + .boolean() + .default(true) + .describe(` Some PDF documents lie about their dimensions. For instance they'll say they are landscape, but when opened in decent Desktop readers, it's really in portrait mode. This can happen if the document has a cropbox defined. When this option is enabled (by default), the cropbox is leading in determining the dimensions of the resulting thumbnails. `), }) @@ -129,17 +172,24 @@ export const robotDocumentThumbsInstructionsWithHiddenFieldsSchema = result: z .union([z.literal('debug'), robotDocumentThumbsInstructionsSchema.shape.result]) .optional(), - stack: z.string().optional().describe(` + stack: z + .string() + .optional() + .describe(` The image processing stack to use. Defaults to the robot's preferred stack (ImageMagick). `), // Override to support lowercase for BC: - alpha: z.enum(['Remove', 'Set', 'remove', 'set']).optional().describe(` + alpha: z + .enum(['Remove', 'Set', 'remove', 'set']) + .optional() + .describe(` Change how the alpha channel of the resulting image should work. Valid values are \`"Set"\` to enable transparency and \`"Remove"\` to remove transparency. Lowercase values are also accepted for backwards compatibility. `), // Override to support 'none' for BC resize_strategy: z .enum(['crop', 'fillcrop', 'fit', 'min_fit', 'pad', 'stretch', 'none']) - .optional().describe(` + .optional() + .describe(` One of the [available resize strategies](/docs/transcoding/image-manipulation/image-resize/#resize-strategies). The 'none' value is supported for backwards compatibility. `), }) diff --git a/src/alphalib/types/robots/dropbox-store.ts b/src/alphalib/types/robots/dropbox-store.ts index d5f75a43..487044b6 100644 --- a/src/alphalib/types/robots/dropbox-store.ts +++ b/src/alphalib/types/robots/dropbox-store.ts @@ -46,10 +46,16 @@ export const robotDropboxStoreInstructionsSchema = robotBase .merge(dropboxBase) .extend({ robot: z.literal('/dropbox/store'), - path: z.string().default('${unique_prefix}/${file.url_name}').describe(` + path: z + .string() + .default('${unique_prefix}/${file.url_name}') + .describe(` The path at which the file is to be stored. This may include any available [Assembly variables](/docs/topics/assembly-instructions/#assembly-variables). `), - create_sharing_link: z.boolean().default(false).describe(` + create_sharing_link: z + .boolean() + .default(false) + .describe(` Whether to create a URL to this file for sharing with other people. This will overwrite the file's \`"url"\` property. `), }) diff --git a/src/alphalib/types/robots/file-compress.ts b/src/alphalib/types/robots/file-compress.ts index 1f65aaa2..16f4dc9b 100644 --- a/src/alphalib/types/robots/file-compress.ts +++ b/src/alphalib/types/robots/file-compress.ts @@ -82,30 +82,52 @@ export const robotFileCompressInstructionsSchema = robotBase .merge(robotUse) .extend({ robot: z.literal('/file/compress'), - format: z.enum(['tar', 'zip']).default('tar').describe(` + format: z + .enum(['tar', 'zip']) + .default('tar') + .describe(` The format of the archive to be created. Supported values are \`"tar"\` and \`"zip"\`. Note that \`"tar"\` without setting \`gzip\` to \`true\` results in an archive that's not compressed in any way. `), - gzip: z.boolean().default(false).describe(` + gzip: z + .boolean() + .default(false) + .describe(` Determines if the result archive should also be gzipped. Gzip compression is only applied if you use the \`"tar"\` format. `), - password: z.string().nullable().default(null).describe(` + password: z + .string() + .nullable() + .default(null) + .describe(` This allows you to encrypt all archive contents with a password and thereby protect it against unauthorized use. To unzip the archive, the user will need to provide the password in a text input field prompt. This parameter has no effect if the format parameter is anything other than \`"zip"\`. `), - compression_level: z.number().int().min(-9).max(0).default(-6).describe(` + compression_level: z + .number() + .int() + .min(-9) + .max(0) + .default(-6) + .describe(` Determines how fiercely to try to compress the archive. \`-0\` is compressionless, which is suitable for media that is already compressed. \`-1\` is fastest with lowest compression. \`-9\` is slowest with the highest compression. If you are using \`-0\` in combination with the \`tar\` format with \`gzip\` enabled, consider setting \`gzip: false\` instead. This results in a plain Tar archive, meaning it already has no compression. `), - file_layout: z.enum(['advanced', 'simple', 'relative-path']).default('advanced').describe(` + file_layout: z + .enum(['advanced', 'simple', 'relative-path']) + .default('advanced') + .describe(` Determines if the result archive should contain all files in one directory (value for this is \`"simple"\`) or in subfolders according to the explanation below (value for this is \`"advanced"\`). The \`"relative-path"\` option preserves the relative directory structure of the input files. Files with same names are numbered in the \`"simple"\` file layout to avoid naming collisions. `), - archive_name: z.string().optional().describe(` + archive_name: z + .string() + .optional() + .describe(` The name of the archive file to be created (without the file extension). `), }) diff --git a/src/alphalib/types/robots/file-decompress.ts b/src/alphalib/types/robots/file-decompress.ts index eb147bc0..368b571d 100644 --- a/src/alphalib/types/robots/file-decompress.ts +++ b/src/alphalib/types/robots/file-decompress.ts @@ -80,7 +80,8 @@ For security reasons, archives that contain symlinks to outside the archived dir .transform((ignoreErrors): 'meta'[] => ignoreErrors === true ? ['meta'] : ignoreErrors === false ? [] : ignoreErrors, ) - .default([]).describe(` + .default([]) + .describe(` A possible array member is only \`"meta"\`. You might see an error when trying to extract metadata from the files inside your archive. This happens, for example, for files with a size of zero bytes. Setting this to \`true\` will cause the Robot to not stop the file decompression (and the entire Assembly) when that happens. diff --git a/src/alphalib/types/robots/file-filter.ts b/src/alphalib/types/robots/file-filter.ts index 71e2af4d..edd699ab 100644 --- a/src/alphalib/types/robots/file-filter.ts +++ b/src/alphalib/types/robots/file-filter.ts @@ -118,13 +118,22 @@ If \`accepts\` and \`declines\` are both provided, the requirements in \`accepts `, ) .optional(), - condition_type: z.enum(['and', 'or']).default('or').describe(` + condition_type: z + .enum(['and', 'or']) + .default('or') + .describe(` Specifies the condition type according to which the members of the \`accepts\` or \`declines\` arrays should be evaluated. Can be \`"or"\` or \`"and"\`. `), - error_on_decline: z.boolean().default(false).describe(` + error_on_decline: z + .boolean() + .default(false) + .describe(` If this is set to \`true\` and one or more files are declined, the Assembly will be stopped and marked with an error. `), - error_msg: z.string().default('One of your files was declined').describe(` + error_msg: z + .string() + .default('One of your files was declined') + .describe(` The error message shown to your users (such as by Uppy) when a file is declined and \`error_on_decline\` is set to \`true\`. `), }) diff --git a/src/alphalib/types/robots/file-hash.ts b/src/alphalib/types/robots/file-hash.ts index 29a3269b..7eeb1003 100644 --- a/src/alphalib/types/robots/file-hash.ts +++ b/src/alphalib/types/robots/file-hash.ts @@ -46,7 +46,8 @@ This Robot allows you to hash any file as part of the AssemblyRobot always generates a preview image with the predefined dimensions and formats, to allow an easy integration into your application's UI. In addition, the generated preview images are optimized by default to reduce their file size while keeping their quality. `), - format: z.enum(['gif', 'jpg', 'png']).default('png').describe(` + format: z + .enum(['gif', 'jpg', 'png']) + .default('png') + .describe(` The output format for the generated thumbnail image. If a short video clip is generated using the \`clip\` strategy, its format is defined by \`clip_format\`. `), width: complexWidthSchema.default(300).describe(` @@ -90,7 +93,8 @@ The hexadecimal code of the color used to fill the background (only used for the video: z.array(z.string()).default(['artwork', 'frame', 'icon']), webpage: z.array(z.string()).default(['render', 'icon']), }) - .optional().describe(` + .optional() + .describe(` Definition of the thumbnail generation process per file category. The parameter must be an object whose keys can be one of the file categories: \`audio\`, \`video\`, \`image\`, \`document\`, \`archive\`, \`webpage\`, and \`unknown\`. The corresponding value is an array of strategies for the specific file category. See the above section for a list of all available strategies. For each file, the Robot will attempt to use the first strategy to generate the thumbnail. If this process fails (e.g., because no artwork is available in a video file), the next strategy is attempted. This is repeated until either a thumbnail is generated or the list is exhausted. Selecting the \`icon\` strategy as the last entry provides a fallback mechanism to ensure that an appropriate strategy is always available. @@ -121,13 +125,28 @@ The color used in the center of the waveform's gradient. The format is \`#rrggbb waveform_outer_color: color_with_alpha.default('#000000ff').describe(` The color used in the outer parts of the waveform's gradient. The format is \`#rrggbb[aa]\` (red, green, blue, alpha). Only used if the \`waveform\` strategy for audio files is applied. `), - waveform_height: z.number().int().min(1).max(5000).default(100).describe(` + waveform_height: z + .number() + .int() + .min(1) + .max(5000) + .default(100) + .describe(` Height of the waveform, in pixels. Only used if the \`waveform\` strategy for audio files is applied. It can be utilized to ensure that the waveform only takes up a section of the preview thumbnail. `), - waveform_width: z.number().int().min(1).max(5000).default(300).describe(` + waveform_width: z + .number() + .int() + .min(1) + .max(5000) + .default(300) + .describe(` Width of the waveform, in pixels. Only used if the \`waveform\` strategy for audio files is applied. It can be utilized to ensure that the waveform only takes up a section of the preview thumbnail. `), - icon_style: z.enum(['square', 'with-text']).default('with-text').describe(` + icon_style: z + .enum(['square', 'with-text']) + .default('with-text') + .describe(` The style of the icon generated if the \`icon\` strategy is applied. The default style, \`with-text\`, includes an icon showing the file type and a text box below it, whose content can be controlled by the \`icon_text_content\` parameter and defaults to the file extension (e.g. MP4, JPEG). The \`square\` style only includes a square variant of the icon showing the file type. Below are exemplary previews generated for a text file utilizing the different styles:

\`with-text\` style:
@@ -139,36 +158,68 @@ The style of the icon generated if the \`icon\` strategy is applied. The default The color of the text used in the icon. The format is \`#rrggbb[aa]\`. Only used if the \`icon\` strategy is applied. `), // TODO: Determine the font enum. - icon_text_font: z.string().default('Roboto').describe(` + icon_text_font: z + .string() + .default('Roboto') + .describe(` The font family of the text used in the icon. Only used if the \`icon\` strategy is applied. [Here](/docs/supported-formats/fonts/) is a list of all supported fonts. `), - icon_text_content: z.enum(['extension', 'none']).default('extension').describe(` + icon_text_content: z + .enum(['extension', 'none']) + .default('extension') + .describe(` The content of the text box in generated icons. Only used if the \`icon_style\` parameter is set to \`with-text\`. The default value, \`extension\`, adds the file extension (e.g. MP4, JPEG) to the icon. The value \`none\` can be used to render an empty text box, which is useful if no text should not be included in the raster image, but some place should be reserved in the image for later overlaying custom text over the image using HTML etc. `), - optimize: z.boolean().default(true).describe(` + optimize: z + .boolean() + .default(true) + .describe(` Specifies whether the generated preview image should be optimized to reduce the image's file size while keeping their quaility. If enabled, the images will be optimized using [🤖/image/optimize](/docs/robots/image-optimize/). `), optimize_priority: optimize_priority.describe(` Specifies whether conversion speed or compression ratio is prioritized when optimizing images. Only used if \`optimize\` is enabled. Please see the [🤖/image/optimize documentation](/docs/robots/image-optimize/#param-priority) for more details. `), - optimize_progressive: z.boolean().default(false).describe(` + optimize_progressive: z + .boolean() + .default(false) + .describe(` Specifies whether images should be interlaced, which makes the result image load progressively in browsers. Only used if \`optimize\` is enabled. Please see the [🤖/image/optimize documentation](/docs/robots/image-optimize/#param-progressive) for more details. `), - clip_format: z.enum(['apng', 'avif', 'gif', 'webp']).default('webp').describe(` + clip_format: z + .enum(['apng', 'avif', 'gif', 'webp']) + .default('webp') + .describe(` The animated image format for the generated video clip. Only used if the \`clip\` strategy for video files is applied. Please consult the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Image_types) for detailed information about the image formats and their characteristics. GIF enjoys the broadest support in software, but only supports a limit color palette. APNG supports a variety of color depths, but its lossless compression produces large images for videos. AVIF is a modern image format that offers great compression, but proper support for animations is still lacking in some browsers. WebP on the other hand, enjoys broad support while offering a great balance between small file sizes and good visual quality, making it the default clip format. `), - clip_offset: z.number().min(0).default(1).describe(` + clip_offset: z + .number() + .min(0) + .default(1) + .describe(` The start position in seconds of where the clip is cut. Only used if the \`clip\` strategy for video files is applied. Be aware that for larger video only the first few MBs of the file may be imported to improve speed. Larger offsets may seek to a position outside of the imported part and thus fail to generate a clip. `), - clip_duration: z.number().min(0).default(5).describe(` + clip_duration: z + .number() + .min(0) + .default(5) + .describe(` The duration in seconds of the generated video clip. Only used if the \`clip\` strategy for video files is applied. Be aware that a longer clip duration also results in a larger file size, which might be undesirable for previews. `), - clip_framerate: z.number().int().min(1).max(60).default(5).describe(` + clip_framerate: z + .number() + .int() + .min(1) + .max(60) + .default(5) + .describe(` The framerate of the generated video clip. Only used if the \`clip\` strategy for video files is applied. Be aware that a higher framerate appears smoother but also results in a larger file size, which might be undesirable for previews. `), - clip_loop: z.boolean().default(true).describe(` + clip_loop: z + .boolean() + .default(true) + .describe(` Specifies whether the generated animated image should loop forever (\`true\`) or stop after playing the animation once (\`false\`). Only used if the \`clip\` strategy for video files is applied. `), }) diff --git a/src/alphalib/types/robots/file-serve.ts b/src/alphalib/types/robots/file-serve.ts index 4fab1f71..fba40410 100644 --- a/src/alphalib/types/robots/file-serve.ts +++ b/src/alphalib/types/robots/file-serve.ts @@ -49,17 +49,20 @@ More information on: - [🤖/tlcdn/deliver](/docs/robots/tlcdn-deliver/) pricing. - [File Preview Feature](/blog/2024/06/file-preview-with-smart-cdn/) blog post. `), - headers: z.record(z.string()).default({ - 'Access-Control-Allow-Headers': - 'X-Requested-With, Content-Type, Cache-Control, Accept, Content-Length, Transloadit-Client, Authorization', - 'Access-Control-Allow-Methods': 'POST, GET, PUT, DELETE, OPTIONS', - 'Access-Control-Allow-Origin': '*', - 'Cache-Control': 'public, max-age=259200, s-max-age=86400', - 'Content-Type': '${file.mime}; charset=utf-8', - 'Transfer-Encoding': 'chunked', - 'Transloadit-Assembly': '…', - 'Transloadit-RequestID': '…', - }).describe(` + headers: z + .record(z.string()) + .default({ + 'Access-Control-Allow-Headers': + 'X-Requested-With, Content-Type, Cache-Control, Accept, Content-Length, Transloadit-Client, Authorization', + 'Access-Control-Allow-Methods': 'POST, GET, PUT, DELETE, OPTIONS', + 'Access-Control-Allow-Origin': '*', + 'Cache-Control': 'public, max-age=259200, s-max-age=86400', + 'Content-Type': '${file.mime}; charset=utf-8', + 'Transfer-Encoding': 'chunked', + 'Transloadit-Assembly': '…', + 'Transloadit-RequestID': '…', + }) + .describe(` An object containing a list of headers to be set for a file as we serve it to a CDN/web browser, such as \`{ FileURL: "\${file.url_name}" }\` which will be merged over the defaults, and can include any available [Assembly Variable](/docs/topics/assembly-instructions/#assembly-variables). `), }) diff --git a/src/alphalib/types/robots/file-verify.ts b/src/alphalib/types/robots/file-verify.ts index 9f553053..dc2f13e5 100644 --- a/src/alphalib/types/robots/file-verify.ts +++ b/src/alphalib/types/robots/file-verify.ts @@ -46,13 +46,22 @@ export const robotFileVerifyInstructionsSchema = robotBase .merge(robotUse) .extend({ robot: z.literal('/file/verify'), - error_on_decline: z.boolean().default(false).describe(` + error_on_decline: z + .boolean() + .default(false) + .describe(` If this is set to \`true\` and one or more files are declined, the Assembly will be stopped and marked with an error. `), - error_msg: z.string().default('One of your files was declined').describe(` + error_msg: z + .string() + .default('One of your files was declined') + .describe(` The error message shown to your users (such as by Uppy) when a file is declined and \`error_on_decline\` is set to \`true\`. `), - verify_to_be: z.string().default('pdf').describe(` + verify_to_be: z + .string() + .default('pdf') + .describe(` The type that you want to match against to ensure your file is of this type. For example, \`image\` will verify whether uploaded files are images. This also works against file media types, in this case \`image/png\` would also work to match against specifically \`png\` files. `), }) diff --git a/src/alphalib/types/robots/file-virusscan.ts b/src/alphalib/types/robots/file-virusscan.ts index 9616a546..8ae97e6e 100644 --- a/src/alphalib/types/robots/file-virusscan.ts +++ b/src/alphalib/types/robots/file-virusscan.ts @@ -58,10 +58,16 @@ By default, this Robot excludes all malicious files from further proc We allow the use of industry standard [EICAR files](https://www.eicar.org/download-anti-malware-testfile/) for integration testing without needing to use potentially dangerous live virus samples. `), - error_on_decline: z.boolean().default(false).describe(` + error_on_decline: z + .boolean() + .default(false) + .describe(` If this is set to \`true\` and one or more files are declined, the Assembly will be stopped and marked with an error. `), - error_msg: z.string().default('One of your files was declined').describe(` + error_msg: z + .string() + .default('One of your files was declined') + .describe(` The error message shown to your users (such as by Uppy) when a file is declined and \`error_on_decline\` is set to \`true\`. `), }) @@ -72,7 +78,10 @@ export const robotFileVirusscanInstructionsWithHiddenFieldsSchema = result: z .union([z.literal('debug'), robotFileVirusscanInstructionsSchema.shape.result]) .optional(), - can_use_daemon_fallback: z.boolean().optional().describe(` + can_use_daemon_fallback: z + .boolean() + .optional() + .describe(` Allow the robot to use a daemon fallback mechanism if the primary scanning method fails. `), }) diff --git a/src/alphalib/types/robots/ftp-import.ts b/src/alphalib/types/robots/ftp-import.ts index 074a4e0b..ad7ca846 100644 --- a/src/alphalib/types/robots/ftp-import.ts +++ b/src/alphalib/types/robots/ftp-import.ts @@ -54,7 +54,10 @@ export const robotFtpImportInstructionsSchema = robotBase path: path.describe(` The path on your FTP server where to search for files. Files are imported recursively from all sub-directories and sub-sub-directories (and so on) from this path. `), - passive_mode: z.boolean().default(true).describe(` + passive_mode: z + .boolean() + .default(true) + .describe(` Determines if passive mode should be used for the FTP connection. `), }) diff --git a/src/alphalib/types/robots/ftp-store.ts b/src/alphalib/types/robots/ftp-store.ts index d1578f38..f4ce1d66 100644 --- a/src/alphalib/types/robots/ftp-store.ts +++ b/src/alphalib/types/robots/ftp-store.ts @@ -46,18 +46,30 @@ export const robotFtpStoreInstructionsSchema = robotBase .merge(ftpBase) .extend({ robot: z.literal('/ftp/store'), - path: z.string().default('${unique_prefix}/${file.url_name}').describe(` + path: z + .string() + .default('${unique_prefix}/${file.url_name}') + .describe(` The path at which the file is to be stored. This can contain any available [Assembly variables](/docs/topics/assembly-instructions/#assembly-variables). Please note that you might need to include your homedir at the beginning of the path. `), - url_template: z.string().default('https://{HOST}/{PATH}').describe(` + url_template: z + .string() + .default('https://{HOST}/{PATH}') + .describe(` The URL of the file in the result JSON. The following [Assembly variables](/docs/topics/assembly-instructions/#assembly-variables) are supported. `), - ssl_url_template: z.string().default('https://{HOST}/{PATH}').describe(` + ssl_url_template: z + .string() + .default('https://{HOST}/{PATH}') + .describe(` The SSL URL of the file in the result JSON. The following [Assembly variables](/docs/topics/assembly-instructions/#assembly-variables) are supported. `), - secure: z.boolean().default(false).describe(` + secure: z + .boolean() + .default(false) + .describe(` Determines whether to establish a secure connection to the FTP server using SSL. `), }) @@ -66,10 +78,16 @@ Determines whether to establish a secure connection to the FTP server using SSL. export const robotFtpStoreInstructionsWithHiddenFieldsSchema = robotFtpStoreInstructionsSchema.extend({ result: z.union([z.literal('debug'), robotFtpStoreInstructionsSchema.shape.result]).optional(), - use_remote_utime: z.boolean().optional().describe(` + use_remote_utime: z + .boolean() + .optional() + .describe(` Use the remote file's modification time instead of the current time when storing the file. `), - version: z.union([z.string(), z.number()]).optional().describe(` + version: z + .union([z.string(), z.number()]) + .optional() + .describe(` Version identifier for the underlying tool used (2 is ncftp, 1 is ftp). `), allowNetwork: z.string().optional(), // For internal test purposes diff --git a/src/alphalib/types/robots/google-store.ts b/src/alphalib/types/robots/google-store.ts index 91c8116a..50621e17 100644 --- a/src/alphalib/types/robots/google-store.ts +++ b/src/alphalib/types/robots/google-store.ts @@ -65,7 +65,10 @@ Next, go to Storage browser and select the ellipsis on your bucket to edit bucke Then, create your associated [Template Credentials](/c/template-credentials/) in your Transloadit account and use the name of your Template Credentials as this parameter's value. `), - path: z.string().default('${unique_prefix}/${file.url_name}').describe(` + path: z + .string() + .default('${unique_prefix}/${file.url_name}') + .describe(` The path at which the file is to be stored. This may include any available [Assembly Variables](/docs/topics/assembly-instructions/#assembly-variables). `), acl: z @@ -77,16 +80,26 @@ The path at which the file is to be stored. This may include any available [Asse 'public-read', ]) .nullable() - .default('public-read').describe(` + .default('public-read') + .describe(` The permissions used for this file. `), - cache_control: z.string().optional().describe(` + cache_control: z + .string() + .optional() + .describe(` The \`Cache-Control\` header determines how long browsers are allowed to cache your object for. Values specified with this parameter will be added to the object's metadata under the \`Cache-Control\` header. For more information on valid values, take a look at the [official Google documentation](https://cloud.google.com/storage/docs/metadata#cache-control). `), - url_template: z.string().default('https://{HOST}/{PATH}').describe(` + url_template: z + .string() + .default('https://{HOST}/{PATH}') + .describe(` The URL of the file in the result JSON. This may include any of the following supported [Assembly variables](/docs/topics/assembly-instructions/#assembly-variables). `), - ssl_url_template: z.string().default('https://{HOST}/{PATH}').describe(` + ssl_url_template: z + .string() + .default('https://{HOST}/{PATH}') + .describe(` The SSL URL of the file in the result JSON. The following [Assembly variables](/docs/topics/assembly-instructions/#assembly-variables) are supported. `), }) diff --git a/src/alphalib/types/robots/html-convert.ts b/src/alphalib/types/robots/html-convert.ts index ee1bf370..1d4d93c2 100644 --- a/src/alphalib/types/robots/html-convert.ts +++ b/src/alphalib/types/robots/html-convert.ts @@ -54,39 +54,72 @@ A URL can be provided instead of an input HTML file, to capture a screenshot fro Use [🤖/image/resize](/docs/robots/image-resize/) to resize or crop the screenshot as needed. `), - url: z.string().nullable().default(null).describe(` + url: z + .string() + .nullable() + .default(null) + .describe(` The URL of the web page to be converted. Optional, as you can also upload/import HTML files and pass it to this Robot. `), - format: z.enum(['jpeg', 'jpg', 'pdf', 'png']).default('png').describe(` + format: z + .enum(['jpeg', 'jpg', 'pdf', 'png']) + .default('png') + .describe(` The format of the resulting image. `), - fullpage: z.boolean().default(true).describe(` + fullpage: z + .boolean() + .default(true) + .describe(` Determines if a screenshot of the full page should be taken or not. If set to \`true\`, the \`height\` parameter will not have any effect, as heights of websites vary. You can control the size of the resulting image somewhat, though, by setting the \`width\` parameter. If set to \`false\`, an image will be cropped from the top of the webpage according to your \`width\` and \`height\` parameters. `), - omit_background: z.boolean().default(false).describe(` + omit_background: z + .boolean() + .default(false) + .describe(` Determines whether to preserve a transparent background in HTML pages. Useful if you're generating artwork in HTML that you want to overlay on e.g. a video. The default of \`false\` fills transparent areas with a white background, for easier reading/printing. This parameter is only used when \`format\` is not \`pdf\`. `), - width: z.number().int().min(1).default(1024).describe(` + width: z + .number() + .int() + .min(1) + .default(1024) + .describe(` The screen width that will be used, in pixels. Change this to change the dimensions of the resulting image. `), - height: z.number().int().min(1).optional().describe(` + height: z + .number() + .int() + .min(1) + .optional() + .describe(` The screen height that will be used, in pixels. By default this equals the length of the web page in pixels if \`fullpage\` is set to \`true\`. If \`fullpage\` is set to \`false\`, the height parameter takes effect and defaults to the value \`768\`. `), - delay: z.number().int().min(0).default(0).describe(` + delay: z + .number() + .int() + .min(0) + .default(0) + .describe(` The delay (in milliseconds) applied to allow the page and all of its JavaScript to render before taking the screenshot. `), - headers: z.record(z.string()).optional().describe(` + headers: z + .record(z.string()) + .optional() + .describe(` An object containing optional headers that will be passed along with the original request to the website. For example, this parameter can be used to pass along an authorization token along with the request. `), - wait_until: z.enum(['domcontentloaded', 'load', 'networkidle', 'commit']).default('networkidle') + wait_until: z + .enum(['domcontentloaded', 'load', 'networkidle', 'commit']) + .default('networkidle') .describe(` The event to wait for before taking the screenshot. Used for loading Javascript, and images. diff --git a/src/alphalib/types/robots/http-import.ts b/src/alphalib/types/robots/http-import.ts index b889e8db..7a0832a6 100644 --- a/src/alphalib/types/robots/http-import.ts +++ b/src/alphalib/types/robots/http-import.ts @@ -63,7 +63,10 @@ The URL from which the file to be imported can be retrieved. You can also specify an array of URLs or a string of \`|\` delimited URLs to import several files at once. Please also check the \`url_delimiter\` parameter for that. `), - url_delimiter: z.string().default('|').describe(` + url_delimiter: z + .string() + .default('|') + .describe(` Provides the delimiter that is used to split the URLs in your \`url\` parameter value. `), headers: z @@ -72,7 +75,8 @@ Provides the delimiter that is used to split the URLs in your \`url\` parameter z.array(z.record(z.string())), z.string(), // For JSON strings like '{"X-Database":"volt"}' ]) - .default([]).describe(` + .default([]) + .describe(` Custom headers to be sent for file import. This is an empty array by default, such that no additional headers except the necessary ones (e.g. Host) are sent. @@ -82,14 +86,23 @@ Headers can be specified as: - An array of objects with header names as keys and values as values - A JSON string that will be parsed into an object `), - import_on_errors: z.array(z.string()).default([]).describe(` + import_on_errors: z + .array(z.string()) + .default([]) + .describe(` Setting this to \`"meta"\` will still import the file on metadata extraction errors. \`ignore_errors\` is similar, it also ignores the error and makes sure the Robot doesn't stop, but it doesn't import the file. `), - fail_fast: z.boolean().default(false).describe(` + fail_fast: z + .boolean() + .default(false) + .describe(` Disable the internal retry mechanism, and fail immediately if a resource can't be imported. This can be useful for performance critical applications. `), return_file_stubs, - range: z.union([z.string(), z.array(z.string())]).optional().describe(` + range: z + .union([z.string(), z.array(z.string())]) + .optional() + .describe(` Allows you to specify one or more byte ranges to import from the file. The server must support range requests for this to work. **Single range**: Use a string like \`"0-99"\` to import bytes 0-99 (the first 100 bytes). @@ -113,7 +126,10 @@ Allows you to specify one or more byte ranges to import from the file. The serve export const robotHttpImportInstructionsWithHiddenFieldsSchema = robotHttpImportInstructionsSchema.extend({ force_original_id: z.string().optional(), - force_name: z.union([z.string(), z.record(z.string())]).optional().describe(` + force_name: z + .union([z.string(), z.record(z.string())]) + .optional() + .describe(` Force a specific filename for imported files. Can be a string to apply to all imports, or an object mapping URLs to filenames. `), result: z diff --git a/src/alphalib/types/robots/image-describe.ts b/src/alphalib/types/robots/image-describe.ts index f182a5cc..00f2637d 100644 --- a/src/alphalib/types/robots/image-describe.ts +++ b/src/alphalib/types/robots/image-describe.ts @@ -65,13 +65,19 @@ Transloadit outsources this task and abstracts the interface so you can expect t granularity: granularitySchema.describe(` Whether to return a full response (\`"full"\`) including confidence percentages for each found label, or just a flat list of labels (\`"list"\`). `), - format: z.enum(['json', 'meta', 'text']).default('json').describe(` + format: z + .enum(['json', 'meta', 'text']) + .default('json') + .describe(` In what format to return the descriptions. - \`"json"\` returns a JSON file. - \`"meta"\` does not return a file, but stores the data inside Transloadit's file object (under \`\${file.meta.descriptions}\`) that's passed around between encoding Steps, so that you can use the values to burn the data into videos, filter on them, etc. `), - explicit_descriptions: z.boolean().default(false).describe(` + explicit_descriptions: z + .boolean() + .default(false) + .describe(` Whether to return only explicit or only non-explicit descriptions of the provided image. Explicit descriptions include labels for NSFW content (nudity, violence, etc). If set to \`false\`, only non-explicit descriptions (such as human or chair) will be returned. If set to \`true\`, only explicit descriptions will be returned. The possible descriptions depend on the chosen provider. The list of labels from AWS can be found [in their documentation](https://docs.aws.amazon.com/rekognition/latest/dg/moderation.html#moderation-api). GCP labels the image based on five categories, as described [in their documentation](https://cloud.google.com/vision/docs/detecting-safe-search). diff --git a/src/alphalib/types/robots/image-facedetect.ts b/src/alphalib/types/robots/image-facedetect.ts index d84046ed..dddc01bc 100644 --- a/src/alphalib/types/robots/image-facedetect.ts +++ b/src/alphalib/types/robots/image-facedetect.ts @@ -72,26 +72,40 @@ Which AI provider to leverage. Transloadit outsources this task and abstracts the interface so you can expect the same data structures, but different latencies and information being returned. Different cloud vendors have different areas they shine in, and we recommend to try out and see what yields the best results for your use case. `), - crop: z.boolean().default(false).describe(` + crop: z + .boolean() + .default(false) + .describe(` Determine if the detected faces should be extracted. If this option is set to \`false\`, then the Robot returns the input image again, but with the coordinates of all detected faces attached to \`file.meta.faces\` in the result JSON. If this parameter is set to \`true\`, the Robot will output all detected faces as images. `), crop_padding: z .string() .regex(/^\d+(px|%)$/) - .default('5px').describe(` + .default('5px') + .describe(` Specifies how much padding is added to the extracted face images if \`crop\` is set to \`true\`. Values can be in \`px\` (pixels) or \`%\` (percentage of the width and height of the particular face image). `), - format: z.enum(['jpg', 'png', 'preserve', 'tiff']).default('preserve').describe(` + format: z + .enum(['jpg', 'png', 'preserve', 'tiff']) + .default('preserve') + .describe(` Determines the output format of the extracted face images if \`crop\` is set to \`true\`. The default value \`"preserve"\` means that the input image format is re-used. `), - min_confidence: z.number().int().min(0).max(100).default(70).describe(` + min_confidence: z + .number() + .int() + .min(0) + .max(100) + .default(70) + .describe(` Specifies the minimum confidence that a detected face must have. Only faces which have a higher confidence value than this threshold will be included in the result. `), faces: z .union([z.enum(['each', 'group', 'max-confidence', 'max-size']), z.number().int()]) - .default('each').describe(` + .default('each') + .describe(` Determines which of the detected faces should be returned. Valid values are: - \`"each"\` — each face is returned individually. diff --git a/src/alphalib/types/robots/image-merge.ts b/src/alphalib/types/robots/image-merge.ts index 693008a8..7b462e61 100644 --- a/src/alphalib/types/robots/image-merge.ts +++ b/src/alphalib/types/robots/image-merge.ts @@ -67,7 +67,11 @@ similar size before merging them. .default('horizontal') .describe('Specifies the direction which the images are displayed.'), // TODO: default is not between 1 and 10 - border: z.number().int().default(0).describe(` + border: z + .number() + .int() + .default(0) + .describe(` An integer value which defines the gap between images on the spritesheet. A value of \`10\` would cause the images to have the largest gap between them, while a value of \`1\` would place the images side-by-side. @@ -79,7 +83,10 @@ By default, the background of transparent images is changed to white. For details about how to preserve transparency across all image types, see [this demo](/demos/image-manipulation/properly-preserve-transparency-across-all-image-types/). `), - adaptive_filtering: z.boolean().default(false).describe(` + adaptive_filtering: z + .boolean() + .default(false) + .describe(` Controls the image compression for PNG images. Setting to \`true\` results in smaller file size, while increasing processing time. It is encouraged to keep this option disabled. `), quality: imageQualitySchema, diff --git a/src/alphalib/types/robots/image-ocr.ts b/src/alphalib/types/robots/image-ocr.ts index 7dcbba77..453eaa58 100644 --- a/src/alphalib/types/robots/image-ocr.ts +++ b/src/alphalib/types/robots/image-ocr.ts @@ -69,7 +69,10 @@ AWS supports detection for the following languages: English, Arabic, Russian, Ge granularity: granularitySchema.describe(` Whether to return a full response including coordinates for the text (\`"full"\`), or a flat list of the extracted phrases (\`"list"\`). This parameter has no effect if the \`format\` parameter is set to \`"text"\`. `), - format: z.enum(['json', 'meta', 'text']).default('json').describe(` + format: z + .enum(['json', 'meta', 'text']) + .default('json') + .describe(` In what format to return the extracted text. - \`"json"\` returns a JSON file. - \`"meta"\` does not return a file, but stores the data inside Transloadit's file object (under \`\${file.meta.recognized_text}\`, which is an array of strings) that's passed around between encoding Steps, so that you can use the values to burn the data into videos, filter on them, etc. diff --git a/src/alphalib/types/robots/image-optimize.ts b/src/alphalib/types/robots/image-optimize.ts index aeb1aa2a..bc1e479d 100644 --- a/src/alphalib/types/robots/image-optimize.ts +++ b/src/alphalib/types/robots/image-optimize.ts @@ -59,13 +59,22 @@ It works well together with [🤖/image/resize](/docs/robots/image-resize/) to b priority: optimize_priority.describe(` Provides different algorithms for better or worse compression for your images, but that run slower or faster. The value \`"conversion-speed"\` will result in an average compression ratio of 18%. \`"compression-ratio"\` will result in an average compression ratio of 31%. `), - progressive: z.boolean().default(false).describe(` + progressive: z + .boolean() + .default(false) + .describe(` Interlaces the image if set to \`true\`, which makes the result image load progressively in browsers. Instead of rendering the image from top to bottom, the browser will first show a low-res blurry version of the image which is then quickly replaced with the actual image as the data arrives. This greatly increases the user experience, but comes at a loss of about 10% of the file size reduction. `), - preserve_meta_data: z.boolean().default(true).describe(` + preserve_meta_data: z + .boolean() + .default(true) + .describe(` Specifies if the image's metadata should be preserved during the optimization, or not. If it is not preserved, the file size is even further reduced. But be aware that this could strip a photographer's copyright information, which for obvious reasons can be frowned upon. `), - fix_breaking_images: z.boolean().default(true).describe(` + fix_breaking_images: z + .boolean() + .default(true) + .describe(` If set to \`true\` this parameter tries to fix images that would otherwise make the underlying tool error out and thereby break your Assemblies. This can sometimes result in a larger file size, though. `), }) diff --git a/src/alphalib/types/robots/image-resize.ts b/src/alphalib/types/robots/image-resize.ts index dc3f3282..83cb6700 100644 --- a/src/alphalib/types/robots/image-resize.ts +++ b/src/alphalib/types/robots/image-resize.ts @@ -58,16 +58,28 @@ export const meta: RobotMetaInput = { export const oneTextSchema = z.object({ // TODO: Determine valid fonts text: z.string(), - font: z.string().default('Arial').describe(` + font: z + .string() + .default('Arial') + .describe(` The font family to use. Also includes boldness and style of the font. [Here](/docs/supported-formats/fonts/) is a list of all supported fonts. `), - size: z.number().int().min(1).default(12).describe(` + size: z + .number() + .int() + .min(1) + .default(12) + .describe(` The text size in pixels. `), - rotate: z.number().int().default(0).describe(` + rotate: z + .number() + .int() + .default(0) + .describe(` The rotation angle in degrees. `), color: color_without_alpha_with_named.default('#000000').describe(` @@ -76,22 +88,41 @@ The text color. All hex colors in the form \`"#xxxxxx"\` are supported, where ea background_color: color_without_alpha_with_named.default('transparent').describe(` The background color behind the text. All hex colors in the form \`"#xxxxxx"\` are supported, where each x can be \`0-9\` or \`a-f\`. Named colors like \`"black"\`, \`"white"\`, \`"transparent"\` etc. are also supported. `), - stroke_width: z.number().int().min(0).default(0).describe(` + stroke_width: z + .number() + .int() + .min(0) + .default(0) + .describe(` The stroke's width in pixels. `), stroke_color: color_without_alpha_with_named.default('transparent').describe(` The stroke's color. All hex colors in the form \`"#xxxxxx"\` are supported, where each x can be \`0-9\` or \`a-f\`. Named colors like \`"black"\`, \`"white"\`, \`"transparent"\` etc. are also supported. `), - align: z.enum(['center', 'left', 'right']).default('center').describe(` + align: z + .enum(['center', 'left', 'right']) + .default('center') + .describe(` The horizontal text alignment. Can be \`"left"\`, \`"center"\` and \`"right"\`. `), - valign: z.enum(['bottom', 'center', 'top']).default('center').describe(` + valign: z + .enum(['bottom', 'center', 'top']) + .default('center') + .describe(` The vertical text alignment. Can be \`"top"\`, \`"center"\` and \`"bottom"\`. `), - x_offset: z.number().int().default(0).describe(` + x_offset: z + .number() + .int() + .default(0) + .describe(` The horizontal offset for the text in pixels that is added (positive integer) or removed (negative integer) from the horizontal alignment. `), - y_offset: z.number().int().default(0).describe(` + y_offset: z + .number() + .int() + .default(0) + .describe(` The vertical offset for the text in pixels that is added (positive integer) or removed (negative integer) from the vertical alignment. `), }) @@ -124,7 +155,11 @@ export const robotImageResizeInstructionsSchema = robotBase .extend({ robot: z.literal('/image/resize'), // TODO: Use an enum - format: z.string().nullable().default(null).describe(` + format: z + .string() + .nullable() + .default(null) + .describe(` The output format for the modified image. Some of the most important available formats are \`"jpg"\`, \`"png"\`, \`"gif"\`, and \`"tiff"\`. For a complete lists of all formats that we can write to please check [our supported image formats list](/docs/supported-formats/image-formats/). @@ -141,23 +176,28 @@ Height of the new image, in pixels. If not specified, will default to the height `), resize_strategy: z .union([ - z.literal('crop') + z + .literal('crop') .describe(`Cuts an area out of an image, discarding any overlapping parts. If the source image is smaller than the crop frame, it will be zoomed. This strategy is implied when you specify coordinates in the \`crop\` parameter, and cannot be used without it. To crop around human faces, see [🤖/image/facedetect](https://transloadit.com/docs/robots/image-facedetect/) instead.`), - z.literal('fillcrop') + z + .literal('fillcrop') .describe(`Scales the image to fit into our 100×100 target while preserving aspect ratio, while trimming away any excess surface. This means both sides will become exactly 100 pixels, at the tradeoff of destroying parts of the image. By default the resulting image is horizontally/vertically centered to fill the target rectangle. Use the \`gravity\` parameter to change where to crop the image, such as \`"bottom\`" or \`"left\`".`), - z.literal('fit') + z + .literal('fit') .describe(`Uses the larger side of the original image as a base for the resize. Aspect ratio is preserved. Either side will become at most 100 pixels. For example: resizing a 400×300 image into 100×100, would produce a 100×75 image.`), - z.literal('min_fit') + z + .literal('min_fit') .describe(`Uses the **smaller** side of the original image as a base for the resize. After resizing, the larger side will have a larger value than specified. Aspect ratio is preserved. Either side will become at least 100 pixels. For example: resizing a 400×300 image into 100×100, would produce a 133×100 image.`), - z.literal('pad') + z + .literal('pad') .describe(`Scales the image to fit while preserving aspect ratio. Both sides of the resized image become exactly 100 pixels, and any remaining surface is filled with a background color. In this example, the background color is determined by the [Assembly Variable](https://transloadit.com/docs/topics/assembly-instructions/#assembly-variables) \`\${file.meta.average_color}\`. If you set \`zoom\` to \`false\` (default is \`true\`), smaller images will be centered horizontally and vertically, and have the background padding all around them.`), @@ -167,10 +207,14 @@ In this example, the background color is determined by the [Assembly Variable](h 'Ignores aspect ratio, resizing the image to the exact width and height specified. This may result in a stretched or distorted image.', ), ]) - .default('fit').describe(` + .default('fit') + .describe(` See the list of available [resize strategies](/docs/topics/resize-strategies/). `), - zoom: z.boolean().default(true).describe(` + zoom: z + .boolean() + .default(true) + .describe(` If this is set to \`false\`, smaller images will not be stretched to the desired width and height. For details about the impact of zooming for your preferred resize strategy, see the list of available [resize strategies](/docs/topics/resize-strategies/). `), crop: unsafeCoordinatesSchema.optional().describe(` @@ -200,7 +244,10 @@ To crop around human faces, see [🤖/image/facedetect](/docs/robots/image-faced gravity: positionSchema.default('center').describe(` The direction from which the image is to be cropped, when \`"resize_strategy"\` is set to \`"crop"\`, but no crop coordinates are defined. `), - strip: z.boolean().default(false).describe(` + strip: z + .boolean() + .default(false) + .describe(` Strips all metadata from the image. This is useful to keep thumbnails as small as possible. `), alpha: z @@ -218,7 +265,8 @@ Strips all metadata from the image. This is useful to keep thumbnails as small a 'Shape', 'Transparent', ]) - .optional().describe(` + .optional() + .describe(` Gives control of the alpha/matte channel of an image. `), preclip_alpha: z @@ -236,19 +284,29 @@ Gives control of the alpha/matte channel of an image. 'Shape', 'Transparent', ]) - .optional().describe(` + .optional() + .describe(` Gives control of the alpha/matte channel of an image before applying the clipping path via \`clip: true\`. `), - flatten: z.boolean().default(true).describe(` + flatten: z + .boolean() + .default(true) + .describe(` Flattens all layers onto the specified background to achieve better results from transparent formats to non-transparent formats, as explained in the [ImageMagick documentation](https://www.imagemagick.org/script/command-line-options.php#layers). To preserve animations, GIF files are not flattened when this is set to \`true\`. To flatten GIF animations, use the \`frame\` parameter. `), - correct_gamma: z.boolean().default(false).describe(` + correct_gamma: z + .boolean() + .default(false) + .describe(` Prevents gamma errors [common in many image scaling algorithms](https://www.4p8.com/eric.brasseur/gamma.html). `), quality: imageQualitySchema, - adaptive_filtering: z.boolean().default(false).describe(` + adaptive_filtering: z + .boolean() + .default(false) + .describe(` Controls the image compression for PNG images. Setting to \`true\` results in smaller file size, while increasing processing time. It is encouraged to keep this option disabled. `), background: color_without_alpha_with_named.default('#FFFFFF').describe(` @@ -256,7 +314,13 @@ Either the hexadecimal code or [name](https://www.imagemagick.org/script/color.p **Note:** By default, the background of transparent images is changed to white. To preserve transparency, set \`"background"\` to \`"none"\`. `), - frame: z.number().int().min(1).nullable().default(null).describe(` + frame: z + .number() + .int() + .min(1) + .nullable() + .default(null) + .describe(` Use this parameter when dealing with animated GIF files to specify which frame of the GIF is used for the operation. Specify \`1\` to use the first frame, \`2\` to use the second, and so on. \`null\` means all frames. `), colorspace: colorspaceSchema.optional().describe(` @@ -274,10 +338,18 @@ Sets the image colorspace. For details about the available values, see the [Imag 'TrueColor', 'TrueColorAlpha', ]) - .optional().describe(` + .optional() + .describe(` Sets the image color type. For details about the available values, see the [ImageMagick documentation](https://www.imagemagick.org/script/command-line-options.php#type). If you're using \`colorspace\`, ImageMagick might try to find the most efficient based on the color of an image, and default to e.g. \`"Gray"\`. To force colors, you could e.g. set this parameter to \`"TrueColor"\` `), - sepia: z.number().int().min(0).max(99).nullable().default(null).describe(` + sepia: z + .number() + .int() + .min(0) + .max(99) + .nullable() + .default(null) + .describe(` Applies a sepia tone effect in percent. `), rotation: z @@ -286,13 +358,15 @@ Applies a sepia tone effect in percent. z.boolean(), z.literal('auto'), // Support 'auto' string value ]) - .default(true).describe(` + .default(true) + .describe(` Determines whether the image should be rotated. Use any number to specify the rotation angle in degrees (e.g., \`90\`, \`180\`, \`270\`, \`360\`, or precise values like \`2.9\`). Use the value \`true\` or \`"auto"\` to auto-rotate images that are rotated incorrectly or depend on EXIF rotation settings. Otherwise, use \`false\` to disable auto-fixing altogether. `), compress: z .enum(['BZip', 'Fax', 'Group4', 'JPEG', 'JPEG2000', 'Lossless', 'LZW', 'None', 'RLE', 'Zip']) .nullable() - .default(null).describe(` + .default(null) + .describe(` Specifies pixel compression for when the image is written. Compression is disabled by default. Please also take a look at [🤖/image/optimize](/docs/robots/image-optimize/). @@ -301,7 +375,8 @@ Please also take a look at [🤖/image/optimize](/docs/robots/image-optimize/). .string() .regex(/^\d+(\.\d+)?x\d+(\.\d+)?$/) .nullable() - .default(null).describe(` + .default(null) + .describe(` Specifies gaussian blur, using a value with the form \`{radius}x{sigma}\`. The radius value specifies the size of area the operator should look at when spreading pixels, and should typically be either \`"0"\` or at least two times the sigma value. The sigma value is an approximation of how many pixels the image is "spread"; think of it as the size of the brush used to blur the image. This number is a floating point value, enabling small values like \`"0.5"\` to be used. `), blur_regions: z @@ -315,24 +390,42 @@ Specifies gaussian blur, using a value with the form \`{radius}x{sigma}\`. The r }), ) .nullable() - .default(null).describe(` + .default(null) + .describe(` Specifies an array of ellipse objects that should be blurred on the image. Each object has the following keys: \`x\`, \`y\`, \`width\`, \`height\`. If \`blur_regions\` has a value, then the \`blur\` parameter is used as the strength of the blur for each region. `), // TODO: An int according to the docs, a float in the example - brightness: z.number().min(0).default(1).describe(` + brightness: z + .number() + .min(0) + .default(1) + .describe(` Increases or decreases the brightness of the image by using a multiplier. For example \`1.5\` would increase the brightness by 50%, and \`0.75\` would decrease the brightness by 25%. `), // TODO: An int according to the docs, a float in the example - saturation: z.number().min(0).default(1).describe(` + saturation: z + .number() + .min(0) + .default(1) + .describe(` Increases or decreases the saturation of the image by using a multiplier. For example \`1.5\` would increase the saturation by 50%, and \`0.75\` would decrease the saturation by 25%. `), - hue: z.number().min(0).default(100).describe(` + hue: z + .number() + .min(0) + .default(100) + .describe(` Changes the hue by rotating the color of the image. The value \`100\` would produce no change whereas \`0\` and \`200\` will negate the colors in the image. `), - watermark_url: z.string().optional().describe(` + watermark_url: z + .string() + .optional() + .describe(` A URL indicating a PNG image to be overlaid above this image. Please note that you can also [supply the watermark via another Assembly Step](/docs/topics/use-parameter/#supplying-the-watermark-via-an-assembly-step). With watermarking you can add an image onto another image. This is usually used for logos. `), - watermark_position: z.union([positionSchema, z.array(positionSchema)]).default('center') + watermark_position: z + .union([positionSchema, z.array(positionSchema)]) + .default('center') .describe(` The position at which the watermark is placed. The available options are \`"center"\`, \`"top"\`, \`"bottom"\`, \`"left"\`, and \`"right"\`. You can also combine options, such as \`"bottom-right"\`. @@ -340,12 +433,20 @@ An array of possible values can also be specified, in which case one value will This setting puts the watermark in the specified corner. To use a specific pixel offset for the watermark, you will need to add the padding to the image itself. `), - watermark_x_offset: z.number().int().default(0).describe(` + watermark_x_offset: z + .number() + .int() + .default(0) + .describe(` The x-offset in number of pixels at which the watermark will be placed in relation to the position it has due to \`watermark_position\`. Values can be both positive and negative and yield different results depending on the \`watermark_position\` parameter. Positive values move the watermark closer to the image's center point, whereas negative values move the watermark further away from the image's center point. `), - watermark_y_offset: z.number().int().default(0).describe(` + watermark_y_offset: z + .number() + .int() + .default(0) + .describe(` The y-offset in number of pixels at which the watermark will be placed in relation to the position it has due to \`watermark_position\`. Values can be both positive and negative and yield different results depending on the \`watermark_position\` parameter. Positive values move the watermark closer to the image's center point, whereas negative values move the watermark further away from the image's center point. @@ -355,7 +456,9 @@ The size of the watermark, as a percentage. For example, a value of \`"50%"\` means that size of the watermark will be 50% of the size of image on which it is placed. The exact sizing depends on \`watermark_resize_strategy\`, too. `), - watermark_resize_strategy: z.enum(['area', 'fit', 'min_fit', 'stretch']).default('fit') + watermark_resize_strategy: z + .enum(['area', 'fit', 'min_fit', 'stretch']) + .default('fit') .describe(` Available values are \`"fit"\`, \`"min_fit"\`, \`"stretch"\` and \`"area"\`. @@ -378,43 +481,65 @@ For the \`"area"\` resize strategy, the watermark is resized (keeping its aspect ]) .optional() .describe(TEXT_DESCRIPTION), - progressive: z.boolean().default(false).describe(` + progressive: z + .boolean() + .default(false) + .describe(` Interlaces the image if set to \`true\`, which makes the image load progressively in browsers. Instead of rendering the image from top to bottom, the browser will first show a low-res blurry version of the images which is then quickly replaced with the actual image as the data arrives. This greatly increases the user experience, but comes at a cost of a file size increase by around 10%. `), transparent: z .union([color_without_alpha_with_named, z.string().regex(/^\d+,\d+,\d+$/)]) - .optional().describe(` + .optional() + .describe(` Make this color transparent within the image. Example: \`"255,255,255"\`. `), - trim_whitespace: z.boolean().default(false).describe(` + trim_whitespace: z + .boolean() + .default(false) + .describe(` This determines if additional whitespace around the image should first be trimmed away. If you set this to \`true\` this parameter removes any edges that are exactly the same color as the corner pixels. `), - clip: z.union([z.string(), z.boolean()]).default(false).describe(` + clip: z + .union([z.string(), z.boolean()]) + .default(false) + .describe(` Apply the clipping path to other operations in the resize job, if one is present. If set to \`true\`, it will automatically take the first clipping path. If set to a String it finds a clipping path by that name. `), - negate: z.boolean().default(false).describe(` + negate: z + .boolean() + .default(false) + .describe(` Replace each pixel with its complementary color, effectively negating the image. Especially useful when testing clipping. `), density: z .string() .regex(/\d+(x\d+)?/) .nullable() - .default(null).describe(` + .default(null) + .describe(` While in-memory quality and file format depth specifies the color resolution, the density of an image is the spatial (space) resolution of the image. That is the density (in pixels per inch) of an image and defines how far apart (or how big) the individual pixels are. It defines the size of the image in real world terms when displayed on devices or printed. You can set this value to a specific \`width\` or in the format \`width\`x\`height\`. If your converted image is unsharp, please try increasing density. `), - monochrome: z.boolean().default(false).describe(` + monochrome: z + .boolean() + .default(false) + .describe(` Transform the image to black and white. This is a shortcut for setting the colorspace to Gray and type to Bilevel. `), shave: z .union([ z.string().regex(/^\d+(x\d+)?$/), - z.number().int().min(0).transform(String), // Accept numbers and convert to string + z + .number() + .int() + .min(0) + .transform(String), // Accept numbers and convert to string ]) - .optional().describe(` + .optional() + .describe(` Shave pixels from the image edges. The value should be in the format \`width\` or \`width\`x\`height\` to specify the number of pixels to remove from each side. `), }) @@ -430,14 +555,20 @@ export const robotImageResizeInstructionsWithHiddenFieldsSchema = .union([ // Support single text object (backward compatibility) oneTextSchema.extend({ - gravity: positionSchema.default('top-left').optional().describe(` + gravity: positionSchema + .default('top-left') + .optional() + .describe(` Legacy. The direction from which to start the offsets. `), }), // Support array of text objects (current schema) z.array( oneTextSchema.extend({ - gravity: positionSchema.default('top-left').optional().describe(` + gravity: positionSchema + .default('top-left') + .optional() + .describe(` Legacy. The direction from which to start the offsets. `), }), @@ -445,10 +576,18 @@ export const robotImageResizeInstructionsWithHiddenFieldsSchema = ]) .optional() .describe(TEXT_DESCRIPTION), - watermark_position_x: z.number().int().optional().describe(` + watermark_position_x: z + .number() + .int() + .optional() + .describe(` Legacy alias for \`watermark_x_offset\`. The x-offset in number of pixels at which the watermark will be placed. `), - watermark_position_y: z.number().int().optional().describe(` + watermark_position_y: z + .number() + .int() + .optional() + .describe(` Legacy alias for \`watermark_y_offset\`. The y-offset in number of pixels at which the watermark will be placed. `), }) diff --git a/src/alphalib/types/robots/meta-write.ts b/src/alphalib/types/robots/meta-write.ts index 33f6b93e..3fff1770 100644 --- a/src/alphalib/types/robots/meta-write.ts +++ b/src/alphalib/types/robots/meta-write.ts @@ -51,7 +51,11 @@ export const robotMetaWriteInstructionsSchema = robotBase robot: z.literal('/meta/write').describe(` **Note:** This Robot currently accepts images, videos and audio files. `), - data_to_write: z.object({}).passthrough().default({}).describe(` + data_to_write: z + .object({}) + .passthrough() + .default({}) + .describe(` A key/value map defining the metadata to write into the file. Valid metadata keys can be found [here](https://exiftool.org/TagNames/EXIF.html). For example: \`ProcessingSoftware\`. diff --git a/src/alphalib/types/robots/minio-store.ts b/src/alphalib/types/robots/minio-store.ts index f5208754..4c30ea2d 100644 --- a/src/alphalib/types/robots/minio-store.ts +++ b/src/alphalib/types/robots/minio-store.ts @@ -48,18 +48,32 @@ export const robotMinioStoreInstructionsSchema = robotBase robot: z.literal('/minio/store').describe(` The URL to the result file will be returned in the Assembly Status JSON. `), - path: z.string().default('${unique_prefix}/${file.url_name}').describe(` + path: z + .string() + .default('${unique_prefix}/${file.url_name}') + .describe(` The path at which the file is to be stored. This may include any available [Assembly variables](/docs/topics/assembly-instructions/#assembly-variables). The path must not be a directory. `), - acl: z.enum(['private', 'public-read']).default('public-read').describe(` + acl: z + .enum(['private', 'public-read']) + .default('public-read') + .describe(` The permissions used for this file. `), - headers: z.record(z.string()).default({ 'Content-Type': '${file.mime}' }).describe(` + headers: z + .record(z.string()) + .default({ 'Content-Type': '${file.mime}' }) + .describe(` An object containing a list of headers to be set for this file on MinIO Spaces, such as \`{ FileURL: "\${file.url_name}" }\`. This can also include any available [Assembly Variables](/docs/topics/assembly-instructions/#assembly-variables). Object Metadata can be specified using \`x-amz-meta-*\` headers. Note that these headers [do not support non-ASCII metadata values](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html#UserMetadata). `), - sign_urls_for: z.number().int().min(0).optional().describe(` + sign_urls_for: z + .number() + .int() + .min(0) + .optional() + .describe(` This parameter provides signed URLs in the result JSON (in the \`signed_ssl_url\` property). The number that you set this parameter to is the URL expiry time in seconds. If this parameter is not used, no URL signing is done. diff --git a/src/alphalib/types/robots/s3-import.ts b/src/alphalib/types/robots/s3-import.ts index ca2bbafb..760d8de4 100644 --- a/src/alphalib/types/robots/s3-import.ts +++ b/src/alphalib/types/robots/s3-import.ts @@ -119,7 +119,10 @@ When doing big imports, make sure no files are added or removed from other scrip The pagination page size. This only works when recursive is \`true\` for now, in order to not break backwards compatibility in non-recursive imports. `), return_file_stubs, - range: z.union([z.string(), z.array(z.string())]).optional().describe(` + range: z + .union([z.string(), z.array(z.string())]) + .optional() + .describe(` Allows you to specify one or more byte ranges to import from the file. S3 must support range requests for this to work. **Single range**: Use a string like \`"0-99"\` to import bytes 0-99 (the first 100 bytes). diff --git a/src/alphalib/types/robots/s3-store.ts b/src/alphalib/types/robots/s3-store.ts index 174c4dd9..d92626a9 100644 --- a/src/alphalib/types/robots/s3-store.ts +++ b/src/alphalib/types/robots/s3-store.ts @@ -88,38 +88,66 @@ In order to build proper result URLs we need to know the region in which your S3 Please keep in mind that if you use bucket encryption you may also need to add \`"sts:*"\` and \`"kms:*"\` to the bucket policy. Please read [here](https://docs.aws.amazon.com/kms/latest/developerguide/kms-api-permissions-reference.html) and [here](https://aws.amazon.com/blogs/security/how-to-restrict-amazon-s3-bucket-access-to-a-specific-iam-role/) in case you run into trouble with our example bucket policy. `), - path: z.string().default('${unique_prefix}/${file.url_name}').describe(` + path: z + .string() + .default('${unique_prefix}/${file.url_name}') + .describe(` The path at which the file is to be stored. This may include any available [Assembly variables](/docs/topics/assembly-instructions/#assembly-variables). The path must not be a directory. `), - url_prefix: z.string().default('http://{bucket}.s3.amazonaws.com/').describe(` + url_prefix: z + .string() + .default('http://{bucket}.s3.amazonaws.com/') + .describe(` The URL prefix used for the returned URL, such as \`"http://my.cdn.com/some/path/"\`. `), - acl: z.enum(['bucket-default', 'private', 'public', 'public-read']).default('public-read') + acl: z + .enum(['bucket-default', 'private', 'public', 'public-read']) + .default('public-read') .describe(` The permissions used for this file. Please keep in mind that the default value \`"public-read"\` can lead to permission errors due to the \`"Block all public access"\` checkbox that is checked by default when creating a new Amazon S3 Bucket in the AWS console. `), - check_integrity: z.boolean().default(false).describe(` + check_integrity: z + .boolean() + .default(false) + .describe(` Calculate and submit the file's checksum in order for S3 to verify its integrity after uploading, which can help with occasional file corruption issues. Enabling this option adds to the overall execution time, as integrity checking can be CPU intensive, especially for larger files. `), - headers: z.record(z.string()).default({ 'Content-Type': '${file.mime}' }).describe(` + headers: z + .record(z.string()) + .default({ 'Content-Type': '${file.mime}' }) + .describe(` An object containing a list of headers to be set for this file on S3, such as \`{ FileURL: "\${file.url_name}" }\`. This can also include any available [Assembly Variables](/docs/topics/assembly-instructions/#assembly-variables). You can find a list of available headers [here](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html). Object Metadata can be specified using \`x-amz-meta-*\` headers. Note that these headers [do not support non-ASCII metadata values](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html#UserMetadata). `), - tags: z.record(z.string()).default({}).describe(` + tags: z + .record(z.string()) + .default({}) + .describe(` Object tagging allows you to categorize storage. You can associate up to 10 tags with an object. Tags that are associated with an object must have unique tag keys. `), - host: z.string().default('s3.amazonaws.com').describe(` + host: z + .string() + .default('s3.amazonaws.com') + .describe(` The host of the storage service used. This only needs to be set when the storage service used is not Amazon S3, but has a compatible API (such as hosteurope.de). The default protocol used is HTTP, for anything else the protocol needs to be explicitly specified. For example, prefix the host with \`https://\` or \`s3://\` to use either respective protocol. `), - no_vhost: z.boolean().default(false).describe(` + no_vhost: z + .boolean() + .default(false) + .describe(` Set to \`true\` if you use a custom host and run into access denied errors. `), - sign_urls_for: z.number().int().min(0).optional().describe(` + sign_urls_for: z + .number() + .int() + .min(0) + .optional() + .describe(` This parameter provides signed URLs in the result JSON (in the \`signed_url\` and \`signed_ssl_url\` properties). The number that you set this parameter to is the URL expiry time in seconds. If this parameter is not used, no URL signing is done. `), }) @@ -128,7 +156,10 @@ This parameter provides signed URLs in the result JSON (in the \`signed_url\` an export const robotS3StoreInstructionsWithHiddenFieldsSchema = robotS3StoreInstructionsSchema.extend( { result: z.union([z.literal('debug'), robotS3StoreInstructionsSchema.shape.result]).optional(), - skip_region_lookup: z.boolean().optional().describe(` + skip_region_lookup: z + .boolean() + .optional() + .describe(` Internal parameter to skip region lookup for testing purposes. `), }, diff --git a/src/alphalib/types/robots/script-run.ts b/src/alphalib/types/robots/script-run.ts index 3ce743c1..5cad094a 100644 --- a/src/alphalib/types/robots/script-run.ts +++ b/src/alphalib/types/robots/script-run.ts @@ -88,7 +88,10 @@ You can check whether evaluating this script was free by inspecting \`file.meta. export const robotScriptRunInstructionsWithHiddenFieldsSchema = robotScriptRunInstructionsSchema.extend({ result: z.union([z.literal('debug'), robotScriptRunInstructionsSchema.shape.result]).optional(), - contextJSON: z.string().optional().describe(` + contextJSON: z + .string() + .optional() + .describe(` A JSON string that provides additional context data to the script. This will be parsed and made available to the script as a \`context\` variable. For example, if you pass \`'{"foo":{"bar":"baz"}}'\`, the script can access \`context.foo.bar\` to get the value \`"baz"\`. `), }) diff --git a/src/alphalib/types/robots/sftp-import.ts b/src/alphalib/types/robots/sftp-import.ts index fb2bf1e3..a71e8e5c 100644 --- a/src/alphalib/types/robots/sftp-import.ts +++ b/src/alphalib/types/robots/sftp-import.ts @@ -56,7 +56,10 @@ export const robotSftpImportInstructionsWithHiddenFieldsSchema = result: z .union([z.literal('debug'), robotSftpImportInstructionsSchema.shape.result]) .optional(), - allowNetwork: z.string().optional().describe(` + allowNetwork: z + .string() + .optional() + .describe(` Network access permission for the SFTP connection. This is used to control which networks the SFTP robot can access. `), }) diff --git a/src/alphalib/types/robots/sftp-store.ts b/src/alphalib/types/robots/sftp-store.ts index a391a60a..e65950d2 100644 --- a/src/alphalib/types/robots/sftp-store.ts +++ b/src/alphalib/types/robots/sftp-store.ts @@ -45,19 +45,29 @@ export const robotSftpStoreInstructionsSchema = robotBase .merge(sftpBase) .extend({ robot: z.literal('/sftp/store'), - path: z.string().default('${unique_prefix}/${file.url_name}').describe(` + path: z + .string() + .default('${unique_prefix}/${file.url_name}') + .describe(` The path at which the file is to be stored. This may include any available [Assembly variables](/docs/topics/assembly-instructions/#assembly-variables). `), - url_template: z.string().default('http://host/path').describe(` + url_template: z + .string() + .default('http://host/path') + .describe(` The URL of the file in the result JSON. This may include any of the following supported [Assembly variables](/docs/topics/assembly-instructions/#assembly-variables). `), - ssl_url_template: z.string().default('https://{HOST}/{PATH}').describe(` + ssl_url_template: z + .string() + .default('https://{HOST}/{PATH}') + .describe(` The SSL URL of the file in the result JSON. The following [Assembly variables](/docs/topics/assembly-instructions/#assembly-variables) are supported. `), file_chmod: z .string() .regex(/([0-7]{3}|auto)/) - .default('auto').describe(` + .default('auto') + .describe(` This optional parameter controls how an uploaded file's permission bits are set. You can use any string format that the \`chmod\` command would accept, such as \`"755"\`. If you don't specify this option, the file's permission bits aren't changed at all, meaning it's up to your server's configuration (e.g. umask). `), }) @@ -66,7 +76,10 @@ This optional parameter controls how an uploaded file's permission bits are set. export const robotSftpStoreInstructionsWithHiddenFieldsSchema = robotSftpStoreInstructionsSchema.extend({ result: z.union([z.literal('debug'), robotSftpStoreInstructionsSchema.shape.result]).optional(), - allowNetwork: z.string().optional().describe(` + allowNetwork: z + .string() + .optional() + .describe(` Network access permission for the SFTP connection. This is used to control which networks the SFTP robot can access. `), }) diff --git a/src/alphalib/types/robots/speech-transcribe.ts b/src/alphalib/types/robots/speech-transcribe.ts index d93ced39..304c6bcd 100644 --- a/src/alphalib/types/robots/speech-transcribe.ts +++ b/src/alphalib/types/robots/speech-transcribe.ts @@ -72,7 +72,10 @@ Transloadit outsources this task and abstracts the interface so you can expect t granularity: granularitySchema.describe(` Whether to return a full response (\`"full"\`), or a flat list of descriptions (\`"list"\`). `), - format: z.enum(['json', 'meta', 'srt', 'meta', 'text', 'webvtt']).default('json').describe(` + format: z + .enum(['json', 'meta', 'srt', 'meta', 'text', 'webvtt']) + .default('json') + .describe(` Output format for the transcription. - \`"text"\` outputs a plain text file that you can store and process. @@ -81,13 +84,19 @@ Output format for the transcription. - \`"meta"\` does not return a file, but stores the data inside Transloadit's file object (under \`\${file.meta.transcription.text}\`) that's passed around between encoding Steps, so that you can use the values to burn the data into videos, filter on them, etc. `), // TODO determine the list of languages - source_language: z.string().default('en-US').describe(` + source_language: z + .string() + .default('en-US') + .describe(` The spoken language of the audio or video. This will also be the language of the transcribed text. The language should be specified in the [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) format, such as \`"en-GB"\`, \`"de-DE"\` or \`"fr-FR"\`. Please also consult the list of supported languages for [the \`gcp\` provider](https://cloud.google.com/speech-to-text/docs/languages) and the [the \`aws\` provider](https://docs.aws.amazon.com/transcribe/latest/dg/what-is-transcribe.html). `), // TODO determine the list of languages - target_language: z.string().default('en-US').describe(` + target_language: z + .string() + .default('en-US') + .describe(` This will also be the language of the written text. The language should be specified in the [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) format, such as \`"en-GB"\`, \`"de-DE"\` or \`"fr-FR"\`. Please consult the list of supported languages and voices. diff --git a/src/alphalib/types/robots/supabase-store.ts b/src/alphalib/types/robots/supabase-store.ts index d1b2073e..0624e146 100644 --- a/src/alphalib/types/robots/supabase-store.ts +++ b/src/alphalib/types/robots/supabase-store.ts @@ -46,15 +46,26 @@ export const robotSupabaseStoreInstructionsSchema = robotBase .merge(supabaseBase) .extend({ robot: z.literal('/supabase/store'), - path: z.string().default('${unique_prefix}/${file.url_name}').describe(` + path: z + .string() + .default('${unique_prefix}/${file.url_name}') + .describe(` The path at which the file is to be stored. This may include any available [Assembly variables](/docs/topics/assembly-instructions/#assembly-variables). The path must not be a directory. `), - headers: z.record(z.string()).default({ 'Content-Type': '${file.mime}' }).describe(` + headers: z + .record(z.string()) + .default({ 'Content-Type': '${file.mime}' }) + .describe(` An object containing a list of headers to be set for this file on supabase Spaces, such as \`{ FileURL: "\${file.url_name}" }\`. This can also include any available [Assembly Variables](/docs/topics/assembly-instructions/#assembly-variables). Object Metadata can be specified using \`x-amz-meta-*\` headers. Note that these headers [do not support non-ASCII metadata values](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html#UserMetadata). `), - sign_urls_for: z.number().int().min(0).optional().describe(` + sign_urls_for: z + .number() + .int() + .min(0) + .optional() + .describe(` This parameter provides signed URLs in the result JSON (in the \`signed_ssl_url\` property). The number that you set this parameter to is the URL expiry time in seconds. If this parameter is not used, no URL signing is done. `), }) diff --git a/src/alphalib/types/robots/swift-store.ts b/src/alphalib/types/robots/swift-store.ts index 46b11289..fb6b0aab 100644 --- a/src/alphalib/types/robots/swift-store.ts +++ b/src/alphalib/types/robots/swift-store.ts @@ -47,18 +47,32 @@ export const robotSwiftStoreInstructionsSchema = robotBase .extend({ robot: z.literal('/swift/store').describe(` The URL to the result file in your OpenStack bucket will be returned in the Assembly Status JSON.`), - path: z.string().default('${unique_prefix}/${file.url_name}').describe(` + path: z + .string() + .default('${unique_prefix}/${file.url_name}') + .describe(` The path at which the file is to be stored. This may include any available [Assembly variables](/docs/topics/assembly-instructions/#assembly-variables). The path must not be a directory. `), - acl: z.enum(['private', 'public-read']).default('public-read').describe(` + acl: z + .enum(['private', 'public-read']) + .default('public-read') + .describe(` The permissions used for this file. `), - headers: z.record(z.string()).default({ 'Content-Type': '${file.mime}' }).describe(` + headers: z + .record(z.string()) + .default({ 'Content-Type': '${file.mime}' }) + .describe(` An object containing a list of headers to be set for this file on swift Spaces, such as \`{ FileURL: "\${file.url_name}" }\`. This can also include any available [Assembly Variables](/docs/topics/assembly-instructions/#assembly-variables). Object Metadata can be specified using \`x-amz-meta-*\` headers. Note that these headers [do not support non-ASCII metadata values](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html#UserMetadata). `), - sign_urls_for: z.number().int().min(0).optional().describe(` + sign_urls_for: z + .number() + .int() + .min(0) + .optional() + .describe(` This parameter provides signed URLs in the result JSON (in the \`signed_ssl_url\` property). The number that you set this parameter to is the URL expiry time in seconds. If this parameter is not used, no URL signing is done. `), }) diff --git a/src/alphalib/types/robots/text-speak.ts b/src/alphalib/types/robots/text-speak.ts index 4524db56..1906687f 100644 --- a/src/alphalib/types/robots/text-speak.ts +++ b/src/alphalib/types/robots/text-speak.ts @@ -84,7 +84,10 @@ You can use the audio that we return in your application, or you can pass the au Another common use case is making your product accessible to people with a reading disability. `), - prompt: z.string().nullish().describe(` + prompt: z + .string() + .nullish() + .describe(` Which text to speak. You can also set this to \`null\` and supply an input text file. `), provider: aiProviderSchema.describe(` @@ -93,17 +96,24 @@ Which AI provider to leverage. Transloadit outsources this task and abstracts the interface so you can expect the same data structures, but different latencies and information being returned. Different cloud vendors have different areas they shine in, and we recommend to try out and see what yields the best results for your use case. `), // TODO determine the list of languages - target_language: z.string().default('en-US').describe(` + target_language: z + .string() + .default('en-US') + .describe(` The written language of the document. This will also be the language of the spoken text. The language should be specified in the [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) format, such as \`"en-GB"\`, \`"de-DE"\` or \`"fr-FR"\`. Please consult the list of supported languages and voices. `), voice: z .enum(['female-1', 'female-2', 'female-3', 'female-child-1', 'male-1', 'male-child-1']) - .default('female-1').describe(` + .default('female-1') + .describe(` The gender to be used for voice synthesis. Please consult the list of supported languages and voices. `), - ssml: z.boolean().default(false).describe(` + ssml: z + .boolean() + .default(false) + .describe(` Supply [Speech Synthesis Markup Language](https://en.wikipedia.org/wiki/Speech_Synthesis_Markup_Language) instead of raw text, in order to gain more control over how your text is voiced, including rests and pronounciations. Please see the supported syntaxes for [AWS](https://docs.aws.amazon.com/polly/latest/dg/supportedtags.html) and [GCP](https://cloud.google.com/text-to-speech/docs/ssml). diff --git a/src/alphalib/types/robots/tigris-store.ts b/src/alphalib/types/robots/tigris-store.ts index c9824e60..02aa0dda 100644 --- a/src/alphalib/types/robots/tigris-store.ts +++ b/src/alphalib/types/robots/tigris-store.ts @@ -48,18 +48,32 @@ export const robotTigrisStoreInstructionsSchema = robotBase robot: z.literal('/tigris/store').describe(` The URL to the result file will be returned in the Assembly Status JSON. `), - path: z.string().default('${unique_prefix}/${file.url_name}').describe(` + path: z + .string() + .default('${unique_prefix}/${file.url_name}') + .describe(` The path at which the file is to be stored. This may include any available [Assembly variables](/docs/topics/assembly-instructions/#assembly-variables). The path must not be a directory. `), - acl: z.enum(['private', 'public-read']).default('public-read').describe(` + acl: z + .enum(['private', 'public-read']) + .default('public-read') + .describe(` The permissions used for this file. `), - headers: z.record(z.string()).default({ 'Content-Type': '${file.mime}' }).describe(` + headers: z + .record(z.string()) + .default({ 'Content-Type': '${file.mime}' }) + .describe(` An object containing a list of headers to be set for this file on Tigris, such as \`{ FileURL: "\${file.url_name}" }\`. This can also include any available [Assembly Variables](/docs/topics/assembly-instructions/#assembly-variables). Object Metadata can be specified using \`x-amz-meta-*\` headers. Note that these headers [do not support non-ASCII metadata values](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html#UserMetadata). `), - sign_urls_for: z.number().int().min(0).optional().describe(` + sign_urls_for: z + .number() + .int() + .min(0) + .optional() + .describe(` This parameter provides signed URLs in the result JSON (in the \`signed_ssl_url\` property). The number that you set this parameter to is the URL expiry time in seconds. If this parameter is not used, no URL signing is done. diff --git a/src/alphalib/types/robots/tus-store.ts b/src/alphalib/types/robots/tus-store.ts index 7085393a..bfbf30f5 100644 --- a/src/alphalib/types/robots/tus-store.ts +++ b/src/alphalib/types/robots/tus-store.ts @@ -55,13 +55,23 @@ Since Vimeo works with OAuth, you will need to generate [Template Credentials](h To change the \`title\` or \`description\` per video, we recommend to [inject variables into your Template](/docs/topics/templates/). `), - endpoint: z.string().url().describe('The URL of the destination Tus server').describe(` + endpoint: z + .string() + .url() + .describe('The URL of the destination Tus server') + .describe(` The URL of the Tus-compatible server, which you're uploading files to. `), - credentials: z.string().optional().describe(` + credentials: z + .string() + .optional() + .describe(` Create Template Credentials for this Robot in your [Transloadit account](/c/template-credentials/) and use the name of the Template Credentials as this parameter's value. For this Robot, use the HTTP template, which allows request headers to be passed along to the destination server. `), - headers: z.record(z.string()).default({}).describe('Headers to pass along to destination') + headers: z + .record(z.string()) + .default({}) + .describe('Headers to pass along to destination') .describe(` Optional extra headers outside of the Template Credentials can be passed along within this parameter. @@ -69,13 +79,20 @@ Although, we recommend to exclusively use Template Credentials, this `), metadata: z .record(z.string()) - .default({ filename: 'example.png', basename: 'example', extension: 'png' }).describe(` + .default({ filename: 'example.png', basename: 'example', extension: 'png' }) + .describe(` Metadata to pass along to destination. Includes some file info by default. `), - url_template: z.string().optional().describe(` + url_template: z + .string() + .optional() + .describe(` The URL of the file in the Assembly Status JSON. The following [Assembly Variables](/docs/topics/assembly-instructions/#assembly-variables) are supported. If this is not specified, the upload URL specified by the destination server will be used instead. `), - ssl_url_template: z.string().optional().describe(` + ssl_url_template: z + .string() + .optional() + .describe(` The SSL URL of the file in the Assembly Status JSON. The following [Assembly Variables](/docs/topics/assembly-instructions/#assembly-variables) are supported. If this is not specified, the upload URL specified by the destination server will be used instead, as long as it starts with \`https\`. `), }) diff --git a/src/alphalib/types/robots/video-adaptive.ts b/src/alphalib/types/robots/video-adaptive.ts index 655e309d..8605f5c9 100644 --- a/src/alphalib/types/robots/video-adaptive.ts +++ b/src/alphalib/types/robots/video-adaptive.ts @@ -11,7 +11,7 @@ import { export const meta: RobotMetaInput = { allowed_for_url_transform: false, - bytescount: Infinity, + bytescount: Number.POSITIVE_INFINITY, discount_factor: 1, discount_pct: 0, example_code: { @@ -117,16 +117,29 @@ The Robot gives its result files (segments, initialization segments, In the \`path\` parameter of the storage Robot of your choice, use the Assembly Variable \`\${file.meta.relative_path}\` to store files in the proper paths to make the playlist files work. `), - technique: z.enum(['dash', 'hls']).default('dash').describe(` + technique: z + .enum(['dash', 'hls']) + .default('dash') + .describe(` Determines which streaming technique should be used. Currently supports \`"dash"\` for MPEG-Dash and \`"hls"\` for HTTP Live Streaming. `), - playlist_name: z.string().optional().describe(` + playlist_name: z + .string() + .optional() + .describe(` The filename for the generated manifest/playlist file. The default is \`"playlist.mpd"\` if your \`technique\` is \`"dash"\`, and \`"playlist.m3u8"\` if your \`technique\` is \`"hls"\`. `), - segment_duration: z.number().int().default(10).describe(` + segment_duration: z + .number() + .int() + .default(10) + .describe(` The duration for each segment in seconds. `), - closed_captions: z.boolean().default(true).describe(` + closed_captions: z + .boolean() + .default(true) + .describe(` Determines whether you want closed caption support when using the \`"hls"\` technique. `), }) diff --git a/src/alphalib/types/robots/video-concat.ts b/src/alphalib/types/robots/video-concat.ts index f0c61a68..90cad860 100644 --- a/src/alphalib/types/robots/video-concat.ts +++ b/src/alphalib/types/robots/video-concat.ts @@ -72,14 +72,20 @@ export const robotVideoConcatInstructionsSchema = robotBase Itʼs possible to concatenate a virtually infinite number of video files using [🤖/video/concat](/docs/robots/video-concat/). `), - video_fade_seconds: z.number().default(1).describe(` + video_fade_seconds: z + .number() + .default(1) + .describe(` When used this adds a video fade in and out effect between each section of your concatenated video. The float value is used so if you want a video delay effect of 500 milliseconds between each video section you would select \`0.5\`, however, integer values can also be represented. This parameter does not add a video fade effect at the beginning or end of your video. If you want to do so, create an additional [🤖/video/encode](/docs/robots/video-encode/) Step and use our \`ffmpeg\` parameter as shown in this [demo](/demos/video-encoding/concatenate-fade-effect/). Please note this parameter is independent of adding audio fades between sections. `), - audio_fade_seconds: z.number().default(1).describe(` + audio_fade_seconds: z + .number() + .default(1) + .describe(` When used this adds an audio fade in and out effect between each section of your concatenated video. The float value is used so if you want an audio delay effect of 500 milliseconds between each video section you would select \`0.5\`, however, integer values can also be represented. This parameter does not add an audio fade effect at the beginning or end of your video. If you want to do so, create an additional [🤖/video/encode](/docs/robots/video-encode/] Step and use our \`ffmpeg\` parameter as shown in this [demo](/demos/audio-encoding/ffmpeg-fade-in-and-out/). diff --git a/src/alphalib/types/robots/video-merge.ts b/src/alphalib/types/robots/video-merge.ts index 7d351418..29737dbd 100644 --- a/src/alphalib/types/robots/video-merge.ts +++ b/src/alphalib/types/robots/video-merge.ts @@ -51,31 +51,54 @@ The background color of the resulting video the \`"rrggbbaa"\` format (red, gree `), framerate: z .union([z.number().int().min(1), z.string().regex(/^\d+(?:\/\d+)?$/)]) - .default('1/5').describe(` + .default('1/5') + .describe(` When merging images to generate a video this is the input framerate. A value of "1/5" means each image is given 5 seconds before the next frame appears (the inverse of a framerate of "5"). Likewise for "1/10", "1/20", etc. A value of "5" means there are 5 frames per second. `), - image_durations: z.array(z.number()).default([]).describe(` + image_durations: z + .array(z.number()) + .default([]) + .describe(` When merging images to generate a video this allows you to define how long (in seconds) each image will be shown inside of the video. So if you pass 3 images and define \`[2.4, 5.6, 9]\` the first image will be shown for 2.4s, the second image for 5.6s and the last one for 9s. The \`duration\` parameter will automatically be set to the sum of the image_durations, so \`17\` in our example. It can still be overwritten, though, in which case the last image will be shown until the defined duration is reached. `), - duration: z.number().default(5).describe(` + duration: z + .number() + .default(5) + .describe(` When merging images to generate a video or when merging audio and video this is the desired target duration in seconds. The float value can take one decimal digit. If you want all images to be displayed exactly once, then you can set the duration according to this formula: \`duration = numberOfImages / framerate\`. This also works for the inverse framerate values like \`1/5\`. If you set this value to \`null\` (default), then the duration of the input audio file will be used when merging images with an audio file. When merging audio files and video files, the duration of the longest video or audio file is used by default. `), - audio_delay: z.number().default(0).describe(` + audio_delay: z + .number() + .default(0) + .describe(` When merging a video and an audio file, and when merging images and an audio file to generate a video, this is the desired delay in seconds for the audio file to start playing. Imagine you merge a video file without sound and an audio file, but you wish the audio to start playing after 5 seconds and not immediately, then this is the parameter to use. `), - loop: z.boolean().default(false).describe(` + loop: z + .boolean() + .default(false) + .describe(` Determines whether the shorter media file should be looped to match the duration of the longer one. For example, if you merge a 1-minute video with a 3-minute audio file and enable this option, the video will play three times in a row to match the audio length.`), - replace_audio: z.boolean().default(false).describe(` + replace_audio: z + .boolean() + .default(false) + .describe(` Determines whether the audio of the video should be replaced with a provided audio file. `), - vstack: z.boolean().default(false).describe(` + vstack: z + .boolean() + .default(false) + .describe(` Stacks the input media vertically. All streams need to have the same pixel format and width - so consider using a [/video/encode](/docs/robots/video-encode/) Step before using this parameter to enforce this. `), - image_url: z.string().url().optional().describe(` + image_url: z + .string() + .url() + .optional() + .describe(` The URL of an image to be merged with the audio or video. When this parameter is provided, the robot will download the image from the URL and merge it with the other media. `), }) diff --git a/src/alphalib/types/robots/video-subtitle.ts b/src/alphalib/types/robots/video-subtitle.ts index 8d85a5de..db0dbf28 100644 --- a/src/alphalib/types/robots/video-subtitle.ts +++ b/src/alphalib/types/robots/video-subtitle.ts @@ -72,17 +72,24 @@ This Robot supports both SRT and VTT subtitle files. subtitles_type: z .enum(['burned', 'external', 'burn']) .transform((val) => (val === 'burn' ? 'burned' : val)) - .default('external').describe(` + .default('external') + .describe(` Determines if subtitles are added as a separate stream to the video (value \`"external"\`) that then can be switched on and off in your video player, or if they should be burned directly into the video (value \`"burned"\` or \`"burn"\`) so that they become part of the video stream. `), - border_style: z.enum(['box', 'outline', 'shadow']).default('outline').describe(` + border_style: z + .enum(['box', 'outline', 'shadow']) + .default('outline') + .describe(` Specifies the style of the subtitle. Use the \`border_color\` parameter to specify the color of the border. `), border_color: color_with_alpha.default('40000000').describe(` The color for the subtitle border. The first two hex digits specify the alpha value of the color. `), // TODO: Make font an enum - font: z.string().default('Arial').describe(` + font: z + .string() + .default('Arial') + .describe(` The font family to use. Also includes boldness and style of the font. [Here](/docs/supported-formats/fonts/) is a list of all supported fonts. @@ -90,16 +97,28 @@ The font family to use. Also includes boldness and style of the font. font_color: color_without_alpha.default('FFFFFF').describe(` The color of the subtitle text. The first two hex digits specify the alpha value of the color. `), - font_size: z.number().int().min(1).default(16).describe(` + font_size: z + .number() + .int() + .min(1) + .default(16) + .describe(` Specifies the size of the text. `), position: positionSchema.default('bottom').describe(` Specifies the position of the subtitles. `), - language: z.string().optional().nullable().describe(` + language: z + .string() + .optional() + .nullable() + .describe(` Specifies the language of the subtitles. Only used if the subtitles are external. `), - keep_subtitles: z.boolean().default(false).describe(` + keep_subtitles: z + .boolean() + .default(false) + .describe(` Specifies if existing subtitles in the input file should be kept or be replaced by the new subtitle. Only used if the subtitles are external. `), }) diff --git a/src/alphalib/types/robots/video-thumbs.ts b/src/alphalib/types/robots/video-thumbs.ts index c28211f6..b2d50dc5 100644 --- a/src/alphalib/types/robots/video-thumbs.ts +++ b/src/alphalib/types/robots/video-thumbs.ts @@ -58,25 +58,49 @@ export const robotVideoThumbsInstructionsSchema = robotBase > [!Note] > Even though thumbnails are extracted from videos in parallel, we sort the thumbnails before adding them to the Assembly results. So the order in which they appear there reflects the order in which they appear in the video. You can also make sure by checking the thumb_index meta key. `), - count: z.number().int().min(1).max(999).default(8).describe(` + count: z + .number() + .int() + .min(1) + .max(999) + .default(8) + .describe(` The number of thumbnails to be extracted. As some videos have incorrect durations, the actual number of thumbnails generated may be less in rare cases. The maximum number of thumbnails we currently allow is 999. The thumbnails are taken at regular intervals, determined by dividing the video duration by the count. For example, a count of 3 will produce thumbnails at 25%, 50% and 75% through the video. To extract thumbnails for specific timestamps, use the \`offsets\` parameter. `), - offsets: z.union([z.array(z.number()), z.array(percentageSchema)]).default([]).describe(` + offsets: z + .union([z.array(z.number()), z.array(percentageSchema)]) + .default([]) + .describe(` An array of offsets representing seconds of the file duration, such as \`[ 2, 45, 120 ]\`. Millisecond durations of a file can also be used by using decimal place values. For example, an offset from 1250 milliseconds would be represented with \`1.25\`. Offsets can also be percentage values such as \`[ "2%", "50%", "75%" ]\`. This option cannot be used with the \`count\` parameter, and takes precedence if both are specified. Out-of-range offsets are silently ignored. `), - format: z.enum(['jpeg', 'jpg', 'png']).default('jpeg').describe(` + format: z + .enum(['jpeg', 'jpg', 'png']) + .default('jpeg') + .describe(` The format of the extracted thumbnail. Supported values are \`"jpg"\`, \`"jpeg"\` and \`"png"\`. Even if you specify the format to be \`"jpeg"\` the resulting thumbnails will have a \`"jpg"\` file extension. `), - width: z.number().int().min(1).max(1920).optional().describe(` + width: z + .number() + .int() + .min(1) + .max(1920) + .optional() + .describe(` The width of the thumbnail, in pixels. Defaults to the original width of the video. `), - height: z.number().int().min(1).max(1080).optional().describe(` + height: z + .number() + .int() + .min(1) + .max(1080) + .optional() + .describe(` The height of the thumbnail, in pixels. Defaults to the original height of the video. `), resize_strategy: resize_strategy.describe(` @@ -87,10 +111,14 @@ The background color of the resulting thumbnails in the \`"rrggbbaa"\` format (r `), rotate: z .union([z.literal(0), z.literal(90), z.literal(180), z.literal(270), z.literal(360)]) - .default(0).describe(` + .default(0) + .describe(` Forces the video to be rotated by the specified degree integer. Currently, only multiples of 90 are supported. We automatically correct the orientation of many videos when the orientation is provided by the camera. This option is only useful for videos requiring rotation because it was not detected by the camera. `), - input_codec: z.string().optional().describe(` + input_codec: z + .string() + .optional() + .describe(` Specifies the input codec to use when decoding the video. This is useful for videos with special codecs that require specific decoders. `), }) diff --git a/src/alphalib/types/robots/vimeo-store.ts b/src/alphalib/types/robots/vimeo-store.ts index 15d8dfd8..a7c7161e 100644 --- a/src/alphalib/types/robots/vimeo-store.ts +++ b/src/alphalib/types/robots/vimeo-store.ts @@ -55,7 +55,8 @@ The description of the video to be displayed on Vimeo. `), acl: z .enum(['anybody', 'contacts', 'disable', 'nobody', 'password', 'unlisted', 'users']) - .default('anybody').describe(` + .default('anybody') + .describe(` Controls access permissions for the video. Here are the valid values: - \`"anybody"\` — anyone can access the video. @@ -66,23 +67,39 @@ Controls access permissions for the video. Here are the valid values: - \`"unlisted"\` — only those with the private link can access the video. - \`"users"\` — only Vimeo members can access the video. `), - password: z.string().optional().describe(` + password: z + .string() + .optional() + .describe(` The password to access the video if \`acl\` is \`"password"\`. `), - showcases: z.array(z.string()).default([]).describe(` + showcases: z + .array(z.string()) + .default([]) + .describe(` An array of string IDs of showcases that you want to add the video to. The IDs can be found when browsing Vimeo. For example \`https://vimeo.com/manage/showcases/[SHOWCASE_ID]/info\`. `), - downloadable: z.boolean().default(false).describe(` + downloadable: z + .boolean() + .default(false) + .describe(` Whether or not the video can be downloaded from the Vimeo website. Only set this to \`true\` if you have unlocked this feature in your Vimeo accounting by upgrading to their "Pro" plan. If you use it while on their Freemium plan, the Vimeo API will return an \`"Invalid parameter supplied"\` error. `), - folder_id: z.string().nullable().default(null).describe(` + folder_id: z + .string() + .nullable() + .default(null) + .describe(` The ID of the folder to which the video is uploaded. When visiting one of your folders, the URL is similar to \`https://vimeo.com/manage/folders/xxxxxxxx\`. The folder_id would be \`"xxxxxxxx"\`. `), - folder_uri: z.string().optional().describe(` + folder_uri: z + .string() + .optional() + .describe(` Deprecated. Please use \`folder_id\` instead. The URI of the folder to which the video is uploaded. `), }) diff --git a/src/alphalib/types/robots/wasabi-store.ts b/src/alphalib/types/robots/wasabi-store.ts index 66dcf239..4304424b 100644 --- a/src/alphalib/types/robots/wasabi-store.ts +++ b/src/alphalib/types/robots/wasabi-store.ts @@ -48,18 +48,32 @@ export const robotWasabiStoreInstructionsSchema = robotBase robot: z.literal('/wasabi/store').describe(` The URL to the result file will be returned in the Assembly Status JSON. `), - path: z.string().default('${unique_prefix}/${file.url_name}').describe(` + path: z + .string() + .default('${unique_prefix}/${file.url_name}') + .describe(` The path at which the file is to be stored. This may include any available [Assembly variables](/docs/topics/assembly-instructions/#assembly-variables). The path must not be a directory. `), - acl: z.enum(['private', 'public-read']).default('public-read').describe(` + acl: z + .enum(['private', 'public-read']) + .default('public-read') + .describe(` The permissions used for this file. `), - headers: z.record(z.string()).default({ 'Content-Type': '${file.mime}' }).describe(` + headers: z + .record(z.string()) + .default({ 'Content-Type': '${file.mime}' }) + .describe(` An object containing a list of headers to be set for this file on Wasabi Spaces, such as \`{ FileURL: "\${file.url_name}" }\`. This can also include any available [Assembly Variables](/docs/topics/assembly-instructions/#assembly-variables). Object Metadata can be specified using \`x-amz-meta-*\` headers. Note that these headers [do not support non-ASCII metadata values](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html#UserMetadata). `), - sign_urls_for: z.number().int().min(0).optional().describe(` + sign_urls_for: z + .number() + .int() + .min(0) + .optional() + .describe(` This parameter provides signed URLs in the result JSON (in the \`signed_ssl_url\` property). The number that you set this parameter to is the URL expiry time in seconds. If this parameter is not used, no URL signing is done. `), }) diff --git a/src/alphalib/types/robots/youtube-store.ts b/src/alphalib/types/robots/youtube-store.ts index a89a66e4..b20a2b29 100644 --- a/src/alphalib/types/robots/youtube-store.ts +++ b/src/alphalib/types/robots/youtube-store.ts @@ -76,7 +76,10 @@ If you encounter an error such as "The authenticated user doesnʼt have permissi credentials: z.string().describe(` The authentication Template credentials used for your YouTube account. You can generate them on the [Template Credentials page](/c/template-credentials/). Simply add the name of your YouTube channel, and you will be redirected to a Google verification page. Accept the presented permissions and you will be good to go. `), - title: z.string().max(80).describe(` + title: z + .string() + .max(80) + .describe(` The title of the video to be displayed on YouTube. Note that since the YouTube API requires titles to be within 80 characters, longer titles may be truncated. @@ -84,25 +87,27 @@ Note that since the YouTube API requires titles to be within 80 characters, long description: z.string().describe(` The description of the video to be displayed on YouTube. This can be up to 5000 characters, including \`\\n\` for new-lines. `), - category: z.preprocess( - (val) => (typeof val === 'string' ? val.toLowerCase() : val), - z.enum([ - 'autos & vehicles', - 'comedy', - 'education', - 'entertainment', - 'film & animation', - 'gaming', - 'howto & style', - 'music', - 'news & politics', - 'people & blogs', - 'pets & animals', - 'science & technology', - 'sports', - 'travel & events', - ]), - ).describe(` + category: z + .preprocess( + (val) => (typeof val === 'string' ? val.toLowerCase() : val), + z.enum([ + 'autos & vehicles', + 'comedy', + 'education', + 'entertainment', + 'film & animation', + 'gaming', + 'howto & style', + 'music', + 'news & politics', + 'people & blogs', + 'pets & animals', + 'science & technology', + 'sports', + 'travel & events', + ]), + ) + .describe(` The category to which this video will be assigned. `), keywords: z.string().describe(`