@commercetools/cli-topic-integration-layer 0.2.1 → 0.3.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.
Files changed (54) hide show
  1. package/README.md +1 -0
  2. package/dist/commands/integration-layer/explore.d.ts +20 -0
  3. package/dist/commands/integration-layer/explore.js +209 -0
  4. package/dist/commands/integration-layer/explore.js.map +1 -0
  5. package/dist/commands/integration-layer/extension/build.d.ts +2 -0
  6. package/dist/commands/integration-layer/extension/build.js +24 -3
  7. package/dist/commands/integration-layer/extension/build.js.map +1 -1
  8. package/dist/commands/integration-layer/extension/invoke.d.ts +1 -0
  9. package/dist/commands/integration-layer/extension/invoke.js +9 -4
  10. package/dist/commands/integration-layer/extension/invoke.js.map +1 -1
  11. package/dist/commands/integration-layer/extension/push.d.ts +15 -0
  12. package/dist/commands/integration-layer/extension/push.js +137 -3
  13. package/dist/commands/integration-layer/extension/push.js.map +1 -1
  14. package/dist/commands/integration-layer/extension/serve.d.ts +30 -0
  15. package/dist/commands/integration-layer/extension/serve.js +244 -6
  16. package/dist/commands/integration-layer/extension/serve.js.map +1 -1
  17. package/dist/commands/integration-layer/extension/status.js +4 -0
  18. package/dist/commands/integration-layer/extension/status.js.map +1 -1
  19. package/dist/commands/integration-layer/extension/validate.d.ts +2 -0
  20. package/dist/commands/integration-layer/extension/validate.js +24 -2
  21. package/dist/commands/integration-layer/extension/validate.js.map +1 -1
  22. package/dist/commands/integration-layer/init.js +228 -77
  23. package/dist/commands/integration-layer/init.js.map +1 -1
  24. package/dist/lib/awaitBundleState.d.ts +33 -0
  25. package/dist/lib/awaitBundleState.js +77 -0
  26. package/dist/lib/awaitBundleState.js.map +1 -0
  27. package/dist/lib/base.d.ts +35 -0
  28. package/dist/lib/base.js +99 -13
  29. package/dist/lib/base.js.map +1 -1
  30. package/dist/lib/ilClient.d.ts +62 -2
  31. package/dist/lib/ilClient.js +42 -2
  32. package/dist/lib/ilClient.js.map +1 -1
  33. package/dist/lib/sourceRevision.d.ts +39 -0
  34. package/dist/lib/sourceRevision.js +95 -0
  35. package/dist/lib/sourceRevision.js.map +1 -0
  36. package/dist/lib/tooling/exploreSchema.d.ts +15 -0
  37. package/dist/lib/tooling/exploreSchema.js +77 -0
  38. package/dist/lib/tooling/exploreSchema.js.map +1 -0
  39. package/dist/lib/tooling/explorerPage.d.ts +1 -0
  40. package/dist/lib/tooling/explorerPage.js +96 -0
  41. package/dist/lib/tooling/explorerPage.js.map +1 -0
  42. package/dist/lib/tooling/explorerServer.d.ts +27 -0
  43. package/dist/lib/tooling/explorerServer.js +134 -0
  44. package/dist/lib/tooling/explorerServer.js.map +1 -0
  45. package/dist/lib/tooling/extensions.d.ts +77 -0
  46. package/dist/lib/tooling/extensions.js +209 -0
  47. package/dist/lib/tooling/extensions.js.map +1 -0
  48. package/dist/lib/tooling/introspectionRequest.d.ts +13 -0
  49. package/dist/lib/tooling/introspectionRequest.js +47 -0
  50. package/dist/lib/tooling/introspectionRequest.js.map +1 -0
  51. package/dist/lib/tooling/session.d.ts +36 -0
  52. package/dist/lib/tooling/session.js +99 -0
  53. package/dist/lib/tooling/session.js.map +1 -0
  54. package/package.json +10 -12
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. It extends the host CLI's `AuthCommand`
3
- // (`@commercetools/cli-plugin-auth`), so the bearer is the token
4
- // `commercetools auth login` already persisted to `~/.commercetools/credentials`
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` is a PEER dependency: at runtime the plugin uses
9
- // the HOST CLI's copy, so the static auth manager/repository the host wires up are
10
- // the same singletons this class reads (a bundled second copy would see an empty
11
- // security context and reject every logged-in caller).
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
- const principal = this.getAuthentication()?.getPrincipal();
60
- if (principal instanceof CtpAuthorizedClient)
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
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/lib/base.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,qEAAqE;AACrE,iEAAiE;AACjE,iFAAiF;AACjF,oFAAoF;AACpF,4DAA4D;AAC5D,EAAE;AACF,oFAAoF;AACpF,mFAAmF;AACnF,iFAAiF;AACjF,uDAAuD;AAEvD,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,gCAAgC,CAAC;AAiBxC;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAC/B,OAAO,wCAAwC,OAAO,oBAAoB,CAAC;AAC7E,CAAC;AAED,MAAM,OAAgB,uBAAwB,SAAQ,WAAW;IAC/D;;;;;OAKG;IACO,UAAU,GAAG,IAAI,CAAC;IAE5B,MAAM,CAAU,SAAS,GAAG;QAC1B,uBAAuB,EAAE,KAAK,CAAC,MAAM,CAAC;YACpC,WAAW,EACT,wIAAwI;YAC1I,GAAG,EAAE,uBAAuB;YAC5B,SAAS,EAAE,mBAAmB;SAC/B,CAAC;QACF,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC;YAC1B,WAAW,EAAE,oCAAoC;YACjD,SAAS,EAAE,mBAAmB;SAC/B,CAAC;KACH,CAAC;IAEiB,KAAK,CAAC,IAAI;QAC3B,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,IAAI,IAAI,CAAC,UAAU;YAAE,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC/C,CAAC;IAED,kGAAkG;IACxF,gBAAgB;QACxB,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,EAAE,EAAE,YAAY,EAAE,CAAC;QAC3D,IAAI,SAAS,YAAY,mBAAmB;YAAE,OAAO,SAAS,CAAC;QAC/D,MAAM,IAAI,kBAAkB,CAAC,sDAAsD,CAAC,CAAC;IACvF,CAAC;IAED;;;;OAIG;IACO,KAAK,CAAC,gBAAgB,CAAC,KAAmB;QAClD,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAG,SAAS,CAAC,cAAc,EAAE,CAAC,aAAa,EAAE,CAAC;QAEzD,MAAM,UAAU,GAAG,KAAK,CAAC,aAAa,CAAC,IAAI,SAAS,CAAC,aAAa,EAAE,CAAC;QACrE,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CACb,mGAAmG,CACpG,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,CAAC,uBAAuB,CAAC,IAAI,gBAAgB,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC;QAC1F,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,mFAAmF;gBACjF,wDAAwD;gBACxD,0EAA0E,CAC7E,CAAC;QACJ,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IACrE,CAAC"}
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/lib/base.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,16 @@ export interface ConfigEntry {
4
4
  value: string | null;
5
5
  secret: boolean;
6
6
  }
7
+ /**
8
+ * Lifecycle state of a stored bundle version.
9
+ *
10
+ * pending — stored and being handed out, but nothing has confirmed it loads.
11
+ * running — an extension loaded it and published its schema. Once a version
12
+ * reaches this it is never demoted.
13
+ * failed — it could not be loaded (`reason` says why). The integration layer
14
+ * stops handing it out and the version beneath it takes over.
15
+ */
16
+ export type ExtensionState = "pending" | "running" | "failed";
7
17
  /** The stored bundle's metadata (integration layer `ExtensionMeta`). */
8
18
  export interface ExtensionMeta {
9
19
  projectKey: string;
@@ -12,6 +22,34 @@ export interface ExtensionMeta {
12
22
  version: number;
13
23
  updatedBy?: string;
14
24
  filename?: string;
25
+ /**
26
+ * The integrator's own version-control revision the stored bundle was built from,
27
+ * as reported on upload. Absent for a bundle uploaded without one (e.g. by hand in
28
+ * the Merchant Center).
29
+ */
30
+ sourceRevision?: string;
31
+ /**
32
+ * Lifecycle state of THIS version. Absent when talking to an integration layer
33
+ * that predates bundle state — callers must treat `undefined` as "this deployment
34
+ * can't tell me", not as a failure.
35
+ */
36
+ state?: ExtensionState;
37
+ /** Why this version failed to load; only ever set alongside state "failed". */
38
+ reason?: string;
39
+ /**
40
+ * The version actually in use, which is NOT always `version`: when the newest
41
+ * upload failed to load, the integration layer serves the one beneath it and this
42
+ * reports that older one. `null` when nothing is in use. Returned by the meta read
43
+ * only, not by an upload's response.
44
+ *
45
+ * It carries the source revision as well as the number, because the number is the
46
+ * integration layer's own counter — the commit is what identifies the build to
47
+ * whoever pushed it.
48
+ */
49
+ served?: {
50
+ version: number;
51
+ sourceRevision?: string;
52
+ } | null;
15
53
  }
16
54
  export interface BreakingChange {
17
55
  type: string;
@@ -27,10 +65,32 @@ export interface RemoteValidationResult {
27
65
  }
28
66
  /** GET the project's raw core-subgraph SDL — the compose input (`GET …/subgraph`). */
29
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>;
30
84
  /** POST a candidate SDL to the composition + breaking-change gate (`POST …/extension/validate`). */
31
85
  export declare function remoteValidate(baseUrl: string, projectKey: string, token: string, typeDefs: string): Promise<RemoteValidationResult>;
32
- /** Upload the built bundle, replacing the project's stored one (`PUT …/extension/bundle`). */
33
- export declare function pushBundle(baseUrl: string, projectKey: string, token: string, bundle: string, filename: string): Promise<ExtensionMeta>;
86
+ /**
87
+ * Upload the built bundle, replacing the project's stored one (`PUT …/extension/bundle`).
88
+ *
89
+ * `sourceRevision` (optional) records which of the integrator's revisions this build
90
+ * came from; the integration layer stores it against the revision, shows it in the
91
+ * Merchant Center, and hands it to the connector.
92
+ */
93
+ export declare function pushBundle(baseUrl: string, projectKey: string, token: string, bundle: string, filename: string, sourceRevision?: string): Promise<ExtensionMeta>;
34
94
  /** The stored bundle's metadata, or null if none is stored (`GET …/extension/bundle/meta`). */
35
95
  export declare function fetchExtensionMeta(baseUrl: string, projectKey: string, token: string): Promise<ExtensionMeta | null>;
36
96
  /** Remove the project's extension subgraph from Hive (`DELETE …/extension/subgraph`). */
@@ -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`;
@@ -36,8 +64,14 @@ export async function remoteValidate(baseUrl, projectKey, token, typeDefs) {
36
64
  }
