deepline 0.1.119 → 0.1.121
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 +4 -0
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/README.md +21 -0
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/batching.ts +185 -0
- package/dist/bundling-sources/apps/play-runner-workers/src/runtime/tool-batch.ts +107 -0
- package/dist/{repo → bundling-sources}/sdk/src/client.ts +116 -12
- package/dist/bundling-sources/sdk/src/compat.ts +191 -0
- package/dist/bundling-sources/sdk/src/gtm.ts +146 -0
- package/dist/bundling-sources/sdk/src/helpers.ts +12 -0
- package/dist/{repo → bundling-sources}/sdk/src/index.ts +2 -1
- package/dist/{repo → bundling-sources}/sdk/src/play.ts +3 -1
- package/dist/{repo → bundling-sources}/sdk/src/plays/bundle-play-file.ts +17 -5
- package/dist/{repo → bundling-sources}/sdk/src/release.ts +2 -2
- package/dist/{repo → bundling-sources}/sdk/src/runs/observe-transport.ts +2 -3
- package/dist/bundling-sources/shared_libs/play-data-plane/index.ts +3 -0
- package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +838 -0
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +5510 -0
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-contract.ts +261 -0
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +828 -0
- package/dist/bundling-sources/shared_libs/play-runtime/dataset-id.ts +10 -0
- package/dist/bundling-sources/shared_libs/play-runtime/daytona-runtime-config.ts +50 -0
- package/dist/bundling-sources/shared_libs/play-runtime/durability-store.ts +20 -0
- package/dist/bundling-sources/shared_libs/play-runtime/event-wait-tools.ts +9 -0
- package/dist/bundling-sources/shared_libs/play-runtime/governor/in-memory-rate-state-backend.ts +171 -0
- package/dist/bundling-sources/shared_libs/play-runtime/hatchet-cold-execution-diagnosis.ts +321 -0
- package/dist/bundling-sources/shared_libs/play-runtime/hatchet-cold-execution-target.ts +158 -0
- package/dist/bundling-sources/shared_libs/play-runtime/internal-step-ids.ts +34 -0
- package/dist/bundling-sources/shared_libs/play-runtime/ledger-safe-payload.ts +34 -0
- package/dist/bundling-sources/shared_libs/play-runtime/live-state-contract.ts +50 -0
- package/dist/bundling-sources/shared_libs/play-runtime/map-execution-frame.ts +119 -0
- package/dist/{repo → bundling-sources}/shared_libs/play-runtime/map-row-identity.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/play-latency-trace.ts +636 -0
- package/dist/bundling-sources/shared_libs/play-runtime/postgres-json.ts +9 -0
- package/dist/bundling-sources/shared_libs/play-runtime/progress-emitter.ts +197 -0
- package/dist/bundling-sources/shared_libs/play-runtime/projection.ts +262 -0
- package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +143 -0
- package/dist/bundling-sources/shared_libs/play-runtime/public-play-contract.ts +42 -0
- package/dist/bundling-sources/shared_libs/play-runtime/receipt-status.ts +40 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-actions.ts +178 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +4015 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-constraints.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-pg-driver-neon-serverless.ts +238 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-pg-driver-pg.ts +53 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-pg-driver.ts +149 -0
- package/dist/bundling-sources/shared_libs/play-runtime/suspension.ts +68 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-batch-executor.ts +149 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tool-result-types.ts +159 -0
- package/dist/bundling-sources/shared_libs/play-runtime/tracing.ts +33 -0
- package/dist/bundling-sources/shared_libs/play-runtime/waterfall-replay.ts +79 -0
- package/dist/bundling-sources/shared_libs/play-runtime/worker-api-types.ts +139 -0
- package/dist/bundling-sources/shared_libs/plays/artifact-transport.ts +14 -0
- package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +49 -0
- package/dist/bundling-sources/shared_libs/plays/compiler-manifest.ts +41 -0
- package/dist/bundling-sources/shared_libs/plays/dataset-summary.ts +163 -0
- package/dist/bundling-sources/shared_libs/plays/definition.ts +267 -0
- package/dist/bundling-sources/shared_libs/plays/file-refs.ts +11 -0
- package/dist/bundling-sources/shared_libs/plays/input-contract.ts +146 -0
- package/dist/bundling-sources/shared_libs/plays/resolve-static-pipeline.ts +190 -0
- package/dist/bundling-sources/shared_libs/plays/runtime-validation.ts +417 -0
- package/dist/bundling-sources/shared_libs/plays/tool-codegen.ts +142 -0
- package/dist/bundling-sources/shared_libs/security/safe-outbound-fetch.ts +274 -0
- package/dist/bundling-sources/shared_libs/temporal/preview-config.ts +150 -0
- package/dist/cli/index.js +811 -2207
- package/dist/cli/index.mjs +847 -2258
- package/dist/compiler-manifest-BjoRENv9.d.mts +227 -0
- package/dist/compiler-manifest-BjoRENv9.d.ts +227 -0
- package/dist/index.d.mts +8 -231
- package/dist/index.d.ts +8 -231
- package/dist/index.js +101 -15
- package/dist/index.mjs +101 -15
- package/dist/plays/bundle-play-file.d.mts +120 -0
- package/dist/plays/bundle-play-file.d.ts +120 -0
- package/dist/plays/bundle-play-file.mjs +1830 -0
- package/package.json +4 -9
- /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/child-play-await.ts +0 -0
- /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/child-play-submit.ts +0 -0
- /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/coordinator-entry.ts +0 -0
- /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/dedup-do.ts +0 -0
- /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/entry.ts +0 -0
- /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/runtime/csv-rows.ts +0 -0
- /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/runtime/dataset-handles.ts +0 -0
- /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/runtime/harness-receipt-store.ts +0 -0
- /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/runtime/live-progress.ts +0 -0
- /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/runtime/map-chunk-plan.ts +0 -0
- /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/runtime/receipts.ts +0 -0
- /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/runtime/row-isolation.ts +0 -0
- /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/runtime/tool-http-errors.ts +0 -0
- /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/workflow-instance-create.ts +0 -0
- /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/workflow-retry-state.ts +0 -0
- /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/workflow-retry.ts +0 -0
- /package/dist/{repo → bundling-sources}/sdk/src/agent-runtime.ts +0 -0
- /package/dist/{repo → bundling-sources}/sdk/src/config.ts +0 -0
- /package/dist/{repo → bundling-sources}/sdk/src/errors.ts +0 -0
- /package/dist/{repo → bundling-sources}/sdk/src/http.ts +0 -0
- /package/dist/{repo → bundling-sources}/sdk/src/plays/harness-stub.ts +0 -0
- /package/dist/{repo → bundling-sources}/sdk/src/plays/local-file-discovery.ts +0 -0
- /package/dist/{repo → bundling-sources}/sdk/src/stream-reconnect.ts +0 -0
- /package/dist/{repo → bundling-sources}/sdk/src/tool-output.ts +0 -0
- /package/dist/{repo → bundling-sources}/sdk/src/types.ts +0 -0
- /package/dist/{repo → bundling-sources}/sdk/src/version.ts +0 -0
- /package/dist/{repo → bundling-sources}/sdk/src/worker-play-entry.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-data-plane/cell-policy.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-data-plane/column-names.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-data-plane/sheet-contract.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/backend.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/batch-runtime.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/batching-types.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/cell-staleness.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/coordinator-headers.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/csv-rename.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/db-session-crypto.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/db-session-plan.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/db-session.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/dedup-backend.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/default-batch-strategies.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/email-status.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/execution-plan.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/extractor-targets.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/fullenrich-batching.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/governor/coordinator-rate-state-backend.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/governor/governor.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/governor/policy.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/governor/rate-state-backend.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/live-events.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/play-runtime-batching-registry.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/profiles.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/providers.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/run-failure.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/run-ledger.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/run-snapshot-stream.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/scheduler-backend.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/secret-capability.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/secret-redaction.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/step-lifecycle-tracker.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/step-program-dataset-builder.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/submit-limits.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/tool-result.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/work-receipts.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/plays/bootstrap-routes.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/plays/bundling/index.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/plays/bundling/limits.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/plays/contracts.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/plays/dataset.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/plays/row-identity.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/plays/secret-guardrails.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/plays/static-pipeline.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/security/outbound-url-policy.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/security/safe-fetch.ts +0 -0
- /package/dist/{repo → bundling-sources}/shared_libs/temporal/constants.ts +0 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { sqlSafePlayColumnName } from '@shared_libs/plays/static-pipeline';
|
|
2
|
+
import type {
|
|
3
|
+
InlineWaterfallSpec,
|
|
4
|
+
MapExecutionScope,
|
|
5
|
+
PlayExecutionEvent,
|
|
6
|
+
PlayRowUpdate,
|
|
7
|
+
} from './ctx-types';
|
|
8
|
+
|
|
9
|
+
type RowContextSnapshot = {
|
|
10
|
+
fieldName?: string;
|
|
11
|
+
mapScope?: MapExecutionScope;
|
|
12
|
+
} | null;
|
|
13
|
+
|
|
14
|
+
type CellStatus =
|
|
15
|
+
| 'queued'
|
|
16
|
+
| 'running'
|
|
17
|
+
| 'completed'
|
|
18
|
+
| 'failed'
|
|
19
|
+
| 'cached'
|
|
20
|
+
| 'missed'
|
|
21
|
+
| 'skipped';
|
|
22
|
+
|
|
23
|
+
export class PlayProgressEmitter {
|
|
24
|
+
constructor(
|
|
25
|
+
private readonly onRowUpdate:
|
|
26
|
+
| ((update: PlayRowUpdate) => void | Promise<void>)
|
|
27
|
+
| undefined,
|
|
28
|
+
private readonly onExecutionEvent:
|
|
29
|
+
| ((event: PlayExecutionEvent) => void | Promise<void>)
|
|
30
|
+
| undefined,
|
|
31
|
+
private readonly getRowContext: () => RowContextSnapshot,
|
|
32
|
+
private readonly isInlineWaterfallToolStep: (
|
|
33
|
+
step: InlineWaterfallSpec['steps'][number],
|
|
34
|
+
) => boolean,
|
|
35
|
+
) {}
|
|
36
|
+
|
|
37
|
+
executionEvent(event: PlayExecutionEvent): void {
|
|
38
|
+
if (!this.onExecutionEvent) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
void this.onExecutionEvent(event);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
rowUpdate(
|
|
45
|
+
key: string | null,
|
|
46
|
+
tableNamespace: string | null,
|
|
47
|
+
update: Omit<PlayRowUpdate, 'key'>,
|
|
48
|
+
): void {
|
|
49
|
+
const rowContext = this.getRowContext();
|
|
50
|
+
const rowScope = rowContext?.mapScope;
|
|
51
|
+
if (rowScope && key) {
|
|
52
|
+
this.executionEvent({
|
|
53
|
+
type: 'map.row.updated',
|
|
54
|
+
mapInvocationId: rowScope.mapInvocationId,
|
|
55
|
+
mapNodeId: rowScope.mapNodeId ?? null,
|
|
56
|
+
logicalNamespace: rowScope.logicalNamespace,
|
|
57
|
+
artifactTableNamespace: rowScope.artifactTableNamespace,
|
|
58
|
+
rowKey: key,
|
|
59
|
+
rowStatus: update.status,
|
|
60
|
+
fieldName: rowContext?.fieldName ?? null,
|
|
61
|
+
stage: update.stage ?? null,
|
|
62
|
+
provider: update.provider ?? null,
|
|
63
|
+
at: Date.now(),
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
if (!key || !this.onRowUpdate) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
void this.onRowUpdate({
|
|
70
|
+
...update,
|
|
71
|
+
key,
|
|
72
|
+
tableNamespace,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
fieldMetaUpdate(input: {
|
|
77
|
+
rowId: number;
|
|
78
|
+
key: string | null;
|
|
79
|
+
tableNamespace: string | null;
|
|
80
|
+
fieldName?: string | null;
|
|
81
|
+
status: CellStatus;
|
|
82
|
+
rowStatus?: PlayRowUpdate['status'];
|
|
83
|
+
stage?: string | null;
|
|
84
|
+
provider?: string | null;
|
|
85
|
+
error?: string | null;
|
|
86
|
+
reused?: boolean;
|
|
87
|
+
dataPatch?: Record<string, unknown>;
|
|
88
|
+
}): void {
|
|
89
|
+
if (!input.fieldName) {
|
|
90
|
+
this.rowUpdate(input.key, input.tableNamespace, {
|
|
91
|
+
rowId: input.rowId,
|
|
92
|
+
status: input.rowStatus,
|
|
93
|
+
stage: input.stage ?? null,
|
|
94
|
+
provider: input.provider ?? null,
|
|
95
|
+
error: input.error ?? null,
|
|
96
|
+
dataPatch: input.dataPatch ?? {},
|
|
97
|
+
});
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
this.rowUpdate(input.key, input.tableNamespace, {
|
|
102
|
+
rowId: input.rowId,
|
|
103
|
+
status: input.rowStatus,
|
|
104
|
+
stage: input.stage ?? null,
|
|
105
|
+
provider: input.provider ?? null,
|
|
106
|
+
error: input.error ?? null,
|
|
107
|
+
dataPatch: input.dataPatch ?? {},
|
|
108
|
+
cellMetaPatch: {
|
|
109
|
+
[input.fieldName]: {
|
|
110
|
+
status: input.status,
|
|
111
|
+
stage: input.stage ?? null,
|
|
112
|
+
provider: input.provider ?? null,
|
|
113
|
+
error: input.error ?? null,
|
|
114
|
+
...(input.reused !== undefined ? { reused: input.reused } : {}),
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
cellUpdate(input: {
|
|
121
|
+
rowId: number;
|
|
122
|
+
key: string | null;
|
|
123
|
+
tableNamespace: string | null;
|
|
124
|
+
columnName: string;
|
|
125
|
+
status: CellStatus;
|
|
126
|
+
rowStatus?: PlayRowUpdate['status'];
|
|
127
|
+
stage?: string | null;
|
|
128
|
+
provider?: string | null;
|
|
129
|
+
error?: string | null;
|
|
130
|
+
producer?: {
|
|
131
|
+
kind: 'play' | 'tool' | 'code';
|
|
132
|
+
id?: string | null;
|
|
133
|
+
displayName?: string | null;
|
|
134
|
+
playId?: string | null;
|
|
135
|
+
toolId?: string | null;
|
|
136
|
+
runId?: string | null;
|
|
137
|
+
} | null;
|
|
138
|
+
value?: unknown;
|
|
139
|
+
}): void {
|
|
140
|
+
this.rowUpdate(input.key, input.tableNamespace, {
|
|
141
|
+
rowId: input.rowId,
|
|
142
|
+
status: input.rowStatus,
|
|
143
|
+
stage: input.stage ?? null,
|
|
144
|
+
provider: input.provider ?? null,
|
|
145
|
+
error: input.error ?? null,
|
|
146
|
+
dataPatch:
|
|
147
|
+
input.value === undefined ? {} : { [input.columnName]: input.value },
|
|
148
|
+
cellMetaPatch: {
|
|
149
|
+
[input.columnName]: {
|
|
150
|
+
status: input.status,
|
|
151
|
+
stage: input.stage ?? null,
|
|
152
|
+
provider: input.provider ?? null,
|
|
153
|
+
error: input.error ?? null,
|
|
154
|
+
...(input.producer !== undefined ? { producer: input.producer } : {}),
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
queuedInlineWaterfallSteps(input: {
|
|
161
|
+
rowId: number;
|
|
162
|
+
key: string | null;
|
|
163
|
+
tableNamespace: string | null;
|
|
164
|
+
spec: InlineWaterfallSpec;
|
|
165
|
+
}): void {
|
|
166
|
+
for (const step of input.spec.steps) {
|
|
167
|
+
this.cellUpdate({
|
|
168
|
+
rowId: input.rowId,
|
|
169
|
+
key: input.key,
|
|
170
|
+
tableNamespace: input.tableNamespace,
|
|
171
|
+
columnName: sqlSafePlayColumnName(`${input.spec.id}.${step.id}`),
|
|
172
|
+
status: 'queued',
|
|
173
|
+
stage: step.id,
|
|
174
|
+
provider: this.isInlineWaterfallToolStep(step)
|
|
175
|
+
? (
|
|
176
|
+
step as Extract<
|
|
177
|
+
InlineWaterfallSpec['steps'][number],
|
|
178
|
+
{ toolId: string }
|
|
179
|
+
>
|
|
180
|
+
).toolId
|
|
181
|
+
: 'code',
|
|
182
|
+
producer: this.isInlineWaterfallToolStep(step)
|
|
183
|
+
? {
|
|
184
|
+
kind: 'tool',
|
|
185
|
+
toolId: (
|
|
186
|
+
step as Extract<
|
|
187
|
+
InlineWaterfallSpec['steps'][number],
|
|
188
|
+
{ toolId: string }
|
|
189
|
+
>
|
|
190
|
+
).toolId,
|
|
191
|
+
}
|
|
192
|
+
: { kind: 'code', id: step.id },
|
|
193
|
+
value: null,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
// The single extractor "projection" interpreter.
|
|
2
|
+
//
|
|
3
|
+
// "Projection" is the step that turns a provider response into the value a
|
|
4
|
+
// target (email, email_status, phone, ...) resolves to. Historically this was
|
|
5
|
+
// reimplemented in three runtimes (the V2 tool-result runtime, the playground
|
|
6
|
+
// waterfall runtime, and the emitted V1-enrich play) with divergent precedence
|
|
7
|
+
// — a latent drift bug class. This module is the one authoritative
|
|
8
|
+
// implementation: callers supply a `ProjectionLookup` that knows how to walk
|
|
9
|
+
// THEIR payload shape, and `project` applies the one fixed precedence.
|
|
10
|
+
//
|
|
11
|
+
// Leaf module: depends only on email-status.ts + extractor-targets.ts, no other
|
|
12
|
+
// runtime code, no Zod — safe inside the size-capped workers-lite bundle.
|
|
13
|
+
//
|
|
14
|
+
// See docs/extractor-projection-unification.md and CONTEXT.md ("Provider Email
|
|
15
|
+
// Status Contract").
|
|
16
|
+
|
|
17
|
+
import { buildEmailStatus } from './email-status';
|
|
18
|
+
import type { EmailStatusExtractorConfig } from './email-status';
|
|
19
|
+
import {
|
|
20
|
+
JOB_CHANGE_STATUS_VALUES,
|
|
21
|
+
type JobChangeGetterValue,
|
|
22
|
+
type JobChangeStatus,
|
|
23
|
+
} from './extractor-targets';
|
|
24
|
+
|
|
25
|
+
/** A located value (value + the concrete path it came from), or null on miss. */
|
|
26
|
+
export type ProjectionHit = { value: unknown; path: string } | null;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The only seam-crossing dependency. Each runtime supplies an adapter that
|
|
30
|
+
* resolves a list of candidate paths against its own payload shape and returns
|
|
31
|
+
* the first meaningful hit (or null). This absorbs the input-shape difference
|
|
32
|
+
* (V2 `{toolResponse:{raw}}` envelope vs playground raw payload vs the enrich
|
|
33
|
+
* play's pre-projected getters); the interpreter itself is payload-agnostic.
|
|
34
|
+
*/
|
|
35
|
+
export type ProjectionLookup = (paths: readonly string[]) => ProjectionHit;
|
|
36
|
+
|
|
37
|
+
export type ProjectionOverrideRule = {
|
|
38
|
+
paths: readonly string[];
|
|
39
|
+
equals?: string | number | boolean | null;
|
|
40
|
+
value: string | number | boolean | null;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/** The serializable descriptor shape (a structural subset of
|
|
44
|
+
* ToolResultExtractorDescriptor — descriptors stay plain JSON on the wire). */
|
|
45
|
+
export type ProjectionDescriptor = {
|
|
46
|
+
paths: readonly string[];
|
|
47
|
+
transforms?: readonly string[];
|
|
48
|
+
enum?: readonly string[];
|
|
49
|
+
overrides?: readonly ProjectionOverrideRule[];
|
|
50
|
+
emailStatus?: EmailStatusExtractorConfig;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// --- small value helpers (kept local so this module stays a dependency-free leaf) ---
|
|
54
|
+
|
|
55
|
+
function normalizeString(value: unknown): string | null {
|
|
56
|
+
if (typeof value === 'string') {
|
|
57
|
+
const trimmed = value.trim();
|
|
58
|
+
return trimmed ? trimmed : null;
|
|
59
|
+
}
|
|
60
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
61
|
+
return String(value);
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
67
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// --- typed-signal coercions (one home for every status normalizer) ---
|
|
71
|
+
|
|
72
|
+
function normalizePhoneStatus(value: unknown): unknown {
|
|
73
|
+
if (typeof value === 'boolean') return value ? 'valid' : 'invalid';
|
|
74
|
+
const normalized = normalizeString(value)
|
|
75
|
+
?.toLowerCase()
|
|
76
|
+
.replace(/[\s-]+/g, '_');
|
|
77
|
+
if (!normalized) return 'unknown';
|
|
78
|
+
if (['verified', 'ok', 'true', 'active'].includes(normalized)) return 'valid';
|
|
79
|
+
if (
|
|
80
|
+
['bad', 'false', 'failed', 'inactive', 'disconnected'].includes(normalized)
|
|
81
|
+
) {
|
|
82
|
+
return 'invalid';
|
|
83
|
+
}
|
|
84
|
+
return normalized;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function normalizeJobChangeStatus(value: unknown): unknown {
|
|
88
|
+
if (typeof value === 'boolean') return value ? 'moved' : 'no_change';
|
|
89
|
+
const normalized = normalizeString(value)
|
|
90
|
+
?.toLowerCase()
|
|
91
|
+
.replace(/[\s-]+/g, '_');
|
|
92
|
+
if (!normalized) return 'unknown';
|
|
93
|
+
if (['true', 'yes', 'moved', 'changed', 'new_company'].includes(normalized)) {
|
|
94
|
+
return 'moved';
|
|
95
|
+
}
|
|
96
|
+
if (['false', 'no', 'same', 'no_change'].includes(normalized))
|
|
97
|
+
return 'no_change';
|
|
98
|
+
if (['left', 'left_company'].includes(normalized)) return 'left_company';
|
|
99
|
+
if ((JOB_CHANGE_STATUS_VALUES as readonly string[]).includes(normalized)) {
|
|
100
|
+
return normalized;
|
|
101
|
+
}
|
|
102
|
+
return 'unknown';
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function firstExperienceDate(value: unknown): string | null {
|
|
106
|
+
if (!Array.isArray(value)) return null;
|
|
107
|
+
for (const entry of value) {
|
|
108
|
+
if (!isRecord(entry)) continue;
|
|
109
|
+
const date = normalizeString(
|
|
110
|
+
entry.start_date ?? entry.started_at ?? entry.startDate,
|
|
111
|
+
);
|
|
112
|
+
if (date) return date;
|
|
113
|
+
}
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function normalizeJobChange(value: unknown): JobChangeGetterValue {
|
|
118
|
+
const record = isRecord(value) ? value : {};
|
|
119
|
+
const nested = isRecord(record.job_change) ? record.job_change : record;
|
|
120
|
+
const output = isRecord(nested.output) ? nested.output : nested;
|
|
121
|
+
const person = isRecord(output.person) ? output.person : {};
|
|
122
|
+
const status = normalizeJobChangeStatus(
|
|
123
|
+
output.status ??
|
|
124
|
+
output.job_change_status ??
|
|
125
|
+
output.job_changed ??
|
|
126
|
+
output.changed,
|
|
127
|
+
) as JobChangeStatus;
|
|
128
|
+
const moved = status === 'moved';
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
status,
|
|
132
|
+
date: moved
|
|
133
|
+
? normalizeString(
|
|
134
|
+
output.date ??
|
|
135
|
+
output.job_change_date ??
|
|
136
|
+
output.change_date ??
|
|
137
|
+
output.changed_at,
|
|
138
|
+
) ?? firstExperienceDate(person.experiences)
|
|
139
|
+
: null,
|
|
140
|
+
new_company: moved
|
|
141
|
+
? normalizeString(
|
|
142
|
+
output.new_company ??
|
|
143
|
+
output.current_company ??
|
|
144
|
+
person.company_name ??
|
|
145
|
+
person.current_company,
|
|
146
|
+
)
|
|
147
|
+
: null,
|
|
148
|
+
new_title: moved
|
|
149
|
+
? normalizeString(
|
|
150
|
+
output.new_title ??
|
|
151
|
+
output.current_title ??
|
|
152
|
+
person.title ??
|
|
153
|
+
person.headline,
|
|
154
|
+
)
|
|
155
|
+
: null,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function applyTransforms(
|
|
160
|
+
value: unknown,
|
|
161
|
+
transforms: readonly string[] | undefined,
|
|
162
|
+
): unknown {
|
|
163
|
+
return (transforms ?? []).reduce((current, transform) => {
|
|
164
|
+
// email_status is materialized by emailStatus (the Provider Email Status
|
|
165
|
+
// Contract), never by a string transform — so an `emailStatus` transform is
|
|
166
|
+
// a no-op and falls through to `return current`.
|
|
167
|
+
if (transform.endsWith('phoneStatus')) return normalizePhoneStatus(current);
|
|
168
|
+
if (transform === 'jobChange') return normalizeJobChange(current);
|
|
169
|
+
if (transform === 'jobChangeStatus')
|
|
170
|
+
return normalizeJobChangeStatus(current);
|
|
171
|
+
return current;
|
|
172
|
+
}, value);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function coerceToEnum(
|
|
176
|
+
value: unknown,
|
|
177
|
+
enumValues: readonly string[] | undefined,
|
|
178
|
+
): unknown {
|
|
179
|
+
if (!enumValues?.length) return value;
|
|
180
|
+
const normalized = normalizeString(value);
|
|
181
|
+
if (!normalized) return value;
|
|
182
|
+
return enumValues.includes(normalized) ? normalized : value;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function findOverride(
|
|
186
|
+
overrides: readonly ProjectionOverrideRule[] | undefined,
|
|
187
|
+
lookup: ProjectionLookup,
|
|
188
|
+
): { value: string | number | boolean | null } | null {
|
|
189
|
+
for (const override of overrides ?? []) {
|
|
190
|
+
const expected = Object.prototype.hasOwnProperty.call(override, 'equals')
|
|
191
|
+
? override.equals
|
|
192
|
+
: true;
|
|
193
|
+
for (const path of override.paths) {
|
|
194
|
+
const match = lookup([path]);
|
|
195
|
+
if (!match) continue;
|
|
196
|
+
if (match.value === expected) return { value: override.value };
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function projectEmailStatus(
|
|
203
|
+
config: EmailStatusExtractorConfig,
|
|
204
|
+
lookup: ProjectionLookup,
|
|
205
|
+
): ProjectionHit {
|
|
206
|
+
const values: Record<string, unknown> = {};
|
|
207
|
+
const pathSets: Record<string, readonly string[] | undefined> = {
|
|
208
|
+
rawStatus: config.rawStatus,
|
|
209
|
+
rawScore: config.rawScore,
|
|
210
|
+
valid: config.valid,
|
|
211
|
+
deliverability: config.deliverability,
|
|
212
|
+
catchAll: config.catchAll,
|
|
213
|
+
mxProvider: config.mxProvider,
|
|
214
|
+
mxRecord: config.mxRecord,
|
|
215
|
+
fraudScore: config.fraudScore,
|
|
216
|
+
disposable: config.disposable,
|
|
217
|
+
roleBased: config.roleBased,
|
|
218
|
+
freeEmail: config.freeEmail,
|
|
219
|
+
abuse: config.abuse,
|
|
220
|
+
spamtrap: config.spamtrap,
|
|
221
|
+
suspect: config.suspect,
|
|
222
|
+
};
|
|
223
|
+
let firstPath: string | null = null;
|
|
224
|
+
for (const [name, paths] of Object.entries(pathSets)) {
|
|
225
|
+
if (!paths) continue;
|
|
226
|
+
const match = lookup(paths);
|
|
227
|
+
if (!match) continue;
|
|
228
|
+
values[name] = match.value;
|
|
229
|
+
firstPath ??= match.path;
|
|
230
|
+
}
|
|
231
|
+
if (!firstPath) return null;
|
|
232
|
+
return { path: firstPath, value: buildEmailStatus({ config, values }) };
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Project one extractor descriptor against a payload (via `lookup`).
|
|
237
|
+
*
|
|
238
|
+
* Fixed precedence (identical for every runtime):
|
|
239
|
+
* 1. emailStatus → buildEmailStatus(...) (terminal; never transformed/enum'd)
|
|
240
|
+
* 2. paths → first meaningful hit
|
|
241
|
+
* 3. transforms → phoneStatus | jobChange | jobChangeStatus
|
|
242
|
+
* 4. enum → keep value if not in the set
|
|
243
|
+
* 5. overrides → a matching override wins over the resolved value
|
|
244
|
+
*
|
|
245
|
+
* Returns null when nothing meaningful resolves (caller omits the target).
|
|
246
|
+
*/
|
|
247
|
+
export function project(
|
|
248
|
+
descriptor: ProjectionDescriptor,
|
|
249
|
+
lookup: ProjectionLookup,
|
|
250
|
+
): ProjectionHit {
|
|
251
|
+
if (descriptor.emailStatus) {
|
|
252
|
+
return projectEmailStatus(descriptor.emailStatus, lookup);
|
|
253
|
+
}
|
|
254
|
+
const base = lookup(descriptor.paths);
|
|
255
|
+
if (!base) return null;
|
|
256
|
+
const transformed = coerceToEnum(
|
|
257
|
+
applyTransforms(base.value, descriptor.transforms),
|
|
258
|
+
descriptor.enum,
|
|
259
|
+
);
|
|
260
|
+
const override = findOverride(descriptor.overrides, lookup);
|
|
261
|
+
return { path: base.path, value: override?.value ?? transformed };
|
|
262
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import type { PlayBundleArtifact } from '../plays/artifact-types';
|
|
2
|
+
import type {
|
|
3
|
+
PlayCheckpoint,
|
|
4
|
+
PlayExecutionEvent,
|
|
5
|
+
PlayRowUpdate,
|
|
6
|
+
PlayStep,
|
|
7
|
+
} from './ctx-types';
|
|
8
|
+
import type { PlayExecutionSuspension } from './suspension';
|
|
9
|
+
import type { PlayStaticPipeline } from '../plays/static-pipeline';
|
|
10
|
+
import type { PlayLiveEventSource } from './live-events';
|
|
11
|
+
import type { PreloadedRuntimeDbSession } from './db-session';
|
|
12
|
+
|
|
13
|
+
export interface PlayRunnerContextConfig {
|
|
14
|
+
executorToken?: string;
|
|
15
|
+
baseUrl?: string;
|
|
16
|
+
vercelProtectionBypassToken?: string | null;
|
|
17
|
+
orgId?: string;
|
|
18
|
+
workflowId?: string;
|
|
19
|
+
playId?: string;
|
|
20
|
+
runId?: string;
|
|
21
|
+
playName?: string;
|
|
22
|
+
userEmail?: string;
|
|
23
|
+
convexUrl?: string;
|
|
24
|
+
staticPipeline?: PlayStaticPipeline | null;
|
|
25
|
+
/**
|
|
26
|
+
* Controls how scoped Postgres sessions enter the runner. `preloaded` means
|
|
27
|
+
* the launch config carries short-lived encrypted sessions minted before
|
|
28
|
+
* dispatch; `sandbox_public_key` means the runner mints missing sessions
|
|
29
|
+
* through the app runtime API with a per-request public key.
|
|
30
|
+
*/
|
|
31
|
+
dbSessionStrategy?: 'preloaded' | 'sandbox_public_key';
|
|
32
|
+
/**
|
|
33
|
+
* Short-lived scoped Postgres sessions minted by the worker before the runner
|
|
34
|
+
* starts. They are only an initial fast path: the runner still renews through
|
|
35
|
+
* the app runtime API when a session is absent, too close to expiry, or not an
|
|
36
|
+
* exact-enough match for the requested play/table/operation scope.
|
|
37
|
+
*/
|
|
38
|
+
preloadedDbSessions?: PreloadedRuntimeDbSession[];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface PlayRunnerExecutionConfig {
|
|
42
|
+
artifact: PlayBundleArtifact;
|
|
43
|
+
artifactTransport?: {
|
|
44
|
+
bundledCodePath?: string | null;
|
|
45
|
+
bundledCodeEncoding?: 'utf8' | 'gzip';
|
|
46
|
+
} | null;
|
|
47
|
+
input: Record<string, unknown>;
|
|
48
|
+
checkpoint?: PlayCheckpoint | null;
|
|
49
|
+
csvSourcePath?: string | null;
|
|
50
|
+
csvSourceUrl?: string | null;
|
|
51
|
+
csvSourceContentBase64?: string | null;
|
|
52
|
+
runtimeInputAlias?: string | null;
|
|
53
|
+
materializedFiles: Record<string, string>;
|
|
54
|
+
workspaceRoot: string;
|
|
55
|
+
context: PlayRunnerContextConfig;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export type PlayRunnerLogEvent = {
|
|
59
|
+
type: 'log';
|
|
60
|
+
at: string;
|
|
61
|
+
source: PlayLiveEventSource;
|
|
62
|
+
line: string;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export type PlayRunnerEvent =
|
|
66
|
+
| PlayRunnerLogEvent
|
|
67
|
+
| {
|
|
68
|
+
type: 'checkpoint';
|
|
69
|
+
checkpoint: PlayCheckpoint;
|
|
70
|
+
}
|
|
71
|
+
| {
|
|
72
|
+
type: 'row_update';
|
|
73
|
+
update: PlayRowUpdate;
|
|
74
|
+
}
|
|
75
|
+
| {
|
|
76
|
+
type: 'execution_event';
|
|
77
|
+
event: PlayExecutionEvent;
|
|
78
|
+
}
|
|
79
|
+
| {
|
|
80
|
+
type: 'result';
|
|
81
|
+
result: PlayRunnerResult;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export type PlayRunnerDeferredRuntimeTask = {
|
|
85
|
+
kind: 'daytona_sandbox_cleanup';
|
|
86
|
+
sandboxId: string;
|
|
87
|
+
billingStartedAt: number;
|
|
88
|
+
cpu: number;
|
|
89
|
+
memoryGiB: number;
|
|
90
|
+
diskGiB: number;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export type PlayRunnerRuntimeTiming = {
|
|
94
|
+
backend: 'daytona';
|
|
95
|
+
daytonaCreateMs?: number;
|
|
96
|
+
daytonaUploadMs?: number;
|
|
97
|
+
daytonaExecuteMs?: number;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export type PlayRunnerResult =
|
|
101
|
+
| {
|
|
102
|
+
status: 'completed';
|
|
103
|
+
output: unknown;
|
|
104
|
+
outputRowCount?: number;
|
|
105
|
+
logs: string[];
|
|
106
|
+
stats: Record<string, unknown>;
|
|
107
|
+
steps: PlayStep[];
|
|
108
|
+
checkpoint: PlayCheckpoint;
|
|
109
|
+
tableNamespace?: string | null;
|
|
110
|
+
totalRows?: number;
|
|
111
|
+
inserted?: number;
|
|
112
|
+
skipped?: number;
|
|
113
|
+
runtimeTiming?: PlayRunnerRuntimeTiming;
|
|
114
|
+
deferredRuntimeTasks?: PlayRunnerDeferredRuntimeTask[];
|
|
115
|
+
}
|
|
116
|
+
| {
|
|
117
|
+
status: 'suspended';
|
|
118
|
+
suspension: PlayExecutionSuspension;
|
|
119
|
+
logs: string[];
|
|
120
|
+
stats: Record<string, unknown>;
|
|
121
|
+
steps: PlayStep[];
|
|
122
|
+
checkpoint: PlayCheckpoint;
|
|
123
|
+
tableNamespace?: string | null;
|
|
124
|
+
totalRows?: number;
|
|
125
|
+
inserted?: number;
|
|
126
|
+
skipped?: number;
|
|
127
|
+
runtimeTiming?: PlayRunnerRuntimeTiming;
|
|
128
|
+
deferredRuntimeTasks?: PlayRunnerDeferredRuntimeTask[];
|
|
129
|
+
}
|
|
130
|
+
| {
|
|
131
|
+
status: 'failed';
|
|
132
|
+
error: string;
|
|
133
|
+
logs: string[];
|
|
134
|
+
stats: Record<string, unknown>;
|
|
135
|
+
steps: PlayStep[];
|
|
136
|
+
checkpoint?: PlayCheckpoint | null;
|
|
137
|
+
tableNamespace?: string | null;
|
|
138
|
+
totalRows?: number;
|
|
139
|
+
inserted?: number;
|
|
140
|
+
skipped?: number;
|
|
141
|
+
runtimeTiming?: PlayRunnerRuntimeTiming;
|
|
142
|
+
deferredRuntimeTasks?: PlayRunnerDeferredRuntimeTask[];
|
|
143
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export type PublicPlayRunStatus =
|
|
2
|
+
| 'queued'
|
|
3
|
+
| 'running'
|
|
4
|
+
| 'waiting'
|
|
5
|
+
| 'completed'
|
|
6
|
+
| 'failed'
|
|
7
|
+
| 'cancelled';
|
|
8
|
+
|
|
9
|
+
export interface PublicPlayRunResult {
|
|
10
|
+
success: boolean;
|
|
11
|
+
runId: string;
|
|
12
|
+
result?: unknown;
|
|
13
|
+
logs: string[];
|
|
14
|
+
durationMs: number;
|
|
15
|
+
error?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface PublicPlayProgressStatus {
|
|
19
|
+
status: string;
|
|
20
|
+
totalRows?: number;
|
|
21
|
+
logs: string[];
|
|
22
|
+
error?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface PublicPlayWaitState {
|
|
26
|
+
kind: 'integration_event' | 'sleep';
|
|
27
|
+
boundaryId?: string;
|
|
28
|
+
eventKey?: string;
|
|
29
|
+
until?: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface PublicPlayStatus {
|
|
33
|
+
runId: string;
|
|
34
|
+
apiVersion?: number;
|
|
35
|
+
status: PublicPlayRunStatus;
|
|
36
|
+
error?: string;
|
|
37
|
+
progress?: PublicPlayProgressStatus;
|
|
38
|
+
result?: unknown;
|
|
39
|
+
resultView?: unknown;
|
|
40
|
+
contract?: Record<string, unknown> | null;
|
|
41
|
+
wait?: PublicPlayWaitState | null;
|
|
42
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { WorkReceiptStatus } from './work-receipts';
|
|
2
|
+
|
|
3
|
+
export const RECEIPT_STATUS_CODE = {
|
|
4
|
+
pending: 0,
|
|
5
|
+
running: 1,
|
|
6
|
+
completed: 2,
|
|
7
|
+
failed: 3,
|
|
8
|
+
skipped: 4,
|
|
9
|
+
} as const satisfies Record<WorkReceiptStatus, number>;
|
|
10
|
+
|
|
11
|
+
export type ReceiptStatusCode =
|
|
12
|
+
(typeof RECEIPT_STATUS_CODE)[keyof typeof RECEIPT_STATUS_CODE];
|
|
13
|
+
|
|
14
|
+
export function receiptStatusFromCode(value: unknown): WorkReceiptStatus {
|
|
15
|
+
switch (Number(value ?? RECEIPT_STATUS_CODE.pending)) {
|
|
16
|
+
case RECEIPT_STATUS_CODE.running:
|
|
17
|
+
return 'running';
|
|
18
|
+
case RECEIPT_STATUS_CODE.completed:
|
|
19
|
+
return 'completed';
|
|
20
|
+
case RECEIPT_STATUS_CODE.failed:
|
|
21
|
+
return 'failed';
|
|
22
|
+
case RECEIPT_STATUS_CODE.skipped:
|
|
23
|
+
return 'skipped';
|
|
24
|
+
case RECEIPT_STATUS_CODE.pending:
|
|
25
|
+
default:
|
|
26
|
+
return 'pending';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function receiptCodeFromStatus(
|
|
31
|
+
status: WorkReceiptStatus,
|
|
32
|
+
): ReceiptStatusCode {
|
|
33
|
+
return RECEIPT_STATUS_CODE[status];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function receiptStatusCodeFromUnknown(
|
|
37
|
+
value: unknown,
|
|
38
|
+
): ReceiptStatusCode {
|
|
39
|
+
return receiptCodeFromStatus(receiptStatusFromCode(value));
|
|
40
|
+
}
|