deepline 0.2.47 → 0.2.49
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/dist/bundling-sources/sdk/src/client.ts +15 -3
- package/dist/bundling-sources/sdk/src/play.ts +15 -1
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +13 -0
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +5 -0
- package/dist/bundling-sources/shared_libs/play-runtime/durable-call-cache.ts +6 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/types.ts +1 -0
- package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +89 -1
- package/dist/cli/index.js +141 -11
- package/dist/cli/index.mjs +141 -11
- package/dist/{compiler-manifest-CGZadg-v.d.mts → compiler-manifest-BPA3r-VG.d.mts} +84 -0
- package/dist/{compiler-manifest-CGZadg-v.d.ts → compiler-manifest-BPA3r-VG.d.ts} +84 -0
- package/dist/index.d.mts +27 -6
- package/dist/index.d.ts +27 -6
- package/dist/index.js +10 -4
- package/dist/index.mjs +10 -4
- package/dist/install-integrity.json +2 -2
- package/dist/plays/bundle-play-file.d.mts +2 -2
- package/dist/plays/bundle-play-file.d.ts +2 -2
- package/dist/plays/bundle-play-file.mjs +71 -1
- package/dist/viewer/viewer.css +15 -0
- package/dist/viewer/viewer.js +35 -1
- package/package.json +1 -1
|
@@ -818,10 +818,14 @@ export type MonitorsNamespace = {
|
|
|
818
818
|
list: (options?: MonitorsListOptions) => Promise<MonitorsListResult>;
|
|
819
819
|
/** Fetch one deployed monitor by public key (without dependents). */
|
|
820
820
|
get: (key: string) => Promise<MonitorDetail>;
|
|
821
|
-
/**
|
|
821
|
+
/**
|
|
822
|
+
* Test a deployed monitor. `validationOnly` safely verifies the callback
|
|
823
|
+
* envelope; omitted options preserve the historic full-ingestion behavior.
|
|
824
|
+
*/
|
|
822
825
|
test: (
|
|
823
826
|
key: string,
|
|
824
827
|
payload: Record<string, unknown>,
|
|
828
|
+
options?: { validationOnly?: boolean },
|
|
825
829
|
) => Promise<MonitorTestResult>;
|
|
826
830
|
validate: (key: string) => Promise<MonitorValidateResult>;
|
|
827
831
|
/** List the published plays depending on one monitor's output streams. */
|
|
@@ -1634,7 +1638,8 @@ export class DeeplineClient {
|
|
|
1634
1638
|
deploy: (definition, options) => this.deployMonitor(definition, options),
|
|
1635
1639
|
list: (options) => this.listMonitors(options),
|
|
1636
1640
|
get: (key) => this.getMonitor(key),
|
|
1637
|
-
test: (key, payload) =>
|
|
1641
|
+
test: (key, payload, options) =>
|
|
1642
|
+
this.testMonitorWebhook(key, payload, options),
|
|
1638
1643
|
validate: (key) => this.validateMonitor(key),
|
|
1639
1644
|
dependents: (key) => this.getMonitorDependents(key),
|
|
1640
1645
|
update: (key, patch) => this.updateMonitor(key, patch),
|
|
@@ -4547,10 +4552,17 @@ export class DeeplineClient {
|
|
|
4547
4552
|
async testMonitorWebhook(
|
|
4548
4553
|
key: string,
|
|
4549
4554
|
payload: Record<string, unknown>,
|
|
4555
|
+
options?: { validationOnly?: boolean },
|
|
4550
4556
|
): Promise<MonitorTestResult> {
|
|
4551
4557
|
return this.http.request<MonitorTestResult>(
|
|
4552
4558
|
`/api/v2/monitors/deployed/${encodeURIComponent(key)}/test`,
|
|
4553
|
-
{
|
|
4559
|
+
{
|
|
4560
|
+
method: 'POST',
|
|
4561
|
+
body: {
|
|
4562
|
+
payload,
|
|
4563
|
+
...(options?.validationOnly ? { mode: 'validation_only' } : {}),
|
|
4564
|
+
},
|
|
4565
|
+
},
|
|
4554
4566
|
);
|
|
4555
4567
|
}
|
|
4556
4568
|
|
|
@@ -176,7 +176,8 @@ export type PlayFetchResponse = PlayAuthoringFetchResponse;
|
|
|
176
176
|
*
|
|
177
177
|
* A play can be triggered three ways, declared as the third argument to
|
|
178
178
|
* {@link definePlay}:
|
|
179
|
-
* - `webhook` — an inbound HTTP call (with optional HMAC
|
|
179
|
+
* - `webhook` — an inbound HTTP call (with optional legacy HMAC or Standard
|
|
180
|
+
* Webhooks signature verification);
|
|
180
181
|
* - `cron` — a schedule; or
|
|
181
182
|
* - `sqlListeners` — a **monitor**: the play runs whenever a monitor writes a new
|
|
182
183
|
* row to its output stream. This is how you build a play "on top of" a monitor
|
|
@@ -198,6 +199,19 @@ export type PlayFetchResponse = PlayAuthoringFetchResponse;
|
|
|
198
199
|
* });
|
|
199
200
|
* ```
|
|
200
201
|
*
|
|
202
|
+
* @example Svix / Standard Webhooks verification with Deepline Secrets
|
|
203
|
+
* ```typescript
|
|
204
|
+
* definePlay('visitor-webhook', handler, {
|
|
205
|
+
* webhook: {
|
|
206
|
+
* auth: {
|
|
207
|
+
* type: 'standard-webhooks',
|
|
208
|
+
* headerFamily: 'svix',
|
|
209
|
+
* signingSecrets: ['VECTOR_WEBHOOK_SECRET'],
|
|
210
|
+
* },
|
|
211
|
+
* },
|
|
212
|
+
* });
|
|
213
|
+
* ```
|
|
214
|
+
*
|
|
201
215
|
* @example Cron schedule
|
|
202
216
|
* ```typescript
|
|
203
217
|
* definePlay('nightly-sync', handler, {
|
|
@@ -160,7 +160,7 @@ export const SDK_RELEASE = {
|
|
|
160
160
|
// 0.2.0 makes Dataset Handles uniformly async-only after 0.1.320 briefly
|
|
161
161
|
// exposed storage-dependent synchronous access. This deliberate minor
|
|
162
162
|
// release keeps lazy paging semantics independent of row residency.
|
|
163
|
-
version: '0.2.
|
|
163
|
+
version: '0.2.49',
|
|
164
164
|
contracts: {
|
|
165
165
|
api: {
|
|
166
166
|
name: 'sdk-http-api',
|
|
@@ -1102,6 +1102,7 @@ function durableCtxKey(input: {
|
|
|
1102
1102
|
id: string;
|
|
1103
1103
|
semanticKey?: string | null;
|
|
1104
1104
|
staleAfterSeconds?: number | null;
|
|
1105
|
+
cacheEpochMs?: number;
|
|
1105
1106
|
}): string {
|
|
1106
1107
|
if (input.operation === 'tool') {
|
|
1107
1108
|
throw new Error('Tool calls use tool receipt keys.');
|
|
@@ -1113,6 +1114,7 @@ function durableCtxKey(input: {
|
|
|
1113
1114
|
id: input.id,
|
|
1114
1115
|
semanticKey: input.semanticKey,
|
|
1115
1116
|
staleAfterSeconds: input.staleAfterSeconds,
|
|
1117
|
+
cacheEpochMs: input.cacheEpochMs,
|
|
1116
1118
|
});
|
|
1117
1119
|
}
|
|
1118
1120
|
|
|
@@ -1391,6 +1393,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
1391
1393
|
private fixtureProviderPacingBypassLogged = false;
|
|
1392
1394
|
private fixtureProviderPacingEnforcementLogged = false;
|
|
1393
1395
|
private checkpoint: PlayCheckpoint;
|
|
1396
|
+
private readonly durableCallCacheEpochMs: number;
|
|
1394
1397
|
/**
|
|
1395
1398
|
* Durable tool receipts are the replay/cache authority for the execution
|
|
1396
1399
|
* paths the host supports. Keeping the same completed result in this
|
|
@@ -1664,6 +1667,14 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
1664
1667
|
};
|
|
1665
1668
|
this.#options = options;
|
|
1666
1669
|
this.checkpoint = options.checkpoint ?? emptyCheckpoint();
|
|
1670
|
+
const checkpointCacheEpochMs = this.checkpoint.durableCallCacheEpochMs;
|
|
1671
|
+
this.durableCallCacheEpochMs =
|
|
1672
|
+
typeof checkpointCacheEpochMs === 'number' &&
|
|
1673
|
+
Number.isFinite(checkpointCacheEpochMs) &&
|
|
1674
|
+
checkpointCacheEpochMs >= 0
|
|
1675
|
+
? checkpointCacheEpochMs
|
|
1676
|
+
: Date.now();
|
|
1677
|
+
this.checkpoint.durableCallCacheEpochMs = this.durableCallCacheEpochMs;
|
|
1667
1678
|
this.durableMappedToolResultsBackedByReceipts = Boolean(
|
|
1668
1679
|
(options.claimRuntimeStepReceipt || options.claimRuntimeStepReceipts) &&
|
|
1669
1680
|
(options.getRuntimeStepReceipt || options.getRuntimeStepReceipts) &&
|
|
@@ -3104,6 +3115,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
3104
3115
|
}),
|
|
3105
3116
|
providerActionVersion,
|
|
3106
3117
|
staleAfterSeconds: input.staleAfterSeconds,
|
|
3118
|
+
cacheEpochMs: this.durableCallCacheEpochMs,
|
|
3107
3119
|
});
|
|
3108
3120
|
}
|
|
3109
3121
|
|
|
@@ -3286,6 +3298,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
3286
3298
|
id,
|
|
3287
3299
|
semanticKey: opts.semanticKey,
|
|
3288
3300
|
staleAfterSeconds: stalePolicy.staleAfterSeconds,
|
|
3301
|
+
cacheEpochMs: this.durableCallCacheEpochMs,
|
|
3289
3302
|
});
|
|
3290
3303
|
return await executeWithDurableRuntimeReceipt<T>({
|
|
3291
3304
|
operation,
|
|
@@ -779,6 +779,11 @@ export interface ContextOptions {
|
|
|
779
779
|
}
|
|
780
780
|
|
|
781
781
|
export interface PlayCheckpoint {
|
|
782
|
+
/**
|
|
783
|
+
* Clock captured when this logical run first creates its context. All
|
|
784
|
+
* staleAfterSeconds receipt buckets use this value across durable resumes.
|
|
785
|
+
*/
|
|
786
|
+
durableCallCacheEpochMs?: number;
|
|
782
787
|
/** Waterfall batches that have completed: key = `${toolName}:${provider}`, value = results array. */
|
|
783
788
|
completedBatches: Record<string, BatchResult[]>;
|
|
784
789
|
/** Tool call batches that have completed: key = toolId, value = sparse row-cache-key -> result map. */
|
|
@@ -42,6 +42,8 @@ export function buildDurableToolCallCacheKey(input: {
|
|
|
42
42
|
providerActionVersion?: string | null;
|
|
43
43
|
cachePolicyVersion?: string | null;
|
|
44
44
|
staleAfterSeconds?: number | null;
|
|
45
|
+
/** Run-stable clock used to choose the stale bucket. */
|
|
46
|
+
cacheEpochMs?: number;
|
|
45
47
|
playLocalScope?: string | null;
|
|
46
48
|
}): string {
|
|
47
49
|
const orgId = input.orgId?.trim() || 'org';
|
|
@@ -70,6 +72,7 @@ export function buildDurableToolCallCacheKey(input: {
|
|
|
70
72
|
input.cachePolicyVersion ?? DURABLE_CALL_CACHE_POLICY_VERSION,
|
|
71
73
|
staleBucket: durableCacheStaleBucket({
|
|
72
74
|
staleAfterSeconds: input.staleAfterSeconds,
|
|
75
|
+
nowMs: input.cacheEpochMs,
|
|
73
76
|
}),
|
|
74
77
|
}),
|
|
75
78
|
);
|
|
@@ -84,6 +87,8 @@ export function buildDurableCtxCallCacheKey(input: {
|
|
|
84
87
|
semanticKey?: string | null;
|
|
85
88
|
cachePolicyVersion?: string | null;
|
|
86
89
|
staleAfterSeconds?: number | null;
|
|
90
|
+
/** Run-stable clock used to choose the stale bucket. */
|
|
91
|
+
cacheEpochMs?: number;
|
|
87
92
|
}): string {
|
|
88
93
|
const orgId = input.orgId?.trim() || 'org';
|
|
89
94
|
const playId = input.playId?.trim() || 'play';
|
|
@@ -104,6 +109,7 @@ export function buildDurableCtxCallCacheKey(input: {
|
|
|
104
109
|
input.cachePolicyVersion ?? DURABLE_CALL_CACHE_POLICY_VERSION,
|
|
105
110
|
staleBucket: durableCacheStaleBucket({
|
|
106
111
|
staleAfterSeconds: input.staleAfterSeconds,
|
|
112
|
+
nowMs: input.cacheEpochMs,
|
|
107
113
|
}),
|
|
108
114
|
}),
|
|
109
115
|
);
|
|
@@ -56,6 +56,7 @@ export const PLAY_AUTHORING_CONTRACT_ISSUE_CODES = [
|
|
|
56
56
|
'play_authoring_billing_limit_invalid',
|
|
57
57
|
'play_authoring_billing_limit_unresolved',
|
|
58
58
|
'play_authoring_webhook_hmac_invalid',
|
|
59
|
+
'play_authoring_standard_webhooks_invalid',
|
|
59
60
|
'play_authoring_secret_invalid',
|
|
60
61
|
'play_authoring_cron_timezone_invalid',
|
|
61
62
|
'play_authoring_tool_request_invalid',
|
|
@@ -83,6 +84,16 @@ export type PlayAuthoringContractIssue = {
|
|
|
83
84
|
};
|
|
84
85
|
|
|
85
86
|
export type PlaySqlListenerOperation = 'INSERT' | 'UPDATE' | 'DELETE';
|
|
87
|
+
export type PlayStandardWebhookHeaderFamily = 'standard' | 'svix';
|
|
88
|
+
export type PlayStandardWebhookAuth = {
|
|
89
|
+
type: 'standard-webhooks';
|
|
90
|
+
/** `webhook-*` for Standard Webhooks, `svix-*` for Svix senders. */
|
|
91
|
+
headerFamily: PlayStandardWebhookHeaderFamily;
|
|
92
|
+
/** Deepline Secret names used for ordinary operation and rotation overlap. */
|
|
93
|
+
signingSecrets: string[];
|
|
94
|
+
/** Replay-protection window. Omitted means the Standard Webhooks 5-minute default. */
|
|
95
|
+
toleranceSeconds?: number;
|
|
96
|
+
};
|
|
86
97
|
export const PLAY_SQL_LISTENER_WHERE_OPERATORS = [
|
|
87
98
|
'eq',
|
|
88
99
|
'neq',
|
|
@@ -259,6 +270,7 @@ export type PlayAuthoringAstBindings = {
|
|
|
259
270
|
header?: string;
|
|
260
271
|
secretEnv: string;
|
|
261
272
|
};
|
|
273
|
+
auth?: PlayStandardWebhookAuth;
|
|
262
274
|
};
|
|
263
275
|
cron?: { schedule: string; timezone?: string };
|
|
264
276
|
sqlListeners?: PlayAuthoringAstSqlListenerDeclaration[];
|
|
@@ -287,6 +299,7 @@ export type PlayAuthoringBindings = {
|
|
|
287
299
|
header?: string;
|
|
288
300
|
secretEnv: string;
|
|
289
301
|
};
|
|
302
|
+
auth?: PlayStandardWebhookAuth;
|
|
290
303
|
};
|
|
291
304
|
cron?: {
|
|
292
305
|
schedule: string;
|
|
@@ -973,6 +986,81 @@ export const PLAY_AUTHORING_FIELD_REGISTRY = {
|
|
|
973
986
|
errorMessage:
|
|
974
987
|
'bindings.webhook.hmac.header must be a non-empty static string.',
|
|
975
988
|
},
|
|
989
|
+
'bindings.webhook.auth.type': {
|
|
990
|
+
schema: Type.Literal('standard-webhooks'),
|
|
991
|
+
fixtures: {
|
|
992
|
+
valid: 'standard-webhooks',
|
|
993
|
+
invalid: 'svix',
|
|
994
|
+
absent: undefined,
|
|
995
|
+
unresolved: { expression: 'type' },
|
|
996
|
+
edition1: undefined,
|
|
997
|
+
},
|
|
998
|
+
referenceType: "'standard-webhooks'",
|
|
999
|
+
// auth itself is optional; once present, the AST adapter requires this
|
|
1000
|
+
// field together with headerFamily and signingSecrets.
|
|
1001
|
+
required: false,
|
|
1002
|
+
resolution: 'static-required',
|
|
1003
|
+
issueCode: 'play_authoring_standard_webhooks_invalid',
|
|
1004
|
+
description: 'Uses the Standard Webhooks v1 symmetric signing scheme.',
|
|
1005
|
+
errorMessage:
|
|
1006
|
+
'bindings.webhook.auth.type must be the static literal "standard-webhooks".',
|
|
1007
|
+
},
|
|
1008
|
+
'bindings.webhook.auth.headerFamily': {
|
|
1009
|
+
schema: Type.Union([Type.Literal('standard'), Type.Literal('svix')]),
|
|
1010
|
+
fixtures: {
|
|
1011
|
+
valid: 'svix',
|
|
1012
|
+
invalid: 'webhook',
|
|
1013
|
+
absent: undefined,
|
|
1014
|
+
unresolved: { expression: 'headerFamily' },
|
|
1015
|
+
edition1: undefined,
|
|
1016
|
+
},
|
|
1017
|
+
referenceType: "'standard' | 'svix'",
|
|
1018
|
+
// auth itself is optional; once present, the AST adapter requires this
|
|
1019
|
+
// field together with type and signingSecrets.
|
|
1020
|
+
required: false,
|
|
1021
|
+
resolution: 'static-required',
|
|
1022
|
+
issueCode: 'play_authoring_standard_webhooks_invalid',
|
|
1023
|
+
description: 'Header namespace expected from the webhook provider.',
|
|
1024
|
+
errorMessage:
|
|
1025
|
+
'bindings.webhook.auth.headerFamily must be the static literal "standard" or "svix".',
|
|
1026
|
+
},
|
|
1027
|
+
'bindings.webhook.auth.signingSecrets[]': {
|
|
1028
|
+
schema: SecretEnvironmentNameSchema,
|
|
1029
|
+
fixtures: {
|
|
1030
|
+
valid: 'VECTOR_WEBHOOK_SECRET',
|
|
1031
|
+
invalid: 'vector_webhook_secret',
|
|
1032
|
+
absent: undefined,
|
|
1033
|
+
unresolved: { expression: 'secret' },
|
|
1034
|
+
edition1: undefined,
|
|
1035
|
+
},
|
|
1036
|
+
referenceType: 'string',
|
|
1037
|
+
// auth itself is optional; once present, the AST adapter requires this
|
|
1038
|
+
// field together with type and headerFamily.
|
|
1039
|
+
required: false,
|
|
1040
|
+
resolution: 'static-required',
|
|
1041
|
+
issueCode: 'play_authoring_standard_webhooks_invalid',
|
|
1042
|
+
description: 'Deepline Secret name used to verify Standard Webhooks.',
|
|
1043
|
+
errorMessage:
|
|
1044
|
+
'bindings.webhook.auth.signingSecrets entries must be uppercase Deepline Secret names beginning with a letter.',
|
|
1045
|
+
},
|
|
1046
|
+
'bindings.webhook.auth.toleranceSeconds': {
|
|
1047
|
+
schema: Type.Integer({ minimum: 1, maximum: 3600 }),
|
|
1048
|
+
fixtures: {
|
|
1049
|
+
valid: 300,
|
|
1050
|
+
invalid: 0,
|
|
1051
|
+
absent: undefined,
|
|
1052
|
+
unresolved: { expression: 'toleranceSeconds' },
|
|
1053
|
+
edition1: undefined,
|
|
1054
|
+
},
|
|
1055
|
+
referenceType: 'number',
|
|
1056
|
+
required: false,
|
|
1057
|
+
resolution: 'static-required',
|
|
1058
|
+
issueCode: 'play_authoring_standard_webhooks_invalid',
|
|
1059
|
+
description:
|
|
1060
|
+
'Accepted delivery timestamp skew in seconds, from 1 through 3600.',
|
|
1061
|
+
errorMessage:
|
|
1062
|
+
'bindings.webhook.auth.toleranceSeconds must be a static whole number from 1 through 3600.',
|
|
1063
|
+
},
|
|
976
1064
|
'bindings.cron.schedule': {
|
|
977
1065
|
schema: Type.String({ minLength: 1 }),
|
|
978
1066
|
fixtures: {
|
|
@@ -2157,7 +2245,7 @@ export const PLAY_AUTHORING_CLOUD_TYPE_DECLARATIONS = [
|
|
|
2157
2245
|
` inline?: ${cloudReferenceType('inline')};`,
|
|
2158
2246
|
` billing?: { maxCreditsPerRun?: ${cloudReferenceType('billing.maxCreditsPerRun')} };`,
|
|
2159
2247
|
` runtime?: { timeout?: ${cloudReferenceType('runtime.timeout')}; size?: ${cloudReferenceType('runtime.size')} };`,
|
|
2160
|
-
` webhook?: { hmac?: { algorithm?: ${cloudReferenceType('bindings.webhook.hmac.algorithm')}; header?: ${cloudReferenceType('bindings.webhook.hmac.header')}; secretEnv: ${cloudReferenceType('bindings.webhook.hmac.secretEnv')} } };`,
|
|
2248
|
+
` webhook?: { hmac?: { algorithm?: ${cloudReferenceType('bindings.webhook.hmac.algorithm')}; header?: ${cloudReferenceType('bindings.webhook.hmac.header')}; secretEnv: ${cloudReferenceType('bindings.webhook.hmac.secretEnv')} }; auth?: { type: ${cloudReferenceType('bindings.webhook.auth.type')}; headerFamily: ${cloudReferenceType('bindings.webhook.auth.headerFamily')}; signingSecrets: readonly ${cloudReferenceType('bindings.webhook.auth.signingSecrets[]')}[]; toleranceSeconds?: ${cloudReferenceType('bindings.webhook.auth.toleranceSeconds')} } };`,
|
|
2161
2249
|
` cron?: { schedule: ${cloudReferenceType('bindings.cron.schedule')}; timezone?: ${cloudReferenceType('bindings.cron.timezone')} };`,
|
|
2162
2250
|
' sqlListeners?: readonly SqlListenerDeclaration[];',
|
|
2163
2251
|
` secrets?: readonly ${cloudReferenceType('bindings.secrets[]')}[];`,
|
package/dist/cli/index.js
CHANGED
|
@@ -1044,7 +1044,7 @@ var SDK_RELEASE = {
|
|
|
1044
1044
|
// 0.2.0 makes Dataset Handles uniformly async-only after 0.1.320 briefly
|
|
1045
1045
|
// exposed storage-dependent synchronous access. This deliberate minor
|
|
1046
1046
|
// release keeps lazy paging semantics independent of row residency.
|
|
1047
|
-
version: "0.2.
|
|
1047
|
+
version: "0.2.49",
|
|
1048
1048
|
contracts: {
|
|
1049
1049
|
api: {
|
|
1050
1050
|
name: "sdk-http-api",
|
|
@@ -3879,7 +3879,7 @@ var DeeplineClient = class {
|
|
|
3879
3879
|
deploy: (definition, options2) => this.deployMonitor(definition, options2),
|
|
3880
3880
|
list: (options2) => this.listMonitors(options2),
|
|
3881
3881
|
get: (key) => this.getMonitor(key),
|
|
3882
|
-
test: (key, payload) => this.testMonitorWebhook(key, payload),
|
|
3882
|
+
test: (key, payload, options2) => this.testMonitorWebhook(key, payload, options2),
|
|
3883
3883
|
validate: (key) => this.validateMonitor(key),
|
|
3884
3884
|
dependents: (key) => this.getMonitorDependents(key),
|
|
3885
3885
|
update: (key, patch) => this.updateMonitor(key, patch),
|
|
@@ -6048,10 +6048,16 @@ var DeeplineClient = class {
|
|
|
6048
6048
|
{ method: "GET" }
|
|
6049
6049
|
);
|
|
6050
6050
|
}
|
|
6051
|
-
async testMonitorWebhook(key, payload) {
|
|
6051
|
+
async testMonitorWebhook(key, payload, options) {
|
|
6052
6052
|
return this.http.request(
|
|
6053
6053
|
`/api/v2/monitors/deployed/${encodeURIComponent(key)}/test`,
|
|
6054
|
-
{
|
|
6054
|
+
{
|
|
6055
|
+
method: "POST",
|
|
6056
|
+
body: {
|
|
6057
|
+
payload,
|
|
6058
|
+
...options?.validationOnly ? { mode: "validation_only" } : {}
|
|
6059
|
+
}
|
|
6060
|
+
}
|
|
6055
6061
|
);
|
|
6056
6062
|
}
|
|
6057
6063
|
async setupMonitor(tool, payload) {
|
|
@@ -15021,6 +15027,76 @@ var PLAY_AUTHORING_FIELD_REGISTRY = {
|
|
|
15021
15027
|
description: "HTTP header containing the webhook signature.",
|
|
15022
15028
|
errorMessage: "bindings.webhook.hmac.header must be a non-empty static string."
|
|
15023
15029
|
},
|
|
15030
|
+
"bindings.webhook.auth.type": {
|
|
15031
|
+
schema: Type.Literal("standard-webhooks"),
|
|
15032
|
+
fixtures: {
|
|
15033
|
+
valid: "standard-webhooks",
|
|
15034
|
+
invalid: "svix",
|
|
15035
|
+
absent: void 0,
|
|
15036
|
+
unresolved: { expression: "type" },
|
|
15037
|
+
edition1: void 0
|
|
15038
|
+
},
|
|
15039
|
+
referenceType: "'standard-webhooks'",
|
|
15040
|
+
// auth itself is optional; once present, the AST adapter requires this
|
|
15041
|
+
// field together with headerFamily and signingSecrets.
|
|
15042
|
+
required: false,
|
|
15043
|
+
resolution: "static-required",
|
|
15044
|
+
issueCode: "play_authoring_standard_webhooks_invalid",
|
|
15045
|
+
description: "Uses the Standard Webhooks v1 symmetric signing scheme.",
|
|
15046
|
+
errorMessage: 'bindings.webhook.auth.type must be the static literal "standard-webhooks".'
|
|
15047
|
+
},
|
|
15048
|
+
"bindings.webhook.auth.headerFamily": {
|
|
15049
|
+
schema: Type.Union([Type.Literal("standard"), Type.Literal("svix")]),
|
|
15050
|
+
fixtures: {
|
|
15051
|
+
valid: "svix",
|
|
15052
|
+
invalid: "webhook",
|
|
15053
|
+
absent: void 0,
|
|
15054
|
+
unresolved: { expression: "headerFamily" },
|
|
15055
|
+
edition1: void 0
|
|
15056
|
+
},
|
|
15057
|
+
referenceType: "'standard' | 'svix'",
|
|
15058
|
+
// auth itself is optional; once present, the AST adapter requires this
|
|
15059
|
+
// field together with type and signingSecrets.
|
|
15060
|
+
required: false,
|
|
15061
|
+
resolution: "static-required",
|
|
15062
|
+
issueCode: "play_authoring_standard_webhooks_invalid",
|
|
15063
|
+
description: "Header namespace expected from the webhook provider.",
|
|
15064
|
+
errorMessage: 'bindings.webhook.auth.headerFamily must be the static literal "standard" or "svix".'
|
|
15065
|
+
},
|
|
15066
|
+
"bindings.webhook.auth.signingSecrets[]": {
|
|
15067
|
+
schema: SecretEnvironmentNameSchema,
|
|
15068
|
+
fixtures: {
|
|
15069
|
+
valid: "VECTOR_WEBHOOK_SECRET",
|
|
15070
|
+
invalid: "vector_webhook_secret",
|
|
15071
|
+
absent: void 0,
|
|
15072
|
+
unresolved: { expression: "secret" },
|
|
15073
|
+
edition1: void 0
|
|
15074
|
+
},
|
|
15075
|
+
referenceType: "string",
|
|
15076
|
+
// auth itself is optional; once present, the AST adapter requires this
|
|
15077
|
+
// field together with type and headerFamily.
|
|
15078
|
+
required: false,
|
|
15079
|
+
resolution: "static-required",
|
|
15080
|
+
issueCode: "play_authoring_standard_webhooks_invalid",
|
|
15081
|
+
description: "Deepline Secret name used to verify Standard Webhooks.",
|
|
15082
|
+
errorMessage: "bindings.webhook.auth.signingSecrets entries must be uppercase Deepline Secret names beginning with a letter."
|
|
15083
|
+
},
|
|
15084
|
+
"bindings.webhook.auth.toleranceSeconds": {
|
|
15085
|
+
schema: Type.Integer({ minimum: 1, maximum: 3600 }),
|
|
15086
|
+
fixtures: {
|
|
15087
|
+
valid: 300,
|
|
15088
|
+
invalid: 0,
|
|
15089
|
+
absent: void 0,
|
|
15090
|
+
unresolved: { expression: "toleranceSeconds" },
|
|
15091
|
+
edition1: void 0
|
|
15092
|
+
},
|
|
15093
|
+
referenceType: "number",
|
|
15094
|
+
required: false,
|
|
15095
|
+
resolution: "static-required",
|
|
15096
|
+
issueCode: "play_authoring_standard_webhooks_invalid",
|
|
15097
|
+
description: "Accepted delivery timestamp skew in seconds, from 1 through 3600.",
|
|
15098
|
+
errorMessage: "bindings.webhook.auth.toleranceSeconds must be a static whole number from 1 through 3600."
|
|
15099
|
+
},
|
|
15024
15100
|
"bindings.cron.schedule": {
|
|
15025
15101
|
schema: Type.String({ minLength: 1 }),
|
|
15026
15102
|
fixtures: {
|
|
@@ -16045,7 +16121,7 @@ var PLAY_AUTHORING_CLOUD_TYPE_DECLARATIONS = [
|
|
|
16045
16121
|
` inline?: ${cloudReferenceType("inline")};`,
|
|
16046
16122
|
` billing?: { maxCreditsPerRun?: ${cloudReferenceType("billing.maxCreditsPerRun")} };`,
|
|
16047
16123
|
` runtime?: { timeout?: ${cloudReferenceType("runtime.timeout")}; size?: ${cloudReferenceType("runtime.size")} };`,
|
|
16048
|
-
` webhook?: { hmac?: { algorithm?: ${cloudReferenceType("bindings.webhook.hmac.algorithm")}; header?: ${cloudReferenceType("bindings.webhook.hmac.header")}; secretEnv: ${cloudReferenceType("bindings.webhook.hmac.secretEnv")} } };`,
|
|
16124
|
+
` webhook?: { hmac?: { algorithm?: ${cloudReferenceType("bindings.webhook.hmac.algorithm")}; header?: ${cloudReferenceType("bindings.webhook.hmac.header")}; secretEnv: ${cloudReferenceType("bindings.webhook.hmac.secretEnv")} }; auth?: { type: ${cloudReferenceType("bindings.webhook.auth.type")}; headerFamily: ${cloudReferenceType("bindings.webhook.auth.headerFamily")}; signingSecrets: readonly ${cloudReferenceType("bindings.webhook.auth.signingSecrets[]")}[]; toleranceSeconds?: ${cloudReferenceType("bindings.webhook.auth.toleranceSeconds")} } };`,
|
|
16049
16125
|
` cron?: { schedule: ${cloudReferenceType("bindings.cron.schedule")}; timezone?: ${cloudReferenceType("bindings.cron.timezone")} };`,
|
|
16050
16126
|
" sqlListeners?: readonly SqlListenerDeclaration[];",
|
|
16051
16127
|
` secrets?: readonly ${cloudReferenceType("bindings.secrets[]")}[];`,
|
|
@@ -30757,6 +30833,31 @@ function readDeployOutputContract(payload) {
|
|
|
30757
30833
|
});
|
|
30758
30834
|
return { tool: asString(contract.tool), streams };
|
|
30759
30835
|
}
|
|
30836
|
+
function renderDeployReplacementWarning(input2) {
|
|
30837
|
+
const summary = asRecord2(input2.payload.change_summary);
|
|
30838
|
+
const upstream = summary ? asRecord2(summary.upstream) : void 0;
|
|
30839
|
+
if (!summary || !upstream || upstream.resource_replaced !== true) return [];
|
|
30840
|
+
const definition = asRecord2(summary.definition);
|
|
30841
|
+
const changed = definition && Array.isArray(definition.changed) ? definition.changed : [];
|
|
30842
|
+
const lines = [
|
|
30843
|
+
input2.completed ? "WARNING: this deploy replaced the existing upstream monitor." : "WARNING: this deploy replaces the existing upstream monitor.",
|
|
30844
|
+
"Existing Customer DB rows are preserved. Provider backfill is not implied."
|
|
30845
|
+
];
|
|
30846
|
+
for (const raw of changed) {
|
|
30847
|
+
const item = asRecord2(raw);
|
|
30848
|
+
const path = item ? asString(item.path) : void 0;
|
|
30849
|
+
if (!item || !path) continue;
|
|
30850
|
+
lines.push(
|
|
30851
|
+
` ${path}: ${JSON.stringify(item.before ?? null)} \u2192 ${JSON.stringify(
|
|
30852
|
+
item.after ?? null
|
|
30853
|
+
)}`
|
|
30854
|
+
);
|
|
30855
|
+
}
|
|
30856
|
+
lines.push(
|
|
30857
|
+
input2.monitorKey ? `Use \`deepline monitors update ${input2.monitorKey} <patch>\` for a patch-style change.` : "Use `deepline monitors update <key> <patch>` for a patch-style change."
|
|
30858
|
+
);
|
|
30859
|
+
return lines;
|
|
30860
|
+
}
|
|
30760
30861
|
function renderMonitorDeployCompletion(payload) {
|
|
30761
30862
|
const monitor = asRecord2(payload.monitor);
|
|
30762
30863
|
const key = monitor ? asString(monitor.key) : void 0;
|
|
@@ -30784,6 +30885,12 @@ function renderMonitorDeployCompletion(payload) {
|
|
|
30784
30885
|
if (pricingLine) {
|
|
30785
30886
|
lines.push("", `Pricing: ${pricingLine}`);
|
|
30786
30887
|
}
|
|
30888
|
+
const replacementWarning = renderDeployReplacementWarning({
|
|
30889
|
+
payload,
|
|
30890
|
+
completed: true,
|
|
30891
|
+
monitorKey: key
|
|
30892
|
+
});
|
|
30893
|
+
if (replacementWarning.length) lines.push("", ...replacementWarning);
|
|
30787
30894
|
const guidance = asRecord2(payload.setup_guidance);
|
|
30788
30895
|
if (guidance) {
|
|
30789
30896
|
const callbackUrl = asString(guidance.callback_url);
|
|
@@ -30835,6 +30942,11 @@ function renderMonitorDeployPlan(payload) {
|
|
|
30835
30942
|
if (message) lines.push(` - ${path ? `${path}: ` : ""}${message}`);
|
|
30836
30943
|
}
|
|
30837
30944
|
}
|
|
30945
|
+
const replacementWarning = renderDeployReplacementWarning({
|
|
30946
|
+
payload,
|
|
30947
|
+
completed: false
|
|
30948
|
+
});
|
|
30949
|
+
if (replacementWarning.length) lines.push("", ...replacementWarning);
|
|
30838
30950
|
const estimate = asRecord2(payload.deploy_cost_estimate);
|
|
30839
30951
|
const credits = estimate ? asFiniteNumber(estimate.credits) : void 0;
|
|
30840
30952
|
if (credits !== void 0) {
|
|
@@ -31201,10 +31313,17 @@ async function handleMonitorsGet(key, options) {
|
|
|
31201
31313
|
}
|
|
31202
31314
|
async function handleMonitorsTest(key, payload, options) {
|
|
31203
31315
|
const explicitPayload = parseJsonObjectArg(payload, "<payload>");
|
|
31204
|
-
const result = await new DeeplineClient().monitors.test(
|
|
31205
|
-
|
|
31206
|
-
|
|
31207
|
-
|
|
31316
|
+
const result = await new DeeplineClient().monitors.test(
|
|
31317
|
+
key,
|
|
31318
|
+
explicitPayload,
|
|
31319
|
+
{
|
|
31320
|
+
validationOnly: options.dispatch !== true
|
|
31321
|
+
}
|
|
31322
|
+
);
|
|
31323
|
+
const dispatch = options.dispatch === true;
|
|
31324
|
+
const text = `Monitor diagnostic for ${key}: ${result.accepted === true ? "accepted" : "rejected"}
|
|
31325
|
+
` + (dispatch ? " mode: dispatch (writes rows and may dispatch bound Plays)\n" : " mode: validation_only (no rows written, credits spent, or Plays dispatched)\n") + `${dispatch ? "persisted" : "would persist"} rows: ${asFiniteNumber(result.persisted_rows) ?? 0}
|
|
31326
|
+
${dispatch ? "dispatched" : "would dispatch"} bound Plays: ${asFiniteNumber(result.dispatched_bound_plays) ?? 0}
|
|
31208
31327
|
`;
|
|
31209
31328
|
printCommandEnvelope(result, { json: options.json, text });
|
|
31210
31329
|
}
|
|
@@ -31416,12 +31535,18 @@ Examples:
|
|
|
31416
31535
|
withJsonOption(
|
|
31417
31536
|
monitors.command("test <key> <payload>").description(
|
|
31418
31537
|
"Send an explicit payload through a monitor\u2019s webhook ingestion path."
|
|
31538
|
+
).option(
|
|
31539
|
+
"--dispatch",
|
|
31540
|
+
"Inject the test event through normal ingestion (writes rows and may dispatch bound Plays)"
|
|
31419
31541
|
).addHelpText(
|
|
31420
31542
|
"after",
|
|
31421
31543
|
`
|
|
31422
31544
|
Notes:
|
|
31423
31545
|
<payload> must be an explicit JSON object. The command uses the deployed
|
|
31424
|
-
monitor\u2019s real
|
|
31546
|
+
monitor\u2019s real binding and payload validation, but is a side-effect-free
|
|
31547
|
+
diagnostic: it does not persist rows, spend credits, dispatch Plays, or alter
|
|
31548
|
+
monitor state. Pass --dispatch only when you deliberately need the historic
|
|
31549
|
+
full-ingestion test event; it can write rows and trigger bound Plays. It does
|
|
31425
31550
|
not synthesize a provider event or accept an omitted payload.
|
|
31426
31551
|
|
|
31427
31552
|
Examples:
|
|
@@ -31442,7 +31567,9 @@ Notes:
|
|
|
31442
31567
|
via --file <path>, or
|
|
31443
31568
|
from stdin with --file -. Does not deploy or spend credits.
|
|
31444
31569
|
For Deepline Native Company Radar monitors, check validates persona-filter enums and the
|
|
31445
|
-
job_titles Boolean-expression grammar locally
|
|
31570
|
+
job_titles Boolean-expression grammar locally (parentheses are unsupported;
|
|
31571
|
+
NOT > AND > OR).
|
|
31572
|
+
Inspect the exact schema with
|
|
31446
31573
|
\`deepline monitors available deepline_native.company_radar --json\`.
|
|
31447
31574
|
|
|
31448
31575
|
Examples:
|
|
@@ -31466,6 +31593,9 @@ Notes:
|
|
|
31466
31593
|
--dry-run validates the definition and shows the plan (deploy cost in Deepline
|
|
31467
31594
|
credits when the server reports it, plus any existing monitors that may
|
|
31468
31595
|
already cover this scope) WITHOUT deploying. Exits 0 when valid, 7 when not.
|
|
31596
|
+
Deploy is a full desired definition for its key: omitting a previously stored
|
|
31597
|
+
field removes it and can replace the upstream resource. Use \`monitors update\`
|
|
31598
|
+
for a patch-style change.
|
|
31469
31599
|
|
|
31470
31600
|
Examples:
|
|
31471
31601
|
deepline monitors deploy '{"key":"job-openings","tool":"deepline_native.company_radar","payload":{"domain":"stripe.com","radar_type":"company_job_openings"}}'
|