@contentful/experience-design-system-cli 2.32.1-dev-build-1c6a348.0 → 2.32.1-dev-build-f054f94.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/apply/api-client.d.ts +68 -4
- package/dist/src/host-utils.d.ts +4 -1
- package/dist/src/import/orchestrator.d.ts +0 -9
- package/dist/src/index.js +78 -237
- package/dist/src/session/db.d.ts +1 -1
- package/package.json +6 -6
- package/dist/src/api/clients/abstract-api-client.d.ts +0 -24
- package/dist/src/api/clients/cma-client.d.ts +0 -8
- package/dist/src/api/clients/edsi-client.d.ts +0 -44
- package/dist/src/api/index.d.ts +0 -10
- package/dist/src/errors/api-error.d.ts +0 -6
- package/dist/src/helpers/http.d.ts +0 -4
- package/dist/src/helpers/url.d.ts +0 -4
- package/dist/src/interfaces/clients/cma-client-options.d.ts +0 -6
- package/dist/src/interfaces/clients/edsi-client-options.d.ts +0 -12
- package/dist/src/interfaces/clients/poll-options.d.ts +0 -7
- package/dist/src/interfaces/responses/existing-component-entity.d.ts +0 -8
- package/dist/src/interfaces/responses/existing-entities-response.d.ts +0 -6
- package/dist/src/interfaces/responses/existing-token-entity.d.ts +0 -6
package/dist/package.json
CHANGED
|
@@ -1,4 +1,68 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
1
|
+
import type { ManifestPayload, ServerPreviewResponse, ApplyOperationResponse, BreakingChange } from '@contentful/experience-design-system-types';
|
|
2
|
+
export declare const DEFAULT_HOST = "https://api.contentful.com";
|
|
3
|
+
export declare const PREVIEW_ERROR_PREFIX = "preview failed:";
|
|
4
|
+
export declare const APPLY_ERROR_PREFIX = "apply failed:";
|
|
5
|
+
export declare const VALIDATION_FAILED_CODE = "\"ValidationFailed\"";
|
|
6
|
+
export interface ApiClientOptions {
|
|
7
|
+
host?: string;
|
|
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
|
+
}
|
package/dist/src/host-utils.d.ts
CHANGED
|
@@ -1 +1,4 @@
|
|
|
1
|
-
export
|
|
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;
|
|
@@ -28,15 +28,6 @@ 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;
|
|
40
31
|
compositionMode?: CompositionMode;
|
|
41
32
|
compositionMap?: string;
|
|
42
33
|
compositionAgent?: boolean;
|
package/dist/src/index.js
CHANGED
|
@@ -12603,7 +12603,7 @@ var init_src3 = __esm({
|
|
|
12603
12603
|
}
|
|
12604
12604
|
});
|
|
12605
12605
|
|
|
12606
|
-
// packages/experience-design-system-cli/src/
|
|
12606
|
+
// packages/experience-design-system-cli/src/host-utils.ts
|
|
12607
12607
|
function trimTrailingSlashes(value) {
|
|
12608
12608
|
return value.replace(/\/+$/, "");
|
|
12609
12609
|
}
|
|
@@ -12626,8 +12626,8 @@ function toApiHost(host) {
|
|
|
12626
12626
|
return `https://${normalized}`;
|
|
12627
12627
|
}
|
|
12628
12628
|
var DEFAULT_API_HOST, DEFAULT_CONFIGURED_HOST;
|
|
12629
|
-
var
|
|
12630
|
-
"packages/experience-design-system-cli/src/
|
|
12629
|
+
var init_host_utils = __esm({
|
|
12630
|
+
"packages/experience-design-system-cli/src/host-utils.ts"() {
|
|
12631
12631
|
"use strict";
|
|
12632
12632
|
DEFAULT_API_HOST = "https://api.contentful.com";
|
|
12633
12633
|
DEFAULT_CONFIGURED_HOST = "api.contentful.com";
|
|
@@ -12834,99 +12834,7 @@ var init_user_agent = __esm({
|
|
|
12834
12834
|
}
|
|
12835
12835
|
});
|
|
12836
12836
|
|
|
12837
|
-
// packages/experience-design-system-cli/src/
|
|
12838
|
-
function buildHeaders(token) {
|
|
12839
|
-
return {
|
|
12840
|
-
Authorization: `Bearer ${token}`,
|
|
12841
|
-
"Content-Type": "application/json",
|
|
12842
|
-
"X-Contentful-User-Agent": buildUserAgent()
|
|
12843
|
-
};
|
|
12844
|
-
}
|
|
12845
|
-
async function request(url, options) {
|
|
12846
|
-
const init = {
|
|
12847
|
-
method: options.method ?? "GET",
|
|
12848
|
-
headers: buildHeaders(options.token)
|
|
12849
|
-
};
|
|
12850
|
-
if (options.body) init.body = options.body;
|
|
12851
|
-
return fetch(url, init);
|
|
12852
|
-
}
|
|
12853
|
-
var init_http = __esm({
|
|
12854
|
-
"packages/experience-design-system-cli/src/helpers/http.ts"() {
|
|
12855
|
-
"use strict";
|
|
12856
|
-
init_user_agent();
|
|
12857
|
-
}
|
|
12858
|
-
});
|
|
12859
|
-
|
|
12860
|
-
// packages/experience-design-system-cli/src/errors/api-error.ts
|
|
12861
|
-
var ERROR_BODY_LOG_CAP, ApiError;
|
|
12862
|
-
var init_api_error = __esm({
|
|
12863
|
-
"packages/experience-design-system-cli/src/errors/api-error.ts"() {
|
|
12864
|
-
"use strict";
|
|
12865
|
-
ERROR_BODY_LOG_CAP = 16384;
|
|
12866
|
-
ApiError = class extends Error {
|
|
12867
|
-
constructor(message, status, body, guidance) {
|
|
12868
|
-
super(message);
|
|
12869
|
-
this.status = status;
|
|
12870
|
-
this.body = body;
|
|
12871
|
-
this.guidance = guidance;
|
|
12872
|
-
if (body) {
|
|
12873
|
-
const trimmed = body.length > ERROR_BODY_LOG_CAP ? body.slice(0, ERROR_BODY_LOG_CAP) + "\u2026" : body;
|
|
12874
|
-
this.message = `${message}
|
|
12875
|
-
${trimmed}`;
|
|
12876
|
-
}
|
|
12877
|
-
}
|
|
12878
|
-
status;
|
|
12879
|
-
body;
|
|
12880
|
-
guidance;
|
|
12881
|
-
};
|
|
12882
|
-
}
|
|
12883
|
-
});
|
|
12884
|
-
|
|
12885
|
-
// packages/experience-design-system-cli/src/api/clients/abstract-api-client.ts
|
|
12886
|
-
var AbstractApiClient;
|
|
12887
|
-
var init_abstract_api_client = __esm({
|
|
12888
|
-
"packages/experience-design-system-cli/src/api/clients/abstract-api-client.ts"() {
|
|
12889
|
-
"use strict";
|
|
12890
|
-
init_url();
|
|
12891
|
-
init_http();
|
|
12892
|
-
init_api_error();
|
|
12893
|
-
AbstractApiClient = class {
|
|
12894
|
-
host;
|
|
12895
|
-
token;
|
|
12896
|
-
spaceId;
|
|
12897
|
-
environmentId;
|
|
12898
|
-
constructor(opts) {
|
|
12899
|
-
this.host = toApiHost(opts.host);
|
|
12900
|
-
this.token = opts.cmaToken;
|
|
12901
|
-
this.spaceId = opts.spaceId;
|
|
12902
|
-
this.environmentId = opts.environmentId;
|
|
12903
|
-
}
|
|
12904
|
-
base() {
|
|
12905
|
-
return `${this.host}/spaces/${this.spaceId}/environments/${this.environmentId}`;
|
|
12906
|
-
}
|
|
12907
|
-
buildHeaders() {
|
|
12908
|
-
return buildHeaders(this.token);
|
|
12909
|
-
}
|
|
12910
|
-
async validateToken() {
|
|
12911
|
-
const url = `${this.host}/users/me`;
|
|
12912
|
-
const res = await request(url, { token: this.token });
|
|
12913
|
-
this.onValidateTokenResponse(res);
|
|
12914
|
-
if (res.status === 401) {
|
|
12915
|
-
throw new ApiError("CMA token is invalid or revoked", res.status, await res.text());
|
|
12916
|
-
}
|
|
12917
|
-
if (!res.ok) {
|
|
12918
|
-
throw new ApiError(`unexpected error validating token: ${res.status}`, res.status, await res.text());
|
|
12919
|
-
}
|
|
12920
|
-
}
|
|
12921
|
-
// Hook for subclasses to observe the raw /users/me response (e.g. capture
|
|
12922
|
-
// x-contentful-request-id). Default is a no-op.
|
|
12923
|
-
onValidateTokenResponse(_res) {
|
|
12924
|
-
}
|
|
12925
|
-
};
|
|
12926
|
-
}
|
|
12927
|
-
});
|
|
12928
|
-
|
|
12929
|
-
// packages/experience-design-system-cli/src/api/clients/edsi-client.ts
|
|
12837
|
+
// packages/experience-design-system-cli/src/apply/api-client.ts
|
|
12930
12838
|
function defaultSleep(delayMs) {
|
|
12931
12839
|
return new Promise((resolve27) => setTimeout(resolve27, delayMs));
|
|
12932
12840
|
}
|
|
@@ -13009,20 +12917,48 @@ function isApsDenialBody(body) {
|
|
|
13009
12917
|
return false;
|
|
13010
12918
|
}
|
|
13011
12919
|
}
|
|
13012
|
-
|
|
13013
|
-
|
|
13014
|
-
|
|
12920
|
+
async function request(url, options) {
|
|
12921
|
+
const headers = {
|
|
12922
|
+
Authorization: `Bearer ${options.token}`,
|
|
12923
|
+
"Content-Type": "application/json",
|
|
12924
|
+
"X-Contentful-User-Agent": buildUserAgent()
|
|
12925
|
+
};
|
|
12926
|
+
const init = {
|
|
12927
|
+
method: options.method ?? "GET",
|
|
12928
|
+
headers
|
|
12929
|
+
};
|
|
12930
|
+
if (options.body) init.body = options.body;
|
|
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"() {
|
|
13015
12936
|
"use strict";
|
|
13016
12937
|
init_src3();
|
|
13017
|
-
|
|
12938
|
+
init_host_utils();
|
|
13018
12939
|
init_debug_logger();
|
|
13019
|
-
|
|
13020
|
-
init_api_error();
|
|
13021
|
-
init_abstract_api_client();
|
|
12940
|
+
init_user_agent();
|
|
13022
12941
|
PREVIEW_ERROR_PREFIX = "preview failed:";
|
|
13023
12942
|
APPLY_ERROR_PREFIX = "apply failed:";
|
|
13024
12943
|
VALIDATION_FAILED_CODE = '"ValidationFailed"';
|
|
13025
12944
|
MAX_RETRY_AFTER_MS = 6e4;
|
|
12945
|
+
ERROR_BODY_LOG_CAP = 16384;
|
|
12946
|
+
ApiError = class extends Error {
|
|
12947
|
+
constructor(message, status, body, guidance) {
|
|
12948
|
+
super(message);
|
|
12949
|
+
this.status = status;
|
|
12950
|
+
this.body = body;
|
|
12951
|
+
this.guidance = guidance;
|
|
12952
|
+
if (body) {
|
|
12953
|
+
const trimmed = body.length > ERROR_BODY_LOG_CAP ? body.slice(0, ERROR_BODY_LOG_CAP) + "\u2026" : body;
|
|
12954
|
+
this.message = `${message}
|
|
12955
|
+
${trimmed}`;
|
|
12956
|
+
}
|
|
12957
|
+
}
|
|
12958
|
+
status;
|
|
12959
|
+
body;
|
|
12960
|
+
guidance;
|
|
12961
|
+
};
|
|
13026
12962
|
COMPONENT_PATH_PREFIX = "manifest:components/";
|
|
13027
12963
|
PROPERTY_BREAKING_REASONS = /* @__PURE__ */ new Set([
|
|
13028
12964
|
"removed",
|
|
@@ -13031,7 +12967,11 @@ var init_edsi_client = __esm({
|
|
|
13031
12967
|
"validation_narrowed"
|
|
13032
12968
|
]);
|
|
13033
12969
|
SLOT_BREAKING_REASONS = /* @__PURE__ */ new Set(["slot_removed", "slot_allowed_components_narrowed"]);
|
|
13034
|
-
|
|
12970
|
+
ImportApiClient = class {
|
|
12971
|
+
host;
|
|
12972
|
+
token;
|
|
12973
|
+
spaceId;
|
|
12974
|
+
environmentId;
|
|
13035
12975
|
retry;
|
|
13036
12976
|
lastRequestId;
|
|
13037
12977
|
getLastRequestId() {
|
|
@@ -13041,11 +12981,11 @@ var init_edsi_client = __esm({
|
|
|
13041
12981
|
const requestId = response.headers.get("x-contentful-request-id");
|
|
13042
12982
|
if (requestId) this.lastRequestId = requestId;
|
|
13043
12983
|
}
|
|
13044
|
-
onValidateTokenResponse(res) {
|
|
13045
|
-
this.noteRequestId(res);
|
|
13046
|
-
}
|
|
13047
12984
|
constructor(opts) {
|
|
13048
|
-
|
|
12985
|
+
this.host = toApiHost(opts.host);
|
|
12986
|
+
this.token = opts.cmaToken;
|
|
12987
|
+
this.spaceId = opts.spaceId;
|
|
12988
|
+
this.environmentId = opts.environmentId;
|
|
13049
12989
|
const initialDelayMs = Math.max(0, opts.retry?.initialDelayMs ?? 250);
|
|
13050
12990
|
this.retry = {
|
|
13051
12991
|
maxAttempts: Math.max(1, Math.floor(opts.retry?.maxAttempts ?? 3)),
|
|
@@ -13054,8 +12994,15 @@ var init_edsi_client = __esm({
|
|
|
13054
12994
|
sleep: opts.retry?.sleep ?? defaultSleep
|
|
13055
12995
|
};
|
|
13056
12996
|
}
|
|
12997
|
+
base() {
|
|
12998
|
+
return `${this.host}/spaces/${this.spaceId}/environments/${this.environmentId}`;
|
|
12999
|
+
}
|
|
13057
13000
|
headers() {
|
|
13058
|
-
return
|
|
13001
|
+
return {
|
|
13002
|
+
Authorization: `Bearer ${this.token}`,
|
|
13003
|
+
"Content-Type": "application/json",
|
|
13004
|
+
"X-Contentful-User-Agent": buildUserAgent()
|
|
13005
|
+
};
|
|
13059
13006
|
}
|
|
13060
13007
|
async requestWithRetry(phase, errorPrefix, makeCall, context = {}) {
|
|
13061
13008
|
const debug = getDebugLogger();
|
|
@@ -13122,7 +13069,15 @@ var init_edsi_client = __esm({
|
|
|
13122
13069
|
throw new Error("Retry attempts exhausted");
|
|
13123
13070
|
}
|
|
13124
13071
|
async validateToken() {
|
|
13125
|
-
|
|
13072
|
+
const url = `${this.host}/users/me`;
|
|
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
|
+
}
|
|
13126
13081
|
await this.checkPreflight();
|
|
13127
13082
|
}
|
|
13128
13083
|
// Probe the sources-api preflight endpoint to catch APS-denied users up-front,
|
|
@@ -13278,15 +13233,6 @@ var init_edsi_client = __esm({
|
|
|
13278
13233
|
}
|
|
13279
13234
|
});
|
|
13280
13235
|
|
|
13281
|
-
// packages/experience-design-system-cli/src/apply/api-client.ts
|
|
13282
|
-
var init_api_client = __esm({
|
|
13283
|
-
"packages/experience-design-system-cli/src/apply/api-client.ts"() {
|
|
13284
|
-
"use strict";
|
|
13285
|
-
init_edsi_client();
|
|
13286
|
-
init_api_error();
|
|
13287
|
-
}
|
|
13288
|
-
});
|
|
13289
|
-
|
|
13290
13236
|
// packages/experience-design-system-cli/src/lib/error-parser.ts
|
|
13291
13237
|
function stripLambdaLogPrefix(body) {
|
|
13292
13238
|
let out = body.replace(LAMBDA_LOG_PREFIX_RE, "");
|
|
@@ -14275,14 +14221,6 @@ var init_strip_allowed_components = __esm({
|
|
|
14275
14221
|
}
|
|
14276
14222
|
});
|
|
14277
14223
|
|
|
14278
|
-
// packages/experience-design-system-cli/src/host-utils.ts
|
|
14279
|
-
var init_host_utils = __esm({
|
|
14280
|
-
"packages/experience-design-system-cli/src/host-utils.ts"() {
|
|
14281
|
-
"use strict";
|
|
14282
|
-
init_url();
|
|
14283
|
-
}
|
|
14284
|
-
});
|
|
14285
|
-
|
|
14286
14224
|
// packages/experience-design-system-cli/src/credentials-store.ts
|
|
14287
14225
|
var credentials_store_exports = {};
|
|
14288
14226
|
__export(credentials_store_exports, {
|
|
@@ -14898,7 +14836,7 @@ async function resolveSharedInputs(opts) {
|
|
|
14898
14836
|
if (opts.tokens) {
|
|
14899
14837
|
tokens = await readTokensFromPath("--tokens", opts.tokens);
|
|
14900
14838
|
}
|
|
14901
|
-
const client2 = new
|
|
14839
|
+
const client2 = new ImportApiClient({
|
|
14902
14840
|
host: opts.host,
|
|
14903
14841
|
cmaToken,
|
|
14904
14842
|
spaceId,
|
|
@@ -15638,7 +15576,7 @@ function App({ sessionId: sessionId2, artifactsRoot, reviewRoot }) {
|
|
|
15638
15576
|
tokens
|
|
15639
15577
|
);
|
|
15640
15578
|
if (!manifest.componentsManifest) manifest.componentsManifest = {};
|
|
15641
|
-
const client2 = new
|
|
15579
|
+
const client2 = new ImportApiClient({ cmaToken, spaceId, environmentId });
|
|
15642
15580
|
const preview = await client2.previewImport(manifest, true);
|
|
15643
15581
|
const annotations = {};
|
|
15644
15582
|
for (const item of preview.components.new) {
|
|
@@ -16660,7 +16598,7 @@ var init_save_path_resolver = __esm({
|
|
|
16660
16598
|
});
|
|
16661
16599
|
|
|
16662
16600
|
// packages/experience-design-system-cli/src/runs/store.ts
|
|
16663
|
-
import { readFile as readFile22, writeFile as
|
|
16601
|
+
import { readFile as readFile22, writeFile as writeFile5, mkdir as mkdir6, rename } from "node:fs/promises";
|
|
16664
16602
|
import { join as join20 } from "node:path";
|
|
16665
16603
|
import { homedir as homedir7 } from "node:os";
|
|
16666
16604
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
@@ -16723,7 +16661,7 @@ async function writeAtomic(file) {
|
|
|
16723
16661
|
await mkdir6(RUNS_DIR, { recursive: true });
|
|
16724
16662
|
const body = JSON.stringify(file, null, 2) + "\n";
|
|
16725
16663
|
const tmp = `${RUNS_PATH}.${process.pid}.${Date.now()}.tmp`;
|
|
16726
|
-
await
|
|
16664
|
+
await writeFile5(tmp, body, { mode: 384 });
|
|
16727
16665
|
await rename(tmp, RUNS_PATH);
|
|
16728
16666
|
}
|
|
16729
16667
|
async function appendRun(input) {
|
|
@@ -24205,7 +24143,7 @@ async function runLivePreview(opts) {
|
|
|
24205
24143
|
tokens = await readTokensFromPath("tokens", tokensPath);
|
|
24206
24144
|
}
|
|
24207
24145
|
const manifest = buildManifest3(components, tokens, { deleteAllComponents: opts.deleteAllComponents === true });
|
|
24208
|
-
const client2 = new
|
|
24146
|
+
const client2 = new ImportApiClient({ host, cmaToken, spaceId, environmentId });
|
|
24209
24147
|
const startedAt = Date.now();
|
|
24210
24148
|
let timeoutHandle;
|
|
24211
24149
|
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
@@ -28425,7 +28363,7 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28425
28363
|
update({ step: "credentials", credentialsValidating: true, credentialsError: "" });
|
|
28426
28364
|
try {
|
|
28427
28365
|
const resolvedHost = resolveWizardHost(host2);
|
|
28428
|
-
const client2 = new
|
|
28366
|
+
const client2 = new ImportApiClient({
|
|
28429
28367
|
cmaToken,
|
|
28430
28368
|
spaceId,
|
|
28431
28369
|
environmentId,
|
|
@@ -28499,7 +28437,7 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28499
28437
|
update({ step: "previewing" });
|
|
28500
28438
|
const resolvedHost = resolveWizardHost(host2);
|
|
28501
28439
|
try {
|
|
28502
|
-
const client2 = new
|
|
28440
|
+
const client2 = new ImportApiClient({
|
|
28503
28441
|
cmaToken,
|
|
28504
28442
|
spaceId,
|
|
28505
28443
|
environmentId,
|
|
@@ -28661,7 +28599,7 @@ If using a custom --host, make sure the space exists on that host.`
|
|
|
28661
28599
|
update({ step: "pushing", pushProgress: null });
|
|
28662
28600
|
try {
|
|
28663
28601
|
const resolvedHost = resolveWizardHost(host2);
|
|
28664
|
-
const client2 = new
|
|
28602
|
+
const client2 = new ImportApiClient({
|
|
28665
28603
|
cmaToken,
|
|
28666
28604
|
spaceId,
|
|
28667
28605
|
environmentId,
|
|
@@ -34427,52 +34365,14 @@ init_db();
|
|
|
34427
34365
|
init_command();
|
|
34428
34366
|
init_manifest();
|
|
34429
34367
|
init_api_client();
|
|
34430
|
-
import { mkdir as mkdir5, writeFile as writeFile5 } from "node:fs/promises";
|
|
34431
|
-
import { join as join18, resolve as resolve21 } from "node:path";
|
|
34432
|
-
import { execFile as execFile2 } from "node:child_process";
|
|
34433
|
-
|
|
34434
|
-
// packages/experience-design-system-cli/src/api/clients/cma-client.ts
|
|
34435
|
-
init_http();
|
|
34436
|
-
init_api_error();
|
|
34437
|
-
init_abstract_api_client();
|
|
34438
|
-
var CMA_PAGE_LIMIT = 100;
|
|
34439
|
-
var CmaApiClient = class extends AbstractApiClient {
|
|
34440
|
-
constructor(opts) {
|
|
34441
|
-
super(opts);
|
|
34442
|
-
}
|
|
34443
|
-
async listExistingEntities() {
|
|
34444
|
-
const [components, tokens] = await Promise.all([
|
|
34445
|
-
this.listAll("component_types", "component_types"),
|
|
34446
|
-
this.listAll("design_tokens", "design_tokens")
|
|
34447
|
-
]);
|
|
34448
|
-
return { components, tokens };
|
|
34449
|
-
}
|
|
34450
|
-
async listAll(resourcePath, opName) {
|
|
34451
|
-
const items = [];
|
|
34452
|
-
let skip = 0;
|
|
34453
|
-
while (true) {
|
|
34454
|
-
const url = `${this.base()}/${resourcePath}?limit=${CMA_PAGE_LIMIT}&skip=${skip}`;
|
|
34455
|
-
const res = await request(url, { token: this.token });
|
|
34456
|
-
if (!res.ok) {
|
|
34457
|
-
throw new ApiError(`${opName} list failed: ${res.status}`, res.status, await res.text());
|
|
34458
|
-
}
|
|
34459
|
-
const page = await res.json();
|
|
34460
|
-
items.push(...page.items);
|
|
34461
|
-
const returned = page.items.length;
|
|
34462
|
-
const total = page.total ?? items.length;
|
|
34463
|
-
if (returned === 0 || items.length >= total) break;
|
|
34464
|
-
skip += returned;
|
|
34465
|
-
}
|
|
34466
|
-
return items;
|
|
34467
|
-
}
|
|
34468
|
-
};
|
|
34469
|
-
|
|
34470
|
-
// packages/experience-design-system-cli/src/import/orchestrator.ts
|
|
34471
34368
|
init_contentful_urls();
|
|
34472
34369
|
init_debug_logger();
|
|
34473
34370
|
init_analytics();
|
|
34474
34371
|
init_env();
|
|
34475
34372
|
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";
|
|
34476
34376
|
async function runStep(args, cliPath, analyticsSessionId, env = {}, streamStderr = false) {
|
|
34477
34377
|
const debug = getDebugLogger();
|
|
34478
34378
|
const startedAt = Date.now();
|
|
@@ -34580,66 +34480,11 @@ async function runPipeline(opts, progressWriter, cliPathOverride) {
|
|
|
34580
34480
|
await mkdir5(outDir, { recursive: true });
|
|
34581
34481
|
const steps = [];
|
|
34582
34482
|
let stepNum = 0;
|
|
34583
|
-
const
|
|
34584
|
-
const canFetchSpaceContext = wantsSpaceContext && !!opts.spaceId && !!opts.environmentId && !!opts.cmaToken;
|
|
34585
|
-
const totalSteps = 5 + (opts.print ? 1 : 0) + (canFetchSpaceContext ? 1 : 0);
|
|
34483
|
+
const totalSteps = 5 + (opts.print ? 1 : 0);
|
|
34586
34484
|
function stepLabel(name) {
|
|
34587
34485
|
stepNum++;
|
|
34588
34486
|
return ` Step ${stepNum}/${totalSteps} ${name} `;
|
|
34589
34487
|
}
|
|
34590
|
-
if (wantsSpaceContext && !canFetchSpaceContext) {
|
|
34591
|
-
progressWriter(
|
|
34592
|
-
" Note: --with-space-context requires --space-id, --environment-id, and --cma-token; skipping context fetch."
|
|
34593
|
-
);
|
|
34594
|
-
}
|
|
34595
|
-
if (canFetchSpaceContext) {
|
|
34596
|
-
const fetchLabel = stepLabel("Fetching existing components + design tokens");
|
|
34597
|
-
const fetchStepId = createStep(db, sessionId2, "fetch existing entities", {
|
|
34598
|
-
spaceId: opts.spaceId,
|
|
34599
|
-
environmentId: opts.environmentId
|
|
34600
|
-
});
|
|
34601
|
-
const t0 = Date.now();
|
|
34602
|
-
try {
|
|
34603
|
-
const cma = new CmaApiClient({
|
|
34604
|
-
host: opts.host,
|
|
34605
|
-
cmaToken: opts.cmaToken,
|
|
34606
|
-
spaceId: opts.spaceId,
|
|
34607
|
-
environmentId: opts.environmentId
|
|
34608
|
-
});
|
|
34609
|
-
const result = await cma.listExistingEntities();
|
|
34610
|
-
const fetchDurationMs = Date.now() - t0;
|
|
34611
|
-
const existingEntitiesPath = join18(outDir, ".existing-entities.json");
|
|
34612
|
-
await writeFile5(existingEntitiesPath, JSON.stringify(result, null, 2), "utf8");
|
|
34613
|
-
updateStep(db, fetchStepId, "complete", {
|
|
34614
|
-
components: String(result.components.length),
|
|
34615
|
-
tokens: String(result.tokens.length),
|
|
34616
|
-
path: existingEntitiesPath
|
|
34617
|
-
});
|
|
34618
|
-
progressWriter(
|
|
34619
|
-
`${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)`
|
|
34620
|
-
);
|
|
34621
|
-
steps.push({
|
|
34622
|
-
step: "fetch existing entities",
|
|
34623
|
-
status: "complete",
|
|
34624
|
-
durationMs: fetchDurationMs,
|
|
34625
|
-
detail: { components: result.components.length, tokens: result.tokens.length }
|
|
34626
|
-
});
|
|
34627
|
-
} catch (error) {
|
|
34628
|
-
const fetchDurationMs = Date.now() - t0;
|
|
34629
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
34630
|
-
updateStep(db, fetchStepId, "failed", {}, message);
|
|
34631
|
-
progressWriter(
|
|
34632
|
-
`${fetchLabel}\u26A0 fetch failed, continuing without space context (${(fetchDurationMs / 1e3).toFixed(1)}s)`
|
|
34633
|
-
);
|
|
34634
|
-
progressWriter(` ${message.split("\n")[0]}`);
|
|
34635
|
-
steps.push({
|
|
34636
|
-
step: "fetch existing entities",
|
|
34637
|
-
status: "failed",
|
|
34638
|
-
durationMs: fetchDurationMs,
|
|
34639
|
-
error: message
|
|
34640
|
-
});
|
|
34641
|
-
}
|
|
34642
|
-
}
|
|
34643
34488
|
const analyzeLabel = stepLabel("Statically analyzing project");
|
|
34644
34489
|
const analyzeSkipped = !opts.noCache && opts.skipAnalyze;
|
|
34645
34490
|
let extractSessionId = null;
|
|
@@ -35594,10 +35439,7 @@ function registerImportCommand(program) {
|
|
|
35594
35439
|
"Override a stage prompt (repeatable). value is a file path or literal text, e.g. --prompt composition=./p.md",
|
|
35595
35440
|
(v, acc) => [...acc, v],
|
|
35596
35441
|
[]
|
|
35597
|
-
).option("--auto-reject-cycles", "Automatically reject components involved in slot cycles and retry").option(
|
|
35598
|
-
"--with-space-context",
|
|
35599
|
-
"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."
|
|
35600
|
-
).option("--auto-filter", "Force the AI auto-filter ON (overrides the credentials.json autoFilter preference)").option(
|
|
35442
|
+
).option("--auto-reject-cycles", "Automatically reject components involved in slot cycles and retry").option("--auto-filter", "Force the AI auto-filter ON (overrides the credentials.json autoFilter preference)").option(
|
|
35601
35443
|
"--no-auto-filter",
|
|
35602
35444
|
"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)"
|
|
35603
35445
|
).option(
|
|
@@ -35944,7 +35786,6 @@ function registerImportCommand(program) {
|
|
|
35944
35786
|
dryRun: dryRunForward,
|
|
35945
35787
|
selectPromptPath: opts.selectPromptPath,
|
|
35946
35788
|
autoRejectCycles: opts.autoRejectCycles ?? false,
|
|
35947
|
-
withSpaceContext: opts.withSpaceContext ?? false,
|
|
35948
35789
|
allowDeletions: opts.allowDeletions ?? false,
|
|
35949
35790
|
compositionMode: headlessCompositionMode,
|
|
35950
35791
|
...opts.compositionMap ? { compositionMap: opts.compositionMap } : {},
|
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' | '
|
|
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';
|
|
9
9
|
export interface SessionRow {
|
|
10
10
|
id: string;
|
|
11
11
|
name: string | null;
|
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-f054f94.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-f054f94.0",
|
|
43
|
+
"@contentful/experience-design-system-types": "2.32.1-dev-build-f054f94.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-client": "2.32.1-dev-build-f054f94.0",
|
|
56
|
+
"@contentful/experience-design-system-generation": "2.32.1-dev-build-f054f94.0",
|
|
57
|
+
"@contentful/experience-design-system-extraction": "2.32.1-dev-build-f054f94.0"
|
|
58
58
|
},
|
|
59
59
|
"repository": {
|
|
60
60
|
"type": "git",
|
|
@@ -1,24 +0,0 @@
|
|
|
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 validateToken flow that both clients need.
|
|
10
|
-
* Subclasses override validateToken() 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
|
-
validateToken(): Promise<void>;
|
|
23
|
-
protected onValidateTokenResponse(_res: Response): void;
|
|
24
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import type { ManifestPayload, ServerPreviewResponse, ApplyOperationResponse, BreakingChange } 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 const DEFAULT_HOST = "https://api.contentful.com";
|
|
6
|
-
export declare const PREVIEW_ERROR_PREFIX = "preview failed:";
|
|
7
|
-
export declare const APPLY_ERROR_PREFIX = "apply failed:";
|
|
8
|
-
export declare const VALIDATION_FAILED_CODE = "\"ValidationFailed\"";
|
|
9
|
-
export interface PreviewValidationError {
|
|
10
|
-
componentName: string;
|
|
11
|
-
path: string;
|
|
12
|
-
message: string;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Parse the JSON body of a 422 from `previewImport()` into structured
|
|
16
|
-
* per-component validation errors. Returns [] for any malformed input
|
|
17
|
-
* so callers can fall back to the generic error path without try/catch.
|
|
18
|
-
*
|
|
19
|
-
* Path shape: `manifest:components/<Name>/$slots/<key>` or
|
|
20
|
-
* `manifest:components/<Name>/$properties/<key>`. Only the component
|
|
21
|
-
* name is extracted today; `path` and `message` are kept verbatim so
|
|
22
|
-
* future surfaces (debug logging, headless retry in SP-4) can render
|
|
23
|
-
* the field-level detail.
|
|
24
|
-
*/
|
|
25
|
-
export declare function parsePreviewValidationErrors(body: string): PreviewValidationError[];
|
|
26
|
-
export declare function sanitizeBreakingChanges(raw: unknown): BreakingChange[];
|
|
27
|
-
export declare class EdsiApiClient extends AbstractApiClient {
|
|
28
|
-
private retry;
|
|
29
|
-
private lastRequestId?;
|
|
30
|
-
getLastRequestId(): string | undefined;
|
|
31
|
-
private noteRequestId;
|
|
32
|
-
protected onValidateTokenResponse(res: Response): void;
|
|
33
|
-
constructor(opts: EdsiClientOptions);
|
|
34
|
-
private headers;
|
|
35
|
-
private requestWithRetry;
|
|
36
|
-
validateToken(): Promise<void>;
|
|
37
|
-
checkPreflight(): Promise<void>;
|
|
38
|
-
previewImport(manifest: ManifestPayload, allowDeletions?: boolean): Promise<ServerPreviewResponse>;
|
|
39
|
-
applyImport(manifest: ManifestPayload, options: {
|
|
40
|
-
acknowledgeBreakingChanges: boolean;
|
|
41
|
-
allowDeletions?: boolean;
|
|
42
|
-
}): Promise<ApplyOperationResponse>;
|
|
43
|
-
pollOperation(operationId: string, opts?: PollOptions): Promise<ApplyOperationResponse>;
|
|
44
|
-
}
|
package/dist/src/api/index.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export { CmaApiClient } from './clients/cma-client.js';
|
|
2
|
-
export { EdsiApiClient, DEFAULT_HOST, PREVIEW_ERROR_PREFIX, APPLY_ERROR_PREFIX, VALIDATION_FAILED_CODE, parsePreviewValidationErrors, sanitizeBreakingChanges, } from './clients/edsi-client.js';
|
|
3
|
-
export type { PreviewValidationError } from './clients/edsi-client.js';
|
|
4
|
-
export { ApiError } from '../errors/api-error.js';
|
|
5
|
-
export type { CmaClientOptions } from '../interfaces/clients/cma-client-options.js';
|
|
6
|
-
export type { EdsiClientOptions } from '../interfaces/clients/edsi-client-options.js';
|
|
7
|
-
export type { PollOptions } from '../interfaces/clients/poll-options.js';
|
|
8
|
-
export type { ExistingComponentEntity } from '../interfaces/responses/existing-component-entity.js';
|
|
9
|
-
export type { ExistingTokenEntity } from '../interfaces/responses/existing-token-entity.js';
|
|
10
|
-
export type { ExistingEntitiesResponse } from '../interfaces/responses/existing-entities-response.js';
|
|
@@ -1,4 +0,0 @@
|
|
|
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;
|
|
@@ -1,12 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,6 +0,0 @@
|
|
|
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
|
-
}
|