@contentful/experience-design-system-cli 2.20.1-dev-build-11e15ac.0 → 2.20.1-dev-build-52daaec.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
CHANGED
|
@@ -50,6 +50,7 @@ export declare class ImportApiClient {
|
|
|
50
50
|
private headers;
|
|
51
51
|
private requestWithRetry;
|
|
52
52
|
validateToken(): Promise<void>;
|
|
53
|
+
checkPreflight(): Promise<void>;
|
|
53
54
|
previewImport(manifest: ManifestPayload): Promise<ServerPreviewResponse>;
|
|
54
55
|
applyImport(manifest: ManifestPayload, acknowledgeBreakingChanges: boolean): Promise<ApplyOperationResponse>;
|
|
55
56
|
pollOperation(operationId: string, opts?: {
|
|
@@ -148,6 +148,18 @@ function sanitizePreviewResponse(res) {
|
|
|
148
148
|
}
|
|
149
149
|
return res;
|
|
150
150
|
}
|
|
151
|
+
function isApsDenialBody(body) {
|
|
152
|
+
if (!body)
|
|
153
|
+
return false;
|
|
154
|
+
try {
|
|
155
|
+
const parsed = JSON.parse(body);
|
|
156
|
+
const id = parsed?.sys?.id;
|
|
157
|
+
return id === 'NotFound' || id === 'AccessDenied';
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
151
163
|
async function request(url, options) {
|
|
152
164
|
const headers = {
|
|
153
165
|
Authorization: `Bearer ${options.token}`,
|
|
@@ -267,6 +279,33 @@ export class ImportApiClient {
|
|
|
267
279
|
if (!res.ok) {
|
|
268
280
|
throw new ApiError(`unexpected error validating token: ${res.status}`, res.status, await res.text());
|
|
269
281
|
}
|
|
282
|
+
await this.checkPreflight();
|
|
283
|
+
}
|
|
284
|
+
// Probe the sources-api preflight endpoint to catch APS-denied users up-front,
|
|
285
|
+
// rather than letting them run a full apply flow that only fails at the write.
|
|
286
|
+
// The endpoint gates Component + DesignToken permissions and returns:
|
|
287
|
+
// 200 → user has apply permissions, proceed
|
|
288
|
+
// 403 { sys.id: AccessDenied } → user lacks write; surface via error-parser
|
|
289
|
+
// 404 { sys.id: NotFound } → user lacks read (APS hides existence)
|
|
290
|
+
// 404 without a NotFound envelope → older backend deployment; treat as pass
|
|
291
|
+
// 5xx / network → backend flake; treat as pass, do not block
|
|
292
|
+
async checkPreflight() {
|
|
293
|
+
const url = `${this.host}/spaces/${this.spaceId}/environments/${this.environmentId}/design_systems/preflight`;
|
|
294
|
+
let res;
|
|
295
|
+
try {
|
|
296
|
+
res = await request(url, { token: this.token });
|
|
297
|
+
}
|
|
298
|
+
catch {
|
|
299
|
+
return; // network error — don't block; the real call will surface it
|
|
300
|
+
}
|
|
301
|
+
if (res.ok)
|
|
302
|
+
return;
|
|
303
|
+
if (res.status >= 500)
|
|
304
|
+
return; // backend flake — don't block
|
|
305
|
+
const body = await res.text();
|
|
306
|
+
if (res.status === 404 && !isApsDenialBody(body))
|
|
307
|
+
return; // legacy backend without the endpoint
|
|
308
|
+
throw new ApiError(`preflight failed: ${res.status}`, res.status, body);
|
|
270
309
|
}
|
|
271
310
|
async previewImport(manifest) {
|
|
272
311
|
const debug = getDebugLogger();
|
|
@@ -747,9 +747,13 @@ export function WizardApp({ initialSpaceId = '', initialEnvironmentId = 'master'
|
|
|
747
747
|
await advanceAfterCredentialsValidated();
|
|
748
748
|
}
|
|
749
749
|
catch (e) {
|
|
750
|
-
if (e instanceof ApiError && (e.status === 401 || e.status === 403)) {
|
|
750
|
+
if (e instanceof ApiError && (e.status === 401 || e.status === 403 || e.status === 404)) {
|
|
751
751
|
cancelGeneratePrefetch();
|
|
752
|
-
update({
|
|
752
|
+
update({
|
|
753
|
+
step: 'credentials',
|
|
754
|
+
credentialsValidating: false,
|
|
755
|
+
credentialsError: formatApiError(e, process.env['EDSI_VERBOSE_ERRORS'] === '1'),
|
|
756
|
+
});
|
|
753
757
|
return;
|
|
754
758
|
}
|
|
755
759
|
const msg = e instanceof Error ? e.message : 'Credential check failed';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/experience-design-system-cli",
|
|
3
|
-
"version": "2.20.1-dev-build-
|
|
3
|
+
"version": "2.20.1-dev-build-52daaec.0",
|
|
4
4
|
"description": "Contentful Experiences design system import CLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
"react": "^18.3.1",
|
|
34
34
|
"react-devtools-core": "^4.19.1",
|
|
35
35
|
"react-dom": "^18.3.1",
|
|
36
|
-
"@contentful/experience-design-system-client": "2.20.1-dev-build-
|
|
37
|
-
"@contentful/experience-design-system-
|
|
38
|
-
"@contentful/experience-design-system-
|
|
39
|
-
"@contentful/experience-design-system-
|
|
36
|
+
"@contentful/experience-design-system-client": "2.20.1-dev-build-52daaec.0",
|
|
37
|
+
"@contentful/experience-design-system-extraction": "2.20.1-dev-build-52daaec.0",
|
|
38
|
+
"@contentful/experience-design-system-generation": "2.20.1-dev-build-52daaec.0",
|
|
39
|
+
"@contentful/experience-design-system-types": "2.20.1-dev-build-52daaec.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@tsconfig/node24": "^24.0.4",
|