@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.
- package/README.md +2 -6
- package/dist/commands/integration-layer/allowlist/add.js +3 -3
- package/dist/commands/integration-layer/allowlist/add.js.map +1 -1
- package/dist/commands/integration-layer/allowlist/list.js +2 -2
- package/dist/commands/integration-layer/allowlist/list.js.map +1 -1
- package/dist/commands/integration-layer/allowlist/remove.js +3 -3
- package/dist/commands/integration-layer/allowlist/remove.js.map +1 -1
- package/dist/commands/integration-layer/allowlist/set.js +3 -3
- package/dist/commands/integration-layer/allowlist/set.js.map +1 -1
- package/dist/commands/integration-layer/config/get.js +2 -2
- package/dist/commands/integration-layer/config/get.js.map +1 -1
- package/dist/commands/integration-layer/config/list.js +2 -2
- package/dist/commands/integration-layer/config/list.js.map +1 -1
- package/dist/commands/integration-layer/config/set.js +2 -2
- package/dist/commands/integration-layer/config/set.js.map +1 -1
- package/dist/commands/integration-layer/config/unset.js +2 -2
- package/dist/commands/integration-layer/config/unset.js.map +1 -1
- package/dist/commands/integration-layer/explore.js +5 -5
- package/dist/commands/integration-layer/explore.js.map +1 -1
- package/dist/commands/integration-layer/extension/build.js +4 -1
- package/dist/commands/integration-layer/extension/build.js.map +1 -1
- package/dist/commands/integration-layer/extension/create-api-extension-input.d.ts +12 -0
- package/dist/commands/integration-layer/extension/create-api-extension-input.js +49 -0
- package/dist/commands/integration-layer/extension/create-api-extension-input.js.map +1 -0
- package/dist/commands/integration-layer/extension/delete.js +2 -2
- package/dist/commands/integration-layer/extension/delete.js.map +1 -1
- package/dist/commands/integration-layer/extension/invoke-api-extension.d.ts +19 -0
- package/dist/commands/integration-layer/extension/invoke-api-extension.js +140 -0
- package/dist/commands/integration-layer/extension/invoke-api-extension.js.map +1 -0
- package/dist/commands/integration-layer/extension/push.js +8 -5
- package/dist/commands/integration-layer/extension/push.js.map +1 -1
- package/dist/commands/integration-layer/extension/serve.d.ts +36 -0
- package/dist/commands/integration-layer/extension/serve.js +140 -36
- package/dist/commands/integration-layer/extension/serve.js.map +1 -1
- package/dist/commands/integration-layer/extension/status.js +2 -2
- package/dist/commands/integration-layer/extension/status.js.map +1 -1
- package/dist/commands/integration-layer/extension/validate.js +6 -3
- package/dist/commands/integration-layer/extension/validate.js.map +1 -1
- package/dist/commands/integration-layer/schema/fetch.js +2 -2
- package/dist/commands/integration-layer/schema/fetch.js.map +1 -1
- package/dist/hooks/authentication.d.ts +3 -0
- package/dist/hooks/authentication.js +33 -0
- package/dist/hooks/authentication.js.map +1 -0
- package/dist/lib/auth.d.ts +5 -0
- package/dist/lib/auth.js +41 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/awaitBundleState.d.ts +2 -2
- package/dist/lib/awaitBundleState.js +2 -2
- package/dist/lib/awaitBundleState.js.map +1 -1
- package/dist/lib/base.d.ts +12 -21
- package/dist/lib/base.js +27 -76
- package/dist/lib/base.js.map +1 -1
- package/dist/lib/extensionConfig.d.ts +17 -0
- package/dist/lib/extensionConfig.js +36 -0
- package/dist/lib/extensionConfig.js.map +1 -0
- package/dist/lib/ilClient.d.ts +16 -10
- package/dist/lib/ilClient.js +28 -31
- package/dist/lib/ilClient.js.map +1 -1
- package/dist/lib/loadLocalEnv.d.ts +49 -0
- package/dist/lib/loadLocalEnv.js +112 -0
- package/dist/lib/loadLocalEnv.js.map +1 -0
- package/dist/lib/tooling/compose.js +2 -2
- package/dist/lib/tooling/compose.js.map +1 -1
- package/dist/lib/tooling/extensionInputSampleObj.d.ts +8 -0
- package/dist/lib/tooling/extensionInputSampleObj.js +178 -0
- package/dist/lib/tooling/extensionInputSampleObj.js.map +1 -0
- package/dist/lib/tooling/extensions.d.ts +22 -5
- package/dist/lib/tooling/extensions.js +30 -8
- package/dist/lib/tooling/extensions.js.map +1 -1
- package/dist/lib/tooling/generateExtensionInputSample.d.ts +22 -0
- package/dist/lib/tooling/generateExtensionInputSample.js +36 -0
- package/dist/lib/tooling/generateExtensionInputSample.js.map +1 -0
- package/dist/lib/tooling/sandboxFetch.d.ts +14 -0
- package/dist/lib/tooling/sandboxFetch.js +100 -0
- package/dist/lib/tooling/sandboxFetch.js.map +1 -0
- package/package.json +11 -3
- package/dist/commands/integration-layer/extension/invoke.d.ts +0 -14
- package/dist/commands/integration-layer/extension/invoke.js +0 -94
- 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,
|
|
17
|
-
const sdl = await fetchSubgraphSdl(baseUrl, projectKey,
|
|
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,
|
|
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,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;
|
package/dist/lib/auth.js
ADDED
|
@@ -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,
|
|
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,
|
|
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,
|
|
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,
|
|
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"}
|
package/dist/lib/base.d.ts
CHANGED
|
@@ -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
|
-
/**
|
|
15
|
-
|
|
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
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
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
|
-
|
|
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
|
-
*
|
|
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.
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
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,
|
|
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
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
147
|
-
|
|
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
|
-
*
|
|
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,
|
|
119
|
+
return { baseUrl: baseUrl.replace(/\/+$/, ""), projectKey, authFetch: this.authFetch };
|
|
169
120
|
}
|
|
170
121
|
}
|
|
171
122
|
//# sourceMappingURL=base.js.map
|
package/dist/lib/base.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/lib/base.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/lib/base.ts"],"names":[],"mappings":"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"}
|
|
@@ -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"}
|
package/dist/lib/ilClient.d.ts
CHANGED
|
@@ -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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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;
|