@contentful/experience-design-system-cli 2.32.1-dev-build-d5e6302.0 → 2.32.1-dev-build-47de682.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/dist/package.json +1 -1
- package/dist/src/api/clients/abstract-api-client.d.ts +24 -0
- package/dist/src/api/clients/cma-client.d.ts +8 -0
- package/dist/src/api/clients/edsi-client.d.ts +22 -0
- package/dist/src/api/index.d.ts +16 -0
- package/dist/src/apply/api-client.d.ts +7 -68
- package/dist/src/constants/cma/pagination.d.ts +1 -0
- package/dist/src/constants/edsi/breaking-changes.d.ts +3 -0
- package/dist/src/constants/edsi/errors.d.ts +3 -0
- package/dist/src/constants/edsi/host.d.ts +1 -0
- package/dist/src/constants/shared/retry.d.ts +1 -0
- package/dist/src/errors/api-error.d.ts +6 -0
- package/dist/src/helpers/edsi-response.d.ts +17 -0
- package/dist/src/helpers/http.d.ts +4 -0
- package/dist/src/helpers/retry.d.ts +5 -0
- package/dist/src/helpers/url.d.ts +4 -0
- package/dist/src/host-utils.d.ts +1 -4
- package/dist/src/import/orchestrator.d.ts +9 -0
- package/dist/src/index.js +345 -117
- package/dist/src/interfaces/clients/cma-client-options.d.ts +6 -0
- package/dist/src/interfaces/clients/edsi-client-options.d.ts +12 -0
- package/dist/src/interfaces/clients/poll-options.d.ts +7 -0
- package/dist/src/interfaces/clients/retry-options.d.ts +6 -0
- package/dist/src/interfaces/responses/cma-collection.d.ts +6 -0
- package/dist/src/interfaces/responses/existing-component-entity.d.ts +8 -0
- package/dist/src/interfaces/responses/existing-entities-response.d.ts +6 -0
- package/dist/src/interfaces/responses/existing-token-entity.d.ts +6 -0
- package/dist/src/interfaces/responses/preview-validation-error.d.ts +5 -0
- package/dist/src/session/db.d.ts +1 -1
- package/dist/src/setup/command.d.ts +0 -6
- package/package.json +6 -6
package/dist/package.json
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface AbstractApiClientOptions {
|
|
2
|
+
host?: string;
|
|
3
|
+
cmaToken: string;
|
|
4
|
+
spaceId: string;
|
|
5
|
+
environmentId: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Shared base for CmaApiClient + EdsiApiClient. Owns the fields, URL
|
|
9
|
+
* helpers, and the /users/me validateCmaToken flow that both clients need.
|
|
10
|
+
* Subclasses override validateCmaToken() when they need to add
|
|
11
|
+
* service-specific follow-ups (e.g. EdsiApiClient calls checkPreflight()
|
|
12
|
+
* after the base check).
|
|
13
|
+
*/
|
|
14
|
+
export declare abstract class AbstractApiClient {
|
|
15
|
+
protected readonly host: string;
|
|
16
|
+
protected readonly token: string;
|
|
17
|
+
protected readonly spaceId: string;
|
|
18
|
+
protected readonly environmentId: string;
|
|
19
|
+
constructor(opts: AbstractApiClientOptions);
|
|
20
|
+
protected base(): string;
|
|
21
|
+
protected buildHeaders(): Record<string, string>;
|
|
22
|
+
validateCmaToken(): Promise<void>;
|
|
23
|
+
protected onValidateCmaTokenResponse(_res: Response): void;
|
|
24
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AbstractApiClient } from './abstract-api-client.js';
|
|
2
|
+
import type { CmaClientOptions } from '../../interfaces/clients/cma-client-options.js';
|
|
3
|
+
import type { ExistingEntitiesResponse } from '../../interfaces/responses/existing-entities-response.js';
|
|
4
|
+
export declare class CmaApiClient extends AbstractApiClient {
|
|
5
|
+
constructor(opts: CmaClientOptions);
|
|
6
|
+
listExistingEntities(): Promise<ExistingEntitiesResponse>;
|
|
7
|
+
private listAll;
|
|
8
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ManifestPayload, ServerPreviewResponse, ApplyOperationResponse } from '@contentful/experience-design-system-types';
|
|
2
|
+
import { AbstractApiClient } from './abstract-api-client.js';
|
|
3
|
+
import type { EdsiClientOptions } from '../../interfaces/clients/edsi-client-options.js';
|
|
4
|
+
import type { PollOptions } from '../../interfaces/clients/poll-options.js';
|
|
5
|
+
export declare class EdsiApiClient extends AbstractApiClient {
|
|
6
|
+
private retry;
|
|
7
|
+
private lastRequestId?;
|
|
8
|
+
getLastRequestId(): string | undefined;
|
|
9
|
+
private noteRequestId;
|
|
10
|
+
protected onValidateCmaTokenResponse(res: Response): void;
|
|
11
|
+
constructor(opts: EdsiClientOptions);
|
|
12
|
+
private headers;
|
|
13
|
+
private requestWithRetry;
|
|
14
|
+
validateCmaToken(): Promise<void>;
|
|
15
|
+
checkPreflight(): Promise<void>;
|
|
16
|
+
previewImport(manifest: ManifestPayload, allowDeletions?: boolean): Promise<ServerPreviewResponse>;
|
|
17
|
+
applyImport(manifest: ManifestPayload, options: {
|
|
18
|
+
acknowledgeBreakingChanges: boolean;
|
|
19
|
+
allowDeletions?: boolean;
|
|
20
|
+
}): Promise<ApplyOperationResponse>;
|
|
21
|
+
pollOperation(operationId: string, opts?: PollOptions): Promise<ApplyOperationResponse>;
|
|
22
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { CmaApiClient } from './clients/cma-client.js';
|
|
2
|
+
export { EdsiApiClient } from './clients/edsi-client.js';
|
|
3
|
+
export { AbstractApiClient } from './clients/abstract-api-client.js';
|
|
4
|
+
export { ApiError } from '../errors/api-error.js';
|
|
5
|
+
export { DEFAULT_HOST } from '../constants/edsi/host.js';
|
|
6
|
+
export { PREVIEW_ERROR_PREFIX, APPLY_ERROR_PREFIX, VALIDATION_FAILED_CODE } from '../constants/edsi/errors.js';
|
|
7
|
+
export { parsePreviewValidationErrors, sanitizeBreakingChanges } from '../helpers/edsi-response.js';
|
|
8
|
+
export type { CmaClientOptions } from '../interfaces/clients/cma-client-options.js';
|
|
9
|
+
export type { EdsiClientOptions } from '../interfaces/clients/edsi-client-options.js';
|
|
10
|
+
export type { PollOptions } from '../interfaces/clients/poll-options.js';
|
|
11
|
+
export type { RetryOptions } from '../interfaces/clients/retry-options.js';
|
|
12
|
+
export type { ExistingComponentEntity } from '../interfaces/responses/existing-component-entity.js';
|
|
13
|
+
export type { ExistingTokenEntity } from '../interfaces/responses/existing-token-entity.js';
|
|
14
|
+
export type { ExistingEntitiesResponse } from '../interfaces/responses/existing-entities-response.js';
|
|
15
|
+
export type { PreviewValidationError } from '../interfaces/responses/preview-validation-error.js';
|
|
16
|
+
export type { CmaCollection } from '../interfaces/responses/cma-collection.js';
|
|
@@ -1,68 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
cmaToken: string;
|
|
9
|
-
spaceId: string;
|
|
10
|
-
environmentId: string;
|
|
11
|
-
retry?: {
|
|
12
|
-
maxAttempts?: number;
|
|
13
|
-
initialDelayMs?: number;
|
|
14
|
-
maxDelayMs?: number;
|
|
15
|
-
sleep?: (delayMs: number) => Promise<void>;
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
export declare class ApiError extends Error {
|
|
19
|
-
readonly status: number;
|
|
20
|
-
readonly body: string;
|
|
21
|
-
readonly guidance?: string | undefined;
|
|
22
|
-
constructor(message: string, status: number, body: string, guidance?: string | undefined);
|
|
23
|
-
}
|
|
24
|
-
export interface PreviewValidationError {
|
|
25
|
-
componentName: string;
|
|
26
|
-
path: string;
|
|
27
|
-
message: string;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Parse the JSON body of a 422 from `previewImport()` into structured
|
|
31
|
-
* per-component validation errors. Returns [] for any malformed input
|
|
32
|
-
* so callers can fall back to the generic error path without try/catch.
|
|
33
|
-
*
|
|
34
|
-
* Path shape: `manifest:components/<Name>/$slots/<key>` or
|
|
35
|
-
* `manifest:components/<Name>/$properties/<key>`. Only the component
|
|
36
|
-
* name is extracted today; `path` and `message` are kept verbatim so
|
|
37
|
-
* future surfaces (debug logging, headless retry in SP-4) can render
|
|
38
|
-
* the field-level detail.
|
|
39
|
-
*/
|
|
40
|
-
export declare function parsePreviewValidationErrors(body: string): PreviewValidationError[];
|
|
41
|
-
export declare function sanitizeBreakingChanges(raw: unknown): BreakingChange[];
|
|
42
|
-
export declare class ImportApiClient {
|
|
43
|
-
private host;
|
|
44
|
-
private token;
|
|
45
|
-
private spaceId;
|
|
46
|
-
private environmentId;
|
|
47
|
-
private retry;
|
|
48
|
-
private lastRequestId?;
|
|
49
|
-
getLastRequestId(): string | undefined;
|
|
50
|
-
private noteRequestId;
|
|
51
|
-
constructor(opts: ApiClientOptions);
|
|
52
|
-
private base;
|
|
53
|
-
private headers;
|
|
54
|
-
private requestWithRetry;
|
|
55
|
-
validateToken(): Promise<void>;
|
|
56
|
-
checkPreflight(): Promise<void>;
|
|
57
|
-
previewImport(manifest: ManifestPayload, allowDeletions?: boolean): Promise<ServerPreviewResponse>;
|
|
58
|
-
applyImport(manifest: ManifestPayload, options: {
|
|
59
|
-
acknowledgeBreakingChanges: boolean;
|
|
60
|
-
allowDeletions?: boolean;
|
|
61
|
-
}): Promise<ApplyOperationResponse>;
|
|
62
|
-
pollOperation(operationId: string, opts?: {
|
|
63
|
-
intervalMs?: number;
|
|
64
|
-
maxIntervalMs?: number;
|
|
65
|
-
maxAttempts?: number;
|
|
66
|
-
onProgress?: (op: ApplyOperationResponse) => void;
|
|
67
|
-
}): Promise<ApplyOperationResponse>;
|
|
68
|
-
}
|
|
1
|
+
export { EdsiApiClient, EdsiApiClient as ImportApiClient } from '../api/clients/edsi-client.js';
|
|
2
|
+
export { DEFAULT_HOST } from '../constants/edsi/host.js';
|
|
3
|
+
export { PREVIEW_ERROR_PREFIX, APPLY_ERROR_PREFIX, VALIDATION_FAILED_CODE } from '../constants/edsi/errors.js';
|
|
4
|
+
export { parsePreviewValidationErrors, sanitizeBreakingChanges } from '../helpers/edsi-response.js';
|
|
5
|
+
export type { PreviewValidationError } from '../interfaces/responses/preview-validation-error.js';
|
|
6
|
+
export { ApiError } from '../errors/api-error.js';
|
|
7
|
+
export type { EdsiClientOptions as ApiClientOptions } from '../interfaces/clients/edsi-client-options.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const CMA_PAGE_LIMIT = 100;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const DEFAULT_HOST = "https://api.contentful.com";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const MAX_RETRY_AFTER_MS = 60000;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { BreakingChange, ServerPreviewResponse } from '@contentful/experience-design-system-types';
|
|
2
|
+
import type { PreviewValidationError } from '../interfaces/responses/preview-validation-error.js';
|
|
3
|
+
/**
|
|
4
|
+
* Parse the JSON body of a 422 from `previewImport()` into structured
|
|
5
|
+
* per-component validation errors. Returns [] for any malformed input
|
|
6
|
+
* so callers can fall back to the generic error path without try/catch.
|
|
7
|
+
*
|
|
8
|
+
* Path shape: `manifest:components/<Name>/$slots/<key>` or
|
|
9
|
+
* `manifest:components/<Name>/$properties/<key>`. Only the component
|
|
10
|
+
* name is extracted today; `path` and `message` are kept verbatim so
|
|
11
|
+
* future surfaces (debug logging, headless retry in SP-4) can render
|
|
12
|
+
* the field-level detail.
|
|
13
|
+
*/
|
|
14
|
+
export declare function parsePreviewValidationErrors(body: string): PreviewValidationError[];
|
|
15
|
+
export declare function sanitizeBreakingChanges(raw: unknown): BreakingChange[];
|
|
16
|
+
export declare function sanitizePreviewResponse(res: ServerPreviewResponse): ServerPreviewResponse;
|
|
17
|
+
export declare function isApsDenialBody(body: string): boolean;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function defaultSleep(delayMs: number): Promise<void>;
|
|
2
|
+
export declare function isTransientStatus(status: number): boolean;
|
|
3
|
+
export declare function retryAfterMs(response: Response): number | undefined;
|
|
4
|
+
export declare function errorMessage(error: unknown): string;
|
|
5
|
+
export declare function stringifyError(error: unknown): string;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const DEFAULT_API_HOST = "https://api.contentful.com";
|
|
2
|
+
export declare const DEFAULT_CONFIGURED_HOST = "api.contentful.com";
|
|
3
|
+
export declare function toConfiguredHost(host?: string): string | undefined;
|
|
4
|
+
export declare function toApiHost(host?: string): string;
|
package/dist/src/host-utils.d.ts
CHANGED
|
@@ -1,4 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export declare const DEFAULT_CONFIGURED_HOST = "api.contentful.com";
|
|
3
|
-
export declare function toConfiguredHost(host?: string): string | undefined;
|
|
4
|
-
export declare function toApiHost(host?: string): string;
|
|
1
|
+
export { DEFAULT_API_HOST, DEFAULT_CONFIGURED_HOST, toConfiguredHost, toApiHost } from './helpers/url.js';
|
|
@@ -28,6 +28,15 @@ export interface PipelineOptions {
|
|
|
28
28
|
/** When true, auto-reject cycle participants and retry push instead of surfacing an error. */
|
|
29
29
|
autoRejectCycles?: boolean;
|
|
30
30
|
allowDeletions?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Fetch existing Components + DesignTokens from the target space+env
|
|
33
|
+
* and persist them under outDir/.existing-entities.json so downstream
|
|
34
|
+
* agent steps can consume them as context. Requires spaceId +
|
|
35
|
+
* environmentId + cmaToken; skipped with a warning otherwise. No-op
|
|
36
|
+
* for the agent flow in this PR — the file is written but nothing
|
|
37
|
+
* reads it yet.
|
|
38
|
+
*/
|
|
39
|
+
withSpaceContext?: boolean;
|
|
31
40
|
compositionMode?: CompositionMode;
|
|
32
41
|
compositionMap?: string;
|
|
33
42
|
compositionAgent?: boolean;
|
package/dist/src/index.js
CHANGED
|
@@ -287,7 +287,7 @@ function resolveAgentModel(agent, explicit, bedrock = false) {
|
|
|
287
287
|
if (bedrock && agent === "codex")
|
|
288
288
|
return DEFAULT_CODEX_BEDROCK_MODEL;
|
|
289
289
|
if (bedrock && agent === "opencode")
|
|
290
|
-
return withBedrockProviderPrefix(
|
|
290
|
+
return withBedrockProviderPrefix(DEFAULT_MODELS.opencode);
|
|
291
291
|
return DEFAULT_MODELS[agent];
|
|
292
292
|
}
|
|
293
293
|
function withBedrockProviderPrefix(model) {
|
|
@@ -298,8 +298,7 @@ function codexBedrockConfigArgs() {
|
|
|
298
298
|
return ["-c", "model_provider=amazon-bedrock", "-c", `model_providers.amazon-bedrock.region=${region}`];
|
|
299
299
|
}
|
|
300
300
|
function buildArgs(agent, prompt2, model, promptViaStdin = false, bedrock = false) {
|
|
301
|
-
const
|
|
302
|
-
const modelArg = resolvedModel ? ["--model", resolvedModel] : [];
|
|
301
|
+
const modelArg = ["--model", resolveAgentModel(agent, model, bedrock)];
|
|
303
302
|
const promptArg = promptViaStdin ? [] : [prompt2];
|
|
304
303
|
switch (agent) {
|
|
305
304
|
case "claude":
|
|
@@ -314,7 +313,7 @@ function buildArgs(agent, prompt2, model, promptViaStdin = false, bedrock = fals
|
|
|
314
313
|
return ["--print", ...modelArg, ...promptArg];
|
|
315
314
|
case "copilot": {
|
|
316
315
|
const copilotModel = resolveAgentModel("copilot", model);
|
|
317
|
-
const copilotModelArg =
|
|
316
|
+
const copilotModelArg = copilotModel === "Auto" ? [] : ["--model", copilotModel];
|
|
318
317
|
return ["-p", ...promptArg, ...copilotModelArg, "--allow-all-tools"];
|
|
319
318
|
}
|
|
320
319
|
}
|
|
@@ -457,7 +456,7 @@ function extractSentinelOutput(stdout) {
|
|
|
457
456
|
return "multiple";
|
|
458
457
|
return stdout.slice(startIdx + START.length, endIdx).trim();
|
|
459
458
|
}
|
|
460
|
-
var VALID_SELECT_TOOL_NAMES, VALID_TOOL_NAMES, VALID_TOKEN_TOOL_NAMES, VALID_CDF_TYPES, VALID_CATEGORIES, AGENT_BINARIES, BEDROCK_ENV_BY_AGENT, BEDROCK_CAPABLE_AGENTS, DEFAULT_CODEX_BEDROCK_REGION,
|
|
459
|
+
var VALID_SELECT_TOOL_NAMES, VALID_TOOL_NAMES, VALID_TOKEN_TOOL_NAMES, VALID_CDF_TYPES, VALID_CATEGORIES, AGENT_BINARIES, BEDROCK_ENV_BY_AGENT, BEDROCK_CAPABLE_AGENTS, DEFAULT_CODEX_BEDROCK_REGION, DEFAULT_MODELS, DEFAULT_CODEX_BEDROCK_MODEL;
|
|
461
460
|
var init_agent_runner = __esm({
|
|
462
461
|
"packages/experience-design-system-generation/dist/src/agent-runner.js"() {
|
|
463
462
|
"use strict";
|
|
@@ -479,10 +478,11 @@ var init_agent_runner = __esm({
|
|
|
479
478
|
};
|
|
480
479
|
BEDROCK_CAPABLE_AGENTS = /* @__PURE__ */ new Set(["claude", "codex", "opencode"]);
|
|
481
480
|
DEFAULT_CODEX_BEDROCK_REGION = "us-east-1";
|
|
482
|
-
DEFAULT_OPENCODE_MODEL = "claude-haiku-4-5";
|
|
483
481
|
DEFAULT_MODELS = {
|
|
484
482
|
claude: "haiku",
|
|
485
|
-
|
|
483
|
+
codex: "gpt-5.6-luna",
|
|
484
|
+
// requires OPENAI_API_KEY; ChatGPT account users must pass --model
|
|
485
|
+
opencode: "claude-haiku-4-5",
|
|
486
486
|
cursor: "gpt-mini",
|
|
487
487
|
// cursor alias for gpt-5.4-mini-medium; haiku not in cursor's catalog
|
|
488
488
|
copilot: "Auto"
|
|
@@ -12603,37 +12603,6 @@ var init_src3 = __esm({
|
|
|
12603
12603
|
}
|
|
12604
12604
|
});
|
|
12605
12605
|
|
|
12606
|
-
// packages/experience-design-system-cli/src/host-utils.ts
|
|
12607
|
-
function trimTrailingSlashes(value) {
|
|
12608
|
-
return value.replace(/\/+$/, "");
|
|
12609
|
-
}
|
|
12610
|
-
function normalizeHostInput(host) {
|
|
12611
|
-
const value = host?.trim();
|
|
12612
|
-
if (!value) return void 0;
|
|
12613
|
-
return trimTrailingSlashes(value);
|
|
12614
|
-
}
|
|
12615
|
-
function toConfiguredHost(host) {
|
|
12616
|
-
const normalized = normalizeHostInput(host);
|
|
12617
|
-
if (!normalized) return void 0;
|
|
12618
|
-
return normalized.replace(/^https:\/\//i, "");
|
|
12619
|
-
}
|
|
12620
|
-
function toApiHost(host) {
|
|
12621
|
-
const normalized = normalizeHostInput(host);
|
|
12622
|
-
if (!normalized) return DEFAULT_API_HOST;
|
|
12623
|
-
if (/^[a-z][a-z\d+\-.]*:\/\//i.test(normalized)) {
|
|
12624
|
-
return normalized;
|
|
12625
|
-
}
|
|
12626
|
-
return `https://${normalized}`;
|
|
12627
|
-
}
|
|
12628
|
-
var DEFAULT_API_HOST, DEFAULT_CONFIGURED_HOST;
|
|
12629
|
-
var init_host_utils = __esm({
|
|
12630
|
-
"packages/experience-design-system-cli/src/host-utils.ts"() {
|
|
12631
|
-
"use strict";
|
|
12632
|
-
DEFAULT_API_HOST = "https://api.contentful.com";
|
|
12633
|
-
DEFAULT_CONFIGURED_HOST = "api.contentful.com";
|
|
12634
|
-
}
|
|
12635
|
-
});
|
|
12636
|
-
|
|
12637
12606
|
// packages/experience-design-system-cli/src/lib/debug-logger.ts
|
|
12638
12607
|
import { mkdirSync as mkdirSync2, appendFileSync } from "node:fs";
|
|
12639
12608
|
import { join as join8, dirname as dirname8 } from "node:path";
|
|
@@ -12834,7 +12803,39 @@ var init_user_agent = __esm({
|
|
|
12834
12803
|
}
|
|
12835
12804
|
});
|
|
12836
12805
|
|
|
12837
|
-
// packages/experience-design-system-cli/src/
|
|
12806
|
+
// packages/experience-design-system-cli/src/helpers/http.ts
|
|
12807
|
+
function buildHeaders(token) {
|
|
12808
|
+
return {
|
|
12809
|
+
Authorization: `Bearer ${token}`,
|
|
12810
|
+
"Content-Type": "application/json",
|
|
12811
|
+
"X-Contentful-User-Agent": buildUserAgent()
|
|
12812
|
+
};
|
|
12813
|
+
}
|
|
12814
|
+
async function request(url, options) {
|
|
12815
|
+
const init = {
|
|
12816
|
+
method: options.method ?? "GET",
|
|
12817
|
+
headers: buildHeaders(options.token)
|
|
12818
|
+
};
|
|
12819
|
+
if (options.body) init.body = options.body;
|
|
12820
|
+
return fetch(url, init);
|
|
12821
|
+
}
|
|
12822
|
+
var init_http = __esm({
|
|
12823
|
+
"packages/experience-design-system-cli/src/helpers/http.ts"() {
|
|
12824
|
+
"use strict";
|
|
12825
|
+
init_user_agent();
|
|
12826
|
+
}
|
|
12827
|
+
});
|
|
12828
|
+
|
|
12829
|
+
// packages/experience-design-system-cli/src/constants/shared/retry.ts
|
|
12830
|
+
var MAX_RETRY_AFTER_MS;
|
|
12831
|
+
var init_retry = __esm({
|
|
12832
|
+
"packages/experience-design-system-cli/src/constants/shared/retry.ts"() {
|
|
12833
|
+
"use strict";
|
|
12834
|
+
MAX_RETRY_AFTER_MS = 6e4;
|
|
12835
|
+
}
|
|
12836
|
+
});
|
|
12837
|
+
|
|
12838
|
+
// packages/experience-design-system-cli/src/helpers/retry.ts
|
|
12838
12839
|
function defaultSleep(delayMs) {
|
|
12839
12840
|
return new Promise((resolve27) => setTimeout(resolve27, delayMs));
|
|
12840
12841
|
}
|
|
@@ -12855,6 +12856,30 @@ function errorMessage(error) {
|
|
|
12855
12856
|
function stringifyError(error) {
|
|
12856
12857
|
return typeof error === "string" ? error : JSON.stringify(error ?? {});
|
|
12857
12858
|
}
|
|
12859
|
+
var init_retry2 = __esm({
|
|
12860
|
+
"packages/experience-design-system-cli/src/helpers/retry.ts"() {
|
|
12861
|
+
"use strict";
|
|
12862
|
+
init_retry();
|
|
12863
|
+
}
|
|
12864
|
+
});
|
|
12865
|
+
|
|
12866
|
+
// packages/experience-design-system-cli/src/constants/edsi/breaking-changes.ts
|
|
12867
|
+
var PROPERTY_BREAKING_REASONS, SLOT_BREAKING_REASONS, COMPONENT_PATH_PREFIX;
|
|
12868
|
+
var init_breaking_changes = __esm({
|
|
12869
|
+
"packages/experience-design-system-cli/src/constants/edsi/breaking-changes.ts"() {
|
|
12870
|
+
"use strict";
|
|
12871
|
+
PROPERTY_BREAKING_REASONS = /* @__PURE__ */ new Set([
|
|
12872
|
+
"removed",
|
|
12873
|
+
"added_required_no_default",
|
|
12874
|
+
"type_changed",
|
|
12875
|
+
"validation_narrowed"
|
|
12876
|
+
]);
|
|
12877
|
+
SLOT_BREAKING_REASONS = /* @__PURE__ */ new Set(["slot_removed", "slot_allowed_components_narrowed"]);
|
|
12878
|
+
COMPONENT_PATH_PREFIX = "manifest:components/";
|
|
12879
|
+
}
|
|
12880
|
+
});
|
|
12881
|
+
|
|
12882
|
+
// packages/experience-design-system-cli/src/helpers/edsi-response.ts
|
|
12858
12883
|
function parsePreviewValidationErrors(body) {
|
|
12859
12884
|
if (!body) return [];
|
|
12860
12885
|
let parsed;
|
|
@@ -12917,31 +12942,18 @@ function isApsDenialBody(body) {
|
|
|
12917
12942
|
return false;
|
|
12918
12943
|
}
|
|
12919
12944
|
}
|
|
12920
|
-
|
|
12921
|
-
|
|
12922
|
-
|
|
12923
|
-
|
|
12924
|
-
|
|
12925
|
-
|
|
12926
|
-
|
|
12927
|
-
|
|
12928
|
-
|
|
12929
|
-
|
|
12930
|
-
|
|
12931
|
-
return fetch(url, init);
|
|
12932
|
-
}
|
|
12933
|
-
var PREVIEW_ERROR_PREFIX, APPLY_ERROR_PREFIX, VALIDATION_FAILED_CODE, MAX_RETRY_AFTER_MS, ERROR_BODY_LOG_CAP, ApiError, COMPONENT_PATH_PREFIX, PROPERTY_BREAKING_REASONS, SLOT_BREAKING_REASONS, ImportApiClient;
|
|
12934
|
-
var init_api_client = __esm({
|
|
12935
|
-
"packages/experience-design-system-cli/src/apply/api-client.ts"() {
|
|
12945
|
+
var init_edsi_response = __esm({
|
|
12946
|
+
"packages/experience-design-system-cli/src/helpers/edsi-response.ts"() {
|
|
12947
|
+
"use strict";
|
|
12948
|
+
init_breaking_changes();
|
|
12949
|
+
}
|
|
12950
|
+
});
|
|
12951
|
+
|
|
12952
|
+
// packages/experience-design-system-cli/src/errors/api-error.ts
|
|
12953
|
+
var ERROR_BODY_LOG_CAP, ApiError;
|
|
12954
|
+
var init_api_error = __esm({
|
|
12955
|
+
"packages/experience-design-system-cli/src/errors/api-error.ts"() {
|
|
12936
12956
|
"use strict";
|
|
12937
|
-
init_src3();
|
|
12938
|
-
init_host_utils();
|
|
12939
|
-
init_debug_logger();
|
|
12940
|
-
init_user_agent();
|
|
12941
|
-
PREVIEW_ERROR_PREFIX = "preview failed:";
|
|
12942
|
-
APPLY_ERROR_PREFIX = "apply failed:";
|
|
12943
|
-
VALIDATION_FAILED_CODE = '"ValidationFailed"';
|
|
12944
|
-
MAX_RETRY_AFTER_MS = 6e4;
|
|
12945
12957
|
ERROR_BODY_LOG_CAP = 16384;
|
|
12946
12958
|
ApiError = class extends Error {
|
|
12947
12959
|
constructor(message, status, body, guidance) {
|
|
@@ -12959,19 +12971,109 @@ ${trimmed}`;
|
|
|
12959
12971
|
body;
|
|
12960
12972
|
guidance;
|
|
12961
12973
|
};
|
|
12962
|
-
|
|
12963
|
-
|
|
12964
|
-
|
|
12965
|
-
|
|
12966
|
-
|
|
12967
|
-
|
|
12968
|
-
|
|
12969
|
-
|
|
12970
|
-
|
|
12974
|
+
}
|
|
12975
|
+
});
|
|
12976
|
+
|
|
12977
|
+
// packages/experience-design-system-cli/src/helpers/url.ts
|
|
12978
|
+
function trimTrailingSlashes(value) {
|
|
12979
|
+
return value.replace(/\/+$/, "");
|
|
12980
|
+
}
|
|
12981
|
+
function normalizeHostInput(host) {
|
|
12982
|
+
const value = host?.trim();
|
|
12983
|
+
if (!value) return void 0;
|
|
12984
|
+
return trimTrailingSlashes(value);
|
|
12985
|
+
}
|
|
12986
|
+
function toConfiguredHost(host) {
|
|
12987
|
+
const normalized = normalizeHostInput(host);
|
|
12988
|
+
if (!normalized) return void 0;
|
|
12989
|
+
return normalized.replace(/^https:\/\//i, "");
|
|
12990
|
+
}
|
|
12991
|
+
function toApiHost(host) {
|
|
12992
|
+
const normalized = normalizeHostInput(host);
|
|
12993
|
+
if (!normalized) return DEFAULT_API_HOST;
|
|
12994
|
+
if (/^[a-z][a-z\d+\-.]*:\/\//i.test(normalized)) {
|
|
12995
|
+
return normalized;
|
|
12996
|
+
}
|
|
12997
|
+
return `https://${normalized}`;
|
|
12998
|
+
}
|
|
12999
|
+
var DEFAULT_API_HOST, DEFAULT_CONFIGURED_HOST;
|
|
13000
|
+
var init_url = __esm({
|
|
13001
|
+
"packages/experience-design-system-cli/src/helpers/url.ts"() {
|
|
13002
|
+
"use strict";
|
|
13003
|
+
DEFAULT_API_HOST = "https://api.contentful.com";
|
|
13004
|
+
DEFAULT_CONFIGURED_HOST = "api.contentful.com";
|
|
13005
|
+
}
|
|
13006
|
+
});
|
|
13007
|
+
|
|
13008
|
+
// packages/experience-design-system-cli/src/api/clients/abstract-api-client.ts
|
|
13009
|
+
var AbstractApiClient;
|
|
13010
|
+
var init_abstract_api_client = __esm({
|
|
13011
|
+
"packages/experience-design-system-cli/src/api/clients/abstract-api-client.ts"() {
|
|
13012
|
+
"use strict";
|
|
13013
|
+
init_url();
|
|
13014
|
+
init_http();
|
|
13015
|
+
init_api_error();
|
|
13016
|
+
AbstractApiClient = class {
|
|
12971
13017
|
host;
|
|
12972
13018
|
token;
|
|
12973
13019
|
spaceId;
|
|
12974
13020
|
environmentId;
|
|
13021
|
+
constructor(opts) {
|
|
13022
|
+
this.host = toApiHost(opts.host);
|
|
13023
|
+
this.token = opts.cmaToken;
|
|
13024
|
+
this.spaceId = opts.spaceId;
|
|
13025
|
+
this.environmentId = opts.environmentId;
|
|
13026
|
+
}
|
|
13027
|
+
base() {
|
|
13028
|
+
return `${this.host}/spaces/${this.spaceId}/environments/${this.environmentId}`;
|
|
13029
|
+
}
|
|
13030
|
+
buildHeaders() {
|
|
13031
|
+
return buildHeaders(this.token);
|
|
13032
|
+
}
|
|
13033
|
+
async validateCmaToken() {
|
|
13034
|
+
const url = `${this.host}/users/me`;
|
|
13035
|
+
const res = await request(url, { token: this.token });
|
|
13036
|
+
this.onValidateCmaTokenResponse(res);
|
|
13037
|
+
if (res.status === 401) {
|
|
13038
|
+
throw new ApiError("CMA token is invalid or revoked", res.status, await res.text());
|
|
13039
|
+
}
|
|
13040
|
+
if (!res.ok) {
|
|
13041
|
+
throw new ApiError(`unexpected error validating token: ${res.status}`, res.status, await res.text());
|
|
13042
|
+
}
|
|
13043
|
+
}
|
|
13044
|
+
// Hook for subclasses to observe the raw /users/me response (e.g. capture
|
|
13045
|
+
// x-contentful-request-id). Default is a no-op.
|
|
13046
|
+
onValidateCmaTokenResponse(_res) {
|
|
13047
|
+
}
|
|
13048
|
+
};
|
|
13049
|
+
}
|
|
13050
|
+
});
|
|
13051
|
+
|
|
13052
|
+
// packages/experience-design-system-cli/src/constants/edsi/errors.ts
|
|
13053
|
+
var PREVIEW_ERROR_PREFIX, APPLY_ERROR_PREFIX, VALIDATION_FAILED_CODE;
|
|
13054
|
+
var init_errors = __esm({
|
|
13055
|
+
"packages/experience-design-system-cli/src/constants/edsi/errors.ts"() {
|
|
13056
|
+
"use strict";
|
|
13057
|
+
PREVIEW_ERROR_PREFIX = "preview failed:";
|
|
13058
|
+
APPLY_ERROR_PREFIX = "apply failed:";
|
|
13059
|
+
VALIDATION_FAILED_CODE = '"ValidationFailed"';
|
|
13060
|
+
}
|
|
13061
|
+
});
|
|
13062
|
+
|
|
13063
|
+
// packages/experience-design-system-cli/src/api/clients/edsi-client.ts
|
|
13064
|
+
var EdsiApiClient;
|
|
13065
|
+
var init_edsi_client = __esm({
|
|
13066
|
+
"packages/experience-design-system-cli/src/api/clients/edsi-client.ts"() {
|
|
13067
|
+
"use strict";
|
|
13068
|
+
init_src3();
|
|
13069
|
+
init_debug_logger();
|
|
13070
|
+
init_http();
|
|
13071
|
+
init_retry2();
|
|
13072
|
+
init_edsi_response();
|
|
13073
|
+
init_api_error();
|
|
13074
|
+
init_abstract_api_client();
|
|
13075
|
+
init_errors();
|
|
13076
|
+
EdsiApiClient = class extends AbstractApiClient {
|
|
12975
13077
|
retry;
|
|
12976
13078
|
lastRequestId;
|
|
12977
13079
|
getLastRequestId() {
|
|
@@ -12981,11 +13083,11 @@ ${trimmed}`;
|
|
|
12981
13083
|
const requestId = response.headers.get("x-contentful-request-id");
|
|
12982
13084
|
if (requestId) this.lastRequestId = requestId;
|
|
12983
13085
|
}
|
|
13086
|
+
onValidateCmaTokenResponse(res) {
|
|
13087
|
+
this.noteRequestId(res);
|
|
13088
|
+
}
|
|
12984
13089
|
constructor(opts) {
|
|
12985
|
-
|
|
12986
|
-
this.token = opts.cmaToken;
|
|
12987
|
-
this.spaceId = opts.spaceId;
|
|
12988
|
-
this.environmentId = opts.environmentId;
|
|
13090
|
+
super(opts);
|
|
12989
13091
|
const initialDelayMs = Math.max(0, opts.retry?.initialDelayMs ?? 250);
|
|
12990
13092
|
this.retry = {
|
|
12991
13093
|
maxAttempts: Math.max(1, Math.floor(opts.retry?.maxAttempts ?? 3)),
|
|
@@ -12994,15 +13096,8 @@ ${trimmed}`;
|
|
|
12994
13096
|
sleep: opts.retry?.sleep ?? defaultSleep
|
|
12995
13097
|
};
|
|
12996
13098
|
}
|
|
12997
|
-
base() {
|
|
12998
|
-
return `${this.host}/spaces/${this.spaceId}/environments/${this.environmentId}`;
|
|
12999
|
-
}
|
|
13000
13099
|
headers() {
|
|
13001
|
-
return
|
|
13002
|
-
Authorization: `Bearer ${this.token}`,
|
|
13003
|
-
"Content-Type": "application/json",
|
|
13004
|
-
"X-Contentful-User-Agent": buildUserAgent()
|
|
13005
|
-
};
|
|
13100
|
+
return this.buildHeaders();
|
|
13006
13101
|
}
|
|
13007
13102
|
async requestWithRetry(phase, errorPrefix, makeCall, context = {}) {
|
|
13008
13103
|
const debug = getDebugLogger();
|
|
@@ -13068,16 +13163,8 @@ ${trimmed}`;
|
|
|
13068
13163
|
}
|
|
13069
13164
|
throw new Error("Retry attempts exhausted");
|
|
13070
13165
|
}
|
|
13071
|
-
async
|
|
13072
|
-
|
|
13073
|
-
const res = await request(url, { token: this.token });
|
|
13074
|
-
this.noteRequestId(res);
|
|
13075
|
-
if (res.status === 401) {
|
|
13076
|
-
throw new ApiError("CMA token is invalid or revoked", res.status, await res.text());
|
|
13077
|
-
}
|
|
13078
|
-
if (!res.ok) {
|
|
13079
|
-
throw new ApiError(`unexpected error validating token: ${res.status}`, res.status, await res.text());
|
|
13080
|
-
}
|
|
13166
|
+
async validateCmaToken() {
|
|
13167
|
+
await super.validateCmaToken();
|
|
13081
13168
|
await this.checkPreflight();
|
|
13082
13169
|
}
|
|
13083
13170
|
// Probe the sources-api preflight endpoint to catch APS-denied users up-front,
|
|
@@ -13089,7 +13176,7 @@ ${trimmed}`;
|
|
|
13089
13176
|
// 404 without a NotFound envelope → older backend deployment; treat as pass
|
|
13090
13177
|
// 5xx / network → backend flake; treat as pass, do not block
|
|
13091
13178
|
async checkPreflight() {
|
|
13092
|
-
const url = `${this.
|
|
13179
|
+
const url = `${this.base()}/design_systems/preflight`;
|
|
13093
13180
|
let res;
|
|
13094
13181
|
try {
|
|
13095
13182
|
res = await request(url, { token: this.token });
|
|
@@ -13233,6 +13320,26 @@ ${trimmed}`;
|
|
|
13233
13320
|
}
|
|
13234
13321
|
});
|
|
13235
13322
|
|
|
13323
|
+
// packages/experience-design-system-cli/src/constants/edsi/host.ts
|
|
13324
|
+
var init_host = __esm({
|
|
13325
|
+
"packages/experience-design-system-cli/src/constants/edsi/host.ts"() {
|
|
13326
|
+
"use strict";
|
|
13327
|
+
init_url();
|
|
13328
|
+
}
|
|
13329
|
+
});
|
|
13330
|
+
|
|
13331
|
+
// packages/experience-design-system-cli/src/apply/api-client.ts
|
|
13332
|
+
var init_api_client = __esm({
|
|
13333
|
+
"packages/experience-design-system-cli/src/apply/api-client.ts"() {
|
|
13334
|
+
"use strict";
|
|
13335
|
+
init_edsi_client();
|
|
13336
|
+
init_host();
|
|
13337
|
+
init_errors();
|
|
13338
|
+
init_edsi_response();
|
|
13339
|
+
init_api_error();
|
|
13340
|
+
}
|
|
13341
|
+
});
|
|
13342
|
+
|
|
13236
13343
|
// packages/experience-design-system-cli/src/lib/error-parser.ts
|
|
13237
13344
|
function stripLambdaLogPrefix(body) {
|
|
13238
13345
|
let out = body.replace(LAMBDA_LOG_PREFIX_RE, "");
|
|
@@ -14221,6 +14328,14 @@ var init_strip_allowed_components = __esm({
|
|
|
14221
14328
|
}
|
|
14222
14329
|
});
|
|
14223
14330
|
|
|
14331
|
+
// packages/experience-design-system-cli/src/host-utils.ts
|
|
14332
|
+
var init_host_utils = __esm({
|
|
14333
|
+
"packages/experience-design-system-cli/src/host-utils.ts"() {
|
|
14334
|
+
"use strict";
|
|
14335
|
+
init_url();
|
|
14336
|
+
}
|
|
14337
|
+
});
|
|
14338
|
+
|
|
14224
14339
|
// packages/experience-design-system-cli/src/credentials-store.ts
|
|
14225
14340
|
var credentials_store_exports = {};
|
|
14226
14341
|
__export(credentials_store_exports, {
|
|
@@ -14836,7 +14951,7 @@ async function resolveSharedInputs(opts) {
|
|
|
14836
14951
|
if (opts.tokens) {
|
|
14837
14952
|
tokens = await readTokensFromPath("--tokens", opts.tokens);
|
|
14838
14953
|
}
|
|
14839
|
-
const client2 = new
|
|
14954
|
+
const client2 = new EdsiApiClient({
|
|
14840
14955
|
host: opts.host,
|
|
14841
14956
|
cmaToken,
|
|
14842
14957
|
spaceId,
|
|
@@ -15077,7 +15192,7 @@ function registerApplyCommand(program) {
|
|
|
15077
15192
|
environment_key: environmentId
|
|
15078
15193
|
});
|
|
15079
15194
|
try {
|
|
15080
|
-
await client2.
|
|
15195
|
+
await client2.validateCmaToken();
|
|
15081
15196
|
} catch (e) {
|
|
15082
15197
|
if (e instanceof ApiError) return await die(`Error: ${formatApiError(e)}`, failureFromApiError(e));
|
|
15083
15198
|
const cause = e instanceof Error && e.cause instanceof Error ? e.cause.message : "";
|
|
@@ -15135,7 +15250,7 @@ function registerApplyCommand(program) {
|
|
|
15135
15250
|
});
|
|
15136
15251
|
await assertNoSlotCycles(components);
|
|
15137
15252
|
try {
|
|
15138
|
-
await client2.
|
|
15253
|
+
await client2.validateCmaToken();
|
|
15139
15254
|
} catch (e) {
|
|
15140
15255
|
if (e instanceof ApiError)
|
|
15141
15256
|
return await die(`Error: ${formatApiError(e, opts.verbose)}`, failureFromApiError(e));
|
|
@@ -15320,7 +15435,7 @@ function registerApplyCommand(program) {
|
|
|
15320
15435
|
const { components, tokens, client: client2 } = inputs;
|
|
15321
15436
|
await assertNoSlotCycles(components);
|
|
15322
15437
|
try {
|
|
15323
|
-
await client2.
|
|
15438
|
+
await client2.validateCmaToken();
|
|
15324
15439
|
} catch (e) {
|
|
15325
15440
|
if (e instanceof ApiError) return await die(`Error: ${formatApiError(e)}`, failureFromApiError(e));
|
|
15326
15441
|
throw e;
|
|
@@ -15576,7 +15691,7 @@ function App({ sessionId: sessionId2, artifactsRoot, reviewRoot }) {
|
|
|
15576
15691
|
tokens
|
|
15577
15692
|
);
|
|
15578
15693
|
if (!manifest.componentsManifest) manifest.componentsManifest = {};
|
|
15579
|
-
const client2 = new
|
|
15694
|
+
const client2 = new EdsiApiClient({ cmaToken, spaceId, environmentId });
|
|
15580
15695
|
const preview = await client2.previewImport(manifest, true);
|
|
15581
15696
|
const annotations = {};
|
|
15582
15697
|
for (const item of preview.components.new) {
|
|
@@ -16598,7 +16713,7 @@ var init_save_path_resolver = __esm({
|
|
|
16598
16713
|
});
|
|
16599
16714
|
|
|
16600
16715
|
// packages/experience-design-system-cli/src/runs/store.ts
|
|
16601
|
-
import { readFile as readFile22, writeFile as
|
|
16716
|
+
import { readFile as readFile22, writeFile as writeFile6, mkdir as mkdir6, rename } from "node:fs/promises";
|
|
16602
16717
|
import { join as join20 } from "node:path";
|
|
16603
16718
|
import { homedir as homedir7 } from "node:os";
|
|
16604
16719
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
@@ -16661,7 +16776,7 @@ async function writeAtomic(file) {
|
|
|
16661
16776
|
await mkdir6(RUNS_DIR, { recursive: true });
|
|
16662
16777
|
const body = JSON.stringify(file, null, 2) + "\n";
|
|
16663
16778
|
const tmp = `${RUNS_PATH}.${process.pid}.${Date.now()}.tmp`;
|
|
16664
|
-
await
|
|
16779
|
+
await writeFile6(tmp, body, { mode: 384 });
|
|
16665
16780
|
await rename(tmp, RUNS_PATH);
|
|
16666
16781
|
}
|
|
16667
16782
|
async function appendRun(input) {
|
|
@@ -24143,7 +24258,7 @@ async function runLivePreview(opts) {
|
|
|
24143
24258
|
tokens = await readTokensFromPath("tokens", tokensPath);
|
|
24144
24259
|
}
|
|
24145
24260
|
const manifest = buildManifest3(components, tokens, { deleteAllComponents: opts.deleteAllComponents === true });
|
|
24146
|
-
const client2 = new
|
|
24261
|
+
const client2 = new EdsiApiClient({ host, cmaToken, spaceId, environmentId });
|
|
24147
24262
|
const startedAt = Date.now();
|
|
24148
24263
|
let timeoutHandle;
|
|
24149
24264
|
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
@@ -28363,13 +28478,13 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28363
28478
|
update({ step: "credentials", credentialsValidating: true, credentialsError: "" });
|
|
28364
28479
|
try {
|
|
28365
28480
|
const resolvedHost = resolveWizardHost(host2);
|
|
28366
|
-
const client2 = new
|
|
28481
|
+
const client2 = new EdsiApiClient({
|
|
28367
28482
|
cmaToken,
|
|
28368
28483
|
spaceId,
|
|
28369
28484
|
environmentId,
|
|
28370
28485
|
host: resolvedHost
|
|
28371
28486
|
});
|
|
28372
|
-
await client2.
|
|
28487
|
+
await client2.validateCmaToken();
|
|
28373
28488
|
update({ spaceId, environmentId, cmaToken, host: resolvedHost, credentialsValidating: false });
|
|
28374
28489
|
await advanceAfterCredentialsValidated();
|
|
28375
28490
|
} catch (e) {
|
|
@@ -28437,7 +28552,7 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28437
28552
|
update({ step: "previewing" });
|
|
28438
28553
|
const resolvedHost = resolveWizardHost(host2);
|
|
28439
28554
|
try {
|
|
28440
|
-
const client2 = new
|
|
28555
|
+
const client2 = new EdsiApiClient({
|
|
28441
28556
|
cmaToken,
|
|
28442
28557
|
spaceId,
|
|
28443
28558
|
environmentId,
|
|
@@ -28599,7 +28714,7 @@ If using a custom --host, make sure the space exists on that host.`
|
|
|
28599
28714
|
update({ step: "pushing", pushProgress: null });
|
|
28600
28715
|
try {
|
|
28601
28716
|
const resolvedHost = resolveWizardHost(host2);
|
|
28602
|
-
const client2 = new
|
|
28717
|
+
const client2 = new EdsiApiClient({
|
|
28603
28718
|
cmaToken,
|
|
28604
28719
|
spaceId,
|
|
28605
28720
|
environmentId,
|
|
@@ -34365,14 +34480,56 @@ init_db();
|
|
|
34365
34480
|
init_command();
|
|
34366
34481
|
init_manifest();
|
|
34367
34482
|
init_api_client();
|
|
34483
|
+
import { mkdir as mkdir5, writeFile as writeFile5 } from "node:fs/promises";
|
|
34484
|
+
import { join as join18, resolve as resolve21 } from "node:path";
|
|
34485
|
+
import { execFile as execFile2 } from "node:child_process";
|
|
34486
|
+
|
|
34487
|
+
// packages/experience-design-system-cli/src/api/clients/cma-client.ts
|
|
34488
|
+
init_http();
|
|
34489
|
+
init_api_error();
|
|
34490
|
+
init_abstract_api_client();
|
|
34491
|
+
|
|
34492
|
+
// packages/experience-design-system-cli/src/constants/cma/pagination.ts
|
|
34493
|
+
var CMA_PAGE_LIMIT = 100;
|
|
34494
|
+
|
|
34495
|
+
// packages/experience-design-system-cli/src/api/clients/cma-client.ts
|
|
34496
|
+
var CmaApiClient = class extends AbstractApiClient {
|
|
34497
|
+
constructor(opts) {
|
|
34498
|
+
super(opts);
|
|
34499
|
+
}
|
|
34500
|
+
async listExistingEntities() {
|
|
34501
|
+
const [components, tokens] = await Promise.all([
|
|
34502
|
+
this.listAll("component_types", "component_types"),
|
|
34503
|
+
this.listAll("design_tokens", "design_tokens")
|
|
34504
|
+
]);
|
|
34505
|
+
return { components, tokens };
|
|
34506
|
+
}
|
|
34507
|
+
async listAll(resourcePath, opName) {
|
|
34508
|
+
const items = [];
|
|
34509
|
+
let skip = 0;
|
|
34510
|
+
while (true) {
|
|
34511
|
+
const url = `${this.base()}/${resourcePath}?limit=${CMA_PAGE_LIMIT}&skip=${skip}`;
|
|
34512
|
+
const res = await request(url, { token: this.token });
|
|
34513
|
+
if (!res.ok) {
|
|
34514
|
+
throw new ApiError(`${opName} list failed: ${res.status}`, res.status, await res.text());
|
|
34515
|
+
}
|
|
34516
|
+
const page = await res.json();
|
|
34517
|
+
items.push(...page.items);
|
|
34518
|
+
const returned = page.items.length;
|
|
34519
|
+
const total = page.total ?? items.length;
|
|
34520
|
+
if (returned === 0 || items.length >= total) break;
|
|
34521
|
+
skip += returned;
|
|
34522
|
+
}
|
|
34523
|
+
return items;
|
|
34524
|
+
}
|
|
34525
|
+
};
|
|
34526
|
+
|
|
34527
|
+
// packages/experience-design-system-cli/src/import/orchestrator.ts
|
|
34368
34528
|
init_contentful_urls();
|
|
34369
34529
|
init_debug_logger();
|
|
34370
34530
|
init_analytics();
|
|
34371
34531
|
init_env();
|
|
34372
34532
|
init_cli_path();
|
|
34373
|
-
import { mkdir as mkdir5 } from "node:fs/promises";
|
|
34374
|
-
import { join as join18, resolve as resolve21 } from "node:path";
|
|
34375
|
-
import { execFile as execFile2 } from "node:child_process";
|
|
34376
34533
|
async function runStep(args, cliPath, analyticsSessionId, env = {}, streamStderr = false) {
|
|
34377
34534
|
const debug = getDebugLogger();
|
|
34378
34535
|
const startedAt = Date.now();
|
|
@@ -34480,11 +34637,66 @@ async function runPipeline(opts, progressWriter, cliPathOverride) {
|
|
|
34480
34637
|
await mkdir5(outDir, { recursive: true });
|
|
34481
34638
|
const steps = [];
|
|
34482
34639
|
let stepNum = 0;
|
|
34483
|
-
const
|
|
34640
|
+
const wantsSpaceContext = opts.withSpaceContext === true;
|
|
34641
|
+
const canFetchSpaceContext = wantsSpaceContext && !!opts.spaceId && !!opts.environmentId && !!opts.cmaToken;
|
|
34642
|
+
const totalSteps = 5 + (opts.print ? 1 : 0) + (canFetchSpaceContext ? 1 : 0);
|
|
34484
34643
|
function stepLabel(name) {
|
|
34485
34644
|
stepNum++;
|
|
34486
34645
|
return ` Step ${stepNum}/${totalSteps} ${name} `;
|
|
34487
34646
|
}
|
|
34647
|
+
if (wantsSpaceContext && !canFetchSpaceContext) {
|
|
34648
|
+
progressWriter(
|
|
34649
|
+
" Note: --with-space-context requires --space-id, --environment-id, and --cma-token; skipping context fetch."
|
|
34650
|
+
);
|
|
34651
|
+
}
|
|
34652
|
+
if (canFetchSpaceContext) {
|
|
34653
|
+
const fetchLabel = stepLabel("Fetching existing components + design tokens");
|
|
34654
|
+
const fetchStepId = createStep(db, sessionId2, "fetch existing entities", {
|
|
34655
|
+
spaceId: opts.spaceId,
|
|
34656
|
+
environmentId: opts.environmentId
|
|
34657
|
+
});
|
|
34658
|
+
const t0 = Date.now();
|
|
34659
|
+
try {
|
|
34660
|
+
const cma = new CmaApiClient({
|
|
34661
|
+
host: opts.host,
|
|
34662
|
+
cmaToken: opts.cmaToken,
|
|
34663
|
+
spaceId: opts.spaceId,
|
|
34664
|
+
environmentId: opts.environmentId
|
|
34665
|
+
});
|
|
34666
|
+
const result = await cma.listExistingEntities();
|
|
34667
|
+
const fetchDurationMs = Date.now() - t0;
|
|
34668
|
+
const existingEntitiesPath = join18(outDir, ".existing-entities.json");
|
|
34669
|
+
await writeFile5(existingEntitiesPath, JSON.stringify(result, null, 2), "utf8");
|
|
34670
|
+
updateStep(db, fetchStepId, "complete", {
|
|
34671
|
+
components: String(result.components.length),
|
|
34672
|
+
tokens: String(result.tokens.length),
|
|
34673
|
+
path: existingEntitiesPath
|
|
34674
|
+
});
|
|
34675
|
+
progressWriter(
|
|
34676
|
+
`${fetchLabel}\u2713 ${result.components.length} component${result.components.length === 1 ? "" : "s"}, ${result.tokens.length} token${result.tokens.length === 1 ? "" : "s"} (${(fetchDurationMs / 1e3).toFixed(1)}s)`
|
|
34677
|
+
);
|
|
34678
|
+
steps.push({
|
|
34679
|
+
step: "fetch existing entities",
|
|
34680
|
+
status: "complete",
|
|
34681
|
+
durationMs: fetchDurationMs,
|
|
34682
|
+
detail: { components: result.components.length, tokens: result.tokens.length }
|
|
34683
|
+
});
|
|
34684
|
+
} catch (error) {
|
|
34685
|
+
const fetchDurationMs = Date.now() - t0;
|
|
34686
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
34687
|
+
updateStep(db, fetchStepId, "failed", {}, message);
|
|
34688
|
+
progressWriter(
|
|
34689
|
+
`${fetchLabel}\u26A0 fetch failed, continuing without space context (${(fetchDurationMs / 1e3).toFixed(1)}s)`
|
|
34690
|
+
);
|
|
34691
|
+
progressWriter(` ${message.split("\n")[0]}`);
|
|
34692
|
+
steps.push({
|
|
34693
|
+
step: "fetch existing entities",
|
|
34694
|
+
status: "failed",
|
|
34695
|
+
durationMs: fetchDurationMs,
|
|
34696
|
+
error: message
|
|
34697
|
+
});
|
|
34698
|
+
}
|
|
34699
|
+
}
|
|
34488
34700
|
const analyzeLabel = stepLabel("Statically analyzing project");
|
|
34489
34701
|
const analyzeSkipped = !opts.noCache && opts.skipAnalyze;
|
|
34490
34702
|
let extractSessionId = null;
|
|
@@ -35439,7 +35651,10 @@ function registerImportCommand(program) {
|
|
|
35439
35651
|
"Override a stage prompt (repeatable). value is a file path or literal text, e.g. --prompt composition=./p.md",
|
|
35440
35652
|
(v, acc) => [...acc, v],
|
|
35441
35653
|
[]
|
|
35442
|
-
).option("--auto-reject-cycles", "Automatically reject components involved in slot cycles and retry").option(
|
|
35654
|
+
).option("--auto-reject-cycles", "Automatically reject components involved in slot cycles and retry").option(
|
|
35655
|
+
"--with-space-context",
|
|
35656
|
+
"Fetch existing Components + DesignTokens from the target space+env and persist them under <out>/.existing-entities.json for future agent-context enrichment. Requires --space-id, --environment-id, and --cma-token."
|
|
35657
|
+
).option("--auto-filter", "Force the AI auto-filter ON (overrides the credentials.json autoFilter preference)").option(
|
|
35443
35658
|
"--no-auto-filter",
|
|
35444
35659
|
"Skip the automatic AI pre-filter; jump straight to manual scope-gate (overrides the credentials.json autoFilter preference; no-op when paired with --auto-accept-scope)"
|
|
35445
35660
|
).option(
|
|
@@ -35786,6 +36001,7 @@ function registerImportCommand(program) {
|
|
|
35786
36001
|
dryRun: dryRunForward,
|
|
35787
36002
|
selectPromptPath: opts.selectPromptPath,
|
|
35788
36003
|
autoRejectCycles: opts.autoRejectCycles ?? false,
|
|
36004
|
+
withSpaceContext: opts.withSpaceContext ?? false,
|
|
35789
36005
|
allowDeletions: opts.allowDeletions ?? false,
|
|
35790
36006
|
compositionMode: headlessCompositionMode,
|
|
35791
36007
|
...opts.compositionMap ? { compositionMap: opts.compositionMap } : {},
|
|
@@ -36169,15 +36385,26 @@ function pick(items, defaultIdx = 0) {
|
|
|
36169
36385
|
process.stdout.write(` \x1B[2m[s] Skip\x1B[0m
|
|
36170
36386
|
`);
|
|
36171
36387
|
}
|
|
36172
|
-
async function promptCodexModel(
|
|
36388
|
+
async function promptCodexModel() {
|
|
36173
36389
|
if (process.env["OPENAI_API_KEY"]) return void 0;
|
|
36174
36390
|
info("");
|
|
36175
36391
|
process.stdout.write(` \x1B[33m\u26A0\x1B[0m No OPENAI_API_KEY \u2014 using ChatGPT account authentication.
|
|
36176
36392
|
`);
|
|
36177
|
-
info(" Tip: run \x1B[1mcodex\x1B[0m then type \x1B[1m/model\x1B[0m to browse
|
|
36178
|
-
|
|
36179
|
-
|
|
36180
|
-
|
|
36393
|
+
info(" Tip: run \x1B[1mcodex\x1B[0m then type \x1B[1m/model\x1B[0m to browse all available models.");
|
|
36394
|
+
info("");
|
|
36395
|
+
info(" Choose a model:");
|
|
36396
|
+
info("");
|
|
36397
|
+
pick([
|
|
36398
|
+
{ label: "gpt-5.4-mini", description: "fast, lower cost" },
|
|
36399
|
+
{ label: "gpt-5.5", description: "most capable" },
|
|
36400
|
+
{ label: "gpt-5.4" }
|
|
36401
|
+
]);
|
|
36402
|
+
info("");
|
|
36403
|
+
const choice = await prompt(" \x1B[2m\u203A\x1B[0m Your choice [1]: ");
|
|
36404
|
+
if (choice === "1" || choice === "") return "gpt-5.4-mini";
|
|
36405
|
+
if (choice === "2") return "gpt-5.5";
|
|
36406
|
+
if (choice === "3") return "gpt-5.4";
|
|
36407
|
+
return void 0;
|
|
36181
36408
|
}
|
|
36182
36409
|
async function setupAgent() {
|
|
36183
36410
|
section("Step 4: Coding agent (claude, codex, opencode, or copilot)", "[required]");
|
|
@@ -36204,6 +36431,7 @@ async function setupAgent() {
|
|
|
36204
36431
|
const parsed = choice2 === "" ? 1 : parseInt(choice2, 10);
|
|
36205
36432
|
const idx = Number.isNaN(parsed) || parsed < 1 || parsed > found.length ? 0 : parsed - 1;
|
|
36206
36433
|
const selected = found[idx];
|
|
36434
|
+
ok(`${selected.name} \x1B[2m(${selected.binary})\x1B[0m selected`);
|
|
36207
36435
|
const agentModel = selected.binary === "codex" ? await promptCodexModel() : void 0;
|
|
36208
36436
|
return { agent: selected.binary, agentModel };
|
|
36209
36437
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface EdsiClientOptions {
|
|
2
|
+
host?: string;
|
|
3
|
+
cmaToken: string;
|
|
4
|
+
spaceId: string;
|
|
5
|
+
environmentId: string;
|
|
6
|
+
retry?: {
|
|
7
|
+
maxAttempts?: number;
|
|
8
|
+
initialDelayMs?: number;
|
|
9
|
+
maxDelayMs?: number;
|
|
10
|
+
sleep?: (delayMs: number) => Promise<void>;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ExistingComponentEntity } from './existing-component-entity.js';
|
|
2
|
+
import type { ExistingTokenEntity } from './existing-token-entity.js';
|
|
3
|
+
export interface ExistingEntitiesResponse {
|
|
4
|
+
components: ExistingComponentEntity[];
|
|
5
|
+
tokens: ExistingTokenEntity[];
|
|
6
|
+
}
|
package/dist/src/session/db.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { ToolCall, TokenToolCall, ComponentSourceRef } from '@contentful/ex
|
|
|
5
5
|
import type { ComponentTypeSummary } from '@contentful/experience-design-system-types';
|
|
6
6
|
import type { SlotCycle, SlotEdge } from '../analyze/cycle-detection.js';
|
|
7
7
|
export type StepStatus = 'pending' | 'complete' | 'failed' | 'interrupted';
|
|
8
|
-
export type CommandName = 'analyze extract' | 'analyze select' | 'generate components' | 'generate tokens' | 'generate edit' | 'apply preview' | 'apply select' | 'apply push' | 'print components' | 'print tokens' | 'map tokens' | 'import';
|
|
8
|
+
export type CommandName = 'analyze extract' | 'analyze select' | 'generate components' | 'generate tokens' | 'generate edit' | 'apply preview' | 'apply select' | 'apply push' | 'print components' | 'print tokens' | 'map tokens' | 'fetch existing entities' | 'import';
|
|
9
9
|
export interface SessionRow {
|
|
10
10
|
id: string;
|
|
11
11
|
name: string | null;
|
|
@@ -1,10 +1,4 @@
|
|
|
1
1
|
import type { Command } from 'commander';
|
|
2
|
-
import type { AgentName } from '@contentful/experience-design-system-generation';
|
|
3
|
-
export declare function promptCodexModel(ask?: (q: string) => Promise<string>): Promise<string | undefined>;
|
|
4
|
-
export declare function setupAgent(): Promise<{
|
|
5
|
-
agent: AgentName | undefined;
|
|
6
|
-
agentModel: string | undefined;
|
|
7
|
-
}>;
|
|
8
2
|
export type SkillPromptKind = 'select' | 'generate';
|
|
9
3
|
/**
|
|
10
4
|
* Prompt the operator for a custom skill prompt path. Returns the resolved
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/experience-design-system-cli",
|
|
3
|
-
"version": "2.32.1-dev-build-
|
|
3
|
+
"version": "2.32.1-dev-build-47de682.0",
|
|
4
4
|
"description": "Contentful Experiences design system import CLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"svelte": "^5.56.4",
|
|
40
40
|
"ts-morph": "^27.0.2",
|
|
41
41
|
"typescript": "^5.9.3",
|
|
42
|
-
"@contentful/experience-design-system-cli-v2": "2.32.1-dev-build-
|
|
43
|
-
"@contentful/experience-design-system-types": "2.32.1-dev-build-
|
|
42
|
+
"@contentful/experience-design-system-cli-v2": "2.32.1-dev-build-47de682.0",
|
|
43
|
+
"@contentful/experience-design-system-types": "2.32.1-dev-build-47de682.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@tsconfig/node24": "^24.0.4",
|
|
@@ -52,9 +52,9 @@
|
|
|
52
52
|
"ink-testing-library": "^4.0.0",
|
|
53
53
|
"typescript-eslint": "^8.67.0",
|
|
54
54
|
"vitest": "^4.0.16",
|
|
55
|
-
"@contentful/experience-design-system-
|
|
56
|
-
"@contentful/experience-design-system-generation": "2.32.1-dev-build-
|
|
57
|
-
"@contentful/experience-design-system-
|
|
55
|
+
"@contentful/experience-design-system-extraction": "2.32.1-dev-build-47de682.0",
|
|
56
|
+
"@contentful/experience-design-system-generation": "2.32.1-dev-build-47de682.0",
|
|
57
|
+
"@contentful/experience-design-system-client": "2.32.1-dev-build-47de682.0"
|
|
58
58
|
},
|
|
59
59
|
"repository": {
|
|
60
60
|
"type": "git",
|