@lifi/composer-sdk 0.5.0 → 0.6.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/README.md +13 -3
- package/dist/authoring/FlowBuilderCore.cjs.map +1 -1
- package/dist/authoring/FlowBuilderCore.d.cts +11 -4
- package/dist/authoring/FlowBuilderCore.d.ts +11 -4
- package/dist/authoring/FlowBuilderCore.js.map +1 -1
- package/dist/authoring/handles.cjs.map +1 -1
- package/dist/authoring/handles.d.cts +2 -2
- package/dist/authoring/handles.d.ts +2 -2
- package/dist/authoring/handles.js.map +1 -1
- package/dist/authoring/raw.cjs +5 -3
- package/dist/authoring/raw.cjs.map +1 -1
- package/dist/authoring/raw.js +5 -3
- package/dist/authoring/raw.js.map +1 -1
- package/dist/client.cjs +94 -60
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +12 -4
- package/dist/client.d.ts +12 -4
- package/dist/client.js +98 -60
- package/dist/client.js.map +1 -1
- package/dist/errors.cjs +42 -3
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.cts +67 -4
- package/dist/errors.d.ts +67 -4
- package/dist/errors.js +29 -2
- package/dist/errors.js.map +1 -1
- package/dist/generated/config.generated.cjs.map +1 -1
- package/dist/generated/config.generated.d.cts +46 -5
- package/dist/generated/config.generated.d.ts +46 -5
- package/dist/generated/operations.generated.cjs +4 -0
- package/dist/generated/operations.generated.cjs.map +1 -1
- package/dist/generated/operations.generated.d.cts +16 -2
- package/dist/generated/operations.generated.d.ts +16 -2
- package/dist/generated/operations.generated.js +4 -0
- package/dist/generated/operations.generated.js.map +1 -1
- package/dist/index.cjs +8 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +11 -2
- package/dist/index.js.map +1 -1
- package/dist/outputs.cjs +33 -0
- package/dist/outputs.cjs.map +1 -0
- package/dist/outputs.d.cts +10 -0
- package/dist/outputs.d.ts +10 -0
- package/dist/outputs.js +9 -0
- package/dist/outputs.js.map +1 -0
- package/dist/responseSchemas.cjs +3 -0
- package/dist/responseSchemas.cjs.map +1 -1
- package/dist/responseSchemas.d.cts +7 -4
- package/dist/responseSchemas.d.ts +7 -4
- package/dist/responseSchemas.js +3 -0
- package/dist/responseSchemas.js.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +16 -5
- package/dist/types.d.ts +16 -5
- package/package.json +4 -3
- package/src/authoring/FlowBuilderCore.ts +12 -3
- package/src/authoring/handles.ts +2 -1
- package/src/authoring/raw.ts +4 -3
- package/src/client.ts +177 -79
- package/src/errors.ts +116 -3
- package/src/examples/flySwap.ts +3 -3
- package/src/examples/lifiZapAsync.ts +8 -7
- package/src/examples/run.ts +6 -9
- package/src/examples/swapAndZap.ts +7 -0
- package/src/examples/swapWithAllowRevert.ts +13 -3
- package/src/generated/config.generated.ts +49 -4
- package/src/generated/operations.generated.ts +25 -0
- package/src/index.ts +21 -3
- package/src/outputs.ts +16 -0
- package/src/responseSchemas.ts +10 -4
- package/src/types.ts +16 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/responseSchemas.ts"],"sourcesContent":["import type { SimulateResult, SimulationRevert } from '@lifi/compose-spec';\nimport z from 'zod';\n\n/**\n * Zod-backed parsers for Compose API response bodies.\n *\n * Server responses are untrusted input crossing into the SDK, so the shapes the\n * client reads back are validated here rather than asserted with `as` casts. The\n * schemas are module-private (the package builds with `--isolatedDeclarations`,\n * which forbids exporting un-annotated complex values); the public surface is\n * the typed `parse*` helpers, whose explicit return types double as the contract.\n *\n * The simulate union is the one response the SDK fully owns and parses itself\n * (it is un-enveloped, unlike `/compose`), so it gets a complete schema kept in\n * lockstep with the canonical `SimulateResult` in `@lifi/compose-spec` by the\n * compile-time assertion below — the same anchoring `@lifi/api-schemas` uses for\n * its server-side simulate schema, so the two cannot silently drift.\n */\n\nconst balanceEntrySchema = z.object({\n token: z.string(),\n owner: z.string(),\n amount: z.string(),\n});\n\nconst simulateOkSchema = z.object({\n status: z.literal('ok'),\n block: z.number(),\n timestamp: z.number(),\n balancesBefore: z.array(balanceEntrySchema),\n balancesAfter: z.array(balanceEntrySchema),\n deltas: z.array(balanceEntrySchema),\n gasUsed: z.string(),\n});\n\nconst simulateRevertDecodeResultSchema = z.object({\n errorCandidates: z\n .array(\n z.object({\n decodedErrorSignature: z.string(),\n decodedParams: z.array(z.string()),\n }),\n )\n .optional(),\n error: z.string().optional(),\n});\n\nconst simulateRevertSchema = z.object({\n status: z.literal('revert'),\n block: z.number(),\n timestamp: z.number(),\n revertReason: z.string().optional(),\n code: z.number().optional(),\n rawErrorBytes: z.string().optional(),\n decodeResult: simulateRevertDecodeResultSchema.optional(),\n});\n\nconst simulateSetupErrorSchema = z.object({\n status: z.literal('error'),\n message: z.string(),\n});\n\nconst simulateResultSchema = z.discriminatedUnion('status', [\n simulateOkSchema,\n simulateRevertSchema,\n simulateSetupErrorSchema,\n]);\n\n// The type the schema actually parses out. Kept private (referencing it from an\n// exported declaration would break `--isolatedDeclarations`) and pinned to the\n// canonical `SimulateResult` inside `parseSimulateResult` below.\ntype SimulateResultWire = z.infer<typeof simulateResultSchema>;\n\n/**\n * Parses a `POST /simulate` body into a {@link SimulateResult}. Returns `null`\n * when the body does not match the `ok`/`revert`/`error` union, letting the\n * caller raise a transport-level error.\n */\nexport const parseSimulateResult = (body: unknown): SimulateResult | null => {\n const parsed = simulateResultSchema.safeParse(body);\n if (!parsed.success) return null;\n // Pin the schema to the canonical contract in both directions, so it cannot\n // silently drift (mirroring the conformance assertion `@lifi/api-schemas` runs\n // on its server-side simulate schema). Assigning the inferred wire value to a\n // `SimulateResult` checks wire→spec; `satisfies SimulateResultWire` checks\n // spec→wire. A missing or mistyped field on either side fails to compile.\n const result: SimulateResult = parsed.data;\n return result satisfies SimulateResultWire;\n};\n\n/**\n * The validated members of an HTTP 206 partial compile envelope. `data` is\n * verified to be an object but
|
|
1
|
+
{"version":3,"sources":["../src/responseSchemas.ts"],"sourcesContent":["import type { SimulateResult, SimulationRevert } from '@lifi/compose-spec';\nimport z from 'zod';\n\n/**\n * Zod-backed parsers for Compose API response bodies.\n *\n * Server responses are untrusted input crossing into the SDK, so the shapes the\n * client reads back are validated here rather than asserted with `as` casts. The\n * schemas are module-private (the package builds with `--isolatedDeclarations`,\n * which forbids exporting un-annotated complex values); the public surface is\n * the typed `parse*` helpers, whose explicit return types double as the contract.\n *\n * The simulate union is the one response the SDK fully owns and parses itself\n * (it is un-enveloped, unlike `/compose`), so it gets a complete schema kept in\n * lockstep with the canonical `SimulateResult` in `@lifi/compose-spec` by the\n * compile-time assertion below — the same anchoring `@lifi/api-schemas` uses for\n * its server-side simulate schema, so the two cannot silently drift.\n */\n\nconst balanceEntrySchema = z.object({\n token: z.string(),\n owner: z.string(),\n amount: z.string(),\n});\n\nconst simulateOkSchema = z.object({\n status: z.literal('ok'),\n block: z.number(),\n timestamp: z.number(),\n balancesBefore: z.array(balanceEntrySchema),\n balancesAfter: z.array(balanceEntrySchema),\n deltas: z.array(balanceEntrySchema),\n gasUsed: z.string(),\n});\n\nconst simulateRevertDecodeResultSchema = z.object({\n errorCandidates: z\n .array(\n z.object({\n decodedErrorSignature: z.string(),\n decodedParams: z.array(z.string()),\n }),\n )\n .optional(),\n error: z.string().optional(),\n});\n\nconst simulateRevertSchema = z.object({\n status: z.literal('revert'),\n block: z.number(),\n timestamp: z.number(),\n revertReason: z.string().optional(),\n code: z.number().optional(),\n rawErrorBytes: z.string().optional(),\n decodeResult: simulateRevertDecodeResultSchema.optional(),\n});\n\nconst simulateSetupErrorSchema = z.object({\n status: z.literal('error'),\n message: z.string(),\n});\n\nconst simulateResultSchema = z.discriminatedUnion('status', [\n simulateOkSchema,\n simulateRevertSchema,\n simulateSetupErrorSchema,\n]);\n\n// The type the schema actually parses out. Kept private (referencing it from an\n// exported declaration would break `--isolatedDeclarations`) and pinned to the\n// canonical `SimulateResult` inside `parseSimulateResult` below.\ntype SimulateResultWire = z.infer<typeof simulateResultSchema>;\n\n/**\n * Parses a `POST /simulate` body into a {@link SimulateResult}. Returns `null`\n * when the body does not match the `ok`/`revert`/`error` union, letting the\n * caller raise a transport-level error.\n */\nexport const parseSimulateResult = (body: unknown): SimulateResult | null => {\n const parsed = simulateResultSchema.safeParse(body);\n if (!parsed.success) return null;\n // Pin the schema to the canonical contract in both directions, so it cannot\n // silently drift (mirroring the conformance assertion `@lifi/api-schemas` runs\n // on its server-side simulate schema). Assigning the inferred wire value to a\n // `SimulateResult` checks wire→spec; `satisfies SimulateResultWire` checks\n // spec→wire. A missing or mistyped field on either side fails to compile.\n const result: SimulateResult = parsed.data;\n return result satisfies SimulateResultWire;\n};\n\n/**\n * The validated members of an HTTP 206 partial compile envelope. `data` is\n * verified to be an object at runtime but left `unknown` here — compose-spec\n * owns its full shape (`ComposeCompilePartialData`) as a hand-authored type, so\n * the caller narrows it in one step. `error` is fully validated.\n */\nexport interface CompilePartialEnvelope {\n readonly data: unknown;\n readonly error: { readonly kind: string; readonly message: string };\n}\n\nconst compilePartialEnvelopeSchema = z.object({\n data: z.record(z.string(), z.unknown()),\n error: z.object({ kind: z.string(), message: z.string() }),\n});\n\n/** Parses an HTTP 206 partial compile envelope; `null` when it does not match. */\nexport const parseCompilePartialEnvelope = (\n body: unknown,\n): CompilePartialEnvelope | null => {\n const parsed = compilePartialEnvelopeSchema.safeParse(body);\n return parsed.success ? parsed.data : null;\n};\n\n/**\n * A single prepared-op failure inside a `preparation_error` envelope. `kind` is\n * kept as `string` here — the narrowing to `GenericComposeErrorKind` happens in\n * `errorFromHttpResponse`, where the value is lifted onto `ComposeError`.\n */\nexport interface ServerFailedPreparedOp {\n readonly callId: string;\n readonly op: string;\n readonly kind: string;\n readonly message: string;\n readonly path?: string;\n}\n\n/** Error envelope returned on non-2xx responses. */\nexport interface ServerErrorBody {\n readonly error?: {\n readonly kind?: string;\n readonly message?: string;\n readonly path?: string;\n readonly sdkVersion?: string;\n readonly serverVersion?: string;\n readonly minimumSdkVersion?: string;\n readonly details?: SimulationRevert;\n readonly failedOps?: readonly ServerFailedPreparedOp[];\n readonly succeededOps?: readonly string[];\n };\n}\n\nconst failedPreparedOpSchema = z.object({\n callId: z.string(),\n op: z.string(),\n kind: z.string(),\n message: z.string(),\n path: z.string().optional(),\n});\n\n// `details` is passed through (`z.custom`) rather than parsed: the SDK does not\n// own the `SimulationRevert` schema and forwards the field verbatim onto\n// `ComposeError`.\n//\n// `failedOps`/`succeededOps` are optional here because every error kind shares\n// this envelope; they are only populated for `preparation_error` (422). Zod\n// strips undeclared keys, so omitting them would silently drop them.\nconst serverErrorBodySchema = z.object({\n error: z\n .object({\n kind: z.string().optional(),\n message: z.string().optional(),\n path: z.string().optional(),\n sdkVersion: z.string().optional(),\n serverVersion: z.string().optional(),\n minimumSdkVersion: z.string().optional(),\n details: z.custom<SimulationRevert>().optional(),\n failedOps: z.array(failedPreparedOpSchema).readonly().optional(),\n succeededOps: z.array(z.string()).readonly().optional(),\n })\n .optional(),\n});\n\n/** Validates an already-parsed error envelope; `null` when it does not match. */\nexport const parseServerErrorBody = (json: unknown): ServerErrorBody | null => {\n const parsed = serverErrorBodySchema.safeParse(json);\n return parsed.success ? parsed.data : null;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,iBAAc;AAkBd,MAAM,qBAAqB,WAAAA,QAAE,OAAO;AAAA,EAClC,OAAO,WAAAA,QAAE,OAAO;AAAA,EAChB,OAAO,WAAAA,QAAE,OAAO;AAAA,EAChB,QAAQ,WAAAA,QAAE,OAAO;AACnB,CAAC;AAED,MAAM,mBAAmB,WAAAA,QAAE,OAAO;AAAA,EAChC,QAAQ,WAAAA,QAAE,QAAQ,IAAI;AAAA,EACtB,OAAO,WAAAA,QAAE,OAAO;AAAA,EAChB,WAAW,WAAAA,QAAE,OAAO;AAAA,EACpB,gBAAgB,WAAAA,QAAE,MAAM,kBAAkB;AAAA,EAC1C,eAAe,WAAAA,QAAE,MAAM,kBAAkB;AAAA,EACzC,QAAQ,WAAAA,QAAE,MAAM,kBAAkB;AAAA,EAClC,SAAS,WAAAA,QAAE,OAAO;AACpB,CAAC;AAED,MAAM,mCAAmC,WAAAA,QAAE,OAAO;AAAA,EAChD,iBAAiB,WAAAA,QACd;AAAA,IACC,WAAAA,QAAE,OAAO;AAAA,MACP,uBAAuB,WAAAA,QAAE,OAAO;AAAA,MAChC,eAAe,WAAAA,QAAE,MAAM,WAAAA,QAAE,OAAO,CAAC;AAAA,IACnC,CAAC;AAAA,EACH,EACC,SAAS;AAAA,EACZ,OAAO,WAAAA,QAAE,OAAO,EAAE,SAAS;AAC7B,CAAC;AAED,MAAM,uBAAuB,WAAAA,QAAE,OAAO;AAAA,EACpC,QAAQ,WAAAA,QAAE,QAAQ,QAAQ;AAAA,EAC1B,OAAO,WAAAA,QAAE,OAAO;AAAA,EAChB,WAAW,WAAAA,QAAE,OAAO;AAAA,EACpB,cAAc,WAAAA,QAAE,OAAO,EAAE,SAAS;AAAA,EAClC,MAAM,WAAAA,QAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,eAAe,WAAAA,QAAE,OAAO,EAAE,SAAS;AAAA,EACnC,cAAc,iCAAiC,SAAS;AAC1D,CAAC;AAED,MAAM,2BAA2B,WAAAA,QAAE,OAAO;AAAA,EACxC,QAAQ,WAAAA,QAAE,QAAQ,OAAO;AAAA,EACzB,SAAS,WAAAA,QAAE,OAAO;AACpB,CAAC;AAED,MAAM,uBAAuB,WAAAA,QAAE,mBAAmB,UAAU;AAAA,EAC1D;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAYM,MAAM,sBAAsB,CAAC,SAAyC;AAC3E,QAAM,SAAS,qBAAqB,UAAU,IAAI;AAClD,MAAI,CAAC,OAAO,QAAS,QAAO;AAM5B,QAAM,SAAyB,OAAO;AACtC,SAAO;AACT;AAaA,MAAM,+BAA+B,WAAAA,QAAE,OAAO;AAAA,EAC5C,MAAM,WAAAA,QAAE,OAAO,WAAAA,QAAE,OAAO,GAAG,WAAAA,QAAE,QAAQ,CAAC;AAAA,EACtC,OAAO,WAAAA,QAAE,OAAO,EAAE,MAAM,WAAAA,QAAE,OAAO,GAAG,SAAS,WAAAA,QAAE,OAAO,EAAE,CAAC;AAC3D,CAAC;AAGM,MAAM,8BAA8B,CACzC,SACkC;AAClC,QAAM,SAAS,6BAA6B,UAAU,IAAI;AAC1D,SAAO,OAAO,UAAU,OAAO,OAAO;AACxC;AA8BA,MAAM,yBAAyB,WAAAA,QAAE,OAAO;AAAA,EACtC,QAAQ,WAAAA,QAAE,OAAO;AAAA,EACjB,IAAI,WAAAA,QAAE,OAAO;AAAA,EACb,MAAM,WAAAA,QAAE,OAAO;AAAA,EACf,SAAS,WAAAA,QAAE,OAAO;AAAA,EAClB,MAAM,WAAAA,QAAE,OAAO,EAAE,SAAS;AAC5B,CAAC;AASD,MAAM,wBAAwB,WAAAA,QAAE,OAAO;AAAA,EACrC,OAAO,WAAAA,QACJ,OAAO;AAAA,IACN,MAAM,WAAAA,QAAE,OAAO,EAAE,SAAS;AAAA,IAC1B,SAAS,WAAAA,QAAE,OAAO,EAAE,SAAS;AAAA,IAC7B,MAAM,WAAAA,QAAE,OAAO,EAAE,SAAS;AAAA,IAC1B,YAAY,WAAAA,QAAE,OAAO,EAAE,SAAS;AAAA,IAChC,eAAe,WAAAA,QAAE,OAAO,EAAE,SAAS;AAAA,IACnC,mBAAmB,WAAAA,QAAE,OAAO,EAAE,SAAS;AAAA,IACvC,SAAS,WAAAA,QAAE,OAAyB,EAAE,SAAS;AAAA,IAC/C,WAAW,WAAAA,QAAE,MAAM,sBAAsB,EAAE,SAAS,EAAE,SAAS;AAAA,IAC/D,cAAc,WAAAA,QAAE,MAAM,WAAAA,QAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS;AAAA,EACxD,CAAC,EACA,SAAS;AACd,CAAC;AAGM,MAAM,uBAAuB,CAAC,SAA0C;AAC7E,QAAM,SAAS,sBAAsB,UAAU,IAAI;AACnD,SAAO,OAAO,UAAU,OAAO,OAAO;AACxC;","names":["z"]}
|
|
@@ -8,12 +8,12 @@ import { SimulationRevert, SimulateResult } from '@lifi/compose-spec';
|
|
|
8
8
|
declare const parseSimulateResult: (body: unknown) => SimulateResult | null;
|
|
9
9
|
/**
|
|
10
10
|
* The validated members of an HTTP 206 partial compile envelope. `data` is
|
|
11
|
-
* verified to be an object but
|
|
12
|
-
* (`ComposeCompilePartialData`) as a hand-authored type, so
|
|
13
|
-
* it. `error` is fully validated.
|
|
11
|
+
* verified to be an object at runtime but left `unknown` here — compose-spec
|
|
12
|
+
* owns its full shape (`ComposeCompilePartialData`) as a hand-authored type, so
|
|
13
|
+
* the caller narrows it in one step. `error` is fully validated.
|
|
14
14
|
*/
|
|
15
15
|
interface CompilePartialEnvelope {
|
|
16
|
-
readonly data:
|
|
16
|
+
readonly data: unknown;
|
|
17
17
|
readonly error: {
|
|
18
18
|
readonly kind: string;
|
|
19
19
|
readonly message: string;
|
|
@@ -39,6 +39,9 @@ interface ServerErrorBody {
|
|
|
39
39
|
readonly kind?: string;
|
|
40
40
|
readonly message?: string;
|
|
41
41
|
readonly path?: string;
|
|
42
|
+
readonly sdkVersion?: string;
|
|
43
|
+
readonly serverVersion?: string;
|
|
44
|
+
readonly minimumSdkVersion?: string;
|
|
42
45
|
readonly details?: SimulationRevert;
|
|
43
46
|
readonly failedOps?: readonly ServerFailedPreparedOp[];
|
|
44
47
|
readonly succeededOps?: readonly string[];
|
|
@@ -8,12 +8,12 @@ import { SimulationRevert, SimulateResult } from '@lifi/compose-spec';
|
|
|
8
8
|
declare const parseSimulateResult: (body: unknown) => SimulateResult | null;
|
|
9
9
|
/**
|
|
10
10
|
* The validated members of an HTTP 206 partial compile envelope. `data` is
|
|
11
|
-
* verified to be an object but
|
|
12
|
-
* (`ComposeCompilePartialData`) as a hand-authored type, so
|
|
13
|
-
* it. `error` is fully validated.
|
|
11
|
+
* verified to be an object at runtime but left `unknown` here — compose-spec
|
|
12
|
+
* owns its full shape (`ComposeCompilePartialData`) as a hand-authored type, so
|
|
13
|
+
* the caller narrows it in one step. `error` is fully validated.
|
|
14
14
|
*/
|
|
15
15
|
interface CompilePartialEnvelope {
|
|
16
|
-
readonly data:
|
|
16
|
+
readonly data: unknown;
|
|
17
17
|
readonly error: {
|
|
18
18
|
readonly kind: string;
|
|
19
19
|
readonly message: string;
|
|
@@ -39,6 +39,9 @@ interface ServerErrorBody {
|
|
|
39
39
|
readonly kind?: string;
|
|
40
40
|
readonly message?: string;
|
|
41
41
|
readonly path?: string;
|
|
42
|
+
readonly sdkVersion?: string;
|
|
43
|
+
readonly serverVersion?: string;
|
|
44
|
+
readonly minimumSdkVersion?: string;
|
|
42
45
|
readonly details?: SimulationRevert;
|
|
43
46
|
readonly failedOps?: readonly ServerFailedPreparedOp[];
|
|
44
47
|
readonly succeededOps?: readonly string[];
|
package/dist/responseSchemas.js
CHANGED
|
@@ -66,6 +66,9 @@ const serverErrorBodySchema = z.object({
|
|
|
66
66
|
kind: z.string().optional(),
|
|
67
67
|
message: z.string().optional(),
|
|
68
68
|
path: z.string().optional(),
|
|
69
|
+
sdkVersion: z.string().optional(),
|
|
70
|
+
serverVersion: z.string().optional(),
|
|
71
|
+
minimumSdkVersion: z.string().optional(),
|
|
69
72
|
details: z.custom().optional(),
|
|
70
73
|
failedOps: z.array(failedPreparedOpSchema).readonly().optional(),
|
|
71
74
|
succeededOps: z.array(z.string()).readonly().optional()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/responseSchemas.ts"],"sourcesContent":["import type { SimulateResult, SimulationRevert } from '@lifi/compose-spec';\nimport z from 'zod';\n\n/**\n * Zod-backed parsers for Compose API response bodies.\n *\n * Server responses are untrusted input crossing into the SDK, so the shapes the\n * client reads back are validated here rather than asserted with `as` casts. The\n * schemas are module-private (the package builds with `--isolatedDeclarations`,\n * which forbids exporting un-annotated complex values); the public surface is\n * the typed `parse*` helpers, whose explicit return types double as the contract.\n *\n * The simulate union is the one response the SDK fully owns and parses itself\n * (it is un-enveloped, unlike `/compose`), so it gets a complete schema kept in\n * lockstep with the canonical `SimulateResult` in `@lifi/compose-spec` by the\n * compile-time assertion below — the same anchoring `@lifi/api-schemas` uses for\n * its server-side simulate schema, so the two cannot silently drift.\n */\n\nconst balanceEntrySchema = z.object({\n token: z.string(),\n owner: z.string(),\n amount: z.string(),\n});\n\nconst simulateOkSchema = z.object({\n status: z.literal('ok'),\n block: z.number(),\n timestamp: z.number(),\n balancesBefore: z.array(balanceEntrySchema),\n balancesAfter: z.array(balanceEntrySchema),\n deltas: z.array(balanceEntrySchema),\n gasUsed: z.string(),\n});\n\nconst simulateRevertDecodeResultSchema = z.object({\n errorCandidates: z\n .array(\n z.object({\n decodedErrorSignature: z.string(),\n decodedParams: z.array(z.string()),\n }),\n )\n .optional(),\n error: z.string().optional(),\n});\n\nconst simulateRevertSchema = z.object({\n status: z.literal('revert'),\n block: z.number(),\n timestamp: z.number(),\n revertReason: z.string().optional(),\n code: z.number().optional(),\n rawErrorBytes: z.string().optional(),\n decodeResult: simulateRevertDecodeResultSchema.optional(),\n});\n\nconst simulateSetupErrorSchema = z.object({\n status: z.literal('error'),\n message: z.string(),\n});\n\nconst simulateResultSchema = z.discriminatedUnion('status', [\n simulateOkSchema,\n simulateRevertSchema,\n simulateSetupErrorSchema,\n]);\n\n// The type the schema actually parses out. Kept private (referencing it from an\n// exported declaration would break `--isolatedDeclarations`) and pinned to the\n// canonical `SimulateResult` inside `parseSimulateResult` below.\ntype SimulateResultWire = z.infer<typeof simulateResultSchema>;\n\n/**\n * Parses a `POST /simulate` body into a {@link SimulateResult}. Returns `null`\n * when the body does not match the `ok`/`revert`/`error` union, letting the\n * caller raise a transport-level error.\n */\nexport const parseSimulateResult = (body: unknown): SimulateResult | null => {\n const parsed = simulateResultSchema.safeParse(body);\n if (!parsed.success) return null;\n // Pin the schema to the canonical contract in both directions, so it cannot\n // silently drift (mirroring the conformance assertion `@lifi/api-schemas` runs\n // on its server-side simulate schema). Assigning the inferred wire value to a\n // `SimulateResult` checks wire→spec; `satisfies SimulateResultWire` checks\n // spec→wire. A missing or mistyped field on either side fails to compile.\n const result: SimulateResult = parsed.data;\n return result satisfies SimulateResultWire;\n};\n\n/**\n * The validated members of an HTTP 206 partial compile envelope. `data` is\n * verified to be an object but
|
|
1
|
+
{"version":3,"sources":["../src/responseSchemas.ts"],"sourcesContent":["import type { SimulateResult, SimulationRevert } from '@lifi/compose-spec';\nimport z from 'zod';\n\n/**\n * Zod-backed parsers for Compose API response bodies.\n *\n * Server responses are untrusted input crossing into the SDK, so the shapes the\n * client reads back are validated here rather than asserted with `as` casts. The\n * schemas are module-private (the package builds with `--isolatedDeclarations`,\n * which forbids exporting un-annotated complex values); the public surface is\n * the typed `parse*` helpers, whose explicit return types double as the contract.\n *\n * The simulate union is the one response the SDK fully owns and parses itself\n * (it is un-enveloped, unlike `/compose`), so it gets a complete schema kept in\n * lockstep with the canonical `SimulateResult` in `@lifi/compose-spec` by the\n * compile-time assertion below — the same anchoring `@lifi/api-schemas` uses for\n * its server-side simulate schema, so the two cannot silently drift.\n */\n\nconst balanceEntrySchema = z.object({\n token: z.string(),\n owner: z.string(),\n amount: z.string(),\n});\n\nconst simulateOkSchema = z.object({\n status: z.literal('ok'),\n block: z.number(),\n timestamp: z.number(),\n balancesBefore: z.array(balanceEntrySchema),\n balancesAfter: z.array(balanceEntrySchema),\n deltas: z.array(balanceEntrySchema),\n gasUsed: z.string(),\n});\n\nconst simulateRevertDecodeResultSchema = z.object({\n errorCandidates: z\n .array(\n z.object({\n decodedErrorSignature: z.string(),\n decodedParams: z.array(z.string()),\n }),\n )\n .optional(),\n error: z.string().optional(),\n});\n\nconst simulateRevertSchema = z.object({\n status: z.literal('revert'),\n block: z.number(),\n timestamp: z.number(),\n revertReason: z.string().optional(),\n code: z.number().optional(),\n rawErrorBytes: z.string().optional(),\n decodeResult: simulateRevertDecodeResultSchema.optional(),\n});\n\nconst simulateSetupErrorSchema = z.object({\n status: z.literal('error'),\n message: z.string(),\n});\n\nconst simulateResultSchema = z.discriminatedUnion('status', [\n simulateOkSchema,\n simulateRevertSchema,\n simulateSetupErrorSchema,\n]);\n\n// The type the schema actually parses out. Kept private (referencing it from an\n// exported declaration would break `--isolatedDeclarations`) and pinned to the\n// canonical `SimulateResult` inside `parseSimulateResult` below.\ntype SimulateResultWire = z.infer<typeof simulateResultSchema>;\n\n/**\n * Parses a `POST /simulate` body into a {@link SimulateResult}. Returns `null`\n * when the body does not match the `ok`/`revert`/`error` union, letting the\n * caller raise a transport-level error.\n */\nexport const parseSimulateResult = (body: unknown): SimulateResult | null => {\n const parsed = simulateResultSchema.safeParse(body);\n if (!parsed.success) return null;\n // Pin the schema to the canonical contract in both directions, so it cannot\n // silently drift (mirroring the conformance assertion `@lifi/api-schemas` runs\n // on its server-side simulate schema). Assigning the inferred wire value to a\n // `SimulateResult` checks wire→spec; `satisfies SimulateResultWire` checks\n // spec→wire. A missing or mistyped field on either side fails to compile.\n const result: SimulateResult = parsed.data;\n return result satisfies SimulateResultWire;\n};\n\n/**\n * The validated members of an HTTP 206 partial compile envelope. `data` is\n * verified to be an object at runtime but left `unknown` here — compose-spec\n * owns its full shape (`ComposeCompilePartialData`) as a hand-authored type, so\n * the caller narrows it in one step. `error` is fully validated.\n */\nexport interface CompilePartialEnvelope {\n readonly data: unknown;\n readonly error: { readonly kind: string; readonly message: string };\n}\n\nconst compilePartialEnvelopeSchema = z.object({\n data: z.record(z.string(), z.unknown()),\n error: z.object({ kind: z.string(), message: z.string() }),\n});\n\n/** Parses an HTTP 206 partial compile envelope; `null` when it does not match. */\nexport const parseCompilePartialEnvelope = (\n body: unknown,\n): CompilePartialEnvelope | null => {\n const parsed = compilePartialEnvelopeSchema.safeParse(body);\n return parsed.success ? parsed.data : null;\n};\n\n/**\n * A single prepared-op failure inside a `preparation_error` envelope. `kind` is\n * kept as `string` here — the narrowing to `GenericComposeErrorKind` happens in\n * `errorFromHttpResponse`, where the value is lifted onto `ComposeError`.\n */\nexport interface ServerFailedPreparedOp {\n readonly callId: string;\n readonly op: string;\n readonly kind: string;\n readonly message: string;\n readonly path?: string;\n}\n\n/** Error envelope returned on non-2xx responses. */\nexport interface ServerErrorBody {\n readonly error?: {\n readonly kind?: string;\n readonly message?: string;\n readonly path?: string;\n readonly sdkVersion?: string;\n readonly serverVersion?: string;\n readonly minimumSdkVersion?: string;\n readonly details?: SimulationRevert;\n readonly failedOps?: readonly ServerFailedPreparedOp[];\n readonly succeededOps?: readonly string[];\n };\n}\n\nconst failedPreparedOpSchema = z.object({\n callId: z.string(),\n op: z.string(),\n kind: z.string(),\n message: z.string(),\n path: z.string().optional(),\n});\n\n// `details` is passed through (`z.custom`) rather than parsed: the SDK does not\n// own the `SimulationRevert` schema and forwards the field verbatim onto\n// `ComposeError`.\n//\n// `failedOps`/`succeededOps` are optional here because every error kind shares\n// this envelope; they are only populated for `preparation_error` (422). Zod\n// strips undeclared keys, so omitting them would silently drop them.\nconst serverErrorBodySchema = z.object({\n error: z\n .object({\n kind: z.string().optional(),\n message: z.string().optional(),\n path: z.string().optional(),\n sdkVersion: z.string().optional(),\n serverVersion: z.string().optional(),\n minimumSdkVersion: z.string().optional(),\n details: z.custom<SimulationRevert>().optional(),\n failedOps: z.array(failedPreparedOpSchema).readonly().optional(),\n succeededOps: z.array(z.string()).readonly().optional(),\n })\n .optional(),\n});\n\n/** Validates an already-parsed error envelope; `null` when it does not match. */\nexport const parseServerErrorBody = (json: unknown): ServerErrorBody | null => {\n const parsed = serverErrorBodySchema.safeParse(json);\n return parsed.success ? parsed.data : null;\n};\n"],"mappings":"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","names":[]}
|
package/dist/types.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { LiteralBinding, Ref } from '@lifi/compose-spec';\nimport {\n InputSpec,\n MaterialiserInput,\n Resource,\n SolType,\n} from '@lifi/compose-spec';\n\n/**\n * A string that represents a non-negative integer (e.g. \"1000000000\").\n * Uses a template literal type so that only numeric-looking strings\n * are assignable at compile time.\n */\nexport type IntegerString = `${bigint}`;\n\n/**\n * Accepted input for integer-string config fields.\n * Callers may pass either a numeric string (\"1000000000\") or a native bigint\n * (1000000000n). Bigint values are stringified automatically during JSON\n * serialization via the SDK's `bigintReplacer`.\n */\nexport type IntegerStringInput = IntegerString | bigint;\n\n/**\n * A `0x`-prefixed hex string representing an Ethereum address.\n * Template literal type catches obviously wrong values at compile time.\n */\nexport type Address = `0x${string}`;\n\n/** The universe of output port kinds: Solidity scalar types plus `'resource'`. */\nexport type OutputKind = SolType | 'resource';\n\n/**\n * Maps an ABI parameter type string (from abitype's `ParseAbiItem`) to the\n * closest `OutputKind`. When the ABI type is one of the supported `SolType`\n * scalars, the mapping is exact; for all other Solidity types (e.g. tuples,\n * fixed-point decimals) it falls back to `SolType` — accepting any scalar\n * handle but not `'resource'` handles.\n *\n * The fallback excludes `'resource'` because every Solidity type is a scalar;\n * resource handles carry token-amount semantics that should only flow into\n * slots explicitly declared as resources.\n *\n * Extending `SolType` with new members automatically widens the exact-match\n * branch — no changes needed here.\n */\nexport type AbiTypeToOutputKind<T extends string> = T extends SolType\n ? T\n : SolType;\n\n/**\n * A typed `$ref` pointer carrying a phantom type parameter.\n *
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { LiteralBinding, Ref } from '@lifi/compose-spec';\nimport {\n InputSpec,\n MaterialiserInput,\n Resource,\n SolType,\n} from '@lifi/compose-spec';\n\n/**\n * A string that represents a non-negative integer (e.g. \"1000000000\").\n * Uses a template literal type so that only numeric-looking strings\n * are assignable at compile time.\n */\nexport type IntegerString = `${bigint}`;\n\n/**\n * Accepted input for integer-string config fields.\n * Callers may pass either a numeric string (\"1000000000\") or a native bigint\n * (1000000000n). Bigint values are stringified automatically during JSON\n * serialization via the SDK's `bigintReplacer`.\n */\nexport type IntegerStringInput = IntegerString | bigint;\n\n/**\n * A `0x`-prefixed hex string representing an Ethereum address.\n * Template literal type catches obviously wrong values at compile time.\n */\nexport type Address = `0x${string}`;\n\n/** The universe of output port kinds: Solidity scalar types plus `'resource'`. */\nexport type OutputKind = SolType | 'resource';\n\n/**\n * Maps an ABI parameter type string (from abitype's `ParseAbiItem`) to the\n * closest `OutputKind`. When the ABI type is one of the supported `SolType`\n * scalars, the mapping is exact; for all other Solidity types (e.g. tuples,\n * fixed-point decimals) it falls back to `SolType` — accepting any scalar\n * handle but not `'resource'` handles.\n *\n * The fallback excludes `'resource'` because every Solidity type is a scalar;\n * resource handles carry token-amount semantics that should only flow into\n * slots explicitly declared as resources.\n *\n * Extending `SolType` with new members automatically widens the exact-match\n * branch — no changes needed here.\n */\nexport type AbiTypeToOutputKind<T extends string> = T extends SolType\n ? T\n : SolType;\n\n/**\n * Phantom brand key for {@link TypedRef}.\n *\n * Declared, never assigned: it exists only so the type checker can tell a\n * typed ref from an arbitrary `{ $ref }` object. Keying it on a `unique\n * symbol` means no caller can produce one by writing an object literal.\n */\nexport declare const typedRefKind: unique symbol;\n\n/**\n * A typed `$ref` pointer carrying a phantom type parameter.\n *\n * On the wire, and at run time, this is exactly `{ $ref: string }` — the\n * brand is erased. The brand is *required* in the type so a plain `Ref` does\n * not satisfy `TypedRef` structurally, which is the contract `RefBindable`\n * advertises: an untyped `{ $ref }` never enters a typed bind slot. Build one\n * with `raw.ref<T>()`.\n */\nexport interface TypedRef<T extends OutputKind = OutputKind> extends Ref {\n readonly [typedRefKind]: T;\n}\n\n/**\n * A literal bind value carrying a phantom type parameter.\n *\n * The wire format accepts a constant in a bind slot as\n * `{ kind: <solType>, value: <string> }`, alongside `$ref` pointers. Use it\n * for a value that must be baked into the flow document rather than supplied\n * at run time — the destination of a flow the backend stores and re-runs\n * later (a `continuation.settle` node's `continuationFlow`) has no run to\n * take an input from.\n *\n * @typeParam T - The Solidity type of the literal (e.g. `'address'`).\n */\nexport interface TypedLiteral<\n T extends SolType = SolType,\n> extends LiteralBinding {\n readonly kind: T;\n readonly __outputKind?: T;\n}\n\n/**\n * An input declaration in a flow schema.\n * `Resource` values become resource inputs (token amounts);\n * `SolType` strings become handle inputs (scalars like addresses).\n */\nexport type InputDecl = Resource | SolType;\n\n/**\n * A record mapping input names to their declarations.\n * Used as the type parameter for generic flow builders and requests.\n */\nexport type InputSchema = Record<string, InputDecl>;\n\n/**\n * Maps an input declaration to the allowed runtime value type.\n * Resource inputs accept materialisers or literal amounts.\n * Handle inputs accept the scalar type matching their SolType.\n */\nexport type InputSpecOf<D> = D extends Resource\n ? MaterialiserInput | IntegerStringInput\n : D extends 'address'\n ? Address\n : D extends 'bool'\n ? boolean\n : D extends `${'u' | ''}int${string}`\n ? IntegerStringInput\n : D extends `bytes${string}`\n ? `0x${string}`\n : D extends 'string'\n ? string\n : InputSpec;\n\n/**\n * A guard applied to an operation, with the `port` field constrained\n * to a specific set of output port names.\n */\nexport interface TypedGuard<Port extends string = string> {\n readonly kind: string;\n readonly port: Port;\n readonly [key: string]: unknown;\n}\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
package/dist/types.d.cts
CHANGED
|
@@ -35,14 +35,25 @@ type OutputKind = SolType | 'resource';
|
|
|
35
35
|
* branch — no changes needed here.
|
|
36
36
|
*/
|
|
37
37
|
type AbiTypeToOutputKind<T extends string> = T extends SolType ? T : SolType;
|
|
38
|
+
/**
|
|
39
|
+
* Phantom brand key for {@link TypedRef}.
|
|
40
|
+
*
|
|
41
|
+
* Declared, never assigned: it exists only so the type checker can tell a
|
|
42
|
+
* typed ref from an arbitrary `{ $ref }` object. Keying it on a `unique
|
|
43
|
+
* symbol` means no caller can produce one by writing an object literal.
|
|
44
|
+
*/
|
|
45
|
+
declare const typedRefKind: unique symbol;
|
|
38
46
|
/**
|
|
39
47
|
* A typed `$ref` pointer carrying a phantom type parameter.
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
48
|
+
*
|
|
49
|
+
* On the wire, and at run time, this is exactly `{ $ref: string }` — the
|
|
50
|
+
* brand is erased. The brand is *required* in the type so a plain `Ref` does
|
|
51
|
+
* not satisfy `TypedRef` structurally, which is the contract `RefBindable`
|
|
52
|
+
* advertises: an untyped `{ $ref }` never enters a typed bind slot. Build one
|
|
53
|
+
* with `raw.ref<T>()`.
|
|
43
54
|
*/
|
|
44
55
|
interface TypedRef<T extends OutputKind = OutputKind> extends Ref {
|
|
45
|
-
readonly
|
|
56
|
+
readonly [typedRefKind]: T;
|
|
46
57
|
}
|
|
47
58
|
/**
|
|
48
59
|
* A literal bind value carrying a phantom type parameter.
|
|
@@ -87,4 +98,4 @@ interface TypedGuard<Port extends string = string> {
|
|
|
87
98
|
readonly [key: string]: unknown;
|
|
88
99
|
}
|
|
89
100
|
|
|
90
|
-
export type
|
|
101
|
+
export { type AbiTypeToOutputKind, type Address, type InputDecl, type InputSchema, type InputSpecOf, type IntegerString, type IntegerStringInput, type OutputKind, type TypedGuard, type TypedLiteral, type TypedRef, typedRefKind };
|
package/dist/types.d.ts
CHANGED
|
@@ -35,14 +35,25 @@ type OutputKind = SolType | 'resource';
|
|
|
35
35
|
* branch — no changes needed here.
|
|
36
36
|
*/
|
|
37
37
|
type AbiTypeToOutputKind<T extends string> = T extends SolType ? T : SolType;
|
|
38
|
+
/**
|
|
39
|
+
* Phantom brand key for {@link TypedRef}.
|
|
40
|
+
*
|
|
41
|
+
* Declared, never assigned: it exists only so the type checker can tell a
|
|
42
|
+
* typed ref from an arbitrary `{ $ref }` object. Keying it on a `unique
|
|
43
|
+
* symbol` means no caller can produce one by writing an object literal.
|
|
44
|
+
*/
|
|
45
|
+
declare const typedRefKind: unique symbol;
|
|
38
46
|
/**
|
|
39
47
|
* A typed `$ref` pointer carrying a phantom type parameter.
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
48
|
+
*
|
|
49
|
+
* On the wire, and at run time, this is exactly `{ $ref: string }` — the
|
|
50
|
+
* brand is erased. The brand is *required* in the type so a plain `Ref` does
|
|
51
|
+
* not satisfy `TypedRef` structurally, which is the contract `RefBindable`
|
|
52
|
+
* advertises: an untyped `{ $ref }` never enters a typed bind slot. Build one
|
|
53
|
+
* with `raw.ref<T>()`.
|
|
43
54
|
*/
|
|
44
55
|
interface TypedRef<T extends OutputKind = OutputKind> extends Ref {
|
|
45
|
-
readonly
|
|
56
|
+
readonly [typedRefKind]: T;
|
|
46
57
|
}
|
|
47
58
|
/**
|
|
48
59
|
* A literal bind value carrying a phantom type parameter.
|
|
@@ -87,4 +98,4 @@ interface TypedGuard<Port extends string = string> {
|
|
|
87
98
|
readonly [key: string]: unknown;
|
|
88
99
|
}
|
|
89
100
|
|
|
90
|
-
export type
|
|
101
|
+
export { type AbiTypeToOutputKind, type Address, type InputDecl, type InputSchema, type InputSpecOf, type IntegerString, type IntegerStringInput, type OutputKind, type TypedGuard, type TypedLiteral, type TypedRef, typedRefKind };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lifi/composer-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Public Composer SDK for building and submitting flows",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -34,8 +34,9 @@
|
|
|
34
34
|
"pack:local": "yarn build && mkdir -p out && yarn pack --out 'out/%s-%v.tgz'",
|
|
35
35
|
"generate": "tsx scripts/generate-sdk/index.ts",
|
|
36
36
|
"generate:staged": "tsx scripts/generate-sdk/index.ts --staged",
|
|
37
|
-
"test": "vitest run --config vitest.config.ts",
|
|
37
|
+
"test": "yarn check:types:test && vitest run --config vitest.config.ts",
|
|
38
38
|
"check:types": "tsc --noEmit",
|
|
39
|
+
"check:types:test": "tsc -p tsconfig.test.json --noEmit",
|
|
39
40
|
"check:sdk-drift": "vitest run --config vitest.drift.config.ts",
|
|
40
41
|
"fix": "yarn fix:lint",
|
|
41
42
|
"fix:lint": "eslint src --fix",
|
|
@@ -46,7 +47,7 @@
|
|
|
46
47
|
"example:staged": "tsx src/examples/run.ts --staged"
|
|
47
48
|
},
|
|
48
49
|
"peerDependencies": {
|
|
49
|
-
"@lifi/compose-spec": "0.
|
|
50
|
+
"@lifi/compose-spec": "0.6.0"
|
|
50
51
|
},
|
|
51
52
|
"dependencies": {
|
|
52
53
|
"abitype": "^1.2.3",
|
|
@@ -4,6 +4,7 @@ import type {
|
|
|
4
4
|
Call,
|
|
5
5
|
Flow,
|
|
6
6
|
FlowInput,
|
|
7
|
+
Ref,
|
|
7
8
|
Resource,
|
|
8
9
|
SolType,
|
|
9
10
|
} from '@lifi/compose-spec';
|
|
@@ -39,13 +40,21 @@ export interface CallArgs {
|
|
|
39
40
|
|
|
40
41
|
/**
|
|
41
42
|
* Any value that can be bound to an operation parameter: an input handle, an
|
|
42
|
-
* output handle from a previous operation, a typed `$ref` pointer,
|
|
43
|
-
* literal.
|
|
43
|
+
* output handle from a previous operation, a typed `$ref` pointer, a typed
|
|
44
|
+
* literal, or a bare `{ $ref }` pointer.
|
|
45
|
+
*
|
|
46
|
+
* This is the bind type of {@link FlowBuilderInternal.call}, the entry point
|
|
47
|
+
* every generated operation lowers into — not a public authoring surface. A
|
|
48
|
+
* bare `Ref` belongs here because a generated op resolves its own typed binds
|
|
49
|
+
* to wire refs (`toBindRef` in `./signatureArgs.js`) before calling it. Typed
|
|
50
|
+
* operation slots use `Bindable<T>`, which rejects a bare `Ref`; see
|
|
51
|
+
* `RefBindable` in `./handles.js`.
|
|
44
52
|
*
|
|
45
53
|
* Use `raw.ref<T>()` to create a typed ref from a raw path string, and
|
|
46
54
|
* `raw.literal<T>()` to bake in a constant.
|
|
47
55
|
*/
|
|
48
|
-
export type AnyBindable =
|
|
56
|
+
export type AnyBindable =
|
|
57
|
+
InputHandle | OutputHandle | TypedRef | TypedLiteral | Ref;
|
|
49
58
|
|
|
50
59
|
/**
|
|
51
60
|
* Provides references to runtime context values available inside a flow.
|
package/src/authoring/handles.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
BindValue,
|
|
3
|
+
Ref,
|
|
3
4
|
Resource,
|
|
4
5
|
SolType,
|
|
5
6
|
StaticSolType,
|
|
@@ -122,5 +123,5 @@ type LiteralBindable<K extends OutputKind> = K extends SolType
|
|
|
122
123
|
* `$ref` pointers, refs and literals pass through as-is.
|
|
123
124
|
*/
|
|
124
125
|
export const toBindValue = (
|
|
125
|
-
bindable: InputHandle | OutputHandle | TypedRef | TypedLiteral,
|
|
126
|
+
bindable: InputHandle | OutputHandle | TypedRef | TypedLiteral | Ref,
|
|
126
127
|
): BindValue => ('_tag' in bindable ? handleToRef(bindable) : bindable);
|
package/src/authoring/raw.ts
CHANGED
|
@@ -35,9 +35,10 @@ import type { OutputKind, TypedLiteral, TypedRef } from '../types.js';
|
|
|
35
35
|
* });
|
|
36
36
|
* ```
|
|
37
37
|
*/
|
|
38
|
-
export const ref = <T extends OutputKind>(path: string): TypedRef<T> =>
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
export const ref = <T extends OutputKind>(path: string): TypedRef<T> =>
|
|
39
|
+
// The brand is phantom, so the runtime value is the bare wire ref. This is
|
|
40
|
+
// the only place a `TypedRef` is minted; the cast is what the brand buys.
|
|
41
|
+
({ $ref: path }) as TypedRef<T>;
|
|
41
42
|
|
|
42
43
|
/**
|
|
43
44
|
* Creates a typed literal for use in bind slots: a constant baked into the
|