ingestron 0.17.6 → 0.17.8

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,29 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.17.8
4
+
5
+ - Pin core 0.12.14. Bridge routes: a connection with `route: bridge` lands a
6
+ source on one platform (such as ADF) for a flow on another (such as
7
+ Databricks); `check` shows it as one route and suggests it when the native
8
+ route is billed separately. `check` now works on projects combining ADF and
9
+ Databricks flows.
10
+ - `ingestron discover` drafts data contracts from what a source offers, before
11
+ you write them: through the portable connector (also for native and bridge
12
+ connections that name a package), or from a platform metadata export with
13
+ `--from`.
14
+ - Official short names `stripe`, `sharepoint`, `onedrive`, `s3`, `gcs`, `sftp`,
15
+ `salesforce`, `hubspot` and `jira`.
16
+
17
+ ## 0.17.7
18
+
19
+ - Pin core 0.12.13. Connections can name a source `kind` and a `route`
20
+ (`portable` or `native`); a native connection is generated by the provider's
21
+ own ingestion standard, with no silent fallback. `check` lists each flow's
22
+ source, route and reference record (licence, cost, access, maturity) and the
23
+ other routes available. Stale reference records are flagged.
24
+ - Official short names `postgresql`, `mysql` and `oracle` for the new database
25
+ connectors.
26
+
3
27
  ## 0.17.6
4
28
 
5
29
  - Pin core 0.12.12. Providers can declare where each engine's rules are enforced,
@@ -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.12
78
+ ### @ingestron/core@0.12.14
79
79
 
80
80
  Declared licence: Apache-2.0
81
81
 
@@ -61,6 +61,39 @@ function runQualityLine(flows) {
61
61
  .join(", ")}${warned.length > 5 ? ", …" : ""}`
62
62
  : ", all passed"}.`;
63
63
  }
