@transloadit/node 6.5.0 → 6.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/dist/alphalib/renderSimpleValue.d.ts +14 -0
  2. package/dist/alphalib/renderSimpleValue.d.ts.map +1 -0
  3. package/dist/alphalib/renderSimpleValue.js +87 -0
  4. package/dist/alphalib/renderSimpleValue.js.map +1 -0
  5. package/dist/alphalib/truncateString.d.ts +5 -0
  6. package/dist/alphalib/truncateString.d.ts.map +1 -0
  7. package/dist/alphalib/truncateString.js +19 -0
  8. package/dist/alphalib/truncateString.js.map +1 -0
  9. package/dist/alphalib/types/robots/_instructions-primitives.d.ts +6 -0
  10. package/dist/alphalib/types/robots/_instructions-primitives.d.ts.map +1 -1
  11. package/dist/alphalib/types/robots/_instructions-primitives.js +29 -7
  12. package/dist/alphalib/types/robots/_instructions-primitives.js.map +1 -1
  13. package/dist/alphalib/types/robots/_video-generate.d.ts +34 -0
  14. package/dist/alphalib/types/robots/_video-generate.d.ts.map +1 -0
  15. package/dist/alphalib/types/robots/_video-generate.js +157 -0
  16. package/dist/alphalib/types/robots/_video-generate.js.map +1 -0
  17. package/dist/alphalib/types/robots/ai-chat.d.ts +2 -0
  18. package/dist/alphalib/types/robots/ai-chat.d.ts.map +1 -1
  19. package/dist/alphalib/types/robots/ai-chat.js +7 -5
  20. package/dist/alphalib/types/robots/ai-chat.js.map +1 -1
  21. package/dist/alphalib/types/robots/audio-concat.d.ts.map +1 -1
  22. package/dist/alphalib/types/robots/audio-concat.js +5 -5
  23. package/dist/alphalib/types/robots/audio-concat.js.map +1 -1
  24. package/dist/alphalib/types/robots/azure-import.d.ts.map +1 -1
  25. package/dist/alphalib/types/robots/azure-import.js +3 -3
  26. package/dist/alphalib/types/robots/azure-import.js.map +1 -1
  27. package/dist/alphalib/types/robots/document-convert.d.ts.map +1 -1
  28. package/dist/alphalib/types/robots/document-convert.js +7 -5
  29. package/dist/alphalib/types/robots/document-convert.js.map +1 -1
  30. package/dist/alphalib/types/robots/document-extract.d.ts +8 -8
  31. package/dist/alphalib/types/robots/document-extract.d.ts.map +1 -1
  32. package/dist/alphalib/types/robots/document-extract.js +18 -2
  33. package/dist/alphalib/types/robots/document-extract.js.map +1 -1
  34. package/dist/alphalib/types/robots/document-split.d.ts +12 -0
  35. package/dist/alphalib/types/robots/document-split.d.ts.map +1 -1
  36. package/dist/alphalib/types/robots/document-split.js +15 -2
  37. package/dist/alphalib/types/robots/document-split.js.map +1 -1
  38. package/dist/alphalib/types/robots/file-decompress.d.ts.map +1 -1
  39. package/dist/alphalib/types/robots/file-decompress.js +2 -0
  40. package/dist/alphalib/types/robots/file-decompress.js.map +1 -1
  41. package/dist/alphalib/types/robots/file-preview.d.ts +22 -0
  42. package/dist/alphalib/types/robots/file-preview.d.ts.map +1 -1
  43. package/dist/alphalib/types/robots/file-preview.js +43 -26
  44. package/dist/alphalib/types/robots/file-preview.js.map +1 -1
  45. package/dist/alphalib/types/robots/http-request.d.ts.map +1 -1
  46. package/dist/alphalib/types/robots/http-request.js +9 -14
  47. package/dist/alphalib/types/robots/http-request.js.map +1 -1
  48. package/dist/alphalib/types/robots/image-enhance.d.ts +8 -8
  49. package/dist/alphalib/types/robots/image-enhance.js +2 -2
  50. package/dist/alphalib/types/robots/image-resize.d.ts.map +1 -1
  51. package/dist/alphalib/types/robots/image-resize.js +3 -1
  52. package/dist/alphalib/types/robots/image-resize.js.map +1 -1
  53. package/dist/alphalib/types/robots/image-upscale.js +1 -1
  54. package/dist/alphalib/types/robots/image-upscale.js.map +1 -1
  55. package/dist/alphalib/types/robots/s3-import.d.ts.map +1 -1
  56. package/dist/alphalib/types/robots/s3-import.js +14 -15
  57. package/dist/alphalib/types/robots/s3-import.js.map +1 -1
  58. package/dist/alphalib/types/robots/supabase-store.d.ts +16 -6
  59. package/dist/alphalib/types/robots/supabase-store.d.ts.map +1 -1
  60. package/dist/alphalib/types/robots/supabase-store.js +23 -1
  61. package/dist/alphalib/types/robots/supabase-store.js.map +1 -1
  62. package/dist/alphalib/types/robots/tigris-store.d.ts.map +1 -1
  63. package/dist/alphalib/types/robots/tigris-store.js +3 -4
  64. package/dist/alphalib/types/robots/tigris-store.js.map +1 -1
  65. package/dist/alphalib/types/robots/transloadit-import.d.ts +2 -2
  66. package/dist/alphalib/types/robots/transloadit-import.d.ts.map +1 -1
  67. package/dist/alphalib/types/robots/transloadit-import.js +4 -1
  68. package/dist/alphalib/types/robots/transloadit-import.js.map +1 -1
  69. package/dist/alphalib/types/robots/transloadit-store.d.ts +2 -3
  70. package/dist/alphalib/types/robots/transloadit-store.d.ts.map +1 -1
  71. package/dist/alphalib/types/robots/transloadit-store.js +19 -0
  72. package/dist/alphalib/types/robots/transloadit-store.js.map +1 -1
  73. package/dist/alphalib/types/robots/video-adaptive.d.ts.map +1 -1
  74. package/dist/alphalib/types/robots/video-adaptive.js +12 -0
  75. package/dist/alphalib/types/robots/video-adaptive.js.map +1 -1
  76. package/dist/alphalib/types/robots/video-concat.d.ts.map +1 -1
  77. package/dist/alphalib/types/robots/video-concat.js +9 -9
  78. package/dist/alphalib/types/robots/video-concat.js.map +1 -1
  79. package/dist/alphalib/types/robots/video-thumbs.d.ts +8 -8
  80. package/dist/alphalib/types/robots/video-thumbs.js +8 -8
  81. package/dist/alphalib/types/robots/video-thumbs.js.map +1 -1
  82. package/dist/alphalib/types/robots/vimeo-store.js +1 -1
  83. package/dist/alphalib/types/template.d.ts +3 -3
  84. package/dist/alphalib/types/templateValues.d.ts +83 -0
  85. package/dist/alphalib/types/templateValues.d.ts.map +1 -0
  86. package/dist/alphalib/types/templateValues.js +117 -0
  87. package/dist/alphalib/types/templateValues.js.map +1 -0
  88. package/dist/cli/stepsInput.d.ts +1 -1
  89. package/dist/cli/stepsInput.d.ts.map +1 -1
  90. package/dist/cli/stepsInput.js +31 -2
  91. package/dist/cli/stepsInput.js.map +1 -1
  92. package/package.json +2 -2
  93. package/src/alphalib/renderSimpleValue.ts +120 -0
  94. package/src/alphalib/truncateString.ts +23 -0
  95. package/src/alphalib/types/robots/_instructions-primitives.ts +34 -7
  96. package/src/alphalib/types/robots/_video-generate.ts +211 -0
  97. package/src/alphalib/types/robots/ai-chat.ts +8 -5
  98. package/src/alphalib/types/robots/audio-concat.ts +5 -4
  99. package/src/alphalib/types/robots/azure-import.ts +3 -4
  100. package/src/alphalib/types/robots/document-convert.ts +8 -5
  101. package/src/alphalib/types/robots/document-extract.ts +18 -2
  102. package/src/alphalib/types/robots/document-split.ts +17 -2
  103. package/src/alphalib/types/robots/file-decompress.ts +2 -0
  104. package/src/alphalib/types/robots/file-preview.ts +44 -25
  105. package/src/alphalib/types/robots/http-request.ts +9 -13
  106. package/src/alphalib/types/robots/image-enhance.ts +2 -2
  107. package/src/alphalib/types/robots/image-resize.ts +3 -1
  108. package/src/alphalib/types/robots/image-upscale.ts +1 -1
  109. package/src/alphalib/types/robots/s3-import.ts +14 -15
  110. package/src/alphalib/types/robots/supabase-store.ts +23 -1
  111. package/src/alphalib/types/robots/tigris-store.ts +2 -3
  112. package/src/alphalib/types/robots/transloadit-import.ts +4 -1
  113. package/src/alphalib/types/robots/transloadit-store.ts +19 -0
  114. package/src/alphalib/types/robots/video-adaptive.ts +12 -0
  115. package/src/alphalib/types/robots/video-concat.ts +9 -8
  116. package/src/alphalib/types/robots/video-thumbs.ts +8 -8
  117. package/src/alphalib/types/robots/vimeo-store.ts +1 -1
  118. package/src/alphalib/types/templateValues.ts +157 -0
  119. package/src/cli/stepsInput.ts +35 -2
