@commercetools/cli-topic-integration-layer 0.5.1 → 0.7.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.
Files changed (79) hide show
  1. package/README.md +2 -6
  2. package/dist/commands/integration-layer/allowlist/add.js +3 -3
  3. package/dist/commands/integration-layer/allowlist/add.js.map +1 -1
  4. package/dist/commands/integration-layer/allowlist/list.js +2 -2
  5. package/dist/commands/integration-layer/allowlist/list.js.map +1 -1
  6. package/dist/commands/integration-layer/allowlist/remove.js +3 -3
  7. package/dist/commands/integration-layer/allowlist/remove.js.map +1 -1
  8. package/dist/commands/integration-layer/allowlist/set.js +3 -3
  9. package/dist/commands/integration-layer/allowlist/set.js.map +1 -1
  10. package/dist/commands/integration-layer/config/get.js +2 -2
  11. package/dist/commands/integration-layer/config/get.js.map +1 -1
  12. package/dist/commands/integration-layer/config/list.js +2 -2
  13. package/dist/commands/integration-layer/config/list.js.map +1 -1
  14. package/dist/commands/integration-layer/config/set.js +2 -2
  15. package/dist/commands/integration-layer/config/set.js.map +1 -1
  16. package/dist/commands/integration-layer/config/unset.js +2 -2
  17. package/dist/commands/integration-layer/config/unset.js.map +1 -1
  18. package/dist/commands/integration-layer/explore.js +5 -5
  19. package/dist/commands/integration-layer/explore.js.map +1 -1
  20. package/dist/commands/integration-layer/extension/build.js +4 -1
  21. package/dist/commands/integration-layer/extension/build.js.map +1 -1
  22. package/dist/commands/integration-layer/extension/create-api-extension-input.d.ts +12 -0
  23. package/dist/commands/integration-layer/extension/create-api-extension-input.js +49 -0
  24. package/dist/commands/integration-layer/extension/create-api-extension-input.js.map +1 -0
  25. package/dist/commands/integration-layer/extension/delete.js +2 -2
  26. package/dist/commands/integration-layer/extension/delete.js.map +1 -1
  27. package/dist/commands/integration-layer/extension/invoke-api-extension.d.ts +19 -0
  28. package/dist/commands/integration-layer/extension/invoke-api-extension.js +140 -0
  29. package/dist/commands/integration-layer/extension/invoke-api-extension.js.map +1 -0
  30. package/dist/commands/integration-layer/extension/push.js +8 -5
  31. package/dist/commands/integration-layer/extension/push.js.map +1 -1
  32. package/dist/commands/integration-layer/extension/serve.d.ts +36 -0
  33. package/dist/commands/integration-layer/extension/serve.js +140 -36
  34. package/dist/commands/integration-layer/extension/serve.js.map +1 -1
  35. package/dist/commands/integration-layer/extension/status.js +2 -2
  36. package/dist/commands/integration-layer/extension/status.js.map +1 -1
  37. package/dist/commands/integration-layer/extension/validate.js +6 -3
  38. package/dist/commands/integration-layer/extension/validate.js.map +1 -1
  39. package/dist/commands/integration-layer/schema/fetch.js +2 -2
  40. package/dist/commands/integration-layer/schema/fetch.js.map +1 -1
  41. package/dist/hooks/authentication.d.ts +3 -0
  42. package/dist/hooks/authentication.js +33 -0
  43. package/dist/hooks/authentication.js.map +1 -0
  44. package/dist/lib/auth.d.ts +5 -0
  45. package/dist/lib/auth.js +41 -0
  46. package/dist/lib/auth.js.map +1 -0
  47. package/dist/lib/awaitBundleState.d.ts +2 -2
  48. package/dist/lib/awaitBundleState.js +2 -2
  49. package/dist/lib/awaitBundleState.js.map +1 -1
  50. package/dist/lib/base.d.ts +12 -21
  51. package/dist/lib/base.js +27 -76
  52. package/dist/lib/base.js.map +1 -1
  53. package/dist/lib/extensionConfig.d.ts +17 -0
  54. package/dist/lib/extensionConfig.js +36 -0
  55. package/dist/lib/extensionConfig.js.map +1 -0
  56. package/dist/lib/ilClient.d.ts +16 -10
  57. package/dist/lib/ilClient.js +28 -31
  58. package/dist/lib/ilClient.js.map +1 -1
  59. package/dist/lib/loadLocalEnv.d.ts +49 -0
  60. package/dist/lib/loadLocalEnv.js +112 -0
  61. package/dist/lib/loadLocalEnv.js.map +1 -0
  62. package/dist/lib/tooling/compose.js +2 -2
  63. package/dist/lib/tooling/compose.js.map +1 -1
  64. package/dist/lib/tooling/extensionInputSampleObj.d.ts +8 -0
  65. package/dist/lib/tooling/extensionInputSampleObj.js +178 -0
  66. package/dist/lib/tooling/extensionInputSampleObj.js.map +1 -0
  67. package/dist/lib/tooling/extensions.d.ts +22 -5
  68. package/dist/lib/tooling/extensions.js +30 -8
  69. package/dist/lib/tooling/extensions.js.map +1 -1
  70. package/dist/lib/tooling/generateExtensionInputSample.d.ts +22 -0
  71. package/dist/lib/tooling/generateExtensionInputSample.js +36 -0
  72. package/dist/lib/tooling/generateExtensionInputSample.js.map +1 -0
  73. package/dist/lib/tooling/sandboxFetch.d.ts +14 -0
  74. package/dist/lib/tooling/sandboxFetch.js +100 -0
  75. package/dist/lib/tooling/sandboxFetch.js.map +1 -0
  76. package/package.json +11 -3
  77. package/dist/commands/integration-layer/extension/invoke.d.ts +0 -14
  78. package/dist/commands/integration-layer/extension/invoke.js +0 -94
  79. package/dist/commands/integration-layer/extension/invoke.js.map +0 -1
