@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
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) commercetools GmbH
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# @commercetools/cli-topic-integration-layer
|
|
2
|
+
|
|
3
|
+
A [commercetools CLI](https://github.com/commercetools/cli) plugin that adds the
|
|
4
|
+
`integration-layer` topic. It is published to the public npm registry and installed on
|
|
5
|
+
demand as a runtime oclif plugin — it is never bundled into the base `@commercetools/cli`.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Public CLI. NB: use @dev for now — the `plugins` command (@oclif/plugin-plugins)
|
|
11
|
+
# is only in the CLI's dev prerelease; @latest (0.0.17) predates it. Drop to
|
|
12
|
+
# @latest once plugin-plugins is promoted to the latest release.
|
|
13
|
+
npm install -g @commercetools/cli@dev
|
|
14
|
+
|
|
15
|
+
# Opt in to the integration-layer topic (public npm — no auth needed)
|
|
16
|
+
commercetools plugins install @commercetools/cli-topic-integration-layer
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Commands
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
commercetools integration-layer init <DIR> # scaffold an extension project [local]
|
|
23
|
+
|
|
24
|
+
commercetools integration-layer extension build # bundle src/extension.ts -> dist [local]
|
|
25
|
+
commercetools integration-layer extension validate # local checks + remote compose/breaking gate
|
|
26
|
+
commercetools integration-layer extension push [--force] # build + validate + upload the bundle
|
|
27
|
+
commercetools integration-layer extension status # show the project's stored bundle
|
|
28
|
+
commercetools integration-layer extension delete [--yes] # remove the extension subgraph
|
|
29
|
+
|
|
30
|
+
commercetools integration-layer schema fetch [--out f] # print the project's core-subgraph SDL
|
|
31
|
+
|
|
32
|
+
commercetools integration-layer config list # config entries (secrets masked)
|
|
33
|
+
commercetools integration-layer config get <KEY>
|
|
34
|
+
commercetools integration-layer config set <KEY> <VALUE> [--secret]
|
|
35
|
+
commercetools integration-layer config unset <KEY>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Authenticated commands present the token from `commercetools auth login` (a
|
|
39
|
+
`manage_project` bearer) and resolve the integration-layer edge from
|
|
40
|
+
`--integration-layer-url` / `INTEGRATION_LAYER_URL` (a region-implied URL is a TODO).
|
|
41
|
+
`build` / `init` are local and need no login. See
|
|
42
|
+
[`integration-layer-cli-command-structure.md`](../../integration-layer-cli-command-structure.md)
|
|
43
|
+
for the full command → route mapping.
|
|
44
|
+
|
|
45
|
+
## Develop
|
|
46
|
+
|
|
47
|
+
This package lives in the octolog monorepo as the `integration-layer-cli` domain
|
|
48
|
+
(pnpm workspace, member `app/`). From the repo root:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pnpm ilc:install # install
|
|
52
|
+
pnpm ilc:build # tsc -> dist/
|
|
53
|
+
pnpm ilc:typecheck # tsc --noEmit (src + tests)
|
|
54
|
+
pnpm ilc:lint # eslint
|
|
55
|
+
pnpm ilc:test # vitest
|
|
56
|
+
|
|
57
|
+
# Run the built command directly against the public CLI's runner:
|
|
58
|
+
# commercetools plugins link . (from app/, after build)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## License
|
|
62
|
+
|
|
63
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { IntegrationLayerCommand } from "../../../lib/base.js";
|
|
2
|
+
export default class ConfigGet extends IntegrationLayerCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
key: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
run(): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Args } from "@oclif/core";
|
|
2
|
+
import { listConfig } from "../../../lib/ilClient.js";
|
|
3
|
+
import { IntegrationLayerCommand } from "../../../lib/base.js";
|
|
4
|
+
export default class ConfigGet extends IntegrationLayerCommand {
|
|
5
|
+
static description = "Print one extension config entry (secret values masked)";
|
|
6
|
+
static examples = ["<%= config.bin %> integration-layer config get ALGOLIA_APP_ID"];
|
|
7
|
+
static args = {
|
|
8
|
+
key: Args.string({ description: "the config entry key", required: true }),
|
|
9
|
+
};
|
|
10
|
+
async run() {
|
|
11
|
+
const { args, flags } = await this.parse(ConfigGet);
|
|
12
|
+
const { baseUrl, projectKey, token } = await this.resolveIlContext(flags);
|
|
13
|
+
const entries = await listConfig(baseUrl, projectKey, token);
|
|
14
|
+
const entry = entries.find((e) => e.key === args.key);
|
|
15
|
+
if (!entry) {
|
|
16
|
+
this.error(`No config entry '${args.key}' for '${projectKey}'.`);
|
|
17
|
+
}
|
|
18
|
+
const value = entry.secret ? "•••••• (secret)" : String(entry.value ?? "");
|
|
19
|
+
this.log(`${entry.key} = ${value}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=get.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get.js","sourceRoot":"","sources":["../../../../src/commands/integration-layer/config/get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,uBAAuB;IAC5D,MAAM,CAAU,WAAW,GAAG,yDAAyD,CAAC;IAExF,MAAM,CAAU,QAAQ,GAAG,CAAC,+DAA+D,CAAC,CAAC;IAE7F,MAAM,CAAU,IAAI,GAAG;QACrB,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,sBAAsB,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;KAC1E,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACpD,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC1E,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;QAC7D,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC;QACtD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,KAAK,CAAC,oBAAoB,IAAI,CAAC,GAAG,UAAU,UAAU,IAAI,CAAC,CAAC;QACnE,CAAC;QACD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QAC3E,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,MAAM,KAAK,EAAE,CAAC,CAAC;IACtC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { listConfig } from "../../../lib/ilClient.js";
|
|
2
|
+
import { IntegrationLayerCommand } from "../../../lib/base.js";
|
|
3
|
+
export default class ConfigList extends IntegrationLayerCommand {
|
|
4
|
+
static description = "List the project's extension config entries (secret values masked)";
|
|
5
|
+
static examples = ["<%= config.bin %> integration-layer config list"];
|
|
6
|
+
async run() {
|
|
7
|
+
const { flags } = await this.parse(ConfigList);
|
|
8
|
+
const { baseUrl, projectKey, token } = await this.resolveIlContext(flags);
|
|
9
|
+
const entries = await listConfig(baseUrl, projectKey, token);
|
|
10
|
+
if (entries.length === 0) {
|
|
11
|
+
this.log(`No extension config entries for '${projectKey}'.`);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
for (const e of entries) {
|
|
15
|
+
const value = e.secret ? "•••••• (secret)" : String(e.value ?? "");
|
|
16
|
+
this.log(`${e.key} = ${value}`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../../src/commands/integration-layer/config/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,uBAAuB;IAC7D,MAAM,CAAU,WAAW,GAAG,oEAAoE,CAAC;IAEnG,MAAM,CAAU,QAAQ,GAAG,CAAC,iDAAiD,CAAC,CAAC;IAE/E,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC/C,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC1E,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;QAC7D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,oCAAoC,UAAU,IAAI,CAAC,CAAC;YAC7D,OAAO;QACT,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;YACnE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,KAAK,EAAE,CAAC,CAAC;QAClC,CAAC;IACH,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { IntegrationLayerCommand } from "../../../lib/base.js";
|
|
2
|
+
export default class ConfigSet extends IntegrationLayerCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
key: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
value: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
8
|
+
};
|
|
9
|
+
static flags: {
|
|
10
|
+
secret: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
};
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Args, Flags } from "@oclif/core";
|
|
2
|
+
import { patchConfig } from "../../../lib/ilClient.js";
|
|
3
|
+
import { IntegrationLayerCommand } from "../../../lib/base.js";
|
|
4
|
+
export default class ConfigSet extends IntegrationLayerCommand {
|
|
5
|
+
static description = "Create or update an extension config entry";
|
|
6
|
+
static examples = [
|
|
7
|
+
"<%= config.bin %> integration-layer config set ALGOLIA_APP_ID abc123",
|
|
8
|
+
"<%= config.bin %> integration-layer config set ALGOLIA_API_KEY s3cr3t --secret",
|
|
9
|
+
];
|
|
10
|
+
static args = {
|
|
11
|
+
key: Args.string({ description: "the config entry key", required: true }),
|
|
12
|
+
value: Args.string({ description: "the value to store", required: true }),
|
|
13
|
+
};
|
|
14
|
+
static flags = {
|
|
15
|
+
secret: Flags.boolean({
|
|
16
|
+
description: "seal the value (write-only thereafter, encrypted at rest)",
|
|
17
|
+
default: false,
|
|
18
|
+
}),
|
|
19
|
+
};
|
|
20
|
+
async run() {
|
|
21
|
+
const { args, flags } = await this.parse(ConfigSet);
|
|
22
|
+
const { baseUrl, projectKey, token } = await this.resolveIlContext(flags);
|
|
23
|
+
await patchConfig(baseUrl, projectKey, token, [
|
|
24
|
+
{ key: args.key, value: args.value, secret: flags.secret },
|
|
25
|
+
]);
|
|
26
|
+
this.log(`✓ set '${args.key}'${flags.secret ? " (secret)" : ""} for '${projectKey}'.`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=set.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"set.js","sourceRoot":"","sources":["../../../../src/commands/integration-layer/config/set.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,uBAAuB;IAC5D,MAAM,CAAU,WAAW,GAAG,4CAA4C,CAAC;IAE3E,MAAM,CAAU,QAAQ,GAAG;QACzB,sEAAsE;QACtE,gFAAgF;KACjF,CAAC;IAEF,MAAM,CAAU,IAAI,GAAG;QACrB,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,sBAAsB,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QACzE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,oBAAoB,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;KAC1E,CAAC;IAEF,MAAM,CAAU,KAAK,GAAG;QACtB,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC;YACpB,WAAW,EAAE,2DAA2D;YACxE,OAAO,EAAE,KAAK;SACf,CAAC;KACH,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACpD,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC1E,MAAM,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE;YAC5C,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;SAC3D,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,UAAU,IAAI,CAAC,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,SAAS,UAAU,IAAI,CAAC,CAAC;IACzF,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { IntegrationLayerCommand } from "../../../lib/base.js";
|
|
2
|
+
export default class ConfigUnset extends IntegrationLayerCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
key: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
run(): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Args } from "@oclif/core";
|
|
2
|
+
import { patchConfig } from "../../../lib/ilClient.js";
|
|
3
|
+
import { IntegrationLayerCommand } from "../../../lib/base.js";
|
|
4
|
+
export default class ConfigUnset extends IntegrationLayerCommand {
|
|
5
|
+
static description = "Remove an extension config entry";
|
|
6
|
+
static examples = ["<%= config.bin %> integration-layer config unset ALGOLIA_APP_ID"];
|
|
7
|
+
static args = {
|
|
8
|
+
key: Args.string({ description: "the config entry key", required: true }),
|
|
9
|
+
};
|
|
10
|
+
async run() {
|
|
11
|
+
const { args, flags } = await this.parse(ConfigUnset);
|
|
12
|
+
const { baseUrl, projectKey, token } = await this.resolveIlContext(flags);
|
|
13
|
+
// A PATCH entry with `value: null` deletes that key (integration layer contract).
|
|
14
|
+
await patchConfig(baseUrl, projectKey, token, [{ key: args.key, value: null }]);
|
|
15
|
+
this.log(`✓ removed '${args.key}' from '${projectKey}'.`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=unset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unset.js","sourceRoot":"","sources":["../../../../src/commands/integration-layer/config/unset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,uBAAuB;IAC9D,MAAM,CAAU,WAAW,GAAG,kCAAkC,CAAC;IAEjE,MAAM,CAAU,QAAQ,GAAG,CAAC,iEAAiE,CAAC,CAAC;IAE/F,MAAM,CAAU,IAAI,GAAG;QACrB,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,sBAAsB,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;KAC1E,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACtD,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC1E,kFAAkF;QAClF,MAAM,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAChF,IAAI,CAAC,GAAG,CAAC,cAAc,IAAI,CAAC,GAAG,WAAW,UAAU,IAAI,CAAC,CAAC;IAC5D,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
export default class ExtensionBuild extends Command {
|
|
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
|
+
};
|
|
9
|
+
run(): Promise<void>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Command, Flags } from "@oclif/core";
|
|
2
|
+
import { buildBundle, defaultEntry, defaultOutfile } from "../../../lib/tooling/build.js";
|
|
3
|
+
export default class ExtensionBuild extends Command {
|
|
4
|
+
static description = "Bundle src/extension.ts into a single self-contained CommonJS artifact";
|
|
5
|
+
static examples = [
|
|
6
|
+
"<%= config.bin %> integration-layer extension build",
|
|
7
|
+
"<%= config.bin %> integration-layer extension build --entry src/extension.ts --out dist/extension.js",
|
|
8
|
+
];
|
|
9
|
+
static flags = {
|
|
10
|
+
entry: Flags.string({ description: "extension entry source file", default: defaultEntry() }),
|
|
11
|
+
out: Flags.string({ description: "bundle output file", default: defaultOutfile() }),
|
|
12
|
+
};
|
|
13
|
+
async run() {
|
|
14
|
+
const { flags } = await this.parse(ExtensionBuild);
|
|
15
|
+
const { outfile } = await buildBundle(flags.entry, flags.out);
|
|
16
|
+
this.log(`✓ bundled ${flags.entry} → ${outfile}`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../../../src/commands/integration-layer/extension/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE1F,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,OAAO;IACjD,MAAM,CAAU,WAAW,GACzB,wEAAwE,CAAC;IAE3E,MAAM,CAAU,QAAQ,GAAG;QACzB,qDAAqD;QACrD,sGAAsG;KACvG,CAAC;IAEF,MAAM,CAAU,KAAK,GAAG;QACtB,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,6BAA6B,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE,CAAC;QAC5F,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,oBAAoB,EAAE,OAAO,EAAE,cAAc,EAAE,EAAE,CAAC;KACpF,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QACnD,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,WAAW,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9D,IAAI,CAAC,GAAG,CAAC,aAAa,KAAK,CAAC,KAAK,MAAM,OAAO,EAAE,CAAC,CAAC;IACpD,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { IntegrationLayerCommand } from "../../../lib/base.js";
|
|
2
|
+
export default class ExtensionDelete extends IntegrationLayerCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
7
|
+
};
|
|
8
|
+
run(): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { createInterface } from "node:readline/promises";
|
|
2
|
+
import { stdin, stdout } from "node:process";
|
|
3
|
+
import { Flags } from "@oclif/core";
|
|
4
|
+
import { deleteExtensionSubgraph } from "../../../lib/ilClient.js";
|
|
5
|
+
import { IntegrationLayerCommand } from "../../../lib/base.js";
|
|
6
|
+
async function confirm(question) {
|
|
7
|
+
const rl = createInterface({ input: stdin, output: stdout });
|
|
8
|
+
try {
|
|
9
|
+
const answer = (await rl.question(`${question} `)).trim().toLowerCase();
|
|
10
|
+
return answer === "y" || answer === "yes";
|
|
11
|
+
}
|
|
12
|
+
finally {
|
|
13
|
+
rl.close();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export default class ExtensionDelete extends IntegrationLayerCommand {
|
|
17
|
+
static description = "Remove the extension subgraph from the project's published graph";
|
|
18
|
+
static examples = [
|
|
19
|
+
"<%= config.bin %> integration-layer extension delete",
|
|
20
|
+
"<%= config.bin %> integration-layer extension delete --yes",
|
|
21
|
+
];
|
|
22
|
+
static flags = {
|
|
23
|
+
yes: Flags.boolean({ char: "y", description: "skip the confirmation prompt", default: false }),
|
|
24
|
+
};
|
|
25
|
+
async run() {
|
|
26
|
+
const { flags } = await this.parse(ExtensionDelete);
|
|
27
|
+
const { baseUrl, projectKey, token } = await this.resolveIlContext(flags);
|
|
28
|
+
if (!flags.yes) {
|
|
29
|
+
const confirmed = await confirm(`Remove the extension subgraph for '${projectKey}' from the published graph? (y/N)`);
|
|
30
|
+
if (!confirmed) {
|
|
31
|
+
this.log("Aborted.");
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
await deleteExtensionSubgraph(baseUrl, projectKey, token);
|
|
36
|
+
this.log(`✓ removed the extension subgraph for '${projectKey}'.`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=delete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.js","sourceRoot":"","sources":["../../../../src/commands/integration-layer/extension/delete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,KAAK,UAAU,OAAO,CAAC,QAAgB;IACrC,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACxE,OAAO,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,KAAK,CAAC;IAC5C,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC;AAED,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,uBAAuB;IAClE,MAAM,CAAU,WAAW,GAAG,kEAAkE,CAAC;IAEjG,MAAM,CAAU,QAAQ,GAAG;QACzB,sDAAsD;QACtD,4DAA4D;KAC7D,CAAC;IAEF,MAAM,CAAU,KAAK,GAAG;QACtB,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,8BAA8B,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;KAC/F,CAAC;IAEF,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;QAE1E,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YACf,MAAM,SAAS,GAAG,MAAM,OAAO,CAC7B,sCAAsC,UAAU,mCAAmC,CACpF,CAAC;YACF,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBACrB,OAAO;YACT,CAAC;QACH,CAAC;QAED,MAAM,uBAAuB,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;QAC1D,IAAI,CAAC,GAAG,CAAC,yCAAyC,UAAU,IAAI,CAAC,CAAC;IACpE,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
export default class ExtensionInvoke extends Command {
|
|
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
|
+
action: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
sku: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
config: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
};
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { Command, Flags } from "@oclif/core";
|
|
3
|
+
import { buildBundle, defaultEntry, defaultOutfile } from "../../../lib/tooling/build.js";
|
|
4
|
+
import { loadBundleSource } from "../../../lib/tooling/loadBundle.js";
|
|
5
|
+
/** A sample commercetools cart callback payload. */
|
|
6
|
+
function sampleCartInput(action, sku) {
|
|
7
|
+
// A minimal sample callback for local testing. The real payload is the SDK's
|
|
8
|
+
// ExtensionInput (resource: a full Cart Reference); we send just the fields a
|
|
9
|
+
// cart handler reads, cast to the SDK type.
|
|
10
|
+
return {
|
|
11
|
+
action,
|
|
12
|
+
resource: {
|
|
13
|
+
typeId: "cart",
|
|
14
|
+
id: "sample-cart",
|
|
15
|
+
obj: {
|
|
16
|
+
id: "sample-cart",
|
|
17
|
+
lineItems: [{ id: "sample-line-item", quantity: 1, variant: { sku } }],
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function describeResult(result) {
|
|
23
|
+
if (result && typeof result === "object") {
|
|
24
|
+
if (Array.isArray(result.errors) && result.errors.length > 0) {
|
|
25
|
+
return `BLOCK — ${result.errors.map((e) => `${e.code}: ${e.message}`).join("; ")}`;
|
|
26
|
+
}
|
|
27
|
+
if (Array.isArray(result.actions) && result.actions.length > 0) {
|
|
28
|
+
return `MODIFY — ${JSON.stringify(result.actions)}`;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return "APPROVE";
|
|
32
|
+
}
|
|
33
|
+
export default class ExtensionInvoke extends Command {
|
|
34
|
+
static description = "Fire a sample commercetools cart callback at the bundle's API-Extension handlers";
|
|
35
|
+
static examples = [
|
|
36
|
+
"<%= config.bin %> integration-layer extension invoke",
|
|
37
|
+
"<%= config.bin %> integration-layer extension invoke --action Update --sku BLOCKED-SKU",
|
|
38
|
+
"<%= config.bin %> integration-layer extension invoke --config MAX_QTY=5 --config REGION=eu",
|
|
39
|
+
];
|
|
40
|
+
static flags = {
|
|
41
|
+
entry: Flags.string({ description: "extension entry source file", default: defaultEntry() }),
|
|
42
|
+
out: Flags.string({ description: "bundle output file", default: defaultOutfile() }),
|
|
43
|
+
action: Flags.string({
|
|
44
|
+
description: "the trigger action",
|
|
45
|
+
options: ["Create", "Update"],
|
|
46
|
+
default: "Create",
|
|
47
|
+
}),
|
|
48
|
+
sku: Flags.string({
|
|
49
|
+
description: "SKU on the sample cart's line item",
|
|
50
|
+
default: "BLOCKED-SKU",
|
|
51
|
+
}),
|
|
52
|
+
config: Flags.string({
|
|
53
|
+
description: "a ctx.config entry as KEY=VALUE (repeatable)",
|
|
54
|
+
multiple: true,
|
|
55
|
+
delimiter: ",",
|
|
56
|
+
}),
|
|
57
|
+
};
|
|
58
|
+
async run() {
|
|
59
|
+
const { flags } = await this.parse(ExtensionInvoke);
|
|
60
|
+
const config = {};
|
|
61
|
+
for (const pair of flags.config ?? []) {
|
|
62
|
+
const eq = pair.indexOf("=");
|
|
63
|
+
if (eq > 0)
|
|
64
|
+
config[pair.slice(0, eq)] = pair.slice(eq + 1);
|
|
65
|
+
}
|
|
66
|
+
const { outfile } = await buildBundle(flags.entry, flags.out);
|
|
67
|
+
const mod = loadBundleSource(await readFile(outfile, "utf8"));
|
|
68
|
+
const handlers = Array.isArray(mod.apiExtensions)
|
|
69
|
+
? mod.apiExtensions
|
|
70
|
+
: [];
|
|
71
|
+
if (handlers.length === 0) {
|
|
72
|
+
this.error("this bundle declares no `apiExtensions`.");
|
|
73
|
+
}
|
|
74
|
+
const action = flags.action;
|
|
75
|
+
const input = sampleCartInput(action, flags.sku);
|
|
76
|
+
const ctx = { now: () => Date.now(), config };
|
|
77
|
+
this.log(`Invoking ${handlers.length} handler(s) with a ${input.action} on cart ` +
|
|
78
|
+
`(line item SKU '${flags.sku}')`);
|
|
79
|
+
for (const h of handlers) {
|
|
80
|
+
if (h.resourceTypeId !== input.resource.typeId || !h.actions.includes(action)) {
|
|
81
|
+
this.log(` · ${h.key}: skipped (does not trigger on cart/${action})`);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
const result = await h.handler(input, ctx);
|
|
85
|
+
this.log(` → ${h.key}: ${describeResult(result)}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=invoke.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoke.js","sourceRoot":"","sources":["../../../../src/commands/integration-layer/extension/invoke.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { IntegrationLayerCommand } from "../../../lib/base.js";
|
|
2
|
+
export default class ExtensionPush 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
|
+
force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
};
|
|
10
|
+
/** True when the remote result should abort the push. */
|
|
11
|
+
private reportRemote;
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { basename } from "node:path";
|
|
3
|
+
import { Flags } from "@oclif/core";
|
|
4
|
+
import { buildBundle, defaultEntry, defaultOutfile } from "../../../lib/tooling/build.js";
|
|
5
|
+
import { validateBundle, BundleValidationError } from "../../../lib/tooling/validateBundle.js";
|
|
6
|
+
import { pushBundle, remoteValidate } from "../../../lib/ilClient.js";
|
|
7
|
+
import { IntegrationLayerCommand } from "../../../lib/base.js";
|
|
8
|
+
export default class ExtensionPush extends IntegrationLayerCommand {
|
|
9
|
+
static description = "Build + validate (local + remote) + upload the bundle, replacing the project's stored one";
|
|
10
|
+
static examples = [
|
|
11
|
+
"<%= config.bin %> integration-layer extension push",
|
|
12
|
+
"<%= config.bin %> integration-layer extension push --force",
|
|
13
|
+
];
|
|
14
|
+
static flags = {
|
|
15
|
+
entry: Flags.string({ description: "extension entry source file", default: defaultEntry() }),
|
|
16
|
+
out: Flags.string({ description: "bundle output file", default: defaultOutfile() }),
|
|
17
|
+
force: Flags.boolean({
|
|
18
|
+
char: "f",
|
|
19
|
+
description: "upload despite a failing REMOTE validation (the local check always hard-fails)",
|
|
20
|
+
default: false,
|
|
21
|
+
}),
|
|
22
|
+
};
|
|
23
|
+
/** True when the remote result should abort the push. */
|
|
24
|
+
reportRemote(result) {
|
|
25
|
+
if (!result.composes) {
|
|
26
|
+
this.logToStderr("✗ extension does not compose with the integration layer supergraph:");
|
|
27
|
+
for (const err of result.compositionErrors)
|
|
28
|
+
this.logToStderr(` - ${err}`);
|
|
29
|
+
}
|
|
30
|
+
else if (result.breakingChanges.length > 0) {
|
|
31
|
+
this.logToStderr("✗ extension introduces breaking changes to the published supergraph:");
|
|
32
|
+
for (const change of result.breakingChanges) {
|
|
33
|
+
this.logToStderr(` - [${change.type}] ${change.description}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
else if (!result.comparedToPublished) {
|
|
37
|
+
this.log("✓ composes with the integration layer supergraph (breaking-change check skipped: no published baseline)");
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
this.log("✓ composes with the integration layer supergraph and introduces no breaking changes");
|
|
41
|
+
}
|
|
42
|
+
return result.valid;
|
|
43
|
+
}
|
|
44
|
+
async run() {
|
|
45
|
+
const { flags } = await this.parse(ExtensionPush);
|
|
46
|
+
// Bundle, then VALIDATE before we touch the store. Local check first — it always
|
|
47
|
+
// hard-fails, regardless of --force.
|
|
48
|
+
const { outfile, sourceFiles } = await buildBundle(flags.entry, flags.out);
|
|
49
|
+
let typeDefs;
|
|
50
|
+
try {
|
|
51
|
+
const local = await validateBundle(outfile, sourceFiles);
|
|
52
|
+
typeDefs = local.typeDefs;
|
|
53
|
+
this.log(`✓ validated bundle (resolver roots: ${local.resolverTypes.join(", ") || "none"}; ` +
|
|
54
|
+
`API extensions: ${local.apiExtensionKeys.join(", ") || "none"})`);
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
if (err instanceof BundleValidationError)
|
|
58
|
+
this.error(err.message);
|
|
59
|
+
throw err;
|
|
60
|
+
}
|
|
61
|
+
const { baseUrl, projectKey, token } = await this.resolveIlContext(flags);
|
|
62
|
+
// Remote check composes the GraphQL subgraph WITH the integration layer + checks
|
|
63
|
+
// for breaking changes. Only applies when the bundle has a subgraph — an
|
|
64
|
+
// API-extensions-only bundle has no SDL, so skip straight to the upload.
|
|
65
|
+
if (typeDefs !== null) {
|
|
66
|
+
const remote = await remoteValidate(baseUrl, projectKey, token, typeDefs);
|
|
67
|
+
const valid = this.reportRemote(remote);
|
|
68
|
+
if (!valid) {
|
|
69
|
+
if (!flags.force) {
|
|
70
|
+
this.error("Aborting push. Re-run with --force to override the remote validation.");
|
|
71
|
+
}
|
|
72
|
+
this.logToStderr("⚠ forcing push despite failing validation (--force).");
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const bundle = await readFile(outfile, "utf8");
|
|
76
|
+
const filename = `${basename(outfile).replace(/\.[^.]+$/, "")}.cjs`;
|
|
77
|
+
const url = `${baseUrl}/${encodeURIComponent(projectKey)}/extension/bundle`;
|
|
78
|
+
this.log(`Pushing extension bundle (${bundle.length} bytes) → ${url}`);
|
|
79
|
+
const meta = await pushBundle(baseUrl, projectKey, token, bundle, filename);
|
|
80
|
+
this.log(`✓ stored revision ${meta.version} (${meta.length} bytes, filename ${meta.filename ?? filename})`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=push.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push.js","sourceRoot":"","sources":["../../../../src/commands/integration-layer/extension/push.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { IntegrationLayerCommand } from "../../../lib/base.js";
|
|
2
|
+
export default class ExtensionServe extends IntegrationLayerCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
protected authorized: boolean;
|
|
6
|
+
static flags: {
|
|
7
|
+
port: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
compose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
gateway: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Start esbuild in watch mode over the current example and feed `onBuild` a freshly
|
|
14
|
+
* loaded subgraph on every (re)build. Resolves once the initial build has produced
|
|
15
|
+
* one (so the caller can start serving); later rebuilds fire `onBuild` again.
|
|
16
|
+
*/
|
|
17
|
+
private watchAndBuild;
|
|
18
|
+
}
|