@@ -0,0 +1,117 @@
1
+ import { formatSimpleValueReason } from "../renderSimpleValue.js";
2
+ /** Usage in MiB charged for each dynamically evaluated Assembly expression. */
3
+ export const expressionEvaluationUsageMebibytes = 0.2;
4
+ /** Character domain shared by stored Template IDs and their pagination cursors. */
5
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: Stored Template IDs allow the full ASCII range.
6
+ export const storedTemplateIdentifierPattern = /^[\x00-\x7F]*$/u;
7
+ /** Template Assembly Status retention values shared by runtime validation and contracts. */
8
+ export const templateAssemblyStatusExpiries = Object.freeze({
9
+ noTmpFileRetention: 'NoSave',
10
+ oneDay: '1day',
11
+ sevenDays: '7days',
12
+ thirtyDays: '30days',
13
+ ninetyDays: '90days',
14
+ });
15
+ /** Template transcoding-result retention values shared by runtime validation and contracts. */
16
+ export const templateTranscodingResultExpiries = Object.freeze({
17
+ noTmpFileRetention: 'NoSave',
18
+ oneDay: '1day',
19
+ });
20
+ /** Default storage lifecycle selections; separate from upload and execution phase timeouts. */
21
+ export const templateRetentionDefaults = Object.freeze({
22
+ assemblyStatus: templateAssemblyStatusExpiries.ninetyDays,
23
+ transcodingResult: templateTranscodingResultExpiries.oneDay,
24
+ });
25
+ export const templateListFieldValues = [
26
+ 'account_id',
27
+ 'assembly_status_expiry',
28
+ 'cron_auth_key_id',
29
+ 'cron_enabled',
30
+ 'cron_max_concurrent_runs',
31
+ 'cron_region',
32
+ 'cron_schedule_with_seconds',
33
+ 'created',
34
+ 'deleted',
35
+ 'encryption_version',
36
+ 'id',
37
+ 'json',
38
+ 'last_used',
39
+ 'modified',
40
+ 'name',
41
+ 'require_signature_auth',
42
+ 'transcoding_result_expiry',
43
+ ];
44
+ export const templateListDefaultFields = [
45
+ 'id',
46
+ 'name',
47
+ 'json',
48
+ 'encryption_version',
49
+ 'require_signature_auth',
50
+ 'assembly_status_expiry',
51
+ 'transcoding_result_expiry',
52
+ 'last_used',
53
+ 'created',
54
+ 'modified',
55
+ ];
56
+ export const templateListOrderValues = ['asc', 'desc'];
57
+ export const templateListSortValues = ['id', 'name', 'created', 'modified', 'last_used'];
58
+ export const templateIncludeBuiltinModes = ['none', 'latest', 'all'];
59
+ export const templateIncludeBuiltinValues = [
60
+ ...templateIncludeBuiltinModes,
61
+ 'exclusively-latest',
62
+ 'exclusively-all',
63
+ ];
64
+ /** Canonical Template-list defaults shared by API2 and generated clients. */
65
+ export const templateListDefaults = Object.freeze({
66
+ includeBuiltin: 'none',
67
+ keywords: '',
68
+ order: 'desc',
69
+ page: 1,
70
+ pagesize: 850,
71
+ sort: 'created',
72
+ });
73
+ /** Maximum page size accepted by Template listing. */
74
+ export const templateListMaxPageSize = 850;
75
+ /** Code-unit length retained for the private admin Workspace override. */
76
+ export const templateListWorkspaceIdCodeUnits = 32;
77
+ /** Maximum customer-supplied characters retained in a Template-list error reason. */
78
+ export const templateListInvalidRequestValueMaxCharacters = 200;
79
+ /** Handler-priority Template-list validation reasons shared by runtime and contract enforcement. */
80
+ export const templateListInvalidRequestReasons = {
81
+ order: {
82
+ message: 'Invalid order (must be "asc" or "desc")',
83
+ value: 'string',
84
+ },
85
+ sort: {
86
+ message: 'Invalid sort (must be "created", "modified", "name", "id" or "last_used")',
87
+ suffix: '.',
88
+ value: 'string',
89
+ },
90
+ pagesize: {
91
+ message: `Invalid pagesize (must be between 1 and ${templateListMaxPageSize})`,
92
+ suffix: '.',
93
+ value: 'integer-prefix',
94
+ },
95
+ page: {
96
+ message: 'Invalid page',
97
+ suffix: '.',
98
+ value: 'integer-prefix',
99
+ },
100
+ account_id: {
101
+ message: 'Invalid accountId',
102
+ suffix: '.',
103
+ value: 'string',
104
+ },
105
+ include_builtin: {
106
+ message: 'Invalid include_builtin',
107
+ value: 'string',
108
+ },
109
+ };
110
+ /** Formats one established Template-list reason from its shared contract fact. */
111
+ export function formatTemplateListInvalidRequestReason(field, value) {
112
+ const reason = templateListInvalidRequestReasons[field];
113
+ return formatSimpleValueReason(typeof value === 'number' && reason.value === 'integer-prefix'
114
+ ? { ...reason, value: 'string' }
115
+ : reason, value, templateListInvalidRequestValueMaxCharacters);
116
+ }
117
+ //# sourceMappingURL=templateValues.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templateValues.js","sourceRoot":"","sources":["../../../src/alphalib/types/templateValues.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import type { StepsInput } from '../alphalib/types/template.ts';
2
2
  import type { IOutputCtl } from './OutputCtl.ts';
