@shipfox/expression 1.1.0

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 (140) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +117 -0
  3. package/dist/evaluator/errors.d.ts +8 -0
  4. package/dist/evaluator/errors.d.ts.map +1 -0
  5. package/dist/evaluator/errors.js +13 -0
  6. package/dist/evaluator/errors.js.map +1 -0
  7. package/dist/evaluator/evaluate-workflow-expression.d.ts +11 -0
  8. package/dist/evaluator/evaluate-workflow-expression.d.ts.map +1 -0
  9. package/dist/evaluator/evaluate-workflow-expression.js +30 -0
  10. package/dist/evaluator/evaluate-workflow-expression.js.map +1 -0
  11. package/dist/evaluator/index.d.ts +3 -0
  12. package/dist/evaluator/index.d.ts.map +1 -0
  13. package/dist/evaluator/index.js +4 -0
  14. package/dist/evaluator/index.js.map +1 -0
  15. package/dist/expression/create-workflow-expression.d.ts +7 -0
  16. package/dist/expression/create-workflow-expression.d.ts.map +1 -0
  17. package/dist/expression/create-workflow-expression.js +156 -0
  18. package/dist/expression/create-workflow-expression.js.map +1 -0
  19. package/dist/expression/errors.d.ts +12 -0
  20. package/dist/expression/errors.d.ts.map +1 -0
  21. package/dist/expression/errors.js +13 -0
  22. package/dist/expression/errors.js.map +1 -0
  23. package/dist/expression/index.d.ts +4 -0
  24. package/dist/expression/index.d.ts.map +1 -0
  25. package/dist/expression/index.js +4 -0
  26. package/dist/expression/index.js.map +1 -0
  27. package/dist/expression/workflow-expression.d.ts +33 -0
  28. package/dist/expression/workflow-expression.d.ts.map +1 -0
  29. package/dist/expression/workflow-expression.js +3 -0
  30. package/dist/expression/workflow-expression.js.map +1 -0
  31. package/dist/index.d.ts +27 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +25 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/outputs/index.d.ts +2 -0
  36. package/dist/outputs/index.d.ts.map +1 -0
  37. package/dist/outputs/index.js +3 -0
  38. package/dist/outputs/index.js.map +1 -0
  39. package/dist/outputs/output-declarations.d.ts +39 -0
  40. package/dist/outputs/output-declarations.d.ts.map +1 -0
  41. package/dist/outputs/output-declarations.js +295 -0
  42. package/dist/outputs/output-declarations.js.map +1 -0
  43. package/dist/plan/bare-reference.d.ts +2 -0
  44. package/dist/plan/bare-reference.d.ts.map +1 -0
  45. package/dist/plan/bare-reference.js +23 -0
  46. package/dist/plan/bare-reference.js.map +1 -0
  47. package/dist/plan/context-key-access.d.ts +25 -0
  48. package/dist/plan/context-key-access.d.ts.map +1 -0
  49. package/dist/plan/context-key-access.js +249 -0
  50. package/dist/plan/context-key-access.js.map +1 -0
  51. package/dist/plan/evaluate-planned-predicate.d.ts +14 -0
  52. package/dist/plan/evaluate-planned-predicate.d.ts.map +1 -0
  53. package/dist/plan/evaluate-planned-predicate.js +31 -0
  54. package/dist/plan/evaluate-planned-predicate.js.map +1 -0
  55. package/dist/plan/evaluation-trace.d.ts +44 -0
  56. package/dist/plan/evaluation-trace.d.ts.map +1 -0
  57. package/dist/plan/evaluation-trace.js +95 -0
  58. package/dist/plan/evaluation-trace.js.map +1 -0
  59. package/dist/plan/extract-exact-context-roots.d.ts +2 -0
  60. package/dist/plan/extract-exact-context-roots.d.ts.map +1 -0
  61. package/dist/plan/extract-exact-context-roots.js +114 -0
  62. package/dist/plan/extract-exact-context-roots.js.map +1 -0
  63. package/dist/plan/fill.d.ts +3 -0
  64. package/dist/plan/fill.d.ts.map +1 -0
  65. package/dist/plan/fill.js +8 -0
  66. package/dist/plan/fill.js.map +1 -0
  67. package/dist/plan/freeze-run-command.d.ts +17 -0
  68. package/dist/plan/freeze-run-command.d.ts.map +1 -0
  69. package/dist/plan/freeze-run-command.js +33 -0
  70. package/dist/plan/freeze-run-command.js.map +1 -0
  71. package/dist/plan/freeze.d.ts +48 -0
  72. package/dist/plan/freeze.d.ts.map +1 -0
  73. package/dist/plan/freeze.js +148 -0
  74. package/dist/plan/freeze.js.map +1 -0
  75. package/dist/plan/plan-field.d.ts +26 -0
  76. package/dist/plan/plan-field.d.ts.map +1 -0
  77. package/dist/plan/plan-field.js +63 -0
  78. package/dist/plan/plan-field.js.map +1 -0
  79. package/dist/plan/predicate-shape.d.ts +2 -0
  80. package/dist/plan/predicate-shape.d.ts.map +1 -0
  81. package/dist/plan/predicate-shape.js +45 -0
  82. package/dist/plan/predicate-shape.js.map +1 -0
  83. package/dist/plan/resolved-field.d.ts +17 -0
  84. package/dist/plan/resolved-field.d.ts.map +1 -0
  85. package/dist/plan/resolved-field.js +3 -0
  86. package/dist/plan/resolved-field.js.map +1 -0
  87. package/dist/plan/route-expression.d.ts +9 -0
  88. package/dist/plan/route-expression.d.ts.map +1 -0
  89. package/dist/plan/route-expression.js +46 -0
  90. package/dist/plan/route-expression.js.map +1 -0
  91. package/dist/plan/validate-server-evaluable.d.ts +14 -0
  92. package/dist/plan/validate-server-evaluable.d.ts.map +1 -0
  93. package/dist/plan/validate-server-evaluable.js +20 -0
  94. package/dist/plan/validate-server-evaluable.js.map +1 -0
  95. package/dist/resolver/coerce-workflow-value-to-string.d.ts +2 -0
  96. package/dist/resolver/coerce-workflow-value-to-string.d.ts.map +1 -0
  97. package/dist/resolver/coerce-workflow-value-to-string.js +16 -0
  98. package/dist/resolver/coerce-workflow-value-to-string.js.map +1 -0
  99. package/dist/resolver/errors.d.ts +10 -0
  100. package/dist/resolver/errors.d.ts.map +1 -0
  101. package/dist/resolver/errors.js +12 -0
  102. package/dist/resolver/errors.js.map +1 -0
  103. package/dist/run/hoist-run-command.d.ts +33 -0
  104. package/dist/run/hoist-run-command.d.ts.map +1 -0
  105. package/dist/run/hoist-run-command.js +79 -0
  106. package/dist/run/hoist-run-command.js.map +1 -0
  107. package/dist/run/shell-quoting.d.ts +24 -0
  108. package/dist/run/shell-quoting.d.ts.map +1 -0
  109. package/dist/run/shell-quoting.js +364 -0
  110. package/dist/run/shell-quoting.js.map +1 -0
  111. package/dist/template/errors.d.ts +14 -0
  112. package/dist/template/errors.d.ts.map +1 -0
  113. package/dist/template/errors.js +14 -0
  114. package/dist/template/errors.js.map +1 -0
  115. package/dist/template/extract-cel-context-roots.d.ts +2 -0
  116. package/dist/template/extract-cel-context-roots.d.ts.map +1 -0
  117. package/dist/template/extract-cel-context-roots.js +110 -0
  118. package/dist/template/extract-cel-context-roots.js.map +1 -0
  119. package/dist/template/extract-cel-untrusted-path-accesses.d.ts +5 -0
  120. package/dist/template/extract-cel-untrusted-path-accesses.d.ts.map +1 -0
  121. package/dist/template/extract-cel-untrusted-path-accesses.js +140 -0
  122. package/dist/template/extract-cel-untrusted-path-accesses.js.map +1 -0
  123. package/dist/template/parse-workflow-template.d.ts +3 -0
  124. package/dist/template/parse-workflow-template.d.ts.map +1 -0
  125. package/dist/template/parse-workflow-template.js +111 -0
  126. package/dist/template/parse-workflow-template.js.map +1 -0
  127. package/dist/template/scan-cel-token.d.ts +3 -0
  128. package/dist/template/scan-cel-token.d.ts.map +1 -0
  129. package/dist/template/scan-cel-token.js +55 -0
  130. package/dist/template/scan-cel-token.js.map +1 -0
  131. package/dist/template/template-segment.d.ts +12 -0
  132. package/dist/template/template-segment.d.ts.map +1 -0
  133. package/dist/template/template-segment.js +3 -0
  134. package/dist/template/template-segment.js.map +1 -0
  135. package/dist/tsconfig.test.tsbuildinfo +1 -0
  136. package/dist/workflow-context/workflow-context.d.ts +458 -0
  137. package/dist/workflow-context/workflow-context.d.ts.map +1 -0
  138. package/dist/workflow-context/workflow-context.js +664 -0
  139. package/dist/workflow-context/workflow-context.js.map +1 -0
  140. package/package.json +49 -0
