@contentful/experience-design-system-cli 2.37.1-dev-build-8757f66c.0 → 2.37.1-dev-build-932fd115.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/app.d.ts +2 -1
- package/dist/app.js +79 -610
- package/dist/index.js +107 -594
- package/dist/package.json +1 -1
- package/dist/src/commands/import-options.d.ts +13 -0
- package/dist/src/commands/import.d.ts +2 -1
- package/dist/src/tui/import/spawn-v1-import.d.ts +3 -1
- package/dist/src/tui/import/steps/04-credentials/logic.d.ts +3 -0
- package/dist/src/tui/import/steps/04-credentials/validate.d.ts +1 -1
- package/legacy/package.json +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -57,6 +57,27 @@ var init_legacy_cli_path = __esm({
|
|
|
57
57
|
}
|
|
58
58
|
});
|
|
59
59
|
|
|
60
|
+
// packages/experience-design-system-cli/src/commands/import-options.ts
|
|
61
|
+
function toImportOptions(raw) {
|
|
62
|
+
return {
|
|
63
|
+
...raw.agent ? { agent: raw.agent } : {},
|
|
64
|
+
prompt: raw.prompt ?? [],
|
|
65
|
+
cache: raw.cache !== false
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function importOptionArgs(options) {
|
|
69
|
+
return [
|
|
70
|
+
...options.agent ? ["--agent", options.agent] : [],
|
|
71
|
+
...options.prompt.flatMap((value) => ["--prompt", value]),
|
|
72
|
+
...options.cache ? [] : ["--no-cache"]
|
|
73
|
+
];
|
|
74
|
+
}
|
|
75
|
+
var init_import_options = __esm({
|
|
76
|
+
"packages/experience-design-system-cli/src/commands/import-options.ts"() {
|
|
77
|
+
"use strict";
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
60
81
|
// packages/experience-design-system-cli/src/tui/home/home.theme.ts
|
|
61
82
|
function brandBar(width, ramp = BRAND_RAMP) {
|
|
62
83
|
if (width <= 0 || ramp.length === 0) return [];
|
|
@@ -3202,11 +3223,9 @@ var init_resolve_session_id = __esm({
|
|
|
3202
3223
|
});
|
|
3203
3224
|
|
|
3204
3225
|
// packages/experience-design-system-backend-pipeline/dist/src/persistence/src/credentials/helpers/host-utils.js
|
|
3205
|
-
var DEFAULT_CONFIGURED_HOST;
|
|
3206
3226
|
var init_host_utils = __esm({
|
|
3207
3227
|
"packages/experience-design-system-backend-pipeline/dist/src/persistence/src/credentials/helpers/host-utils.js"() {
|
|
3208
3228
|
"use strict";
|
|
3209
|
-
DEFAULT_CONFIGURED_HOST = "api.contentful.com";
|
|
3210
3229
|
}
|
|
3211
3230
|
});
|
|
3212
3231
|
|
|
@@ -3681,9 +3700,9 @@ var init_utils_gen = __esm({
|
|
|
3681
3700
|
config.headers = mergeHeaders(a.headers, b.headers);
|
|
3682
3701
|
return config;
|
|
3683
3702
|
};
|
|
3684
|
-
mergeHeaders = (...
|
|
3703
|
+
mergeHeaders = (...headers2) => {
|
|
3685
3704
|
const mergedHeaders = new Headers();
|
|
3686
|
-
for (const header of
|
|
3705
|
+
for (const header of headers2) {
|
|
3687
3706
|
if (!header || typeof header !== "object") {
|
|
3688
3707
|
continue;
|
|
3689
3708
|
}
|
|
@@ -3930,37 +3949,10 @@ var init_client_gen2 = __esm({
|
|
|
3930
3949
|
});
|
|
3931
3950
|
|
|
3932
3951
|
// packages/experience-design-system-client/dist/src/generated/sdk.gen.js
|
|
3933
|
-
var designSystemImportSourcelessPreview, designSystemImportApply, designSystemImportGetOperation;
|
|
3934
3952
|
var init_sdk_gen = __esm({
|
|
3935
3953
|
"packages/experience-design-system-client/dist/src/generated/sdk.gen.js"() {
|
|
3936
3954
|
"use strict";
|
|
3937
3955
|
init_client_gen2();
|
|
3938
|
-
designSystemImportSourcelessPreview = (options) => {
|
|
3939
|
-
return (options.client ?? client).post({
|
|
3940
|
-
url: "/spaces/{spaceId}/environments/{environmentId}/design_systems/imports/preview",
|
|
3941
|
-
...options,
|
|
3942
|
-
headers: {
|
|
3943
|
-
"Content-Type": "application/json",
|
|
3944
|
-
...options.headers
|
|
3945
|
-
}
|
|
3946
|
-
});
|
|
3947
|
-
};
|
|
3948
|
-
designSystemImportApply = (options) => {
|
|
3949
|
-
return (options.client ?? client).post({
|
|
3950
|
-
url: "/spaces/{spaceId}/environments/{environmentId}/design_systems/imports/apply",
|
|
3951
|
-
...options,
|
|
3952
|
-
headers: {
|
|
3953
|
-
"Content-Type": "application/json",
|
|
3954
|
-
...options.headers
|
|
3955
|
-
}
|
|
3956
|
-
});
|
|
3957
|
-
};
|
|
3958
|
-
designSystemImportGetOperation = (options) => {
|
|
3959
|
-
return (options.client ?? client).get({
|
|
3960
|
-
url: "/spaces/{spaceId}/environments/{environmentId}/design_systems/imports/apply/{operationId}",
|
|
3961
|
-
...options
|
|
3962
|
-
});
|
|
3963
|
-
};
|
|
3964
3956
|
}
|
|
3965
3957
|
});
|
|
3966
3958
|
|
|
@@ -3983,13 +3975,9 @@ var init_src2 = __esm({
|
|
|
3983
3975
|
});
|
|
3984
3976
|
|
|
3985
3977
|
// packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/constants/api.js
|
|
3986
|
-
var PREVIEW_ERROR_PREFIX, APPLY_ERROR_PREFIX, USER_AGENT;
|
|
3987
3978
|
var init_api = __esm({
|
|
3988
3979
|
"packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/constants/api.js"() {
|
|
3989
3980
|
"use strict";
|
|
3990
|
-
PREVIEW_ERROR_PREFIX = "preview failed:";
|
|
3991
|
-
APPLY_ERROR_PREFIX = "apply failed:";
|
|
3992
|
-
USER_AGENT = "experience-design-system-backend-pipeline";
|
|
3993
3981
|
}
|
|
3994
3982
|
});
|
|
3995
3983
|
|
|
@@ -4002,153 +3990,34 @@ var init_constants5 = __esm({
|
|
|
4002
3990
|
});
|
|
4003
3991
|
|
|
4004
3992
|
// packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/http-utils.js
|
|
4005
|
-
function isTransientStatus(status) {
|
|
4006
|
-
return status >= 500 && status <= 599;
|
|
4007
|
-
}
|
|
4008
|
-
function retryAfterMs(response) {
|
|
4009
|
-
const value = response.headers?.get("retry-after")?.trim();
|
|
4010
|
-
if (!value)
|
|
4011
|
-
return void 0;
|
|
4012
|
-
const seconds = Number(value);
|
|
4013
|
-
const delayMs = Number.isFinite(seconds) ? seconds * 1e3 : Date.parse(value) - Date.now();
|
|
4014
|
-
if (!Number.isFinite(delayMs) || delayMs < 0 || delayMs > MAX_RETRY_AFTER_MS)
|
|
4015
|
-
return void 0;
|
|
4016
|
-
return Math.round(delayMs);
|
|
4017
|
-
}
|
|
4018
|
-
function isApsDenialBody(body) {
|
|
4019
|
-
if (!body)
|
|
4020
|
-
return false;
|
|
4021
|
-
try {
|
|
4022
|
-
const parsed = JSON.parse(body);
|
|
4023
|
-
const id = parsed?.sys?.id;
|
|
4024
|
-
return id === "NotFound" || id === "AccessDenied";
|
|
4025
|
-
} catch {
|
|
4026
|
-
return false;
|
|
4027
|
-
}
|
|
4028
|
-
}
|
|
4029
|
-
function stringifyError(error) {
|
|
4030
|
-
return typeof error === "string" ? error : JSON.stringify(error ?? {});
|
|
4031
|
-
}
|
|
4032
|
-
function errorMessage(error) {
|
|
4033
|
-
return error instanceof Error && error.message ? error.message : String(error);
|
|
4034
|
-
}
|
|
4035
|
-
function defaultSleep(delayMs) {
|
|
4036
|
-
return new Promise((resolve2) => setTimeout(resolve2, delayMs));
|
|
4037
|
-
}
|
|
4038
|
-
var MAX_RETRY_AFTER_MS;
|
|
4039
3993
|
var init_http_utils = __esm({
|
|
4040
3994
|
"packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/http-utils.js"() {
|
|
4041
3995
|
"use strict";
|
|
4042
|
-
MAX_RETRY_AFTER_MS = 6e4;
|
|
4043
3996
|
}
|
|
4044
3997
|
});
|
|
4045
3998
|
|
|
4046
3999
|
// packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/sanitize-preview.js
|
|
4047
|
-
function sanitizeBreakingChanges(raw) {
|
|
4048
|
-
if (!Array.isArray(raw))
|
|
4049
|
-
return [];
|
|
4050
|
-
const out = [];
|
|
4051
|
-
for (const bc of raw) {
|
|
4052
|
-
if (typeof bc !== "object" || bc === null)
|
|
4053
|
-
continue;
|
|
4054
|
-
const reason = bc.reason;
|
|
4055
|
-
if (typeof reason !== "string")
|
|
4056
|
-
continue;
|
|
4057
|
-
if ("propertyId" in bc && typeof bc.propertyId === "string") {
|
|
4058
|
-
if (PROPERTY_BREAKING_REASONS.has(reason))
|
|
4059
|
-
out.push(bc);
|
|
4060
|
-
continue;
|
|
4061
|
-
}
|
|
4062
|
-
if ("slotId" in bc && typeof bc.slotId === "string") {
|
|
4063
|
-
if (SLOT_BREAKING_REASONS.has(reason))
|
|
4064
|
-
out.push(bc);
|
|
4065
|
-
continue;
|
|
4066
|
-
}
|
|
4067
|
-
}
|
|
4068
|
-
return out;
|
|
4069
|
-
}
|
|
4070
|
-
function sanitizePreviewResponse(res) {
|
|
4071
|
-
for (const item of res.components?.changed ?? []) {
|
|
4072
|
-
const cc = item.changeClassification;
|
|
4073
|
-
if (cc && Array.isArray(cc.breakingChanges)) {
|
|
4074
|
-
cc.breakingChanges = sanitizeBreakingChanges(cc.breakingChanges);
|
|
4075
|
-
}
|
|
4076
|
-
}
|
|
4077
|
-
return res;
|
|
4078
|
-
}
|
|
4079
|
-
var PROPERTY_BREAKING_REASONS, SLOT_BREAKING_REASONS;
|
|
4080
4000
|
var init_sanitize_preview = __esm({
|
|
4081
4001
|
"packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/sanitize-preview.js"() {
|
|
4082
4002
|
"use strict";
|
|
4083
|
-
PROPERTY_BREAKING_REASONS = /* @__PURE__ */ new Set([
|
|
4084
|
-
"removed",
|
|
4085
|
-
"added_required_no_default",
|
|
4086
|
-
"type_changed",
|
|
4087
|
-
"validation_narrowed"
|
|
4088
|
-
]);
|
|
4089
|
-
SLOT_BREAKING_REASONS = /* @__PURE__ */ new Set(["slot_removed", "slot_allowed_components_narrowed"]);
|
|
4090
4003
|
}
|
|
4091
4004
|
});
|
|
4092
4005
|
|
|
4093
4006
|
// packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/host-utils.js
|
|
4094
|
-
function trimTrailingSlashes(value) {
|
|
4095
|
-
return value.replace(/\/+$/, "");
|
|
4096
|
-
}
|
|
4097
|
-
function normalizeHostInput(host) {
|
|
4098
|
-
const value = host?.trim();
|
|
4099
|
-
if (!value)
|
|
4100
|
-
return void 0;
|
|
4101
|
-
return trimTrailingSlashes(value);
|
|
4102
|
-
}
|
|
4103
|
-
function toConfiguredHost2(host) {
|
|
4104
|
-
const normalized = normalizeHostInput(host);
|
|
4105
|
-
if (!normalized)
|
|
4106
|
-
return void 0;
|
|
4107
|
-
return normalized.replace(/^https:\/\//i, "");
|
|
4108
|
-
}
|
|
4109
|
-
function toApiHost2(host) {
|
|
4110
|
-
const normalized = normalizeHostInput(host);
|
|
4111
|
-
if (!normalized)
|
|
4112
|
-
return DEFAULT_API_HOST;
|
|
4113
|
-
if (/^[a-z][a-z\d+\-.]*:\/\//i.test(normalized))
|
|
4114
|
-
return normalized;
|
|
4115
|
-
return `https://${normalized}`;
|
|
4116
|
-
}
|
|
4117
|
-
var DEFAULT_API_HOST;
|
|
4118
4007
|
var init_host_utils2 = __esm({
|
|
4119
4008
|
"packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/host-utils.js"() {
|
|
4120
4009
|
"use strict";
|
|
4121
|
-
DEFAULT_API_HOST = "https://api.contentful.com";
|
|
4122
4010
|
}
|
|
4123
4011
|
});
|
|
4124
4012
|
|
|
4125
4013
|
// packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/types/api-error.js
|
|
4126
|
-
var ERROR_BODY_LOG_CAP, ApiError;
|
|
4127
4014
|
var init_api_error = __esm({
|
|
4128
4015
|
"packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/types/api-error.js"() {
|
|
4129
4016
|
"use strict";
|
|
4130
|
-
ERROR_BODY_LOG_CAP = 16384;
|
|
4131
|
-
ApiError = class extends Error {
|
|
4132
|
-
status;
|
|
4133
|
-
body;
|
|
4134
|
-
guidance;
|
|
4135
|
-
constructor(message, status, body, guidance) {
|
|
4136
|
-
super(message);
|
|
4137
|
-
this.status = status;
|
|
4138
|
-
this.body = body;
|
|
4139
|
-
this.guidance = guidance;
|
|
4140
|
-
if (body) {
|
|
4141
|
-
const trimmed = body.length > ERROR_BODY_LOG_CAP ? body.slice(0, ERROR_BODY_LOG_CAP) + "\u2026" : body;
|
|
4142
|
-
this.message = `${message}
|
|
4143
|
-
${trimmed}`;
|
|
4144
|
-
}
|
|
4145
|
-
}
|
|
4146
|
-
};
|
|
4147
4017
|
}
|
|
4148
4018
|
});
|
|
4149
4019
|
|
|
4150
4020
|
// packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/api-client/api-client.js
|
|
4151
|
-
var ApiClient;
|
|
4152
4021
|
var init_api_client = __esm({
|
|
4153
4022
|
"packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/api-client/api-client.js"() {
|
|
4154
4023
|
"use strict";
|
|
@@ -4158,161 +4027,6 @@ var init_api_client = __esm({
|
|
|
4158
4027
|
init_sanitize_preview();
|
|
4159
4028
|
init_host_utils2();
|
|
4160
4029
|
init_api_error();
|
|
4161
|
-
ApiClient = class {
|
|
4162
|
-
host;
|
|
4163
|
-
token;
|
|
4164
|
-
spaceId;
|
|
4165
|
-
environmentId;
|
|
4166
|
-
retry;
|
|
4167
|
-
lastRequestId;
|
|
4168
|
-
constructor(opts) {
|
|
4169
|
-
this.host = toApiHost2(opts.host);
|
|
4170
|
-
this.token = opts.cmaToken;
|
|
4171
|
-
this.spaceId = opts.spaceId;
|
|
4172
|
-
this.environmentId = opts.environmentId;
|
|
4173
|
-
const initialDelayMs = Math.max(0, opts.retry?.initialDelayMs ?? 250);
|
|
4174
|
-
this.retry = {
|
|
4175
|
-
maxAttempts: Math.max(1, Math.floor(opts.retry?.maxAttempts ?? 3)),
|
|
4176
|
-
initialDelayMs,
|
|
4177
|
-
maxDelayMs: Math.max(initialDelayMs, opts.retry?.maxDelayMs ?? 2e3),
|
|
4178
|
-
sleep: opts.retry?.sleep ?? defaultSleep
|
|
4179
|
-
};
|
|
4180
|
-
}
|
|
4181
|
-
getLastRequestId() {
|
|
4182
|
-
return this.lastRequestId;
|
|
4183
|
-
}
|
|
4184
|
-
noteRequestId(response) {
|
|
4185
|
-
const id = response.headers.get("x-contentful-request-id");
|
|
4186
|
-
if (id)
|
|
4187
|
-
this.lastRequestId = id;
|
|
4188
|
-
}
|
|
4189
|
-
headers() {
|
|
4190
|
-
return {
|
|
4191
|
-
Authorization: `Bearer ${this.token}`,
|
|
4192
|
-
"Content-Type": "application/json",
|
|
4193
|
-
"X-Contentful-User-Agent": USER_AGENT
|
|
4194
|
-
};
|
|
4195
|
-
}
|
|
4196
|
-
async requestWithRetry(phase, errorPrefix, makeCall) {
|
|
4197
|
-
for (let attempt = 1; attempt <= this.retry.maxAttempts; attempt++) {
|
|
4198
|
-
let result;
|
|
4199
|
-
try {
|
|
4200
|
-
result = await makeCall();
|
|
4201
|
-
} catch (error) {
|
|
4202
|
-
if (attempt === this.retry.maxAttempts) {
|
|
4203
|
-
const body = `The request failed after ${attempt} attempts because of a network error: ${errorMessage(error)}. Check your connection and try again.`;
|
|
4204
|
-
throw new ApiError(`${errorPrefix} 0`, 0, body);
|
|
4205
|
-
}
|
|
4206
|
-
await this.retry.sleep(Math.min(this.retry.initialDelayMs * 2 ** (attempt - 1), this.retry.maxDelayMs));
|
|
4207
|
-
continue;
|
|
4208
|
-
}
|
|
4209
|
-
if (!isTransientStatus(result.response.status)) {
|
|
4210
|
-
this.noteRequestId(result.response);
|
|
4211
|
-
return result;
|
|
4212
|
-
}
|
|
4213
|
-
if (attempt === this.retry.maxAttempts) {
|
|
4214
|
-
const body = stringifyError(result.error);
|
|
4215
|
-
const guidance = `The ${phase} request failed after ${attempt} attempts because the service remained unavailable. Wait a moment and try again.`;
|
|
4216
|
-
throw new ApiError(`${errorPrefix} ${result.response.status}`, result.response.status, body, guidance);
|
|
4217
|
-
}
|
|
4218
|
-
const backoffMs = Math.min(this.retry.initialDelayMs * 2 ** (attempt - 1), this.retry.maxDelayMs);
|
|
4219
|
-
await this.retry.sleep(retryAfterMs(result.response) ?? backoffMs);
|
|
4220
|
-
}
|
|
4221
|
-
throw new Error("Retry attempts exhausted");
|
|
4222
|
-
}
|
|
4223
|
-
async validateToken() {
|
|
4224
|
-
const res = await fetch(`${this.host}/users/me`, { headers: this.headers() });
|
|
4225
|
-
this.noteRequestId(res);
|
|
4226
|
-
if (res.status === 401) {
|
|
4227
|
-
throw new ApiError("CMA token is invalid or revoked", res.status, await res.text());
|
|
4228
|
-
}
|
|
4229
|
-
if (!res.ok) {
|
|
4230
|
-
throw new ApiError(`unexpected error validating token: ${res.status}`, res.status, await res.text());
|
|
4231
|
-
}
|
|
4232
|
-
await this.checkPreflight();
|
|
4233
|
-
}
|
|
4234
|
-
async checkPreflight() {
|
|
4235
|
-
const url = `${this.host}/spaces/${this.spaceId}/environments/${this.environmentId}/design_systems/preflight`;
|
|
4236
|
-
let res;
|
|
4237
|
-
try {
|
|
4238
|
-
res = await fetch(url, { headers: this.headers() });
|
|
4239
|
-
} catch {
|
|
4240
|
-
return;
|
|
4241
|
-
}
|
|
4242
|
-
this.noteRequestId(res);
|
|
4243
|
-
if (res.ok)
|
|
4244
|
-
return;
|
|
4245
|
-
if (res.status >= 500)
|
|
4246
|
-
return;
|
|
4247
|
-
const body = await res.text();
|
|
4248
|
-
if (res.status === 404 && !isApsDenialBody(body))
|
|
4249
|
-
return;
|
|
4250
|
-
throw new ApiError(`preflight failed: ${res.status}`, res.status, body);
|
|
4251
|
-
}
|
|
4252
|
-
async previewImport(cdf) {
|
|
4253
|
-
const result = await this.requestWithRetry("preview", PREVIEW_ERROR_PREFIX, () => designSystemImportSourcelessPreview({
|
|
4254
|
-
baseUrl: this.host,
|
|
4255
|
-
headers: this.headers(),
|
|
4256
|
-
path: { spaceId: this.spaceId, environmentId: this.environmentId },
|
|
4257
|
-
body: cdf,
|
|
4258
|
-
parseAs: "json"
|
|
4259
|
-
}));
|
|
4260
|
-
if (!result.response.ok) {
|
|
4261
|
-
throw new ApiError(`${PREVIEW_ERROR_PREFIX} ${result.response.status}`, result.response.status, stringifyError(result.error));
|
|
4262
|
-
}
|
|
4263
|
-
return sanitizePreviewResponse(result.data);
|
|
4264
|
-
}
|
|
4265
|
-
async applyImport(cdf, opts) {
|
|
4266
|
-
let result;
|
|
4267
|
-
try {
|
|
4268
|
-
result = await designSystemImportApply({
|
|
4269
|
-
baseUrl: this.host,
|
|
4270
|
-
headers: this.headers(),
|
|
4271
|
-
path: { spaceId: this.spaceId, environmentId: this.environmentId },
|
|
4272
|
-
body: { ...cdf, acknowledgeBreakingChanges: opts.acknowledgeBreakingChanges },
|
|
4273
|
-
parseAs: "json"
|
|
4274
|
-
});
|
|
4275
|
-
} catch (error) {
|
|
4276
|
-
const body = `The apply request was not retried because its outcome is unknown and retrying could start a duplicate operation. Cause: ${errorMessage(error)}`;
|
|
4277
|
-
throw new ApiError(`${APPLY_ERROR_PREFIX} 0`, 0, body);
|
|
4278
|
-
}
|
|
4279
|
-
if (!result.response.ok) {
|
|
4280
|
-
const body = stringifyError(result.error);
|
|
4281
|
-
const guidance = isTransientStatus(result.response.status) ? "The apply request was not retried because the server may already have started an operation and retrying could create a duplicate." : void 0;
|
|
4282
|
-
throw new ApiError(`${APPLY_ERROR_PREFIX} ${result.response.status}`, result.response.status, body, guidance);
|
|
4283
|
-
}
|
|
4284
|
-
this.noteRequestId(result.response);
|
|
4285
|
-
return result.data;
|
|
4286
|
-
}
|
|
4287
|
-
async pollOperation(operationId, opts = {}) {
|
|
4288
|
-
const intervalMs = opts.intervalMs ?? 2e3;
|
|
4289
|
-
const maxIntervalMs = opts.maxIntervalMs ?? Math.round(intervalMs * 2.5);
|
|
4290
|
-
const maxAttempts = opts.maxAttempts ?? 150;
|
|
4291
|
-
const terminalStatuses = /* @__PURE__ */ new Set(["succeeded", "partial", "failed"]);
|
|
4292
|
-
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
4293
|
-
const result = await this.requestWithRetry("poll", "poll failed:", () => designSystemImportGetOperation({
|
|
4294
|
-
baseUrl: this.host,
|
|
4295
|
-
headers: this.headers(),
|
|
4296
|
-
path: { spaceId: this.spaceId, environmentId: this.environmentId, operationId },
|
|
4297
|
-
parseAs: "json"
|
|
4298
|
-
}));
|
|
4299
|
-
if (!result.response.ok) {
|
|
4300
|
-
throw new ApiError(`poll failed: ${result.response.status}`, result.response.status, stringifyError(result.error));
|
|
4301
|
-
}
|
|
4302
|
-
const op = result.data;
|
|
4303
|
-
opts.onProgress?.(op);
|
|
4304
|
-
if (terminalStatuses.has(op.sys.status))
|
|
4305
|
-
return op;
|
|
4306
|
-
if (attempt < maxAttempts - 1) {
|
|
4307
|
-
const progress = maxAttempts > 1 ? attempt / (maxAttempts - 1) : 0;
|
|
4308
|
-
const baseDelay = intervalMs + (maxIntervalMs - intervalMs) * progress;
|
|
4309
|
-
const jitter = Math.random() * baseDelay * 0.15;
|
|
4310
|
-
await new Promise((resolve2) => setTimeout(resolve2, baseDelay + jitter));
|
|
4311
|
-
}
|
|
4312
|
-
}
|
|
4313
|
-
throw new Error(`Operation ${operationId} timed out after ${maxAttempts} attempts`);
|
|
4314
|
-
}
|
|
4315
|
-
};
|
|
4316
4030
|
}
|
|
4317
4031
|
});
|
|
4318
4032
|
|
|
@@ -4515,25 +4229,6 @@ var init_annotate_preview2 = __esm({
|
|
|
4515
4229
|
});
|
|
4516
4230
|
|
|
4517
4231
|
// packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/edsi-errors/parse-binding-diagnostics.js
|
|
4518
|
-
function parseBindingDiagnostics(body) {
|
|
4519
|
-
if (!/binding configurations are invalid|Pointer path does not exist/i.test(body))
|
|
4520
|
-
return null;
|
|
4521
|
-
const locationMatches = [...body.matchAll(/(?:^|\.\s)([A-Za-z0-9_$-]+(?:\s*›\s*[A-Za-z0-9_$-]+){2,})/g)];
|
|
4522
|
-
const location = locationMatches.at(-1)?.[1];
|
|
4523
|
-
const pointerMessage = body.match(/Pointer path does not exist for '\[object Object\]':\s*(.+?)(?=\.\s*Default\s*›|$)/i)?.[1];
|
|
4524
|
-
const graphQlMessage = body.match(/return GraphQL validation error:\s*(.+?)(?=\.\s*Default\s*›|$)/i)?.[1];
|
|
4525
|
-
const heading = body.match(/^(.*?)(?=\.?\s*Pointer path does not exist|\.?\s*Default\s*›)/i)?.[1]?.trim();
|
|
4526
|
-
const diagnostics = [];
|
|
4527
|
-
if (pointerMessage)
|
|
4528
|
-
diagnostics.push({ message: pointerMessage.trim(), ...location ? { path: location } : {} });
|
|
4529
|
-
if (graphQlMessage)
|
|
4530
|
-
diagnostics.push({ message: graphQlMessage.trim(), ...location ? { path: location } : {} });
|
|
4531
|
-
return {
|
|
4532
|
-
code: "BindingValidationFailed",
|
|
4533
|
-
message: heading || "One or more binding configurations are invalid.",
|
|
4534
|
-
...diagnostics.length > 0 ? { diagnostics } : {}
|
|
4535
|
-
};
|
|
4536
|
-
}
|
|
4537
4232
|
var init_parse_binding_diagnostics = __esm({
|
|
4538
4233
|
"packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/edsi-errors/parse-binding-diagnostics.js"() {
|
|
4539
4234
|
"use strict";
|
|
@@ -4541,76 +4236,6 @@ var init_parse_binding_diagnostics = __esm({
|
|
|
4541
4236
|
});
|
|
4542
4237
|
|
|
4543
4238
|
// packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/edsi-errors/helpers.js
|
|
4544
|
-
function asRecord(value) {
|
|
4545
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
4546
|
-
}
|
|
4547
|
-
function displayValue(value) {
|
|
4548
|
-
if (typeof value === "string")
|
|
4549
|
-
return value;
|
|
4550
|
-
if (typeof value === "number" || typeof value === "boolean")
|
|
4551
|
-
return String(value);
|
|
4552
|
-
if (value === null || value === void 0)
|
|
4553
|
-
return null;
|
|
4554
|
-
try {
|
|
4555
|
-
return JSON.stringify(value);
|
|
4556
|
-
} catch {
|
|
4557
|
-
return null;
|
|
4558
|
-
}
|
|
4559
|
-
}
|
|
4560
|
-
function isPathSegment(value) {
|
|
4561
|
-
return typeof value === "string" || typeof value === "number" && Number.isFinite(value);
|
|
4562
|
-
}
|
|
4563
|
-
function formatPath(value) {
|
|
4564
|
-
if (isPathSegment(value))
|
|
4565
|
-
return String(value) ? { path: String(value) } : { path: null };
|
|
4566
|
-
if (Array.isArray(value)) {
|
|
4567
|
-
const parts = value.filter(isPathSegment);
|
|
4568
|
-
return parts.length > 0 ? { path: parts.join(" \u203A ") } : { path: null };
|
|
4569
|
-
}
|
|
4570
|
-
return {};
|
|
4571
|
-
}
|
|
4572
|
-
function componentFromPath(path5) {
|
|
4573
|
-
if (!path5)
|
|
4574
|
-
return void 0;
|
|
4575
|
-
const manifestMatch = path5.match(/manifest:components\/([^/›]+)/);
|
|
4576
|
-
if (manifestMatch?.[1])
|
|
4577
|
-
return manifestMatch[1];
|
|
4578
|
-
const parts = path5.split(/[›/]/).map((part) => part.trim()).filter(Boolean);
|
|
4579
|
-
const componentsIndex = parts.findIndex((part) => part === "components");
|
|
4580
|
-
return componentsIndex === -1 ? void 0 : parts[componentsIndex + 1];
|
|
4581
|
-
}
|
|
4582
|
-
function diagnosticMessage(error) {
|
|
4583
|
-
const candidates = [
|
|
4584
|
-
["message", error.message],
|
|
4585
|
-
["details", error.details],
|
|
4586
|
-
["error", error.error],
|
|
4587
|
-
["name", error.name]
|
|
4588
|
-
];
|
|
4589
|
-
for (const [messageSource, value] of candidates) {
|
|
4590
|
-
const message = displayValue(value);
|
|
4591
|
-
if (message !== null)
|
|
4592
|
-
return { message, messageSource };
|
|
4593
|
-
}
|
|
4594
|
-
return { message: "Validation failed" };
|
|
4595
|
-
}
|
|
4596
|
-
function parseObjectLiteralTail(body) {
|
|
4597
|
-
const braceStart = body.lastIndexOf("{");
|
|
4598
|
-
if (braceStart === -1)
|
|
4599
|
-
return null;
|
|
4600
|
-
const tail = body.slice(braceStart);
|
|
4601
|
-
const codeMatch = tail.match(/code:\s*['"]([^'"]+)['"]/);
|
|
4602
|
-
const cycleMatch = tail.match(/cycle:\s*\[\s*([^\]]*)\s*\]/);
|
|
4603
|
-
if (!codeMatch && !cycleMatch)
|
|
4604
|
-
return null;
|
|
4605
|
-
const code = codeMatch ? codeMatch[1] : null;
|
|
4606
|
-
let cycle = null;
|
|
4607
|
-
if (cycleMatch) {
|
|
4608
|
-
cycle = cycleMatch[1].split(",").map((s) => s.trim().replace(/^['"]|['"]$/g, "")).filter((s) => s.length > 0);
|
|
4609
|
-
if (cycle.length === 0)
|
|
4610
|
-
cycle = null;
|
|
4611
|
-
}
|
|
4612
|
-
return { code, cycle };
|
|
4613
|
-
}
|
|
4614
4239
|
var init_helpers3 = __esm({
|
|
4615
4240
|
"packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/edsi-errors/helpers.js"() {
|
|
4616
4241
|
"use strict";
|
|
@@ -4618,50 +4243,6 @@ var init_helpers3 = __esm({
|
|
|
4618
4243
|
});
|
|
4619
4244
|
|
|
4620
4245
|
// packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/edsi-errors/parse-json-body.js
|
|
4621
|
-
function parseValidationDiagnostics(details) {
|
|
4622
|
-
if (!Array.isArray(details.errors))
|
|
4623
|
-
return [];
|
|
4624
|
-
const diagnostics = [];
|
|
4625
|
-
for (const rawError of details.errors) {
|
|
4626
|
-
const error = asRecord(rawError);
|
|
4627
|
-
if (!error)
|
|
4628
|
-
continue;
|
|
4629
|
-
const location = formatPath(error.path);
|
|
4630
|
-
const component = displayValue(error.component ?? error.componentName ?? error.componentId) ?? componentFromPath(location.path);
|
|
4631
|
-
diagnostics.push({ ...diagnosticMessage(error), ...location, ...component ? { component } : {} });
|
|
4632
|
-
}
|
|
4633
|
-
return diagnostics;
|
|
4634
|
-
}
|
|
4635
|
-
function parseJsonBody(body) {
|
|
4636
|
-
let parsed;
|
|
4637
|
-
try {
|
|
4638
|
-
parsed = JSON.parse(body);
|
|
4639
|
-
} catch {
|
|
4640
|
-
return null;
|
|
4641
|
-
}
|
|
4642
|
-
const p = asRecord(parsed);
|
|
4643
|
-
if (!p)
|
|
4644
|
-
return null;
|
|
4645
|
-
const details = asRecord(p.details) ?? {};
|
|
4646
|
-
const pick = (k) => p[k] !== void 0 ? p[k] : details[k];
|
|
4647
|
-
const codeRaw = pick("code") ?? asRecord(p.sys)?.id;
|
|
4648
|
-
const messageRaw = pick("message");
|
|
4649
|
-
const cycleRaw = pick("cycle");
|
|
4650
|
-
const out = {};
|
|
4651
|
-
if (typeof codeRaw === "string")
|
|
4652
|
-
out.code = codeRaw;
|
|
4653
|
-
if (typeof messageRaw === "string")
|
|
4654
|
-
out.message = messageRaw;
|
|
4655
|
-
if (Array.isArray(cycleRaw)) {
|
|
4656
|
-
const strs = cycleRaw.filter((x) => typeof x === "string");
|
|
4657
|
-
if (strs.length > 0)
|
|
4658
|
-
out.cycle = strs;
|
|
4659
|
-
}
|
|
4660
|
-
const diagnostics = parseValidationDiagnostics(details);
|
|
4661
|
-
if (diagnostics.length > 0)
|
|
4662
|
-
out.diagnostics = diagnostics;
|
|
4663
|
-
return out;
|
|
4664
|
-
}
|
|
4665
4246
|
var init_parse_json_body = __esm({
|
|
4666
4247
|
"packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/edsi-errors/parse-json-body.js"() {
|
|
4667
4248
|
"use strict";
|
|
@@ -4670,72 +4251,13 @@ var init_parse_json_body = __esm({
|
|
|
4670
4251
|
});
|
|
4671
4252
|
|
|
4672
4253
|
// packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/edsi-errors/strip-lambda-log-prefix.js
|
|
4673
|
-
function stripLambdaLogPrefix(body) {
|
|
4674
|
-
return body.replace(LAMBDA_LOG_PREFIX_RE, "").replace(DD_TAG_RE, "").trim();
|
|
4675
|
-
}
|
|
4676
|
-
var LAMBDA_LOG_PREFIX_RE, DD_TAG_RE;
|
|
4677
4254
|
var init_strip_lambda_log_prefix = __esm({
|
|
4678
4255
|
"packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/edsi-errors/strip-lambda-log-prefix.js"() {
|
|
4679
4256
|
"use strict";
|
|
4680
|
-
LAMBDA_LOG_PREFIX_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z\s+[0-9a-f-]+\s+ERROR\s+(?:\[dd\.[^\]]*\]\s*)?/;
|
|
4681
|
-
DD_TAG_RE = /\[dd\.(?:trace_id|span_id)=[^\]]*\]\s*/g;
|
|
4682
4257
|
}
|
|
4683
4258
|
});
|
|
4684
4259
|
|
|
4685
4260
|
// packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/edsi-errors/parse-edsi-error.js
|
|
4686
|
-
function parseEdsiError(rawInput) {
|
|
4687
|
-
if (!rawInput)
|
|
4688
|
-
return { code: null, message: "", cycle: null, raw: true };
|
|
4689
|
-
const { body, prefix } = splitPhasePrefix(rawInput);
|
|
4690
|
-
const cleaned = stripLambdaLogPrefix(body);
|
|
4691
|
-
const json = parseJsonBody(cleaned) ?? parseJsonBody(body);
|
|
4692
|
-
const bindingFromJson = typeof json?.message === "string" ? parseBindingDiagnostics(json.message) : null;
|
|
4693
|
-
if (bindingFromJson) {
|
|
4694
|
-
return {
|
|
4695
|
-
code: bindingFromJson.code ?? json?.code ?? null,
|
|
4696
|
-
message: bindingFromJson.message ?? cleaned,
|
|
4697
|
-
cycle: null,
|
|
4698
|
-
raw: false,
|
|
4699
|
-
...bindingFromJson.diagnostics ? { diagnostics: bindingFromJson.diagnostics } : {}
|
|
4700
|
-
};
|
|
4701
|
-
}
|
|
4702
|
-
if (json && (json.code || json.message || json.cycle)) {
|
|
4703
|
-
return {
|
|
4704
|
-
code: json.code ?? null,
|
|
4705
|
-
message: json.message ?? (cleaned || prefix),
|
|
4706
|
-
cycle: json.cycle ?? null,
|
|
4707
|
-
raw: false,
|
|
4708
|
-
...json.diagnostics ? { diagnostics: json.diagnostics } : {}
|
|
4709
|
-
};
|
|
4710
|
-
}
|
|
4711
|
-
const binding = parseBindingDiagnostics(cleaned);
|
|
4712
|
-
if (binding) {
|
|
4713
|
-
return {
|
|
4714
|
-
code: binding.code ?? null,
|
|
4715
|
-
message: binding.message ?? cleaned,
|
|
4716
|
-
cycle: null,
|
|
4717
|
-
raw: false,
|
|
4718
|
-
...binding.diagnostics ? { diagnostics: binding.diagnostics } : {}
|
|
4719
|
-
};
|
|
4720
|
-
}
|
|
4721
|
-
const literal2 = parseObjectLiteralTail(cleaned);
|
|
4722
|
-
if (literal2 && (literal2.code || literal2.cycle)) {
|
|
4723
|
-
const braceStart = cleaned.lastIndexOf("{");
|
|
4724
|
-
const head = braceStart === -1 ? cleaned : cleaned.slice(0, braceStart).trim();
|
|
4725
|
-
return { code: literal2.code ?? null, message: head || cleaned, cycle: literal2.cycle ?? null, raw: false };
|
|
4726
|
-
}
|
|
4727
|
-
return { code: null, message: cleaned || prefix || rawInput, cycle: null, raw: true };
|
|
4728
|
-
}
|
|
4729
|
-
function splitPhasePrefix(input) {
|
|
4730
|
-
const nlIndex = input.indexOf("\n");
|
|
4731
|
-
if (nlIndex === -1)
|
|
4732
|
-
return { body: input, prefix: "" };
|
|
4733
|
-
const firstLine = input.slice(0, nlIndex);
|
|
4734
|
-
if (!API_ERROR_PREFIX_RE.test(firstLine))
|
|
4735
|
-
return { body: input, prefix: "" };
|
|
4736
|
-
return { body: input.slice(nlIndex + 1), prefix: firstLine };
|
|
4737
|
-
}
|
|
4738
|
-
var API_ERROR_PREFIX_RE;
|
|
4739
4261
|
var init_parse_edsi_error = __esm({
|
|
4740
4262
|
"packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/edsi-errors/parse-edsi-error.js"() {
|
|
4741
4263
|
"use strict";
|
|
@@ -4743,51 +4265,10 @@ var init_parse_edsi_error = __esm({
|
|
|
4743
4265
|
init_parse_json_body();
|
|
4744
4266
|
init_helpers3();
|
|
4745
4267
|
init_strip_lambda_log_prefix();
|
|
4746
|
-
API_ERROR_PREFIX_RE = /^(?:apply|preview|poll) failed: \d+$/;
|
|
4747
4268
|
}
|
|
4748
4269
|
});
|
|
4749
4270
|
|
|
4750
4271
|
// packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/edsi-errors/format-parsed-edsi-error.js
|
|
4751
|
-
function formatParsedEdsiError(parsed, opts = {}) {
|
|
4752
|
-
const lines = [];
|
|
4753
|
-
if (parsed.code)
|
|
4754
|
-
lines.push(`[${parsed.code}]`);
|
|
4755
|
-
if (parsed.message)
|
|
4756
|
-
lines.push(parsed.message);
|
|
4757
|
-
for (const diagnostic of parsed.diagnostics ?? []) {
|
|
4758
|
-
const context = [
|
|
4759
|
-
diagnostic.component ? `Component: ${diagnostic.component}` : null,
|
|
4760
|
-
diagnostic.path ? `Path: ${diagnostic.path}` : null
|
|
4761
|
-
].filter(Boolean);
|
|
4762
|
-
lines.push(`- ${diagnostic.message}${context.length > 0 ? ` (${context.join("; ")})` : ""}`);
|
|
4763
|
-
if (diagnostic.path === null) {
|
|
4764
|
-
lines.push(" Location: not provided by the server. Review the submitted CDF file; no component or field was identified.");
|
|
4765
|
-
}
|
|
4766
|
-
if (opts.verbose && diagnostic.messageSource) {
|
|
4767
|
-
lines.push(` Message field: ${diagnostic.messageSource}`);
|
|
4768
|
-
}
|
|
4769
|
-
}
|
|
4770
|
-
if (parsed.code === "BindingValidationFailed") {
|
|
4771
|
-
const location = parsed.diagnostics?.find((d) => d.path)?.path;
|
|
4772
|
-
lines.push(location ? `Next action: review the binding at ${location} and correct its pointer or GraphQL selection.` : "Next action: review the binding pointer and GraphQL selection.");
|
|
4773
|
-
}
|
|
4774
|
-
if (parsed.code === "AccessDenied") {
|
|
4775
|
-
lines.push("Next action: this operation requires DesignToken and Component permissions in this environment. Ask a Contentful admin to grant both on your role.");
|
|
4776
|
-
}
|
|
4777
|
-
if (parsed.code === "NotFound") {
|
|
4778
|
-
lines.push("Next action: verify the resource id is correct. If it should exist, your role may lack read permission on DesignToken or Component.");
|
|
4779
|
-
}
|
|
4780
|
-
if (parsed.cycle && parsed.cycle.length > 0) {
|
|
4781
|
-
lines.push(`Cycle: ${parsed.cycle.join(" \u2192 ")} \u2192 ${parsed.cycle[0]}`);
|
|
4782
|
-
lines.push("Break the cycle by removing at least one $allowedComponents entry.");
|
|
4783
|
-
}
|
|
4784
|
-
if (opts.verbose && opts.raw) {
|
|
4785
|
-
lines.push("");
|
|
4786
|
-
lines.push("--- raw ---");
|
|
4787
|
-
lines.push(opts.raw);
|
|
4788
|
-
}
|
|
4789
|
-
return lines.filter(Boolean).join("\n");
|
|
4790
|
-
}
|
|
4791
4272
|
var init_format_parsed_edsi_error = __esm({
|
|
4792
4273
|
"packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/edsi-errors/format-parsed-edsi-error.js"() {
|
|
4793
4274
|
"use strict";
|
|
@@ -4795,12 +4276,6 @@ var init_format_parsed_edsi_error = __esm({
|
|
|
4795
4276
|
});
|
|
4796
4277
|
|
|
4797
4278
|
// packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/edsi-errors/format-edsi-error.js
|
|
4798
|
-
function formatEdsiError(raw, opts = {}) {
|
|
4799
|
-
const input = typeof raw === "string" ? raw : displayValue(raw);
|
|
4800
|
-
if (!input)
|
|
4801
|
-
return "";
|
|
4802
|
-
return formatParsedEdsiError(parseEdsiError(input), { ...opts, raw: opts.raw ?? input });
|
|
4803
|
-
}
|
|
4804
4279
|
var init_format_edsi_error = __esm({
|
|
4805
4280
|
"packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/edsi-errors/format-edsi-error.js"() {
|
|
4806
4281
|
"use strict";
|
|
@@ -4811,14 +4286,6 @@ var init_format_edsi_error = __esm({
|
|
|
4811
4286
|
});
|
|
4812
4287
|
|
|
4813
4288
|
// packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/edsi-errors/format-api-error.js
|
|
4814
|
-
function formatApiError(error, verbose = false) {
|
|
4815
|
-
const formatted = formatEdsiError(error.body || error.message, { verbose, raw: error.body }) || error.message;
|
|
4816
|
-
const phase = error.message.split("\n", 1)[0];
|
|
4817
|
-
const withPhase = /^(?:apply|preview|poll) failed: \d+$/.test(phase) && formatted !== phase ? `${phase}
|
|
4818
|
-
${formatted}` : formatted;
|
|
4819
|
-
return error.guidance ? `${withPhase}
|
|
4820
|
-
${error.guidance}` : withPhase;
|
|
4821
|
-
}
|
|
4822
4289
|
var init_format_api_error = __esm({
|
|
4823
4290
|
"packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/helpers/edsi-errors/format-api-error.js"() {
|
|
4824
4291
|
"use strict";
|
|
@@ -4855,9 +4322,6 @@ var init_format_edsi_error2 = __esm({
|
|
|
4855
4322
|
});
|
|
4856
4323
|
|
|
4857
4324
|
// packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/controller/errors/format-api-error.js
|
|
4858
|
-
function formatApiError2(request) {
|
|
4859
|
-
return formatApiError(request.error, request.verbose ?? false);
|
|
4860
|
-
}
|
|
4861
4325
|
var init_format_api_error2 = __esm({
|
|
4862
4326
|
"packages/experience-design-system-backend-pipeline/dist/src/steps/apply/src/controller/errors/format-api-error.js"() {
|
|
4863
4327
|
"use strict";
|
|
@@ -5367,12 +4831,21 @@ function keyAction2(input, key) {
|
|
|
5367
4831
|
function nextField(field) {
|
|
5368
4832
|
return FIELDS[(FIELDS.indexOf(field) + 1) % FIELDS.length];
|
|
5369
4833
|
}
|
|
4834
|
+
function toConfiguredHost3(host) {
|
|
4835
|
+
const value = (host ?? "").trim().replace(/\/+$/, "");
|
|
4836
|
+
return value === "" ? DEFAULT_HOST : value.replace(/^https:\/\//i, "");
|
|
4837
|
+
}
|
|
4838
|
+
function toApiHost3(host) {
|
|
4839
|
+
const value = host.trim().replace(/\/+$/, "");
|
|
4840
|
+
if (value === "") return `https://${DEFAULT_HOST}`;
|
|
4841
|
+
return /^[a-z][a-z\d+\-.]*:\/\//i.test(value) ? value : `https://${value}`;
|
|
4842
|
+
}
|
|
5370
4843
|
function normalize(values) {
|
|
5371
4844
|
return {
|
|
5372
4845
|
spaceId: values.spaceId.trim(),
|
|
5373
4846
|
environmentId: values.environmentId.trim(),
|
|
5374
4847
|
cmaToken: values.cmaToken.trim(),
|
|
5375
|
-
host:
|
|
4848
|
+
host: toConfiguredHost3(values.host)
|
|
5376
4849
|
};
|
|
5377
4850
|
}
|
|
5378
4851
|
function missingField(values) {
|
|
@@ -5381,12 +4854,12 @@ function missingField(values) {
|
|
|
5381
4854
|
function isUnchanged(current, initial) {
|
|
5382
4855
|
return FIELDS.every((field) => current[field] === initial[field]);
|
|
5383
4856
|
}
|
|
5384
|
-
var FIELDS;
|
|
4857
|
+
var FIELDS, DEFAULT_HOST;
|
|
5385
4858
|
var init_logic4 = __esm({
|
|
5386
4859
|
"packages/experience-design-system-cli/src/tui/import/steps/04-credentials/logic.ts"() {
|
|
5387
4860
|
"use strict";
|
|
5388
|
-
init_src3();
|
|
5389
4861
|
FIELDS = ["spaceId", "environmentId", "cmaToken", "host"];
|
|
4862
|
+
DEFAULT_HOST = "api.contentful.com";
|
|
5390
4863
|
}
|
|
5391
4864
|
});
|
|
5392
4865
|
|
|
@@ -5416,35 +4889,65 @@ var init_controls4 = __esm({
|
|
|
5416
4889
|
});
|
|
5417
4890
|
|
|
5418
4891
|
// packages/experience-design-system-cli/src/tui/import/steps/04-credentials/validate.ts
|
|
4892
|
+
function headers(token) {
|
|
4893
|
+
return { Authorization: `Bearer ${token}`, "X-Contentful-User-Agent": USER_AGENT2 };
|
|
4894
|
+
}
|
|
4895
|
+
function isApsDenial(body) {
|
|
4896
|
+
try {
|
|
4897
|
+
const id = JSON.parse(body).sys?.id;
|
|
4898
|
+
return id === "NotFound" || id === "AccessDenied";
|
|
4899
|
+
} catch {
|
|
4900
|
+
return false;
|
|
4901
|
+
}
|
|
4902
|
+
}
|
|
4903
|
+
function messageFrom(body) {
|
|
4904
|
+
try {
|
|
4905
|
+
const message = JSON.parse(body).message;
|
|
4906
|
+
return typeof message === "string" && message !== "" ? message : void 0;
|
|
4907
|
+
} catch {
|
|
4908
|
+
return void 0;
|
|
4909
|
+
}
|
|
4910
|
+
}
|
|
5419
4911
|
async function validateCredentials(values) {
|
|
5420
|
-
const
|
|
5421
|
-
|
|
5422
|
-
host,
|
|
5423
|
-
spaceId: values.spaceId,
|
|
5424
|
-
environmentId: values.environmentId,
|
|
5425
|
-
cmaToken: values.cmaToken
|
|
5426
|
-
});
|
|
4912
|
+
const base = toApiHost3(values.host);
|
|
4913
|
+
let me;
|
|
5427
4914
|
try {
|
|
5428
|
-
await
|
|
5429
|
-
return { ok: true };
|
|
4915
|
+
me = await fetch(`${base}/users/me`, { headers: headers(values.cmaToken) });
|
|
5430
4916
|
} catch (error) {
|
|
5431
|
-
return { ok: false, error:
|
|
4917
|
+
return { ok: false, error: `Could not reach ${base}: ${error instanceof Error ? error.message : String(error)}` };
|
|
5432
4918
|
}
|
|
5433
|
-
}
|
|
5434
|
-
|
|
5435
|
-
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
|
|
4919
|
+
if (me.status === 401) return { ok: false, error: "CMA token is invalid or revoked." };
|
|
4920
|
+
if (!me.ok) return { ok: false, error: `Unexpected error validating the token (${me.status}).` };
|
|
4921
|
+
let preflight;
|
|
4922
|
+
try {
|
|
4923
|
+
preflight = await fetch(
|
|
4924
|
+
`${base}/spaces/${values.spaceId}/environments/${values.environmentId}/design_systems/preflight`,
|
|
4925
|
+
{ headers: headers(values.cmaToken) }
|
|
4926
|
+
);
|
|
4927
|
+
} catch {
|
|
4928
|
+
return { ok: true };
|
|
5440
4929
|
}
|
|
5441
|
-
if (
|
|
5442
|
-
|
|
4930
|
+
if (preflight.ok || preflight.status >= 500) return { ok: true };
|
|
4931
|
+
const body = await preflight.text();
|
|
4932
|
+
if (preflight.status === 404 && !isApsDenial(body)) return { ok: true };
|
|
4933
|
+
const detail = messageFrom(body);
|
|
4934
|
+
if (preflight.status === 403) {
|
|
4935
|
+
return { ok: false, error: `Access denied. ${detail ?? "Your token cannot write design system components here."}` };
|
|
4936
|
+
}
|
|
4937
|
+
if (preflight.status === 404) {
|
|
4938
|
+
return {
|
|
4939
|
+
ok: false,
|
|
4940
|
+
error: `Not found. Check the space ID, environment and API host.${detail ? ` (${detail})` : ""}`
|
|
4941
|
+
};
|
|
4942
|
+
}
|
|
4943
|
+
return { ok: false, error: `Credential check failed (${preflight.status}).${detail ? ` ${detail}` : ""}` };
|
|
5443
4944
|
}
|
|
4945
|
+
var USER_AGENT2;
|
|
5444
4946
|
var init_validate4 = __esm({
|
|
5445
4947
|
"packages/experience-design-system-cli/src/tui/import/steps/04-credentials/validate.ts"() {
|
|
5446
4948
|
"use strict";
|
|
5447
|
-
|
|
4949
|
+
init_logic4();
|
|
4950
|
+
USER_AGENT2 = "app contentful.experience-design-system-cli";
|
|
5448
4951
|
}
|
|
5449
4952
|
});
|
|
5450
4953
|
|
|
@@ -5519,7 +5022,7 @@ function CredentialsScreen({
|
|
|
5519
5022
|
value: values[field],
|
|
5520
5023
|
focus: active === field && !validating,
|
|
5521
5024
|
mask: field === "cmaToken" ? "\u2022" : void 0,
|
|
5522
|
-
placeholder: field === "host" ?
|
|
5025
|
+
placeholder: field === "host" ? DEFAULT_HOST : void 0,
|
|
5523
5026
|
onChange: change(field),
|
|
5524
5027
|
onSubmit: () => void submit(field)
|
|
5525
5028
|
}
|
|
@@ -5546,7 +5049,6 @@ var init_screen4 = __esm({
|
|
|
5546
5049
|
"use strict";
|
|
5547
5050
|
init_home_theme();
|
|
5548
5051
|
init_controls4();
|
|
5549
|
-
init_src3();
|
|
5550
5052
|
init_logic4();
|
|
5551
5053
|
init_validate4();
|
|
5552
5054
|
LABELS = {
|
|
@@ -5579,6 +5081,7 @@ function buildArgs2(options) {
|
|
|
5579
5081
|
if (options.tokens) {
|
|
5580
5082
|
args.push("--tokens", options.tokens);
|
|
5581
5083
|
}
|
|
5084
|
+
args.push(...importOptionArgs({ agent: options.agent, prompt: options.prompt ?? [], cache: options.cache ?? true }));
|
|
5582
5085
|
return args;
|
|
5583
5086
|
}
|
|
5584
5087
|
async function spawnV1Import(options = {}) {
|
|
@@ -5601,6 +5104,7 @@ var init_spawn_v1_import = __esm({
|
|
|
5601
5104
|
"packages/experience-design-system-cli/src/tui/import/spawn-v1-import.ts"() {
|
|
5602
5105
|
"use strict";
|
|
5603
5106
|
init_legacy_cli_path();
|
|
5107
|
+
init_import_options();
|
|
5604
5108
|
}
|
|
5605
5109
|
});
|
|
5606
5110
|
|
|
@@ -6453,7 +5957,7 @@ __export(app_exports, {
|
|
|
6453
5957
|
});
|
|
6454
5958
|
import { useEffect as useEffect9, useState as useState13 } from "react";
|
|
6455
5959
|
import { Fragment as Fragment5, jsx as jsx14 } from "react/jsx-runtime";
|
|
6456
|
-
function App({ onLaunchImport, importExitCode }) {
|
|
5960
|
+
function App({ importOptions, onLaunchImport, importExitCode }) {
|
|
6457
5961
|
const returnedFromImport = importExitCode !== void 0;
|
|
6458
5962
|
const [screen, setScreen] = useState13(returnedFromImport ? "import" : "start");
|
|
6459
5963
|
const [showImportResult, setShowImportResult] = useState13(returnedFromImport);
|
|
@@ -6476,7 +5980,7 @@ function App({ onLaunchImport, importExitCode }) {
|
|
|
6476
5980
|
}, [screen]);
|
|
6477
5981
|
const finishCredentials = async (result, projectPath2, tokens, filePaths) => {
|
|
6478
5982
|
if (!result.skipped) await writeCredentials({ ...result.credentials });
|
|
6479
|
-
onLaunchImport?.({ projectPath: projectPath2, tokens, filePaths, skipCredentials: result.skipped });
|
|
5983
|
+
onLaunchImport?.({ projectPath: projectPath2, tokens, filePaths, skipCredentials: result.skipped, ...importOptions });
|
|
6480
5984
|
};
|
|
6481
5985
|
const goToStart = () => setScreen("start");
|
|
6482
5986
|
const goToSettings = () => setScreen("settings");
|
|
@@ -6546,12 +6050,13 @@ function App({ onLaunchImport, importExitCode }) {
|
|
|
6546
6050
|
return /* @__PURE__ */ jsx14(HomeScreen, { onNavigate: setScreen });
|
|
6547
6051
|
}
|
|
6548
6052
|
}
|
|
6549
|
-
async function renderUntilImportRequestedOrExit(renderApp, importExitCode) {
|
|
6053
|
+
async function renderUntilImportRequestedOrExit(renderApp, importOptions, importExitCode) {
|
|
6550
6054
|
let requestedImport;
|
|
6551
6055
|
const instance = renderApp(
|
|
6552
6056
|
/* @__PURE__ */ jsx14(
|
|
6553
6057
|
App,
|
|
6554
6058
|
{
|
|
6059
|
+
importOptions,
|
|
6555
6060
|
importExitCode,
|
|
6556
6061
|
onLaunchImport: (options) => {
|
|
6557
6062
|
requestedImport = options;
|
|
@@ -6567,13 +6072,13 @@ async function renderUntilImportRequestedOrExit(renderApp, importExitCode) {
|
|
|
6567
6072
|
}
|
|
6568
6073
|
return requestedImport;
|
|
6569
6074
|
}
|
|
6570
|
-
async function runApp(renderApp) {
|
|
6075
|
+
async function runApp(renderApp, importOptions) {
|
|
6571
6076
|
let importExitCode;
|
|
6572
|
-
let requestedImport = await renderUntilImportRequestedOrExit(renderApp, importExitCode);
|
|
6077
|
+
let requestedImport = await renderUntilImportRequestedOrExit(renderApp, importOptions, importExitCode);
|
|
6573
6078
|
while (requestedImport !== void 0) {
|
|
6574
6079
|
importExitCode = (await spawnV1Import(requestedImport)).exitCode;
|
|
6575
6080
|
startReadingTerminal();
|
|
6576
|
-
requestedImport = await renderUntilImportRequestedOrExit(renderApp, importExitCode);
|
|
6081
|
+
requestedImport = await renderUntilImportRequestedOrExit(renderApp, importOptions, importExitCode);
|
|
6577
6082
|
}
|
|
6578
6083
|
}
|
|
6579
6084
|
var CLEAR_SCREEN;
|
|
@@ -6657,6 +6162,9 @@ function forwardedImportArgs(argv) {
|
|
|
6657
6162
|
return argv[0] === "import" ? argv.slice(1) : argv;
|
|
6658
6163
|
}
|
|
6659
6164
|
|
|
6165
|
+
// packages/experience-design-system-cli/src/commands/import.ts
|
|
6166
|
+
init_import_options();
|
|
6167
|
+
|
|
6660
6168
|
// packages/experience-design-system-cli/src/commands/watch.ts
|
|
6661
6169
|
init_package_root();
|
|
6662
6170
|
import { spawn as spawn2 } from "node:child_process";
|
|
@@ -6687,12 +6195,17 @@ function runDevWatch(args) {
|
|
|
6687
6195
|
|
|
6688
6196
|
// packages/experience-design-system-cli/src/commands/import.ts
|
|
6689
6197
|
function registerImportCommand(program, openTui) {
|
|
6690
|
-
program.command("import", { isDefault: true }).description("Launch the Experiences CLI").allowUnknownOption().allowExcessArguments().helpOption(false).argument("[args...]").
|
|
6198
|
+
program.command("import", { isDefault: true }).description("Launch the Experiences CLI").allowUnknownOption().allowExcessArguments().helpOption(false).argument("[args...]").option("--agent <name>", "Agent (or agent:model) the import runs its steps with").option(
|
|
6199
|
+
"--prompt <stage=value>",
|
|
6200
|
+
"Override a stage prompt (repeatable): a file path or literal text, e.g. --prompt select=./p.md",
|
|
6201
|
+
(value, previous) => [...previous, value],
|
|
6202
|
+
[]
|
|
6203
|
+
).option("--no-cache", "Re-run every step even if its output already exists").action(async (_args, raw) => {
|
|
6691
6204
|
const { watch, rest: forwarded } = extractWatchFlag(forwardedImportArgs(process.argv.slice(2)));
|
|
6692
6205
|
if (watch) {
|
|
6693
6206
|
process.exit(await runDevWatch(forwarded));
|
|
6694
6207
|
}
|
|
6695
|
-
await openTui();
|
|
6208
|
+
await openTui(toImportOptions(raw));
|
|
6696
6209
|
});
|
|
6697
6210
|
}
|
|
6698
6211
|
|
|
@@ -6706,10 +6219,10 @@ var pkg = JSON.parse(
|
|
|
6706
6219
|
);
|
|
6707
6220
|
function createProgram() {
|
|
6708
6221
|
const program = new Command().name("experiences").description("Contentful Experiences design system import CLI").version(pkg.version, "--version", "Print version number");
|
|
6709
|
-
registerImportCommand(program, async () => {
|
|
6222
|
+
registerImportCommand(program, async (options) => {
|
|
6710
6223
|
const { render } = await import("ink");
|
|
6711
6224
|
const { runApp: runApp2 } = await Promise.resolve().then(() => (init_app(), app_exports));
|
|
6712
|
-
await runApp2(render);
|
|
6225
|
+
await runApp2(render, options);
|
|
6713
6226
|
});
|
|
6714
6227
|
registerForwardedCommands(program);
|
|
6715
6228
|
return program;
|