37
65
  return JSON.parse(text);
38
66
  }
39
- /** Upload the built bundle, replacing the project's stored one (`PUT …/extension/bundle`). */
40
- export async function pushBundle(baseUrl, projectKey, token, bundle, filename) {
67
+ /**
68
+ * Upload the built bundle, replacing the project's stored one (`PUT …/extension/bundle`).
69
+ *
70
+ * `sourceRevision` (optional) records which of the integrator's revisions this build
71
+ * came from; the integration layer stores it against the revision, shows it in the
72
+ * Merchant Center, and hands it to the connector.
73
+ */
74
+ export async function pushBundle(baseUrl, projectKey, token, bundle, filename, sourceRevision) {
41
75
  const url = `${apiRoot(baseUrl, projectKey)}/extension/bundle`;
42
76
  const res = await fetch(url, {
43
77
  method: "PUT",
@@ -46,6 +80,12 @@ export async function pushBundle(baseUrl, projectKey, token, bundle, filename) {
46
80
  // The route requires the original filename (percent-encoded; it carries the
47
81
  // module's type). The bundle is plain CommonJS, so name it `.cjs`.
48
82
  "x-extension-filename": encodeURIComponent(filename),
83
+ // Percent-encoded for the same reason as the filename: keep an arbitrary value
84
+ // header-safe. Omitted entirely when there's no revision to report — the route
85
+ // treats a missing header as "no revision", not an error.
86
+ ...(sourceRevision
87
+ ? { "x-extension-source-revision": encodeURIComponent(sourceRevision) }
88
+ : {}),
49
89
  ...bearer(token),
50
90
  },
51
91
  body: bundle,
@@ -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,39 @@
1
+ /**
2
+ * Longest revision the integration layer stores — it truncates past this. Applied
3
+ * here too so what the CLI prints is what actually gets stored, rather than a value
4
+ * the server silently shortens.
5
+ */
6
+ export declare const MAX_SOURCE_REVISION_LENGTH = 200;
7
+ /**
8
+ * Reduce a revision to printable ASCII, length-capped — matching the integration
9
+ * layer's own rule, so the CLI never reports a value different from the stored one.
10
+ * (The server sanitizes regardless; it doesn't trust its callers. This is about
11
+ * telling the user the truth.)
12
+ */
13
+ export declare function sanitizeSourceRevision(value: string | undefined): string | undefined;
14
+ /**
15
+ * The git revision describing `cwd`'s working copy, or null when it isn't a git
16
+ * checkout.
17
+ *
18
+ * `git describe --tags --always` gives the most human-meaningful identifier
19
+ * available, in decreasing order of usefulness: an exact tag (`v1.4.2`), a tag plus
20
+ * distance and commit (`v1.4.2-3-g1a2b3c4d`), or — with no tags at all — the bare
21
+ * commit (`1a2b3c4d`). That single command therefore covers "commit hash or tag"
22
+ * without the caller choosing.
23
+ *
24
+ * A `-dirty` suffix is appended from `git status --porcelain -- .` rather than
25
+ * `describe --dirty`, because `--dirty` ignores UNTRACKED files — and an untracked
26
+ * source file that the entry point imports is bundled into the artifact, so a build
27
+ * containing it is genuinely not the tagged commit. Scoped to `-- .` so it reflects
28
+ * the directory being pushed, not unrelated edits elsewhere in a monorepo.
29
+ */
30
+ export declare function detectGitRevision(cwd: string): Promise<string | null>;
31
+ /**
32
+ * The source revision to record for this push: the explicit value if the caller gave
33
+ * one, else whatever the working copy says, else nothing.
34
+ *
35
+ * Nothing is a legitimate outcome — a bundle built outside version control has no
36
+ * revision, and inventing one ("unknown", a timestamp) would put a value in the
37
+ * Merchant Center and in every connector log line that means nothing.
38
+ */
39
+ export declare function resolveSourceRevision(explicit: string | undefined, cwd: string): Promise<string | undefined>;
@@ -0,0 +1,95 @@
1
+ // Where the bundle being pushed came from — the integrator's OWN version-control
2
+ // revision, recorded against the stored bundle by the integration layer.
3
+ //
4
+ // The point is provenance: with this, the Merchant Center shows which revision a
5
+ // project is running, the connector stamps it on every log line, and
6
+ // `{ _extensionBundle { sourceRevision } }` answers it over GraphQL. So the default
7
+ // has to be zero-effort — `extension push` reads the working copy and reports what
8
+ // it finds, with no flag.
9
+ //
10
+ // GIT is auto-detected because that's what the examples and (nearly) every
11
+ // integrator use. Any other VCS — hg, svn, Perforce, a CI build id — is supported
12
+ // through `--source-revision` / `EXTENSION_SOURCE_REVISION` rather than a detector
13
+ // per system: the integration layer treats the value as an OPAQUE string, so
14
+ // whatever identifies a revision to the integrator is the right thing to send.
15
+ import { execFile } from "node:child_process";
16
+ import { promisify } from "node:util";
17
+ const exec = promisify(execFile);
18
+ /**
19
+ * Longest revision the integration layer stores — it truncates past this. Applied
20
+ * here too so what the CLI prints is what actually gets stored, rather than a value
21
+ * the server silently shortens.
22
+ */
23
+ export const MAX_SOURCE_REVISION_LENGTH = 200;
24
+ /**
25
+ * Reduce a revision to printable ASCII, length-capped — matching the integration
26
+ * layer's own rule, so the CLI never reports a value different from the stored one.
27
+ * (The server sanitizes regardless; it doesn't trust its callers. This is about
28
+ * telling the user the truth.)
29
+ */
30
+ export function sanitizeSourceRevision(value) {
31
+ if (!value)
32
+ return undefined;
33
+ const cleaned = value
34
+ .replace(/[^\x20-\x7e]/g, "")
35
+ .trim()
36
+ .slice(0, MAX_SOURCE_REVISION_LENGTH);
37
+ return cleaned || undefined;
38
+ }
39
+ // Run a git command in `cwd`, or return null if git isn't available, this isn't a
40
+ // repository, or the command has nothing to say. Provenance is a nice-to-have on a
41
+ // push: never fail the push over it.
42
+ async function git(args, cwd) {
43
+ try {
44
+ const { stdout } = await exec("git", args, { cwd, windowsHide: true });
45
+ const trimmed = stdout.trim();
46
+ return trimmed || null;
47
+ }
48
+ catch {
49
+ return null;
50
+ }
51
+ }
52
+ /**
53
+ * The git revision describing `cwd`'s working copy, or null when it isn't a git
54
+ * checkout.
55
+ *
56
+ * `git describe --tags --always` gives the most human-meaningful identifier
57
+ * available, in decreasing order of usefulness: an exact tag (`v1.4.2`), a tag plus
58
+ * distance and commit (`v1.4.2-3-g1a2b3c4d`), or — with no tags at all — the bare
59
+ * commit (`1a2b3c4d`). That single command therefore covers "commit hash or tag"
60
+ * without the caller choosing.
61
+ *
62
+ * A `-dirty` suffix is appended from `git status --porcelain -- .` rather than
63
+ * `describe --dirty`, because `--dirty` ignores UNTRACKED files — and an untracked
64
+ * source file that the entry point imports is bundled into the artifact, so a build
65
+ * containing it is genuinely not the tagged commit. Scoped to `-- .` so it reflects
66
+ * the directory being pushed, not unrelated edits elsewhere in a monorepo.
67
+ */
68
+ export async function detectGitRevision(cwd) {
69
+ // Cheapest possible "is this a git checkout?" probe — everything below is
70
+ // pointless outside one, and this keeps a non-git working copy silent rather than
71
+ // noisy.
72
+ if (!(await git(["rev-parse", "--git-dir"], cwd)))
73
+ return null;
74
+ const described = await git(["describe", "--tags", "--always", "--abbrev=12"], cwd);
75
+ // A repository with no commits yet describes to nothing — there is no revision to
76
+ // report, so report none.
77
+ if (!described)
78
+ return null;
79
+ const dirt = await git(["status", "--porcelain", "--", "."], cwd);
80
+ return dirt ? `${described}-dirty` : described;
81
+ }
82
+ /**
83
+ * The source revision to record for this push: the explicit value if the caller gave
84
+ * one, else whatever the working copy says, else nothing.
85
+ *
86
+ * Nothing is a legitimate outcome — a bundle built outside version control has no
87
+ * revision, and inventing one ("unknown", a timestamp) would put a value in the
88
+ * Merchant Center and in every connector log line that means nothing.
89
+ */
90
+ export async function resolveSourceRevision(explicit, cwd) {
91
+ if (explicit !== undefined)
92
+ return sanitizeSourceRevision(explicit);
93
+ return sanitizeSourceRevision((await detectGitRevision(cwd)) ?? undefined);
94
+ }
95
+ //# sourceMappingURL=sourceRevision.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sourceRevision.js","sourceRoot":"","sources":["../../src/lib/sourceRevision.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,yEAAyE;AACzE,EAAE;AACF,iFAAiF;AACjF,qEAAqE;AACrE,oFAAoF;AACpF,mFAAmF;AACnF,0BAA0B;AAC1B,EAAE;AACF,2EAA2E;AAC3E,kFAAkF;AAClF,mFAAmF;AACnF,6EAA6E;AAC7E,+EAA+E;AAE/E,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAEjC;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,GAAG,CAAC;AAE9C;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAyB;IAC9D,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,MAAM,OAAO,GAAG,KAAK;SAClB,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC;SAC5B,IAAI,EAAE;SACN,KAAK,CAAC,CAAC,EAAE,0BAA0B,CAAC,CAAC;IACxC,OAAO,OAAO,IAAI,SAAS,CAAC;AAC9B,CAAC;AAED,kFAAkF;AAClF,mFAAmF;AACnF,qCAAqC;AACrC,KAAK,UAAU,GAAG,CAAC,IAAc,EAAE,GAAW;IAC5C,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;QACvE,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;QAC9B,OAAO,OAAO,IAAI,IAAI,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,GAAW;IACjD,0EAA0E;IAC1E,kFAAkF;IAClF,SAAS;IACT,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,GAAG,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAE/D,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,CAAC,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,aAAa,CAAC,EAAE,GAAG,CAAC,CAAC;IACpF,kFAAkF;IAClF,0BAA0B;IAC1B,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAE5B,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;IAClE,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,SAAS,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;AACjD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,QAA4B,EAC5B,GAAW;IAEX,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IACpE,OAAO,sBAAsB,CAAC,CAAC,MAAM,iBAAiB,CAAC,GAAG,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC;AAC7E,CAAC"}
@@ -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;