@@ -13,8 +13,8 @@ export default class SchemaFetch extends IntegrationLayerCommand {
13
13
  };
14
14
  async run() {
15
15
  const { flags } = await this.parse(SchemaFetch);
16
- const { baseUrl, projectKey, token } = await this.resolveIlContext(flags);
17
- const sdl = await fetchSubgraphSdl(baseUrl, projectKey, token);
16
+ const { baseUrl, projectKey, authFetch } = await this.resolveIlContext(flags);
17
+ const sdl = await fetchSubgraphSdl(baseUrl, projectKey, authFetch);
18
18
  if (flags.out) {
19
19
  await writeFile(flags.out, sdl, "utf8");
20
20
  this.log(`✓ wrote ${projectKey} core-subgraph SDL → ${flags.out}`);
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../../../src/commands/integration-layer/schema/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,uBAAuB;IAC9D,MAAM,CAAU,WAAW,GACzB,yFAAyF,CAAC;IAE5F,MAAM,CAAU,QAAQ,GAAG;QACzB,kDAAkD;QAClD,yEAAyE;KAC1E,CAAC;IAEF,MAAM,CAAU,KAAK,GAAG;QACtB,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,8CAA8C,EAAE,CAAC;KACnF,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAChD,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC1E,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;QAC/D,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;YACd,MAAM,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;YACxC,IAAI,CAAC,GAAG,CAAC,WAAW,UAAU,wBAAwB,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QACrE,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAChB,CAAC;IACH,CAAC"}
1
+ {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../../../src/commands/integration-layer/schema/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,uBAAuB;IAC9D,MAAM,CAAU,WAAW,GACzB,yFAAyF,CAAC;IAE5F,MAAM,CAAU,QAAQ,GAAG;QACzB,kDAAkD;QAClD,yEAAyE;KAC1E,CAAC;IAEF,MAAM,CAAU,KAAK,GAAG;QACtB,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,8CAA8C,EAAE,CAAC;KACnF,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAChD,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC9E,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;QACnE,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;YACd,MAAM,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;YACxC,IAAI,CAAC,GAAG,CAAC,WAAW,UAAU,wBAAwB,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QACrE,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAChB,CAAC;IACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Hook } from "@oclif/core";
2
+ declare const authentication: Hook.Prerun;
3
+ export default authentication;
@@ -0,0 +1,33 @@
1
+ // THE ONE HACK — and it is deliberately the only one.
2
+ //
3
+ // Every other topic gets its auth wiring for free: the host CLI's own `init` hook calls
4
+ // `configureAuth(...)` and the auth plugin's `prerun` hook fills the in-memory
5
+ // `SecurityContextHolder`, after which `AuthCommand` hands commands the logged-in
6
+ // principal + a self-refreshing fetch. But that machinery all lives on the HOST's copy of
7
+ // `@commercetools/cli-plugin-auth`. When this topic is installed via `oclif plugins
8
+ // install` it lands in the oclif data dir with its OWN second copy of that module, whose
9
+ // statics the host never touches — so `getAuthentication()` from our commands would read
10
+ // an empty context and reject every logged-in caller ("not logged in").
11
+ //
12
+ // We close that gap here, and ONLY here: this prerun hook configures + fills THIS copy
13
+ // from the same on-disk credentials file, resolved through the same bare specifier our
14
+ // commands import, so the copy it fills is exactly the copy they read. When the topic is
15
+ // instead bundled into the host (a single shared copy) this just re-does the host's work
16
+ // idempotently. With this in place `base.ts` is an ordinary `AuthCommand` topic — do NOT
17
+ // "simplify" it back to reading credentials off disk by hand.
18
+ import { AuthCommand, SecurityContextHolder, configureAuth } from "@commercetools/cli-plugin-auth";
19
+ import { provideAuthenticationManager, provideAuthenticationRepository, } from "../lib/auth.js";
20
+ const authentication = async (params) => {
21
+ // Only our own commands need this; leave every other command's context untouched.
22
+ if (!(params.Command.prototype instanceof AuthCommand))
23
+ return;
24
+ const authenticationRepository = provideAuthenticationRepository();
25
+ configureAuth({
26
+ authenticationManager: provideAuthenticationManager(),
27
+ authenticationRepository,
28
+ });
29
+ const authentication = await authenticationRepository.loadAuthentication();
30
+ SecurityContextHolder.getContext().setAuthentication(authentication);
31
+ };
32
+ export default authentication;
33
+ //# sourceMappingURL=authentication.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authentication.js","sourceRoot":"","sources":["../../src/hooks/authentication.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,EAAE;AACF,wFAAwF;AACxF,+EAA+E;AAC/E,kFAAkF;AAClF,0FAA0F;AAC1F,oFAAoF;AACpF,yFAAyF;AACzF,yFAAyF;AACzF,wEAAwE;AACxE,EAAE;AACF,uFAAuF;AACvF,uFAAuF;AACvF,yFAAyF;AACzF,yFAAyF;AACzF,yFAAyF;AACzF,8DAA8D;AAE9D,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAGnG,OAAO,EACL,4BAA4B,EAC5B,+BAA+B,GAChC,MAAM,gBAAgB,CAAC;AAExB,MAAM,cAAc,GAAgB,KAAK,EAAE,MAAM,EAAE,EAAE;IACnD,kFAAkF;IAClF,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,YAAY,WAAW,CAAC;QAAE,OAAO;IAE/D,MAAM,wBAAwB,GAAG,+BAA+B,EAAE,CAAC;IACnE,aAAa,CAAC;QACZ,qBAAqB,EAAE,4BAA4B,EAAE;QACrD,wBAAwB;KACzB,CAAC,CAAC;IAEH,MAAM,cAAc,GAAG,MAAM,wBAAwB,CAAC,kBAAkB,EAAE,CAAC;IAC3E,qBAAqB,CAAC,UAAU,EAAE,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAC;AACvE,CAAC,CAAC;AAEF,eAAe,cAAc,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { type AuthenticationManager, type AuthenticationRepository } from "@commercetools/cli-plugin-auth";
2
+ /** The `client_credentials` manager that re-mints an access token from the stored secret. */
3
+ export declare function provideAuthenticationManager(): AuthenticationManager;
4
+ /** The repository over the shared credentials file, wired to (de)serialize the login. */
5
+ export declare function provideAuthenticationRepository(): AuthenticationRepository;
@@ -0,0 +1,41 @@
1
+ // The auth-plugin wiring this topic hands to `configureAuth`, mirroring the host CLI's
2
+ // `providers.ts` (`@commercetools/cli`) verbatim: a `client_credentials` authentication
3
+ // manager (which re-mints an access token from the stored client id/secret when the old
4
+ // one lapses) and a `FileBasedAuthenticationRepository` over the shared
5
+ // `~/.commercetools/credentials` file `commercetools auth login` writes. The prerun hook
6
+ // (`hooks/authentication.ts`) is what actually calls these; see its header for why the
7
+ // topic has to do this itself instead of inheriting the host's copy.
8
+ //
9
+ // We reproduce those ~15 lines rather than import the host's, because they are NOT
10
+ // available as a supported API. `@commercetools/cli` re-exports only `run` from its entry
11
+ // (`src/index.ts`) — its `providers.ts` is private application wiring. The functions are
12
+ // reachable solely by deep-importing compiled internals
13
+ // (`@commercetools/cli/dist/providers.js`), which resolves only because that package
14
+ // happens to declare no `exports` map — an unversioned path that can vanish on any patch.
15
+ // Doing so would also invert the dependency graph: a topic pulling in the host CLI
16
+ // *application* (a `bin` package) to reuse two factories. The classes composed below —
17
+ // `CtpAuthenticationManager`, `CtpHttpAuthClient`, `FileBasedAuthenticationRepository`,
18
+ // `CtpClientAuthenticationToken` — ARE the public exports of `@commercetools/cli-plugin-auth`
19
+ // (the dependency we already declare), so composing them here is the supported path, not a
20
+ // workaround: it is exactly what the host's `providers.ts` does, against the same public API.
21
+ import os from "node:os";
22
+ import path from "node:path";
23
+ import { CtpAuthenticationManager, CtpClientAuthenticationToken, CtpHttpAuthClient, FileBasedAuthenticationRepository, } from "@commercetools/cli-plugin-auth";
24
+ /**
25
+ * Where `commercetools auth login` persists the serialized principal, and the auth id it
26
+ * files the client-credentials token under. These mirror the host CLI's `providers.ts`
27
+ * (`@commercetools/cli`) — the on-disk credentials contract — verbatim.
28
+ */
29
+ const CREDENTIALS_FILE = path.join(os.homedir(), ".commercetools", "credentials");
30
+ const CLIENT_CREDENTIALS_AUTH_ID = "client-credentials";
31
+ /** The `client_credentials` manager that re-mints an access token from the stored secret. */
32
+ export function provideAuthenticationManager() {
33
+ return new CtpAuthenticationManager(new CtpHttpAuthClient());
34
+ }
35
+ /** The repository over the shared credentials file, wired to (de)serialize the login. */
36
+ export function provideAuthenticationRepository() {
37
+ const repository = new FileBasedAuthenticationRepository(CREDENTIALS_FILE);
38
+ repository.addSerializable(CLIENT_CREDENTIALS_AUTH_ID, CtpClientAuthenticationToken, CtpClientAuthenticationToken.Serializable);
39
+ return repository;
40
+ }
41
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,wFAAwF;AACxF,wFAAwF;AACxF,wEAAwE;AACxE,yFAAyF;AACzF,uFAAuF;AACvF,qEAAqE;AACrE,EAAE;AACF,mFAAmF;AACnF,0FAA0F;AAC1F,yFAAyF;AACzF,wDAAwD;AACxD,qFAAqF;AACrF,0FAA0F;AAC1F,mFAAmF;AACnF,uFAAuF;AACvF,wFAAwF;AACxF,8FAA8F;AAC9F,2FAA2F;AAC3F,8FAA8F;AAE9F,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EACL,wBAAwB,EACxB,4BAA4B,EAC5B,iBAAiB,EACjB,iCAAiC,GAGlC,MAAM,gCAAgC,CAAC;AAExC;;;;GAIG;AACH,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,gBAAgB,EAAE,aAAa,CAAC,CAAC;AAClF,MAAM,0BAA0B,GAAG,oBAAoB,CAAC;AAExD,6FAA6F;AAC7F,MAAM,UAAU,4BAA4B;IAC1C,OAAO,IAAI,wBAAwB,CAAC,IAAI,iBAAiB,EAAE,CAAC,CAAC;AAC/D,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,+BAA+B;IAC7C,MAAM,UAAU,GAAG,IAAI,iCAAiC,CAAC,gBAAgB,CAAC,CAAC;IAC3E,UAAU,CAAC,eAAe,CACxB,0BAA0B,EAC1B,4BAA4B,EAC5B,4BAA4B,CAAC,YAAY,CAC1C,CAAC;IACF,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -1,4 +1,4 @@
1
- import { type ExtensionMeta } from "./ilClient.js";
1
+ import { type AuthFetch, type ExtensionMeta } from "./ilClient.js";
2
2
  /** How the wait ended. Only `failed` means "the push produced a broken bundle". */
3
3
  export type BundleOutcome = {
4
4
  kind: "running";
@@ -30,4 +30,4 @@ export interface AwaitOptions {
30
30
  * The first read happens immediately — an extension that was already mid-poll can
31
31
  * settle the version before we ever sleep.
32
32
  */
33
- export declare function awaitBundleState(baseUrl: string, projectKey: string, token: string, version: number, options: AwaitOptions): Promise<BundleOutcome>;
33
+ export declare function awaitBundleState(baseUrl: string, projectKey: string, authFetch: AuthFetch, version: number, options: AwaitOptions): Promise<BundleOutcome>;
@@ -28,14 +28,14 @@ const defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
28
28
  * The first read happens immediately — an extension that was already mid-poll can
29
29
  * settle the version before we ever sleep.
30
30
  */
31
- export async function awaitBundleState(baseUrl, projectKey, token, version, options) {
31
+ export async function awaitBundleState(baseUrl, projectKey, authFetch, version, options) {
32
32
  const sleep = options.sleep ?? defaultSleep;
33
33
  const now = options.now ?? Date.now;
34
34
  const deadline = now() + options.timeoutMs;
35
35
  for (;;) {
36
36
  let meta;
37
37
  try {
38
- meta = await fetchExtensionMeta(baseUrl, projectKey, token);
38
+ meta = await fetchExtensionMeta(baseUrl, projectKey, authFetch);
39
39
  }
40
40
  catch (err) {
41
41
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"awaitBundleState.js","sourceRoot":"","sources":["../../src/lib/awaitBundleState.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,EAAE;AACF,mFAAmF;AACnF,+EAA+E;AAC/E,gFAAgF;AAChF,mFAAmF;AACnF,oFAAoF;AACpF,EAAE;AACF,iFAAiF;AACjF,kEAAkE;AAClE,EAAE;AACF,4CAA4C;AAC5C,EAAE;AACF,4FAA4F;AAC5F,qFAAqF;AACrF,gFAAgF;AAChF,+EAA+E;AAC/E,kFAAkF;AAClF,qFAAqF;AACrF,2CAA2C;AAC3C,kFAAkF;AAClF,iEAAiE;AAEjE,OAAO,EAAE,kBAAkB,EAAsB,MAAM,eAAe,CAAC;AAoBvE,MAAM,YAAY,GAAG,CAAC,EAAU,EAAiB,EAAE,CACjD,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAe,EACf,UAAkB,EAClB,KAAa,EACb,OAAe,EACf,OAAqB;IAErB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,YAAY,CAAC;IAC5C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACpC,MAAM,QAAQ,GAAG,GAAG,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC;IAE3C,SAAS,CAAC;QACR,IAAI,IAA0B,CAAC;QAC/B,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,kBAAkB,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;QAC9D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO;gBACL,IAAI,EAAE,SAAS;gBACf,MAAM,EAAE,8CAA+C,GAAa,CAAC,OAAO,EAAE;aAC/E,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,4DAA4D;YAC5D,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,+CAA+C,EAAE,CAAC;QACtF,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC7B,+EAA+E;YAC/E,OAAO;gBACL,IAAI,EAAE,SAAS;gBACf,MAAM,EAAE,+DAA+D;gBACvE,IAAI;aACL,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;YAC7B,4EAA4E;YAC5E,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;QACtC,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;YAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;QAC/D,IAAI,IAAI,CAAC,KAAK,KAAK,QAAQ;YAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAE7D,iBAAiB;QACjB,IAAI,GAAG,EAAE,IAAI,QAAQ,EAAE,CAAC;YACtB,OAAO;gBACL,IAAI,EAAE,SAAS;gBACf,MAAM,EAAE,2CAA2C,OAAO,WAAW,IAAI,CAAC,KAAK,CAC7E,OAAO,CAAC,SAAS,GAAG,IAAI,CACzB,GAAG;gBACJ,IAAI;aACL,CAAC;QACJ,CAAC;QACD,MAAM,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAClC,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"awaitBundleState.js","sourceRoot":"","sources":["../../src/lib/awaitBundleState.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,EAAE;AACF,mFAAmF;AACnF,+EAA+E;AAC/E,gFAAgF;AAChF,mFAAmF;AACnF,oFAAoF;AACpF,EAAE;AACF,iFAAiF;AACjF,kEAAkE;AAClE,EAAE;AACF,4CAA4C;AAC5C,EAAE;AACF,4FAA4F;AAC5F,qFAAqF;AACrF,gFAAgF;AAChF,+EAA+E;AAC/E,kFAAkF;AAClF,qFAAqF;AACrF,2CAA2C;AAC3C,kFAAkF;AAClF,iEAAiE;AAEjE,OAAO,EAAE,kBAAkB,EAAsC,MAAM,eAAe,CAAC;AAoBvF,MAAM,YAAY,GAAG,CAAC,EAAU,EAAiB,EAAE,CACjD,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAe,EACf,UAAkB,EAClB,SAAoB,EACpB,OAAe,EACf,OAAqB;IAErB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,YAAY,CAAC;IAC5C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACpC,MAAM,QAAQ,GAAG,GAAG,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC;IAE3C,SAAS,CAAC;QACR,IAAI,IAA0B,CAAC;QAC/B,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,kBAAkB,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;QAClE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO;gBACL,IAAI,EAAE,SAAS;gBACf,MAAM,EAAE,8CAA+C,GAAa,CAAC,OAAO,EAAE;aAC/E,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,4DAA4D;YAC5D,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,+CAA+C,EAAE,CAAC;QACtF,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC7B,+EAA+E;YAC/E,OAAO;gBACL,IAAI,EAAE,SAAS;gBACf,MAAM,EAAE,+DAA+D;gBACvE,IAAI;aACL,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;YAC7B,4EAA4E;YAC5E,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;QACtC,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;YAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;QAC/D,IAAI,IAAI,CAAC,KAAK,KAAK,QAAQ;YAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAE7D,iBAAiB;QACjB,IAAI,GAAG,EAAE,IAAI,QAAQ,EAAE,CAAC;YACtB,OAAO;gBACL,IAAI,EAAE,SAAS;gBACf,MAAM,EAAE,2CAA2C,OAAO,WAAW,IAAI,CAAC,KAAK,CAC7E,OAAO,CAAC,SAAS,GAAG,IAAI,CACzB,GAAG;gBACJ,IAAI;aACL,CAAC;QACJ,CAAC;QACD,MAAM,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAClC,CAAC;AACH,CAAC"}
@@ -1,18 +1,15 @@
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>;
9
2
  /** The resolved, ready-to-use integration-layer context: where to call and as whom. */
10
3
  export interface IlContext {
11
4
  /** The integration-layer edge base URL, trailing slashes trimmed. */
12
5
  baseUrl: string;
13
6
  projectKey: string;
14
- /** The logged-in principal's commercetools access token (the `manage_project` bearer). */
15
- token: string;
7
+ /**
8
+ * Authenticated fetch bound to the logged-in `manage_project` principal — it injects
9
+ * the bearer and transparently refreshes/retries it (`CtpAuthFetchFactory`). Hand it
10
+ * straight to the `ilClient` calls in place of a raw token.
11
+ */
12
+ authFetch: typeof fetch;
16
13
  }
17
14
  /** The subset of parsed flags {@link IntegrationLayerCommand.resolveIlContext} reads. */
18
15
  export interface IlFlagValues {
@@ -57,28 +54,22 @@ export declare abstract class IntegrationLayerCommand extends AuthCommand {
57
54
  */
58
55
  protected authorized: boolean;
59
56
  /**
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.
57
+ * Authenticated fetch for the `manage_project` boundary — injects the bearer and
58
+ * refreshes/retries it. Built once in {@link init} (after the prerun hook has
59
+ * configured the auth plugin + filled the security context).
63
60
  */
64
- private persistedPrincipal?;
61
+ protected authFetch: typeof fetch;
65
62
  static baseFlags: {
63
+ "env-file": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
66
64
  "integration-layer-url": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
67
65
  "project-key": import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
68
66
  };
69
67
  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;
77
68
  /** The logged-in commercetools principal, or an `AuthorizationError` pointing at `auth login`. */
78
69
  protected requirePrincipal(): CtpAuthorizedClient;
79
70
  /**
80
71
  * Resolve the integration-layer base URL + project key from the login context and
81
- * take the principal's access token as the bearer. Fails loudly (no defensive
72
+ * hand back the authenticated fetch as the bearer. Fails loudly (no defensive
82
73
  * defaults) when a required value is absent.
83
74
  */
84
75
  protected resolveIlContext(flags: IlFlagValues): Promise<IlContext>;
package/dist/lib/base.js CHANGED
@@ -1,62 +1,13 @@
1
1
  // Base class for the topic's commands that reach the Commerce Integration Layer's
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.
5
- //
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";
2
+ // `manage_project` boundary. An ordinary `AuthCommand` topic: the logged-in principal
3
+ // comes from the inherited `getAuthentication()` (the security context our prerun hook
4
+ // fills — see `hooks/authentication.ts`), and outbound calls go through a
5
+ // `CtpAuthFetchFactory` fetch that injects the bearer and transparently refreshes/retries
6
+ // it, exactly like the `connect` topic. There is no bespoke credential reading here; the
7
+ // one topic-specific concession is the prerun hook.
29
8
  import { Flags } from "@oclif/core";
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
- }
9
+ import { AuthCommand, AuthorizationError, CtpAuthFetchFactory, CtpAuthorizedClient, } from "@commercetools/cli-plugin-auth";
10
+ import { loadLocalEnv } from "./loadLocalEnv.js";
60
11
  /**
61
12
  * Derive the integration-layer EXTENSIONS edge base URL from the authenticated
62
13
  * principal's commercetools region. The extensions edge serves the CLI's
@@ -110,12 +61,16 @@ export class IntegrationLayerCommand extends AuthCommand {
110
61
  */
111
62
  authorized = true;
112
63
  /**
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.
64
+ * Authenticated fetch for the `manage_project` boundary — injects the bearer and
65
+ * refreshes/retries it. Built once in {@link init} (after the prerun hook has
66
+ * configured the auth plugin + filled the security context).
116
67
  */
117
- persistedPrincipal;
68
+ authFetch;
118
69
  static baseFlags = {
70
+ "env-file": Flags.string({
71
+ description: "dotenv file to load before the command runs (default: .env in the cwd, if present); does not override variables already set in the environment",
72
+ helpGroup: "GLOBAL",
73
+ }),
119
74
  "integration-layer-url": Flags.string({
120
75
  description: "integration-layer extensions edge base URL (also settable via INTEGRATION_LAYER_URL); overrides the URL derived from your login region",
121
76
  env: "INTEGRATION_LAYER_URL",
@@ -127,34 +82,30 @@ export class IntegrationLayerCommand extends AuthCommand {
127
82
  }),
128
83
  };
129
84
  async init() {
85
+ // Before oclif resolves flag `env:` bindings (and before `serve` reads
86
+ // EXTENSION_CONFIG_*), so a project `.env` / `--env-file` actually takes effect.
87
+ loadLocalEnv();
130
88
  await super.init();
131
- this.persistedPrincipal = await this.loadPersistedPrincipal();
89
+ // The prerun hook has configured the auth plugin + filled this copy's security
90
+ // context by now, so the inherited accessors resolve as in any other topic.
91
+ this.authFetch = new CtpAuthFetchFactory(this.getAuthenticationManager(), this.getAuthenticationRepository()).create();
132
92
  if (this.authorized)
133
93
  this.requirePrincipal();
134
94
  }
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
- }
144
95
  /** The logged-in commercetools principal, or an `AuthorizationError` pointing at `auth login`. */
145
96
  requirePrincipal() {
146
- if (this.persistedPrincipal)
147
- return this.persistedPrincipal;
97
+ const principal = this.getAuthentication()?.getPrincipal();
98
+ if (principal instanceof CtpAuthorizedClient)
99
+ return principal;
148
100
  throw new AuthorizationError("not logged in — run `commercetools auth login` first");
149
101
  }
150
102
  /**
151
103
  * Resolve the integration-layer base URL + project key from the login context and
152
- * take the principal's access token as the bearer. Fails loudly (no defensive
104
+ * hand back the authenticated fetch as the bearer. Fails loudly (no defensive
153
105
  * defaults) when a required value is absent.
154
106
  */
155
107
  async resolveIlContext(flags) {
156
108
  const principal = this.requirePrincipal();
157
- const token = principal.getAccessToken().getTokenValue();
158
109
  const projectKey = flags["project-key"] ?? principal.getProjectKey();
159
110
  if (!projectKey) {
160
111
  throw new Error("no project key — log in with `commercetools auth login --project-key <key>` or pass --project-key");
@@ -165,7 +116,7 @@ export class IntegrationLayerCommand extends AuthCommand {
165
116
  "INTEGRATION_LAYER_URL (the extensions edge base, e.g. " +
166
117
  "https://extensions.integration-layer.eu-central-1.aws.commercetools.com)");
167
118
  }
168
- return { baseUrl: baseUrl.replace(/\/+$/, ""), projectKey, token };
119
+ return { baseUrl: baseUrl.replace(/\/+$/, ""), projectKey, authFetch: this.authFetch };
169
120
  }
170
121
  }
171
122
  //# sourceMappingURL=base.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/lib/base.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/lib/base.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,sFAAsF;AACtF,uFAAuF;AACvF,0EAA0E;AAC1E,0FAA0F;AAC1F,yFAAyF;AACzF,oDAAoD;AAEpD,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAqBjD;;;;;;;;;;;;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;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAc;IACpD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAC/B,OAAO,qCAAqC,OAAO,oBAAoB,CAAC;AAC1E,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAc;IACjD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAC/B,OAAO,kCAAkC,OAAO,oBAAoB,CAAC;AACvE,CAAC;AAED,MAAM,OAAgB,uBAAwB,SAAQ,WAAW;IAC/D;;;;;OAKG;IACO,UAAU,GAAG,IAAI,CAAC;IAE5B;;;;OAIG;IACO,SAAS,CAAgB;IAEnC,MAAM,CAAU,SAAS,GAAG;QAC1B,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC;YACvB,WAAW,EACT,gJAAgJ;YAClJ,SAAS,EAAE,QAAQ;SACpB,CAAC;QACF,uBAAuB,EAAE,KAAK,CAAC,MAAM,CAAC;YACpC,WAAW,EACT,wIAAwI;YAC1I,GAAG,EAAE,uBAAuB;YAC5B,SAAS,EAAE,4BAA4B;SACxC,CAAC;QACF,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC;YAC1B,WAAW,EAAE,oCAAoC;YACjD,SAAS,EAAE,4BAA4B;SACxC,CAAC;KACH,CAAC;IAEiB,KAAK,CAAC,IAAI;QAC3B,uEAAuE;QACvE,iFAAiF;QACjF,YAAY,EAAE,CAAC;QACf,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,+EAA+E;QAC/E,4EAA4E;QAC5E,IAAI,CAAC,SAAS,GAAG,IAAI,mBAAmB,CACtC,IAAI,CAAC,wBAAwB,EAAE,EAC/B,IAAI,CAAC,2BAA2B,EAAE,CACnC,CAAC,MAAM,EAAE,CAAC;QACX,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;QAE1C,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,4FAA4F;gBAC1F,wDAAwD;gBACxD,0EAA0E,CAC7E,CAAC;QACJ,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;IACzF,CAAC"}
@@ -0,0 +1,17 @@
1
+ /** Prefix for local-dev env vars that feed `ctx.config` (see `loadLocalEnv` / `.env`). */
2
+ export declare const EXTENSION_CONFIG_PREFIX = "EXTENSION_CONFIG_";
3
+ /**
4
+ * Project the `EXTENSION_CONFIG_<KEY>` entries of an env-shaped record into the
5
+ * `ctx.config` map the runtime injects — `EXTENSION_CONFIG_ALGOLIA_API_KEY=…` becomes
6
+ * `ALGOLIA_API_KEY`. Locally there is no Commerce Integration Layer to read the
7
+ * project's stored config from, so `serve` sources it from the environment and any
8
+ * `.env` / `--env-file`. Keys with an empty remainder (bare `EXTENSION_CONFIG_`) are
9
+ * dropped.
10
+ */
11
+ export declare function extensionConfigFromEnv(env?: Record<string, string | undefined>): Record<string, string>;
12
+ /**
13
+ * Parse `--config KEY=VALUE` pairs into a `ctx.config` map; a later pair wins on the
14
+ * same key. A pair without a `=` (or with an empty key) is skipped. Used by
15
+ * `invoke-api-extension` to overlay explicit flags on top of the environment / `.env`.
16
+ */
17
+ export declare function extensionConfigFromPairs(pairs: readonly string[]): Record<string, string>;
@@ -0,0 +1,36 @@
1
+ /** Prefix for local-dev env vars that feed `ctx.config` (see `loadLocalEnv` / `.env`). */
2
+ export const EXTENSION_CONFIG_PREFIX = "EXTENSION_CONFIG_";
3
+ /**
4
+ * Project the `EXTENSION_CONFIG_<KEY>` entries of an env-shaped record into the
5
+ * `ctx.config` map the runtime injects — `EXTENSION_CONFIG_ALGOLIA_API_KEY=…` becomes
6
+ * `ALGOLIA_API_KEY`. Locally there is no Commerce Integration Layer to read the
7
+ * project's stored config from, so `serve` sources it from the environment and any
8
+ * `.env` / `--env-file`. Keys with an empty remainder (bare `EXTENSION_CONFIG_`) are
9
+ * dropped.
10
+ */
11
+ export function extensionConfigFromEnv(env = process.env) {
12
+ const config = {};
13
+ for (const [key, value] of Object.entries(env)) {
14
+ if (!key.startsWith(EXTENSION_CONFIG_PREFIX) || typeof value !== "string")
15
+ continue;
16
+ const name = key.slice(EXTENSION_CONFIG_PREFIX.length);
17
+ if (name)
18
+ config[name] = value;
19
+ }
20
+ return config;
21
+ }
22
+ /**
23
+ * Parse `--config KEY=VALUE` pairs into a `ctx.config` map; a later pair wins on the
24
+ * same key. A pair without a `=` (or with an empty key) is skipped. Used by
25
+ * `invoke-api-extension` to overlay explicit flags on top of the environment / `.env`.
26
+ */
27
+ export function extensionConfigFromPairs(pairs) {
28
+ const config = {};
29
+ for (const pair of pairs) {
30
+ const eq = pair.indexOf("=");
31
+ if (eq > 0)
32
+ config[pair.slice(0, eq)] = pair.slice(eq + 1);
33
+ }
34
+ return config;
35
+ }
36
+ //# sourceMappingURL=extensionConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extensionConfig.js","sourceRoot":"","sources":["../../src/lib/extensionConfig.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAC1F,MAAM,CAAC,MAAM,uBAAuB,GAAG,mBAAmB,CAAC;AAE3D;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CACpC,MAA0C,OAAO,CAAC,GAAG;IAErD,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,uBAAuB,CAAC,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,SAAS;QACpF,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;QACvD,IAAI,IAAI;YAAE,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;IACjC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CAAC,KAAwB;IAC/D,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,EAAE,GAAG,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -63,8 +63,14 @@ export interface RemoteValidationResult {
63
63
  /** False when no published baseline was available, so the breaking check was skipped. */
64
64
  comparedToPublished: boolean;
65
65
  }
66
+ /**
67
+ * The authenticated fetch supplied by the command layer — the `CtpAuthFetchFactory` fetch,
68
+ * which injects the `manage_project` bearer and refreshes/retries it. Structurally a
69
+ * `fetch`, so callers can pass a plain stub in tests.
70
+ */
71
+ export type AuthFetch = typeof fetch;
66
72
  /** GET the project's raw core-subgraph SDL — the compose input (`GET …/subgraph`). */
67
- export declare function fetchSubgraphSdl(baseUrl: string, projectKey: string, token: string): Promise<string>;
73
+ export declare function fetchSubgraphSdl(baseUrl: string, projectKey: string, authFetch: AuthFetch): Promise<string>;
68
74
  /**
69
75
  * GET the project's DEPLOYED composed graph as a PUBLIC API SCHEMA — what the router
70
76
  * actually plans and serves (core subgraph + the project's published extension),
@@ -80,9 +86,9 @@ export declare function fetchSubgraphSdl(baseUrl: string, projectKey: string, to
80
86
  * same `manage_project` boundary as `/subgraph`. 404 means the project has never
81
87
  * published a composable version.
82
88
  */
83
- export declare function fetchDeployedApiSchemaSdl(baseUrl: string, projectKey: string, token: string): Promise<string>;
89
+ export declare function fetchDeployedApiSchemaSdl(baseUrl: string, projectKey: string, authFetch: AuthFetch): Promise<string>;
84
90
  /** POST a candidate SDL to the composition + breaking-change gate (`POST …/extension/validate`). */
85
- export declare function remoteValidate(baseUrl: string, projectKey: string, token: string, typeDefs: string): Promise<RemoteValidationResult>;
91
+ export declare function remoteValidate(baseUrl: string, projectKey: string, authFetch: AuthFetch, typeDefs: string): Promise<RemoteValidationResult>;
86
92
  /**
87
93
  * Upload the built bundle, replacing the project's stored one (`PUT …/extension/bundle`).
88
94
  *
@@ -90,11 +96,11 @@ export declare function remoteValidate(baseUrl: string, projectKey: string, toke
90
96
  * came from; the Commerce Integration Layer stores it against the revision, shows it in the
91
97
  * Merchant Center, and hands it to the connector.
92
98
  */
93
- export declare function pushBundle(baseUrl: string, projectKey: string, token: string, bundle: string, filename: string, sourceRevision?: string): Promise<ExtensionMeta>;
99
+ export declare function pushBundle(baseUrl: string, projectKey: string, authFetch: AuthFetch, bundle: string, filename: string, sourceRevision?: string): Promise<ExtensionMeta>;
94
100
  /** The stored bundle's metadata, or null if none is stored (`GET …/extension/bundle/meta`). */
95
- export declare function fetchExtensionMeta(baseUrl: string, projectKey: string, token: string): Promise<ExtensionMeta | null>;
101
+ export declare function fetchExtensionMeta(baseUrl: string, projectKey: string, authFetch: AuthFetch): Promise<ExtensionMeta | null>;
96
102
  /** Remove the project's extension subgraph from Hive (`DELETE …/extension/subgraph`). */
97
- export declare function deleteExtensionSubgraph(baseUrl: string, projectKey: string, token: string): Promise<void>;
103
+ export declare function deleteExtensionSubgraph(baseUrl: string, projectKey: string, authFetch: AuthFetch): Promise<void>;
98
104
  /**
99
105
  * The project's extension HTTP allowlist: the merchant-tunable `allow` host patterns
100
106
  * the extension sandbox's `fetch` may reach, plus the operator `deny` ceiling. A host
@@ -109,7 +115,7 @@ export interface AllowlistView {
109
115
  deny: string[];
110
116
  }
111
117
  /** GET the project's extension HTTP allowlist (`GET …/extension/allowlist`). */
112
- export declare function getAllowlist(baseUrl: string, projectKey: string, token: string): Promise<AllowlistView>;
118
+ export declare function getAllowlist(baseUrl: string, projectKey: string, authFetch: AuthFetch): Promise<AllowlistView>;
113
119
  /**
114
120
  * Replace the merchant `allow` patterns with `patterns` (`PUT …/extension/allowlist`).
115
121
  * The route takes a bare JSON array and REPLACES the whole allow list — the add/remove
@@ -118,18 +124,18 @@ export declare function getAllowlist(baseUrl: string, projectKey: string, token:
118
124
  * returns the stored list plus the config's new monotonic version. The `deny` ceiling
119
125
  * is untouched (it has no write route).
120
126
  */
121
- export declare function putAllowlist(baseUrl: string, projectKey: string, token: string, patterns: string[]): Promise<{
127
+ export declare function putAllowlist(baseUrl: string, projectKey: string, authFetch: AuthFetch, patterns: string[]): Promise<{
122
128
  allow: string[];
123
129
  version: number;
124
130
  }>;
125
131
  /** List the project's extension config entries, secret values redacted (`GET …/extension/config`). */
126
- export declare function listConfig(baseUrl: string, projectKey: string, token: string): Promise<ConfigEntry[]>;
132
+ export declare function listConfig(baseUrl: string, projectKey: string, authFetch: AuthFetch): Promise<ConfigEntry[]>;
127
133
  /**
128
134
  * Upsert/delete config entries and return the resulting (redacted) list
129
135
  * (`PATCH …/extension/config`). An entry with `value: null` deletes that key. PATCH
130
136
  * (not PUT) so a single set/unset touches one key without clobbering the rest.
131
137
  */
132
- export declare function patchConfig(baseUrl: string, projectKey: string, token: string, entries: Array<{
138
+ export declare function patchConfig(baseUrl: string, projectKey: string, authFetch: AuthFetch, entries: Array<{
133
139
  key: string;
134
140
  value: string | null;
135
141
  secret?: boolean;