@commercetools/cli-topic-integration-layer 0.2.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/commands/integration-layer/explore.d.ts +20 -0
- package/dist/commands/integration-layer/explore.js +209 -0
- package/dist/commands/integration-layer/explore.js.map +1 -0
- package/dist/commands/integration-layer/extension/invoke.d.ts +1 -0
- package/dist/commands/integration-layer/extension/invoke.js +9 -4
- package/dist/commands/integration-layer/extension/invoke.js.map +1 -1
- package/dist/commands/integration-layer/extension/serve.d.ts +11 -0
- package/dist/commands/integration-layer/extension/serve.js +35 -5
- package/dist/commands/integration-layer/extension/serve.js.map +1 -1
- package/dist/commands/integration-layer/index.d.ts +9 -0
- package/dist/commands/integration-layer/index.js +28 -0
- package/dist/commands/integration-layer/index.js.map +1 -0
- package/dist/commands/integration-layer/init.js +11 -4
- package/dist/commands/integration-layer/init.js.map +1 -1
- package/dist/lib/base.d.ts +35 -0
- package/dist/lib/base.js +99 -13
- package/dist/lib/base.js.map +1 -1
- package/dist/lib/ilClient.d.ts +16 -0
- package/dist/lib/ilClient.js +28 -0
- package/dist/lib/ilClient.js.map +1 -1
- package/dist/lib/tooling/exploreSchema.d.ts +15 -0
- package/dist/lib/tooling/exploreSchema.js +77 -0
- package/dist/lib/tooling/exploreSchema.js.map +1 -0
- package/dist/lib/tooling/explorerPage.d.ts +1 -0
- package/dist/lib/tooling/explorerPage.js +96 -0
- package/dist/lib/tooling/explorerPage.js.map +1 -0
- package/dist/lib/tooling/explorerServer.d.ts +27 -0
- package/dist/lib/tooling/explorerServer.js +134 -0
- package/dist/lib/tooling/explorerServer.js.map +1 -0
- package/dist/lib/tooling/introspectionRequest.d.ts +13 -0
- package/dist/lib/tooling/introspectionRequest.js +47 -0
- package/dist/lib/tooling/introspectionRequest.js.map +1 -0
- package/dist/lib/tooling/session.d.ts +36 -0
- package/dist/lib/tooling/session.js +99 -0
- package/dist/lib/tooling/session.js.map +1 -0
- package/package.json +9 -12
package/dist/lib/base.d.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import { AuthCommand, CtpAuthorizedClient } from "@commercetools/cli-plugin-auth";
|
|
2
|
+
/**
|
|
3
|
+
* Reconstruct the logged-in principal from the persisted credentials file. Returns
|
|
4
|
+
* undefined when no valid client-credentials login is on disk (absent file, or a
|
|
5
|
+
* different auth kind), so unauthorized commands still run. No network. Exported for
|
|
6
|
+
* tests; commands go through {@link IntegrationLayerCommand.requirePrincipal}.
|
|
7
|
+
*/
|
|
8
|
+
export declare function loadPersistedPrincipal(credentialsFile?: string): Promise<CtpAuthorizedClient | undefined>;
|
|
2
9
|
/** The resolved, ready-to-use integration-layer context: where to call and as whom. */
|
|
3
10
|
export interface IlContext {
|
|
4
11
|
/** The integration-layer edge base URL, trailing slashes trimmed. */
|
|
@@ -26,6 +33,21 @@ export interface IlFlagValues {
|
|
|
26
33
|
* only when the region is absent, so resolveIlContext then fails loudly.
|
|
27
34
|
*/
|
|
28
35
|
export declare function edgeUrlForRegion(region: string): string | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* The GRAPHQL edge (the integration-router) for a region — where operations are
|
|
38
|
+
* actually served, at `/{project}/graphql`. A distinct host from the extensions
|
|
39
|
+
* edge above: the extensions edge is the connector backend (manage_project routes),
|
|
40
|
+
* the graphql edge is the router. `--graphql-url` / `IL_GRAPHQL_URL` overrides it
|
|
41
|
+
* for staging zones, which don't follow the production convention.
|
|
42
|
+
*/
|
|
43
|
+
export declare function graphqlEdgeUrlForRegion(region: string): string | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* The IDENTITY edge (the storefront pod) for a region — where sessions are minted,
|
|
46
|
+
* at `POST /{project}/session`. Again a distinct host from both of the above; the
|
|
47
|
+
* four-pod split put shopper identity, shopper GraphQL, and the machine surface on
|
|
48
|
+
* separate ingresses. `--auth-url` / `IL_AUTH_URL` overrides it.
|
|
49
|
+
*/
|
|
50
|
+
export declare function authEdgeUrlForRegion(region: string): string | undefined;
|
|
29
51
|
export declare abstract class IntegrationLayerCommand extends AuthCommand {
|
|
30
52
|
/**
|
|
31
53
|
* Whether the command needs a logged-in principal. True for every command that
|
|
@@ -34,11 +56,24 @@ export declare abstract class IntegrationLayerCommand extends AuthCommand {
|
|
|
34
56
|
* to fail loudly if the network path is actually taken.
|
|
35
57
|
*/
|
|
36
58
|
protected authorized: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* The principal loaded from `~/.commercetools/credentials` in {@link init}, or
|
|
61
|
+
* undefined when no valid login is persisted. Resolved once per command run so the
|
|
62
|
+
* synchronous {@link requirePrincipal} call sites (here and in `explore`) are unchanged.
|
|
63
|
+
*/
|
|
64
|
+
private persistedPrincipal?;
|
|
37
65
|
static baseFlags: {
|
|
38
66
|
"integration-layer-url": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
39
67
|
"project-key": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
40
68
|
};
|
|
41
69
|
protected init(): Promise<void>;
|
|
70
|
+
/**
|
|
71
|
+
* Read the persisted login from `~/.commercetools/credentials`. Returns undefined when
|
|
72
|
+
* no login is on disk (so unauthorized commands like standalone `serve` still run) and
|
|
73
|
+
* only fails loudly when the file is present but malformed. No network — the token was
|
|
74
|
+
* already minted by `auth login` and serialized whole.
|
|
75
|
+
*/
|
|
76
|
+
private loadPersistedPrincipal;
|
|
42
77
|
/** The logged-in commercetools principal, or an `AuthorizationError` pointing at `auth login`. */
|
|
43
78
|
protected requirePrincipal(): CtpAuthorizedClient;
|
|
44
79
|
/**
|
package/dist/lib/base.js
CHANGED
|
@@ -1,16 +1,62 @@
|
|
|
1
1
|
// Base class for the topic's commands that reach the integration layer's
|
|
2
|
-
// `manage_project` boundary.
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
// (loaded into the security context by the auth plugin's prerun hook) — no separate
|
|
6
|
-
// credential handling, exactly as the `connect` topic does.
|
|
2
|
+
// `manage_project` boundary. The bearer is the token `commercetools auth login`
|
|
3
|
+
// already persisted to `~/.commercetools/credentials`; we read it back from disk
|
|
4
|
+
// here rather than from the auth plugin's in-memory security context — see below.
|
|
7
5
|
//
|
|
8
|
-
// `@commercetools/cli-plugin-auth`
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
6
|
+
// `@commercetools/cli-plugin-auth` holds the security context in a MODULE-LEVEL
|
|
7
|
+
// STATIC (`SecurityContextHolder.globalContext`), so there is one context per loaded
|
|
8
|
+
// copy of that module. When this topic is bundled into the host CLI it resolves up
|
|
9
|
+
// into the host's single copy and the static the host fills is the one we read. But
|
|
10
|
+
// when the topic is installed via `oclif plugins install`, it lands in the oclif data
|
|
11
|
+
// dir's own node_modules tree, npm auto-installs the declared `cli-plugin-auth` there,
|
|
12
|
+
// and Node loads that as a SECOND, distinct module instance. `auth login`'s prerun
|
|
13
|
+
// hook (running in the host) fills the HOST copy's static; a read via the inherited
|
|
14
|
+
// `getAuthentication()` would hit the DATA-DIR copy's empty static and reject every
|
|
15
|
+
// logged-in caller ("not logged in"). This is not hypothetical — it is the exact
|
|
16
|
+
// failure mode that a CI symlink-dedupe workaround previously papered over.
|
|
17
|
+
//
|
|
18
|
+
// The cure is to stop depending on cross-copy static identity. `auth login` serializes
|
|
19
|
+
// the full principal (token, region, project key, scope, expiry) to
|
|
20
|
+
// `~/.commercetools/credentials` via the host CLI's `FileBasedAuthenticationRepository`.
|
|
21
|
+
// We reconstruct it from that same file, from THIS module's own copy of the repository
|
|
22
|
+
// — no network, no auth manager, no shared static — so it no longer matters whether one
|
|
23
|
+
// or two copies of `cli-plugin-auth` are loaded. Accordingly `cli-plugin-auth` is a
|
|
24
|
+
// regular `dependency`, not a peer: a second copy is now harmless. The path, auth id
|
|
25
|
+
// (`"client-credentials"`), and serialized shape mirror the host CLI's
|
|
26
|
+
// `providers.ts`/`init.ts` wiring exactly.
|
|
27
|
+
import os from "node:os";
|
|
28
|
+
import path from "node:path";
|
|
12
29
|
import { Flags } from "@oclif/core";
|
|
13
|
-
import { AuthCommand, AuthorizationError, CtpAuthorizedClient, } from "@commercetools/cli-plugin-auth";
|
|
30
|
+
import { AuthCommand, AuthorizationError, CtpAuthorizedClient, CtpClientAuthenticationToken, FileBasedAuthenticationRepository, } from "@commercetools/cli-plugin-auth";
|
|
31
|
+
/**
|
|
32
|
+
* Where `commercetools auth login` persists the serialized principal, and the auth id
|
|
33
|
+
* it files the client-credentials token under. These mirror the host CLI's
|
|
34
|
+
* `providers.ts` (`@commercetools/cli`) — the on-disk credentials contract — verbatim.
|
|
35
|
+
*/
|
|
36
|
+
const CREDENTIALS_FILE = path.join(os.homedir(), ".commercetools", "credentials");
|
|
37
|
+
const CLIENT_CREDENTIALS_AUTH_ID = "client-credentials";
|
|
38
|
+
/**
|
|
39
|
+
* A `FileBasedAuthenticationRepository` over the shared credentials file, wired to
|
|
40
|
+
* deserialize the client-credentials principal. Constructed from THIS module's copy of
|
|
41
|
+
* `cli-plugin-auth`, so `loadAuthentication()` reconstructs the principal regardless of
|
|
42
|
+
* how many copies of the auth plugin are loaded (see the header note).
|
|
43
|
+
*/
|
|
44
|
+
function persistedAuthenticationRepository(credentialsFile) {
|
|
45
|
+
const repository = new FileBasedAuthenticationRepository(credentialsFile);
|
|
46
|
+
repository.addSerializable(CLIENT_CREDENTIALS_AUTH_ID, CtpClientAuthenticationToken, CtpClientAuthenticationToken.Serializable);
|
|
47
|
+
return repository;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Reconstruct the logged-in principal from the persisted credentials file. Returns
|
|
51
|
+
* undefined when no valid client-credentials login is on disk (absent file, or a
|
|
52
|
+
* different auth kind), so unauthorized commands still run. No network. Exported for
|
|
53
|
+
* tests; commands go through {@link IntegrationLayerCommand.requirePrincipal}.
|
|
54
|
+
*/
|
|
55
|
+
export async function loadPersistedPrincipal(credentialsFile = CREDENTIALS_FILE) {
|
|
56
|
+
const authentication = await persistedAuthenticationRepository(credentialsFile).loadAuthentication();
|
|
57
|
+
const principal = authentication?.getPrincipal();
|
|
58
|
+
return principal instanceof CtpAuthorizedClient ? principal : undefined;
|
|
59
|
+
}
|
|
14
60
|
/**
|
|
15
61
|
* Derive the integration-layer EXTENSIONS edge base URL from the authenticated
|
|
16
62
|
* principal's commercetools region. The extensions edge — the connector-backend pod
|
|
@@ -30,6 +76,31 @@ export function edgeUrlForRegion(region) {
|
|
|
30
76
|
return undefined;
|
|
31
77
|
return `https://extensions.integration-layer.${trimmed}.commercetools.com`;
|
|
32
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* The GRAPHQL edge (the integration-router) for a region — where operations are
|
|
81
|
+
* actually served, at `/{project}/graphql`. A distinct host from the extensions
|
|
82
|
+
* edge above: the extensions edge is the connector backend (manage_project routes),
|
|
83
|
+
* the graphql edge is the router. `--graphql-url` / `IL_GRAPHQL_URL` overrides it
|
|
84
|
+
* for staging zones, which don't follow the production convention.
|
|
85
|
+
*/
|
|
86
|
+
export function graphqlEdgeUrlForRegion(region) {
|
|
87
|
+
const trimmed = region.trim();
|
|
88
|
+
if (!trimmed)
|
|
89
|
+
return undefined;
|
|
90
|
+
return `https://graphql.integration-layer.${trimmed}.commercetools.com`;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* The IDENTITY edge (the storefront pod) for a region — where sessions are minted,
|
|
94
|
+
* at `POST /{project}/session`. Again a distinct host from both of the above; the
|
|
95
|
+
* four-pod split put shopper identity, shopper GraphQL, and the machine surface on
|
|
96
|
+
* separate ingresses. `--auth-url` / `IL_AUTH_URL` overrides it.
|
|
97
|
+
*/
|
|
98
|
+
export function authEdgeUrlForRegion(region) {
|
|
99
|
+
const trimmed = region.trim();
|
|
100
|
+
if (!trimmed)
|
|
101
|
+
return undefined;
|
|
102
|
+
return `https://auth.integration-layer.${trimmed}.commercetools.com`;
|
|
103
|
+
}
|
|
33
104
|
export class IntegrationLayerCommand extends AuthCommand {
|
|
34
105
|
/**
|
|
35
106
|
* Whether the command needs a logged-in principal. True for every command that
|
|
@@ -38,6 +109,12 @@ export class IntegrationLayerCommand extends AuthCommand {
|
|
|
38
109
|
* to fail loudly if the network path is actually taken.
|
|
39
110
|
*/
|
|
40
111
|
authorized = true;
|
|
112
|
+
/**
|
|
113
|
+
* The principal loaded from `~/.commercetools/credentials` in {@link init}, or
|
|
114
|
+
* undefined when no valid login is persisted. Resolved once per command run so the
|
|
115
|
+
* synchronous {@link requirePrincipal} call sites (here and in `explore`) are unchanged.
|
|
116
|
+
*/
|
|
117
|
+
persistedPrincipal;
|
|
41
118
|
static baseFlags = {
|
|
42
119
|
"integration-layer-url": Flags.string({
|
|
43
120
|
description: "integration-layer extensions edge base URL (also settable via INTEGRATION_LAYER_URL); overrides the URL derived from your login region",
|
|
@@ -51,14 +128,23 @@ export class IntegrationLayerCommand extends AuthCommand {
|
|
|
51
128
|
};
|
|
52
129
|
async init() {
|
|
53
130
|
await super.init();
|
|
131
|
+
this.persistedPrincipal = await this.loadPersistedPrincipal();
|
|
54
132
|
if (this.authorized)
|
|
55
133
|
this.requirePrincipal();
|
|
56
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* Read the persisted login from `~/.commercetools/credentials`. Returns undefined when
|
|
137
|
+
* no login is on disk (so unauthorized commands like standalone `serve` still run) and
|
|
138
|
+
* only fails loudly when the file is present but malformed. No network — the token was
|
|
139
|
+
* already minted by `auth login` and serialized whole.
|
|
140
|
+
*/
|
|
141
|
+
async loadPersistedPrincipal() {
|
|
142
|
+
return loadPersistedPrincipal();
|
|
143
|
+
}
|
|
57
144
|
/** The logged-in commercetools principal, or an `AuthorizationError` pointing at `auth login`. */
|
|
58
145
|
requirePrincipal() {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
return principal;
|
|
146
|
+
if (this.persistedPrincipal)
|
|
147
|
+
return this.persistedPrincipal;
|
|
62
148
|
throw new AuthorizationError("not logged in — run `commercetools auth login` first");
|
|
63
149
|
}
|
|
64
150
|
/**
|
package/dist/lib/base.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/lib/base.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/lib/base.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/ilClient.d.ts
CHANGED
|
@@ -65,6 +65,22 @@ export interface RemoteValidationResult {
|
|
|
65
65
|
}
|
|
66
66
|
/** GET the project's raw core-subgraph SDL — the compose input (`GET …/subgraph`). */
|
|
67
67
|
export declare function fetchSubgraphSdl(baseUrl: string, projectKey: string, token: string): Promise<string>;
|
|
68
|
+
/**
|
|
69
|
+
* GET the project's DEPLOYED composed graph as a PUBLIC API SCHEMA — what the router
|
|
70
|
+
* actually plans and serves (core subgraph + the project's published extension),
|
|
71
|
+
* read from Hive by the integration layer and reduced there (`GET …/schema/api`).
|
|
72
|
+
*
|
|
73
|
+
* The integration layer strips the federation machinery before sending, so this is
|
|
74
|
+
* `buildSchema`-able as-is; there is no supergraph to reduce client-side. It is the
|
|
75
|
+
* byte-identical response the Merchant Center console's explorer reads under its
|
|
76
|
+
* own operator JWT — one artifact, two guards.
|
|
77
|
+
*
|
|
78
|
+
* This is the authenticated replacement for introspecting the public edge: the
|
|
79
|
+
* router runs `introspection: false`, so the composed graph is read here, over the
|
|
80
|
+
* same `manage_project` boundary as `/subgraph`. 404 means the project has never
|
|
81
|
+
* published a composable version.
|
|
82
|
+
*/
|
|
83
|
+
export declare function fetchDeployedApiSchemaSdl(baseUrl: string, projectKey: string, token: string): Promise<string>;
|
|
68
84
|
/** POST a candidate SDL to the composition + breaking-change gate (`POST …/extension/validate`). */
|
|
69
85
|
export declare function remoteValidate(baseUrl: string, projectKey: string, token: string, typeDefs: string): Promise<RemoteValidationResult>;
|
|
70
86
|
/**
|
package/dist/lib/ilClient.js
CHANGED
|
@@ -22,6 +22,34 @@ export async function fetchSubgraphSdl(baseUrl, projectKey, token) {
|
|
|
22
22
|
}
|
|
23
23
|
return text;
|
|
24
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* GET the project's DEPLOYED composed graph as a PUBLIC API SCHEMA — what the router
|
|
27
|
+
* actually plans and serves (core subgraph + the project's published extension),
|
|
28
|
+
* read from Hive by the integration layer and reduced there (`GET …/schema/api`).
|
|
29
|
+
*
|
|
30
|
+
* The integration layer strips the federation machinery before sending, so this is
|
|
31
|
+
* `buildSchema`-able as-is; there is no supergraph to reduce client-side. It is the
|
|
32
|
+
* byte-identical response the Merchant Center console's explorer reads under its
|
|
33
|
+
* own operator JWT — one artifact, two guards.
|
|
34
|
+
*
|
|
35
|
+
* This is the authenticated replacement for introspecting the public edge: the
|
|
36
|
+
* router runs `introspection: false`, so the composed graph is read here, over the
|
|
37
|
+
* same `manage_project` boundary as `/subgraph`. 404 means the project has never
|
|
38
|
+
* published a composable version.
|
|
39
|
+
*/
|
|
40
|
+
export async function fetchDeployedApiSchemaSdl(baseUrl, projectKey, token) {
|
|
41
|
+
const url = `${apiRoot(baseUrl, projectKey)}/schema/api`;
|
|
42
|
+
const res = await fetch(url, { headers: { accept: "text/plain", ...bearer(token) } });
|
|
43
|
+
const text = await res.text();
|
|
44
|
+
if (res.status === 404) {
|
|
45
|
+
throw new Error(`project '${projectKey}' has no composed schema published yet — publish one from the ` +
|
|
46
|
+
`Merchant Center console (Schema → Refresh schema), or drop --deployed to compose locally`);
|
|
47
|
+
}
|
|
48
|
+
if (!res.ok) {
|
|
49
|
+
throw new Error(`could not fetch the deployed composed schema (${res.status}) from ${url}: ${text}`);
|
|
50
|
+
}
|
|
51
|
+
return text;
|
|
52
|
+
}
|
|
25
53
|
/** POST a candidate SDL to the composition + breaking-change gate (`POST …/extension/validate`). */
|
|
26
54
|
export async function remoteValidate(baseUrl, projectKey, token, typeDefs) {
|
|
27
55
|
const url = `${apiRoot(baseUrl, projectKey)}/extension/validate`;
|
package/dist/lib/ilClient.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ilClient.js","sourceRoot":"","sources":["../../src/lib/ilClient.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ilClient.js","sourceRoot":"","sources":["../../src/lib/ilClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type GraphQLSchema } from "graphql";
|
|
2
|
+
/** A resolved explorer schema plus how it was obtained (for the startup banner). */
|
|
3
|
+
export interface ExplorerSchema {
|
|
4
|
+
schema: GraphQLSchema;
|
|
5
|
+
sdl: string;
|
|
6
|
+
/** e.g. `local compose (core + your extension)` or `deployed (Hive)`. */
|
|
7
|
+
describe: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The local-composition path: the project's core subgraph, plus `extensionSdl` when
|
|
11
|
+
* the caller found a local extension to build. Throws with the composition errors
|
|
12
|
+
* when the two don't compose — the same failure `extension validate` reports, and a
|
|
13
|
+
* real answer rather than a half-rendered explorer.
|
|
14
|
+
*/
|
|
15
|
+
export declare function composeLocalExplorerSchema(coreSdl: string, extensionSdl: string | undefined): ExplorerSchema;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// The schema the local explorer renders — resolved one of two ways.
|
|
2
|
+
//
|
|
3
|
+
// default compose locally: the project's core-subgraph SDL (GET /subgraph)
|
|
4
|
+
// plus, when the working directory holds one, your LOCAL extension.
|
|
5
|
+
// Fast inner loop: edit the extension, restart, see your fields.
|
|
6
|
+
//
|
|
7
|
+
// --deployed the project's DEPLOYED composed graph (GET /schema/api), read from
|
|
8
|
+
// Hive by the integration layer and reduced THERE to a public API
|
|
9
|
+
// schema — exactly what the router plans and serves, including
|
|
10
|
+
// whichever extension is actually deployed. The command just
|
|
11
|
+
// buildSchema()s it, so nothing in this module handles that path.
|
|
12
|
+
//
|
|
13
|
+
// Only the LOCAL path composes, which is why this module exists at all: a supergraph
|
|
14
|
+
// can't be composed on the server for a working-tree extension that was never pushed.
|
|
15
|
+
// Both paths end at a client-facing `GraphQLSchema`, which the explorer serves to
|
|
16
|
+
// GraphiQL (answering introspection locally). Execution is proxied to the real edge
|
|
17
|
+
// either way — this schema drives the docs pane, autocomplete, and validation only.
|
|
18
|
+
import { printSchema } from "graphql";
|
|
19
|
+
import { composeServices } from "@apollo/composition";
|
|
20
|
+
import { parse } from "graphql";
|
|
21
|
+
import { composeWithIntegrationLayer, INTEGRATION_LAYER_SERVICE, } from "./compose.js";
|
|
22
|
+
/** Placeholder URLs baked into a locally-composed supergraph. The explorer never
|
|
23
|
+
* routes through them (it proxies whole operations to the edge), so they are
|
|
24
|
+
* cosmetic — but composition requires each subgraph to declare one. */
|
|
25
|
+
const LOCAL_IL_URL = "http://integration-layer.local/graphql";
|
|
26
|
+
const LOCAL_EXTENSION_URL = "http://extension.local/graphql";
|
|
27
|
+
/**
|
|
28
|
+
* Compose the core subgraph ALONE into an API schema — the local path when the
|
|
29
|
+
* working directory has no extension. `composeWithIntegrationLayer` takes two
|
|
30
|
+
* subgraphs, so the single-subgraph case goes straight to `composeServices`.
|
|
31
|
+
*/
|
|
32
|
+
function composeCoreOnly(coreSdl) {
|
|
33
|
+
let services;
|
|
34
|
+
try {
|
|
35
|
+
services = [
|
|
36
|
+
{ name: INTEGRATION_LAYER_SERVICE, typeDefs: parse(coreSdl), url: LOCAL_IL_URL },
|
|
37
|
+
];
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
return { ok: false, errors: [`core-subgraph SDL is not valid GraphQL: ${err.message}`] };
|
|
41
|
+
}
|
|
42
|
+
const result = composeServices(services);
|
|
43
|
+
if (result.errors)
|
|
44
|
+
return { ok: false, errors: result.errors.map((e) => e.message) };
|
|
45
|
+
const apiSchema = result.schema.toAPISchema().toGraphQLJSSchema();
|
|
46
|
+
return {
|
|
47
|
+
ok: true,
|
|
48
|
+
apiSchema,
|
|
49
|
+
apiSdl: printSchema(apiSchema),
|
|
50
|
+
supergraphSdl: result.supergraphSdl,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The local-composition path: the project's core subgraph, plus `extensionSdl` when
|
|
55
|
+
* the caller found a local extension to build. Throws with the composition errors
|
|
56
|
+
* when the two don't compose — the same failure `extension validate` reports, and a
|
|
57
|
+
* real answer rather than a half-rendered explorer.
|
|
58
|
+
*/
|
|
59
|
+
export function composeLocalExplorerSchema(coreSdl, extensionSdl) {
|
|
60
|
+
const result = extensionSdl
|
|
61
|
+
? composeWithIntegrationLayer(coreSdl, extensionSdl, {
|
|
62
|
+
integrationLayerUrl: LOCAL_IL_URL,
|
|
63
|
+
extensionUrl: LOCAL_EXTENSION_URL,
|
|
64
|
+
})
|
|
65
|
+
: composeCoreOnly(coreSdl);
|
|
66
|
+
if (!result.ok) {
|
|
67
|
+
throw new Error(`could not compose the schema locally:\n${result.errors.map((e) => ` - ${e}`).join("\n")}`);
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
schema: result.apiSchema,
|
|
71
|
+
sdl: result.apiSdl,
|
|
72
|
+
describe: extensionSdl
|
|
73
|
+
? "local compose (core subgraph + your local extension)"
|
|
74
|
+
: "local compose (core subgraph only — no extension in this directory)",
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=exploreSchema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exploreSchema.js","sourceRoot":"","sources":["../../../src/lib/tooling/exploreSchema.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,EAAE;AACF,kFAAkF;AAClF,mFAAmF;AACnF,gFAAgF;AAChF,EAAE;AACF,oFAAoF;AACpF,iFAAiF;AACjF,8EAA8E;AAC9E,4EAA4E;AAC5E,iFAAiF;AACjF,EAAE;AACF,qFAAqF;AACrF,sFAAsF;AACtF,kFAAkF;AAClF,oFAAoF;AACpF,oFAAoF;AAEpF,OAAO,EAAE,WAAW,EAAsB,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,GAE1B,MAAM,cAAc,CAAC;AAEtB;;wEAEwE;AACxE,MAAM,YAAY,GAAG,wCAAwC,CAAC;AAC9D,MAAM,mBAAmB,GAAG,gCAAgC,CAAC;AAU7D;;;;GAIG;AACH,SAAS,eAAe,CAAC,OAAe;IACtC,IAAI,QAAQ,CAAC;IACb,IAAI,CAAC;QACH,QAAQ,GAAG;YACT,EAAE,IAAI,EAAE,yBAAyB,EAAE,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,YAAY,EAAE;SACjF,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,2CAA4C,GAAa,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;IACtG,CAAC;IACD,MAAM,MAAM,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,MAAM,CAAC,MAAM;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACrF,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,iBAAiB,EAAE,CAAC;IAClE,OAAO;QACL,EAAE,EAAE,IAAI;QACR,SAAS;QACT,MAAM,EAAE,WAAW,CAAC,SAAS,CAAC;QAC9B,aAAa,EAAE,MAAM,CAAC,aAAa;KACpC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,0BAA0B,CACxC,OAAe,EACf,YAAgC;IAEhC,MAAM,MAAM,GAAG,YAAY;QACzB,CAAC,CAAC,2BAA2B,CAAC,OAAO,EAAE,YAAY,EAAE;YACjD,mBAAmB,EAAE,YAAY;YACjC,YAAY,EAAE,mBAAmB;SAClC,CAAC;QACJ,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IAE7B,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,0CAA0C,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC5F,CAAC;IACJ,CAAC;IACD,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,SAAS;QACxB,GAAG,EAAE,MAAM,CAAC,MAAM;QAClB,QAAQ,EAAE,YAAY;YACpB,CAAC,CAAC,sDAAsD;YACxD,CAAC,CAAC,qEAAqE;KAC1E,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const EXPLORER_HTML: string;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// The GraphiQL page the local explorer serves at `/`.
|
|
2
|
+
//
|
|
3
|
+
// A static HTML shell loading GraphiQL from a CDN (esm.sh, version-pinned + SRI),
|
|
4
|
+
// pointed at this same local server's `/graphql`. Nothing is templated into it: the
|
|
5
|
+
// project key, the edge URL, and the session bearer all live server-side, so the
|
|
6
|
+
// page holds no credential and needs no configuration.
|
|
7
|
+
//
|
|
8
|
+
// The local server answers introspection itself from the resolved schema and proxies
|
|
9
|
+
// everything else to the deployed edge, so GraphiQL gets full docs/autocomplete even
|
|
10
|
+
// though the edge itself has introspection disabled.
|
|
11
|
+
export const EXPLORER_HTML = String.raw `<!doctype html>
|
|
12
|
+
<html lang="en">
|
|
13
|
+
<head>
|
|
14
|
+
<meta charset="utf-8" />
|
|
15
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
16
|
+
<title>GraphQL Explorer · commercetools integration layer</title>
|
|
17
|
+
<style>
|
|
18
|
+
body { margin: 0; height: 100dvh; overflow: hidden; }
|
|
19
|
+
#graphiql { height: 100dvh; }
|
|
20
|
+
.loading { display: flex; height: 100dvh; align-items: center;
|
|
21
|
+
justify-content: center; font-family: ui-sans-serif, system-ui, sans-serif;
|
|
22
|
+
color: #6b7280; }
|
|
23
|
+
</style>
|
|
24
|
+
<link
|
|
25
|
+
rel="stylesheet"
|
|
26
|
+
href="https://esm.sh/graphiql@5.2.4/dist/style.css"
|
|
27
|
+
integrity="sha384-TFpQQKp325U5sd3PddH4cS0KOB3Gz/aqdEe12Mqkkq3wm2MGcDhRX5WhWf+o8akh"
|
|
28
|
+
crossorigin="anonymous"
|
|
29
|
+
/>
|
|
30
|
+
<link
|
|
31
|
+
rel="stylesheet"
|
|
32
|
+
href="https://esm.sh/@graphiql/plugin-explorer@5.1.3/dist/style.css"
|
|
33
|
+
integrity="sha384-vTFGj0krVqwFXLB7kq/VHR0/j2+cCT/B63rge2mULaqnib2OX7DVLUVksTlqvMab"
|
|
34
|
+
crossorigin="anonymous"
|
|
35
|
+
/>
|
|
36
|
+
<script type="importmap">
|
|
37
|
+
{
|
|
38
|
+
"imports": {
|
|
39
|
+
"react": "https://esm.sh/react@19.2.0",
|
|
40
|
+
"react/jsx-runtime": "https://esm.sh/react@19.2.0/jsx-runtime",
|
|
41
|
+
"react-dom": "https://esm.sh/react-dom@19.2.0",
|
|
42
|
+
"react-dom/client": "https://esm.sh/react-dom@19.2.0/client",
|
|
43
|
+
"graphql": "https://esm.sh/graphql@16.11.0",
|
|
44
|
+
"graphiql": "https://esm.sh/graphiql@5.2.4?standalone&external=react,react-dom,@graphiql/react,graphql",
|
|
45
|
+
"graphiql/": "https://esm.sh/graphiql@5.2.4/",
|
|
46
|
+
"@graphiql/plugin-explorer": "https://esm.sh/@graphiql/plugin-explorer@5.1.3?standalone&external=react,@graphiql/react,graphql",
|
|
47
|
+
"@graphiql/react": "https://esm.sh/@graphiql/react@0.37.7?standalone&external=react,react-dom,graphql,@graphiql/toolkit,@emotion/is-prop-valid",
|
|
48
|
+
"@graphiql/toolkit": "https://esm.sh/@graphiql/toolkit@0.12.1?standalone&external=graphql"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
</script>
|
|
52
|
+
</head>
|
|
53
|
+
<body>
|
|
54
|
+
<div id="graphiql"><div class="loading">Loading the explorer…</div></div>
|
|
55
|
+
<script type="module">
|
|
56
|
+
import React from 'react';
|
|
57
|
+
import ReactDOM from 'react-dom/client';
|
|
58
|
+
import { GraphiQL, HISTORY_PLUGIN } from 'graphiql';
|
|
59
|
+
import { createGraphiQLFetcher } from '@graphiql/toolkit';
|
|
60
|
+
import { explorerPlugin } from '@graphiql/plugin-explorer';
|
|
61
|
+
import 'graphiql/setup-workers/esm.sh';
|
|
62
|
+
|
|
63
|
+
// Same-origin: this page and the GraphQL endpoint are both served by the CLI's
|
|
64
|
+
// local server, which holds the session bearer and forwards to the edge.
|
|
65
|
+
const fetcher = createGraphiQLFetcher({ url: location.origin + '/graphql' });
|
|
66
|
+
|
|
67
|
+
const plugins = [HISTORY_PLUGIN, explorerPlugin()];
|
|
68
|
+
|
|
69
|
+
const DEFAULT_QUERY = [
|
|
70
|
+
'# Local GraphQL explorer for your commercetools integration layer.',
|
|
71
|
+
'#',
|
|
72
|
+
'# Operations run against the DEPLOYED edge under the session shown in your',
|
|
73
|
+
'# terminal. Docs and autocomplete come from the schema the CLI resolved.',
|
|
74
|
+
'',
|
|
75
|
+
'query Categories {',
|
|
76
|
+
' categories {',
|
|
77
|
+
' items {',
|
|
78
|
+
' name',
|
|
79
|
+
' }',
|
|
80
|
+
' }',
|
|
81
|
+
'}',
|
|
82
|
+
'',
|
|
83
|
+
].join('\n');
|
|
84
|
+
|
|
85
|
+
ReactDOM.createRoot(document.getElementById('graphiql')).render(
|
|
86
|
+
React.createElement(GraphiQL, {
|
|
87
|
+
fetcher,
|
|
88
|
+
plugins,
|
|
89
|
+
defaultQuery: DEFAULT_QUERY,
|
|
90
|
+
}),
|
|
91
|
+
);
|
|
92
|
+
</script>
|
|
93
|
+
</body>
|
|
94
|
+
</html>
|
|
95
|
+
`;
|
|
96
|
+
//# sourceMappingURL=explorerPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explorerPage.js","sourceRoot":"","sources":["../../../src/lib/tooling/explorerPage.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,EAAE;AACF,kFAAkF;AAClF,oFAAoF;AACpF,iFAAiF;AACjF,uDAAuD;AACvD,EAAE;AACF,qFAAqF;AACrF,qFAAqF;AACrF,qDAAqD;AAErD,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoFtC,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type Server } from "node:http";
|
|
2
|
+
import { type GraphQLSchema } from "graphql";
|
|
3
|
+
/** The GraphQL-over-HTTP request body GraphiQL sends. */
|
|
4
|
+
export interface GraphQLBody {
|
|
5
|
+
query?: string;
|
|
6
|
+
variables?: Record<string, unknown>;
|
|
7
|
+
operationName?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ExplorerServerOptions {
|
|
10
|
+
/** The schema introspection is answered from (docs, autocomplete, validation). */
|
|
11
|
+
schema: GraphQLSchema;
|
|
12
|
+
/** Absolute URL of the deployed edge's per-project GraphQL endpoint. */
|
|
13
|
+
endpoint: string;
|
|
14
|
+
/** Session bearer attached to every proxied operation. Never sent to the browser. */
|
|
15
|
+
bearer: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Build (but do not listen on) the explorer's server.
|
|
19
|
+
*
|
|
20
|
+
* The edge endpoint is validated ONCE here, not per request: it must be an
|
|
21
|
+
* absolute `http:`/`https:` URL. It comes from the operator's own login region or
|
|
22
|
+
* their explicit `--graphql-url` / `IL_GRAPHQL_URL`, so this is not a trust
|
|
23
|
+
* boundary — but pinning the scheme up front means a typo or a stray `file://`
|
|
24
|
+
* fails at startup with a clear message rather than at the first query, and the
|
|
25
|
+
* value the proxy uses can never be anything else.
|
|
26
|
+
*/
|
|
27
|
+
export declare function createExplorerServer(opts: ExplorerServerOptions): Server;
|