@commercetools/cli-topic-integration-layer 0.0.0 → 0.2.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/LICENSE +21 -0
- package/README.md +64 -0
- package/dist/commands/integration-layer/config/get.d.ts +9 -0
- package/dist/commands/integration-layer/config/get.js +22 -0
- package/dist/commands/integration-layer/config/get.js.map +1 -0
- package/dist/commands/integration-layer/config/list.d.ts +6 -0
- package/dist/commands/integration-layer/config/list.js +20 -0
- package/dist/commands/integration-layer/config/list.js.map +1 -0
- package/dist/commands/integration-layer/config/set.d.ts +13 -0
- package/dist/commands/integration-layer/config/set.js +29 -0
- package/dist/commands/integration-layer/config/set.js.map +1 -0
- package/dist/commands/integration-layer/config/unset.d.ts +9 -0
- package/dist/commands/integration-layer/config/unset.js +18 -0
- package/dist/commands/integration-layer/config/unset.js.map +1 -0
- package/dist/commands/integration-layer/extension/build.d.ts +12 -0
- package/dist/commands/integration-layer/extension/build.js +40 -0
- package/dist/commands/integration-layer/extension/build.js.map +1 -0
- package/dist/commands/integration-layer/extension/delete.d.ts +9 -0
- package/dist/commands/integration-layer/extension/delete.js +39 -0
- package/dist/commands/integration-layer/extension/delete.js.map +1 -0
- package/dist/commands/integration-layer/extension/invoke.d.ts +13 -0
- package/dist/commands/integration-layer/extension/invoke.js +89 -0
- package/dist/commands/integration-layer/extension/invoke.js.map +1 -0
- package/dist/commands/integration-layer/extension/push.d.ts +28 -0
- package/dist/commands/integration-layer/extension/push.js +217 -0
- package/dist/commands/integration-layer/extension/push.js.map +1 -0
- package/dist/commands/integration-layer/extension/serve.d.ts +37 -0
- package/dist/commands/integration-layer/extension/serve.js +528 -0
- package/dist/commands/integration-layer/extension/serve.js.map +1 -0
- package/dist/commands/integration-layer/extension/status.d.ts +6 -0
- package/dist/commands/integration-layer/extension/status.js +28 -0
- package/dist/commands/integration-layer/extension/status.js.map +1 -0
- package/dist/commands/integration-layer/extension/validate.d.ts +15 -0
- package/dist/commands/integration-layer/extension/validate.js +98 -0
- package/dist/commands/integration-layer/extension/validate.js.map +1 -0
- package/dist/commands/integration-layer/hello.d.ts +6 -0
- package/dist/commands/integration-layer/hello.js +10 -0
- package/dist/commands/integration-layer/hello.js.map +1 -0
- package/dist/commands/integration-layer/init.d.ts +13 -0
- package/dist/commands/integration-layer/init.js +279 -0
- package/dist/commands/integration-layer/init.js.map +1 -0
- package/dist/commands/integration-layer/schema/fetch.d.ts +9 -0
- package/dist/commands/integration-layer/schema/fetch.js +27 -0
- package/dist/commands/integration-layer/schema/fetch.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/awaitBundleState.d.ts +33 -0
- package/dist/lib/awaitBundleState.js +77 -0
- package/dist/lib/awaitBundleState.js.map +1 -0
- package/dist/lib/base.d.ts +50 -0
- package/dist/lib/base.js +85 -0
- package/dist/lib/base.js.map +1 -0
- package/dist/lib/ilClient.d.ts +93 -0
- package/dist/lib/ilClient.js +120 -0
- package/dist/lib/ilClient.js.map +1 -0
- package/dist/lib/sourceRevision.d.ts +39 -0
- package/dist/lib/sourceRevision.js +95 -0
- package/dist/lib/sourceRevision.js.map +1 -0
- package/dist/lib/tooling/apiExtension.d.ts +31 -0
- package/dist/lib/tooling/apiExtension.js +39 -0
- package/dist/lib/tooling/apiExtension.js.map +1 -0
- package/dist/lib/tooling/build.d.ts +18 -0
- package/dist/lib/tooling/build.js +54 -0
- package/dist/lib/tooling/build.js.map +1 -0
- package/dist/lib/tooling/compose.d.ts +28 -0
- package/dist/lib/tooling/compose.js +48 -0
- package/dist/lib/tooling/compose.js.map +1 -0
- package/dist/lib/tooling/extensions.d.ts +77 -0
- package/dist/lib/tooling/extensions.js +209 -0
- package/dist/lib/tooling/extensions.js.map +1 -0
- package/dist/lib/tooling/gateway.d.ts +21 -0
- package/dist/lib/tooling/gateway.js +65 -0
- package/dist/lib/tooling/gateway.js.map +1 -0
- package/dist/lib/tooling/loadBundle.d.ts +10 -0
- package/dist/lib/tooling/loadBundle.js +27 -0
- package/dist/lib/tooling/loadBundle.js.map +1 -0
- package/dist/lib/tooling/staticAnalysis.d.ts +11 -0
- package/dist/lib/tooling/staticAnalysis.js +167 -0
- package/dist/lib/tooling/staticAnalysis.js.map +1 -0
- package/dist/lib/tooling/validateBundle.d.ts +19 -0
- package/dist/lib/tooling/validateBundle.js +144 -0
- package/dist/lib/tooling/validateBundle.js.map +1 -0
- package/package.json +47 -5
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
// Best-effort static analysis of an extension's source, run by `validate`/`push`.
|
|
2
|
+
//
|
|
3
|
+
// Kept in sync with commercetools/integration-layer-extension-examples
|
|
4
|
+
// (packages/tooling/src/staticAnalysis.ts) — that repo is the canonical copy, and it
|
|
5
|
+
// in turn mirrors the connector's `webPlatformEndowments` (octolog-extensions-sandbox
|
|
6
|
+
// service/src/bundle/sandbox/compartment.ts), the real source of truth for what the
|
|
7
|
+
// sandbox endows. When the connector's endowment list changes, update ILEE first,
|
|
8
|
+
// then port the change here. The resolver environment provides a restricted set of
|
|
9
|
+
// capabilities, not a full Node runtime, so this flags patterns that won't work there
|
|
10
|
+
// before the bundle is uploaded. It parses the author's own source files to a
|
|
11
|
+
// TypeScript AST (so a mention in a comment or string is never a false positive) and
|
|
12
|
+
// is a lint, not an enforcement boundary — it catches honest mistakes, not deliberate
|
|
13
|
+
// obfuscation. It rejects:
|
|
14
|
+
// - a well-known global the sandbox does NOT endow (`process`, `Buffer`,
|
|
15
|
+
// `setInterval`, `SharedArrayBuffer`, `WebAssembly`, DOM globals, …) — so an
|
|
16
|
+
// author who reaches for one is warned here instead of crashing at runtime;
|
|
17
|
+
// - importing a Node built-in (`fs`, `crypto`, `node:*`, …) — use `fetch` or an npm package;
|
|
18
|
+
// - `eval` / `new Function`.
|
|
19
|
+
import { readFile } from "node:fs/promises";
|
|
20
|
+
import ts from "typescript";
|
|
21
|
+
/** Node core modules an extension may not import; `node:`-prefixed ids are also rejected. */
|
|
22
|
+
const NODE_BUILTINS = new Set([
|
|
23
|
+
"assert", "async_hooks", "buffer", "child_process", "cluster", "console",
|
|
24
|
+
"constants", "crypto", "dgram", "dns", "domain", "events", "fs", "http",
|
|
25
|
+
"http2", "https", "inspector", "module", "net", "os", "path", "perf_hooks",
|
|
26
|
+
"process", "punycode", "querystring", "readline", "repl", "stream",
|
|
27
|
+
"string_decoder", "sys", "timers", "tls", "trace_events", "tty", "url",
|
|
28
|
+
"util", "v8", "vm", "worker_threads", "zlib",
|
|
29
|
+
]);
|
|
30
|
+
// The web-platform globals the sandbox endows (its "Tier-1 data surface"), on top
|
|
31
|
+
// of the ECMAScript intrinsics SES lockdown leaves in place (JSON, Object, Array,
|
|
32
|
+
// Map, Set, Promise, RegExp, typed arrays, …, always available). This mirrors the
|
|
33
|
+
// connector's `webPlatformEndowments` (bundle/sandbox/compartment.ts) and is the
|
|
34
|
+
// SOURCE OF TRUTH `UNAVAILABLE_GLOBALS` is the curated complement of — keep the two
|
|
35
|
+
// in sync when the connector's endowment list changes. Referenced by the check so
|
|
36
|
+
// a global that is BOTH endowed and (mistakenly) listed as unavailable never fires.
|
|
37
|
+
const ENDOWED_GLOBALS = new Set([
|
|
38
|
+
"fetch",
|
|
39
|
+
"setTimeout", "clearTimeout",
|
|
40
|
+
"Date", "Math",
|
|
41
|
+
"URL", "URLSearchParams",
|
|
42
|
+
"TextEncoder", "TextDecoder", "btoa", "atob",
|
|
43
|
+
"Headers", "Request", "Response", "FormData",
|
|
44
|
+
"structuredClone", "Intl",
|
|
45
|
+
"AbortController", "AbortSignal",
|
|
46
|
+
"console", // tamed, forwarded to the host logger
|
|
47
|
+
]);
|
|
48
|
+
// Well-known globals the sandbox deliberately does NOT provide, each with a hint at
|
|
49
|
+
// the endowed alternative. Using one throws at runtime, so flag it at validate time.
|
|
50
|
+
// NOT exhaustive (it can't enumerate every absent name) and NOT a security boundary
|
|
51
|
+
// — a curated, high-signal set: Node-only globals, and the capability / DoS /
|
|
52
|
+
// side-channel globals the compartment withholds on purpose (see compartment.ts).
|
|
53
|
+
const UNAVAILABLE_GLOBALS = new Map([
|
|
54
|
+
// Node-only — read config from `ctx.config`, or use the web-standard equivalent.
|
|
55
|
+
["process", "read configuration from `ctx.config` instead"],
|
|
56
|
+
["Buffer", "use `TextEncoder`/`Uint8Array`, or `btoa`/`atob` for base64"],
|
|
57
|
+
["global", "use `globalThis`"],
|
|
58
|
+
["setInterval", "the sandbox endows `setTimeout`/`clearTimeout` only — loop with `setTimeout`"],
|
|
59
|
+
["clearInterval", "the sandbox endows `setTimeout`/`clearTimeout` only"],
|
|
60
|
+
["setImmediate", "use `setTimeout(fn, 0)`"],
|
|
61
|
+
// Deliberately withheld (capability / DoS / side-channel) — see compartment.ts.
|
|
62
|
+
["SharedArrayBuffer", "withheld — shared memory is a cross-sandbox channel"],
|
|
63
|
+
["Atomics", "withheld — pairs with SharedArrayBuffer (channel + synchronous blocking)"],
|
|
64
|
+
["WebAssembly", "withheld — a second execution engine is not exposed to extensions"],
|
|
65
|
+
["MessageChannel", "withheld — communication primitive"],
|
|
66
|
+
["MessagePort", "withheld — communication primitive"],
|
|
67
|
+
["BroadcastChannel", "withheld — communication primitive"],
|
|
68
|
+
["WeakRef", "withheld — GC observability is a side channel"],
|
|
69
|
+
["FinalizationRegistry", "withheld — GC observability is a side channel"],
|
|
70
|
+
["performance", "withheld — high-resolution timing is a side channel; use `Date.now()`"],
|
|
71
|
+
["CompressionStream", "withheld — decompression is an unbounded DoS vector"],
|
|
72
|
+
["DecompressionStream", "withheld — decompression is an unbounded DoS vector"],
|
|
73
|
+
// Browser/DOM globals that simply do not exist server-side.
|
|
74
|
+
["window", "not available (no DOM); use `globalThis`"],
|
|
75
|
+
["document", "not available (no DOM)"],
|
|
76
|
+
["localStorage", "not available; use `ctx.config` for configuration"],
|
|
77
|
+
["sessionStorage", "not available; use `ctx.config` for configuration"],
|
|
78
|
+
["XMLHttpRequest", "not available; use the global `fetch`"],
|
|
79
|
+
["WebSocket", "not available; only outbound `fetch` egress is provided"],
|
|
80
|
+
]);
|
|
81
|
+
/** Is `spec` a Node built-in module (or a `node:`-prefixed import)? */
|
|
82
|
+
function isBuiltinSpecifier(spec) {
|
|
83
|
+
if (spec.startsWith("node:"))
|
|
84
|
+
return true;
|
|
85
|
+
return NODE_BUILTINS.has(spec);
|
|
86
|
+
}
|
|
87
|
+
/** Analyse one already-parsed source file, appending any issues found. */
|
|
88
|
+
function analyzeSourceFile(sf, issues) {
|
|
89
|
+
const report = (node, message) => {
|
|
90
|
+
const { line } = sf.getLineAndCharacterOfPosition(node.getStart(sf));
|
|
91
|
+
issues.push({ file: sf.fileName, line: line + 1, message });
|
|
92
|
+
};
|
|
93
|
+
const checkSpecifier = (spec, node) => {
|
|
94
|
+
if (isBuiltinSpecifier(spec)) {
|
|
95
|
+
report(node, `imports the Node built-in "${spec}", which the runtime does not provide — ` +
|
|
96
|
+
"use the global `fetch` for HTTP, or bundle an npm package");
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
const visit = (node) => {
|
|
100
|
+
// import ... from "x" / export ... from "x"
|
|
101
|
+
if ((ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) &&
|
|
102
|
+
node.moduleSpecifier &&
|
|
103
|
+
ts.isStringLiteral(node.moduleSpecifier)) {
|
|
104
|
+
checkSpecifier(node.moduleSpecifier.text, node.moduleSpecifier);
|
|
105
|
+
}
|
|
106
|
+
if (ts.isCallExpression(node)) {
|
|
107
|
+
const callee = node.expression;
|
|
108
|
+
const firstArg = node.arguments[0];
|
|
109
|
+
// require("x") / import("x")
|
|
110
|
+
if ((callee.kind === ts.SyntaxKind.ImportKeyword ||
|
|
111
|
+
(ts.isIdentifier(callee) && callee.text === "require")) &&
|
|
112
|
+
firstArg &&
|
|
113
|
+
ts.isStringLiteral(firstArg)) {
|
|
114
|
+
checkSpecifier(firstArg.text, firstArg);
|
|
115
|
+
}
|
|
116
|
+
// eval(...)
|
|
117
|
+
if (ts.isIdentifier(callee) && callee.text === "eval") {
|
|
118
|
+
report(node, "uses `eval`, which the runtime does not allow");
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// new Function(...)
|
|
122
|
+
if (ts.isNewExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === "Function") {
|
|
123
|
+
report(node, "uses `new Function`, which the runtime does not allow");
|
|
124
|
+
}
|
|
125
|
+
// Reference to a global the sandbox does not endow (e.g. `process.env`,
|
|
126
|
+
// `new SharedArrayBuffer(…)`). Skip when the identifier is the property side of
|
|
127
|
+
// an access (`foo.process`), a declaration name, or otherwise not a value read —
|
|
128
|
+
// this is a syntactic lint, so keep it to high-signal free-identifier reads.
|
|
129
|
+
if (ts.isIdentifier(node) && UNAVAILABLE_GLOBALS.has(node.text) && !ENDOWED_GLOBALS.has(node.text)) {
|
|
130
|
+
const parent = node.parent;
|
|
131
|
+
const isPropertyName = (ts.isPropertyAccessExpression(parent) && parent.name === node) ||
|
|
132
|
+
(ts.isQualifiedName(parent) && parent.right === node);
|
|
133
|
+
// A local binding of the same name (import/param/var/function/property) is the
|
|
134
|
+
// author's own — not the ambient global — so don't flag it.
|
|
135
|
+
const isLocalBinding = (ts.isParameter(parent) ||
|
|
136
|
+
ts.isVariableDeclaration(parent) ||
|
|
137
|
+
ts.isFunctionDeclaration(parent) ||
|
|
138
|
+
ts.isBindingElement(parent) ||
|
|
139
|
+
ts.isPropertyAssignment(parent) ||
|
|
140
|
+
ts.isImportSpecifier(parent) ||
|
|
141
|
+
ts.isImportClause(parent)) &&
|
|
142
|
+
parent.name === node;
|
|
143
|
+
if (!isPropertyName && !isLocalBinding) {
|
|
144
|
+
const hint = UNAVAILABLE_GLOBALS.get(node.text) ?? "";
|
|
145
|
+
report(node, `uses the global \`${node.text}\`, which the sandbox does not provide` +
|
|
146
|
+
(hint ? ` — ${hint}` : ""));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
ts.forEachChild(node, visit);
|
|
150
|
+
};
|
|
151
|
+
visit(sf);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Analyse the given source files (the author's entry + its local imports) and
|
|
155
|
+
* return every runtime-incompatibility issue found. An empty array means the source
|
|
156
|
+
* is clean of the patterns this checks.
|
|
157
|
+
*/
|
|
158
|
+
export async function analyzeSources(files) {
|
|
159
|
+
const issues = [];
|
|
160
|
+
for (const file of files) {
|
|
161
|
+
const text = await readFile(file, "utf8");
|
|
162
|
+
const sf = ts.createSourceFile(file, text, ts.ScriptTarget.Latest, /* setParentNodes */ true);
|
|
163
|
+
analyzeSourceFile(sf, issues);
|
|
164
|
+
}
|
|
165
|
+
return issues;
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=staticAnalysis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staticAnalysis.js","sourceRoot":"","sources":["../../../src/lib/tooling/staticAnalysis.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,EAAE;AACF,uEAAuE;AACvE,qFAAqF;AACrF,sFAAsF;AACtF,oFAAoF;AACpF,kFAAkF;AAClF,mFAAmF;AACnF,sFAAsF;AACtF,8EAA8E;AAC9E,qFAAqF;AACrF,sFAAsF;AACtF,2BAA2B;AAC3B,2EAA2E;AAC3E,iFAAiF;AACjF,gFAAgF;AAChF,+FAA+F;AAC/F,+BAA+B;AAE/B,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,6FAA6F;AAC7F,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC;IAC5B,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,SAAS,EAAE,SAAS;IACxE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM;IACvE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY;IAC1E,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ;IAClE,gBAAgB,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,KAAK;IACtE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM;CAC7C,CAAC,CAAC;AAEH,kFAAkF;AAClF,kFAAkF;AAClF,kFAAkF;AAClF,iFAAiF;AACjF,oFAAoF;AACpF,kFAAkF;AAClF,oFAAoF;AACpF,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;IAC9B,OAAO;IACP,YAAY,EAAE,cAAc;IAC5B,MAAM,EAAE,MAAM;IACd,KAAK,EAAE,iBAAiB;IACxB,aAAa,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM;IAC5C,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU;IAC5C,iBAAiB,EAAE,MAAM;IACzB,iBAAiB,EAAE,aAAa;IAChC,SAAS,EAAE,sCAAsC;CAClD,CAAC,CAAC;AAEH,oFAAoF;AACpF,qFAAqF;AACrF,oFAAoF;AACpF,8EAA8E;AAC9E,kFAAkF;AAClF,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAiB;IAClD,iFAAiF;IACjF,CAAC,SAAS,EAAE,8CAA8C,CAAC;IAC3D,CAAC,QAAQ,EAAE,6DAA6D,CAAC;IACzE,CAAC,QAAQ,EAAE,kBAAkB,CAAC;IAC9B,CAAC,aAAa,EAAE,8EAA8E,CAAC;IAC/F,CAAC,eAAe,EAAE,qDAAqD,CAAC;IACxE,CAAC,cAAc,EAAE,yBAAyB,CAAC;IAC3C,gFAAgF;IAChF,CAAC,mBAAmB,EAAE,qDAAqD,CAAC;IAC5E,CAAC,SAAS,EAAE,0EAA0E,CAAC;IACvF,CAAC,aAAa,EAAE,mEAAmE,CAAC;IACpF,CAAC,gBAAgB,EAAE,oCAAoC,CAAC;IACxD,CAAC,aAAa,EAAE,oCAAoC,CAAC;IACrD,CAAC,kBAAkB,EAAE,oCAAoC,CAAC;IAC1D,CAAC,SAAS,EAAE,+CAA+C,CAAC;IAC5D,CAAC,sBAAsB,EAAE,+CAA+C,CAAC;IACzE,CAAC,aAAa,EAAE,uEAAuE,CAAC;IACxF,CAAC,mBAAmB,EAAE,qDAAqD,CAAC;IAC5E,CAAC,qBAAqB,EAAE,qDAAqD,CAAC;IAC9E,4DAA4D;IAC5D,CAAC,QAAQ,EAAE,0CAA0C,CAAC;IACtD,CAAC,UAAU,EAAE,wBAAwB,CAAC;IACtC,CAAC,cAAc,EAAE,mDAAmD,CAAC;IACrE,CAAC,gBAAgB,EAAE,mDAAmD,CAAC;IACvE,CAAC,gBAAgB,EAAE,uCAAuC,CAAC;IAC3D,CAAC,WAAW,EAAE,yDAAyD,CAAC;CACzE,CAAC,CAAC;AAQH,uEAAuE;AACvE,SAAS,kBAAkB,CAAC,IAAY;IACtC,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,OAAO,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC;AAED,0EAA0E;AAC1E,SAAS,iBAAiB,CAAC,EAAiB,EAAE,MAAuB;IACnE,MAAM,MAAM,GAAG,CAAC,IAAa,EAAE,OAAe,EAAQ,EAAE;QACtD,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,6BAA6B,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;QACrE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;IAC9D,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,CAAC,IAAY,EAAE,IAAa,EAAQ,EAAE;QAC3D,IAAI,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,MAAM,CACJ,IAAI,EACJ,8BAA8B,IAAI,0CAA0C;gBAC1E,2DAA2D,CAC9D,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,KAAK,GAAG,CAAC,IAAa,EAAQ,EAAE;QACpC,4CAA4C;QAC5C,IACE,CAAC,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAC9D,IAAI,CAAC,eAAe;YACpB,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,eAAe,CAAC,EACxC,CAAC;YACD,cAAc,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAClE,CAAC;QAED,IAAI,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC;YAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YACnC,6BAA6B;YAC7B,IACE,CAAC,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,aAAa;gBAC1C,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;gBACzD,QAAQ;gBACR,EAAE,CAAC,eAAe,CAAC,QAAQ,CAAC,EAC5B,CAAC;gBACD,cAAc,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC1C,CAAC;YACD,YAAY;YACZ,IAAI,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBACtD,MAAM,CAAC,IAAI,EAAE,+CAA+C,CAAC,CAAC;YAChE,CAAC;QACH,CAAC;QAED,oBAAoB;QACpB,IAAI,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACxG,MAAM,CAAC,IAAI,EAAE,uDAAuD,CAAC,CAAC;QACxE,CAAC;QAED,wEAAwE;QACxE,gFAAgF;QAChF,iFAAiF;QACjF,6EAA6E;QAC7E,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACnG,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;YAC3B,MAAM,cAAc,GAClB,CAAC,EAAE,CAAC,0BAA0B,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC;gBAC/D,CAAC,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC;YACxD,+EAA+E;YAC/E,4DAA4D;YAC5D,MAAM,cAAc,GAClB,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC;gBACrB,EAAE,CAAC,qBAAqB,CAAC,MAAM,CAAC;gBAChC,EAAE,CAAC,qBAAqB,CAAC,MAAM,CAAC;gBAChC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC;gBAC3B,EAAE,CAAC,oBAAoB,CAAC,MAAM,CAAC;gBAC/B,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC;gBAC5B,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;gBAC3B,MAA6B,CAAC,IAAI,KAAK,IAAI,CAAC;YAC/C,IAAI,CAAC,cAAc,IAAI,CAAC,cAAc,EAAE,CAAC;gBACvC,MAAM,IAAI,GAAG,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACtD,MAAM,CACJ,IAAI,EACJ,qBAAqB,IAAI,CAAC,IAAI,wCAAwC;oBACpE,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAC7B,CAAC;YACJ,CAAC;QACH,CAAC;QAED,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC,CAAC;IAEF,KAAK,CAAC,EAAE,CAAC,CAAC;AACZ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAe;IAClD,MAAM,MAAM,GAAoB,EAAE,CAAC;IACnC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC1C,MAAM,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,oBAAoB,CAAC,IAAI,CAAC,CAAC;QAC9F,iBAAiB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** Thrown when a bundle fails validation; `message` is safe to surface to the author. */
|
|
2
|
+
export declare class BundleValidationError extends Error {
|
|
3
|
+
constructor(message: string);
|
|
4
|
+
}
|
|
5
|
+
export type ValidationResult = {
|
|
6
|
+
/** The bundle's exported SDL, or null for an API-extensions-only bundle. */
|
|
7
|
+
typeDefs: string | null;
|
|
8
|
+
/** The resolver root keys that matched a type in the schema (e.g. `Query`). */
|
|
9
|
+
resolverTypes: string[];
|
|
10
|
+
/** The keys of the bundle's commercetools API Extensions (empty if none). */
|
|
11
|
+
apiExtensionKeys: string[];
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Validate the bundle at `bundlePath`, having analysed the author's `sourceFiles`
|
|
15
|
+
* (the entry + its local imports, as reported by {@link buildBundle}). Resolves with
|
|
16
|
+
* the parsed metadata, or rejects with a {@link BundleValidationError} carrying a
|
|
17
|
+
* precise reason. Composition is the remote check's job (see the file header).
|
|
18
|
+
*/
|
|
19
|
+
export declare function validateBundle(bundlePath: string, sourceFiles: string[]): Promise<ValidationResult>;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// Validate a built bundle before it is pushed, so a broken one fails on the author's
|
|
2
|
+
// machine rather than when it is loaded live.
|
|
3
|
+
//
|
|
4
|
+
// Copied verbatim from commercetools/integration-layer-extension-examples
|
|
5
|
+
// (packages/tooling/src/validateBundle.ts). Two local checks (the push sends the SDL
|
|
6
|
+
// only, so these have no remote equivalent; composition is the remote check):
|
|
7
|
+
// 1. STATIC ANALYSIS of the source (staticAnalysis.ts) — run first, rejects the
|
|
8
|
+
// patterns that won't work at runtime.
|
|
9
|
+
// 2. SHAPE + COHERENCE — load the bundle and confirm it exports a non-empty
|
|
10
|
+
// `typeDefs` string and a `resolvers` object whose types/fields the SDL declares
|
|
11
|
+
// (a resolver naming an undeclared field is a silent runtime no-op).
|
|
12
|
+
import { readFile } from "node:fs/promises";
|
|
13
|
+
import { GraphQLInterfaceType, GraphQLObjectType, buildASTSchema, parse, } from "graphql";
|
|
14
|
+
import { loadBundleSource } from "./loadBundle.js";
|
|
15
|
+
import { analyzeSources } from "./staticAnalysis.js";
|
|
16
|
+
/** Thrown when a bundle fails validation; `message` is safe to surface to the author. */
|
|
17
|
+
export class BundleValidationError extends Error {
|
|
18
|
+
constructor(message) {
|
|
19
|
+
super(message);
|
|
20
|
+
this.name = "BundleValidationError";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
const API_EXTENSION_ACTIONS = new Set(['Create', 'Update']);
|
|
24
|
+
/**
|
|
25
|
+
* Validate the bundle's optional `apiExtensions` export (shape only — a handler's
|
|
26
|
+
* behaviour is the author's to test). Returns the declared keys.
|
|
27
|
+
*/
|
|
28
|
+
function validateApiExtensions(raw) {
|
|
29
|
+
if (raw === undefined)
|
|
30
|
+
return [];
|
|
31
|
+
if (!Array.isArray(raw)) {
|
|
32
|
+
throw new BundleValidationError('`apiExtensions` must be an array');
|
|
33
|
+
}
|
|
34
|
+
const keys = new Set();
|
|
35
|
+
raw.forEach((entry, i) => {
|
|
36
|
+
if (entry === null || typeof entry !== 'object') {
|
|
37
|
+
throw new BundleValidationError(`apiExtensions[${i}] must be an object`);
|
|
38
|
+
}
|
|
39
|
+
const e = entry;
|
|
40
|
+
const key = typeof e.key === 'string' ? e.key.trim() : '';
|
|
41
|
+
if (!/^[a-z0-9][a-z0-9-]*$/.test(key)) {
|
|
42
|
+
throw new BundleValidationError(`apiExtensions[${i}].key must be kebab-case (got '${String(e.key)}')`);
|
|
43
|
+
}
|
|
44
|
+
if (keys.has(key))
|
|
45
|
+
throw new BundleValidationError(`apiExtensions has a duplicate key '${key}'`);
|
|
46
|
+
keys.add(key);
|
|
47
|
+
if (typeof e.resourceTypeId !== 'string' || e.resourceTypeId.trim() === '') {
|
|
48
|
+
throw new BundleValidationError(`apiExtensions['${key}'].resourceTypeId must be a non-empty string`);
|
|
49
|
+
}
|
|
50
|
+
const actions = Array.isArray(e.actions) ? e.actions : [];
|
|
51
|
+
if (actions.length === 0 ||
|
|
52
|
+
!actions.every((a) => typeof a === 'string' && API_EXTENSION_ACTIONS.has(a))) {
|
|
53
|
+
throw new BundleValidationError(`apiExtensions['${key}'].actions must be a non-empty subset of ["Create","Update"]`);
|
|
54
|
+
}
|
|
55
|
+
if (typeof e.handler !== 'function') {
|
|
56
|
+
throw new BundleValidationError(`apiExtensions['${key}'].handler must be a function`);
|
|
57
|
+
}
|
|
58
|
+
if (e.condition !== undefined && typeof e.condition !== 'string') {
|
|
59
|
+
throw new BundleValidationError(`apiExtensions['${key}'].condition must be a string`);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
return [...keys];
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Validate the bundle at `bundlePath`, having analysed the author's `sourceFiles`
|
|
66
|
+
* (the entry + its local imports, as reported by {@link buildBundle}). Resolves with
|
|
67
|
+
* the parsed metadata, or rejects with a {@link BundleValidationError} carrying a
|
|
68
|
+
* precise reason. Composition is the remote check's job (see the file header).
|
|
69
|
+
*/
|
|
70
|
+
export async function validateBundle(bundlePath, sourceFiles) {
|
|
71
|
+
// 1. Static analysis of the author's source — runtime-incompatible patterns.
|
|
72
|
+
const issues = await analyzeSources(sourceFiles);
|
|
73
|
+
if (issues.length > 0) {
|
|
74
|
+
const lines = issues.map((i) => ` - ${i.file}:${i.line} — ${i.message}`).join("\n");
|
|
75
|
+
throw new BundleValidationError(`extension source uses features the runtime does not support:\n${lines}`);
|
|
76
|
+
}
|
|
77
|
+
// 2. Load the built bundle and check its shape + resolver/SDL coherence.
|
|
78
|
+
let mod;
|
|
79
|
+
try {
|
|
80
|
+
mod = loadBundleSource(await readFile(bundlePath, "utf8"));
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
throw new BundleValidationError(`bundle is not a loadable module: ${err.message}`);
|
|
84
|
+
}
|
|
85
|
+
const { typeDefs, resolvers } = mod;
|
|
86
|
+
const apiExtensionKeys = validateApiExtensions(mod.apiExtensions);
|
|
87
|
+
// A bundle must contribute at least one of a GraphQL subgraph or API Extensions.
|
|
88
|
+
const hasTypeDefs = typeof typeDefs === "string" && typeDefs.trim() !== "";
|
|
89
|
+
if (!hasTypeDefs) {
|
|
90
|
+
if (apiExtensionKeys.length === 0) {
|
|
91
|
+
throw new BundleValidationError("bundle must export a non-empty `typeDefs` string and/or an `apiExtensions` array");
|
|
92
|
+
}
|
|
93
|
+
// API-extensions-only bundle: no SDL to check, no remote composition.
|
|
94
|
+
return { typeDefs: null, resolverTypes: [], apiExtensionKeys };
|
|
95
|
+
}
|
|
96
|
+
if (resolvers === null || typeof resolvers !== "object") {
|
|
97
|
+
throw new BundleValidationError("bundle with `typeDefs` must also export a `resolvers` object");
|
|
98
|
+
}
|
|
99
|
+
let doc;
|
|
100
|
+
try {
|
|
101
|
+
doc = parse(typeDefs);
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
throw new BundleValidationError(`\`typeDefs\` is not valid GraphQL SDL: ${err.message}`);
|
|
105
|
+
}
|
|
106
|
+
// `assumeValidSDL` skips full re-validation (federation directives aren't defined
|
|
107
|
+
// here; the remote compose proves the SDL sound) but still rejects an SDL that
|
|
108
|
+
// references a type it never declares.
|
|
109
|
+
let schema;
|
|
110
|
+
try {
|
|
111
|
+
schema = buildASTSchema(doc, { assumeValidSDL: true });
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
throw new BundleValidationError(`\`typeDefs\` does not build into a valid schema: ${err.message}`);
|
|
115
|
+
}
|
|
116
|
+
// Coherence: every resolver type/field must exist in the schema. A typo here
|
|
117
|
+
// would otherwise be a silent no-op the runtime serves without complaint.
|
|
118
|
+
const resolverMap = resolvers;
|
|
119
|
+
const resolverTypes = [];
|
|
120
|
+
for (const typeName of Object.keys(resolverMap)) {
|
|
121
|
+
if (typeName.startsWith("__"))
|
|
122
|
+
continue; // e.g. __resolveType — not a schema type
|
|
123
|
+
const type = schema.getType(typeName);
|
|
124
|
+
if (!type) {
|
|
125
|
+
throw new BundleValidationError(`\`resolvers\` references type \`${typeName}\`, which \`typeDefs\` does not define`);
|
|
126
|
+
}
|
|
127
|
+
resolverTypes.push(typeName);
|
|
128
|
+
const fieldResolvers = resolverMap[typeName];
|
|
129
|
+
if (fieldResolvers &&
|
|
130
|
+
typeof fieldResolvers === "object" &&
|
|
131
|
+
(type instanceof GraphQLObjectType || type instanceof GraphQLInterfaceType)) {
|
|
132
|
+
const schemaFields = type.getFields();
|
|
133
|
+
for (const fieldName of Object.keys(fieldResolvers)) {
|
|
134
|
+
if (fieldName.startsWith("__"))
|
|
135
|
+
continue; // e.g. __resolveReference
|
|
136
|
+
if (!(fieldName in schemaFields)) {
|
|
137
|
+
throw new BundleValidationError(`resolver \`${typeName}.${fieldName}\` has no matching field in \`typeDefs\``);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return { typeDefs, resolverTypes, apiExtensionKeys };
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=validateBundle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateBundle.js","sourceRoot":"","sources":["../../../src/lib/tooling/validateBundle.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,50 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@commercetools/cli-topic-integration-layer",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
5
|
-
"license": "
|
|
6
|
-
"
|
|
7
|
-
"
|
|
3
|
+
"version": "0.2.2",
|
|
4
|
+
"description": "commercetools CLI plugin: integration-layer topic",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"LICENSE",
|
|
11
|
+
"README.md"
|
|
12
|
+
],
|
|
13
|
+
"publishConfig": {
|
|
14
|
+
"access": "public",
|
|
15
|
+
"registry": "https://registry.npmjs.org/"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"clean": "rimraf dist",
|
|
19
|
+
"build": "pnpm clean && tsc -p tsconfig.build.json",
|
|
20
|
+
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
|
|
21
|
+
"test": "vitest run --disable-console-intercept"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@apollo/composition": "^2.14.1",
|
|
25
|
+
"@apollo/gateway": "^2.14.1",
|
|
26
|
+
"@apollo/subgraph": "^2.14.1",
|
|
27
|
+
"@envelop/apollo-federation": "^8.1.1",
|
|
28
|
+
"@graphql-tools/merge": "^9.2.2",
|
|
29
|
+
"@oclif/core": "4.2.10",
|
|
30
|
+
"esbuild": "^0.28.0",
|
|
31
|
+
"graphql": "^16.9.0",
|
|
32
|
+
"graphql-yoga": "^5.21.2",
|
|
33
|
+
"typescript": "^5.7.2"
|
|
34
|
+
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"@commercetools/cli-plugin-auth": ">=0.0.6"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@commercetools/cli-plugin-auth": "0.0.6",
|
|
40
|
+
"@commercetools/platform-sdk": "8.25.0",
|
|
41
|
+
"@oclif/test": "^4.1.12",
|
|
42
|
+
"@types/node": "^22.10.2",
|
|
43
|
+
"rimraf": "^6.0.1",
|
|
44
|
+
"vitest": "^4.1.8"
|
|
45
|
+
},
|
|
46
|
+
"oclif": {
|
|
47
|
+
"topicSeparator": " ",
|
|
48
|
+
"commands": "./dist/commands"
|
|
49
|
+
}
|
|
8
50
|
}
|