64
+ // Source routes from core (PB-064); absent with older core versions.
65
+ const costLabel = {
66
+ none: "no extra cost",
67
+ included: "included in platform pricing",
68
+ "separately-billed": "billed separately",
69
+ };
70
+ function routeLabel(route) {
71
+ const r = route?.reference;
72
+ const via = route?.route === "native"
73
+ ? `native on ${clean(route.configuration)} via ${(route.standards ?? []).map(clean).join(", ")}`
74
+ : route?.route === "bridge"
75
+ ? `bridge: lands on ${clean(route.via)}, ingests on ${clean(route.configuration)} via ${(route.standards ?? []).map(clean).join(" → ")}`
76
+ : `portable ${clean(route?.package ?? "connector")} on ${clean(route?.configuration)}`;
77
+ if (!r)
78
+ return `${via} [no reference record]`;
79
+ const stale = Date.now() - new Date(`${r.verified}T00:00:00Z`).getTime() >
80
+ 180 * 86_400_000;
81
+ return `${via} [${clean(r.maturity)}, ${costLabel[r.cost?.model] ?? clean(r.cost?.model)}${stale ? `, record checked ${clean(r.verified)}` : ""}]`;
82
+ }
83
+ function sourceLines(sources) {
84
+ if (!Array.isArray(sources) || !sources.length)
85
+ return "";
86
+ return ("\nSources:" +
87
+ sources
88
+ .slice(0, 20)
89
+ .map((s) => `\n ${clean(s.flow)}: ${clean(s.connection)} (${clean(s.kind)}) ${routeLabel(s.selected)}` +
90
+ (s.alternative
91
+ ? `\n Also available: ${routeLabel(s.alternative)}`
92
+ : ""))
93
+ .join("") +
94
+ (sources.length > 20 ? `\n … ${sources.length - 20} more` : "") +
95
+ "\nUse --json for every route with documentation, licence, cost and access.");
96
+ }
64
97
  function pluginLabel(reference) {
65
98
  for (const [name, entry] of Object.entries(officialPlugins)) {
66
99
  const prefixes = [
@@ -140,7 +173,8 @@ export function terminal(result, verbose = false, args = {}) {
140
173
  return value.mode === "draft"
141
174
  ? `Draft configuration checked (${value.flows} flows).\n${value.pending.length} unresolved inputs. Strict build readiness has not been checked.`
142
175
  : `Project checks passed${value.nodes === undefined ? "" : ` (${value.nodes} planned nodes)`}.\nValidation is local; no platform connection was tested.` +
143
- dataProductLines(value.dataProducts, value.quality);
176
+ dataProductLines(value.dataProducts, value.quality) +
177
+ sourceLines(value.sources);
144
178
  case "doctor":
145
179
  return `Project ${clean(value.project)} (${clean(value.environment)})\n${value.pending.length} unresolved inputs.\n${clean(value.platformAccess)}\nNext: ${clean(value.next)}`;
146
180
  case "runtime_prepare":
@@ -149,6 +183,24 @@ export function terminal(result, verbose = false, args = {}) {
149
183
  .map((f) => `\n ${clean(f.flow)}: Python ${clean(f.pythonVersion ?? "3.12")} (${f.reused ? "reused" : "prepared"})`)
150
184
  .join("") +
151
185
  `\nUse ingestron run status ${clean(value.id)} --verbose for environment paths and details.`);
186
+ case "discover":
187
+ return (`Discovered ${clean(value.flow)} (${clean(value.route)}):` +
188
+ (value.tables ?? [])
189
+ .map((t) => `\n ${clean(t.table)}: ${Number(t.fields)} fields → ${clean(t.file)}` +
190
+ (t.keys?.length
191
+ ? ` (source keys: ${t.keys.map(clean).join(", ")})`
192
+ : "") +
193
+ (t.skipped ?? [])
194
+ .slice(0, 10)
195
+ .map((s) => `\n skipped ${clean(s.name)}: ${clean(s.reason)}`)
196
+ .join(""))
197
+ .join("") +
198
+ (value.files ?? []).map((f) => `\n wrote ${clean(f)}`).join("") +
199
+ (value.review ?? [])
200
+ .slice(0, 10)
201
+ .map((r) => `\n review: ${clean(r)}`)
202
+ .join("") +
203
+ `\nNext: ${clean(value.next)}`);
152
204
  case "run":
153
205
  case "run_status":
154
206
  return `Run ${clean(value.id)}: ${clean(value.status)} (${clean(value.action)}).\nTarget: ${clean(value.configuration)}; flows: ${value.flows.map(clean).join(", ")}.${runQualityLine(value.result?.flows)}\nUse ingestron run status ${clean(value.id)} to inspect the receipt.`;
@@ -25,24 +25,96 @@ export declare const officialPlugins: {
25
25
  readonly path: "connectors/files/connector.yaml";
26
26
  readonly tagPrefix: "files-";
27
27
  };
28
+ readonly gcs: {
29
+ readonly kind: "connector";
30
+ readonly repository: "ingestron/connectors";
31
+ readonly path: "connectors/gcs/connector.yaml";
32
+ readonly tagPrefix: "gcs-";
33
+ };
28
34
  readonly github: {
29
35
  readonly kind: "connector";
30
36
  readonly repository: "ingestron/connectors";
31
37
  readonly path: "connectors/github/connector.yaml";
32
38
  readonly tagPrefix: "github-";
33
39
  };
40
+ readonly hubspot: {
41
+ readonly kind: "connector";
42
+ readonly repository: "ingestron/connectors";
43
+ readonly path: "connectors/hubspot/connector.yaml";
44
+ readonly tagPrefix: "hubspot-";
45
+ };
46
+ readonly jira: {
47
+ readonly kind: "connector";
48
+ readonly repository: "ingestron/connectors";
49
+ readonly path: "connectors/jira/connector.yaml";
50
+ readonly tagPrefix: "jira-";
51
+ };
34
52
  readonly local: {
35
53
  readonly kind: "provider";
36
54
  readonly repository: "ingestron/provider-local";
37
55
  readonly path: "plugin/provider.yaml";
38
56
  readonly tagPrefix: "";
39
57
  };
58
+ readonly mysql: {
59
+ readonly kind: "connector";
60
+ readonly repository: "ingestron/connectors";
61
+ readonly path: "connectors/mysql/connector.yaml";
62
+ readonly tagPrefix: "mysql-";
63
+ };
64
+ readonly onedrive: {
65
+ readonly kind: "connector";
66
+ readonly repository: "ingestron/connectors";
67
+ readonly path: "connectors/onedrive/connector.yaml";
68
+ readonly tagPrefix: "onedrive-";
69
+ };
70
+ readonly oracle: {
71
+ readonly kind: "connector";
72
+ readonly repository: "ingestron/connectors";
73
+ readonly path: "connectors/oracle/connector.yaml";
74
+ readonly tagPrefix: "oracle-";
75
+ };
76
+ readonly postgresql: {
77
+ readonly kind: "connector";
78
+ readonly repository: "ingestron/connectors";
79
+ readonly path: "connectors/postgresql/connector.yaml";
80
+ readonly tagPrefix: "postgresql-";
81
+ };
82
+ readonly s3: {
83
+ readonly kind: "connector";
84
+ readonly repository: "ingestron/connectors";
85
+ readonly path: "connectors/s3/connector.yaml";
86
+ readonly tagPrefix: "s3-";
87
+ };
88
+ readonly salesforce: {
89
+ readonly kind: "connector";
90
+ readonly repository: "ingestron/connectors";
91
+ readonly path: "connectors/salesforce/connector.yaml";
92
+ readonly tagPrefix: "salesforce-";
93
+ };
94
+ readonly sftp: {
95
+ readonly kind: "connector";
96
+ readonly repository: "ingestron/connectors";
97
+ readonly path: "connectors/sftp/connector.yaml";
98
+ readonly tagPrefix: "sftp-";
99
+ };
100
+ readonly sharepoint: {
101
+ readonly kind: "connector";
102
+ readonly repository: "ingestron/connectors";
103
+ readonly path: "connectors/sharepoint/connector.yaml";
104
+ readonly tagPrefix: "sharepoint-";
105
+ };
40
106
  readonly "sql-server": {
41
107
  readonly kind: "connector";
42
108
  readonly repository: "ingestron/connectors";
43
109
  readonly path: "connectors/sql-server/connector.yaml";
44
110
  readonly tagPrefix: "sql-server-";
45
111
  };
112
+ readonly stripe: {
113
+ readonly kind: "connector";
114
+ readonly repository: "ingestron/connectors";
115
+ readonly path: "connectors/stripe/connector.yaml";
116
+ readonly tagPrefix: "stripe-";
117
+ };
46
118
  };
47
119
  export declare function officialName(reference: string): {
48
120
  name: keyof typeof officialPlugins;
@@ -27,24 +27,96 @@ export const officialPlugins = {
27
27
  path: "connectors/files/connector.yaml",
28
28
  tagPrefix: "files-",
29
29
  },
30
+ gcs: {
31
+ kind: "connector",
32
+ repository: "ingestron/connectors",
33
+ path: "connectors/gcs/connector.yaml",
34
+ tagPrefix: "gcs-",
35
+ },
30
36
  github: {
31
37
  kind: "connector",
32
38
  repository: "ingestron/connectors",
33
39
  path: "connectors/github/connector.yaml",
34
40
  tagPrefix: "github-",
35
41
  },
42
+ hubspot: {
43
+ kind: "connector",
44
+ repository: "ingestron/connectors",
45
+ path: "connectors/hubspot/connector.yaml",
46
+ tagPrefix: "hubspot-",
47
+ },
48
+ jira: {
49
+ kind: "connector",
50
+ repository: "ingestron/connectors",
51
+ path: "connectors/jira/connector.yaml",
52
+ tagPrefix: "jira-",
53
+ },
36
54
  local: {
37
55
  kind: "provider",
38
56
  repository: "ingestron/provider-local",
39
57
  path: "plugin/provider.yaml",
40
58
  tagPrefix: "",
41
59
  },
60
+ mysql: {
61
+ kind: "connector",
62
+ repository: "ingestron/connectors",
63
+ path: "connectors/mysql/connector.yaml",
64
+ tagPrefix: "mysql-",
65
+ },
66
+ onedrive: {
67
+ kind: "connector",
68
+ repository: "ingestron/connectors",
69
+ path: "connectors/onedrive/connector.yaml",
70
+ tagPrefix: "onedrive-",
71
+ },
72
+ oracle: {
73
+ kind: "connector",
74
+ repository: "ingestron/connectors",
75
+ path: "connectors/oracle/connector.yaml",
76
+ tagPrefix: "oracle-",
77
+ },
78
+ postgresql: {
79
+ kind: "connector",
80
+ repository: "ingestron/connectors",
81
+ path: "connectors/postgresql/connector.yaml",
82
+ tagPrefix: "postgresql-",
83
+ },
84
+ s3: {
85
+ kind: "connector",
86
+ repository: "ingestron/connectors",
87
+ path: "connectors/s3/connector.yaml",
88
+ tagPrefix: "s3-",
89
+ },
90
+ salesforce: {
91
+ kind: "connector",
92
+ repository: "ingestron/connectors",
93
+ path: "connectors/salesforce/connector.yaml",
94
+ tagPrefix: "salesforce-",
95
+ },
96
+ sftp: {
97
+ kind: "connector",
98
+ repository: "ingestron/connectors",
99
+ path: "connectors/sftp/connector.yaml",
100
+ tagPrefix: "sftp-",
101
+ },
102
+ sharepoint: {
103
+ kind: "connector",
104
+ repository: "ingestron/connectors",
105
+ path: "connectors/sharepoint/connector.yaml",
106
+ tagPrefix: "sharepoint-",
107
+ },
42
108
  "sql-server": {
43
109
  kind: "connector",
44
110
  repository: "ingestron/connectors",
45
111
  path: "connectors/sql-server/connector.yaml",
46
112
  tagPrefix: "sql-server-",
47
113
  },
114
+ stripe: {
115
+ kind: "connector",
116
+ repository: "ingestron/connectors",
117
+ path: "connectors/stripe/connector.yaml",
118
+ tagPrefix: "stripe-",
119
+ },
48
120
  };
49
121
  const catalogueUrl = "https://raw.githubusercontent.com/ingestron/connectors/main/catalogue.json";
50
122
  const stable = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/;
@@ -185,6 +185,21 @@ export function workflowCommands(app, host) {
185
185
  ...options,
186
186
  ...(secretsFile ? { envFile: secretsFile } : {}),
187
187
  }));
188
+ app
189
+ .command("discover")
190
+ .description("List every field a flow's source offers and write draft contracts for review")
191
+ .requiredOption("--flow <id>", "Ingestion flow to discover")
192
+ .option("--from <file>", "Use a source catalogue or exported metadata rows instead of reading the source")
193
+ .option("--out <directory>", "Directory for draft contracts", "contracts")
194
+ .option("--local <configuration>", "Local provider configuration used for native or bridge connections")
195
+ .option("--accept-keys", "Mark the source's primary keys in the drafts")
196
+ .option("--python <path>", "Optional Python 3.12 bootstrap override")
197
+ .option("--secrets-file <file>", "Project-relative dotenv file; only declared secret names are passed")
198
+ .action(({ secretsFile, acceptKeys, ...options }) => run("discover", {
199
+ ...options,
200
+ acceptKeys: !!acceptKeys,
201
+ ...(secretsFile ? { envFile: secretsFile } : {}),
202
+ }));
188
203
  execution
189
204
  .command("status <id>")
190
205
  .description("Read the durable local run receipt")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ingestron",
3
- "version": "0.17.6",
3
+ "version": "0.17.8",
4
4
  "type": "module",
5
5
  "description": "Build repeatable data pipelines from reviewed contracts and versioned standards.",
6
6
  "license": "Apache-2.0",
@@ -40,7 +40,7 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@clack/prompts": "1.7.0",
43
- "@ingestron/core": "0.12.12",
43
+ "@ingestron/core": "0.12.14",
44
44
  "@modelcontextprotocol/sdk": "1.30.0",
45
45
  "commander": "15.0.0",
46
46
  "yaml": "2.9.0"