@commercetools/cli-topic-integration-layer 0.0.0 → 0.2.1
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 +63 -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 +10 -0
- package/dist/commands/integration-layer/extension/build.js +19 -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 +13 -0
- package/dist/commands/integration-layer/extension/push.js +83 -0
- package/dist/commands/integration-layer/extension/push.js.map +1 -0
- package/dist/commands/integration-layer/extension/serve.d.ts +18 -0
- package/dist/commands/integration-layer/extension/serve.js +320 -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 +24 -0
- package/dist/commands/integration-layer/extension/status.js.map +1 -0
- package/dist/commands/integration-layer/extension/validate.d.ts +13 -0
- package/dist/commands/integration-layer/extension/validate.js +76 -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 +135 -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/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 +49 -0
- package/dist/lib/ilClient.js +108 -0
- package/dist/lib/ilClient.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/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 +46 -5
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
// Local dev server for an extension — the inner loop the build/validate/push flow
|
|
2
|
+
// lacks. It builds the bundle, loads it, serves an Apollo Federation v2 subgraph from
|
|
3
|
+
// its `typeDefs` + `resolvers`, and esbuild watches the source so an edit hot-swaps
|
|
4
|
+
// the served schema with no restart. The command wrapper is ours; the schema
|
|
5
|
+
// composition / gateway / SDL-fetch building blocks are the copied low-level tooling
|
|
6
|
+
// functions (compose.ts, gateway.ts, ilClient.fetchSubgraphSdl).
|
|
7
|
+
//
|
|
8
|
+
// Modes:
|
|
9
|
+
// serve standalone: the extension subgraph at /graphql.
|
|
10
|
+
// serve --compose + the merged schema (extension + integration layer) at /composed.
|
|
11
|
+
// serve --gateway /graphql becomes an executable federated gateway over the
|
|
12
|
+
// local extension + the deployed integration layer.
|
|
13
|
+
// --compose/--gateway reach the integration layer, so they need the auth flags/env
|
|
14
|
+
// (ilFlags); --gateway also mints an anonymous session for its calls.
|
|
15
|
+
import { createServer } from "node:http";
|
|
16
|
+
import { readFile } from "node:fs/promises";
|
|
17
|
+
import process from "node:process";
|
|
18
|
+
import { Flags } from "@oclif/core";
|
|
19
|
+
import { parse } from "graphql";
|
|
20
|
+
import { createYoga } from "graphql-yoga";
|
|
21
|
+
import { useApolloFederation } from "@envelop/apollo-federation";
|
|
22
|
+
import { buildSubgraphSchema } from "@apollo/subgraph";
|
|
23
|
+
import { context as esbuildContext } from "esbuild";
|
|
24
|
+
import { defaultEntry, defaultOutfile, HOST_PROVIDED_EXTERNALS } from "../../../lib/tooling/build.js";
|
|
25
|
+
import { loadBundleSource } from "../../../lib/tooling/loadBundle.js";
|
|
26
|
+
import { composeWithIntegrationLayer, } from "../../../lib/tooling/compose.js";
|
|
27
|
+
import { makeGateway, mintAnonymousSession } from "../../../lib/tooling/gateway.js";
|
|
28
|
+
import { fetchSubgraphSdl } from "../../../lib/ilClient.js";
|
|
29
|
+
import { IntegrationLayerCommand } from "../../../lib/base.js";
|
|
30
|
+
/**
|
|
31
|
+
* Per-project config the runtime injects as `ctx.config`. Locally there is no
|
|
32
|
+
* integration layer to read it from, so it's sourced from `EXTENSION_CONFIG_<KEY>`
|
|
33
|
+
* env vars — e.g. `EXTENSION_CONFIG_ALGOLIA_API_KEY=…` becomes `ctx.config.ALGOLIA_API_KEY`.
|
|
34
|
+
*/
|
|
35
|
+
function devConfigFromEnv() {
|
|
36
|
+
const prefix = "EXTENSION_CONFIG_";
|
|
37
|
+
const config = {};
|
|
38
|
+
for (const [key, value] of Object.entries(process.env)) {
|
|
39
|
+
if (key.startsWith(prefix) && typeof value === "string") {
|
|
40
|
+
config[key.slice(prefix.length)] = value;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return config;
|
|
44
|
+
}
|
|
45
|
+
function devContext() {
|
|
46
|
+
return { now: () => Date.now(), config: devConfigFromEnv() };
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Build a federation subgraph schema from the loaded bundle, the same way the runtime
|
|
50
|
+
* does. Throws (with a clean message) if the bundle didn't export a `typeDefs` string
|
|
51
|
+
* + `resolvers` object — the same shape `validateBundle` checks.
|
|
52
|
+
*/
|
|
53
|
+
function buildSubgraph(mod) {
|
|
54
|
+
const { typeDefs, resolvers } = mod;
|
|
55
|
+
if (typeof typeDefs !== "string" || typeDefs.trim() === "") {
|
|
56
|
+
throw new Error("bundle must export a non-empty `typeDefs` string");
|
|
57
|
+
}
|
|
58
|
+
if (resolvers === null || typeof resolvers !== "object") {
|
|
59
|
+
throw new Error("bundle must export a `resolvers` object");
|
|
60
|
+
}
|
|
61
|
+
// `@apollo/subgraph` types `resolvers` as its internal `GraphQLResolverMap`; the
|
|
62
|
+
// bundle's exports are `unknown` (validated above), so cast through the function's
|
|
63
|
+
// own parameter type rather than reaching into its `dist/` internals.
|
|
64
|
+
const moduleArg = { typeDefs: parse(typeDefs), resolvers };
|
|
65
|
+
return { schema: buildSubgraphSchema(moduleArg), typeDefs };
|
|
66
|
+
}
|
|
67
|
+
export default class ExtensionServe extends IntegrationLayerCommand {
|
|
68
|
+
static description = "Run a local dev server for the extension (subgraph, or a composed/federated gateway)";
|
|
69
|
+
static examples = [
|
|
70
|
+
"<%= config.bin %> integration-layer extension serve",
|
|
71
|
+
"<%= config.bin %> integration-layer extension serve --compose",
|
|
72
|
+
"<%= config.bin %> integration-layer extension serve --gateway --port 4000",
|
|
73
|
+
];
|
|
74
|
+
// Standalone serve needs no login; --compose/--gateway resolve the context lazily
|
|
75
|
+
// (and then require a logged-in principal) only when they actually reach the IL.
|
|
76
|
+
authorized = false;
|
|
77
|
+
static flags = {
|
|
78
|
+
port: Flags.integer({ char: "p", description: "port to listen on", default: 4000 }),
|
|
79
|
+
compose: Flags.boolean({
|
|
80
|
+
description: "also serve the merged (extension + integration layer) schema at /composed",
|
|
81
|
+
default: false,
|
|
82
|
+
}),
|
|
83
|
+
gateway: Flags.boolean({
|
|
84
|
+
description: "make /graphql an executable federated gateway over both subgraphs",
|
|
85
|
+
default: false,
|
|
86
|
+
}),
|
|
87
|
+
};
|
|
88
|
+
async run() {
|
|
89
|
+
const { flags } = await this.parse(ExtensionServe);
|
|
90
|
+
const entry = defaultEntry();
|
|
91
|
+
const outfile = defaultOutfile();
|
|
92
|
+
const port = flags.port;
|
|
93
|
+
// In gateway mode /graphql is the gateway, so the raw extension subgraph moves to
|
|
94
|
+
// an internal path the gateway reaches over HTTP. Otherwise /graphql is the subgraph.
|
|
95
|
+
const subgraphPath = flags.gateway ? "/_extension" : "/graphql";
|
|
96
|
+
const extensionUrl = `http://localhost:${port}${subgraphPath}`;
|
|
97
|
+
// --compose/--gateway fetch the integration-layer SDL once up front; --gateway
|
|
98
|
+
// also mints an anonymous session so its integration-layer calls authenticate.
|
|
99
|
+
const withIntegrationLayer = flags.compose || flags.gateway;
|
|
100
|
+
let integrationLayerSdl;
|
|
101
|
+
let integrationLayerGraphqlUrl = "";
|
|
102
|
+
let integrationLayerBearer;
|
|
103
|
+
if (withIntegrationLayer) {
|
|
104
|
+
const { baseUrl, projectKey, token } = await this.resolveIlContext(flags);
|
|
105
|
+
integrationLayerGraphqlUrl = `${baseUrl}/${encodeURIComponent(projectKey)}/graphql`;
|
|
106
|
+
this.log(`Fetching integration-layer subgraph SDL for '${projectKey}' from ${baseUrl} …`);
|
|
107
|
+
integrationLayerSdl = await fetchSubgraphSdl(baseUrl, projectKey, token);
|
|
108
|
+
if (flags.gateway) {
|
|
109
|
+
integrationLayerBearer = await mintAnonymousSession(baseUrl, projectKey);
|
|
110
|
+
this.log("Minted an anonymous session for the gateway.");
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Served-schema state, hot-swapped on each rebuild. The yoga factories/dispatcher
|
|
114
|
+
// below close over these, so a reload is picked up with no restart.
|
|
115
|
+
let subgraphSchema;
|
|
116
|
+
let composed;
|
|
117
|
+
// The gateway yoga handler + the supergraph it was built for. We only rebuild the
|
|
118
|
+
// (expensive) gateway when the supergraph SDL changes; a resolver-only edit is
|
|
119
|
+
// covered by the /_extension hot-reload alone. On a failed recompile we keep the
|
|
120
|
+
// last good gateway serving and log the errors.
|
|
121
|
+
let gatewayYoga;
|
|
122
|
+
let gatewaySupergraphSdl;
|
|
123
|
+
let apolloGateway;
|
|
124
|
+
const log = (m) => this.log(m);
|
|
125
|
+
const warn = (m) => {
|
|
126
|
+
this.logToStderr(m);
|
|
127
|
+
};
|
|
128
|
+
const ctx = await this.watchAndBuild(entry, outfile, async (built) => {
|
|
129
|
+
subgraphSchema = built.schema;
|
|
130
|
+
if (!withIntegrationLayer)
|
|
131
|
+
return;
|
|
132
|
+
composed = composeWithIntegrationLayer(integrationLayerSdl, built.typeDefs, {
|
|
133
|
+
integrationLayerUrl: integrationLayerGraphqlUrl,
|
|
134
|
+
extensionUrl,
|
|
135
|
+
});
|
|
136
|
+
if (!composed.ok) {
|
|
137
|
+
warn("✗ does not compose with the integration layer:");
|
|
138
|
+
for (const e of composed.errors)
|
|
139
|
+
warn(` - ${e}`);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
log(`✓ composes with the integration layer — full schema at http://localhost:${port}/composed`);
|
|
143
|
+
if (!flags.gateway)
|
|
144
|
+
return;
|
|
145
|
+
if (composed.supergraphSdl === gatewaySupergraphSdl) {
|
|
146
|
+
log(" (gateway plan unchanged — extension reloaded in place)");
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
const gw = await makeGateway({
|
|
151
|
+
supergraphSdl: composed.supergraphSdl,
|
|
152
|
+
integrationLayerBearer: integrationLayerBearer,
|
|
153
|
+
});
|
|
154
|
+
const prev = apolloGateway;
|
|
155
|
+
apolloGateway = gw;
|
|
156
|
+
gatewaySupergraphSdl = composed.supergraphSdl;
|
|
157
|
+
gatewayYoga = createYoga({
|
|
158
|
+
plugins: [useApolloFederation({ gateway: gw })],
|
|
159
|
+
graphqlEndpoint: "/graphql",
|
|
160
|
+
landingPage: false,
|
|
161
|
+
});
|
|
162
|
+
log(`✓ gateway ready at http://localhost:${port}/graphql`);
|
|
163
|
+
if (prev)
|
|
164
|
+
await prev.stop();
|
|
165
|
+
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
warn(`✗ gateway build failed: ${err.message}`);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
if (!subgraphSchema) {
|
|
171
|
+
await ctx.dispose();
|
|
172
|
+
this.error("initial build did not produce a valid subgraph (see errors above)");
|
|
173
|
+
}
|
|
174
|
+
if (withIntegrationLayer && !composed?.ok) {
|
|
175
|
+
warn(flags.gateway
|
|
176
|
+
? "⚠ extension does not compose with the integration layer yet — the gateway is " +
|
|
177
|
+
"unavailable until it does; fix the errors above and save to recompose."
|
|
178
|
+
: "⚠ extension does not compose with the integration layer yet — serving the " +
|
|
179
|
+
"standalone subgraph; fix the errors above and save to recompose.");
|
|
180
|
+
}
|
|
181
|
+
// The raw extension subgraph (executable). At /graphql normally, or the internal
|
|
182
|
+
// /_extension when the gateway owns /graphql.
|
|
183
|
+
const subgraphYoga = createYoga({
|
|
184
|
+
schema: () => subgraphSchema,
|
|
185
|
+
context: () => devContext(),
|
|
186
|
+
graphqlEndpoint: subgraphPath,
|
|
187
|
+
landingPage: false,
|
|
188
|
+
});
|
|
189
|
+
// The composed, client-facing merged schema — browsable/introspectable, not
|
|
190
|
+
// executable (no resolvers). Available in both --compose and --gateway.
|
|
191
|
+
const composedYoga = withIntegrationLayer
|
|
192
|
+
? createYoga({
|
|
193
|
+
schema: () => {
|
|
194
|
+
if (!composed?.ok) {
|
|
195
|
+
throw new Error(`extension does not compose with the integration layer:\n${(composed?.errors ?? []).join("\n")}`);
|
|
196
|
+
}
|
|
197
|
+
return composed.apiSchema;
|
|
198
|
+
},
|
|
199
|
+
graphqlEndpoint: "/composed",
|
|
200
|
+
landingPage: false,
|
|
201
|
+
})
|
|
202
|
+
: undefined;
|
|
203
|
+
const server = createServer((req, res) => {
|
|
204
|
+
const path = (req.url ?? "").split("?")[0];
|
|
205
|
+
// Plain-text SDL endpoints (handy for `curl > schema.graphql`).
|
|
206
|
+
if (req.method === "GET" && (path === "/schema.graphql" || path === "/supergraph.graphql")) {
|
|
207
|
+
if (!composed?.ok) {
|
|
208
|
+
res.statusCode = 503;
|
|
209
|
+
res.setHeader("content-type", "text/plain");
|
|
210
|
+
res.end(`extension does not compose with the integration layer:\n${(composed?.errors ?? []).join("\n")}\n`);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
res.setHeader("content-type", "text/plain; charset=utf-8");
|
|
214
|
+
res.end(path === "/schema.graphql" ? composed.apiSdl : composed.supergraphSdl);
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
if (composedYoga && path.startsWith("/composed"))
|
|
218
|
+
return void composedYoga(req, res);
|
|
219
|
+
if (flags.gateway && path.startsWith("/graphql")) {
|
|
220
|
+
if (!gatewayYoga) {
|
|
221
|
+
const errs = composed && !composed.ok ? composed.errors : [];
|
|
222
|
+
res.statusCode = 503;
|
|
223
|
+
res.setHeader("content-type", "text/plain");
|
|
224
|
+
res.end(`gateway not ready — extension does not compose with the integration layer:\n${errs.join("\n")}\n`);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
return void gatewayYoga(req, res);
|
|
228
|
+
}
|
|
229
|
+
// /_extension (gateway) or /graphql (standalone/compose).
|
|
230
|
+
return void subgraphYoga(req, res);
|
|
231
|
+
});
|
|
232
|
+
await new Promise((resolve) => server.listen(port, resolve));
|
|
233
|
+
const base = `http://localhost:${port}`;
|
|
234
|
+
const lines = [`\n🔌 ${entry} live:`];
|
|
235
|
+
lines.push(flags.gateway
|
|
236
|
+
? ` ${base}/graphql — FEDERATED gateway (local extension + deployed integration layer)`
|
|
237
|
+
: ` ${base}/graphql — extension subgraph`);
|
|
238
|
+
if (flags.gateway)
|
|
239
|
+
lines.push(` ${base}/_extension — the raw extension subgraph (gateway routes to it)`);
|
|
240
|
+
if (withIntegrationLayer) {
|
|
241
|
+
lines.push(` ${base}/composed — full merged schema (browsable; not executable)`);
|
|
242
|
+
lines.push(` ${base}/schema.graphql, ${base}/supergraph.graphql — SDL (text)`);
|
|
243
|
+
}
|
|
244
|
+
lines.push(` open ${base}/graphql in a browser for GraphiQL`);
|
|
245
|
+
lines.push(` watching ${entry} — edit and save to hot-reload\n`);
|
|
246
|
+
this.log(lines.join("\n"));
|
|
247
|
+
const shutdown = () => {
|
|
248
|
+
void ctx.dispose();
|
|
249
|
+
server.close(() => process.exit(0));
|
|
250
|
+
};
|
|
251
|
+
process.on("SIGINT", shutdown);
|
|
252
|
+
process.on("SIGTERM", shutdown);
|
|
253
|
+
// Keep the process alive; the server + esbuild watcher run until a signal.
|
|
254
|
+
await new Promise(() => { });
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Start esbuild in watch mode over the current example and feed `onBuild` a freshly
|
|
258
|
+
* loaded subgraph on every (re)build. Resolves once the initial build has produced
|
|
259
|
+
* one (so the caller can start serving); later rebuilds fire `onBuild` again.
|
|
260
|
+
*/
|
|
261
|
+
async watchAndBuild(entry, outfile, onBuild) {
|
|
262
|
+
const reload = async () => {
|
|
263
|
+
const source = await readFile(outfile, "utf8");
|
|
264
|
+
const mod = loadBundleSource(source);
|
|
265
|
+
await onBuild(buildSubgraph(mod));
|
|
266
|
+
};
|
|
267
|
+
let firstBuildDone;
|
|
268
|
+
const firstBuild = new Promise((resolve) => {
|
|
269
|
+
firstBuildDone = resolve;
|
|
270
|
+
});
|
|
271
|
+
let isFirstBuild = true;
|
|
272
|
+
const log = (m) => this.log(m);
|
|
273
|
+
const warn = (m) => this.logToStderr(m);
|
|
274
|
+
const ctx = await esbuildContext({
|
|
275
|
+
entryPoints: [entry],
|
|
276
|
+
outfile,
|
|
277
|
+
bundle: true,
|
|
278
|
+
format: "cjs",
|
|
279
|
+
platform: "neutral",
|
|
280
|
+
target: "node22",
|
|
281
|
+
conditions: ["worker"],
|
|
282
|
+
external: HOST_PROVIDED_EXTERNALS,
|
|
283
|
+
logLevel: "silent",
|
|
284
|
+
plugins: [
|
|
285
|
+
{
|
|
286
|
+
name: "il-serve-reload",
|
|
287
|
+
setup(build) {
|
|
288
|
+
build.onEnd(async (result) => {
|
|
289
|
+
try {
|
|
290
|
+
if (result.errors.length > 0) {
|
|
291
|
+
warn("✗ build failed — fix the error and save again");
|
|
292
|
+
for (const e of result.errors)
|
|
293
|
+
warn(` ${e.text}`);
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
try {
|
|
297
|
+
await reload();
|
|
298
|
+
log(`✓ ${isFirstBuild ? "built" : "reloaded"} ${entry}`);
|
|
299
|
+
}
|
|
300
|
+
catch (err) {
|
|
301
|
+
warn(`✗ reload failed: ${err.message}`);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
finally {
|
|
305
|
+
if (isFirstBuild) {
|
|
306
|
+
isFirstBuild = false;
|
|
307
|
+
firstBuildDone();
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
},
|
|
312
|
+
},
|
|
313
|
+
],
|
|
314
|
+
});
|
|
315
|
+
await ctx.watch();
|
|
316
|
+
await firstBuild;
|
|
317
|
+
return ctx;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
//# sourceMappingURL=serve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../../../../src/commands/integration-layer/extension/serve.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { fetchExtensionMeta } from "../../../lib/ilClient.js";
|
|
2
|
+
import { IntegrationLayerCommand } from "../../../lib/base.js";
|
|
3
|
+
export default class ExtensionStatus extends IntegrationLayerCommand {
|
|
4
|
+
static description = "Show the project's stored extension bundle (version, size, …)";
|
|
5
|
+
static examples = ["<%= config.bin %> integration-layer extension status"];
|
|
6
|
+
async run() {
|
|
7
|
+
const { flags } = await this.parse(ExtensionStatus);
|
|
8
|
+
const { baseUrl, projectKey, token } = await this.resolveIlContext(flags);
|
|
9
|
+
const meta = await fetchExtensionMeta(baseUrl, projectKey, token);
|
|
10
|
+
if (!meta) {
|
|
11
|
+
this.log(`No extension bundle is stored for '${projectKey}'.`);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
this.log(`Stored extension for '${projectKey}':`);
|
|
15
|
+
this.log(` version: ${meta.version}`);
|
|
16
|
+
this.log(` size: ${meta.length} bytes`);
|
|
17
|
+
this.log(` uploaded: ${new Date(meta.uploadedAt).toISOString()}`);
|
|
18
|
+
if (meta.filename)
|
|
19
|
+
this.log(` filename: ${meta.filename}`);
|
|
20
|
+
if (meta.updatedBy)
|
|
21
|
+
this.log(` updated by: ${meta.updatedBy}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../../src/commands/integration-layer/extension/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,uBAAuB;IAClE,MAAM,CAAU,WAAW,GAAG,+DAA+D,CAAC;IAE9F,MAAM,CAAU,QAAQ,GAAG,CAAC,sDAAsD,CAAC,CAAC;IAEpF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QACpD,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC1E,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;QAClE,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,CAAC,GAAG,CAAC,sCAAsC,UAAU,IAAI,CAAC,CAAC;YAC/D,OAAO;QACT,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,yBAAyB,UAAU,IAAI,CAAC,CAAC;QAClD,IAAI,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,MAAM,QAAQ,CAAC,CAAC;QAC/C,IAAI,CAAC,GAAG,CAAC,iBAAiB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACrE,IAAI,IAAI,CAAC,QAAQ;YAAE,IAAI,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC9D,IAAI,IAAI,CAAC,SAAS;YAAE,IAAI,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IAClE,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { IntegrationLayerCommand } from "../../../lib/base.js";
|
|
2
|
+
export default class ExtensionValidate extends IntegrationLayerCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
entry: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
out: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
skip: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
};
|
|
10
|
+
/** Print a remote validation result legibly. Returns true when it passed. */
|
|
11
|
+
private reportRemote;
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Flags } from "@oclif/core";
|
|
2
|
+
import { buildBundle, defaultEntry, defaultOutfile } from "../../../lib/tooling/build.js";
|
|
3
|
+
import { validateBundle, BundleValidationError } from "../../../lib/tooling/validateBundle.js";
|
|
4
|
+
import { remoteValidate } from "../../../lib/ilClient.js";
|
|
5
|
+
import { IntegrationLayerCommand } from "../../../lib/base.js";
|
|
6
|
+
export default class ExtensionValidate extends IntegrationLayerCommand {
|
|
7
|
+
static description = "Build, run local checks, then compose against the project schema and gate breaking changes";
|
|
8
|
+
static examples = [
|
|
9
|
+
"<%= config.bin %> integration-layer extension validate",
|
|
10
|
+
"<%= config.bin %> integration-layer extension validate --skip remote",
|
|
11
|
+
];
|
|
12
|
+
static flags = {
|
|
13
|
+
entry: Flags.string({ description: "extension entry source file", default: defaultEntry() }),
|
|
14
|
+
out: Flags.string({ description: "bundle output file", default: defaultOutfile() }),
|
|
15
|
+
skip: Flags.string({
|
|
16
|
+
description: "run only one half of the gate",
|
|
17
|
+
options: ["local", "remote"],
|
|
18
|
+
}),
|
|
19
|
+
};
|
|
20
|
+
/** Print a remote validation result legibly. Returns true when it passed. */
|
|
21
|
+
reportRemote(result) {
|
|
22
|
+
if (!result.composes) {
|
|
23
|
+
this.logToStderr("✗ extension does not compose with the integration layer supergraph:");
|
|
24
|
+
for (const err of result.compositionErrors)
|
|
25
|
+
this.logToStderr(` - ${err}`);
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
if (result.breakingChanges.length > 0) {
|
|
29
|
+
this.logToStderr("✗ extension introduces breaking changes to the published supergraph:");
|
|
30
|
+
for (const change of result.breakingChanges) {
|
|
31
|
+
this.logToStderr(` - [${change.type}] ${change.description}`);
|
|
32
|
+
}
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
if (!result.comparedToPublished) {
|
|
36
|
+
this.log("✓ composes with the integration layer supergraph (breaking-change check skipped: no published baseline)");
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
this.log("✓ composes with the integration layer supergraph and introduces no breaking changes");
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
async run() {
|
|
43
|
+
const { flags } = await this.parse(ExtensionValidate);
|
|
44
|
+
const { outfile, sourceFiles } = await buildBundle(flags.entry, flags.out);
|
|
45
|
+
let typeDefs = null;
|
|
46
|
+
if (flags.skip !== "local") {
|
|
47
|
+
try {
|
|
48
|
+
const local = await validateBundle(outfile, sourceFiles);
|
|
49
|
+
typeDefs = local.typeDefs;
|
|
50
|
+
this.log(`✓ local checks passed (resolver roots: ${local.resolverTypes.join(", ") || "none"}; ` +
|
|
51
|
+
`API extensions: ${local.apiExtensionKeys.join(", ") || "none"})`);
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
if (err instanceof BundleValidationError)
|
|
55
|
+
this.error(err.message);
|
|
56
|
+
throw err;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
// Skipping local: still need the SDL for the remote check — load it cheaply.
|
|
61
|
+
const local = await validateBundle(outfile, sourceFiles).catch(() => null);
|
|
62
|
+
typeDefs = local?.typeDefs ?? null;
|
|
63
|
+
}
|
|
64
|
+
if (flags.skip === "remote")
|
|
65
|
+
return;
|
|
66
|
+
if (typeDefs === null) {
|
|
67
|
+
this.log("· no GraphQL subgraph in this bundle — nothing to compose remotely.");
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const { baseUrl, projectKey, token } = await this.resolveIlContext(flags);
|
|
71
|
+
const result = await remoteValidate(baseUrl, projectKey, token, typeDefs);
|
|
72
|
+
if (!this.reportRemote(result))
|
|
73
|
+
this.error("remote validation failed.");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../../src/commands/integration-layer/extension/validate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
export default class IntegrationLayerHelloCommand extends Command {
|
|
3
|
+
static description = "Print a hello world message from the integration-layer topic";
|
|
4
|
+
static examples = ["<%= config.bin %> integration-layer hello"];
|
|
5
|
+
async run() {
|
|
6
|
+
await this.parse(IntegrationLayerHelloCommand);
|
|
7
|
+
this.log("Hello, world!");
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=hello.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hello.js","sourceRoot":"","sources":["../../../src/commands/integration-layer/hello.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,MAAM,CAAC,OAAO,OAAO,4BAA6B,SAAQ,OAAO;IAC/D,MAAM,CAAU,WAAW,GAAG,8DAA8D,CAAC;IAE7F,MAAM,CAAU,QAAQ,GAAG,CAAC,2CAA2C,CAAC,CAAC;IAEzE,KAAK,CAAC,GAAG;QACP,MAAM,IAAI,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAC/C,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC5B,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
export default class Init extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
directory: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
template: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
};
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { mkdir, readdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { Args, Command, Flags } from "@oclif/core";
|
|
4
|
+
// The `basic` template is vendored inline (no network fetch) — a minimal, buildable
|
|
5
|
+
// extension: a GraphQL subgraph field plus a commented API-Extension example. Keep it
|
|
6
|
+
// dependency-light so `extension build`/`validate` work on it out of the box.
|
|
7
|
+
const TEMPLATE_FILES = {
|
|
8
|
+
"src/extension.ts": `// A minimal integration-layer extension.
|
|
9
|
+
//
|
|
10
|
+
// Export a GraphQL subgraph (\`typeDefs\` + \`resolvers\`) to add fields to the graph,
|
|
11
|
+
// and/or \`apiExtensions\` to run synchronous commercetools cart/order callbacks.
|
|
12
|
+
// Build it with: commercetools integration-layer extension build
|
|
13
|
+
// Serve it with: commercetools integration-layer extension serve
|
|
14
|
+
|
|
15
|
+
export const typeDefs = /* GraphQL */ \`
|
|
16
|
+
type Query {
|
|
17
|
+
extensionInfo: String
|
|
18
|
+
}
|
|
19
|
+
\`;
|
|
20
|
+
|
|
21
|
+
export const resolvers = {
|
|
22
|
+
Query: {
|
|
23
|
+
extensionInfo: () => "hello from the integration-layer extension",
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// // Example API Extension (uncomment to block a cart line item by SKU):
|
|
28
|
+
// export const apiExtensions = [
|
|
29
|
+
// {
|
|
30
|
+
// key: "block-sku",
|
|
31
|
+
// resourceTypeId: "cart",
|
|
32
|
+
// actions: ["Create", "Update"],
|
|
33
|
+
// handler: (input, ctx) => {
|
|
34
|
+
// const blocked = ctx.config.BLOCKED_SKU ?? "BLOCKED-SKU";
|
|
35
|
+
// const items = input.resource.obj?.lineItems ?? [];
|
|
36
|
+
// if (items.some((li) => li.variant?.sku === blocked)) {
|
|
37
|
+
// return { errors: [{ code: "SkuBlocked", message: \\\`\\\${blocked} is not purchasable\\\` }] };
|
|
38
|
+
// }
|
|
39
|
+
// return {};
|
|
40
|
+
// },
|
|
41
|
+
// },
|
|
42
|
+
// ];
|
|
43
|
+
`,
|
|
44
|
+
"package.json": `{
|
|
45
|
+
"name": "integration-layer-extension",
|
|
46
|
+
"version": "0.0.0",
|
|
47
|
+
"private": true,
|
|
48
|
+
"type": "module",
|
|
49
|
+
"scripts": {
|
|
50
|
+
"build": "commercetools integration-layer extension build",
|
|
51
|
+
"serve": "commercetools integration-layer extension serve",
|
|
52
|
+
"push": "commercetools integration-layer extension push"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@commercetools/platform-sdk": "8.25.0",
|
|
56
|
+
"graphql": "^16.9.0",
|
|
57
|
+
"typescript": "^5.7.2"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
`,
|
|
61
|
+
"tsconfig.json": `{
|
|
62
|
+
"compilerOptions": {
|
|
63
|
+
"target": "ES2022",
|
|
64
|
+
"module": "NodeNext",
|
|
65
|
+
"moduleResolution": "NodeNext",
|
|
66
|
+
"strict": true,
|
|
67
|
+
"skipLibCheck": true,
|
|
68
|
+
"noEmit": true
|
|
69
|
+
},
|
|
70
|
+
"include": ["src/**/*"]
|
|
71
|
+
}
|
|
72
|
+
`,
|
|
73
|
+
".env.example": `# The authenticated commands (validate/push/status/delete, schema, config) reuse the
|
|
74
|
+
# token from \`commercetools auth login\` (as a manage_project client) — no credentials
|
|
75
|
+
# go here. Optionally override the integration-layer edge URL. Copy to .env.
|
|
76
|
+
INTEGRATION_LAYER_URL=
|
|
77
|
+
`,
|
|
78
|
+
".gitignore": `node_modules/
|
|
79
|
+
dist/
|
|
80
|
+
.env
|
|
81
|
+
`,
|
|
82
|
+
"README.md": `# integration-layer extension
|
|
83
|
+
|
|
84
|
+
Scaffolded by \`commercetools integration-layer init\`.
|
|
85
|
+
|
|
86
|
+
- \`commercetools integration-layer extension build\` — bundle \`src/extension.ts\`
|
|
87
|
+
- \`commercetools integration-layer extension serve\` — local dev server
|
|
88
|
+
- \`commercetools integration-layer extension push\` — validate + upload
|
|
89
|
+
|
|
90
|
+
Run \`commercetools auth login\` first — the authenticated commands (push/validate/
|
|
91
|
+
status/delete, schema, config) reuse that token. Optionally copy \`.env.example\` to
|
|
92
|
+
\`.env\` to override the integration-layer edge URL.
|
|
93
|
+
`,
|
|
94
|
+
};
|
|
95
|
+
export default class Init extends Command {
|
|
96
|
+
static description = "Scaffold an integration-layer extension project from a template";
|
|
97
|
+
static examples = [
|
|
98
|
+
"<%= config.bin %> integration-layer init my-extension",
|
|
99
|
+
"<%= config.bin %> integration-layer init my-extension --template basic",
|
|
100
|
+
];
|
|
101
|
+
static args = {
|
|
102
|
+
directory: Args.string({ description: "directory to scaffold into", required: true }),
|
|
103
|
+
};
|
|
104
|
+
static flags = {
|
|
105
|
+
template: Flags.string({
|
|
106
|
+
description: "the template to use",
|
|
107
|
+
options: ["basic"],
|
|
108
|
+
default: "basic",
|
|
109
|
+
}),
|
|
110
|
+
force: Flags.boolean({
|
|
111
|
+
char: "f",
|
|
112
|
+
description: "scaffold into a non-empty directory",
|
|
113
|
+
default: false,
|
|
114
|
+
}),
|
|
115
|
+
};
|
|
116
|
+
async run() {
|
|
117
|
+
const { args, flags } = await this.parse(Init);
|
|
118
|
+
const dir = args.directory;
|
|
119
|
+
const existing = await readdir(dir).catch(() => []);
|
|
120
|
+
if (existing.length > 0 && !flags.force) {
|
|
121
|
+
this.error(`Directory '${dir}' is not empty. Pass --force to scaffold into it anyway.`);
|
|
122
|
+
}
|
|
123
|
+
for (const [relPath, contents] of Object.entries(TEMPLATE_FILES)) {
|
|
124
|
+
const target = join(dir, relPath);
|
|
125
|
+
await mkdir(join(target, ".."), { recursive: true });
|
|
126
|
+
await writeFile(target, contents, "utf8");
|
|
127
|
+
}
|
|
128
|
+
this.log(`✓ scaffolded a '${flags.template}' extension in ${dir}`);
|
|
129
|
+
this.log("Next steps:");
|
|
130
|
+
this.log(` cd ${dir}`);
|
|
131
|
+
this.log(" npm install");
|
|
132
|
+
this.log(" commercetools integration-layer extension serve");
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=init.js.map
|