ingestron 0.17.7 → 1.0.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.
Files changed (273) hide show
  1. package/NOTICE +3 -5
  2. package/README.md +26 -74
  3. package/THIRD_PARTY_NOTICES +148 -0
  4. package/dist/main.js +29188 -0
  5. package/package.json +32 -65
  6. package/project-recipes/adf/connections/adls-gen2.yaml +7 -0
  7. package/project-recipes/adf/connections/amazon-rds-oracle.yaml +9 -0
  8. package/project-recipes/adf/connections/amazon-rds-sqlserver.yaml +9 -0
  9. package/project-recipes/adf/connections/amazon-redshift.yaml +10 -0
  10. package/project-recipes/adf/connections/amazon-s3.yaml +8 -0
  11. package/project-recipes/adf/connections/azure-blob.yaml +7 -0
  12. package/project-recipes/adf/connections/azure-cosmos-db-mongodb.yaml +8 -0
  13. package/project-recipes/adf/connections/azure-cosmos-db-nosql.yaml +8 -0
  14. package/project-recipes/adf/connections/azure-cosmos-postgresql.yaml +10 -0
  15. package/project-recipes/adf/connections/azure-data-explorer.yaml +8 -0
  16. package/project-recipes/adf/connections/azure-databricks-delta.yaml +9 -0
  17. package/project-recipes/adf/connections/azure-files.yaml +8 -0
  18. package/project-recipes/adf/connections/azure-mysql.yaml +7 -0
  19. package/project-recipes/adf/connections/azure-postgresql.yaml +10 -0
  20. package/project-recipes/adf/connections/azure-sql-database.yaml +9 -0
  21. package/project-recipes/adf/connections/azure-sql-managed-instance.yaml +9 -0
  22. package/project-recipes/adf/connections/azure-synapse.yaml +9 -0
  23. package/project-recipes/adf/connections/azure-table-storage.yaml +7 -0
  24. package/project-recipes/adf/connections/cassandra.yaml +9 -0
  25. package/project-recipes/adf/connections/dataverse.yaml +9 -0
  26. package/project-recipes/adf/connections/db2.yaml +7 -0
  27. package/project-recipes/adf/connections/dynamics-365.yaml +9 -0
  28. package/project-recipes/adf/connections/dynamics-ax.yaml +11 -0
  29. package/project-recipes/adf/connections/dynamics-crm.yaml +9 -0
  30. package/project-recipes/adf/connections/fabric-lakehouse.yaml +8 -0
  31. package/project-recipes/adf/connections/fabric-warehouse.yaml +9 -0
  32. package/project-recipes/adf/connections/files.yaml +9 -0
  33. package/project-recipes/adf/connections/ftp.yaml +9 -0
  34. package/project-recipes/adf/connections/google-ads.yaml +12 -0
  35. package/project-recipes/adf/connections/google-bigquery.yaml +8 -0
  36. package/project-recipes/adf/connections/google-cloud-storage.yaml +8 -0
  37. package/project-recipes/adf/connections/greenplum.yaml +10 -0
  38. package/project-recipes/adf/connections/hdfs.yaml +9 -0
  39. package/project-recipes/adf/connections/hive.yaml +11 -0
  40. package/project-recipes/adf/connections/http.yaml +7 -0
  41. package/project-recipes/adf/connections/hubspot.yaml +10 -0
  42. package/project-recipes/adf/connections/impala.yaml +11 -0
  43. package/project-recipes/adf/connections/informix.yaml +9 -0
  44. package/project-recipes/adf/connections/jira.yaml +9 -0
  45. package/project-recipes/adf/connections/mariadb.yaml +10 -0
  46. package/project-recipes/adf/connections/microsoft-365.yaml +10 -0
  47. package/project-recipes/adf/connections/microsoft-access.yaml +9 -0
  48. package/project-recipes/adf/connections/mongodb-atlas.yaml +8 -0
  49. package/project-recipes/adf/connections/mongodb.yaml +8 -0
  50. package/project-recipes/adf/connections/mysql.yaml +10 -0
  51. package/project-recipes/adf/connections/netezza.yaml +11 -0
  52. package/project-recipes/adf/connections/odata.yaml +9 -0
  53. package/project-recipes/adf/connections/odbc.yaml +9 -0
  54. package/project-recipes/adf/connections/oracle-cloud-storage.yaml +9 -0
  55. package/project-recipes/adf/connections/oracle.yaml +9 -0
  56. package/project-recipes/adf/connections/postgresql.yaml +10 -0
  57. package/project-recipes/adf/connections/presto.yaml +11 -0
  58. package/project-recipes/adf/connections/quickbooks.yaml +10 -0
  59. package/project-recipes/adf/connections/rest.yaml +12 -0
  60. package/project-recipes/adf/connections/s3-compatible.yaml +9 -0
  61. package/project-recipes/adf/connections/salesforce-service-cloud.yaml +10 -0
  62. package/project-recipes/adf/connections/salesforce.yaml +10 -0
  63. package/project-recipes/adf/connections/sap-bw-mdx.yaml +11 -0
  64. package/project-recipes/adf/connections/sap-bw-open-hub.yaml +11 -0
  65. package/project-recipes/adf/connections/sap-c4c.yaml +9 -0
  66. package/project-recipes/adf/connections/sap-ecc.yaml +9 -0
  67. package/project-recipes/adf/connections/sap-hana.yaml +7 -0
  68. package/project-recipes/adf/connections/sap-table.yaml +11 -0
  69. package/project-recipes/adf/connections/servicenow.yaml +9 -0
  70. package/project-recipes/adf/connections/sftp.yaml +10 -0
  71. package/project-recipes/adf/connections/sharepoint-online-list.yaml +10 -0
  72. package/project-recipes/adf/connections/shopify.yaml +8 -0
  73. package/project-recipes/adf/connections/snowflake.yaml +11 -0
  74. package/project-recipes/adf/connections/spark.yaml +11 -0
  75. package/project-recipes/adf/connections/sqlserver.yaml +9 -0
  76. package/project-recipes/adf/connections/square.yaml +10 -0
  77. package/project-recipes/adf/connections/sybase.yaml +10 -0
  78. package/project-recipes/adf/connections/teradata.yaml +9 -0
  79. package/project-recipes/adf/connections/vertica.yaml +10 -0
  80. package/project-recipes/adf/connections/web-table.yaml +7 -0
  81. package/project-recipes/adf/connections/xero.yaml +10 -0
  82. package/project-recipes/adf/contracts/records.yaml +12 -0
  83. package/project-recipes/adf/contracts/salesforce-account.yaml +12 -0
  84. package/project-recipes/adf/flows/adls-gen2.yaml +14 -0
  85. package/project-recipes/adf/flows/amazon-rds-oracle.yaml +12 -0
  86. package/project-recipes/adf/flows/amazon-rds-sqlserver.yaml +12 -0
  87. package/project-recipes/adf/flows/amazon-redshift.yaml +12 -0
  88. package/project-recipes/adf/flows/amazon-s3.yaml +14 -0
  89. package/project-recipes/adf/flows/azure-blob.yaml +14 -0
  90. package/project-recipes/adf/flows/azure-cosmos-db-mongodb.yaml +12 -0
  91. package/project-recipes/adf/flows/azure-cosmos-db-nosql.yaml +12 -0
  92. package/project-recipes/adf/flows/azure-cosmos-postgresql.yaml +12 -0
  93. package/project-recipes/adf/flows/azure-data-explorer.yaml +13 -0
  94. package/project-recipes/adf/flows/azure-databricks-delta.yaml +15 -0
  95. package/project-recipes/adf/flows/azure-files.yaml +14 -0
  96. package/project-recipes/adf/flows/azure-mysql.yaml +12 -0
  97. package/project-recipes/adf/flows/azure-postgresql.yaml +12 -0
  98. package/project-recipes/adf/flows/azure-sql-database.yaml +12 -0
  99. package/project-recipes/adf/flows/azure-sql-managed-instance.yaml +12 -0
  100. package/project-recipes/adf/flows/azure-synapse.yaml +12 -0
  101. package/project-recipes/adf/flows/azure-table-storage.yaml +12 -0
  102. package/project-recipes/adf/flows/cassandra.yaml +12 -0
  103. package/project-recipes/adf/flows/dataverse.yaml +12 -0
  104. package/project-recipes/adf/flows/db2.yaml +12 -0
  105. package/project-recipes/adf/flows/dynamics-365.yaml +12 -0
  106. package/project-recipes/adf/flows/dynamics-ax.yaml +12 -0
  107. package/project-recipes/adf/flows/dynamics-crm.yaml +12 -0
  108. package/project-recipes/adf/flows/fabric-lakehouse.yaml +14 -0
  109. package/project-recipes/adf/flows/fabric-warehouse.yaml +14 -0
  110. package/project-recipes/adf/flows/files.yaml +14 -0
  111. package/project-recipes/adf/flows/ftp.yaml +14 -0
  112. package/project-recipes/adf/flows/google-ads.yaml +13 -0
  113. package/project-recipes/adf/flows/google-bigquery.yaml +12 -0
  114. package/project-recipes/adf/flows/google-cloud-storage.yaml +14 -0
  115. package/project-recipes/adf/flows/greenplum.yaml +12 -0
  116. package/project-recipes/adf/flows/hdfs.yaml +14 -0
  117. package/project-recipes/adf/flows/hive.yaml +12 -0
  118. package/project-recipes/adf/flows/http.yaml +18 -0
  119. package/project-recipes/adf/flows/hubspot.yaml +12 -0
  120. package/project-recipes/adf/flows/impala.yaml +12 -0
  121. package/project-recipes/adf/flows/informix.yaml +13 -0
  122. package/project-recipes/adf/flows/jira.yaml +12 -0
  123. package/project-recipes/adf/flows/mariadb.yaml +13 -0
  124. package/project-recipes/adf/flows/microsoft-365.yaml +19 -0
  125. package/project-recipes/adf/flows/microsoft-access.yaml +13 -0
  126. package/project-recipes/adf/flows/mongodb-atlas.yaml +12 -0
  127. package/project-recipes/adf/flows/mongodb.yaml +12 -0
  128. package/project-recipes/adf/flows/mysql.yaml +12 -0
  129. package/project-recipes/adf/flows/netezza.yaml +13 -0
  130. package/project-recipes/adf/flows/odata.yaml +12 -0
  131. package/project-recipes/adf/flows/odbc.yaml +13 -0
  132. package/project-recipes/adf/flows/oracle-cloud-storage.yaml +14 -0
  133. package/project-recipes/adf/flows/oracle.yaml +12 -0
  134. package/project-recipes/adf/flows/postgresql.yaml +18 -0
  135. package/project-recipes/adf/flows/presto.yaml +12 -0
  136. package/project-recipes/adf/flows/quickbooks.yaml +12 -0
  137. package/project-recipes/adf/flows/rest.yaml +21 -0
  138. package/project-recipes/adf/flows/s3-compatible.yaml +14 -0
  139. package/project-recipes/adf/flows/salesforce-service-cloud.yaml +12 -0
  140. package/project-recipes/adf/flows/salesforce.yaml +13 -0
  141. package/project-recipes/adf/flows/sap-bw-mdx.yaml +14 -0
  142. package/project-recipes/adf/flows/sap-bw-open-hub.yaml +13 -0
  143. package/project-recipes/adf/flows/sap-c4c.yaml +12 -0
  144. package/project-recipes/adf/flows/sap-ecc.yaml +13 -0
  145. package/project-recipes/adf/flows/sap-hana.yaml +14 -0
  146. package/project-recipes/adf/flows/sap-table.yaml +13 -0
  147. package/project-recipes/adf/flows/servicenow.yaml +12 -0
  148. package/project-recipes/adf/flows/sftp.yaml +14 -0
  149. package/project-recipes/adf/flows/sharepoint-online-list.yaml +12 -0
  150. package/project-recipes/adf/flows/shopify.yaml +12 -0
  151. package/project-recipes/adf/flows/snowflake.yaml +15 -0
  152. package/project-recipes/adf/flows/spark.yaml +12 -0
  153. package/project-recipes/adf/flows/sqlserver.yaml +12 -0
  154. package/project-recipes/adf/flows/square.yaml +13 -0
  155. package/project-recipes/adf/flows/sybase.yaml +13 -0
  156. package/project-recipes/adf/flows/teradata.yaml +12 -0
  157. package/project-recipes/adf/flows/vertica.yaml +12 -0
  158. package/project-recipes/adf/flows/web-table.yaml +14 -0
  159. package/project-recipes/adf/flows/xero.yaml +12 -0
  160. package/project-recipes/adf/platform.yaml +29 -0
  161. package/project-recipes/adf/project.yaml +10 -0
  162. package/project-recipes/adf/sample.yaml +3 -0
  163. package/project-recipes/adf/standard.yaml +15 -0
  164. package/project-templates/kafka/README.md +12 -0
  165. package/project-templates/kafka/connections/events.yaml +8 -0
  166. package/project-templates/kafka/contracts/page_views.yaml +13 -0
  167. package/project-templates/kafka/contracts/purchases.yaml +13 -0
  168. package/project-templates/kafka/flows/events.yaml +10 -0
  169. package/project-templates/kafka/project.yaml +10 -0
  170. package/project-templates/kafka/standard.yaml +4 -0
  171. package/project-templates/kafka/template.yaml +3 -0
  172. package/project-templates/minimal/README.md +10 -0
  173. package/project-templates/minimal/connections/shop.yaml +7 -0
  174. package/project-templates/minimal/contracts/orders.yaml +14 -0
  175. package/project-templates/minimal/flows/orders.yaml +6 -0
  176. package/project-templates/minimal/project.yaml +11 -0
  177. package/project-templates/minimal/standard.yaml +4 -0
  178. package/project-templates/minimal/template.yaml +7 -0
  179. package/project-templates/private-files/README.md +29 -0
  180. package/project-templates/private-files/connections/share.yaml +10 -0
  181. package/project-templates/private-files/contracts/sales.yaml +14 -0
  182. package/project-templates/private-files/contracts/stock.yaml +14 -0
  183. package/project-templates/private-files/flows/stores.yaml +9 -0
  184. package/project-templates/private-files/platform.yaml +11 -0
  185. package/project-templates/private-files/project.yaml +19 -0
  186. package/project-templates/private-files/standard.yaml +11 -0
  187. package/project-templates/private-files/template.yaml +10 -0
  188. package/project-templates/private-sql-server/README.md +25 -0
  189. package/project-templates/private-sql-server/connections/erp.yaml +10 -0
  190. package/project-templates/private-sql-server/contracts/customers.yaml +14 -0
  191. package/project-templates/private-sql-server/contracts/invoices.yaml +15 -0
  192. package/project-templates/private-sql-server/flows/erp.yaml +13 -0
  193. package/project-templates/private-sql-server/platform.yaml +11 -0
  194. package/project-templates/private-sql-server/project.yaml +19 -0
  195. package/project-templates/private-sql-server/standard.yaml +17 -0
  196. package/project-templates/private-sql-server/template.yaml +10 -0
  197. package/project-templates/pyspark/README.md +12 -0
  198. package/project-templates/pyspark/connections/billing.yaml +7 -0
  199. package/project-templates/pyspark/contracts/invoices.yaml +16 -0
  200. package/project-templates/pyspark/contracts/monthly_revenue.yaml +14 -0
  201. package/project-templates/pyspark/flows/billing.yaml +6 -0
  202. package/project-templates/pyspark/project.yaml +11 -0
  203. package/project-templates/pyspark/standard.yaml +4 -0
  204. package/project-templates/pyspark/template.yaml +3 -0
  205. package/project-templates/pyspark/transforms/monthly_revenue.py +10 -0
  206. package/project-templates/pyspark/transforms/monthly_revenue.yaml +10 -0
  207. package/project-templates/retail/README.md +22 -0
  208. package/project-templates/retail/connections/shop.yaml +8 -0
  209. package/project-templates/retail/contracts/customers.yaml +12 -0
  210. package/project-templates/retail/contracts/daily_sales.yaml +19 -0
  211. package/project-templates/retail/contracts/orders.yaml +16 -0
  212. package/project-templates/retail/flows/shop.yaml +18 -0
  213. package/project-templates/retail/platform.yaml +21 -0
  214. package/project-templates/retail/project.yaml +18 -0
  215. package/project-templates/retail/standard.yaml +15 -0
  216. package/project-templates/retail/template.yaml +10 -0
  217. package/project-templates/retail/transforms/daily_sales.sql +7 -0
  218. package/project-templates/retail/transforms/daily_sales.yaml +7 -0
  219. package/project-templates/salesforce/README.md +6 -0
  220. package/project-templates/salesforce/connections/salesforce.yaml +7 -0
  221. package/project-templates/salesforce/contracts/accounts.yaml +13 -0
  222. package/project-templates/salesforce/contracts/opportunities.yaml +14 -0
  223. package/project-templates/salesforce/flows/salesforce.yaml +7 -0
  224. package/project-templates/salesforce/project.yaml +9 -0
  225. package/project-templates/salesforce/standard.yaml +4 -0
  226. package/project-templates/salesforce/template.yaml +3 -0
  227. package/project-templates/sql-server/README.md +17 -0
  228. package/project-templates/sql-server/connections/erp.yaml +8 -0
  229. package/project-templates/sql-server/contracts/customer_balances.yaml +13 -0
  230. package/project-templates/sql-server/contracts/customers.yaml +13 -0
  231. package/project-templates/sql-server/contracts/invoices.yaml +14 -0
  232. package/project-templates/sql-server/flows/erp.yaml +13 -0
  233. package/project-templates/sql-server/platform.yaml +6 -0
  234. package/project-templates/sql-server/project.yaml +13 -0
  235. package/project-templates/sql-server/standard.yaml +9 -0
  236. package/project-templates/sql-server/template.yaml +3 -0
  237. package/project-templates/sql-server/transforms/customer_balances.sql +5 -0
  238. package/project-templates/sql-server/transforms/customer_balances.yaml +6 -0
  239. package/schemas/NOTICE.md +7 -0
  240. package/schemas/connection.schema.yaml +37 -0
  241. package/schemas/flow.schema.yaml +124 -0
  242. package/schemas/odcs-v3.1.0.schema.json +2808 -0
  243. package/schemas/platform.schema.yaml +260 -0
  244. package/schemas/standard.schema.yaml +211 -0
  245. package/schemas/transform.schema.yaml +108 -0
  246. package/templates/apply-contract.py.liquid +58 -0
  247. package/templates/change-data.sql.liquid +20 -0
  248. package/templates/materialised-view.py.liquid +28 -0
  249. package/templates/materialised-view.sql.liquid +4 -0
  250. package/templates/read-files.liquid +7 -0
  251. package/templates/streaming-table.sql.liquid +3 -0
  252. package/templates/table.liquid +17 -0
  253. package/CHANGELOG.md +0 -148
  254. package/SECURITY.md +0 -32
  255. package/THIRD_PARTY_NOTICES.md +0 -3678
  256. package/build/cli/cli/index.d.ts +0 -2
  257. package/build/cli/cli/index.js +0 -685
  258. package/build/cli/cli/operation-worker.d.ts +0 -1
  259. package/build/cli/cli/operation-worker.js +0 -5
  260. package/build/cli/cli/output.d.ts +0 -3
  261. package/build/cli/cli/output.js +0 -226
  262. package/build/cli/cli/plugin-browser.d.ts +0 -14
  263. package/build/cli/cli/plugin-browser.js +0 -74
  264. package/build/cli/cli/plugin-resolution.d.ts +0 -72
  265. package/build/cli/cli/plugin-resolution.js +0 -216
  266. package/build/cli/cli/presentation.d.ts +0 -12
  267. package/build/cli/cli/presentation.js +0 -57
  268. package/build/cli/cli/workflow-commands.d.ts +0 -15
  269. package/build/cli/cli/workflow-commands.js +0 -415
  270. package/build/cli/mcp/index.d.ts +0 -3
  271. package/build/cli/mcp/index.js +0 -67
  272. package/build/cli/version.d.ts +0 -2
  273. package/build/cli/version.js +0 -14
