@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
package/README.md
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# @sequenceholdings/pipeline-spec
|
|
2
|
+
|
|
3
|
+
Schema and offline validation support for Sequence Managed Pipeline stage
|
|
4
|
+
specifications.
|
|
5
|
+
|
|
6
|
+
This package is published so `@sequenceholdings/studio-cli` can load its
|
|
7
|
+
pipeline commands in standalone repositories. Its JavaScript module export is
|
|
8
|
+
an internal implementation detail, not a supported public SDK contract. Author
|
|
9
|
+
and validate pipeline repositories through `seq-studio pipeline`.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
Install the CLI and its pipeline-spec peer dependency in the repository that
|
|
14
|
+
owns your pipeline:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pnpm add --save-dev \
|
|
18
|
+
@sequenceholdings/studio-cli \
|
|
19
|
+
@sequenceholdings/pipeline-spec
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Validate a pipeline repository
|
|
23
|
+
|
|
24
|
+
Run validation from the repository root:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pnpm exec seq-studio pipeline validate .
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The validator discovers `*.stage.yml` files recursively. A stage specification
|
|
31
|
+
describes one deployable unit and its inputs, outputs, runtime, ownership, and
|
|
32
|
+
environment policy. For example:
|
|
33
|
+
|
|
34
|
+
```yaml
|
|
35
|
+
schema_version: 1
|
|
36
|
+
stage: ingest-events
|
|
37
|
+
title: Event ingestion
|
|
38
|
+
description: Pulls event records into the bronze landing zone.
|
|
39
|
+
type: ingestion
|
|
40
|
+
owners:
|
|
41
|
+
- data-platform@example.com
|
|
42
|
+
criticality: standard
|
|
43
|
+
environments:
|
|
44
|
+
- staging
|
|
45
|
+
runtime: databricks
|
|
46
|
+
source:
|
|
47
|
+
system: events_api
|
|
48
|
+
credential: events_api_key
|
|
49
|
+
feeds:
|
|
50
|
+
events:
|
|
51
|
+
description: Event records updated since the previous run.
|
|
52
|
+
snapshot_mode: incremental
|
|
53
|
+
natural_key:
|
|
54
|
+
- event_id
|
|
55
|
+
cursor:
|
|
56
|
+
column: updated_at
|
|
57
|
+
format: json
|
|
58
|
+
schedule:
|
|
59
|
+
cron: "0 5 * * *"
|
|
60
|
+
tz: UTC
|
|
61
|
+
entrypoint: src/ingest_events.py
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Credentials are symbolic references such as `events_api_key`; never put secret
|
|
65
|
+
values, tokens, connection strings, or environment-specific URLs in a stage
|
|
66
|
+
specification.
|
|
67
|
+
|
|
68
|
+
## Table and column descriptions
|
|
69
|
+
|
|
70
|
+
Keep bronze source documentation inline with each feed:
|
|
71
|
+
|
|
72
|
+
```yaml
|
|
73
|
+
feeds:
|
|
74
|
+
events:
|
|
75
|
+
description: Event records updated since the previous run.
|
|
76
|
+
columns:
|
|
77
|
+
event_id:
|
|
78
|
+
description: Identifier assigned by the source system.
|
|
79
|
+
updated_at:
|
|
80
|
+
description: Time the source last updated this event.
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Each optional `columns` entry requires a `description` string and does not
|
|
84
|
+
accept types or constraints. The source determines bronze columns and types.
|
|
85
|
+
Description edits change specification provenance, not the data contract.
|
|
86
|
+
After deployment, `seq-studio pipeline schema <assetId> -e <env> --json`
|
|
87
|
+
returns descriptions alongside observed columns when supported by the server.
|
|
88
|
+
|
|
89
|
+
Stage YAML files allow up to 5 MiB; other specification files retain a 1 MiB
|
|
90
|
+
limit. Existing `column_descriptions` and `documentation_ref` declarations
|
|
91
|
+
remain supported; inline `columns.<name>.description` takes precedence.
|
|
92
|
+
|
|
93
|
+
## Validation coverage
|
|
94
|
+
|
|
95
|
+
Offline validation checks:
|
|
96
|
+
|
|
97
|
+
- strict schemas for ingestion, transformation, and serving stages;
|
|
98
|
+
- references between stages, feeds, outputs, and triggers;
|
|
99
|
+
- asset column compatibility and contract changes;
|
|
100
|
+
- symbolic credential and webhook references;
|
|
101
|
+
- deterministic specification and contract hashes; and
|
|
102
|
+
- serving-stage compatibility with declared ORM bindings.
|
|
103
|
+
|
|
104
|
+
Validation reports all discoverable issues in one pass so repository authors
|
|
105
|
+
can correct the complete graph before deployment.
|
|
106
|
+
|
|
107
|
+
## Compatibility
|
|
108
|
+
|
|
109
|
+
- Node.js 20 or newer
|
|
110
|
+
- package versioning follows the release consumed by `seq-studio`
|
|
111
|
+
- the root JavaScript export may change without a standalone public SDK
|
|
112
|
+
deprecation cycle
|
|
113
|
+
|
|
114
|
+
This package is distributed under the license declared in `package.json`.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { Criticality, IngestionStageSpec, StageSpecInput } from '../envelope.js';
|
|
2
|
+
import type { FeedFormat, FeedSpec, IngestionRuntime, ScheduleSpec, SnapshotMode } from '../bodies/ingestion.js';
|
|
3
|
+
/** Scalar extraction hints allowed on a feed (matches feedSchema.extraction). */
|
|
4
|
+
export type ExtractionHint = string | number | boolean;
|
|
5
|
+
/**
|
|
6
|
+
* One source table → one ingestion stage with a single feed. This is the
|
|
7
|
+
* recommended JH / SilverLake authoring shape (SEQ-2485): N sibling stages
|
|
8
|
+
* instead of N feeds in one stage.
|
|
9
|
+
*/
|
|
10
|
+
export interface IngestionTableDefinition {
|
|
11
|
+
/** Source-side table identifier (e.g. iSeries DDMAST). */
|
|
12
|
+
table: string;
|
|
13
|
+
/** Override stage slug; default `${stagePrefix}-${tableSlug}`. */
|
|
14
|
+
stage?: string;
|
|
15
|
+
/** Override feed name; default is the lowercased table slug. */
|
|
16
|
+
feed?: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
columns?: Readonly<Record<string, {
|
|
19
|
+
readonly description: string;
|
|
20
|
+
}>>;
|
|
21
|
+
column_descriptions?: Readonly<Record<string, string>>;
|
|
22
|
+
documentation_ref?: string;
|
|
23
|
+
snapshot_mode: SnapshotMode;
|
|
24
|
+
natural_key: readonly string[];
|
|
25
|
+
cursor?: {
|
|
26
|
+
column: string;
|
|
27
|
+
encoding?: string;
|
|
28
|
+
};
|
|
29
|
+
format?: FeedFormat;
|
|
30
|
+
pii?: FeedSpec['pii'];
|
|
31
|
+
extraction?: Readonly<Record<string, ExtractionHint>>;
|
|
32
|
+
}
|
|
33
|
+
/** Shared envelope + runtime config replicated onto every generated stage. */
|
|
34
|
+
export interface PerTableIngestionAuthoring {
|
|
35
|
+
/** Prefix for generated stage slugs (`silverlake` → `silverlake-ddmast`). */
|
|
36
|
+
stagePrefix: string;
|
|
37
|
+
runtime: IngestionRuntime;
|
|
38
|
+
entrypoint: string;
|
|
39
|
+
owners: readonly string[];
|
|
40
|
+
criticality: Criticality;
|
|
41
|
+
environments: readonly string[];
|
|
42
|
+
/** Applied to every stage unless overridden per table. */
|
|
43
|
+
titleTemplate?: string;
|
|
44
|
+
descriptionTemplate?: string;
|
|
45
|
+
slos?: IngestionStageSpec['slos'];
|
|
46
|
+
alerts?: IngestionStageSpec['alerts'];
|
|
47
|
+
runbook?: string;
|
|
48
|
+
remediation_posture?: IngestionStageSpec['remediation_posture'];
|
|
49
|
+
worker?: IngestionStageSpec['worker'];
|
|
50
|
+
source?: IngestionStageSpec['source'];
|
|
51
|
+
schedule?: ScheduleSpec;
|
|
52
|
+
freshness_slo?: string;
|
|
53
|
+
retention?: string;
|
|
54
|
+
tables: readonly IngestionTableDefinition[];
|
|
55
|
+
}
|
|
56
|
+
export interface GeneratedStageFile {
|
|
57
|
+
readonly stage: string;
|
|
58
|
+
readonly filename: string;
|
|
59
|
+
readonly spec: StageSpecInput;
|
|
60
|
+
readonly yaml: string;
|
|
61
|
+
}
|
|
62
|
+
/** Lowercase identifier from a source table name (DDMAST → ddmast). */
|
|
63
|
+
export declare function tableToSlug(table: string): string;
|
|
64
|
+
/** Kebab-case stage slug from prefix + table (`silverlake`, `DDMAST` → `silverlake-ddmast`). */
|
|
65
|
+
export declare function perTableStageSlug(stagePrefix: string, table: string): string;
|
|
66
|
+
/**
|
|
67
|
+
* Expand a typed authoring definition into one validated-shaped stage spec per
|
|
68
|
+
* table. Does not run Zod parse — callers should `stageSpecSchema.parse` each
|
|
69
|
+
* spec (or run `seq-studio pipeline validate` on the emitted directory).
|
|
70
|
+
*/
|
|
71
|
+
export declare function buildPerTableIngestionStages(authoring: PerTableIngestionAuthoring): readonly StageSpecInput[];
|
|
72
|
+
/** Build stage specs and their on-disk filenames (`<stage>.stage.yml`). */
|
|
73
|
+
export declare function generatePerTableStageFiles(authoring: PerTableIngestionAuthoring): readonly GeneratedStageFile[];
|
|
74
|
+
//# sourceMappingURL=per-table-ingestion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"per-table-ingestion.d.ts","sourceRoot":"","sources":["../../src/authoring/per-table-ingestion.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { workerCapacityGroup } from '../bodies/ingestion.js';
|
|
2
|
+
import { dumpStageYaml } from './yaml.js';
|
|
3
|
+
const TABLE_SLUG_PATTERN = /[^a-z0-9]+/g;
|
|
4
|
+
/** Lowercase identifier from a source table name (DDMAST → ddmast). */
|
|
5
|
+
export function tableToSlug(table) {
|
|
6
|
+
const slug = table.trim().toLowerCase().replace(TABLE_SLUG_PATTERN, '_').replace(/^_|_$/g, '');
|
|
7
|
+
if (!slug)
|
|
8
|
+
throw new Error(`table '${table}' does not yield a valid slug`);
|
|
9
|
+
return slug;
|
|
10
|
+
}
|
|
11
|
+
/** Kebab-case stage slug from prefix + table (`silverlake`, `DDMAST` → `silverlake-ddmast`). */
|
|
12
|
+
export function perTableStageSlug(stagePrefix, table) {
|
|
13
|
+
return `${stagePrefix}-${tableToSlug(table)}`;
|
|
14
|
+
}
|
|
15
|
+
function renderTemplate(template, table, feed) {
|
|
16
|
+
return template.replace(/\{\{table\}\}/g, table).replace(/\{\{feed\}\}/g, feed);
|
|
17
|
+
}
|
|
18
|
+
function buildFeed(table) {
|
|
19
|
+
const feedName = table.feed ?? tableToSlug(table.table);
|
|
20
|
+
const extraction = {
|
|
21
|
+
table: table.table,
|
|
22
|
+
...table.extraction,
|
|
23
|
+
};
|
|
24
|
+
const feed = {
|
|
25
|
+
snapshot_mode: table.snapshot_mode,
|
|
26
|
+
natural_key: [...table.natural_key],
|
|
27
|
+
pii: table.pii ?? 'none',
|
|
28
|
+
format: table.format ?? 'parquet',
|
|
29
|
+
extraction,
|
|
30
|
+
};
|
|
31
|
+
if (table.description)
|
|
32
|
+
feed.description = table.description;
|
|
33
|
+
if (table.columns)
|
|
34
|
+
feed.columns = Object.fromEntries(Object.entries(table.columns).map(([name, column]) => [name, { ...column }]));
|
|
35
|
+
if (table.column_descriptions)
|
|
36
|
+
feed.column_descriptions = { ...table.column_descriptions };
|
|
37
|
+
if (table.documentation_ref)
|
|
38
|
+
feed.documentation_ref = table.documentation_ref;
|
|
39
|
+
if (table.cursor)
|
|
40
|
+
feed.cursor = { ...table.cursor };
|
|
41
|
+
return { [feedName]: feed };
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* The group N sibling stages contend on. Grouping by the shared upstream — the
|
|
45
|
+
* worker machine + data source for edge workers, the source system for API
|
|
46
|
+
* pulls — is what keeps ~150 per-table stages from hammering one ODBC
|
|
47
|
+
* connection or one rate-limited API the moment their crons align. A per-stage
|
|
48
|
+
* group would be a declaration that they are independent, which they are not.
|
|
49
|
+
* Falls back to the stage slug only when a stage has no shared upstream to name.
|
|
50
|
+
*/
|
|
51
|
+
function capacityGroup(authoring, stage) {
|
|
52
|
+
if (authoring.worker)
|
|
53
|
+
return workerCapacityGroup(authoring.worker);
|
|
54
|
+
if (authoring.source)
|
|
55
|
+
return authoring.source.system;
|
|
56
|
+
return stage.replace(/-/g, '_');
|
|
57
|
+
}
|
|
58
|
+
function buildSchedule(schedule, group) {
|
|
59
|
+
if (!schedule)
|
|
60
|
+
return undefined;
|
|
61
|
+
const policy = schedule.policy;
|
|
62
|
+
return {
|
|
63
|
+
...schedule,
|
|
64
|
+
// An explicitly authored group always wins — coordinated maintenance
|
|
65
|
+
// windows and deliberately isolated tables both need the override.
|
|
66
|
+
policy: policy
|
|
67
|
+
? { ...policy, exclusion_group: policy.exclusion_group ?? group }
|
|
68
|
+
: { singleton: true, exclusion_group: group },
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Expand a typed authoring definition into one validated-shaped stage spec per
|
|
73
|
+
* table. Does not run Zod parse — callers should `stageSpecSchema.parse` each
|
|
74
|
+
* spec (or run `seq-studio pipeline validate` on the emitted directory).
|
|
75
|
+
*/
|
|
76
|
+
export function buildPerTableIngestionStages(authoring) {
|
|
77
|
+
if (authoring.tables.length === 0) {
|
|
78
|
+
throw new Error('buildPerTableIngestionStages: tables must be non-empty');
|
|
79
|
+
}
|
|
80
|
+
const titleTemplate = authoring.titleTemplate ?? '{{table}} extraction';
|
|
81
|
+
const descriptionTemplate = authoring.descriptionTemplate ?? 'Ingest {{table}} into bronze via {{feed}}.';
|
|
82
|
+
return authoring.tables.map((table) => {
|
|
83
|
+
const stage = table.stage ?? perTableStageSlug(authoring.stagePrefix, table.table);
|
|
84
|
+
const feedName = table.feed ?? tableToSlug(table.table);
|
|
85
|
+
return {
|
|
86
|
+
schema_version: 1,
|
|
87
|
+
stage,
|
|
88
|
+
title: renderTemplate(titleTemplate, table.table, feedName),
|
|
89
|
+
description: renderTemplate(descriptionTemplate, table.table, feedName),
|
|
90
|
+
type: 'ingestion',
|
|
91
|
+
owners: [...authoring.owners],
|
|
92
|
+
criticality: authoring.criticality,
|
|
93
|
+
...(authoring.slos ? { slos: authoring.slos } : {}),
|
|
94
|
+
...(authoring.alerts ? { alerts: authoring.alerts } : {}),
|
|
95
|
+
...(authoring.runbook ? { runbook: authoring.runbook } : {}),
|
|
96
|
+
...(authoring.remediation_posture
|
|
97
|
+
? { remediation_posture: authoring.remediation_posture }
|
|
98
|
+
: {}),
|
|
99
|
+
environments: [...authoring.environments],
|
|
100
|
+
runtime: authoring.runtime,
|
|
101
|
+
...(authoring.worker ? { worker: authoring.worker } : {}),
|
|
102
|
+
...(authoring.source ? { source: authoring.source } : {}),
|
|
103
|
+
feeds: buildFeed(table),
|
|
104
|
+
...(authoring.schedule
|
|
105
|
+
? { schedule: buildSchedule(authoring.schedule, capacityGroup(authoring, stage)) }
|
|
106
|
+
: {}),
|
|
107
|
+
...(authoring.freshness_slo ? { freshness_slo: authoring.freshness_slo } : {}),
|
|
108
|
+
...(authoring.retention ? { retention: authoring.retention } : {}),
|
|
109
|
+
entrypoint: authoring.entrypoint,
|
|
110
|
+
};
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
/** Build stage specs and their on-disk filenames (`<stage>.stage.yml`). */
|
|
114
|
+
export function generatePerTableStageFiles(authoring) {
|
|
115
|
+
return buildPerTableIngestionStages(authoring).map((spec) => ({
|
|
116
|
+
stage: spec.stage,
|
|
117
|
+
filename: `${spec.stage}.stage.yml`,
|
|
118
|
+
spec,
|
|
119
|
+
yaml: dumpStageYaml(spec),
|
|
120
|
+
}));
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=per-table-ingestion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"per-table-ingestion.js","sourceRoot":"","sources":["../../src/authoring/per-table-ingestion.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yaml.d.ts","sourceRoot":"","sources":["../../src/authoring/yaml.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQpD"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { dump } from 'js-yaml';
|
|
2
|
+
/**
|
|
3
|
+
* Deterministic YAML for generated stage specs — sorted keys, stable quoting.
|
|
4
|
+
* Same spec object → byte-identical output (golden-friendly).
|
|
5
|
+
*/
|
|
6
|
+
export function dumpStageYaml(value) {
|
|
7
|
+
return dump(value, {
|
|
8
|
+
sortKeys: true,
|
|
9
|
+
lineWidth: 120,
|
|
10
|
+
noRefs: true,
|
|
11
|
+
quotingType: '"',
|
|
12
|
+
forceQuotes: false,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=yaml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yaml.js","sourceRoot":"","sources":["../../src/authoring/yaml.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAE9B;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,IAAI,CAAC,KAAK,EAAE;QACjB,QAAQ,EAAE,IAAI;QACd,SAAS,EAAE,GAAG;QACd,MAAM,EAAE,IAAI;QACZ,WAAW,EAAE,GAAG;QAChB,WAAW,EAAE,KAAK;KACnB,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ResolutionErrorCode } from './errors.js';
|
|
2
|
+
import type { StageSpec } from './envelope.js';
|
|
3
|
+
import { type TargetFactsInput } from './resolve.js';
|
|
4
|
+
export interface BindingGap {
|
|
5
|
+
readonly code: ResolutionErrorCode;
|
|
6
|
+
readonly message: string;
|
|
7
|
+
readonly symbolic?: string;
|
|
8
|
+
readonly stage?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Collect target-binding gaps for one portable spec without throwing.
|
|
12
|
+
* `resolveSpec` remains fail-fast for execute paths; plan aggregates via
|
|
13
|
+
* {@link collectPipelineBindingGaps}.
|
|
14
|
+
*/
|
|
15
|
+
export declare function collectBindingGaps(spec: StageSpec, facts: TargetFactsInput): BindingGap[];
|
|
16
|
+
/** Aggregate binding gaps across every stage spec in a deploy unit. */
|
|
17
|
+
export declare function collectPipelineBindingGaps({ specs, facts, }: {
|
|
18
|
+
specs: readonly StageSpec[];
|
|
19
|
+
facts: TargetFactsInput;
|
|
20
|
+
}): BindingGap[];
|
|
21
|
+
//# sourceMappingURL=binding-gaps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binding-gaps.d.ts","sourceRoot":"","sources":["../src/binding-gaps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAEvE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAA;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CACxB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,gBAAgB,GAAG,UAAU,EAAE,CAoEzF;AAED,uEAAuE;AACvE,wBAAgB,0BAA0B,CAAC,EACzC,KAAK,EACL,KAAK,GACN,EAAE;IACD,KAAK,EAAE,SAAS,SAAS,EAAE,CAAA;IAC3B,KAAK,EAAE,gBAAgB,CAAA;CACxB,GAAG,UAAU,EAAE,CAEf"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { targetFactsSchema } from './resolve.js';
|
|
2
|
+
/**
|
|
3
|
+
* Collect target-binding gaps for one portable spec without throwing.
|
|
4
|
+
* `resolveSpec` remains fail-fast for execute paths; plan aggregates via
|
|
5
|
+
* {@link collectPipelineBindingGaps}.
|
|
6
|
+
*/
|
|
7
|
+
export function collectBindingGaps(spec, facts) {
|
|
8
|
+
const parsedFacts = targetFactsSchema.safeParse(facts);
|
|
9
|
+
if (!parsedFacts.success) {
|
|
10
|
+
return [
|
|
11
|
+
{
|
|
12
|
+
code: 'invalid_target_facts',
|
|
13
|
+
message: `invalid target facts: ${parsedFacts.error.issues
|
|
14
|
+
.map((issue) => `${issue.path.join('.')}: ${issue.message}`)
|
|
15
|
+
.join('; ')}`,
|
|
16
|
+
stage: spec.stage,
|
|
17
|
+
},
|
|
18
|
+
];
|
|
19
|
+
}
|
|
20
|
+
const target = parsedFacts.data;
|
|
21
|
+
if (!spec.environments.includes(target.deploy_target)) {
|
|
22
|
+
return [
|
|
23
|
+
{
|
|
24
|
+
code: 'unknown_target',
|
|
25
|
+
message: `stage '${spec.stage}' does not declare environment '${target.deploy_target}' (declared: ${spec.environments.join(', ')})`,
|
|
26
|
+
symbolic: target.deploy_target,
|
|
27
|
+
stage: spec.stage,
|
|
28
|
+
},
|
|
29
|
+
];
|
|
30
|
+
}
|
|
31
|
+
const gaps = [];
|
|
32
|
+
if (!target.workspace_id) {
|
|
33
|
+
gaps.push({
|
|
34
|
+
code: 'missing_workspace_binding',
|
|
35
|
+
message: `target '${target.deploy_target}' has no workspace binding — every deploy target must bind exactly one workspace_id (no fallback)`,
|
|
36
|
+
symbolic: target.deploy_target,
|
|
37
|
+
stage: spec.stage,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
if (spec.type === 'ingestion' && spec.source?.credential) {
|
|
41
|
+
if (!target.credential_bindings[spec.source.credential]) {
|
|
42
|
+
gaps.push({
|
|
43
|
+
code: 'missing_credential_binding',
|
|
44
|
+
message: `target '${target.deploy_target}' has no credential binding for symbolic name '${spec.source.credential}'`,
|
|
45
|
+
symbolic: spec.source.credential,
|
|
46
|
+
stage: spec.stage,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (spec.type === 'serving' && spec.transport?.kind === 'postgres_snapshot_landing_v1') {
|
|
51
|
+
const binding = target.postgres_snapshot_bindings?.[spec.transport.binding];
|
|
52
|
+
if (!binding || binding.database !== spec.transport.database)
|
|
53
|
+
gaps.push({
|
|
54
|
+
code: 'invalid_target_facts', stage: spec.stage, symbolic: spec.transport.binding,
|
|
55
|
+
message: `snapshot transport binding '${spec.transport.binding}' is missing or names a different database`,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
for (const channel of spec.alerts?.channels ?? []) {
|
|
59
|
+
if (!target.alert_channel_bindings[channel]) {
|
|
60
|
+
gaps.push({
|
|
61
|
+
code: 'missing_alert_channel_binding',
|
|
62
|
+
message: `target '${target.deploy_target}' has no alert channel binding for symbolic name '${channel}'`,
|
|
63
|
+
symbolic: channel,
|
|
64
|
+
stage: spec.stage,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return gaps;
|
|
69
|
+
}
|
|
70
|
+
/** Aggregate binding gaps across every stage spec in a deploy unit. */
|
|
71
|
+
export function collectPipelineBindingGaps({ specs, facts, }) {
|
|
72
|
+
return specs.flatMap((spec) => collectBindingGaps(spec, facts));
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=binding-gaps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binding-gaps.js","sourceRoot":"","sources":["../src/binding-gaps.ts"],"names":[],"mappings":"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"}
|