3
3
  import { z } from 'zod';
4
- /** CLI inputs can be partial overrides; API2 validates OCR after merging their runtime context. */
4
+ /** CLI overrides warn on new parameters and defer contextual OCR checks to API2. */
5
5
  export declare function createCliStepsSchema(output?: Pick<IOutputCtl, 'warn'>): z.ZodType<StepsInput>;
6
6
  export declare function parseStepsInputJson(content: string, output?: Pick<IOutputCtl, 'warn'>): StepsInput;
7
7
  export declare function readStepsInputFile(filePath: string, output?: Pick<IOutputCtl, 'warn'>): Promise<StepsInput>;
@@ -1 +1 @@
1
- {"version":3,"file":"stepsInput.d.ts","sourceRoot":"","sources":["../../src/cli/stepsInput.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAA;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAIhD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAUvB,mGAAmG;AACnG,wBAAgB,oBAAoB,CAClC,MAAM,GAAE,IAAI,CAAC,UAAU,EAAE,MAAM,CAAW,GACzC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAevB;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,IAAI,CAAC,UAAU,EAAE,MAAM,CAAW,GACzC,UAAU,CA0CZ;AAED,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,IAAI,CAAC,UAAU,EAAE,MAAM,CAAW,GACzC,OAAO,CAAC,UAAU,CAAC,CAMrB"}
1
+ {"version":3,"file":"stepsInput.d.ts","sourceRoot":"","sources":["../../src/cli/stepsInput.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAA;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAIhD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAUvB,oFAAoF;AACpF,wBAAgB,oBAAoB,CAClC,MAAM,GAAE,IAAI,CAAC,UAAU,EAAE,MAAM,CAAW,GACzC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAgDvB;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,IAAI,CAAC,UAAU,EAAE,MAAM,CAAW,GACzC,UAAU,CA0CZ;AAED,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,IAAI,CAAC,UAAU,EAAE,MAAM,CAAW,GACzC,OAAO,CAAC,UAAU,CAAC,CAMrB"}
@@ -6,9 +6,38 @@ import { refineDocumentExtractOcr } from "../alphalib/types/robots/document-extr
6
6
  import { refineTransloaditImportSelector } from "../alphalib/types/robots/transloadit-import.js";
7
7
  import { CliInputError, formatSchemaIssues } from "./errors.js";
8
8
  const stepsWrapperSchema = z.object({ steps: z.record(z.unknown()) });
9
- /** CLI inputs can be partial overrides; API2 validates OCR after merging their runtime context. */
9
+ /** CLI overrides warn on new parameters and defer contextual OCR checks to API2. */
10
10
  export function createCliStepsSchema(output = console) {
11
- const cliStepSchema = robotsSchema
11
+ const cliStepSchema = z
12
+ .object({ robot: z.string() })
13
+ .catchall(z.unknown())
14
+ .transform((step, context) => {
15
+ let validated = robotsSchema.safeParse(step, { path: context.path });
16
+ const unknownKeys = new Set();
17
+ if (!validated.success) {
18
+ for (const issue of validated.error.issues) {
19
+ // Only new top-level Robot parameters are advisory; nested objects stay strict.
20
+ if (issue.code !== 'unrecognized_keys' || issue.path.length !== context.path.length)
21
+ continue;
22
+ for (const key of issue.keys)
23
+ unknownKeys.add(key);
24
+ }
25
+ if (unknownKeys.size > 0) {
26
+ validated = robotsSchema.safeParse(Object.fromEntries(Object.entries(step).filter(([key]) => !unknownKeys.has(key))), { path: context.path });
27
+ }
28
+ }
29
+ if (!validated.success) {
30
+ for (const issue of validated.error.issues) {
31
+ // Keep nested union diagnostics rooted at the Step while addIssue prefixes its own path.
32
+ context.addIssue({ ...issue, path: issue.path.slice(context.path.length) });
33
+ }
34
+ return z.NEVER;
35
+ }
36
+ if (unknownKeys.size > 0) {
37
+ output.warn(`${context.path.join('.')}: Unrecognized step parameters: ${[...unknownKeys].join(', ')}. Preserving them for API validation when submitted.`);
38
+ }
39
+ return { ...step, ...validated.data };
40
+ })
12
41
  .superRefine(refineTransloaditImportSelector)
13
42
  .superRefine((step, context) => {
14
43
  // API2 merges Template defaults before Robot validation. New OCR checks must not reject
@@ -1 +1 @@
1
- {"version":3,"file":"stepsInput.js","sourceRoot":"","sources":["../../src/cli/stepsInput.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stepsInput.js","sourceRoot":"","sources":["../../src/cli/stepsInput.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@transloadit/node",
3
- "version": "6.5.0",
4
- "description": "Node.js SDK for Transloadit",
3
+ "version": "6.6.1",
4
+ "description": "Node.js SDK and `transloadit` CLI for Transloadit",
5
5
  "homepage": "https://github.com/transloadit/node-sdk/tree/main/packages/node",
6
6
  "bugs": {
7
7
  "url": "https://github.com/transloadit/node-sdk/issues"
@@ -0,0 +1,120 @@
1
+ import { truncateCodePointsWithEllipsis, truncateStringWithEllipsis } from './truncateString.ts'
2
+
3
+ /** A safe scalar rendering policy for one customer-visible validation reason. */
4
+ export interface SimpleValueReason {
5
+ readonly message: string
6
+ readonly suffix?: string
7
+ readonly value: 'integer-prefix' | 'string' | 'trimmed-string'
8
+ }
9
+
10
+ type SimpleArrayItem = string | number | boolean | bigint | null | Date
11
+
12
+ function isSimpleArrayItem(value: unknown): value is SimpleArrayItem {
13
+ return (
14
+ value === null ||
15
+ value instanceof Date ||
16
+ typeof value === 'string' ||
17
+ typeof value === 'number' ||
18
+ typeof value === 'boolean' ||
19
+ typeof value === 'bigint'
20
+ )
21
+ }
22
+
23
+ function isSimpleValueArray(value: unknown): value is SimpleArrayItem[] {
24
+ return Array.isArray(value) && value.every(isSimpleArrayItem)
25
+ }
26
+
27
+ function renderSimpleArrayItem(value: SimpleArrayItem): string {
28
+ return value === null ? '' : String(value)
29
+ }
30
+
31
+ function* renderSimpleArrayCharacters(
32
+ values: readonly SimpleArrayItem[],
33
+ trim: boolean,
34
+ ): Generator<string, void, undefined> {
35
+ for (let index = 0; index < values.length; index += 1) {
36
+ if (index > 0) {
37
+ yield ','
38
+ }
39
+ let renderedItem = renderSimpleArrayItem(values[index])
40
+ if (trim && index === 0) {
41
+ renderedItem = renderedItem.trimStart()
42
+ }
43
+ if (trim && index === values.length - 1) {
44
+ renderedItem = renderedItem.trimEnd()
45
+ }
46
+ yield* renderedItem
47
+ }
48
+ }
49
+
50
+ /**
51
+ * Renders a scalar, Date, or flat scalar array without traversing arbitrary objects. Semantic
52
+ * predicates use the complete string; customer-facing reasons use the bounded formatter below.
53
+ */
54
+ export function renderSimpleValueAsString(value: unknown): string | undefined {
55
+ if (
56
+ typeof value === 'string' ||
57
+ typeof value === 'number' ||
58
+ typeof value === 'boolean' ||
59
+ typeof value === 'bigint'
60
+ ) {
61
+ return String(value)
62
+ }
63
+ if (value === null) {
64
+ return 'null'
65
+ }
66
+ if (value instanceof Date) {
67
+ return Date.prototype.toString.call(value)
68
+ }
69
+ if (isSimpleValueArray(value)) {
70
+ return value.map(renderSimpleArrayItem).join(',')
71
+ }
72
+ return undefined
73
+ }
74
+
75
+ /** Formats a bounded validation reason without traversing or stringifying arbitrary objects. */
76
+ export function formatSimpleValueReason(
77
+ reason: SimpleValueReason,
78
+ value: unknown,
79
+ maxCharacters: number,
80
+ ): string {
81
+ const suffix = reason.suffix ?? ''
82
+ if (reason.value === 'integer-prefix') {
83
+ const renderedValue = renderSimpleValueAsString(value)
84
+ if (renderedValue == null) {
85
+ return `${reason.message}${suffix}`
86
+ }
87
+
88
+ const parsedValue = Number.parseInt(renderedValue, 10)
89
+ const normalizedValue = Number.isFinite(parsedValue) ? String(parsedValue) : renderedValue
90
+ if (normalizedValue === '') {
91
+ return `${reason.message}${suffix}`
92
+ }
93
+ return `${reason.message}: ${truncateStringWithEllipsis(normalizedValue, maxCharacters)}${suffix}`
94
+ }
95
+
96
+ if (Array.isArray(value)) {
97
+ if (!isSimpleValueArray(value)) {
98
+ return `${reason.message}${suffix}`
99
+ }
100
+ const renderedValue = truncateCodePointsWithEllipsis(
101
+ renderSimpleArrayCharacters(value, reason.value === 'trimmed-string'),
102
+ maxCharacters,
103
+ )
104
+ return renderedValue === ''
105
+ ? `${reason.message}${suffix}`
106
+ : `${reason.message}: ${renderedValue}${suffix}`
107
+ }
108
+
109
+ const renderedValue = renderSimpleValueAsString(value)
110
+ if (renderedValue == null) {
111
+ return `${reason.message}${suffix}`
112
+ }
113
+
114
+ const normalizedValue = reason.value === 'trimmed-string' ? renderedValue.trim() : renderedValue
115
+ if (normalizedValue === '') {
116
+ return `${reason.message}${suffix}`
117
+ }
118
+
119
+ return `${reason.message}: ${truncateStringWithEllipsis(normalizedValue, maxCharacters)}${suffix}`
120
+ }
@@ -0,0 +1,23 @@
1
+ /** Lazily truncates Unicode code points and marks a truncated value with an ellipsis. */
2
+ export function truncateCodePointsWithEllipsis(
3
+ codePoints: Iterable<string>,
4
+ maxCharacters: number,
5
+ ): string {
6
+ if (!Number.isSafeInteger(maxCharacters) || maxCharacters < 0) {
7
+ throw new Error('String truncation requires a nonnegative safe character limit')
8
+ }
9
+
10
+ const characters: string[] = []
11
+ for (const character of codePoints) {
12
+ if (characters.length === maxCharacters) {
13
+ return `${characters.join('')}…`
14
+ }
15
+ characters.push(character)
16
+ }
17
+ return characters.join('')
18
+ }
19
+
20
+ /** Truncates a string by Unicode code points and marks a truncated value with an ellipsis. */
21
+ export function truncateStringWithEllipsis(value: string, maxCharacters: number): string {
22
+ return truncateCodePointsWithEllipsis(value, maxCharacters)
23
+ }
@@ -828,6 +828,22 @@ const deprecatedFfmpegVersions = formatEnglishList([
828
828
  ),
829
829
  ])
830
830
 
831
+ /** Common per-input concat fade behavior; Robot-specific transition controls stay owner-local. */
832
+ export function getConcatFadeDescription(media: 'audio' | 'video'): string {
833
+ const timing =
834
+ media === 'audio'
835
+ ? 'Audio fade-outs start on a whole-second boundary and may finish before the input ends.'
836
+ : 'Video fade durations are rounded down to whole frames and capped at the duration of each input.'
837
+
838
+ return `
839
+ When concatenating at least two files, a positive value fades out the ${media} of each input and fades in every input after the first. There is no fade-in at the beginning of the output, but the fade-out is also applied to the last input.
840
+
841
+ The value is a duration in seconds. For example, \`0.5\` means 500 milliseconds. Omit this parameter or set it to \`0\` to disable these per-input fades. They do not overlap clips or insert additional time between them.
842
+
843
+ ${timing}
844
+ `
845
+ }
846
+
831
847
  export const robotParameterDocs = {
832
848
  adaptive_filtering: {
833
849
  description: `
@@ -2075,6 +2091,12 @@ export const vimeoBase = z
2075
2091
  .optional()
2076
2092
  .describe(`
2077
2093
  Please create your associated <dfn>Template Credentials</dfn> in your Transloadit account and use the name of your <dfn>Template Credentials</dfn> as this parameter's value. They will contain the values for your Vimeo access token.
2094
+
2095
+ For /vimeo/import, create your own app at [developer.vimeo.com/apps](https://developer.vimeo.com/apps), open \`Generate Access Token\`, choose \`Authenticated (you)\`, and select \`Public\`, \`Private\`, and \`Video Files\` (\`public private video_files\`). Generate the personal access token, then choose **Vimeo** and **Paste a personal access token** in the Console. The token is stored as \`access_token\` and is never displayed back in the Console. Saving checks your Vimeo account and the token’s scopes. Video file links also require an eligible Vimeo account and video permissions.
2096
+
2097
+ Vimeo OAuth in the Console supports /vimeo/store. It cannot grant \`video_files\` for other members’ accounts because Transloadit is not a Vimeo partner. Imports require your own personal access token. To use that token for /vimeo/store too, also grant \`Upload\`, \`Edit\`, and \`Interact\` (\`upload edit interact\`) and ensure your Vimeo app has upload access.
2098
+
2099
+ Updating a credential does not run OAuth again or add permissions. To reconnect, **Remove** the credential (which revokes its token at Vimeo), then create a new credential with the same name. For a personal token, generate a new one before saving it again. Revocation also affects any other use of that token. See the [Vimeo credential instructions](/docs/topics/template-credentials/#vimeo).
2078
2100
  `),
2079
2101
  })
2080
2102
  .strict()
@@ -2172,6 +2194,9 @@ While we recommend to use <dfn>Template Credentials</dfn> at all times, some use
2172
2194
  })
2173
2195
  .strict()
2174
2196
 
2197
+ /** Default SSH/SFTP port when no explicit connection port is supplied. */
2198
+ export const sftpDefaultPort = 22
2199
+
2175
2200
  export type SftpBase = z.infer<typeof sftpBase>
2176
2201
  export const sftpBase = z
2177
2202
  .object({
@@ -2184,7 +2209,7 @@ Please create your associated <dfn>Template Credentials</dfn> in your Transloadi
2184
2209
  While we recommend to use <dfn>Template Credentials</dfn> at all times, some use cases demand dynamic credentials for which using <dfn>Template Credentials</dfn> 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).
2185
2210
  `),
2186
2211
  host: z.string().optional(),
2187
- port: port.default(21).describe('The port to use for the FTP connection.'),
2212
+ port: port.default(sftpDefaultPort).describe('The port to use for the SFTP connection.'),
2188
2213
  user: z.string().optional(),
2189
2214
  public_key: z.string().optional(),
2190
2215
  })
@@ -2333,6 +2358,11 @@ export const filterConditionPartSchema = z.tuple([
2333
2358
  export type FilterCondition = z.infer<typeof filterCondition>
2334
2359
  export const filterCondition = z.union([z.null(), z.string(), z.array(filterConditionPartSchema)])
2335
2360
 
2361
+ /** English Turbo guidance shared by the public parameter and supporting video FAQ. */
2362
+ export const videoTurboParameterDocumentation = `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.
2363
+
2364
+ VP8 output and unresolved video-codec expressions use normal encoding even when \`turbo\` is \`true\`.`
2365
+
2336
2366
  /**
2337
2367
  * Parameters specific to the /video/encode robot. Useful for typing robots that pass files to /video/encode.
2338
2368
  */
@@ -2391,12 +2421,7 @@ Forces the video to be rotated by the specified degree integer. Currently, only
2391
2421
  .describe(`
2392
2422
  Enables hinting for mp4 files, for RTP/RTSP streaming.
2393
2423
  `),
2394
- turbo: z
2395
- .boolean()
2396
- .default(false)
2397
- .describe(`
2398
- 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 <dfn>Priority Job Slots</dfn> and may prove to be counter-productive for very small video files.
2399
- `),
2424
+ turbo: z.boolean().default(false).describe(videoTurboParameterDocumentation),
2400
2425
  chunk_duration: z
2401
2426
  .number()
2402
2427
  .int()
@@ -2404,6 +2429,8 @@ Splits the video into multiple chunks so that each chunk can be encoded in paral
2404
2429
  .optional()
2405
2430
  .describe(`
2406
2431
  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 <dfn>Priority Job Slots</dfn>. For instance, the longer each chunk is, the fewer <dfn>Encoding Jobs</dfn> will need to be used.
2432
+
2433
+ Requested durations below 5 seconds are treated as 5 seconds.
2407
2434
  `),
2408
2435
  watermark_url: z
2409
2436
  .union([z.literal(''), httpUrlSchema])
@@ -0,0 +1,211 @@
1
+ import type { RobotVideoGenerateInstructions } from './video-generate.ts'
2
+
3
+ import { videoGenerateDefaultModelIdentifier } from './_ai-models.ts'
4
+
5
+ // Keep the schema wording portable without exposing the server's provider policy to SDKs.
6
+ export { videoGenerationParameterEnforcementDate } from './_video-generate-description.ts'
7
+
8
+ const optionalVideoParameters = [
9
+ 'seed',
10
+ 'aspect_ratio',
11
+ 'height',
12
+ 'width',
13
+ 'style',
14
+ 'duration',
15
+ 'fps',
16
+ 'motion_amount',
17
+ 'camera_motion',
18
+ 'negative_prompt',
19
+ 'reference_strength',
20
+ ] satisfies (keyof RobotVideoGenerateInstructions)[]
21
+
22
+ const ltxAspectRatioError = 'aspect_ratio must be a nonempty string for lightricks/ltx-video.'
23
+
24
+ /** Stable code included in Assembly warning text and structured server logs. */
25
+ export const videoGenerationParameterWarningCode = 'VIDEO_GENERATE_PARAMETER_IGNORED'
26
+
27
+ /** Flip this one flag on the enforcement date; both policy paths have regression coverage. */
28
+ export const videoGenerationParameterValidation = { enforceUnsupportedParameters: false }
29
+
30
+ type VideoGenerationParameters = Pick<
31
+ RobotVideoGenerateInstructions,
32
+ 'model' | 'prompt' | (typeof optionalVideoParameters)[number]
33
+ >
34
+
35
+ interface VideoGenerationModel {
36
+ replicateModel: `${string}/${string}`
37
+ parameters: readonly (typeof optionalVideoParameters)[number][]
38
+ imageInput?: string
39
+ imageMimeTypes?: readonly string[]
40
+ requiresImage?: boolean
41
+ }
42
+
43
+ // https://platform.minimax.io/docs/api-reference/video-generation-i2v#body-first-frame-image
44
+ const minimaxImageMimeTypes = ['image/jpeg', 'image/png', 'image/webp']
45
+
46
+ /** Verified Replicate video capabilities; model schemas do not accept a generic video input. */
47
+ // Unavailable luma/ray and image-only luma/photon stay excluded in both modes. The transition
48
+ // applies to ignored settings on supported video models, preserving the other validation fixes.
49
+ export const videoGenerationModels: Record<string, VideoGenerationModel> = {
50
+ // https://replicate.com/minimax/video-01/api/schema: fixed six-second output, no duration input.
51
+ 'minimax/video-01': {
52
+ replicateModel: 'minimax/video-01',
53
+ parameters: [],
54
+ imageInput: 'first_frame_image',
55
+ imageMimeTypes: minimaxImageMimeTypes,
56
+ },
57
+ 'minimax/video-01-live': {
58
+ replicateModel: 'minimax/video-01-live',
59
+ parameters: [],
60
+ imageInput: 'first_frame_image',
61
+ imageMimeTypes: minimaxImageMimeTypes,
62
+ requiresImage: true,
63
+ },
64
+ // https://replicate.com/tencent/hunyuan-video/api/schema: length is specified in frames.
65
+ 'tencent/hunyuan-video': {
66
+ replicateModel: 'tencent/hunyuan-video',
67
+ parameters: ['seed', 'height', 'width', 'fps'],
68
+ },
69
+ // https://replicate.com/lightricks/ltx-video/api/schema: length is specified in frames.
70
+ 'lightricks/ltx-video': {
71
+ replicateModel: 'lightricks/ltx-video',
72
+ parameters: ['seed', 'aspect_ratio', 'negative_prompt'],
73
+ imageInput: 'image',
74
+ },
75
+ }
76
+
77
+ /** Looks up only configured model names, excluding inherited object properties. */
78
+ export function getVideoGenerationModel(model: string): VideoGenerationModel | undefined {
79
+ return Object.hasOwn(videoGenerationModels, model) ? videoGenerationModels[model] : undefined
80
+ }
81
+
82
+ /** Identifies known unsupported frame formats without rejecting legacy CLI inputs lacking MIME. */
83
+ export function getVideoGenerationImageFormatError(
84
+ modelName: string,
85
+ mime: string | null | undefined,
86
+ ): string | undefined {
87
+ const supported = getVideoGenerationModel(modelName)?.imageMimeTypes
88
+ if (!mime || !supported || supported.includes(mime)) return undefined
89
+ return `Model ${modelName} supports only JPEG, PNG, or WebP input images. Convert the image before using it.`
90
+ }
91
+
92
+ /** Shares safe value constraints between migration warnings and later enforcement errors. */
93
+ export function getPreviouslyOmittedVideoGenerationValueError(
94
+ instructions: VideoGenerationParameters,
95
+ parameter: (typeof optionalVideoParameters)[number],
96
+ hasImage: boolean,
97
+ ): string | undefined {
98
+ if (instructions.model === 'tencent/hunyuan-video') {
99
+ if (
100
+ parameter === 'fps' &&
101
+ instructions.fps != null &&
102
+ (!Number.isInteger(instructions.fps) || instructions.fps < 1)
103
+ ) {
104
+ return 'fps must be a positive integer for tencent/hunyuan-video.'
105
+ }
106
+ if (parameter === 'height' || parameter === 'width') {
107
+ const value = instructions[parameter]
108
+ if (value != null && (value < 16 || value > 1280 || value % 16 !== 0)) {
109
+ return `${parameter} must be a multiple of 16 between 16 and 1280 for tencent/hunyuan-video.`
110
+ }
111
+ }
112
+ }
113
+ if (
114
+ instructions.model === 'lightricks/ltx-video' &&
115
+ parameter === 'aspect_ratio' &&
116
+ !hasImage &&
117
+ instructions.aspect_ratio === ''
118
+ ) {
119
+ return ltxAspectRatioError
120
+ }
121
+ return undefined
122
+ }
123
+
124
+ /** Enumerates ignored scalar settings without including customer-supplied values. */
125
+ export function getUnsupportedVideoGenerationParameters(
126
+ instructions: VideoGenerationParameters,
127
+ hasImage = false,
128
+ ): (typeof optionalVideoParameters)[number][] {
129
+ const model = getVideoGenerationModel(instructions.model ?? videoGenerateDefaultModelIdentifier)
130
+ if (!model) return []
131
+ return optionalVideoParameters.filter(
132
+ (parameter) =>
133
+ instructions[parameter] != null &&
134
+ (!model.parameters.includes(parameter) ||
135
+ (hasImage && parameter === 'aspect_ratio') ||
136
+ getPreviouslyOmittedVideoGenerationValueError(instructions, parameter, hasImage) != null),
137
+ )
138
+ }
139
+
140
+ /** Enforces model constraints and, after the transition, rejects ignored scalar settings. */
141
+ export function getVideoGenerationParameterError(
142
+ instructions: VideoGenerationParameters,
143
+ hasImage = false,
144
+ ): string | undefined {
145
+ const modelName = instructions.model ?? videoGenerateDefaultModelIdentifier
146
+ const model = getVideoGenerationModel(modelName)
147
+ if (!model) return `Model ${modelName} is not supported for video generation.`
148
+ const unsupported = getUnsupportedVideoGenerationParameters(instructions, hasImage)
149
+ if (videoGenerationParameterValidation.enforceUnsupportedParameters && unsupported.length > 0) {
150
+ const parameter = unsupported[0]
151
+ const valueError = getPreviouslyOmittedVideoGenerationValueError(
152
+ instructions,
153
+ parameter,
154
+ hasImage,
155
+ )
156
+ if (valueError) return valueError
157
+ const imageConstraint =
158
+ hasImage && parameter === 'aspect_ratio' && model.parameters.includes(parameter)
159
+ ? ' with an input image'
160
+ : ''
161
+ return `Model ${modelName} does not support ${parameter}${imageConstraint}. Omit this parameter or select a model that supports it.`
162
+ }
163
+ // Whitespace was forwarded before this change, unlike the previously omitted empty string.
164
+ if (
165
+ modelName === 'lightricks/ltx-video' &&
166
+ !hasImage &&
167
+ instructions.aspect_ratio != null &&
168
+ instructions.aspect_ratio !== '' &&
169
+ instructions.aspect_ratio.trim() === ''
170
+ ) {
171
+ return ltxAspectRatioError
172
+ }
173
+ return undefined
174
+ }
175
+
176
+ /** Requires necessary images immediately; unsupported inputs share the compatibility window. */
177
+ export function getVideoGenerationImageError(
178
+ instructions: Pick<VideoGenerationParameters, 'model' | 'aspect_ratio'>,
179
+ hasImage: boolean,
180
+ ): string | undefined {
181
+ const modelName = instructions.model ?? videoGenerateDefaultModelIdentifier
182
+ const model = getVideoGenerationModel(modelName)
183
+ if (!model) return `Model ${modelName} is not supported for video generation.`
184
+ if (model.requiresImage && !hasImage) return `Model ${modelName} requires an input image.`
185
+ if (
186
+ videoGenerationParameterValidation.enforceUnsupportedParameters &&
187
+ hasImage &&
188
+ !model.imageInput
189
+ ) {
190
+ return `Model ${modelName} does not support an input image.`
191
+ }
192
+ return undefined
193
+ }
194
+
195
+ /** Builds only model-supported provider fields, preserving explicit zero values. */
196
+ export function buildVideoGenerationInput(
197
+ instructions: VideoGenerationParameters,
198
+ hasImage = false,
199
+ ): Record<string, unknown> {
200
+ const error = getVideoGenerationParameterError(instructions, hasImage)
201
+ if (error) throw new Error(error)
202
+ const model = getVideoGenerationModel(instructions.model ?? videoGenerateDefaultModelIdentifier)
203
+ if (!model) throw new Error('Missing video generation model configuration.')
204
+ const unsupported = getUnsupportedVideoGenerationParameters(instructions, hasImage)
205
+ const input: Record<string, unknown> = { prompt: instructions.prompt }
206
+ for (const parameter of model.parameters) {
207
+ const value = instructions[parameter]
208
+ if (value != null && !unsupported.includes(parameter)) input[parameter] = value
209
+ }
210
+ return input
211
+ }