@@ -1 +0,0 @@
1
- export {};
@@ -1,5 +0,0 @@
1
- /** Keep package-network work off the presentation thread so progress reflects
2
- * actual pending work. This worker uses the same JSON operations as MCP/Web. */
3
- import { parentPort, workerData } from "node:worker_threads";
4
- import { executePluginOperation } from "./plugin-resolution.js";
5
- parentPort.postMessage(await executePluginOperation(workerData.context, workerData.operation, workerData.args));
@@ -1,3 +0,0 @@
1
- import type { Result } from "@ingestron/core";
2
- export declare function exitCode(result: Result): number;
3
- export declare function terminal(result: Result, verbose?: boolean, args?: any): string;
@@ -1,226 +0,0 @@
1
- /** Presentation is deliberately separate from operation results. JSON is the
2
- * lossless API; terminal output is bounded, plain text and actionable. Never
3
- * serialise arbitrary plugin data or resolved bindings in the default summary. */
4
- import { friendlyReference } from "@ingestron/core/adapter";
5
- import { stringify } from "yaml";
6
- import { officialPlugins } from "./plugin-resolution.js";
7
- export function exitCode(result) {
8
- if (result.ok)
9
- return 0;
10
- const codes = result.diagnostics.map((d) => d.code);
11
- if (codes.includes("CANCELLED"))
12
- return 130;
13
- if (codes.includes("NOT_IMPLEMENTED"))
14
- return 4;
15
- if (codes.some((c) => ["STALE", "OWNER", "CONFLICT"].includes(c)))
16
- return 5;
17
- if (codes.some((c) => [
18
- "INPUT",
19
- "BINDING",
20
- "CAPABILITY",
21
- "PACKAGE",
22
- "OPTION",
23
- "COMMAND",
24
- "SCHEMA",
25
- ].includes(c)))
26
- return 3;
27
- return 2;
28
- }
29
- const clean = (value) => String(value).replace(/[\u0000-\u001f\u007f-\u009f]/g, " ");
30
- // Data product ownership from ODCS contracts; absent with older core versions.
31
- function dataProductLines(products, quality) {
32
- if (!Array.isArray(products) || !products.length)
33
- return "";
34
- const summary = quality?.summary;
35
- const shown = products.slice(0, 20).map((p) => {
36
- const owners = Array.isArray(p.owners) ? p.owners.map(clean) : [];
37
- return `\n ${clean(p.contract)} ${clean(p.status ?? "no status")} ${owners.length ? `owner ${owners.join(", ")}` : "no owner"}`;
38
- });
39
- const recorded = products.reduce((n, p) => n + Math.max(0, (p.qualityRules ?? 0) - (p.enforcedQualityRules ?? 0)), 0);
40
- return ("\nData products:" +
41
- shown.join("") +
42
- (products.length > 20 ? `\n … ${products.length - 20} more` : "") +
43
- (summary && summary.rules
44
- ? `\nQuality rules: ${summary.rules} (${summary.atLoad} at load, ${summary.afterLoad} after load, ${summary.unsupported} not enforced by the target${summary.documentation ? `, ${summary.documentation} documentation only` : ""}).`
45
- : !summary && recorded
46
- ? `\n${recorded} quality rule(s) are recorded in contracts but not yet enforced.`
47
- : ""));
48
- }
49
- // Quality results recorded by connector runtimes before commit; counts only.
50
- function runQualityLine(flows) {
51
- if (!Array.isArray(flows))
52
- return "";
53
- const rules = flows.flatMap((f) => Array.isArray(f?.quality) ? f.quality : []);
54
- if (!rules.length)
55
- return "";
56
- const warned = rules.filter((r) => r.passed === false);
57
- return `\nQuality rules: ${rules.length} checked before commit${warned.length
58
- ? `; ${warned.length} warning(s): ${warned
59
- .slice(0, 5)
60
- .map((r) => clean(r.id))
61
- .join(", ")}${warned.length > 5 ? ", …" : ""}`
62
- : ", all passed"}.`;
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
- : `portable ${clean(route?.package ?? "connector")} on ${clean(route?.configuration)}`;
75
- if (!r)
76
- return `${via} [no reference record]`;
77
- const stale = Date.now() - new Date(`${r.verified}T00:00:00Z`).getTime() >
78
- 180 * 86_400_000;
79
- return `${via} [${clean(r.maturity)}, ${costLabel[r.cost?.model] ?? clean(r.cost?.model)}${stale ? `, record checked ${clean(r.verified)}` : ""}]`;
80
- }
81
- function sourceLines(sources) {
82
- if (!Array.isArray(sources) || !sources.length)
83
- return "";
84
- return ("\nSources:" +
85
- sources
86
- .slice(0, 20)
87
- .map((s) => `\n ${clean(s.flow)}: ${clean(s.connection)} (${clean(s.kind)}) ${routeLabel(s.selected)}` +
88
- (s.alternative
89
- ? `\n Also available: ${routeLabel(s.alternative)}`
90
- : ""))
91
- .join("") +
92
- (sources.length > 20 ? `\n … ${sources.length - 20} more` : "") +
93
- "\nUse --json for every route with documentation, licence, cost and access.");
94
- }
95
- function pluginLabel(reference) {
96
- for (const [name, entry] of Object.entries(officialPlugins)) {
97
- const prefixes = [
98
- `${entry.repository}/${entry.path}@`,
99
- ...(name === "local" ? [`${entry.repository}@`] : []),
100
- ];
101
- for (const prefix of prefixes)
102
- if (reference.startsWith(prefix)) {
103
- const version = reference.slice(prefix.length);
104
- if (/^\d+\.\d+\.\d+$/.test(version))
105
- return `${name}@${version}`;
106
- }
107
- }
108
- return friendlyReference(reference);
109
- }
110
- function lines(title, items, empty) {
111
- if (!items.length)
112
- return empty;
113
- return `${title} (${items.length})\n${items
114
- .slice(0, 20)
115
- .map((i) => ` ${clean(i)}`)
116
- .join("\n")}${items.length > 20 ? "\n More results available with --json or --verbose." : ""}`;
117
- }
118
- export function terminal(result, verbose = false, args = {}) {
119
- if (!result.ok)
120
- return result.diagnostics
121
- .map((d) => `Error: ${clean(d.message)}${verbose ? ` [${d.code}]` : ""}${d.file ? `\n File: ${clean(d.file)}${clean(d.pointer ?? "")}` : ""}${d.hint ? `\n Next: ${clean(d.hint)}` : ""}`)
122
- .join("\n");
123
- const value = result.result;
124
- if (verbose)
125
- return `${result.operation.replaceAll("_", " ")}\n${typeof value === "string" ? value : stringify(value).trimEnd()}`;
126
- if (value?.apiVersion === "ingestron.change/v1")
127
- return (lines("Proposed file changes", value.changes.map((c) => `${c.before === null ? "Create" : "Update"} ${c.path}`), "No file changes needed.") + "\nPreview only; no files changed.");
128
- if (value?.applied)
129
- return lines("Saved files", value.files, "No file changes needed.");
130
- switch (result.operation) {
131
- case "plugin_browse":
132
- return ((value.length
133
- ? "Installed plugins\n\n" +
134
- value
135
- .map((p) => ` ${clean(p.id).padEnd(13)} ${clean(p.name)} [${clean(p.kindLabel)} · ${clean(p.availability)}]\n ${clean(p.description)}\n ${clean(p.url)}`)
136
- .join("\n\n")
137
- : "No installed plugins match this search.") +
138
- "\n\nInstall a provider: ingestron provider install local\nInstall a connector: ingestron connector install github");
139
- case "plugin_versions":
140
- return (lines(`Versions for ${value.provider}`, value.versions.map((v) => `${v.reference}${v.ambiguous ? " (conflicting tags; select a commit)" : ""}`), "No stable version tags found.") +
141
- "\n\n" +
142
- value.evidence +
143
- "\nInstall: ingestron plugin install <owner/repository>@<version>");
144
- case "packages_install":
145
- return `${value.cached ? "Using cached" : "Installed"} ${args.kind ?? "plugin"} ${clean(pluginLabel(args.reference ?? value.reference ?? "package"))}.\nUse --verbose for the exact reference and licence information.`;
146
- case "packages_list":
147
- return lines("Installed plugins", Object.keys(value.packages).map(pluginLabel), "No plugins installed.\nNext: ingestron provider install local");
148
- case "source_list":
149
- return lines("Sources", value.map((s) => `${s.id} ${s.type}${s.format ? "/" + s.format : ""} ${s.execution}`), "No sources configured.\nNext: ingestron source add <name> --type <type>");
150
- case "source_show":
151
- return `Source ${clean(value.id)}\n Type: ${clean(value.type)}${value.format ? ` (${clean(value.format)})` : ""}\n Execution: ${clean(value.selected.execution)}\n Environment: ${clean(value.selected.environment)}\n Provider: ${clean(value.selected.provider ?? "project default")}\nUse --verbose to inspect connection references.`;
152
- case "contract_list":
153
- return lines("Contracts", value.map((c) => `${c.id} ${c.status} ${c.path}`), "No contracts drafted.\nNext: ingestron contract draft <name> --metadata <file>");
154
- case "contract_show":
155
- return (`Contract ${clean(value.id)} (${clean(value.status)})\n` +
156
- lines("Entities", (value.schema ?? []).map((s) => `${s.physicalName ?? s.name}: ${(s.properties ?? []).length} fields`), "No entities.") +
157
- "\nUse --verbose to review the complete contract.");
158
- case "contract_check":
159
- return `Contract valid: ${clean(value.path)}${value.status === "draft" ? "\nStatus: draft; review business requirements before use." : ""}\n${clean(value.evidence)}`;
160
- case "contract_validate":
161
- return `Contract valid for native table authoring (${value.columns.length} columns).`;
162
- case "inspect":
163
- return lines("Flows", value.flows.map((f) => `${f.id} ${f.kind} ${f.tables.length} tables, ${f.outputs.length} outputs`), "No flows configured.\nNext: ingestron flow add <name> --contract <name> --standard <standard>");
164
- case "flow_show":
165
- return `Flow ${clean(value.id)}\n Kind: ${clean(value.kind)}\n Tables: ${Object.keys(value.tables ?? {})
166
- .map(clean)
167
- .join(", ") || "none"}\n Outputs: ${Object.keys(value.publishes ?? {})
168
- .map(clean)
169
- .join(", ") || "none"}\nUse --verbose to inspect configuration.`;
170
- case "validate":
171
- return value.mode === "draft"
172
- ? `Draft configuration checked (${value.flows} flows).\n${value.pending.length} unresolved inputs. Strict build readiness has not been checked.`
173
- : `Project checks passed${value.nodes === undefined ? "" : ` (${value.nodes} planned nodes)`}.\nValidation is local; no platform connection was tested.` +
174
- dataProductLines(value.dataProducts, value.quality) +
175
- sourceLines(value.sources);
176
- case "doctor":
177
- return `Project ${clean(value.project)} (${clean(value.environment)})\n${value.pending.length} unresolved inputs.\n${clean(value.platformAccess)}\nNext: ${clean(value.next)}`;
178
- case "runtime_prepare":
179
- return (`Runtime ${clean(value.status)} for ${value.flows.map(clean).join(", ")}.` +
180
- (value.result?.flows ?? [])
181
- .map((f) => `\n ${clean(f.flow)}: Python ${clean(f.pythonVersion ?? "3.12")} (${f.reused ? "reused" : "prepared"})`)
182
- .join("") +
183
- `\nUse ingestron run status ${clean(value.id)} --verbose for environment paths and details.`);
184
- case "run":
185
- case "run_status":
186
- 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.`;
187
- case "build":
188
- return `Built ${value.packages?.length ?? 1} project package(s) into ${clean(value.directory)}.\n${clean(value.evidence)}`;
189
- case "generate":
190
- return "Generated native assets.\nUse check --output <directory> to verify local output.";
191
- case "validate_output":
192
- return "Generated output checks passed.\nOwnership and syntax checked locally; no platform connection was tested.";
193
- case "environments":
194
- return lines("Environments", value.available.map((e) => `${e}${e === value.selected ? " (selected)" : ""}`), "No environments configured.");
195
- case "tables":
196
- return lines("Flow tables", value.map((f) => `${f.flow}: ${f.tables.join(", ") || "none"}`), "No tables configured.");
197
- case "catalogue":
198
- return lines(args.kind ?? "Capabilities", value.map((v) => `${v.id}${v.version ? "@" + v.version : ""}${v.description ? " " + v.description : ""}`), `No ${args.kind ?? "capabilities"} available.\nNext: ingestron plugin list`);
199
- case "provider_commands":
200
- return lines("Plugin operations", value.commands.map((c) => `${c.name} ${c.description}`), "No plugin operations available.");
201
- case "plugin_command":
202
- case "provider_command":
203
- return "Plugin operation completed locally.\nUse --json, --verbose or --out to inspect its result.";
204
- case "plan":
205
- return `Local build plan ready (${value.nodes.length} nodes).\nUse --json or --verbose to inspect the plan.`;
206
- case "diff":
207
- return `Local differences: ${value.added.length} added, ${value.changed.length} changed, ${value.removed.length} removed.`;
208
- case "config_explain":
209
- return `Configuration: ${clean(value.path)} (${clean(value.environment)})\nUse --verbose to inspect declared and resolved values.`;
210
- case "resolve":
211
- return (`Project ${clean(value.project.id)} — resolved build configuration\n` +
212
- `Providers: ${Object.keys(value.project.providers?.configurations ?? {})
213
- .map(clean)
214
- .join(", ") || "none"}\n` +
215
- `Connections: ${Object.keys(value.project.connections ?? {})
216
- .map(clean)
217
- .join(", ") || "none"}\n` +
218
- `Flows: ${value.flows.length}; unresolved inputs: ${value.pending.length}.\n` +
219
- "Authored files: ingestron source list; ingestron contract list.\nUse --verbose for resolved configuration and input-file digests.");
220
- case "read":
221
- return value.content;
222
- case "schema":
223
- return "Schema available. Use --json for tools or --verbose to inspect it.";
224
- }
225
- return `${result.operation.replaceAll("_", " ")} completed.\nUse --json for structured data or --verbose for details.`;
226
- }
@@ -1,14 +0,0 @@
1
- interface Browser {
2
- select(message: string, options: {
3
- value: string;
4
- label: string;
5
- hint?: string;
6
- }[]): Promise<string>;
7
- search(): Promise<string>;
8
- details(text: string): void;
9
- }
10
- /** Read-only navigation of installed plugin metadata. */
11
- export declare function browsePlugins(ui: Browser, query?: string, initialKind?: string, filters?: {
12
- engine?: string;
13
- }, root?: string): Promise<void>;
14
- export {};
@@ -1,74 +0,0 @@
1
- import { browseProviders, pluginKindLabel } from "@ingestron/core/adapter";
2
- /** Read-only navigation of installed plugin metadata. */
3
- export async function browsePlugins(ui, query = "", initialKind, filters = {}, root = process.cwd()) {
4
- browseProviders(root, query, initialKind, filters); // Validate filters even when catalogue is empty.
5
- let kind = initialKind;
6
- let listing = !!query || !!kind;
7
- let page = 0;
8
- for (;;) {
9
- if (!listing) {
10
- const choice = await ui.select("Browse plugins", [
11
- { value: "all", label: "Browse all plugins" },
12
- { value: "search", label: "Search plugins" },
13
- ...["provider", "model-pack", "activity-pack", "report-pack"].map((value) => ({ value, label: pluginKindLabel(value) })),
14
- {
15
- value: "connector",
16
- label: "Connectors",
17
- hint: "Installed connector packages",
18
- },
19
- { value: "exit", label: "Finish browsing" },
20
- ]);
21
- if (choice === "exit")
22
- return;
23
- kind = ["all", "search"].includes(choice) ? undefined : choice;
24
- query = choice === "search" ? await ui.search() : "";
25
- listing = true;
26
- page = 0;
27
- }
28
- const plugins = browseProviders(root, query, kind, filters);
29
- const visible = plugins.slice(page * 25, (page + 1) * 25);
30
- const selected = await ui.select(plugins.length
31
- ? `Select a plugin (${plugins.length} results, page ${page + 1})`
32
- : "No plugins match; change category or search", [
33
- ...visible.map((p) => ({
34
- value: p.reference,
35
- label: `${p.name} [${p.kindLabel}]`,
36
- hint: `${p.availability} · ${p.description}`,
37
- })),
38
- ...(page > 0 ? [{ value: ":previous", label: "Previous page" }] : []),
39
- ...((page + 1) * 25 < plugins.length
40
- ? [{ value: ":next", label: "Next page" }]
41
- : []),
42
- { value: ":search", label: "Search this category" },
43
- { value: ":back", label: "Change category / browse all" },
44
- { value: ":exit", label: "Finish browsing" },
45
- ]);
46
- if (selected === ":next") {
47
- page++;
48
- continue;
49
- }
50
- if (selected === ":previous") {
51
- page--;
52
- continue;
53
- }
54
- if (selected === ":exit")
55
- return;
56
- if (selected === ":back") {
57
- listing = false;
58
- continue;
59
- }
60
- if (selected === ":search") {
61
- query = await ui.search();
62
- page = 0;
63
- continue;
64
- }
65
- const plugin = plugins.find((p) => p.reference === selected);
66
- ui.details(`${plugin.name} (${plugin.id})\n${plugin.kindLabel} · ${plugin.availability}\n\n${plugin.description}\n${plugin.evidence}\n\nLicence: ${plugin.licence}\nDocumentation: ${plugin.documentation}\nSource and package documentation: ${plugin.url}\n\nExact-version licences/notices and provenance are saved to .ingestron/plugin-info/ during installation. Engine compatibility is package-specific; installed metadata is not runtime verification.`);
67
- const action = await ui.select("Next step", [
68
- { value: "back", label: "Back to results" },
69
- { value: "exit", label: "Finish browsing" },
70
- ]);
71
- if (action === "exit")
72
- return;
73
- }
74
- }
@@ -1,72 +0,0 @@
1
- /** Official-name convenience at the adapter boundary; core only receives exact references. */
2
- import { type Context, type OperationName, type Result } from "@ingestron/core";
3
- export declare const officialPlugins: {
4
- readonly adf: {
5
- readonly kind: "provider";
6
- readonly repository: "ingestron/provider-adf";
7
- readonly path: "plugin/provider.yaml";
8
- readonly tagPrefix: "";
9
- };
10
- readonly "azure-blob": {
11
- readonly kind: "connector";
12
- readonly repository: "ingestron/connectors";
13
- readonly path: "connectors/azure-blob/connector.yaml";
14
- readonly tagPrefix: "azure-blob-";
15
- };
16
- readonly databricks: {
17
- readonly kind: "provider";
18
- readonly repository: "ingestron/provider-databricks";
19
- readonly path: "plugin/provider.yaml";
20
- readonly tagPrefix: "";
21
- };
22
- readonly files: {
23
- readonly kind: "connector";
24
- readonly repository: "ingestron/connectors";
25
- readonly path: "connectors/files/connector.yaml";
26
- readonly tagPrefix: "files-";
27
- };
28
- readonly github: {
29
- readonly kind: "connector";
30
- readonly repository: "ingestron/connectors";
31
- readonly path: "connectors/github/connector.yaml";
32
- readonly tagPrefix: "github-";
33
- };
34
- readonly local: {
35
- readonly kind: "provider";
36
- readonly repository: "ingestron/provider-local";
37
- readonly path: "plugin/provider.yaml";
38
- readonly tagPrefix: "";
39
- };
40
- readonly mysql: {
41
- readonly kind: "connector";
42
- readonly repository: "ingestron/connectors";
43
- readonly path: "connectors/mysql/connector.yaml";
44
- readonly tagPrefix: "mysql-";
45
- };
46
- readonly oracle: {
47
- readonly kind: "connector";
48
- readonly repository: "ingestron/connectors";
49
- readonly path: "connectors/oracle/connector.yaml";
50
- readonly tagPrefix: "oracle-";
51
- };
52
- readonly postgresql: {
53
- readonly kind: "connector";
54
- readonly repository: "ingestron/connectors";
55
- readonly path: "connectors/postgresql/connector.yaml";
56
- readonly tagPrefix: "postgresql-";
57
- };
58
- readonly "sql-server": {
59
- readonly kind: "connector";
60
- readonly repository: "ingestron/connectors";
61
- readonly path: "connectors/sql-server/connector.yaml";
62
- readonly tagPrefix: "sql-server-";
63
- };
64
- };
65
- export declare function officialName(reference: string): {
66
- name: keyof typeof officialPlugins;
67
- version: string;
68
- } | undefined;
69
- export declare function catalogueReleases(value: any, name: keyof typeof officialPlugins, host?: string): string[];
70
- export declare function fetchCatalogue(): Promise<unknown>;
71
- export declare function resolvePluginArgs(context: Context, operation: OperationName, args: any, catalogue?: typeof fetchCatalogue): Promise<any>;
72
- export declare function executePluginOperation(context: Context, operation: OperationName, args?: any): Promise<Result>;
@@ -1,216 +0,0 @@
1
- /** Official-name convenience at the adapter boundary; core only receives exact references. */
2
- import { executeAsync, operationSchemas, } from "@ingestron/core";
3
- import { check, packageLock, Problem } from "@ingestron/core/adapter";
4
- import { coreVersion } from "../version.js";
5
- export const officialPlugins = {
6
- adf: {
7
- kind: "provider",
8
- repository: "ingestron/provider-adf",
9
- path: "plugin/provider.yaml",
10
- tagPrefix: "",
11
- },
12
- "azure-blob": {
13
- kind: "connector",
14
- repository: "ingestron/connectors",
15
- path: "connectors/azure-blob/connector.yaml",
16
- tagPrefix: "azure-blob-",
17
- },
18
- databricks: {
19
- kind: "provider",
20
- repository: "ingestron/provider-databricks",
21
- path: "plugin/provider.yaml",
22
- tagPrefix: "",
23
- },
24
- files: {
25
- kind: "connector",
26
- repository: "ingestron/connectors",
27
- path: "connectors/files/connector.yaml",
28
- tagPrefix: "files-",
29
- },
30
- github: {
31
- kind: "connector",
32
- repository: "ingestron/connectors",
33
- path: "connectors/github/connector.yaml",
34
- tagPrefix: "github-",
35
- },
36
- local: {
37
- kind: "provider",
38
- repository: "ingestron/provider-local",
39
- path: "plugin/provider.yaml",
40
- tagPrefix: "",
41
- },
42
- mysql: {
43
- kind: "connector",
44
- repository: "ingestron/connectors",
45
- path: "connectors/mysql/connector.yaml",
46
- tagPrefix: "mysql-",
47
- },
48
- oracle: {
49
- kind: "connector",
50
- repository: "ingestron/connectors",
51
- path: "connectors/oracle/connector.yaml",
52
- tagPrefix: "oracle-",
53
- },
54
- postgresql: {
55
- kind: "connector",
56
- repository: "ingestron/connectors",
57
- path: "connectors/postgresql/connector.yaml",
58
- tagPrefix: "postgresql-",
59
- },
60
- "sql-server": {
61
- kind: "connector",
62
- repository: "ingestron/connectors",
63
- path: "connectors/sql-server/connector.yaml",
64
- tagPrefix: "sql-server-",
65
- },
66
- };
67
- const catalogueUrl = "https://raw.githubusercontent.com/ingestron/connectors/main/catalogue.json";
68
- const stable = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/;
69
- const compare = (a, b) => {
70
- const x = a.split(".").map(Number), y = b.split(".").map(Number);
71
- return y[0] - x[0] || y[1] - x[1] || y[2] - x[2];
72
- };
73
- export function officialName(reference) {
74
- if (reference.includes("/"))
75
- return undefined;
76
- const [name, version, extra] = reference.split("@");
77
- check(Object.hasOwn(officialPlugins, name), "PACKAGE", `Unknown official plugin '${name}'. Use ${Object.keys(officialPlugins).join(", ")}, or an explicit owner/repository reference. Check ingestron --version and update the CLI if a documented name is missing.`);
78
- check(extra === undefined &&
79
- (version === undefined || version === "latest" || stable.test(version)), "PACKAGE", "Use a stable version, @latest, or omit the version for an official plugin");
80
- return { name: name, version };
81
- }
82
- export function catalogueReleases(value, name, host = coreVersion) {
83
- const identity = officialPlugins[name];
84
- check(value?.apiVersion === "ingestron.catalogue/v1", "CATALOGUE", "Unsupported official catalogue format");
85
- const entry = value.plugins?.[name];
86
- check(entry &&
87
- entry.repository === identity.repository &&
88
- entry.path === identity.path &&
89
- entry.tagPrefix === identity.tagPrefix &&
90
- Array.isArray(entry.releases) &&
91
- entry.releases.length <= 1000, "CATALOGUE", `Invalid official catalogue identity for ${name}`);
92
- const seen = new Set();
93
- for (const release of entry.releases) {
94
- check(stable.test(release.version) &&
95
- !seen.has(release.version) &&
96
- Array.isArray(release.coreVersions) &&
97
- release.coreVersions.length > 0 &&
98
- release.coreVersions.every((v) => typeof v === "string" && stable.test(v)), "CATALOGUE", `Invalid qualified release for ${name}`);
99
- seen.add(release.version);
100
- }
101
- return entry.releases
102
- .filter((r) => r.coreVersions.includes(host))
103
- .map((r) => r.version)
104
- .sort(compare);
105
- }
106
- export async function fetchCatalogue() {
107
- try {
108
- const response = await fetch(catalogueUrl, {
109
- signal: AbortSignal.timeout(10000),
110
- redirect: "error",
111
- });
112
- check(response.ok && response.body, "CATALOGUE", "Official catalogue is unavailable; retry or install an explicit version");
113
- const reader = response.body.getReader();
114
- const chunks = [];
115
- let size = 0;
116
- try {
117
- for (;;) {
118
- const { value, done } = await reader.read();
119
- if (done)
120
- break;
121
- size += value.length;
122
- check(size <= 262144, "CATALOGUE", "Official catalogue exceeds the size limit");
123
- chunks.push(value);
124
- }
125
- }
126
- finally {
127
- await reader.cancel();
128
- }
129
- return JSON.parse(Buffer.concat(chunks).toString("utf8"));
130
- }
131
- catch (error) {
132
- if (error instanceof Problem)
133
- throw error;
134
- throw new Problem("CATALOGUE", "Cannot read the official catalogue; retry or install an explicit version");
135
- }
136
- }
137
- export async function resolvePluginArgs(context, operation, args, catalogue = fetchCatalogue) {
138
- if (operation !== "packages_install" && operation !== "plugin_versions")
139
- return args;
140
- const field = operation === "packages_install" ? "reference" : "provider";
141
- const alias = officialName(args[field]);
142
- if (!alias)
143
- return args;
144
- const identity = officialPlugins[alias.name];
145
- if (operation === "packages_install" && args.kind)
146
- check(args.kind === identity.kind, "PACKAGE", `${alias.name} is a ${identity.kind}; use ingestron ${identity.kind} install ${alias.name}`);
147
- check(args.tagPrefix === undefined || args.tagPrefix === identity.tagPrefix, "OPTION", "Official plugin tag prefixes cannot be overridden; use an explicit reference for custom tags");
148
- if (operation === "plugin_versions")
149
- return {
150
- ...args,
151
- provider: identity.repository,
152
- tagPrefix: identity.tagPrefix,
153
- };
154
- // Check permissions before catalogue network access, just as core does before install.
155
- check(context.allowWrite, "PERMISSION", "Package installation requires write access");
156
- check(!(args.update && args.frozen), "PACKAGE", "Frozen installation cannot update packages");
157
- const base = `${identity.repository}/${identity.path}@`;
158
- let version = alias.version;
159
- if (version === undefined || version === "latest") {
160
- const installed = Object.keys(packageLock(context.root).packages)
161
- .filter((r) => r.startsWith(base) && stable.test(r.slice(base.length)))
162
- .map((r) => r.slice(base.length))
163
- .sort(compare);
164
- if (!args.update && installed.length)
165
- version = installed[0];
166
- else {
167
- check(!args.frozen, "PACKAGE", "Frozen installation requires an existing exact lock; install an exact version first");
168
- check(context.allowNetwork, "PERMISSION", "Latest plugin resolution requires explicit package-network access");
169
- check(!args.fromGit, "OPTION", "Use an exact version with --from-git; latest selects official qualified releases");
170
- const versions = catalogueReleases(await catalogue(), alias.name);
171
- check(versions.length, "COMPATIBILITY", `No qualified ${alias.name} release supports core ${coreVersion}; update the CLI or select an explicitly compatible version`);
172
- version = [...versions, ...installed].sort(compare)[0];
173
- }
174
- }
175
- // Even 'update' must never retarget an existing immutable version lock.
176
- return {
177
- ...args,
178
- reference: `${base}${version}`,
179
- tagPrefix: identity.tagPrefix,
180
- update: false,
181
- };
182
- }
183
- export async function executePluginOperation(context, operation, args = {}) {
184
- try {
185
- if (operation === "packages_install" || operation === "plugin_versions") {
186
- const parsed = operationSchemas[operation].safeParse(args);
187
- check(parsed.success, "SCHEMA", "Invalid plugin operation arguments");
188
- if (operation === "packages_install")
189
- check(context.allowWrite, "PERMISSION", "Package installation requires write access");
190
- check(context.allowNetwork || parsed.data?.fromGit, "PERMISSION", "Package access requires explicit package-network access");
191
- args = await resolvePluginArgs(context, operation, parsed.data);
192
- }
193
- const result = await executeAsync(context, operation, args);
194
- // Keep custom manifest paths in every returned installable reference.
195
- if (operation === "plugin_versions" && result.ok) {
196
- const identity = Object.values(officialPlugins).find((p) => p.repository === args.provider && p.tagPrefix === args.tagPrefix);
197
- if (identity)
198
- result.result.versions = result.result.versions.map((v) => ({
199
- ...v,
200
- reference: `${identity.repository}/${identity.path}@${v.version}`,
201
- }));
202
- }
203
- return result;
204
- }
205
- catch (error) {
206
- const e = error instanceof Problem
207
- ? error
208
- : new Problem("PACKAGE", "Plugin resolution failed; check the reference and catalogue");
209
- return {
210
- apiVersion: "ingestron.operation/v1",
211
- operation,
212
- ok: false,
213
- diagnostics: [{ code: e.code, message: e.message }],
214
- };
215
- }
216
- }
@@ -1,12 +0,0 @@
1
- import type { Context, OperationName, Result } from "@ingestron/core";
2
- export interface Presentation {
3
- tty: boolean;
4
- plain?: boolean;
5
- colour?: boolean;
6
- progress?: boolean;
7
- json?: boolean;
8
- }
9
- export declare function richTerminal(options: Presentation, env?: NodeJS.ProcessEnv): boolean;
10
- export declare function decorate(text: string, ok: boolean, options: Presentation): string;
11
- export declare function banner(text: string, options: Presentation): string;
12
- export declare function backgroundOperation(context: Context, operation: OperationName, args: unknown, label: string, options: Presentation): Promise<Result>;