ingestron 0.15.1 → 0.16.2
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/CHANGELOG.md +21 -0
- package/README.md +11 -5
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/build/cli/cli/index.js +79 -1
- package/build/cli/cli/workflow-commands.js +11 -0
- package/package.json +20 -17
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.16.2
|
|
4
|
+
|
|
5
|
+
- Pin core 0.12.6 so mixed local and native-target projects validate correctly.
|
|
6
|
+
- Add a JSON-stdin operation boundary for Studio hosts, with explicit write,
|
|
7
|
+
download and execution permissions and a bounded request size.
|
|
8
|
+
|
|
9
|
+
## 0.16.1
|
|
10
|
+
|
|
11
|
+
- Add `contract scaffold` for a minimal draft from a known field.
|
|
12
|
+
- Let `connections flow-add --execution <file>` pass reviewed provider-specific
|
|
13
|
+
execution settings to the core operation.
|
|
14
|
+
- Pin the public core 0.12.5 package for the shared operation contract.
|
|
15
|
+
|
|
16
|
+
## 0.16.0 (private candidate)
|
|
17
|
+
|
|
18
|
+
- Add reviewable `connections add` and `connections flow-add` commands for
|
|
19
|
+
connector-backed project authoring.
|
|
20
|
+
- Add `contract map` for versioned source-field selection and target names using
|
|
21
|
+
saved discovery evidence. Review, approval and execution remain separate.
|
|
22
|
+
- Consume the matching unpublished core 0.12.5 operation contract.
|
|
23
|
+
|
|
3
24
|
## 0.15.1
|
|
4
25
|
|
|
5
26
|
- Pin core 0.12.4 so CLI and MCP accept reusable connections with per-table source selectors; new projects start with short top-level package names.
|
package/README.md
CHANGED
|
@@ -8,9 +8,16 @@ The CLI is a thin application over [`@ingestron/core`](https://github.com/ingest
|
|
|
8
8
|
Providers supply platform-specific generators, connectors and standards. Installing
|
|
9
9
|
the CLI does not install a platform provider or connect to a cloud account.
|
|
10
10
|
|
|
11
|
+
Version 0.16.1 uses core 0.12.5. It adds
|
|
12
|
+
`connections add`, `connections flow-add`, `contract scaffold` and `contract map`
|
|
13
|
+
for reviewable connector/workflow authoring, an editable first contract and
|
|
14
|
+
source-to-target ODCS mapping. `connections flow-add --execution <file>` passes
|
|
15
|
+
reviewed provider execution settings to core. Use a qualified local provider and
|
|
16
|
+
connector release for execution.
|
|
17
|
+
|
|
11
18
|
## Get started
|
|
12
19
|
|
|
13
|
-
Use Node 22.12 or newer, Git and pnpm 10.15.0
|
|
20
|
+
Use Node 22.12 or newer, Git and pnpm 10.15.0:
|
|
14
21
|
|
|
15
22
|
```sh
|
|
16
23
|
git clone https://github.com/ingestron/cli.git
|
|
@@ -29,13 +36,12 @@ To install this checkout's CLI in your terminal:
|
|
|
29
36
|
|
|
30
37
|
```sh
|
|
31
38
|
pnpm pack --pack-destination build/release
|
|
32
|
-
npm install --global ./build/release/ingestron-0.
|
|
39
|
+
npm install --global ./build/release/ingestron-0.16.1.tgz
|
|
33
40
|
ingestron --version
|
|
34
41
|
```
|
|
35
42
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
public, exact version `@ingestron/core@0.12.4`.
|
|
43
|
+
The package name is `ingestron`; its core dependency is the public, exact version
|
|
44
|
+
`@ingestron/core@0.12.5`.
|
|
39
45
|
|
|
40
46
|
Follow the [five-minute quickstart](docs/quickstart.md) for a project you can keep.
|
|
41
47
|
|
package/THIRD_PARTY_NOTICES.md
CHANGED
package/build/cli/cli/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import * as prompts from "@clack/prompts";
|
|
|
4
4
|
import { resolve, basename, dirname } from "node:path";
|
|
5
5
|
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
|
|
6
6
|
import { parseDocument } from "yaml";
|
|
7
|
-
import { execute, executeAsync, } from "@ingestron/core";
|
|
7
|
+
import { execute, executeAsync, operationSchemas, } from "@ingestron/core";
|
|
8
8
|
import { fence } from "@ingestron/core/adapter";
|
|
9
9
|
import { Configuration } from "@ingestron/core/adapter";
|
|
10
10
|
import { check, Problem } from "@ingestron/core/adapter";
|
|
@@ -79,6 +79,38 @@ const run = async (name, args = {}, ctx = context()) => {
|
|
|
79
79
|
: await executeAsync(ctx, name, args);
|
|
80
80
|
print(result, args);
|
|
81
81
|
};
|
|
82
|
+
// Structured host boundary: request bytes are data, never shell arguments.
|
|
83
|
+
app
|
|
84
|
+
.command("operation <name>")
|
|
85
|
+
.description("Invoke a versioned core operation with a JSON request on stdin")
|
|
86
|
+
.option("--allow-write", "Permit this operation to write project files")
|
|
87
|
+
.option("--allow-network", "Permit this operation to download packages")
|
|
88
|
+
.option("--allow-execute", "Permit this operation to execute a local runtime")
|
|
89
|
+
.action(async (name, flags) => {
|
|
90
|
+
check(Object.hasOwn(operationSchemas, name), "OPERATION", "Unknown operation");
|
|
91
|
+
let bytes = 0;
|
|
92
|
+
const chunks = [];
|
|
93
|
+
for await (const chunk of process.stdin) {
|
|
94
|
+
const value = Buffer.from(chunk);
|
|
95
|
+
bytes += value.length;
|
|
96
|
+
check(bytes <= 1024 * 1024, "LIMIT", "Operation request exceeds 1 MiB");
|
|
97
|
+
chunks.push(value);
|
|
98
|
+
}
|
|
99
|
+
let request;
|
|
100
|
+
try {
|
|
101
|
+
request = JSON.parse(Buffer.concat(chunks).toString("utf8") || "{}");
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
throw new Problem("INPUT", "Expected a JSON operation request on stdin");
|
|
105
|
+
}
|
|
106
|
+
const result = await executeAsync({
|
|
107
|
+
...context(),
|
|
108
|
+
allowWrite: !!flags.allowWrite && !opts().dryRun,
|
|
109
|
+
allowNetwork: !!flags.allowNetwork && !opts().dryRun,
|
|
110
|
+
allowExecute: !!flags.allowExecute && !opts().dryRun,
|
|
111
|
+
}, name, request);
|
|
112
|
+
print(result, request);
|
|
113
|
+
});
|
|
82
114
|
function author(name, args, ctx = context()) {
|
|
83
115
|
const result = execute(ctx, name, args);
|
|
84
116
|
return print(!result.ok || opts().dryRun
|
|
@@ -290,6 +322,48 @@ for (const kind of ["activities", "standards", "providers"]) {
|
|
|
290
322
|
const connections = app
|
|
291
323
|
.command("connections")
|
|
292
324
|
.description("Validate and prepare project-defined connector flows without source access");
|
|
325
|
+
connections
|
|
326
|
+
.command("add <id>")
|
|
327
|
+
.description("Register an installed connector as a project connection")
|
|
328
|
+
.requiredOption("--package <alias>", "Configured connector package alias")
|
|
329
|
+
.requiredOption("--source-id <id>", "Non-secret source identity")
|
|
330
|
+
.requiredOption("--tenant-id <id>", "Non-secret tenant identity")
|
|
331
|
+
.option("--binding <id>", "Environment binding for runtime secrets")
|
|
332
|
+
.option("--settings <file>", "Project-relative YAML/JSON settings file")
|
|
333
|
+
.action((id, options) => author("connection_add", {
|
|
334
|
+
id,
|
|
335
|
+
package: options.package,
|
|
336
|
+
sourceId: options.sourceId,
|
|
337
|
+
tenantId: options.tenantId,
|
|
338
|
+
...(options.binding ? { binding: options.binding } : {}),
|
|
339
|
+
settings: options.settings ? readData(options.settings) : {},
|
|
340
|
+
}));
|
|
341
|
+
connections
|
|
342
|
+
.command("flow-add <id>")
|
|
343
|
+
.description("Create a connection-backed ingestion flow")
|
|
344
|
+
.requiredOption("--provider <configuration>", "Configured provider")
|
|
345
|
+
.requiredOption("--connection <id>", "Configured connection")
|
|
346
|
+
.requiredOption("--table <id>", "Output table")
|
|
347
|
+
.requiredOption("--contract <file>", "Project-relative ODCS contract")
|
|
348
|
+
.option("--source <file>", "Project-relative YAML/JSON table source settings")
|
|
349
|
+
.option("--source-path <path>", "Files connector source path")
|
|
350
|
+
.option("--format <format>", "Files connector format")
|
|
351
|
+
.option("--execution <file>", "Project-relative provider execution settings")
|
|
352
|
+
.action((id, options) => {
|
|
353
|
+
check(!!options.source !== !!options.sourcePath, "OPTION", "Choose a source settings file or a source path");
|
|
354
|
+
check(!options.sourcePath || options.format, "OPTION", "A file source needs its format");
|
|
355
|
+
author("connection_flow_add", {
|
|
356
|
+
id,
|
|
357
|
+
provider: options.provider,
|
|
358
|
+
connection: options.connection,
|
|
359
|
+
table: options.table,
|
|
360
|
+
contract: options.contract,
|
|
361
|
+
source: options.source
|
|
362
|
+
? readData(options.source)
|
|
363
|
+
: { path: options.sourcePath, format: options.format },
|
|
364
|
+
...(options.execution ? { execution: readData(options.execution) } : {}),
|
|
365
|
+
});
|
|
366
|
+
});
|
|
293
367
|
connections
|
|
294
368
|
.command("validate <flow>")
|
|
295
369
|
.action((flow) => run("connection_prepare", { flow, validateOnly: true }));
|
|
@@ -495,6 +569,8 @@ app.hook("preAction", (_root, command) => {
|
|
|
495
569
|
"source prepare",
|
|
496
570
|
"source import",
|
|
497
571
|
"plugin configure",
|
|
572
|
+
"connections add",
|
|
573
|
+
"connections flow-add",
|
|
498
574
|
"plugin migrate",
|
|
499
575
|
"config environment add",
|
|
500
576
|
"flow table add",
|
|
@@ -514,6 +590,8 @@ app.hook("preAction", (_root, command) => {
|
|
|
514
590
|
"providers migrate",
|
|
515
591
|
"providers export",
|
|
516
592
|
"contract draft",
|
|
593
|
+
"contract scaffold",
|
|
594
|
+
"contract map",
|
|
517
595
|
"plugin scaffold",
|
|
518
596
|
"plugin pack-add",
|
|
519
597
|
]).has(parts.join(" ")), "OPTION", "--dry-run is supported only by project authoring commands; this command has not run");
|
|
@@ -61,6 +61,13 @@ export function workflowCommands(app, host) {
|
|
|
61
61
|
check(!id || !options.id || id === options.id, "INPUT", "Provide one contract identifier");
|
|
62
62
|
author("contract_create", { ...options, id: id ?? options.id });
|
|
63
63
|
});
|
|
64
|
+
contract
|
|
65
|
+
.command("scaffold <id>")
|
|
66
|
+
.description("Create an editable draft contract from one known field")
|
|
67
|
+
.requiredOption("--table <name>", "Dataset/table name")
|
|
68
|
+
.requiredOption("--field <name>", "First known source field")
|
|
69
|
+
.requiredOption("--type <type>", "Field type: string, integer, number or boolean")
|
|
70
|
+
.action((id, options) => author("contract_scaffold", { id, ...options }));
|
|
64
71
|
contract
|
|
65
72
|
.command("list")
|
|
66
73
|
.description("List authored contracts")
|
|
@@ -74,6 +81,10 @@ export function workflowCommands(app, host) {
|
|
|
74
81
|
.description("Validate full ODCS, including nested schemas")
|
|
75
82
|
.option("--native", "Also check eligibility for flat native table authoring")
|
|
76
83
|
.action((id, options) => run("contract_check", { id, ...options }));
|
|
84
|
+
contract
|
|
85
|
+
.command("map <file>")
|
|
86
|
+
.description("Preview or apply a versioned source-to-contract field mapping draft")
|
|
87
|
+
.action((file) => author("contract_map_fields", readData(file)));
|
|
77
88
|
const flow = app.commands.find((c) => c.name() === "flow");
|
|
78
89
|
flow
|
|
79
90
|
.command("connect <id>")
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ingestron",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Build repeatable data pipelines from reviewed contracts and versioned standards.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -22,9 +22,25 @@
|
|
|
22
22
|
"engines": {
|
|
23
23
|
"node": ">=22.12.0"
|
|
24
24
|
},
|
|
25
|
+
"packageManager": "pnpm@10.15.0",
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "node scripts/clean-build.mjs && tsc",
|
|
28
|
+
"test": "tsx --test --test-concurrency=1 test/unit/*.test.ts test/providers/*.test.ts test/integration/*.test.ts",
|
|
29
|
+
"format": "prettier --write .",
|
|
30
|
+
"format:check": "prettier --check .",
|
|
31
|
+
"secrets:check": "node scripts/secrets.mjs",
|
|
32
|
+
"validate": "pnpm format:check && pnpm build && pnpm test && pnpm examples:check && pnpm secrets:check && pnpm docs:check && pnpm release:check && pnpm package:check",
|
|
33
|
+
"prepack": "pnpm build",
|
|
34
|
+
"package:check": "tsx scripts/package-check.ts",
|
|
35
|
+
"release:check": "node scripts/release-check.mjs",
|
|
36
|
+
"prepublishOnly": "node scripts/release-check.mjs --publish",
|
|
37
|
+
"docs:check": "node scripts/docs-check.mjs",
|
|
38
|
+
"examples:check": "node examples/quickstart.mjs",
|
|
39
|
+
"licences:inventory": "node scripts/licence-inventory.mjs"
|
|
40
|
+
},
|
|
25
41
|
"dependencies": {
|
|
26
42
|
"@clack/prompts": "1.7.0",
|
|
27
|
-
"@ingestron/core": "0.12.
|
|
43
|
+
"@ingestron/core": "0.12.6",
|
|
28
44
|
"@modelcontextprotocol/sdk": "1.30.0",
|
|
29
45
|
"commander": "15.0.0",
|
|
30
46
|
"yaml": "2.9.0"
|
|
@@ -56,18 +72,5 @@
|
|
|
56
72
|
"cli",
|
|
57
73
|
"mcp",
|
|
58
74
|
"code-generation"
|
|
59
|
-
]
|
|
60
|
-
|
|
61
|
-
"build": "node scripts/clean-build.mjs && tsc",
|
|
62
|
-
"test": "tsx --test --test-concurrency=1 test/unit/*.test.ts test/providers/*.test.ts test/integration/*.test.ts",
|
|
63
|
-
"format": "prettier --write .",
|
|
64
|
-
"format:check": "prettier --check .",
|
|
65
|
-
"secrets:check": "node scripts/secrets.mjs",
|
|
66
|
-
"validate": "pnpm format:check && pnpm build && pnpm test && pnpm examples:check && pnpm secrets:check && pnpm docs:check && pnpm release:check && pnpm package:check",
|
|
67
|
-
"package:check": "tsx scripts/package-check.ts",
|
|
68
|
-
"release:check": "node scripts/release-check.mjs",
|
|
69
|
-
"docs:check": "node scripts/docs-check.mjs",
|
|
70
|
-
"examples:check": "node examples/quickstart.mjs",
|
|
71
|
-
"licences:inventory": "node scripts/licence-inventory.mjs"
|
|
72
|
-
}
|
|
73
|
-
}
|
|
75
|
+
]
|
|
76
|
+
}
|