@sequenceholdings/pipeline-spec 0.1.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 +114 -0
- package/dist/authoring/per-table-ingestion.d.ts +74 -0
- package/dist/authoring/per-table-ingestion.d.ts.map +1 -0
- package/dist/authoring/per-table-ingestion.js +122 -0
- package/dist/authoring/per-table-ingestion.js.map +1 -0
- package/dist/authoring/yaml.d.ts +6 -0
- package/dist/authoring/yaml.d.ts.map +1 -0
- package/dist/authoring/yaml.js +15 -0
- package/dist/authoring/yaml.js.map +1 -0
- package/dist/binding-gaps.d.ts +21 -0
- package/dist/binding-gaps.d.ts.map +1 -0
- package/dist/binding-gaps.js +74 -0
- package/dist/binding-gaps.js.map +1 -0
- package/dist/bodies/ingestion.d.ts +359 -0
- package/dist/bodies/ingestion.d.ts.map +1 -0
- package/dist/bodies/ingestion.js +446 -0
- package/dist/bodies/ingestion.js.map +1 -0
- package/dist/bodies/serving.d.ts +316 -0
- package/dist/bodies/serving.d.ts.map +1 -0
- package/dist/bodies/serving.js +290 -0
- package/dist/bodies/serving.js.map +1 -0
- package/dist/bodies/transformation.d.ts +397 -0
- package/dist/bodies/transformation.d.ts.map +1 -0
- package/dist/bodies/transformation.js +278 -0
- package/dist/bodies/transformation.js.map +1 -0
- package/dist/catalog-binding.d.ts +15 -0
- package/dist/catalog-binding.d.ts.map +1 -0
- package/dist/catalog-binding.js +15 -0
- package/dist/catalog-binding.js.map +1 -0
- package/dist/columns.d.ts +177 -0
- package/dist/columns.d.ts.map +1 -0
- package/dist/columns.js +89 -0
- package/dist/columns.js.map +1 -0
- package/dist/compatibility.d.ts +25 -0
- package/dist/compatibility.d.ts.map +1 -0
- package/dist/compatibility.js +108 -0
- package/dist/compatibility.js.map +1 -0
- package/dist/constants.d.ts +95 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +105 -0
- package/dist/constants.js.map +1 -0
- package/dist/diff.d.ts +36 -0
- package/dist/diff.d.ts.map +1 -0
- package/dist/diff.js +300 -0
- package/dist/diff.js.map +1 -0
- package/dist/documentation.d.ts +22 -0
- package/dist/documentation.d.ts.map +1 -0
- package/dist/documentation.js +43 -0
- package/dist/documentation.js.map +1 -0
- package/dist/envelope.d.ts +1241 -0
- package/dist/envelope.d.ts.map +1 -0
- package/dist/envelope.js +163 -0
- package/dist/envelope.js.map +1 -0
- package/dist/errors.d.ts +30 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +47 -0
- package/dist/errors.js.map +1 -0
- package/dist/graph-references.d.ts +34 -0
- package/dist/graph-references.d.ts.map +1 -0
- package/dist/graph-references.js +81 -0
- package/dist/graph-references.js.map +1 -0
- package/dist/graph.d.ts +112 -0
- package/dist/graph.d.ts.map +1 -0
- package/dist/graph.js +546 -0
- package/dist/graph.js.map +1 -0
- package/dist/hash.d.ts +28 -0
- package/dist/hash.d.ts.map +1 -0
- package/dist/hash.js +91 -0
- package/dist/hash.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/issues.d.ts +14 -0
- package/dist/issues.d.ts.map +1 -0
- package/dist/issues.js +27 -0
- package/dist/issues.js.map +1 -0
- package/dist/loader.d.ts +50 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +241 -0
- package/dist/loader.js.map +1 -0
- package/dist/migrations/contracts.d.ts +38 -0
- package/dist/migrations/contracts.d.ts.map +1 -0
- package/dist/migrations/contracts.js +175 -0
- package/dist/migrations/contracts.js.map +1 -0
- package/dist/migrations/manifest.d.ts +137 -0
- package/dist/migrations/manifest.d.ts.map +1 -0
- package/dist/migrations/manifest.js +137 -0
- package/dist/migrations/manifest.js.map +1 -0
- package/dist/operations.d.ts +214 -0
- package/dist/operations.d.ts.map +1 -0
- package/dist/operations.js +275 -0
- package/dist/operations.js.map +1 -0
- package/dist/orm-satisfies.d.ts +132 -0
- package/dist/orm-satisfies.d.ts.map +1 -0
- package/dist/orm-satisfies.js +119 -0
- package/dist/orm-satisfies.js.map +1 -0
- package/dist/primitives.d.ts +11 -0
- package/dist/primitives.d.ts.map +1 -0
- package/dist/primitives.js +20 -0
- package/dist/primitives.js.map +1 -0
- package/dist/resolve.d.ts +124 -0
- package/dist/resolve.d.ts.map +1 -0
- package/dist/resolve.js +194 -0
- package/dist/resolve.js.map +1 -0
- package/dist/secret-scan.d.ts +34 -0
- package/dist/secret-scan.d.ts.map +1 -0
- package/dist/secret-scan.js +98 -0
- package/dist/secret-scan.js.map +1 -0
- package/dist/serving-compatibility.d.ts +14 -0
- package/dist/serving-compatibility.d.ts.map +1 -0
- package/dist/serving-compatibility.js +19 -0
- package/dist/serving-compatibility.js.map +1 -0
- package/dist/snapshot-transport.d.ts +83 -0
- package/dist/snapshot-transport.d.ts.map +1 -0
- package/dist/snapshot-transport.js +42 -0
- package/dist/snapshot-transport.js.map +1 -0
- package/dist/suggestions.d.ts +3 -0
- package/dist/suggestions.d.ts.map +1 -0
- package/dist/suggestions.js +26 -0
- package/dist/suggestions.js.map +1 -0
- package/dist/types.d.ts +72 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +119 -0
- package/dist/types.js.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../src/envelope.ts"],"names":[],"mappings":"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"}
|
package/dist/envelope.js
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { DEPLOY_TARGET_PATTERN, STAGE_ID_PATTERN } from './constants.js';
|
|
3
|
+
import { operationsBlockSchema } from './operations.js';
|
|
4
|
+
import { scanForCredentialLikeStrings } from './secret-scan.js';
|
|
5
|
+
import { ingestionBodyShape, isoDurationSchema, refineIngestionBody, symbolicRefSchema, } from './bodies/ingestion.js';
|
|
6
|
+
import { refineTransformationBody, transformationBodyShape } from './bodies/transformation.js';
|
|
7
|
+
import { refineServingBody, servingBodyShape } from './bodies/serving.js';
|
|
8
|
+
/**
|
|
9
|
+
* The stage envelope — the kind-agnostic contract every stage carries:
|
|
10
|
+
* identity, ownership, reliability posture, deploy targets, and operations.
|
|
11
|
+
* The typed bodies (ingestion / transformation / serving) hang off the `type`
|
|
12
|
+
* discriminator.
|
|
13
|
+
*
|
|
14
|
+
* Everything here is **portable**: symbolic references only (credential
|
|
15
|
+
* families, alert channels, worker machines). Resolution against a deploy
|
|
16
|
+
* target's facts happens in `resolveSpec`.
|
|
17
|
+
*/
|
|
18
|
+
export const stageIdSchema = z
|
|
19
|
+
.string()
|
|
20
|
+
.max(63)
|
|
21
|
+
.regex(STAGE_ID_PATTERN, 'must be a kebab-case slug (a-z, 0-9, -)');
|
|
22
|
+
export const deployTargetSchema = z
|
|
23
|
+
.string()
|
|
24
|
+
.regex(DEPLOY_TARGET_PATTERN, 'must be a lowercase deploy-target slug (no path separators or dots)');
|
|
25
|
+
export const CRITICALITIES = ['critical', 'standard', 'experimental'];
|
|
26
|
+
export const criticalitySchema = z.enum(CRITICALITIES);
|
|
27
|
+
/**
|
|
28
|
+
* Remediation posture when the platform detects a contract/reliability
|
|
29
|
+
* failure (carried over from the pipeline-observability contract vocabulary):
|
|
30
|
+
* `manual_only` (default) — page a human; `draft_pr_allowlisted` — the
|
|
31
|
+
* platform may draft a fix PR touching allowlisted paths; `disabled` — no
|
|
32
|
+
* automated remediation, alerts only.
|
|
33
|
+
*/
|
|
34
|
+
export const REMEDIATION_POSTURES = ['manual_only', 'draft_pr_allowlisted', 'disabled'];
|
|
35
|
+
export const remediationPostureSchema = z.enum(REMEDIATION_POSTURES);
|
|
36
|
+
/** Reliability targets. Both optional — criticality drives which are required by policy, not schema. */
|
|
37
|
+
export const slosSchema = z.strictObject({
|
|
38
|
+
/** Max staleness of the stage's outputs before the freshness SLO is breached. */
|
|
39
|
+
freshness: isoDurationSchema.optional(),
|
|
40
|
+
/** Wall-clock budget for a single run. */
|
|
41
|
+
max_duration: isoDurationSchema.optional(),
|
|
42
|
+
});
|
|
43
|
+
/** Symbolic alert channel references — bound to concrete routes by `resolveSpec`. */
|
|
44
|
+
export const alertsSchema = z.strictObject({
|
|
45
|
+
channels: z.array(symbolicRefSchema).min(1),
|
|
46
|
+
});
|
|
47
|
+
/**
|
|
48
|
+
* The kind-agnostic envelope fields shared by all stage types. Kept as a raw
|
|
49
|
+
* shape so each discriminated-union variant can spread it alongside its body.
|
|
50
|
+
*/
|
|
51
|
+
const envelopeShape = {
|
|
52
|
+
/** Spec grammar version — bump on breaking grammar changes. */
|
|
53
|
+
schema_version: z.literal(1),
|
|
54
|
+
/** Kebab id, unique within its Pipeline (repo); must match the spec's file basename. */
|
|
55
|
+
stage: stageIdSchema,
|
|
56
|
+
title: z.string().min(1).max(255),
|
|
57
|
+
description: z.string().min(1),
|
|
58
|
+
owners: z
|
|
59
|
+
.array(z.email())
|
|
60
|
+
.min(1)
|
|
61
|
+
.refine((owners) => new Set(owners).size === owners.length, 'owners must be unique'),
|
|
62
|
+
criticality: criticalitySchema,
|
|
63
|
+
slos: slosSchema.optional(),
|
|
64
|
+
alerts: alertsSchema.optional(),
|
|
65
|
+
/** Where humans go when this stage pages. */
|
|
66
|
+
runbook: z.url().optional(),
|
|
67
|
+
remediation_posture: remediationPostureSchema.default('manual_only'),
|
|
68
|
+
/** Deploy targets the stage supports (e.g. staging, production, banksouth). */
|
|
69
|
+
environments: z
|
|
70
|
+
.array(deployTargetSchema)
|
|
71
|
+
.min(1)
|
|
72
|
+
.refine((environments) => new Set(environments).size === environments.length, 'environments must be unique'),
|
|
73
|
+
operations: operationsBlockSchema.default({}),
|
|
74
|
+
};
|
|
75
|
+
function refineCatalogBindingTargets({ binding, environments, path, ctx, }) {
|
|
76
|
+
if (!binding || typeof binding === 'string')
|
|
77
|
+
return;
|
|
78
|
+
const defaultTarget = environments[0];
|
|
79
|
+
for (const target of Object.keys(binding.by_target)) {
|
|
80
|
+
if (environments.includes(target) && target !== defaultTarget)
|
|
81
|
+
continue;
|
|
82
|
+
ctx.addIssue({
|
|
83
|
+
code: 'custom',
|
|
84
|
+
path: [...path, 'by_target', target],
|
|
85
|
+
message: `catalog target '${target}' must be a non-default declared environment`,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
for (const target of environments.slice(1)) {
|
|
89
|
+
if (target in binding.by_target)
|
|
90
|
+
continue;
|
|
91
|
+
ctx.addIssue({
|
|
92
|
+
code: 'custom',
|
|
93
|
+
path: [...path, 'by_target'],
|
|
94
|
+
message: `catalog binding must explicitly map non-default environment '${target}'`,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
export const ingestionStageSchema = z.strictObject({
|
|
99
|
+
...envelopeShape,
|
|
100
|
+
type: z.literal('ingestion'),
|
|
101
|
+
...ingestionBodyShape,
|
|
102
|
+
});
|
|
103
|
+
export const transformationStageSchema = z.strictObject({
|
|
104
|
+
...envelopeShape,
|
|
105
|
+
type: z.literal('transformation'),
|
|
106
|
+
...transformationBodyShape,
|
|
107
|
+
});
|
|
108
|
+
export const servingStageSchema = z.strictObject({
|
|
109
|
+
...envelopeShape,
|
|
110
|
+
type: z.literal('serving'),
|
|
111
|
+
...servingBodyShape,
|
|
112
|
+
});
|
|
113
|
+
/**
|
|
114
|
+
* A full stage spec: envelope + typed body, discriminated on `type`.
|
|
115
|
+
* The single source of truth for spec shapes — all TS types are inferred.
|
|
116
|
+
*/
|
|
117
|
+
export const stageSpecSchema = z
|
|
118
|
+
.discriminatedUnion('type', [ingestionStageSchema, transformationStageSchema, servingStageSchema])
|
|
119
|
+
.superRefine((spec, ctx) => {
|
|
120
|
+
// Symbolic-references-only invariant: reject literal credentials, webhook
|
|
121
|
+
// URLs, and connection strings anywhere in the spec. Use the segment
|
|
122
|
+
// array — record keys like `gold.players` contain dots, so splitting the
|
|
123
|
+
// display path would mis-place the issue.
|
|
124
|
+
for (const finding of scanForCredentialLikeStrings(spec)) {
|
|
125
|
+
ctx.addIssue({
|
|
126
|
+
code: 'custom',
|
|
127
|
+
path: [...finding.segments],
|
|
128
|
+
message: finding.reason,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
refineCatalogBindingTargets({
|
|
132
|
+
binding: spec.type === 'transformation'
|
|
133
|
+
? spec.config?.catalog
|
|
134
|
+
: spec.type === 'serving'
|
|
135
|
+
? spec.source.catalog
|
|
136
|
+
: undefined,
|
|
137
|
+
environments: spec.environments,
|
|
138
|
+
path: spec.type === 'serving' ? ['source', 'catalog'] : ['config', 'catalog'],
|
|
139
|
+
ctx,
|
|
140
|
+
});
|
|
141
|
+
if (spec.type === 'transformation') {
|
|
142
|
+
for (const key of ['history_catalog', 'silver_catalog']) {
|
|
143
|
+
refineCatalogBindingTargets({
|
|
144
|
+
binding: spec.config?.[key],
|
|
145
|
+
environments: spec.environments,
|
|
146
|
+
path: ['config', key],
|
|
147
|
+
ctx,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
switch (spec.type) {
|
|
152
|
+
case 'ingestion':
|
|
153
|
+
refineIngestionBody(spec, ctx);
|
|
154
|
+
break;
|
|
155
|
+
case 'transformation':
|
|
156
|
+
refineTransformationBody(spec, ctx);
|
|
157
|
+
break;
|
|
158
|
+
case 'serving':
|
|
159
|
+
refineServingBody(spec, ctx);
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
//# sourceMappingURL=envelope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"envelope.js","sourceRoot":"","sources":["../src/envelope.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A spec failed to parse or validate. `file` is the repo-relative source file
|
|
3
|
+
* and `path` the dotted location within it (`feeds.games.cursor`), so CLI and
|
|
4
|
+
* CI output can point at the exact line of YAML to fix.
|
|
5
|
+
*/
|
|
6
|
+
export declare class SpecDefinitionError extends Error {
|
|
7
|
+
readonly file?: string | undefined;
|
|
8
|
+
readonly path?: string | undefined;
|
|
9
|
+
readonly name = "SpecDefinitionError";
|
|
10
|
+
constructor(message: string, file?: string | undefined, path?: string | undefined);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Enumerable resolution failure codes — the full set of ways
|
|
14
|
+
* `resolveSpec` can fail, so callers (deploy adapter, CLI, registry) can
|
|
15
|
+
* switch on them rather than string-match messages.
|
|
16
|
+
*/
|
|
17
|
+
export declare const RESOLUTION_ERROR_CODES: readonly ["missing_workspace_binding", "missing_credential_binding", "missing_alert_channel_binding", "unknown_target", "invalid_target_facts"];
|
|
18
|
+
export type ResolutionErrorCode = (typeof RESOLUTION_ERROR_CODES)[number];
|
|
19
|
+
/**
|
|
20
|
+
* Structured resolution failure. `code` is machine-readable; `subject` names
|
|
21
|
+
* the symbolic reference or target involved (e.g. the credential family that
|
|
22
|
+
* has no binding).
|
|
23
|
+
*/
|
|
24
|
+
export declare class SpecResolutionError extends Error {
|
|
25
|
+
readonly code: ResolutionErrorCode;
|
|
26
|
+
readonly subject?: string | undefined;
|
|
27
|
+
readonly name = "SpecResolutionError";
|
|
28
|
+
constructor(code: ResolutionErrorCode, message: string, subject?: string | undefined);
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAK1C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM;IALxB,SAAkB,IAAI,yBAAwB;gBAG5C,OAAO,EAAE,MAAM,EACN,IAAI,CAAC,EAAE,MAAM,YAAA,EACb,IAAI,CAAC,EAAE,MAAM,YAAA;CAUzB;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,iJAMzB,CAAA;AAEV,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEzE;;;;GAIG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAI1C,QAAQ,CAAC,IAAI,EAAE,mBAAmB;IAElC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM;IAL3B,SAAkB,IAAI,yBAAwB;gBAGnC,IAAI,EAAE,mBAAmB,EAClC,OAAO,EAAE,MAAM,EACN,OAAO,CAAC,EAAE,MAAM,YAAA;CAI5B"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A spec failed to parse or validate. `file` is the repo-relative source file
|
|
3
|
+
* and `path` the dotted location within it (`feeds.games.cursor`), so CLI and
|
|
4
|
+
* CI output can point at the exact line of YAML to fix.
|
|
5
|
+
*/
|
|
6
|
+
export class SpecDefinitionError extends Error {
|
|
7
|
+
file;
|
|
8
|
+
path;
|
|
9
|
+
name = 'SpecDefinitionError';
|
|
10
|
+
constructor(message, file, path) {
|
|
11
|
+
super(file
|
|
12
|
+
? `${file}${path ? ` (${path})` : ''}: ${message}`
|
|
13
|
+
: path
|
|
14
|
+
? `${path}: ${message}`
|
|
15
|
+
: message);
|
|
16
|
+
this.file = file;
|
|
17
|
+
this.path = path;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Enumerable resolution failure codes — the full set of ways
|
|
22
|
+
* `resolveSpec` can fail, so callers (deploy adapter, CLI, registry) can
|
|
23
|
+
* switch on them rather than string-match messages.
|
|
24
|
+
*/
|
|
25
|
+
export const RESOLUTION_ERROR_CODES = [
|
|
26
|
+
'missing_workspace_binding',
|
|
27
|
+
'missing_credential_binding',
|
|
28
|
+
'missing_alert_channel_binding',
|
|
29
|
+
'unknown_target',
|
|
30
|
+
'invalid_target_facts',
|
|
31
|
+
];
|
|
32
|
+
/**
|
|
33
|
+
* Structured resolution failure. `code` is machine-readable; `subject` names
|
|
34
|
+
* the symbolic reference or target involved (e.g. the credential family that
|
|
35
|
+
* has no binding).
|
|
36
|
+
*/
|
|
37
|
+
export class SpecResolutionError extends Error {
|
|
38
|
+
code;
|
|
39
|
+
subject;
|
|
40
|
+
name = 'SpecResolutionError';
|
|
41
|
+
constructor(code, message, subject) {
|
|
42
|
+
super(message);
|
|
43
|
+
this.code = code;
|
|
44
|
+
this.subject = subject;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAKjC;IACA;IALO,IAAI,GAAG,qBAAqB,CAAA;IAE9C,YACE,OAAe,EACN,IAAa,EACb,IAAa;QAEtB,KAAK,CACH,IAAI;YACF,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,EAAE;YAClD,CAAC,CAAC,IAAI;gBACJ,CAAC,CAAC,GAAG,IAAI,KAAK,OAAO,EAAE;gBACvB,CAAC,CAAC,OAAO,CACd,CAAA;QATQ,SAAI,GAAJ,IAAI,CAAS;QACb,SAAI,GAAJ,IAAI,CAAS;IASxB,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,2BAA2B;IAC3B,4BAA4B;IAC5B,+BAA+B;IAC/B,gBAAgB;IAChB,sBAAsB;CACd,CAAA;AAIV;;;;GAIG;AACH,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAIjC;IAEA;IALO,IAAI,GAAG,qBAAqB,CAAA;IAE9C,YACW,IAAyB,EAClC,OAAe,EACN,OAAgB;QAEzB,KAAK,CAAC,OAAO,CAAC,CAAA;QAJL,SAAI,GAAJ,IAAI,CAAqB;QAEzB,YAAO,GAAP,OAAO,CAAS;IAG3B,CAAC;CACF"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type ColumnMap, type ColumnsOrRef } from './columns.js';
|
|
2
|
+
import type { StageSpec } from './envelope.js';
|
|
3
|
+
/**
|
|
4
|
+
* Edge extraction for graph validation: which assets a stage consumes and
|
|
5
|
+
* which stages its schedule chains off. Pure lookups shared by reference
|
|
6
|
+
* resolution, trigger-target validation, and cycle detection.
|
|
7
|
+
*/
|
|
8
|
+
export interface ConsumedReference {
|
|
9
|
+
/** Logical asset id the reference points at. */
|
|
10
|
+
readonly id: string;
|
|
11
|
+
readonly producerStage: string;
|
|
12
|
+
/** Column names the consumer narrows to (undefined = whole asset). */
|
|
13
|
+
readonly columns?: readonly string[];
|
|
14
|
+
readonly loose: boolean;
|
|
15
|
+
readonly path: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function consumedReferences(spec: StageSpec): ConsumedReference[];
|
|
18
|
+
/** `after:` scheduling targets — transformation `trigger.after[]` and serving `trigger.after`. */
|
|
19
|
+
export declare function triggerTargets(spec: StageSpec): string[];
|
|
20
|
+
/** Stages a stage depends on (graph edges for cycle detection). */
|
|
21
|
+
export declare function upstreamStages(spec: StageSpec): string[];
|
|
22
|
+
/** Columns when resolved; undefined for an unresolved ref (reported as `unresolved_schema_ref`). */
|
|
23
|
+
export declare const softColumns: (columns: ColumnsOrRef) => ColumnMap | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* Columns positions still holding a `schema_ref` — loaded specs never have
|
|
26
|
+
* any (the loader resolves them); direct SDK callers get a structured
|
|
27
|
+
* `unresolved_schema_ref` finding instead of an exception, and the affected
|
|
28
|
+
* column checks degrade to skipped.
|
|
29
|
+
*/
|
|
30
|
+
export declare function unresolvedSchemaRefs(spec: StageSpec): Array<{
|
|
31
|
+
path: string;
|
|
32
|
+
ref: string;
|
|
33
|
+
}>;
|
|
34
|
+
//# sourceMappingURL=graph-references.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-references.d.ts","sourceRoot":"","sources":["../src/graph-references.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAA;AAC7E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAE9C;;;;GAIG;AAEH,MAAM,WAAW,iBAAiB;IAChC,gDAAgD;IAChD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,sEAAsE;IACtE,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,SAAS,GAAG,iBAAiB,EAAE,CA8BvE;AAED,kGAAkG;AAClG,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,EAAE,CAIxD;AAED,mEAAmE;AACnE,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,EAAE,CAKxD;AAED,oGAAoG;AACpG,eAAO,MAAM,WAAW,GAAI,SAAS,YAAY,KAAG,SAAS,GAAG,SACpB,CAAA;AAE5C;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,GAAG,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAkB1F"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { isLakebaseCdfInput } from './bodies/transformation.js';
|
|
2
|
+
import { isSchemaRef } from './columns.js';
|
|
3
|
+
export function consumedReferences(spec) {
|
|
4
|
+
if (spec.type === 'transformation') {
|
|
5
|
+
const references = [];
|
|
6
|
+
spec.inputs.forEach((input, index) => {
|
|
7
|
+
if (isLakebaseCdfInput(input))
|
|
8
|
+
return;
|
|
9
|
+
const asset = input.feed ?? input.output;
|
|
10
|
+
// Shape validation guarantees exactly one of feed/output.
|
|
11
|
+
if (asset === undefined)
|
|
12
|
+
return;
|
|
13
|
+
references.push({
|
|
14
|
+
id: `${input.stage}.${asset}`,
|
|
15
|
+
producerStage: input.stage,
|
|
16
|
+
columns: input.columns,
|
|
17
|
+
loose: input.declared_loose === true,
|
|
18
|
+
path: `inputs.${index}`,
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
return references;
|
|
22
|
+
}
|
|
23
|
+
if (spec.type === 'serving') {
|
|
24
|
+
if (spec.source.external)
|
|
25
|
+
return [];
|
|
26
|
+
return [
|
|
27
|
+
{
|
|
28
|
+
id: `${spec.source.stage}.${spec.source.output}`,
|
|
29
|
+
producerStage: spec.source.stage,
|
|
30
|
+
loose: false,
|
|
31
|
+
path: 'source',
|
|
32
|
+
},
|
|
33
|
+
];
|
|
34
|
+
}
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
/** `after:` scheduling targets — transformation `trigger.after[]` and serving `trigger.after`. */
|
|
38
|
+
export function triggerTargets(spec) {
|
|
39
|
+
if (spec.type === 'transformation')
|
|
40
|
+
return spec.trigger.after ?? [];
|
|
41
|
+
if (spec.type === 'serving' && spec.trigger)
|
|
42
|
+
return [spec.trigger.after];
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
/** Stages a stage depends on (graph edges for cycle detection). */
|
|
46
|
+
export function upstreamStages(spec) {
|
|
47
|
+
const upstream = new Set();
|
|
48
|
+
for (const reference of consumedReferences(spec))
|
|
49
|
+
upstream.add(reference.producerStage);
|
|
50
|
+
for (const target of triggerTargets(spec))
|
|
51
|
+
upstream.add(target);
|
|
52
|
+
return [...upstream];
|
|
53
|
+
}
|
|
54
|
+
/** Columns when resolved; undefined for an unresolved ref (reported as `unresolved_schema_ref`). */
|
|
55
|
+
export const softColumns = (columns) => isSchemaRef(columns) ? undefined : columns;
|
|
56
|
+
/**
|
|
57
|
+
* Columns positions still holding a `schema_ref` — loaded specs never have
|
|
58
|
+
* any (the loader resolves them); direct SDK callers get a structured
|
|
59
|
+
* `unresolved_schema_ref` finding instead of an exception, and the affected
|
|
60
|
+
* column checks degrade to skipped.
|
|
61
|
+
*/
|
|
62
|
+
export function unresolvedSchemaRefs(spec) {
|
|
63
|
+
const unresolved = [];
|
|
64
|
+
if (spec.type === 'transformation') {
|
|
65
|
+
for (const [asset, output] of Object.entries(spec.outputs)) {
|
|
66
|
+
if (isSchemaRef(output.columns)) {
|
|
67
|
+
unresolved.push({ path: `outputs.${asset}.columns`, ref: output.columns.schema_ref });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
spec.inputs.forEach((input, index) => {
|
|
71
|
+
if (isLakebaseCdfInput(input) && isSchemaRef(input.columns)) {
|
|
72
|
+
unresolved.push({ path: `inputs.${index}.columns`, ref: input.columns.schema_ref });
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
if (spec.type === 'serving' && isSchemaRef(spec.projection.columns)) {
|
|
77
|
+
unresolved.push({ path: 'projection.columns', ref: spec.projection.columns.schema_ref });
|
|
78
|
+
}
|
|
79
|
+
return unresolved;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=graph-references.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-references.js","sourceRoot":"","sources":["../src/graph-references.ts"],"names":[],"mappings":"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"}
|
package/dist/graph.d.ts
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { type PostgresSnapshotBindings } from './snapshot-transport.js';
|
|
3
|
+
import { type OrmContractCatalog } from './orm-satisfies.js';
|
|
4
|
+
import type { StageSpec } from './envelope.js';
|
|
5
|
+
/**
|
|
6
|
+
* Offline repo-level graph validation: a Pipeline's stages form a DAG through
|
|
7
|
+
* declared inputs/outputs. `validateSpecGraph` resolves references, enforces
|
|
8
|
+
* single-writer-per-physical-asset, rejects cycles, and runs column checks —
|
|
9
|
+
* with ZERO I/O, so the CI gate can run without network or database.
|
|
10
|
+
*/
|
|
11
|
+
export declare const GRAPH_FINDING_CODES: readonly ["snapshot_source_shape_mismatch", "duplicate_stage_id", "single_writer_violation", "unresolved_reference", "unresolved_trigger_target", "cycle_detected", "column_not_produced", "projection_column_missing", "projection_incompatible", "sync_mode_incompatible", "no_inputs_declared", "unresolved_schema_ref", "orm_contract_unavailable", "orm_contract_hash_mismatch", "orm_contract_pk_mismatch", "orm_contract_incompatible", "serving_source_catalog_mismatch"];
|
|
12
|
+
export type GraphFindingCode = (typeof GRAPH_FINDING_CODES)[number];
|
|
13
|
+
export interface GraphFinding {
|
|
14
|
+
readonly code: GraphFindingCode;
|
|
15
|
+
readonly severity: 'error' | 'warning';
|
|
16
|
+
readonly message: string;
|
|
17
|
+
/** Stage the finding is attached to (usually the consumer). */
|
|
18
|
+
readonly stage?: string;
|
|
19
|
+
/** Logical asset id (`<stage>.<asset>`) involved. */
|
|
20
|
+
readonly asset?: string;
|
|
21
|
+
/** Consumer stages affected (breaking-change reporting). */
|
|
22
|
+
readonly consumers?: readonly string[];
|
|
23
|
+
/** Near-miss candidates for unresolved references. */
|
|
24
|
+
readonly suggestions?: readonly string[];
|
|
25
|
+
/** Stage cycle, in order, for cycle_detected. */
|
|
26
|
+
readonly cycle_path?: readonly string[];
|
|
27
|
+
}
|
|
28
|
+
export interface GraphValidationResult {
|
|
29
|
+
readonly ok: boolean;
|
|
30
|
+
readonly findings: readonly GraphFinding[];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Cross-Pipeline references resolve against a registry **asset export**
|
|
34
|
+
* supplied by the caller — keeps the SDK offline-capable. Keys are logical
|
|
35
|
+
* asset ids (`<stage>.<asset>`, e.g. `billing-silver.silver.coding_usage`).
|
|
36
|
+
*
|
|
37
|
+
* Evolution contract: `schema_version` is the explicit format version — the
|
|
38
|
+
* registry bumps it on breaking export changes and consumers reject versions
|
|
39
|
+
* they don't understand. Objects stay STRICT in v1 (unknown keys are a
|
|
40
|
+
* version bump, never silently ignored), so producers can't leak fields the
|
|
41
|
+
* gate doesn't validate.
|
|
42
|
+
*/
|
|
43
|
+
export declare const externalAssetsExportSchema: z.ZodObject<{
|
|
44
|
+
schema_version: z.ZodLiteral<1>;
|
|
45
|
+
assets: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
46
|
+
columns: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
47
|
+
type: z.ZodUnion<readonly [z.ZodEnum<{
|
|
48
|
+
string: "string";
|
|
49
|
+
boolean: "boolean";
|
|
50
|
+
uuid: "uuid";
|
|
51
|
+
int: "int";
|
|
52
|
+
long: "long";
|
|
53
|
+
numeric: "numeric";
|
|
54
|
+
double: "double";
|
|
55
|
+
timestamp: "timestamp";
|
|
56
|
+
date: "date";
|
|
57
|
+
json: "json";
|
|
58
|
+
}>, z.ZodEnum<{
|
|
59
|
+
float: "float";
|
|
60
|
+
timestamp_ntz: "timestamp_ntz";
|
|
61
|
+
array: "array";
|
|
62
|
+
map: "map";
|
|
63
|
+
struct: "struct";
|
|
64
|
+
binary: "binary";
|
|
65
|
+
}>, z.ZodString]>;
|
|
66
|
+
nullable: z.ZodDefault<z.ZodBoolean>;
|
|
67
|
+
key: z.ZodDefault<z.ZodBoolean>;
|
|
68
|
+
domain: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
|
|
69
|
+
description: z.ZodOptional<z.ZodString>;
|
|
70
|
+
on_violation: z.ZodDefault<z.ZodEnum<{
|
|
71
|
+
fail: "fail";
|
|
72
|
+
quarantine: "quarantine";
|
|
73
|
+
warn: "warn";
|
|
74
|
+
}>>;
|
|
75
|
+
}, z.core.$strict>>>;
|
|
76
|
+
}, z.core.$strict>>;
|
|
77
|
+
}, z.core.$strict>;
|
|
78
|
+
export type ExternalAssetsExport = z.infer<typeof externalAssetsExportSchema>;
|
|
79
|
+
/** Check physical ownership across local and already deployed stages. */
|
|
80
|
+
export declare function validateWriteOwnership(stages: readonly StageSpec[], options?: Pick<ValidateSpecGraphOptions, 'catalog' | 'deployTarget' | 'postgresSnapshotBindings'> & {
|
|
81
|
+
readonly externalStages?: readonly StageSpec[];
|
|
82
|
+
}): GraphFinding[];
|
|
83
|
+
export interface ValidateSpecGraphOptions {
|
|
84
|
+
readonly postgresSnapshotBindings?: PostgresSnapshotBindings;
|
|
85
|
+
/**
|
|
86
|
+
* Active ORM synced-table contracts keyed by `namespace.table`. When a
|
|
87
|
+
* serving stage declares `satisfies`, this catalog is required — omitting
|
|
88
|
+
* it (or missing the entry) is a graph error so drift checks never fail
|
|
89
|
+
* open. Offline CI supplies `orm-contracts.json` or `--orm-contracts`;
|
|
90
|
+
* production deploy plans load via `loadOrmContractCatalog`.
|
|
91
|
+
*/
|
|
92
|
+
readonly ormContracts?: OrmContractCatalog;
|
|
93
|
+
/**
|
|
94
|
+
* Deploy-target UC catalog. When set, transformation single-writer keys
|
|
95
|
+
* are `<publish-catalog>.<asset>` (publish catalog = `config.catalog` or
|
|
96
|
+
* this value) so an unpinned writer and a writer pinned to the deploy
|
|
97
|
+
* catalog collide. Omit for offline validate without a target.
|
|
98
|
+
*/
|
|
99
|
+
readonly catalog?: string;
|
|
100
|
+
/** Deploy target used to select target-aware catalog bindings. */
|
|
101
|
+
readonly deployTarget?: string;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Validate a Pipeline's stage graph offline. `externalAssets` (a registry
|
|
105
|
+
* export) resolves cross-Pipeline references; without it, every reference
|
|
106
|
+
* must resolve in-repo. Zero I/O.
|
|
107
|
+
*
|
|
108
|
+
* Pass `options.ormContracts` to enforce serving `satisfies:` against active
|
|
109
|
+
* ORM synced-table contracts (SEQ-2499).
|
|
110
|
+
*/
|
|
111
|
+
export declare function validateSpecGraph(definitions: readonly StageSpec[], externalAssets?: ExternalAssetsExport, options?: ValidateSpecGraphOptions): GraphValidationResult;
|
|
112
|
+
//# sourceMappingURL=graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAgD,KAAK,wBAAwB,EAAE,MAAM,yBAAyB,CAAA;AAcrH,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAE9C;;;;;GAKG;AAEH,eAAO,MAAM,mBAAmB,mdAkBtB,CAAA;AAEV,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEnE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAA;IAC/B,QAAQ,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAA;IACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,+DAA+D;IAC/D,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,qDAAqD;IACrD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,4DAA4D;IAC5D,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACtC,sDAAsD;IACtD,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACxC,iDAAiD;IACjD,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CACxC;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAA;IACpB,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAA;CAC3C;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAQrC,CAAA;AAEF,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAA;AAiO7E,yEAAyE;AACzE,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,SAAS,SAAS,EAAE,EAC5B,OAAO,CAAC,EAAE,IAAI,CAAC,wBAAwB,EAAE,SAAS,GAAG,cAAc,GAAG,0BAA0B,CAAC,GAAG;IAClG,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,SAAS,EAAE,CAAA;CAC/C,GACA,YAAY,EAAE,CAMhB;AAsDD,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,wBAAwB,CAAC,EAAE,wBAAwB,CAAA;IAC5D;;;;;;OAMG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,kBAAkB,CAAA;IAC1C;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,kEAAkE;IAClE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAC/B;AAsND;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,SAAS,SAAS,EAAE,EACjC,cAAc,CAAC,EAAE,oBAAoB,EACrC,OAAO,CAAC,EAAE,wBAAwB,GACjC,qBAAqB,CAsEvB"}
|