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 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. Build the public source:
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.15.1.tgz
39
+ npm install --global ./build/release/ingestron-0.16.1.tgz
33
40
  ingestron --version
34
41
  ```
35
42
 
36
- This source release prepares the npm package named `ingestron`; it does not claim
37
- that the same CLI version is already published on npm. Its core dependency is the
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
 
@@ -75,7 +75,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
75
75
  SOFTWARE.
76
76
  ```
77
77
 
78
- ### @ingestron/core@0.12.4
78
+ ### @ingestron/core@0.12.6
79
79
 
80
80
  Declared licence: Apache-2.0
81
81
 
@@ -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.15.1",
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.4",
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
- "scripts": {
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
+ }