@@ -0,0 +1,2 @@
1
+ export declare function coerceWorkflowValueToString(value: unknown): string;
2
+ //# sourceMappingURL=coerce-workflow-value-to-string.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coerce-workflow-value-to-string.d.ts","sourceRoot":"","sources":["../../src/resolver/coerce-workflow-value-to-string.ts"],"names":[],"mappings":"AAAA,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CASlE"}
@@ -0,0 +1,16 @@
1
+ export function coerceWorkflowValueToString(value) {
2
+ if (value === null || value === undefined) return '';
3
+ if (typeof value === 'string') return value;
4
+ if (typeof value === 'boolean') return value ? 'true' : 'false';
5
+ if (typeof value === 'bigint' || typeof value === 'number') return String(value);
6
+ if (value instanceof Date) return value.toISOString();
7
+ const serialized = JSON.stringify(value, stringifyBigint);
8
+ return serialized ?? '';
9
+ }
10
+ function stringifyBigint(_key, value) {
11
+ if (typeof value !== 'bigint') return value;
12
+ const numberValue = Number(value);
13
+ return Number.isSafeInteger(numberValue) ? numberValue : value.toString();
14
+ }
15
+
16
+ //# sourceMappingURL=coerce-workflow-value-to-string.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/resolver/coerce-workflow-value-to-string.ts"],"sourcesContent":["export function coerceWorkflowValueToString(value: unknown): string {\n if (value === null || value === undefined) return '';\n if (typeof value === 'string') return value;\n if (typeof value === 'boolean') return value ? 'true' : 'false';\n if (typeof value === 'bigint' || typeof value === 'number') return String(value);\n if (value instanceof Date) return value.toISOString();\n\n const serialized = JSON.stringify(value, stringifyBigint);\n return serialized ?? '';\n}\n\nfunction stringifyBigint(_key: string, value: unknown): unknown {\n if (typeof value !== 'bigint') return value;\n\n const numberValue = Number(value);\n return Number.isSafeInteger(numberValue) ? numberValue : value.toString();\n}\n"],"names":["coerceWorkflowValueToString","value","undefined","String","Date","toISOString","serialized","JSON","stringify","stringifyBigint","_key","numberValue","Number","isSafeInteger","toString"],"mappings":"AAAA,OAAO,SAASA,4BAA4BC,KAAc;IACxD,IAAIA,UAAU,QAAQA,UAAUC,WAAW,OAAO;IAClD,IAAI,OAAOD,UAAU,UAAU,OAAOA;IACtC,IAAI,OAAOA,UAAU,WAAW,OAAOA,QAAQ,SAAS;IACxD,IAAI,OAAOA,UAAU,YAAY,OAAOA,UAAU,UAAU,OAAOE,OAAOF;IAC1E,IAAIA,iBAAiBG,MAAM,OAAOH,MAAMI,WAAW;IAEnD,MAAMC,aAAaC,KAAKC,SAAS,CAACP,OAAOQ;IACzC,OAAOH,cAAc;AACvB;AAEA,SAASG,gBAAgBC,IAAY,EAAET,KAAc;IACnD,IAAI,OAAOA,UAAU,UAAU,OAAOA;IAEtC,MAAMU,cAAcC,OAAOX;IAC3B,OAAOW,OAAOC,aAAa,CAACF,eAAeA,cAAcV,MAAMa,QAAQ;AACzE"}
@@ -0,0 +1,10 @@
1
+ export declare const workflowTemplateResolutionErrorCode = "workflow-template-resolution-failed";
2
+ export declare class WorkflowTemplateResolutionError extends Error {
3
+ readonly code = "workflow-template-resolution-failed";
4
+ readonly source: string;
5
+ constructor(params: {
6
+ source: string;
7
+ cause: unknown;
8
+ });
9
+ }
10
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/resolver/errors.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mCAAmC,wCAAwC,CAAC;AAEzF,qBAAa,+BAAgC,SAAQ,KAAK;IACxD,QAAQ,CAAC,IAAI,yCAAuC;IACpD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,MAAM,EAAE;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAC;CAKrD"}
@@ -0,0 +1,12 @@
1
+ export const workflowTemplateResolutionErrorCode = 'workflow-template-resolution-failed';
2
+ export class WorkflowTemplateResolutionError extends Error {
3
+ constructor(params){
4
+ super('Workflow template resolution failed', {
5
+ cause: params.cause
6
+ }), this.code = workflowTemplateResolutionErrorCode;
7
+ this.name = 'WorkflowTemplateResolutionError';
8
+ this.source = params.source;
9
+ }
10
+ }
11
+
12
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/resolver/errors.ts"],"sourcesContent":["export const workflowTemplateResolutionErrorCode = 'workflow-template-resolution-failed';\n\nexport class WorkflowTemplateResolutionError extends Error {\n readonly code = workflowTemplateResolutionErrorCode;\n readonly source: string;\n\n constructor(params: {source: string; cause: unknown}) {\n super('Workflow template resolution failed', {cause: params.cause});\n this.name = 'WorkflowTemplateResolutionError';\n this.source = params.source;\n }\n}\n"],"names":["workflowTemplateResolutionErrorCode","WorkflowTemplateResolutionError","Error","params","cause","code","name","source"],"mappings":"AAAA,OAAO,MAAMA,sCAAsC,sCAAsC;AAEzF,OAAO,MAAMC,wCAAwCC;IAInD,YAAYC,MAAwC,CAAE;QACpD,KAAK,CAAC,uCAAuC;YAACC,OAAOD,OAAOC,KAAK;QAAA,SAJ1DC,OAAOL;QAKd,IAAI,CAACM,IAAI,GAAG;QACZ,IAAI,CAACC,MAAM,GAAGJ,OAAOI,MAAM;IAC7B;AACF"}
@@ -0,0 +1,33 @@
1
+ import type { ResolvedField, ResolvedFieldDeferredSegment } from '../plan/resolved-field.js';
2
+ import { type ShellUnsafeRegion } from './shell-quoting.js';
3
+ export declare const unsafeRunInterpolationErrorCode = "unsafe-run-interpolation";
4
+ export interface RunCommandHoistOptions {
5
+ readonly reservedNames?: Iterable<string>;
6
+ }
7
+ export interface PlannedRunCommandBinding {
8
+ readonly name: string;
9
+ readonly segment: ResolvedFieldDeferredSegment;
10
+ }
11
+ export interface HoistedPlannedRunCommand {
12
+ readonly command: string;
13
+ readonly bindings: readonly PlannedRunCommandBinding[];
14
+ }
15
+ export declare class UnsafeRunInterpolationError extends Error {
16
+ readonly code = "unsafe-run-interpolation";
17
+ readonly region: ShellUnsafeRegion;
18
+ readonly source: string;
19
+ constructor(params: {
20
+ readonly region: ShellUnsafeRegion;
21
+ readonly source: string;
22
+ });
23
+ }
24
+ /**
25
+ * Hoists unfilled planned run-command segments into generated shell env
26
+ * references. Literal segments are trusted authored shell text; only call this
27
+ * on planned command fields that have not already been filled.
28
+ */
29
+ export declare function hoistPlannedRunCommand(params: {
30
+ readonly field: ResolvedField;
31
+ readonly reservedNames?: Iterable<string>;
32
+ }): HoistedPlannedRunCommand;
33
+ //# sourceMappingURL=hoist-run-command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hoist-run-command.d.ts","sourceRoot":"","sources":["../../src/run/hoist-run-command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,aAAa,EAAE,4BAA4B,EAAC,MAAM,2BAA2B,CAAC;AAC3F,OAAO,EAKL,KAAK,iBAAiB,EAEvB,MAAM,oBAAoB,CAAC;AAE5B,eAAO,MAAM,+BAA+B,6BAA6B,CAAC;AAK1E,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,aAAa,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,4BAA4B,CAAC;CAChD;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,SAAS,wBAAwB,EAAE,CAAC;CACxD;AAED,qBAAa,2BAA4B,SAAQ,KAAK;IACpD,QAAQ,CAAC,IAAI,8BAAmC;IAChD,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,MAAM,EAAE;QAAC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAC;CAQlF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAC7C,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,aAAa,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;CAC3C,GAAG,wBAAwB,CAQ3B"}
@@ -0,0 +1,79 @@
1
+ import { classifyShellSite, initialShellScanState, scanShellLiteral } from './shell-quoting.js';
2
+ export const unsafeRunInterpolationErrorCode = 'unsafe-run-interpolation';
3
+ const generatedNamePrefix = '__sf_';
4
+ const shellIdentifierPattern = /^[A-Za-z_][A-Za-z0-9_]*$/;
5
+ export class UnsafeRunInterpolationError extends Error {
6
+ constructor(params){
7
+ super(`Unsafe run interpolation inside ${params.region}. Bind the value to env and reference $VAR instead.`), this.code = unsafeRunInterpolationErrorCode;
8
+ this.name = 'UnsafeRunInterpolationError';
9
+ this.region = params.region;
10
+ this.source = params.source;
11
+ }
12
+ }
13
+ /**
14
+ * Hoists unfilled planned run-command segments into generated shell env
15
+ * references. Literal segments are trusted authored shell text; only call this
16
+ * on planned command fields that have not already been filled.
17
+ */ export function hoistPlannedRunCommand(params) {
18
+ return hoistCommandSegments({
19
+ segments: params.field.segments,
20
+ options: params.reservedNames === undefined ? {} : {
21
+ reservedNames: params.reservedNames
22
+ },
23
+ literalText: (segment)=>segment.value,
24
+ isBindingSegment: (segment)=>segment.kind === 'deferred'
25
+ });
26
+ }
27
+ function hoistCommandSegments(params) {
28
+ let command = '';
29
+ let state = initialShellScanState;
30
+ const bindings = [];
31
+ const reservedNames = new Set(params.options.reservedNames ?? []);
32
+ let nextIndex = 0;
33
+ for (const segment of params.segments){
34
+ if (segment.kind === 'literal') {
35
+ const text = params.literalText(segment);
36
+ command += text;
37
+ state = scanShellLiteral(text, state);
38
+ continue;
39
+ }
40
+ if (!params.isBindingSegment(segment)) continue;
41
+ const site = classifyShellSite(state);
42
+ if (site.kind === 'unsafe') {
43
+ throw new UnsafeRunInterpolationError({
44
+ region: site.region,
45
+ source: segment.expression.source
46
+ });
47
+ }
48
+ const name = nextGeneratedName(reservedNames, nextIndex);
49
+ nextIndex = Number(name.slice(generatedNamePrefix.length)) + 1;
50
+ reservedNames.add(name);
51
+ bindings.push({
52
+ name,
53
+ segment
54
+ });
55
+ command += shellReference(name, site);
56
+ }
57
+ return {
58
+ command,
59
+ bindings
60
+ };
61
+ }
62
+ function nextGeneratedName(reservedNames, startIndex) {
63
+ let index = startIndex;
64
+ while(true){
65
+ const name = `${generatedNamePrefix}${index}`;
66
+ if (!shellIdentifierPattern.test(name)) {
67
+ throw new Error(`Generated run env name is not a shell identifier: ${name}`);
68
+ }
69
+ if (!reservedNames.has(name)) return name;
70
+ index += 1;
71
+ }
72
+ }
73
+ function shellReference(name, site) {
74
+ if (site.kind === 'double') return `\${${name}}`;
75
+ if (site.kind === 'single') return `'"\${${name}}"'`;
76
+ return `"\${${name}}"`;
77
+ }
78
+
79
+ //# sourceMappingURL=hoist-run-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/run/hoist-run-command.ts"],"sourcesContent":["import type {ResolvedField, ResolvedFieldDeferredSegment} from '../plan/resolved-field.js';\nimport {\n classifyShellSite,\n initialShellScanState,\n type ShellScanState,\n type ShellSiteContext,\n type ShellUnsafeRegion,\n scanShellLiteral,\n} from './shell-quoting.js';\n\nexport const unsafeRunInterpolationErrorCode = 'unsafe-run-interpolation';\n\nconst generatedNamePrefix = '__sf_';\nconst shellIdentifierPattern = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\nexport interface RunCommandHoistOptions {\n readonly reservedNames?: Iterable<string>;\n}\n\nexport interface PlannedRunCommandBinding {\n readonly name: string;\n readonly segment: ResolvedFieldDeferredSegment;\n}\n\nexport interface HoistedPlannedRunCommand {\n readonly command: string;\n readonly bindings: readonly PlannedRunCommandBinding[];\n}\n\nexport class UnsafeRunInterpolationError extends Error {\n readonly code = unsafeRunInterpolationErrorCode;\n readonly region: ShellUnsafeRegion;\n readonly source: string;\n\n constructor(params: {readonly region: ShellUnsafeRegion; readonly source: string}) {\n super(\n `Unsafe run interpolation inside ${params.region}. Bind the value to env and reference $VAR instead.`,\n );\n this.name = 'UnsafeRunInterpolationError';\n this.region = params.region;\n this.source = params.source;\n }\n}\n\n/**\n * Hoists unfilled planned run-command segments into generated shell env\n * references. Literal segments are trusted authored shell text; only call this\n * on planned command fields that have not already been filled.\n */\nexport function hoistPlannedRunCommand(params: {\n readonly field: ResolvedField;\n readonly reservedNames?: Iterable<string>;\n}): HoistedPlannedRunCommand {\n return hoistCommandSegments({\n segments: params.field.segments,\n options: params.reservedNames === undefined ? {} : {reservedNames: params.reservedNames},\n literalText: (segment) => segment.value,\n isBindingSegment: (segment): segment is ResolvedFieldDeferredSegment =>\n segment.kind === 'deferred',\n });\n}\n\nfunction hoistCommandSegments<\n Segment extends {readonly kind: string},\n BindingSegment extends Segment & {readonly expression: {readonly source: string}},\n>(params: {\n readonly segments: readonly Segment[];\n readonly options: RunCommandHoistOptions;\n readonly literalText: (segment: Extract<Segment, {readonly kind: 'literal'}>) => string;\n readonly isBindingSegment: (segment: Segment) => segment is BindingSegment;\n}): {\n readonly command: string;\n readonly bindings: readonly {readonly name: string; readonly segment: BindingSegment}[];\n} {\n let command = '';\n let state: ShellScanState = initialShellScanState;\n const bindings: {name: string; segment: BindingSegment}[] = [];\n const reservedNames = new Set(params.options.reservedNames ?? []);\n let nextIndex = 0;\n\n for (const segment of params.segments) {\n if (segment.kind === 'literal') {\n const text = params.literalText(segment as Extract<Segment, {readonly kind: 'literal'}>);\n command += text;\n state = scanShellLiteral(text, state);\n continue;\n }\n\n if (!params.isBindingSegment(segment)) continue;\n\n const site = classifyShellSite(state);\n if (site.kind === 'unsafe') {\n throw new UnsafeRunInterpolationError({\n region: site.region,\n source: segment.expression.source,\n });\n }\n\n const name = nextGeneratedName(reservedNames, nextIndex);\n nextIndex = Number(name.slice(generatedNamePrefix.length)) + 1;\n reservedNames.add(name);\n bindings.push({name, segment});\n command += shellReference(name, site);\n }\n\n return {command, bindings};\n}\n\nfunction nextGeneratedName(reservedNames: ReadonlySet<string>, startIndex: number): string {\n let index = startIndex;\n\n while (true) {\n const name = `${generatedNamePrefix}${index}`;\n if (!shellIdentifierPattern.test(name)) {\n throw new Error(`Generated run env name is not a shell identifier: ${name}`);\n }\n\n if (!reservedNames.has(name)) return name;\n index += 1;\n }\n}\n\nfunction shellReference(name: string, site: Exclude<ShellSiteContext, {readonly kind: 'unsafe'}>) {\n if (site.kind === 'double') return `\\${${name}}`;\n if (site.kind === 'single') return `'\"\\${${name}}\"'`;\n return `\"\\${${name}}\"`;\n}\n"],"names":["classifyShellSite","initialShellScanState","scanShellLiteral","unsafeRunInterpolationErrorCode","generatedNamePrefix","shellIdentifierPattern","UnsafeRunInterpolationError","Error","params","region","code","name","source","hoistPlannedRunCommand","hoistCommandSegments","segments","field","options","reservedNames","undefined","literalText","segment","value","isBindingSegment","kind","command","state","bindings","Set","nextIndex","text","site","expression","nextGeneratedName","Number","slice","length","add","push","shellReference","startIndex","index","test","has"],"mappings":"AACA,SACEA,iBAAiB,EACjBC,qBAAqB,EAIrBC,gBAAgB,QACX,qBAAqB;AAE5B,OAAO,MAAMC,kCAAkC,2BAA2B;AAE1E,MAAMC,sBAAsB;AAC5B,MAAMC,yBAAyB;AAgB/B,OAAO,MAAMC,oCAAoCC;IAK/C,YAAYC,MAAqE,CAAE;QACjF,KAAK,CACH,CAAC,gCAAgC,EAAEA,OAAOC,MAAM,CAAC,mDAAmD,CAAC,QANhGC,OAAOP;QAQd,IAAI,CAACQ,IAAI,GAAG;QACZ,IAAI,CAACF,MAAM,GAAGD,OAAOC,MAAM;QAC3B,IAAI,CAACG,MAAM,GAAGJ,OAAOI,MAAM;IAC7B;AACF;AAEA;;;;CAIC,GACD,OAAO,SAASC,uBAAuBL,MAGtC;IACC,OAAOM,qBAAqB;QAC1BC,UAAUP,OAAOQ,KAAK,CAACD,QAAQ;QAC/BE,SAAST,OAAOU,aAAa,KAAKC,YAAY,CAAC,IAAI;YAACD,eAAeV,OAAOU,aAAa;QAAA;QACvFE,aAAa,CAACC,UAAYA,QAAQC,KAAK;QACvCC,kBAAkB,CAACF,UACjBA,QAAQG,IAAI,KAAK;IACrB;AACF;AAEA,SAASV,qBAGPN,MAKD;IAIC,IAAIiB,UAAU;IACd,IAAIC,QAAwBzB;IAC5B,MAAM0B,WAAsD,EAAE;IAC9D,MAAMT,gBAAgB,IAAIU,IAAIpB,OAAOS,OAAO,CAACC,aAAa,IAAI,EAAE;IAChE,IAAIW,YAAY;IAEhB,KAAK,MAAMR,WAAWb,OAAOO,QAAQ,CAAE;QACrC,IAAIM,QAAQG,IAAI,KAAK,WAAW;YAC9B,MAAMM,OAAOtB,OAAOY,WAAW,CAACC;YAChCI,WAAWK;YACXJ,QAAQxB,iBAAiB4B,MAAMJ;YAC/B;QACF;QAEA,IAAI,CAAClB,OAAOe,gBAAgB,CAACF,UAAU;QAEvC,MAAMU,OAAO/B,kBAAkB0B;QAC/B,IAAIK,KAAKP,IAAI,KAAK,UAAU;YAC1B,MAAM,IAAIlB,4BAA4B;gBACpCG,QAAQsB,KAAKtB,MAAM;gBACnBG,QAAQS,QAAQW,UAAU,CAACpB,MAAM;YACnC;QACF;QAEA,MAAMD,OAAOsB,kBAAkBf,eAAeW;QAC9CA,YAAYK,OAAOvB,KAAKwB,KAAK,CAAC/B,oBAAoBgC,MAAM,KAAK;QAC7DlB,cAAcmB,GAAG,CAAC1B;QAClBgB,SAASW,IAAI,CAAC;YAAC3B;YAAMU;QAAO;QAC5BI,WAAWc,eAAe5B,MAAMoB;IAClC;IAEA,OAAO;QAACN;QAASE;IAAQ;AAC3B;AAEA,SAASM,kBAAkBf,aAAkC,EAAEsB,UAAkB;IAC/E,IAAIC,QAAQD;IAEZ,MAAO,KAAM;QACX,MAAM7B,OAAO,GAAGP,sBAAsBqC,OAAO;QAC7C,IAAI,CAACpC,uBAAuBqC,IAAI,CAAC/B,OAAO;YACtC,MAAM,IAAIJ,MAAM,CAAC,kDAAkD,EAAEI,MAAM;QAC7E;QAEA,IAAI,CAACO,cAAcyB,GAAG,CAAChC,OAAO,OAAOA;QACrC8B,SAAS;IACX;AACF;AAEA,SAASF,eAAe5B,IAAY,EAAEoB,IAA0D;IAC9F,IAAIA,KAAKP,IAAI,KAAK,UAAU,OAAO,CAAC,GAAG,EAAEb,KAAK,CAAC,CAAC;IAChD,IAAIoB,KAAKP,IAAI,KAAK,UAAU,OAAO,CAAC,KAAK,EAAEb,KAAK,GAAG,CAAC;IACpD,OAAO,CAAC,IAAI,EAAEA,KAAK,EAAE,CAAC;AACxB"}
@@ -0,0 +1,24 @@
1
+ export type ShellFrame = 'single' | 'double' | 'dollar-single' | 'dollar-double' | 'paren-sub' | 'arith' | 'backtick' | 'param-brace' | 'heredoc' | 'line-comment';
2
+ export type ShellUnsafeRegion = ShellFrame | 'escape';
3
+ interface ArithSquareFrame {
4
+ readonly kind: 'arith-square';
5
+ readonly bracketDepth: number;
6
+ }
7
+ type ShellScanFrame = ShellFrame | ArithSquareFrame;
8
+ export type ShellSiteContext = {
9
+ readonly kind: 'unquoted' | 'single' | 'double';
10
+ } | {
11
+ readonly kind: 'unsafe';
12
+ readonly region: ShellUnsafeRegion;
13
+ };
14
+ export interface ShellScanState {
15
+ readonly frames: readonly ShellScanFrame[];
16
+ readonly pendingEscape?: boolean;
17
+ readonly previousCharacter?: string;
18
+ readonly previousCharacterEscaped?: boolean;
19
+ }
20
+ export declare const initialShellScanState: ShellScanState;
21
+ export declare function scanShellLiteral(text: string, state: ShellScanState): ShellScanState;
22
+ export declare function classifyShellSite(state: ShellScanState): ShellSiteContext;
23
+ export {};
24
+ //# sourceMappingURL=shell-quoting.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell-quoting.d.ts","sourceRoot":"","sources":["../../src/run/shell-quoting.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAClB,QAAQ,GACR,QAAQ,GACR,eAAe,GACf,eAAe,GACf,WAAW,GACX,OAAO,GACP,UAAU,GACV,aAAa,GACb,SAAS,GACT,cAAc,CAAC;AAEnB,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,QAAQ,CAAC;AACtD,UAAU,gBAAgB;IACxB,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AACD,KAAK,cAAc,GAAG,UAAU,GAAG,gBAAgB,CAAC;AAEpD,MAAM,MAAM,gBAAgB,GACxB;IAAC,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,QAAQ,GAAG,QAAQ,CAAA;CAAC,GACjD;IAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAA;CAAC,CAAC;AAElE,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;IAC3C,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,wBAAwB,CAAC,EAAE,OAAO,CAAC;CAC7C;AAED,eAAO,MAAM,qBAAqB,EAAE,cAA6B,CAAC;AAIlE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,cAAc,CAgNpF;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,GAAG,gBAAgB,CAOzE"}
@@ -0,0 +1,364 @@
1
+ export const initialShellScanState = {
2
+ frames: []
3
+ };
4
+ const shellCommentStarterPrefixPattern = /\s|[;&|()<>]/;
5
+ export function scanShellLiteral(text, state) {
6
+ const frames = state.frames.map(cloneShellScanFrame);
7
+ let pendingEscape = state.pendingEscape ?? false;
8
+ let previousCharacter = state.previousCharacter;
9
+ let previousCharacterEscaped = state.previousCharacterEscaped ?? false;
10
+ let index = 0;
11
+ function advance(nextIndex, escaped) {
12
+ if (nextIndex > index) {
13
+ previousCharacter = text[nextIndex - 1];
14
+ previousCharacterEscaped = escaped;
15
+ }
16
+ index = nextIndex;
17
+ }
18
+ function consumeShellEscape() {
19
+ const result = skipShellEscape(text, index);
20
+ pendingEscape = result.pendingEscape;
21
+ if (result.continuedLine) {
22
+ index = result.index;
23
+ return;
24
+ }
25
+ advance(result.index, result.consumedEscapedCharacter);
26
+ }
27
+ while(index < text.length){
28
+ if (pendingEscape) {
29
+ pendingEscape = false;
30
+ advance(index + 1, true);
31
+ continue;
32
+ }
33
+ const frame = topFrame(frames);
34
+ if (frame === 'single') {
35
+ if (text[index] === "'") frames.pop();
36
+ advance(index + 1, false);
37
+ continue;
38
+ }
39
+ if (frame === 'dollar-single') {
40
+ if (text[index] === '\\') {
41
+ consumeShellEscape();
42
+ continue;
43
+ }
44
+ if (text[index] === "'") frames.pop();
45
+ advance(index + 1, false);
46
+ continue;
47
+ }
48
+ if (frame === 'backtick') {
49
+ if (text[index] === '\\') {
50
+ consumeShellEscape();
51
+ continue;
52
+ }
53
+ if (text[index] === '`') {
54
+ frames.pop();
55
+ advance(index + 1, false);
56
+ continue;
57
+ }
58
+ advance(scanShellControlStart(text, index, frames), false);
59
+ continue;
60
+ }
61
+ if (frame === 'double' || frame === 'dollar-double') {
62
+ if (text[index] === '\\') {
63
+ consumeShellEscape();
64
+ continue;
65
+ }
66
+ if (text[index] === '"') {
67
+ frames.pop();
68
+ advance(index + 1, false);
69
+ continue;
70
+ }
71
+ if (text[index] === '`') {
72
+ frames.push('backtick');
73
+ advance(index + 1, false);
74
+ continue;
75
+ }
76
+ advance(scanShellControlStart(text, index, frames), false);
77
+ continue;
78
+ }
79
+ if (frame === 'param-brace') {
80
+ if (text[index] === '\\') {
81
+ consumeShellEscape();
82
+ continue;
83
+ }
84
+ if (text[index] === '}') {
85
+ frames.pop();
86
+ advance(index + 1, false);
87
+ continue;
88
+ }
89
+ if (text[index] === '`') {
90
+ frames.push('backtick');
91
+ advance(index + 1, false);
92
+ continue;
93
+ }
94
+ advance(scanShellControlStart(text, index, frames), false);
95
+ continue;
96
+ }
97
+ if (frame === 'paren-sub') {
98
+ if (text[index] === '\\') {
99
+ consumeShellEscape();
100
+ continue;
101
+ }
102
+ if (text[index] === ')') {
103
+ frames.pop();
104
+ advance(index + 1, false);
105
+ continue;
106
+ }
107
+ advance(scanShellPlainStart(text, index, frames, previousCharacter, previousCharacterEscaped), false);
108
+ continue;
109
+ }
110
+ if (frame === 'arith') {
111
+ const arithEnd = matchShellLogicalPrefix(text, index, '))');
112
+ if (arithEnd !== undefined) {
113
+ frames.pop();
114
+ advance(arithEnd, false);
115
+ continue;
116
+ }
117
+ if (text[index] === '\\') {
118
+ consumeShellEscape();
119
+ continue;
120
+ }
121
+ advance(scanShellPlainStart(text, index, frames, previousCharacter, previousCharacterEscaped), false);
122
+ continue;
123
+ }
124
+ if (frame === 'heredoc') {
125
+ advance(index + 1, false);
126
+ continue;
127
+ }
128
+ if (frame === 'line-comment') {
129
+ if (text[index] === '\n') frames.pop();
130
+ advance(index + 1, false);
131
+ continue;
132
+ }
133
+ if (isArithSquareFrame(frame)) {
134
+ if (text[index] === '[') {
135
+ replaceTopArithSquareFrame(frames, frame.bracketDepth + 1);
136
+ advance(index + 1, false);
137
+ continue;
138
+ }
139
+ if (text[index] === ']') {
140
+ if (frame.bracketDepth === 0) {
141
+ frames.pop();
142
+ } else {
143
+ replaceTopArithSquareFrame(frames, frame.bracketDepth - 1);
144
+ }
145
+ advance(index + 1, false);
146
+ continue;
147
+ }
148
+ if (text[index] === '\\') {
149
+ consumeShellEscape();
150
+ continue;
151
+ }
152
+ advance(scanShellPlainStart(text, index, frames, previousCharacter, previousCharacterEscaped), false);
153
+ continue;
154
+ }
155
+ if (text[index] === '\\') {
156
+ consumeShellEscape();
157
+ continue;
158
+ }
159
+ advance(scanShellPlainStart(text, index, frames, previousCharacter, previousCharacterEscaped), false);
160
+ }
161
+ return {
162
+ frames,
163
+ ...pendingEscape ? {
164
+ pendingEscape
165
+ } : {},
166
+ ...previousCharacter === undefined ? {} : {
167
+ previousCharacter
168
+ },
169
+ ...previousCharacterEscaped ? {
170
+ previousCharacterEscaped
171
+ } : {}
172
+ };
173
+ }
174
+ export function classifyShellSite(state) {
175
+ if (state.pendingEscape === true) return {
176
+ kind: 'unsafe',
177
+ region: 'escape'
178
+ };
179
+ if (state.frames.length === 0) return {
180
+ kind: 'unquoted'
181
+ };
182
+ if (state.frames.length === 1 && state.frames[0] === 'single') return {
183
+ kind: 'single'
184
+ };
185
+ if (state.frames.length === 1 && state.frames[0] === 'double') return {
186
+ kind: 'double'
187
+ };
188
+ return {
189
+ kind: 'unsafe',
190
+ region: findUnsafeRegion(state.frames)
191
+ };
192
+ }
193
+ function scanShellPlainStart(text, index, frames, previousCharacter, previousCharacterEscaped) {
194
+ if (startsShellLineComment(text, index, previousCharacter, previousCharacterEscaped)) {
195
+ frames.push('line-comment');
196
+ return index + 1;
197
+ }
198
+ const heredocStripTabsStart = matchShellLogicalPrefix(text, index, '<<-');
199
+ if (heredocStripTabsStart !== undefined) {
200
+ frames.push('heredoc');
201
+ return heredocStripTabsStart;
202
+ }
203
+ const heredocStart = matchShellLogicalPrefix(text, index, '<<');
204
+ if (heredocStart !== undefined) {
205
+ frames.push('heredoc');
206
+ return heredocStart;
207
+ }
208
+ const dollarArithStart = matchShellLogicalPrefix(text, index, '$((');
209
+ if (dollarArithStart !== undefined) {
210
+ frames.push('arith');
211
+ return dollarArithStart;
212
+ }
213
+ const arithSquareStart = matchShellLogicalPrefix(text, index, '$[');
214
+ if (arithSquareStart !== undefined) {
215
+ frames.push({
216
+ kind: 'arith-square',
217
+ bracketDepth: 0
218
+ });
219
+ return arithSquareStart;
220
+ }
221
+ const parenSubStart = matchShellLogicalPrefix(text, index, '$(');
222
+ if (parenSubStart !== undefined) {
223
+ frames.push('paren-sub');
224
+ return parenSubStart;
225
+ }
226
+ const paramBraceStart = matchShellLogicalPrefix(text, index, '${');
227
+ if (paramBraceStart !== undefined) {
228
+ frames.push('param-brace');
229
+ return paramBraceStart;
230
+ }
231
+ const dollarSingleStart = matchShellLogicalPrefix(text, index, "$'");
232
+ if (dollarSingleStart !== undefined) {
233
+ frames.push('dollar-single');
234
+ return dollarSingleStart;
235
+ }
236
+ const dollarDoubleStart = matchShellLogicalPrefix(text, index, '$"');
237
+ if (dollarDoubleStart !== undefined) {
238
+ frames.push('dollar-double');
239
+ return dollarDoubleStart;
240
+ }
241
+ const arithStart = matchShellLogicalPrefix(text, index, '((');
242
+ if (arithStart !== undefined) {
243
+ frames.push('arith');
244
+ return arithStart;
245
+ }
246
+ if (text[index] === "'") {
247
+ frames.push('single');
248
+ return index + 1;
249
+ }
250
+ if (text[index] === '"') {
251
+ frames.push('double');
252
+ return index + 1;
253
+ }
254
+ if (text[index] === '`') {
255
+ frames.push('backtick');
256
+ return index + 1;
257
+ }
258
+ return index + 1;
259
+ }
260
+ function scanShellControlStart(text, index, frames) {
261
+ const dollarArithStart = matchShellLogicalPrefix(text, index, '$((');
262
+ if (dollarArithStart !== undefined) {
263
+ frames.push('arith');
264
+ return dollarArithStart;
265
+ }
266
+ const arithSquareStart = matchShellLogicalPrefix(text, index, '$[');
267
+ if (arithSquareStart !== undefined) {
268
+ frames.push({
269
+ kind: 'arith-square',
270
+ bracketDepth: 0
271
+ });
272
+ return arithSquareStart;
273
+ }
274
+ const parenSubStart = matchShellLogicalPrefix(text, index, '$(');
275
+ if (parenSubStart !== undefined) {
276
+ frames.push('paren-sub');
277
+ return parenSubStart;
278
+ }
279
+ const paramBraceStart = matchShellLogicalPrefix(text, index, '${');
280
+ if (paramBraceStart !== undefined) {
281
+ frames.push('param-brace');
282
+ return paramBraceStart;
283
+ }
284
+ const dollarSingleStart = matchShellLogicalPrefix(text, index, "$'");
285
+ if (dollarSingleStart !== undefined) {
286
+ frames.push('dollar-single');
287
+ return dollarSingleStart;
288
+ }
289
+ const dollarDoubleStart = matchShellLogicalPrefix(text, index, '$"');
290
+ if (dollarDoubleStart !== undefined) {
291
+ frames.push('dollar-double');
292
+ return dollarDoubleStart;
293
+ }
294
+ return index + 1;
295
+ }
296
+ function matchShellLogicalPrefix(text, index, prefix) {
297
+ let nextIndex = index;
298
+ for(let prefixIndex = 0; prefixIndex < prefix.length; prefixIndex += 1){
299
+ if (text[nextIndex] !== prefix[prefixIndex]) return undefined;
300
+ nextIndex += 1;
301
+ if (prefixIndex + 1 < prefix.length) nextIndex = skipShellLineContinuations(text, nextIndex);
302
+ }
303
+ return nextIndex;
304
+ }
305
+ function skipShellLineContinuations(text, index) {
306
+ let nextIndex = index;
307
+ while(text[nextIndex] === '\\' && text[nextIndex + 1] === '\n'){
308
+ nextIndex += 2;
309
+ }
310
+ return nextIndex;
311
+ }
312
+ function skipShellEscape(text, index) {
313
+ if (index + 1 >= text.length) {
314
+ return {
315
+ index: text.length,
316
+ pendingEscape: true,
317
+ consumedEscapedCharacter: false,
318
+ continuedLine: false
319
+ };
320
+ }
321
+ return {
322
+ index: index + 2,
323
+ pendingEscape: false,
324
+ consumedEscapedCharacter: true,
325
+ continuedLine: text[index + 1] === '\n'
326
+ };
327
+ }
328
+ function topFrame(frames) {
329
+ return frames.at(-1);
330
+ }
331
+ function cloneShellScanFrame(frame) {
332
+ if (isArithSquareFrame(frame)) return {
333
+ ...frame
334
+ };
335
+ return frame;
336
+ }
337
+ function findUnsafeRegion(frames) {
338
+ for(let index = frames.length - 1; index >= 0; index -= 1){
339
+ const frame = frames[index];
340
+ if (frame === undefined) continue;
341
+ if (isArithSquareFrame(frame)) return 'arith';
342
+ if (frame !== 'single' && frame !== 'double') return frame;
343
+ }
344
+ return 'heredoc';
345
+ }
346
+ function isArithSquareFrame(frame) {
347
+ return typeof frame === 'object' && frame.kind === 'arith-square';
348
+ }
349
+ function replaceTopArithSquareFrame(frames, bracketDepth) {
350
+ const topIndex = frames.length - 1;
351
+ const frame = frames[topIndex];
352
+ if (isArithSquareFrame(frame)) frames[topIndex] = {
353
+ ...frame,
354
+ bracketDepth
355
+ };
356
+ }
357
+ function startsShellLineComment(text, index, previousCharacter, previousCharacterEscaped) {
358
+ if (text[index] !== '#') return false;
359
+ if (previousCharacterEscaped) return false;
360
+ if (previousCharacter === undefined) return true;
361
+ return shellCommentStarterPrefixPattern.test(previousCharacter);
362
+ }
363
+
364
+ //# sourceMappingURL=shell-quoting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/run/shell-quoting.ts"],"sourcesContent":["export type ShellFrame =\n | 'single'\n | 'double'\n | 'dollar-single'\n | 'dollar-double'\n | 'paren-sub'\n | 'arith'\n | 'backtick'\n | 'param-brace'\n | 'heredoc'\n | 'line-comment';\n\nexport type ShellUnsafeRegion = ShellFrame | 'escape';\ninterface ArithSquareFrame {\n readonly kind: 'arith-square';\n readonly bracketDepth: number;\n}\ntype ShellScanFrame = ShellFrame | ArithSquareFrame;\n\nexport type ShellSiteContext =\n | {readonly kind: 'unquoted' | 'single' | 'double'}\n | {readonly kind: 'unsafe'; readonly region: ShellUnsafeRegion};\n\nexport interface ShellScanState {\n readonly frames: readonly ShellScanFrame[];\n readonly pendingEscape?: boolean;\n readonly previousCharacter?: string;\n readonly previousCharacterEscaped?: boolean;\n}\n\nexport const initialShellScanState: ShellScanState = {frames: []};\n\nconst shellCommentStarterPrefixPattern = /\\s|[;&|()<>]/;\n\nexport function scanShellLiteral(text: string, state: ShellScanState): ShellScanState {\n const frames = state.frames.map(cloneShellScanFrame);\n let pendingEscape = state.pendingEscape ?? false;\n let previousCharacter = state.previousCharacter;\n let previousCharacterEscaped = state.previousCharacterEscaped ?? false;\n let index = 0;\n\n function advance(nextIndex: number, escaped: boolean): void {\n if (nextIndex > index) {\n previousCharacter = text[nextIndex - 1];\n previousCharacterEscaped = escaped;\n }\n index = nextIndex;\n }\n\n function consumeShellEscape(): void {\n const result = skipShellEscape(text, index);\n pendingEscape = result.pendingEscape;\n if (result.continuedLine) {\n index = result.index;\n return;\n }\n\n advance(result.index, result.consumedEscapedCharacter);\n }\n\n while (index < text.length) {\n if (pendingEscape) {\n pendingEscape = false;\n advance(index + 1, true);\n continue;\n }\n\n const frame = topFrame(frames);\n\n if (frame === 'single') {\n if (text[index] === \"'\") frames.pop();\n advance(index + 1, false);\n continue;\n }\n\n if (frame === 'dollar-single') {\n if (text[index] === '\\\\') {\n consumeShellEscape();\n continue;\n }\n\n if (text[index] === \"'\") frames.pop();\n advance(index + 1, false);\n continue;\n }\n\n if (frame === 'backtick') {\n if (text[index] === '\\\\') {\n consumeShellEscape();\n continue;\n }\n\n if (text[index] === '`') {\n frames.pop();\n advance(index + 1, false);\n continue;\n }\n\n advance(scanShellControlStart(text, index, frames), false);\n continue;\n }\n\n if (frame === 'double' || frame === 'dollar-double') {\n if (text[index] === '\\\\') {\n consumeShellEscape();\n continue;\n }\n\n if (text[index] === '\"') {\n frames.pop();\n advance(index + 1, false);\n continue;\n }\n\n if (text[index] === '`') {\n frames.push('backtick');\n advance(index + 1, false);\n continue;\n }\n\n advance(scanShellControlStart(text, index, frames), false);\n continue;\n }\n\n if (frame === 'param-brace') {\n if (text[index] === '\\\\') {\n consumeShellEscape();\n continue;\n }\n\n if (text[index] === '}') {\n frames.pop();\n advance(index + 1, false);\n continue;\n }\n\n if (text[index] === '`') {\n frames.push('backtick');\n advance(index + 1, false);\n continue;\n }\n\n advance(scanShellControlStart(text, index, frames), false);\n continue;\n }\n\n if (frame === 'paren-sub') {\n if (text[index] === '\\\\') {\n consumeShellEscape();\n continue;\n }\n\n if (text[index] === ')') {\n frames.pop();\n advance(index + 1, false);\n continue;\n }\n\n advance(\n scanShellPlainStart(text, index, frames, previousCharacter, previousCharacterEscaped),\n false,\n );\n continue;\n }\n\n if (frame === 'arith') {\n const arithEnd = matchShellLogicalPrefix(text, index, '))');\n if (arithEnd !== undefined) {\n frames.pop();\n advance(arithEnd, false);\n continue;\n }\n\n if (text[index] === '\\\\') {\n consumeShellEscape();\n continue;\n }\n\n advance(\n scanShellPlainStart(text, index, frames, previousCharacter, previousCharacterEscaped),\n false,\n );\n continue;\n }\n\n if (frame === 'heredoc') {\n advance(index + 1, false);\n continue;\n }\n\n if (frame === 'line-comment') {\n if (text[index] === '\\n') frames.pop();\n advance(index + 1, false);\n continue;\n }\n\n if (isArithSquareFrame(frame)) {\n if (text[index] === '[') {\n replaceTopArithSquareFrame(frames, frame.bracketDepth + 1);\n advance(index + 1, false);\n continue;\n }\n\n if (text[index] === ']') {\n if (frame.bracketDepth === 0) {\n frames.pop();\n } else {\n replaceTopArithSquareFrame(frames, frame.bracketDepth - 1);\n }\n advance(index + 1, false);\n continue;\n }\n\n if (text[index] === '\\\\') {\n consumeShellEscape();\n continue;\n }\n\n advance(\n scanShellPlainStart(text, index, frames, previousCharacter, previousCharacterEscaped),\n false,\n );\n continue;\n }\n\n if (text[index] === '\\\\') {\n consumeShellEscape();\n continue;\n }\n\n advance(\n scanShellPlainStart(text, index, frames, previousCharacter, previousCharacterEscaped),\n false,\n );\n }\n\n return {\n frames,\n ...(pendingEscape ? {pendingEscape} : {}),\n ...(previousCharacter === undefined ? {} : {previousCharacter}),\n ...(previousCharacterEscaped ? {previousCharacterEscaped} : {}),\n };\n}\n\nexport function classifyShellSite(state: ShellScanState): ShellSiteContext {\n if (state.pendingEscape === true) return {kind: 'unsafe', region: 'escape'};\n if (state.frames.length === 0) return {kind: 'unquoted'};\n if (state.frames.length === 1 && state.frames[0] === 'single') return {kind: 'single'};\n if (state.frames.length === 1 && state.frames[0] === 'double') return {kind: 'double'};\n\n return {kind: 'unsafe', region: findUnsafeRegion(state.frames)};\n}\n\nfunction scanShellPlainStart(\n text: string,\n index: number,\n frames: ShellScanFrame[],\n previousCharacter: string | undefined,\n previousCharacterEscaped: boolean,\n): number {\n if (startsShellLineComment(text, index, previousCharacter, previousCharacterEscaped)) {\n frames.push('line-comment');\n return index + 1;\n }\n\n const heredocStripTabsStart = matchShellLogicalPrefix(text, index, '<<-');\n if (heredocStripTabsStart !== undefined) {\n frames.push('heredoc');\n return heredocStripTabsStart;\n }\n\n const heredocStart = matchShellLogicalPrefix(text, index, '<<');\n if (heredocStart !== undefined) {\n frames.push('heredoc');\n return heredocStart;\n }\n\n const dollarArithStart = matchShellLogicalPrefix(text, index, '$((');\n if (dollarArithStart !== undefined) {\n frames.push('arith');\n return dollarArithStart;\n }\n\n const arithSquareStart = matchShellLogicalPrefix(text, index, '$[');\n if (arithSquareStart !== undefined) {\n frames.push({kind: 'arith-square', bracketDepth: 0});\n return arithSquareStart;\n }\n\n const parenSubStart = matchShellLogicalPrefix(text, index, '$(');\n if (parenSubStart !== undefined) {\n frames.push('paren-sub');\n return parenSubStart;\n }\n\n const paramBraceStart = matchShellLogicalPrefix(text, index, '${');\n if (paramBraceStart !== undefined) {\n frames.push('param-brace');\n return paramBraceStart;\n }\n\n const dollarSingleStart = matchShellLogicalPrefix(text, index, \"$'\");\n if (dollarSingleStart !== undefined) {\n frames.push('dollar-single');\n return dollarSingleStart;\n }\n\n const dollarDoubleStart = matchShellLogicalPrefix(text, index, '$\"');\n if (dollarDoubleStart !== undefined) {\n frames.push('dollar-double');\n return dollarDoubleStart;\n }\n\n const arithStart = matchShellLogicalPrefix(text, index, '((');\n if (arithStart !== undefined) {\n frames.push('arith');\n return arithStart;\n }\n\n if (text[index] === \"'\") {\n frames.push('single');\n return index + 1;\n }\n\n if (text[index] === '\"') {\n frames.push('double');\n return index + 1;\n }\n\n if (text[index] === '`') {\n frames.push('backtick');\n return index + 1;\n }\n\n return index + 1;\n}\n\nfunction scanShellControlStart(text: string, index: number, frames: ShellScanFrame[]): number {\n const dollarArithStart = matchShellLogicalPrefix(text, index, '$((');\n if (dollarArithStart !== undefined) {\n frames.push('arith');\n return dollarArithStart;\n }\n\n const arithSquareStart = matchShellLogicalPrefix(text, index, '$[');\n if (arithSquareStart !== undefined) {\n frames.push({kind: 'arith-square', bracketDepth: 0});\n return arithSquareStart;\n }\n\n const parenSubStart = matchShellLogicalPrefix(text, index, '$(');\n if (parenSubStart !== undefined) {\n frames.push('paren-sub');\n return parenSubStart;\n }\n\n const paramBraceStart = matchShellLogicalPrefix(text, index, '${');\n if (paramBraceStart !== undefined) {\n frames.push('param-brace');\n return paramBraceStart;\n }\n\n const dollarSingleStart = matchShellLogicalPrefix(text, index, \"$'\");\n if (dollarSingleStart !== undefined) {\n frames.push('dollar-single');\n return dollarSingleStart;\n }\n\n const dollarDoubleStart = matchShellLogicalPrefix(text, index, '$\"');\n if (dollarDoubleStart !== undefined) {\n frames.push('dollar-double');\n return dollarDoubleStart;\n }\n\n return index + 1;\n}\n\nfunction matchShellLogicalPrefix(text: string, index: number, prefix: string): number | undefined {\n let nextIndex = index;\n\n for (let prefixIndex = 0; prefixIndex < prefix.length; prefixIndex += 1) {\n if (text[nextIndex] !== prefix[prefixIndex]) return undefined;\n nextIndex += 1;\n if (prefixIndex + 1 < prefix.length) nextIndex = skipShellLineContinuations(text, nextIndex);\n }\n\n return nextIndex;\n}\n\nfunction skipShellLineContinuations(text: string, index: number): number {\n let nextIndex = index;\n\n while (text[nextIndex] === '\\\\' && text[nextIndex + 1] === '\\n') {\n nextIndex += 2;\n }\n\n return nextIndex;\n}\n\nfunction skipShellEscape(\n text: string,\n index: number,\n): {\n readonly index: number;\n readonly pendingEscape: boolean;\n readonly consumedEscapedCharacter: boolean;\n readonly continuedLine: boolean;\n} {\n if (index + 1 >= text.length) {\n return {\n index: text.length,\n pendingEscape: true,\n consumedEscapedCharacter: false,\n continuedLine: false,\n };\n }\n\n return {\n index: index + 2,\n pendingEscape: false,\n consumedEscapedCharacter: true,\n continuedLine: text[index + 1] === '\\n',\n };\n}\n\nfunction topFrame(frames: readonly ShellScanFrame[]): ShellScanFrame | undefined {\n return frames.at(-1);\n}\n\nfunction cloneShellScanFrame(frame: ShellScanFrame): ShellScanFrame {\n if (isArithSquareFrame(frame)) return {...frame};\n return frame;\n}\n\nfunction findUnsafeRegion(frames: readonly ShellScanFrame[]): ShellFrame {\n for (let index = frames.length - 1; index >= 0; index -= 1) {\n const frame = frames[index];\n if (frame === undefined) continue;\n if (isArithSquareFrame(frame)) return 'arith';\n if (frame !== 'single' && frame !== 'double') return frame;\n }\n\n return 'heredoc';\n}\n\nfunction isArithSquareFrame(frame: ShellScanFrame | undefined): frame is ArithSquareFrame {\n return typeof frame === 'object' && frame.kind === 'arith-square';\n}\n\nfunction replaceTopArithSquareFrame(frames: ShellScanFrame[], bracketDepth: number): void {\n const topIndex = frames.length - 1;\n const frame = frames[topIndex];\n if (isArithSquareFrame(frame)) frames[topIndex] = {...frame, bracketDepth};\n}\n\nfunction startsShellLineComment(\n text: string,\n index: number,\n previousCharacter: string | undefined,\n previousCharacterEscaped: boolean,\n): boolean {\n if (text[index] !== '#') return false;\n if (previousCharacterEscaped) return false;\n if (previousCharacter === undefined) return true;\n\n return shellCommentStarterPrefixPattern.test(previousCharacter);\n}\n"],"names":["initialShellScanState","frames","shellCommentStarterPrefixPattern","scanShellLiteral","text","state","map","cloneShellScanFrame","pendingEscape","previousCharacter","previousCharacterEscaped","index","advance","nextIndex","escaped","consumeShellEscape","result","skipShellEscape","continuedLine","consumedEscapedCharacter","length","frame","topFrame","pop","scanShellControlStart","push","scanShellPlainStart","arithEnd","matchShellLogicalPrefix","undefined","isArithSquareFrame","replaceTopArithSquareFrame","bracketDepth","classifyShellSite","kind","region","findUnsafeRegion","startsShellLineComment","heredocStripTabsStart","heredocStart","dollarArithStart","arithSquareStart","parenSubStart","paramBraceStart","dollarSingleStart","dollarDoubleStart","arithStart","prefix","prefixIndex","skipShellLineContinuations","at","topIndex","test"],"mappings":"AA8BA,OAAO,MAAMA,wBAAwC;IAACC,QAAQ,EAAE;AAAA,EAAE;AAElE,MAAMC,mCAAmC;AAEzC,OAAO,SAASC,iBAAiBC,IAAY,EAAEC,KAAqB;IAClE,MAAMJ,SAASI,MAAMJ,MAAM,CAACK,GAAG,CAACC;IAChC,IAAIC,gBAAgBH,MAAMG,aAAa,IAAI;IAC3C,IAAIC,oBAAoBJ,MAAMI,iBAAiB;IAC/C,IAAIC,2BAA2BL,MAAMK,wBAAwB,IAAI;IACjE,IAAIC,QAAQ;IAEZ,SAASC,QAAQC,SAAiB,EAAEC,OAAgB;QAClD,IAAID,YAAYF,OAAO;YACrBF,oBAAoBL,IAAI,CAACS,YAAY,EAAE;YACvCH,2BAA2BI;QAC7B;QACAH,QAAQE;IACV;IAEA,SAASE;QACP,MAAMC,SAASC,gBAAgBb,MAAMO;QACrCH,gBAAgBQ,OAAOR,aAAa;QACpC,IAAIQ,OAAOE,aAAa,EAAE;YACxBP,QAAQK,OAAOL,KAAK;YACpB;QACF;QAEAC,QAAQI,OAAOL,KAAK,EAAEK,OAAOG,wBAAwB;IACvD;IAEA,MAAOR,QAAQP,KAAKgB,MAAM,CAAE;QAC1B,IAAIZ,eAAe;YACjBA,gBAAgB;YAChBI,QAAQD,QAAQ,GAAG;YACnB;QACF;QAEA,MAAMU,QAAQC,SAASrB;QAEvB,IAAIoB,UAAU,UAAU;YACtB,IAAIjB,IAAI,CAACO,MAAM,KAAK,KAAKV,OAAOsB,GAAG;YACnCX,QAAQD,QAAQ,GAAG;YACnB;QACF;QAEA,IAAIU,UAAU,iBAAiB;YAC7B,IAAIjB,IAAI,CAACO,MAAM,KAAK,MAAM;gBACxBI;gBACA;YACF;YAEA,IAAIX,IAAI,CAACO,MAAM,KAAK,KAAKV,OAAOsB,GAAG;YACnCX,QAAQD,QAAQ,GAAG;YACnB;QACF;QAEA,IAAIU,UAAU,YAAY;YACxB,IAAIjB,IAAI,CAACO,MAAM,KAAK,MAAM;gBACxBI;gBACA;YACF;YAEA,IAAIX,IAAI,CAACO,MAAM,KAAK,KAAK;gBACvBV,OAAOsB,GAAG;gBACVX,QAAQD,QAAQ,GAAG;gBACnB;YACF;YAEAC,QAAQY,sBAAsBpB,MAAMO,OAAOV,SAAS;YACpD;QACF;QAEA,IAAIoB,UAAU,YAAYA,UAAU,iBAAiB;YACnD,IAAIjB,IAAI,CAACO,MAAM,KAAK,MAAM;gBACxBI;gBACA;YACF;YAEA,IAAIX,IAAI,CAACO,MAAM,KAAK,KAAK;gBACvBV,OAAOsB,GAAG;gBACVX,QAAQD,QAAQ,GAAG;gBACnB;YACF;YAEA,IAAIP,IAAI,CAACO,MAAM,KAAK,KAAK;gBACvBV,OAAOwB,IAAI,CAAC;gBACZb,QAAQD,QAAQ,GAAG;gBACnB;YACF;YAEAC,QAAQY,sBAAsBpB,MAAMO,OAAOV,SAAS;YACpD;QACF;QAEA,IAAIoB,UAAU,eAAe;YAC3B,IAAIjB,IAAI,CAACO,MAAM,KAAK,MAAM;gBACxBI;gBACA;YACF;YAEA,IAAIX,IAAI,CAACO,MAAM,KAAK,KAAK;gBACvBV,OAAOsB,GAAG;gBACVX,QAAQD,QAAQ,GAAG;gBACnB;YACF;YAEA,IAAIP,IAAI,CAACO,MAAM,KAAK,KAAK;gBACvBV,OAAOwB,IAAI,CAAC;gBACZb,QAAQD,QAAQ,GAAG;gBACnB;YACF;YAEAC,QAAQY,sBAAsBpB,MAAMO,OAAOV,SAAS;YACpD;QACF;QAEA,IAAIoB,UAAU,aAAa;YACzB,IAAIjB,IAAI,CAACO,MAAM,KAAK,MAAM;gBACxBI;gBACA;YACF;YAEA,IAAIX,IAAI,CAACO,MAAM,KAAK,KAAK;gBACvBV,OAAOsB,GAAG;gBACVX,QAAQD,QAAQ,GAAG;gBACnB;YACF;YAEAC,QACEc,oBAAoBtB,MAAMO,OAAOV,QAAQQ,mBAAmBC,2BAC5D;YAEF;QACF;QAEA,IAAIW,UAAU,SAAS;YACrB,MAAMM,WAAWC,wBAAwBxB,MAAMO,OAAO;YACtD,IAAIgB,aAAaE,WAAW;gBAC1B5B,OAAOsB,GAAG;gBACVX,QAAQe,UAAU;gBAClB;YACF;YAEA,IAAIvB,IAAI,CAACO,MAAM,KAAK,MAAM;gBACxBI;gBACA;YACF;YAEAH,QACEc,oBAAoBtB,MAAMO,OAAOV,QAAQQ,mBAAmBC,2BAC5D;YAEF;QACF;QAEA,IAAIW,UAAU,WAAW;YACvBT,QAAQD,QAAQ,GAAG;YACnB;QACF;QAEA,IAAIU,UAAU,gBAAgB;YAC5B,IAAIjB,IAAI,CAACO,MAAM,KAAK,MAAMV,OAAOsB,GAAG;YACpCX,QAAQD,QAAQ,GAAG;YACnB;QACF;QAEA,IAAImB,mBAAmBT,QAAQ;YAC7B,IAAIjB,IAAI,CAACO,MAAM,KAAK,KAAK;gBACvBoB,2BAA2B9B,QAAQoB,MAAMW,YAAY,GAAG;gBACxDpB,QAAQD,QAAQ,GAAG;gBACnB;YACF;YAEA,IAAIP,IAAI,CAACO,MAAM,KAAK,KAAK;gBACvB,IAAIU,MAAMW,YAAY,KAAK,GAAG;oBAC5B/B,OAAOsB,GAAG;gBACZ,OAAO;oBACLQ,2BAA2B9B,QAAQoB,MAAMW,YAAY,GAAG;gBAC1D;gBACApB,QAAQD,QAAQ,GAAG;gBACnB;YACF;YAEA,IAAIP,IAAI,CAACO,MAAM,KAAK,MAAM;gBACxBI;gBACA;YACF;YAEAH,QACEc,oBAAoBtB,MAAMO,OAAOV,QAAQQ,mBAAmBC,2BAC5D;YAEF;QACF;QAEA,IAAIN,IAAI,CAACO,MAAM,KAAK,MAAM;YACxBI;YACA;QACF;QAEAH,QACEc,oBAAoBtB,MAAMO,OAAOV,QAAQQ,mBAAmBC,2BAC5D;IAEJ;IAEA,OAAO;QACLT;QACA,GAAIO,gBAAgB;YAACA;QAAa,IAAI,CAAC,CAAC;QACxC,GAAIC,sBAAsBoB,YAAY,CAAC,IAAI;YAACpB;QAAiB,CAAC;QAC9D,GAAIC,2BAA2B;YAACA;QAAwB,IAAI,CAAC,CAAC;IAChE;AACF;AAEA,OAAO,SAASuB,kBAAkB5B,KAAqB;IACrD,IAAIA,MAAMG,aAAa,KAAK,MAAM,OAAO;QAAC0B,MAAM;QAAUC,QAAQ;IAAQ;IAC1E,IAAI9B,MAAMJ,MAAM,CAACmB,MAAM,KAAK,GAAG,OAAO;QAACc,MAAM;IAAU;IACvD,IAAI7B,MAAMJ,MAAM,CAACmB,MAAM,KAAK,KAAKf,MAAMJ,MAAM,CAAC,EAAE,KAAK,UAAU,OAAO;QAACiC,MAAM;IAAQ;IACrF,IAAI7B,MAAMJ,MAAM,CAACmB,MAAM,KAAK,KAAKf,MAAMJ,MAAM,CAAC,EAAE,KAAK,UAAU,OAAO;QAACiC,MAAM;IAAQ;IAErF,OAAO;QAACA,MAAM;QAAUC,QAAQC,iBAAiB/B,MAAMJ,MAAM;IAAC;AAChE;AAEA,SAASyB,oBACPtB,IAAY,EACZO,KAAa,EACbV,MAAwB,EACxBQ,iBAAqC,EACrCC,wBAAiC;IAEjC,IAAI2B,uBAAuBjC,MAAMO,OAAOF,mBAAmBC,2BAA2B;QACpFT,OAAOwB,IAAI,CAAC;QACZ,OAAOd,QAAQ;IACjB;IAEA,MAAM2B,wBAAwBV,wBAAwBxB,MAAMO,OAAO;IACnE,IAAI2B,0BAA0BT,WAAW;QACvC5B,OAAOwB,IAAI,CAAC;QACZ,OAAOa;IACT;IAEA,MAAMC,eAAeX,wBAAwBxB,MAAMO,OAAO;IAC1D,IAAI4B,iBAAiBV,WAAW;QAC9B5B,OAAOwB,IAAI,CAAC;QACZ,OAAOc;IACT;IAEA,MAAMC,mBAAmBZ,wBAAwBxB,MAAMO,OAAO;IAC9D,IAAI6B,qBAAqBX,WAAW;QAClC5B,OAAOwB,IAAI,CAAC;QACZ,OAAOe;IACT;IAEA,MAAMC,mBAAmBb,wBAAwBxB,MAAMO,OAAO;IAC9D,IAAI8B,qBAAqBZ,WAAW;QAClC5B,OAAOwB,IAAI,CAAC;YAACS,MAAM;YAAgBF,cAAc;QAAC;QAClD,OAAOS;IACT;IAEA,MAAMC,gBAAgBd,wBAAwBxB,MAAMO,OAAO;IAC3D,IAAI+B,kBAAkBb,WAAW;QAC/B5B,OAAOwB,IAAI,CAAC;QACZ,OAAOiB;IACT;IAEA,MAAMC,kBAAkBf,wBAAwBxB,MAAMO,OAAO;IAC7D,IAAIgC,oBAAoBd,WAAW;QACjC5B,OAAOwB,IAAI,CAAC;QACZ,OAAOkB;IACT;IAEA,MAAMC,oBAAoBhB,wBAAwBxB,MAAMO,OAAO;IAC/D,IAAIiC,sBAAsBf,WAAW;QACnC5B,OAAOwB,IAAI,CAAC;QACZ,OAAOmB;IACT;IAEA,MAAMC,oBAAoBjB,wBAAwBxB,MAAMO,OAAO;IAC/D,IAAIkC,sBAAsBhB,WAAW;QACnC5B,OAAOwB,IAAI,CAAC;QACZ,OAAOoB;IACT;IAEA,MAAMC,aAAalB,wBAAwBxB,MAAMO,OAAO;IACxD,IAAImC,eAAejB,WAAW;QAC5B5B,OAAOwB,IAAI,CAAC;QACZ,OAAOqB;IACT;IAEA,IAAI1C,IAAI,CAACO,MAAM,KAAK,KAAK;QACvBV,OAAOwB,IAAI,CAAC;QACZ,OAAOd,QAAQ;IACjB;IAEA,IAAIP,IAAI,CAACO,MAAM,KAAK,KAAK;QACvBV,OAAOwB,IAAI,CAAC;QACZ,OAAOd,QAAQ;IACjB;IAEA,IAAIP,IAAI,CAACO,MAAM,KAAK,KAAK;QACvBV,OAAOwB,IAAI,CAAC;QACZ,OAAOd,QAAQ;IACjB;IAEA,OAAOA,QAAQ;AACjB;AAEA,SAASa,sBAAsBpB,IAAY,EAAEO,KAAa,EAAEV,MAAwB;IAClF,MAAMuC,mBAAmBZ,wBAAwBxB,MAAMO,OAAO;IAC9D,IAAI6B,qBAAqBX,WAAW;QAClC5B,OAAOwB,IAAI,CAAC;QACZ,OAAOe;IACT;IAEA,MAAMC,mBAAmBb,wBAAwBxB,MAAMO,OAAO;IAC9D,IAAI8B,qBAAqBZ,WAAW;QAClC5B,OAAOwB,IAAI,CAAC;YAACS,MAAM;YAAgBF,cAAc;QAAC;QAClD,OAAOS;IACT;IAEA,MAAMC,gBAAgBd,wBAAwBxB,MAAMO,OAAO;IAC3D,IAAI+B,kBAAkBb,WAAW;QAC/B5B,OAAOwB,IAAI,CAAC;QACZ,OAAOiB;IACT;IAEA,MAAMC,kBAAkBf,wBAAwBxB,MAAMO,OAAO;IAC7D,IAAIgC,oBAAoBd,WAAW;QACjC5B,OAAOwB,IAAI,CAAC;QACZ,OAAOkB;IACT;IAEA,MAAMC,oBAAoBhB,wBAAwBxB,MAAMO,OAAO;IAC/D,IAAIiC,sBAAsBf,WAAW;QACnC5B,OAAOwB,IAAI,CAAC;QACZ,OAAOmB;IACT;IAEA,MAAMC,oBAAoBjB,wBAAwBxB,MAAMO,OAAO;IAC/D,IAAIkC,sBAAsBhB,WAAW;QACnC5B,OAAOwB,IAAI,CAAC;QACZ,OAAOoB;IACT;IAEA,OAAOlC,QAAQ;AACjB;AAEA,SAASiB,wBAAwBxB,IAAY,EAAEO,KAAa,EAAEoC,MAAc;IAC1E,IAAIlC,YAAYF;IAEhB,IAAK,IAAIqC,cAAc,GAAGA,cAAcD,OAAO3B,MAAM,EAAE4B,eAAe,EAAG;QACvE,IAAI5C,IAAI,CAACS,UAAU,KAAKkC,MAAM,CAACC,YAAY,EAAE,OAAOnB;QACpDhB,aAAa;QACb,IAAImC,cAAc,IAAID,OAAO3B,MAAM,EAAEP,YAAYoC,2BAA2B7C,MAAMS;IACpF;IAEA,OAAOA;AACT;AAEA,SAASoC,2BAA2B7C,IAAY,EAAEO,KAAa;IAC7D,IAAIE,YAAYF;IAEhB,MAAOP,IAAI,CAACS,UAAU,KAAK,QAAQT,IAAI,CAACS,YAAY,EAAE,KAAK,KAAM;QAC/DA,aAAa;IACf;IAEA,OAAOA;AACT;AAEA,SAASI,gBACPb,IAAY,EACZO,KAAa;IAOb,IAAIA,QAAQ,KAAKP,KAAKgB,MAAM,EAAE;QAC5B,OAAO;YACLT,OAAOP,KAAKgB,MAAM;YAClBZ,eAAe;YACfW,0BAA0B;YAC1BD,eAAe;QACjB;IACF;IAEA,OAAO;QACLP,OAAOA,QAAQ;QACfH,eAAe;QACfW,0BAA0B;QAC1BD,eAAed,IAAI,CAACO,QAAQ,EAAE,KAAK;IACrC;AACF;AAEA,SAASW,SAASrB,MAAiC;IACjD,OAAOA,OAAOiD,EAAE,CAAC,CAAC;AACpB;AAEA,SAAS3C,oBAAoBc,KAAqB;IAChD,IAAIS,mBAAmBT,QAAQ,OAAO;QAAC,GAAGA,KAAK;IAAA;IAC/C,OAAOA;AACT;AAEA,SAASe,iBAAiBnC,MAAiC;IACzD,IAAK,IAAIU,QAAQV,OAAOmB,MAAM,GAAG,GAAGT,SAAS,GAAGA,SAAS,EAAG;QAC1D,MAAMU,QAAQpB,MAAM,CAACU,MAAM;QAC3B,IAAIU,UAAUQ,WAAW;QACzB,IAAIC,mBAAmBT,QAAQ,OAAO;QACtC,IAAIA,UAAU,YAAYA,UAAU,UAAU,OAAOA;IACvD;IAEA,OAAO;AACT;AAEA,SAASS,mBAAmBT,KAAiC;IAC3D,OAAO,OAAOA,UAAU,YAAYA,MAAMa,IAAI,KAAK;AACrD;AAEA,SAASH,2BAA2B9B,MAAwB,EAAE+B,YAAoB;IAChF,MAAMmB,WAAWlD,OAAOmB,MAAM,GAAG;IACjC,MAAMC,QAAQpB,MAAM,CAACkD,SAAS;IAC9B,IAAIrB,mBAAmBT,QAAQpB,MAAM,CAACkD,SAAS,GAAG;QAAC,GAAG9B,KAAK;QAAEW;IAAY;AAC3E;AAEA,SAASK,uBACPjC,IAAY,EACZO,KAAa,EACbF,iBAAqC,EACrCC,wBAAiC;IAEjC,IAAIN,IAAI,CAACO,MAAM,KAAK,KAAK,OAAO;IAChC,IAAID,0BAA0B,OAAO;IACrC,IAAID,sBAAsBoB,WAAW,OAAO;IAE5C,OAAO3B,iCAAiCkD,IAAI,CAAC3C;AAC/C"}
@@ -0,0 +1,14 @@
1
+ export declare const invalidWorkflowTemplateErrorCode = "invalid-workflow-template";
2
+ export declare class InvalidWorkflowTemplateError extends Error {
3
+ readonly code = "invalid-workflow-template";
4
+ readonly source: string;
5
+ readonly reason: string;
6
+ readonly offset: number;
7
+ constructor(params: {
8
+ source: string;
9
+ reason: string;
10
+ offset: number;
11
+ cause?: unknown;
12
+ });
13
+ }
14
+ //# sourceMappingURL=errors.d.ts.map