@uipath/maestro-builder-sdk 5.2.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.
- package/LICENSE +21 -0
- package/README.md +322 -0
- package/dist/bindings-v2.d.ts +37 -0
- package/dist/bindings-v2.js +155 -0
- package/dist/bindings.d.ts +6 -0
- package/dist/bindings.js +6 -0
- package/dist/bpmn/bpmn-expr-check.d.ts +41 -0
- package/dist/bpmn/bpmn-expr-check.js +218 -0
- package/dist/bpmn/bpmn-sdk.d.ts +2257 -0
- package/dist/bpmn/bpmn-sdk.js +1476 -0
- package/dist/bpmn/check-cli.d.ts +3 -0
- package/dist/bpmn/check-cli.js +32 -0
- package/dist/bpmn/check.d.ts +25 -0
- package/dist/bpmn/check.js +430 -0
- package/dist/bpmn/compile-cli.d.ts +3 -0
- package/dist/bpmn/compile-cli.js +60 -0
- package/dist/bpmn/connector.d.ts +56 -0
- package/dist/bpmn/connector.js +199 -0
- package/dist/bpmn/decompile-cli.d.ts +8 -0
- package/dist/bpmn/decompile-cli.js +54 -0
- package/dist/bpmn/decompile.d.ts +6 -0
- package/dist/bpmn/decompile.js +1108 -0
- package/dist/bpmn/format-profile.d.ts +27 -0
- package/dist/bpmn/format-profile.js +11 -0
- package/dist/bpmn/intsvc.d.ts +77 -0
- package/dist/bpmn/intsvc.js +155 -0
- package/dist/bpmn/load.d.ts +4 -0
- package/dist/bpmn/load.js +22 -0
- package/dist/bpmn/merge-cli.d.ts +3 -0
- package/dist/bpmn/merge-cli.js +45 -0
- package/dist/bpmn/merge.d.ts +19 -0
- package/dist/bpmn/merge.js +293 -0
- package/dist/bpmn/registry-types.json +1869 -0
- package/dist/bpmn/serialize.d.ts +28 -0
- package/dist/bpmn/serialize.js +757 -0
- package/dist/bpmn/tidy-cli.d.ts +2 -0
- package/dist/bpmn/tidy-cli.js +39 -0
- package/dist/bpmn/typed-node.d.ts +382 -0
- package/dist/bpmn/typed-node.js +551 -0
- package/dist/bpmn/uipath-moddle.v1.json +823 -0
- package/dist/bpmn/xml-ranges.d.ts +45 -0
- package/dist/bpmn/xml-ranges.js +151 -0
- package/dist/case/case-expr-check.d.ts +35 -0
- package/dist/case/case-expr-check.js +85 -0
- package/dist/case/case-sdk.d.ts +1282 -0
- package/dist/case/case-sdk.js +923 -0
- package/dist/case/check-cli.d.ts +3 -0
- package/dist/case/check-cli.js +31 -0
- package/dist/case/check.d.ts +18 -0
- package/dist/case/check.js +456 -0
- package/dist/case/compile-cli.d.ts +3 -0
- package/dist/case/compile-cli.js +291 -0
- package/dist/case/decompile-cli.d.ts +9 -0
- package/dist/case/decompile-cli.js +117 -0
- package/dist/case/decompile.d.ts +187 -0
- package/dist/case/decompile.js +1170 -0
- package/dist/case/entry-points.d.ts +79 -0
- package/dist/case/entry-points.js +118 -0
- package/dist/case/format-profile.d.ts +60 -0
- package/dist/case/format-profile.js +79 -0
- package/dist/case/ids.d.ts +24 -0
- package/dist/case/ids.js +76 -0
- package/dist/case/load.d.ts +12 -0
- package/dist/case/load.js +32 -0
- package/dist/case/preserve.d.ts +133 -0
- package/dist/case/preserve.js +105 -0
- package/dist/case/serialize.d.ts +10 -0
- package/dist/case/serialize.js +1414 -0
- package/dist/check-cli.d.ts +3 -0
- package/dist/check-cli.js +118 -0
- package/dist/check.d.ts +146 -0
- package/dist/check.js +4898 -0
- package/dist/cli/commands/bpmn.d.ts +2 -0
- package/dist/cli/commands/bpmn.js +73 -0
- package/dist/cli/commands/case.d.ts +2 -0
- package/dist/cli/commands/case.js +60 -0
- package/dist/cli/commands/flow.d.ts +2 -0
- package/dist/cli/commands/flow.js +99 -0
- package/dist/cli/commands/registry.d.ts +10 -0
- package/dist/cli/commands/registry.js +170 -0
- package/dist/cli/common.d.ts +30 -0
- package/dist/cli/common.js +92 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +18 -0
- package/dist/cli-run.d.ts +2 -0
- package/dist/cli-run.js +42 -0
- package/dist/compile-cli.d.ts +3 -0
- package/dist/compile-cli.js +160 -0
- package/dist/config.d.ts +47 -0
- package/dist/config.js +201 -0
- package/dist/core/actions.d.ts +3244 -0
- package/dist/core/actions.js +1062 -0
- package/dist/core/binding-messages.d.ts +1 -0
- package/dist/core/binding-messages.js +16 -0
- package/dist/core/bindings.d.ts +12 -0
- package/dist/core/bindings.js +67 -0
- package/dist/core/ceql.d.ts +73 -0
- package/dist/core/ceql.js +272 -0
- package/dist/core/cli-spelling.d.ts +39 -0
- package/dist/core/cli-spelling.js +62 -0
- package/dist/core/connector-raw-node.d.ts +21 -0
- package/dist/core/connector-raw-node.js +47 -0
- package/dist/core/connectors.d.ts +184 -0
- package/dist/core/connectors.js +128 -0
- package/dist/core/expr-check.d.ts +93 -0
- package/dist/core/expr-check.js +186 -0
- package/dist/core/expr.d.ts +323 -0
- package/dist/core/expr.js +400 -0
- package/dist/core/index.d.ts +10 -0
- package/dist/core/index.js +10 -0
- package/dist/core/library.d.ts +440 -0
- package/dist/core/library.js +1183 -0
- package/dist/core/list-envelope.d.ts +45 -0
- package/dist/core/list-envelope.js +97 -0
- package/dist/core/lookup-store.d.ts +22 -0
- package/dist/core/lookup-store.js +85 -0
- package/dist/core/lookups.d.ts +227 -0
- package/dist/core/lookups.js +231 -0
- package/dist/core/node-classes.d.ts +234 -0
- package/dist/core/node-classes.js +158 -0
- package/dist/core/script-return.d.ts +68 -0
- package/dist/core/script-return.js +197 -0
- package/dist/core/stable-id.d.ts +28 -0
- package/dist/core/stable-id.js +37 -0
- package/dist/core-definitions.json +16249 -0
- package/dist/decompile-cli.d.ts +3 -0
- package/dist/decompile-cli.js +131 -0
- package/dist/decompile.d.ts +138 -0
- package/dist/decompile.js +2482 -0
- package/dist/emit.d.ts +10 -0
- package/dist/emit.js +60 -0
- package/dist/event-filters.d.ts +130 -0
- package/dist/event-filters.js +137 -0
- package/dist/flow-expr-check.d.ts +17 -0
- package/dist/flow-expr-check.js +193 -0
- package/dist/flow-sdk.d.ts +1341 -0
- package/dist/flow-sdk.js +1164 -0
- package/dist/flow-variables.d.ts +13 -0
- package/dist/flow-variables.js +42 -0
- package/dist/format-profile.d.ts +72 -0
- package/dist/format-profile.js +97 -0
- package/dist/generators/_connections.py +287 -0
- package/dist/generators/_events.py +355 -0
- package/dist/generators/_lookups.py +114 -0
- package/dist/generators/_naming.py +185 -0
- package/dist/generators/_objects.py +299 -0
- package/dist/generators/_resolve.py +273 -0
- package/dist/generators/convert_library_to_md.py +1441 -0
- package/dist/generators/extract_library.py +125 -0
- package/dist/generators/generate_connectors_ts.py +936 -0
- package/dist/generators/generate_library_json.py +2527 -0
- package/dist/generators/generate_triggers_ts.py +110 -0
- package/dist/generators/materialize_registry.py +155 -0
- package/dist/generators/prepare_connector.py +1688 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.js +35 -0
- package/dist/ixp-definition.json +1982 -0
- package/dist/library.d.ts +6 -0
- package/dist/library.js +6 -0
- package/dist/load.d.ts +16 -0
- package/dist/load.js +95 -0
- package/dist/merge-cli.d.ts +3 -0
- package/dist/merge-cli.js +47 -0
- package/dist/merge.d.ts +125 -0
- package/dist/merge.js +0 -0
- package/dist/migrate.d.ts +15 -0
- package/dist/migrate.js +245 -0
- package/dist/node-runtime.d.ts +3 -0
- package/dist/node-runtime.js +22 -0
- package/dist/package-name.d.ts +17 -0
- package/dist/package-name.js +17 -0
- package/dist/ref-resolve.d.ts +77 -0
- package/dist/ref-resolve.js +170 -0
- package/dist/registry/cache.d.ts +55 -0
- package/dist/registry/cache.js +134 -0
- package/dist/registry/curated-overlay.d.ts +16 -0
- package/dist/registry/curated-overlay.js +62 -0
- package/dist/registry/extractor.d.ts +22 -0
- package/dist/registry/extractor.js +18 -0
- package/dist/registry/materialize-bin.d.ts +2 -0
- package/dist/registry/materialize-bin.js +7 -0
- package/dist/registry/materialize-cli.d.ts +1 -0
- package/dist/registry/materialize-cli.js +46 -0
- package/dist/registry/materializer.d.ts +23 -0
- package/dist/registry/materializer.js +34 -0
- package/dist/registry/path-cli.d.ts +1 -0
- package/dist/registry/path-cli.js +56 -0
- package/dist/registry/prepare-cli.d.ts +62 -0
- package/dist/registry/prepare-cli.js +185 -0
- package/dist/registry/pull-cli.d.ts +1 -0
- package/dist/registry/pull-cli.js +274 -0
- package/dist/registry/python.d.ts +26 -0
- package/dist/registry/python.js +46 -0
- package/dist/registry/search-cli.d.ts +52 -0
- package/dist/registry/search-cli.js +159 -0
- package/dist/schema-version.d.ts +165 -0
- package/dist/schema-version.js +148 -0
- package/dist/serialize.d.ts +64 -0
- package/dist/serialize.js +6398 -0
- package/lib/README.md +112 -0
- package/lib/library-json.samples/index.json +158 -0
- package/lib/library-json.samples/invariant-collections.json +83 -0
- package/lib/library-json.samples/list-envelopes.json +123 -0
- package/lib/library-json.samples/uipath-atlassian-jira/create-issue@1.0.0.json +131 -0
- package/lib/library-json.samples/uipath-atlassian-jira/create-issue@1.0.0.v1def.json +306 -0
- package/lib/library-json.samples/uipath-atlassian-jira/generic/create_issue/create@1.0.0.json +86 -0
- package/lib/library-json.samples/uipath-atlassian-jira/generic/create_issue/create@1.0.0.v1def.json +208 -0
- package/lib/library-json.samples/uipath-atlassian-jira/get-issue@1.0.0.json +2040 -0
- package/lib/library-json.samples/uipath-atlassian-jira/get-issue@1.0.0.v1def.json +195 -0
- package/lib/library-json.samples/uipath-google-vertex/execute-google-vertex-agent@1.0.0.json +169 -0
- package/lib/library-json.samples/uipath-google-vertex/execute-google-vertex-agent@1.0.0.v1def.json +209 -0
- package/lib/library-json.samples/uipath-http-webhook/event-http-webhook@1.0.0.json +63 -0
- package/lib/library-json.samples/uipath-http-webhook/event-http-webhook@1.0.0.v1def.json +262 -0
- package/lib/library-json.samples/uipath-http-webhook/trigger-http-webhook@1.0.0.json +63 -0
- package/lib/library-json.samples/uipath-http-webhook/trigger-http-webhook@1.0.0.v1def.json +213 -0
- package/lib/library-json.samples/uipath-microsoft-azureactivedirectory/list-groups@1.0.0.json +227 -0
- package/lib/library-json.samples/uipath-microsoft-azureactivedirectory/list-groups@1.0.0.v1def.json +373 -0
- package/lib/library-json.samples/uipath-microsoft-onedrive/event-file-created@1.0.0.json +116 -0
- package/lib/library-json.samples/uipath-microsoft-onedrive/event-file-created@1.0.0.v1def.json +369 -0
- package/lib/library-json.samples/uipath-microsoft-onedrive/event-list-item-added@1.0.0.json +56 -0
- package/lib/library-json.samples/uipath-microsoft-onedrive/event-list-item-added@1.0.0.v1def.json +256 -0
- package/lib/library-json.samples/uipath-microsoft-onedrive/trigger-file-created@1.0.0.json +116 -0
- package/lib/library-json.samples/uipath-microsoft-onedrive/trigger-file-created@1.0.0.v1def.json +320 -0
- package/lib/library-json.samples/uipath-microsoft-onedrive/trigger-list-item-added@1.0.0.json +56 -0
- package/lib/library-json.samples/uipath-microsoft-onedrive/trigger-list-item-added@1.0.0.v1def.json +207 -0
- package/lib/library-json.samples/uipath-microsoft-outlook365/event-email-received@1.0.0.json +107 -0
- package/lib/library-json.samples/uipath-microsoft-outlook365/event-email-received@1.0.0.v1def.json +264 -0
- package/lib/library-json.samples/uipath-microsoft-outlook365/send-email@1.0.0.json +142 -0
- package/lib/library-json.samples/uipath-microsoft-outlook365/send-email@1.0.0.v1def.json +306 -0
- package/lib/library-json.samples/uipath-microsoft-outlook365/trigger-email-received@1.0.0.json +107 -0
- package/lib/library-json.samples/uipath-microsoft-outlook365/trigger-email-received@1.0.0.v1def.json +217 -0
- package/lib/library-json.samples/uipath-microsoft-powerautomate/invoke-a-microsoft-power-automate-flow@1.0.0.json +85 -0
- package/lib/library-json.samples/uipath-microsoft-powerautomate/invoke-a-microsoft-power-automate-flow@1.0.0.v1def.json +209 -0
- package/lib/library-json.samples/uipath-salesforce-slack/send-message-to-user@1.0.0.json +755 -0
- package/lib/library-json.samples/uipath-salesforce-slack/send-message-to-user@1.0.0.v1def.json +513 -0
- package/lib/library-json.samples/uipath-uipath-dataservice/query-entity-records@1.0.0.json +122 -0
- package/lib/library-json.samples/uipath-uipath-dataservice/query-entity-records@1.0.0.v1def.json +227 -0
- package/package.json +85 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* core/script-return — what a `core.action.script` node PUBLISHES.
|
|
3
|
+
*
|
|
4
|
+
* A script node's runtime output IS its return value, but the platform's own
|
|
5
|
+
* definition can only say `output: {type: 'object', description: 'The return
|
|
6
|
+
* value of the script'}` — the node type has no way to know what any particular
|
|
7
|
+
* body returns. The designer believes that declaration and types the read as
|
|
8
|
+
* `Record<string, any>`, so mapping a string-returning script into a `string`
|
|
9
|
+
* flow output is reported as
|
|
10
|
+
*
|
|
11
|
+
* Type 'Record<string, any>' is not assignable to type 'string'
|
|
12
|
+
*
|
|
13
|
+
* on a flow that is correct and runs. The declaration is the thing that is
|
|
14
|
+
* wrong, and it is knowable at author time: the body is right there.
|
|
15
|
+
*
|
|
16
|
+
* So the type rides on the INSTANCE, the same split `httpOutputs` uses — the
|
|
17
|
+
* bundled definition stays byte-faithful to the platform's, and what the author
|
|
18
|
+
* wrote (or what their code plainly says) is the only source of shape.
|
|
19
|
+
*
|
|
20
|
+
* Two ways in, in precedence order:
|
|
21
|
+
*
|
|
22
|
+
* 1. `script({ code, returns })` — the author says so. Always wins.
|
|
23
|
+
* 2. inference from the body, below — used when `returns` is absent.
|
|
24
|
+
*
|
|
25
|
+
* Inference is deliberately TIMID. It answers only when every `return` in the
|
|
26
|
+
* body agrees, and says nothing at all otherwise: an unknown shape must stay the
|
|
27
|
+
* definition's open object, because narrowing it wrongly turns a working read
|
|
28
|
+
* into a designer error — the exact defect this file exists to remove, pointed
|
|
29
|
+
* the other way.
|
|
30
|
+
*/
|
|
31
|
+
/** The vocabulary a script's output can be declared as. */
|
|
32
|
+
export type ScriptReturnType = 'string' | 'number' | 'boolean' | 'object' | 'array';
|
|
33
|
+
/**
|
|
34
|
+
* What an author may write for `script({ returns })`: the type outright, or —
|
|
35
|
+
* for an object return — the FIELDS, which is the spelling every other action's
|
|
36
|
+
* `returns` uses (`http`, `rpaWorkflow`, `agent`).
|
|
37
|
+
*/
|
|
38
|
+
export type ScriptReturns = ScriptReturnType | Record<string, ScriptReturnType>;
|
|
39
|
+
/** A resolved output declaration: a type, and for objects the fields we know. */
|
|
40
|
+
export interface ScriptOutputShape {
|
|
41
|
+
type: ScriptReturnType;
|
|
42
|
+
properties?: Record<string, {
|
|
43
|
+
type: ScriptReturnType;
|
|
44
|
+
}>;
|
|
45
|
+
}
|
|
46
|
+
/** Normalize whatever the author wrote into the emitted shape. */
|
|
47
|
+
export declare function declaredScriptShape(returns: ScriptReturns): ScriptOutputShape;
|
|
48
|
+
/**
|
|
49
|
+
* The TYPE a script body plainly returns, or `undefined` when it does not
|
|
50
|
+
* plainly return one.
|
|
51
|
+
*
|
|
52
|
+
* "Plainly" is the whole contract. Every `return` in the body must resolve to
|
|
53
|
+
* the same type; one that resolves to nothing (a call, a parameter, anything
|
|
54
|
+
* whose type is not written down) makes the ANSWER nothing, not a guess from the
|
|
55
|
+
* returns that did resolve. A body with no `return` at all also answers nothing.
|
|
56
|
+
*
|
|
57
|
+
* **It types, it does not enumerate.** An object return comes back as plain
|
|
58
|
+
* `object`, never as a field list, even though the literal's fields are right
|
|
59
|
+
* there. A field list is a COMPLETENESS claim — "these are the fields" — and a
|
|
60
|
+
* body that returns `{a}` on one path and `{a, b}` on another, or assembles
|
|
61
|
+
* fields in a loop, makes that claim false while the top-level type stays true.
|
|
62
|
+
* Nothing is lost by declining: the designer types an undescribed object as
|
|
63
|
+
* `Record<string, any>`, which already admits every field read, so an inferred
|
|
64
|
+
* field list buys no diagnostic and would rewrite `properties` into every
|
|
65
|
+
* object-returning script node in every existing flow. An author who wants the
|
|
66
|
+
* fields written down says so with `returns: {…}`.
|
|
67
|
+
*/
|
|
68
|
+
export declare function inferScriptShape(code: string): ScriptOutputShape | undefined;
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* core/script-return — what a `core.action.script` node PUBLISHES.
|
|
3
|
+
*
|
|
4
|
+
* A script node's runtime output IS its return value, but the platform's own
|
|
5
|
+
* definition can only say `output: {type: 'object', description: 'The return
|
|
6
|
+
* value of the script'}` — the node type has no way to know what any particular
|
|
7
|
+
* body returns. The designer believes that declaration and types the read as
|
|
8
|
+
* `Record<string, any>`, so mapping a string-returning script into a `string`
|
|
9
|
+
* flow output is reported as
|
|
10
|
+
*
|
|
11
|
+
* Type 'Record<string, any>' is not assignable to type 'string'
|
|
12
|
+
*
|
|
13
|
+
* on a flow that is correct and runs. The declaration is the thing that is
|
|
14
|
+
* wrong, and it is knowable at author time: the body is right there.
|
|
15
|
+
*
|
|
16
|
+
* So the type rides on the INSTANCE, the same split `httpOutputs` uses — the
|
|
17
|
+
* bundled definition stays byte-faithful to the platform's, and what the author
|
|
18
|
+
* wrote (or what their code plainly says) is the only source of shape.
|
|
19
|
+
*
|
|
20
|
+
* Two ways in, in precedence order:
|
|
21
|
+
*
|
|
22
|
+
* 1. `script({ code, returns })` — the author says so. Always wins.
|
|
23
|
+
* 2. inference from the body, below — used when `returns` is absent.
|
|
24
|
+
*
|
|
25
|
+
* Inference is deliberately TIMID. It answers only when every `return` in the
|
|
26
|
+
* body agrees, and says nothing at all otherwise: an unknown shape must stay the
|
|
27
|
+
* definition's open object, because narrowing it wrongly turns a working read
|
|
28
|
+
* into a designer error — the exact defect this file exists to remove, pointed
|
|
29
|
+
* the other way.
|
|
30
|
+
*/
|
|
31
|
+
import * as ts from 'typescript';
|
|
32
|
+
/** Normalize whatever the author wrote into the emitted shape. */
|
|
33
|
+
export function declaredScriptShape(returns) {
|
|
34
|
+
if (typeof returns === 'string')
|
|
35
|
+
return { type: returns };
|
|
36
|
+
return {
|
|
37
|
+
type: 'object',
|
|
38
|
+
properties: Object.fromEntries(Object.entries(returns).map(([k, t]) => [k, { type: t }])),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The TYPE a script body plainly returns, or `undefined` when it does not
|
|
43
|
+
* plainly return one.
|
|
44
|
+
*
|
|
45
|
+
* "Plainly" is the whole contract. Every `return` in the body must resolve to
|
|
46
|
+
* the same type; one that resolves to nothing (a call, a parameter, anything
|
|
47
|
+
* whose type is not written down) makes the ANSWER nothing, not a guess from the
|
|
48
|
+
* returns that did resolve. A body with no `return` at all also answers nothing.
|
|
49
|
+
*
|
|
50
|
+
* **It types, it does not enumerate.** An object return comes back as plain
|
|
51
|
+
* `object`, never as a field list, even though the literal's fields are right
|
|
52
|
+
* there. A field list is a COMPLETENESS claim — "these are the fields" — and a
|
|
53
|
+
* body that returns `{a}` on one path and `{a, b}` on another, or assembles
|
|
54
|
+
* fields in a loop, makes that claim false while the top-level type stays true.
|
|
55
|
+
* Nothing is lost by declining: the designer types an undescribed object as
|
|
56
|
+
* `Record<string, any>`, which already admits every field read, so an inferred
|
|
57
|
+
* field list buys no diagnostic and would rewrite `properties` into every
|
|
58
|
+
* object-returning script node in every existing flow. An author who wants the
|
|
59
|
+
* fields written down says so with `returns: {…}`.
|
|
60
|
+
*/
|
|
61
|
+
export function inferScriptShape(code) {
|
|
62
|
+
// Wrap so a top-level `return` parses — this is how the runtime executes it.
|
|
63
|
+
const sf = ts.createSourceFile('script.ts', `function __block() {\n${code}\n}`, ts.ScriptTarget.ES2020, true);
|
|
64
|
+
// `var d = Math.floor(...); return { days: d }` is how these bodies are
|
|
65
|
+
// written, so simple local initializers are resolved before typing a return.
|
|
66
|
+
// Last write wins: a name reassigned to a different type is a name we cannot
|
|
67
|
+
// type, and the disagreement below is what discards it.
|
|
68
|
+
const locals = new Map();
|
|
69
|
+
const collectLocals = (n) => {
|
|
70
|
+
if (ts.isVariableDeclaration(n) && ts.isIdentifier(n.name) && n.initializer) {
|
|
71
|
+
locals.set(n.name.text, n.initializer);
|
|
72
|
+
}
|
|
73
|
+
ts.forEachChild(n, collectLocals);
|
|
74
|
+
};
|
|
75
|
+
collectLocals(sf);
|
|
76
|
+
const shapes = [];
|
|
77
|
+
const visit = (n) => {
|
|
78
|
+
// A nested function's `return` belongs to that function, not to the script.
|
|
79
|
+
if (n !== sf && (ts.isFunctionDeclaration(n) || ts.isFunctionExpression(n) || ts.isArrowFunction(n))) {
|
|
80
|
+
if (n.parent !== sf)
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (ts.isReturnStatement(n))
|
|
84
|
+
shapes.push(n.expression ? typeOf(n.expression, locals, 0) : undefined);
|
|
85
|
+
ts.forEachChild(n, visit);
|
|
86
|
+
};
|
|
87
|
+
// Skip the synthetic wrapper so its own body is walked, not treated as nested.
|
|
88
|
+
ts.forEachChild(sf, (n) => (ts.isFunctionDeclaration(n) && n.body ? ts.forEachChild(n.body, visit) : visit(n)));
|
|
89
|
+
if (shapes.length === 0)
|
|
90
|
+
return undefined;
|
|
91
|
+
// One unresolved return poisons the answer — see the doc comment.
|
|
92
|
+
if (shapes.some((s) => s === undefined))
|
|
93
|
+
return undefined;
|
|
94
|
+
const first = shapes[0];
|
|
95
|
+
if (shapes.some((s) => s.type !== first.type))
|
|
96
|
+
return undefined;
|
|
97
|
+
// Type only — never the fields, see the doc comment.
|
|
98
|
+
return { type: first.type };
|
|
99
|
+
}
|
|
100
|
+
/** The type of one expression, or undefined when it is not written down. */
|
|
101
|
+
function typeOf(expr, locals, depth) {
|
|
102
|
+
// Bounded: a local initialized from another local is followed, a cycle is not.
|
|
103
|
+
if (depth > 8)
|
|
104
|
+
return undefined;
|
|
105
|
+
const e = ts.isParenthesizedExpression(expr) ? expr.expression : expr;
|
|
106
|
+
if (ts.isStringLiteral(e) || ts.isNoSubstitutionTemplateLiteral(e) || ts.isTemplateExpression(e)) {
|
|
107
|
+
return { type: 'string' };
|
|
108
|
+
}
|
|
109
|
+
if (ts.isNumericLiteral(e))
|
|
110
|
+
return { type: 'number' };
|
|
111
|
+
if (e.kind === ts.SyntaxKind.TrueKeyword || e.kind === ts.SyntaxKind.FalseKeyword) {
|
|
112
|
+
return { type: 'boolean' };
|
|
113
|
+
}
|
|
114
|
+
if (ts.isArrayLiteralExpression(e))
|
|
115
|
+
return { type: 'array' };
|
|
116
|
+
if (ts.isObjectLiteralExpression(e))
|
|
117
|
+
return { type: 'object' };
|
|
118
|
+
// `-1` / `+n` / `!ok` — the operator decides, not the operand.
|
|
119
|
+
if (ts.isPrefixUnaryExpression(e)) {
|
|
120
|
+
if (e.operator === ts.SyntaxKind.ExclamationToken)
|
|
121
|
+
return { type: 'boolean' };
|
|
122
|
+
if (e.operator === ts.SyntaxKind.MinusToken || e.operator === ts.SyntaxKind.PlusToken) {
|
|
123
|
+
return typeOf(e.operand, locals, depth + 1)?.type === 'number' ? { type: 'number' } : undefined;
|
|
124
|
+
}
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
127
|
+
if (ts.isBinaryExpression(e))
|
|
128
|
+
return binaryShape(e, locals, depth);
|
|
129
|
+
// `cond ? a : b` — only when both arms agree.
|
|
130
|
+
if (ts.isConditionalExpression(e)) {
|
|
131
|
+
const a = typeOf(e.whenTrue, locals, depth + 1);
|
|
132
|
+
const b = typeOf(e.whenFalse, locals, depth + 1);
|
|
133
|
+
return a && b && a.type === b.type ? { type: a.type } : undefined;
|
|
134
|
+
}
|
|
135
|
+
// A local whose initializer we can type. `$vars.…` is an identifier chain the
|
|
136
|
+
// script reads from the runtime bag, never a local, so it lands here and
|
|
137
|
+
// correctly answers nothing.
|
|
138
|
+
if (ts.isIdentifier(e)) {
|
|
139
|
+
const init = locals.get(e.text);
|
|
140
|
+
return init ? typeOf(init, locals, depth + 1) : undefined;
|
|
141
|
+
}
|
|
142
|
+
// `String(x)` / `Number(x)` / `Boolean(x)` — the platform's own bodies use
|
|
143
|
+
// these to coerce before publishing, and the conversion names the type.
|
|
144
|
+
if (ts.isCallExpression(e) && ts.isIdentifier(e.expression)) {
|
|
145
|
+
const fn = e.expression.text;
|
|
146
|
+
if (fn === 'String')
|
|
147
|
+
return { type: 'string' };
|
|
148
|
+
if (fn === 'Number' || fn === 'parseInt' || fn === 'parseFloat')
|
|
149
|
+
return { type: 'number' };
|
|
150
|
+
if (fn === 'Boolean')
|
|
151
|
+
return { type: 'boolean' };
|
|
152
|
+
}
|
|
153
|
+
// `[...].join(…)` / `x.toFixed(…)` and friends: the METHOD names the type.
|
|
154
|
+
if (ts.isCallExpression(e) && ts.isPropertyAccessExpression(e.expression)) {
|
|
155
|
+
const m = e.expression.name.text;
|
|
156
|
+
if (m === 'join' || m === 'toFixed' || m === 'toString' || m === 'trim'
|
|
157
|
+
|| m === 'toUpperCase' || m === 'toLowerCase')
|
|
158
|
+
return { type: 'string' };
|
|
159
|
+
if (m === 'map' || m === 'filter' || m === 'slice' || m === 'concat' || m === 'sort')
|
|
160
|
+
return undefined;
|
|
161
|
+
}
|
|
162
|
+
return undefined;
|
|
163
|
+
}
|
|
164
|
+
/** `a + b`, comparisons, and the short-circuit operators. */
|
|
165
|
+
function binaryShape(e, locals, depth) {
|
|
166
|
+
const op = e.operatorToken.kind;
|
|
167
|
+
// A comparison is a boolean whatever its operands are.
|
|
168
|
+
if (op === ts.SyntaxKind.EqualsEqualsToken || op === ts.SyntaxKind.EqualsEqualsEqualsToken
|
|
169
|
+
|| op === ts.SyntaxKind.ExclamationEqualsToken || op === ts.SyntaxKind.ExclamationEqualsEqualsToken
|
|
170
|
+
|| op === ts.SyntaxKind.LessThanToken || op === ts.SyntaxKind.LessThanEqualsToken
|
|
171
|
+
|| op === ts.SyntaxKind.GreaterThanToken || op === ts.SyntaxKind.GreaterThanEqualsToken) {
|
|
172
|
+
return { type: 'boolean' };
|
|
173
|
+
}
|
|
174
|
+
const left = typeOf(e.left, locals, depth + 1);
|
|
175
|
+
const right = typeOf(e.right, locals, depth + 1);
|
|
176
|
+
if (op === ts.SyntaxKind.PlusToken) {
|
|
177
|
+
// JS `+` is concatenation the moment EITHER side is a string — which is how
|
|
178
|
+
// these bodies build a message out of a runtime value: `"claim " + $vars.…`.
|
|
179
|
+
// That is a string no matter what the unknown side turns out to be.
|
|
180
|
+
if (left?.type === 'string' || right?.type === 'string')
|
|
181
|
+
return { type: 'string' };
|
|
182
|
+
if (left?.type === 'number' && right?.type === 'number')
|
|
183
|
+
return { type: 'number' };
|
|
184
|
+
return undefined;
|
|
185
|
+
}
|
|
186
|
+
if (op === ts.SyntaxKind.MinusToken || op === ts.SyntaxKind.AsteriskToken
|
|
187
|
+
|| op === ts.SyntaxKind.SlashToken || op === ts.SyntaxKind.PercentToken) {
|
|
188
|
+
// Arithmetic is numeric regardless of what the operands turn out to be —
|
|
189
|
+
// `$vars.a.output * 2` is a number even though the left side is unknown.
|
|
190
|
+
return { type: 'number' };
|
|
191
|
+
}
|
|
192
|
+
// `a || b` / `a ?? b` — only when both sides agree; the fallback is the point.
|
|
193
|
+
if (op === ts.SyntaxKind.BarBarToken || op === ts.SyntaxKind.QuestionQuestionToken) {
|
|
194
|
+
return left && right && left.type === right.type ? { type: left.type } : undefined;
|
|
195
|
+
}
|
|
196
|
+
return undefined;
|
|
197
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* core/stable-id — a uuid-shaped id derived from a seed, with no randomness.
|
|
3
|
+
*
|
|
4
|
+
* The designer mints random uuids for the ids inside a connector's filter tree
|
|
5
|
+
* and event subscription. We cannot: recompiling an unchanged flow has to be
|
|
6
|
+
* byte-identical, and a random id would churn every build and show up as a diff
|
|
7
|
+
* in every artifact review.
|
|
8
|
+
*
|
|
9
|
+
* Shared by the event-subscription serializer and the CEQL filter-tree parser so
|
|
10
|
+
* there is one implementation rather than two that drift.
|
|
11
|
+
*
|
|
12
|
+
* ## The `>>> 0` on the last segment is a fix, not a flourish
|
|
13
|
+
*
|
|
14
|
+
* `^` in JavaScript yields a SIGNED 32-bit integer, so `(h1 ^ h2)` is negative
|
|
15
|
+
* about half the time. `(-2023473408).toString(16)` is `'-78a62ef0'`, which is
|
|
16
|
+
* already 8 characters, so the `padStart(8, '0')` never fires and the `-` lands
|
|
17
|
+
* in the middle of the id:
|
|
18
|
+
*
|
|
19
|
+
* 86592478-0100-4008-8000--78a62ef0100
|
|
20
|
+
* ↑ not a uuid
|
|
21
|
+
*
|
|
22
|
+
* Measured over 5,000 seeds before the fix: **2,483 malformed — 49.7%.** Every
|
|
23
|
+
* other connector event-subscription filter therefore shipped an id the canvas
|
|
24
|
+
* cannot read as a uuid. Coercing to unsigned first is the whole repair; the
|
|
25
|
+
* hash itself is unchanged, so a seed that produced a WELL-FORMED id still
|
|
26
|
+
* produces exactly that id.
|
|
27
|
+
*/
|
|
28
|
+
export declare function stableId(seed: string): string;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* core/stable-id — a uuid-shaped id derived from a seed, with no randomness.
|
|
3
|
+
*
|
|
4
|
+
* The designer mints random uuids for the ids inside a connector's filter tree
|
|
5
|
+
* and event subscription. We cannot: recompiling an unchanged flow has to be
|
|
6
|
+
* byte-identical, and a random id would churn every build and show up as a diff
|
|
7
|
+
* in every artifact review.
|
|
8
|
+
*
|
|
9
|
+
* Shared by the event-subscription serializer and the CEQL filter-tree parser so
|
|
10
|
+
* there is one implementation rather than two that drift.
|
|
11
|
+
*
|
|
12
|
+
* ## The `>>> 0` on the last segment is a fix, not a flourish
|
|
13
|
+
*
|
|
14
|
+
* `^` in JavaScript yields a SIGNED 32-bit integer, so `(h1 ^ h2)` is negative
|
|
15
|
+
* about half the time. `(-2023473408).toString(16)` is `'-78a62ef0'`, which is
|
|
16
|
+
* already 8 characters, so the `padStart(8, '0')` never fires and the `-` lands
|
|
17
|
+
* in the middle of the id:
|
|
18
|
+
*
|
|
19
|
+
* 86592478-0100-4008-8000--78a62ef0100
|
|
20
|
+
* ↑ not a uuid
|
|
21
|
+
*
|
|
22
|
+
* Measured over 5,000 seeds before the fix: **2,483 malformed — 49.7%.** Every
|
|
23
|
+
* other connector event-subscription filter therefore shipped an id the canvas
|
|
24
|
+
* cannot read as a uuid. Coercing to unsigned first is the whole repair; the
|
|
25
|
+
* hash itself is unchanged, so a seed that produced a WELL-FORMED id still
|
|
26
|
+
* produces exactly that id.
|
|
27
|
+
*/
|
|
28
|
+
export function stableId(seed) {
|
|
29
|
+
let h1 = 0x811c9dc5;
|
|
30
|
+
let h2 = 0x01000193;
|
|
31
|
+
for (let i = 0; i < seed.length; i++) {
|
|
32
|
+
h1 = (h1 ^ seed.charCodeAt(i)) * 0x01000193 >>> 0;
|
|
33
|
+
h2 = (h2 + seed.charCodeAt(i) * (i + 7)) >>> 0;
|
|
34
|
+
}
|
|
35
|
+
const hex = (n, len) => (n >>> 0).toString(16).padStart(8, '0').slice(0, len);
|
|
36
|
+
return `${hex(h1, 8)}-${hex(h2, 4)}-4${hex(h1 >>> 8, 3)}-8${hex(h2 >>> 8, 3)}-${hex(h1 ^ h2, 8)}${hex(h2, 4)}`;
|
|
37
|
+
}
|