deepline 0.2.48 → 0.2.50
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/plays/authoring-contract.ts +89 -1
- package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +35 -7
- package/dist/bundling-sources/shared_libs/plays/enrich-compat-adapter.ts +21 -0
- package/dist/bundling-sources/shared_libs/plays/enrich-play-compiler.ts +1555 -0
- package/dist/bundling-sources/shared_libs/plays/user-code-safety.ts +61 -0
- package/dist/cli/index.js +147 -15
- package/dist/cli/index.mjs +150 -16
- 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 +5 -2
- package/dist/plays/bundle-play-file.d.mts +4 -2
- package/dist/plays/bundle-play-file.d.ts +4 -2
- package/dist/plays/bundle-play-file.mjs +102 -7
- 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.50',
|
|
164
164
|
contracts: {
|
|
165
165
|
api: {
|
|
166
166
|
name: 'sdk-http-api',
|
|
@@ -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[]')}[];`,
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
join,
|
|
11
11
|
relative,
|
|
12
12
|
resolve,
|
|
13
|
+
sep,
|
|
13
14
|
} from 'node:path';
|
|
14
15
|
import { builtinModules } from 'node:module';
|
|
15
16
|
import { Parser } from 'acorn';
|
|
@@ -94,6 +95,8 @@ export type PlayLocalFileDiscoveryResult = {
|
|
|
94
95
|
|
|
95
96
|
export type PlayBundlingAdapter = {
|
|
96
97
|
projectRoot: string;
|
|
98
|
+
/** Optional root used only to make source-graph identity independent of temporary absolute paths. */
|
|
99
|
+
sourceIdentityRoot?: string;
|
|
97
100
|
nodeModulesDir: string;
|
|
98
101
|
cacheDir?: string;
|
|
99
102
|
sdkSourceRoot: string;
|
|
@@ -179,6 +182,24 @@ function sha256(value: string): string {
|
|
|
179
182
|
return createHash('sha256').update(value).digest('hex');
|
|
180
183
|
}
|
|
181
184
|
|
|
185
|
+
function sourceIdentityPath(
|
|
186
|
+
filePath: string,
|
|
187
|
+
adapter: PlayBundlingAdapter,
|
|
188
|
+
): string {
|
|
189
|
+
if (!adapter.sourceIdentityRoot) return filePath;
|
|
190
|
+
const identityRoot = resolve(adapter.sourceIdentityRoot);
|
|
191
|
+
const logicalPath = relative(identityRoot, resolve(filePath));
|
|
192
|
+
if (
|
|
193
|
+
!logicalPath ||
|
|
194
|
+
logicalPath === '..' ||
|
|
195
|
+
logicalPath.startsWith(`..${sep}`) ||
|
|
196
|
+
isAbsolute(logicalPath)
|
|
197
|
+
) {
|
|
198
|
+
return filePath;
|
|
199
|
+
}
|
|
200
|
+
return logicalPath.split(/[\\/]+/).join('/');
|
|
201
|
+
}
|
|
202
|
+
|
|
182
203
|
function formatEsbuildMessage(message: Message): string {
|
|
183
204
|
const location = message.location
|
|
184
205
|
? `${message.location.file}:${message.location.line}:${message.location.column}`
|
|
@@ -1598,9 +1619,12 @@ async function analyzeSourceGraph(
|
|
|
1598
1619
|
const sourceHash = sha256(sourceCode);
|
|
1599
1620
|
const graphHash = sha256(
|
|
1600
1621
|
JSON.stringify({
|
|
1601
|
-
entryFile: absoluteEntryFile,
|
|
1622
|
+
entryFile: sourceIdentityPath(absoluteEntryFile, adapter),
|
|
1602
1623
|
localFiles: [...localFiles.entries()]
|
|
1603
|
-
.map(([filePath, contents]) => ({
|
|
1624
|
+
.map(([filePath, contents]) => ({
|
|
1625
|
+
filePath: sourceIdentityPath(filePath, adapter),
|
|
1626
|
+
hash: sha256(contents),
|
|
1627
|
+
}))
|
|
1604
1628
|
.sort((left, right) => left.filePath.localeCompare(right.filePath)),
|
|
1605
1629
|
nodeBuiltins: [...nodeBuiltins].sort(),
|
|
1606
1630
|
packages: [...packages.entries()]
|
|
@@ -1608,7 +1632,7 @@ async function analyzeSourceGraph(
|
|
|
1608
1632
|
.sort((left, right) => left.name.localeCompare(right.name)),
|
|
1609
1633
|
importedPlayDependencies: [...importedPlayDependencies.values()]
|
|
1610
1634
|
.map((dependency) => ({
|
|
1611
|
-
filePath: dependency.filePath,
|
|
1635
|
+
filePath: sourceIdentityPath(dependency.filePath, adapter),
|
|
1612
1636
|
playName: dependency.playName,
|
|
1613
1637
|
}))
|
|
1614
1638
|
.sort((left, right) => left.filePath.localeCompare(right.filePath)),
|
|
@@ -1660,7 +1684,7 @@ function artifactCachePath(
|
|
|
1660
1684
|
adapter: PlayBundlingAdapter,
|
|
1661
1685
|
): string {
|
|
1662
1686
|
return join(
|
|
1663
|
-
adapter.cacheDir ?? PLAY_ARTIFACT_CACHE_DIR,
|
|
1687
|
+
/* turbopackIgnore: true */ adapter.cacheDir ?? PLAY_ARTIFACT_CACHE_DIR,
|
|
1664
1688
|
`${graphHash}.${artifactKind}.json`,
|
|
1665
1689
|
);
|
|
1666
1690
|
}
|
|
@@ -1672,7 +1696,11 @@ async function readArtifactCache(
|
|
|
1672
1696
|
): Promise<PlayBundleArtifact | null> {
|
|
1673
1697
|
try {
|
|
1674
1698
|
const serialized = await readFile(
|
|
1675
|
-
artifactCachePath(
|
|
1699
|
+
/* turbopackIgnore: true */ artifactCachePath(
|
|
1700
|
+
graphHash,
|
|
1701
|
+
artifactKind,
|
|
1702
|
+
adapter,
|
|
1703
|
+
),
|
|
1676
1704
|
'utf-8',
|
|
1677
1705
|
);
|
|
1678
1706
|
return JSON.parse(serialized) as PlayBundleArtifact;
|
|
@@ -1686,9 +1714,9 @@ async function writeArtifactCache(
|
|
|
1686
1714
|
adapter: PlayBundlingAdapter,
|
|
1687
1715
|
): Promise<void> {
|
|
1688
1716
|
const cacheDir = adapter.cacheDir ?? PLAY_ARTIFACT_CACHE_DIR;
|
|
1689
|
-
await mkdir(cacheDir, { recursive: true });
|
|
1717
|
+
await mkdir(/* turbopackIgnore: true */ cacheDir, { recursive: true });
|
|
1690
1718
|
await writeFile(
|
|
1691
|
-
artifactCachePath(
|
|
1719
|
+
/* turbopackIgnore: true */ artifactCachePath(
|
|
1692
1720
|
artifact.graphHash,
|
|
1693
1721
|
artifact.artifactKind ?? PLAY_ARTIFACT_KINDS.cjsNode20,
|
|
1694
1722
|
adapter,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export const ENRICH_COMPAT_DEFAULT_PLAY_NAME = 'deepline-enrich-v1-compat';
|
|
2
|
+
export const ENRICH_COMPAT_DEFAULT_MAP_NAME = 'deepline_enrich_rows';
|
|
3
|
+
|
|
4
|
+
export type EnrichCompatibilityOptions = {
|
|
5
|
+
playName?: string;
|
|
6
|
+
mapName?: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export type EnrichCompatibilityPlan = {
|
|
10
|
+
playName: string;
|
|
11
|
+
mapName: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export function buildEnrichCompatibilityPlan(
|
|
15
|
+
options: EnrichCompatibilityOptions = {},
|
|
16
|
+
): EnrichCompatibilityPlan {
|
|
17
|
+
return {
|
|
18
|
+
playName: options.playName?.trim() || ENRICH_COMPAT_DEFAULT_PLAY_NAME,
|
|
19
|
+
mapName: options.mapName?.trim() || ENRICH_COMPAT_DEFAULT_MAP_NAME,
|
|
20
|
+
};
|
|
21
|
+
}
|