@payloadcms/figma 0.0.1-alpha.58 → 0.0.1-alpha.59
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/api/control-plane.d.ts +8 -7
- package/dist/api/control-plane.js +16 -23
- package/dist/api/figma-api.d.ts +3 -2
- package/dist/api/figma-api.js +6 -9
- package/dist/auth/credentials.d.ts +21 -0
- package/dist/auth/credentials.js +21 -0
- package/dist/auth/oauth-flow.d.ts +13 -4
- package/dist/auth/oauth-flow.js +34 -8
- package/dist/auth/project-token.js +5 -5
- package/dist/cli.js +5 -0
- package/dist/commands/deploy.d.ts +3 -0
- package/dist/commands/deploy.js +67 -37
- package/dist/commands/env.js +4 -4
- package/dist/commands/init.js +8 -8
- package/dist/commands/login.js +3 -3
- package/dist/commands/upgrade.js +11 -11
- package/dist/db-content-api/index.js +48 -11
- package/dist/db-content-api/temp-utilities/sorting.d.ts +1 -1
- package/dist/db-content-api/temp-utilities/sorting.js +4 -1
- package/dist/db-content-api/temp-utilities/unwrapDocument.d.ts +7 -2
- package/dist/db-content-api/temp-utilities/unwrapDocument.js +11 -5
- package/dist/db-content-api/utilities/data/castFieldValue.js +11 -12
- package/dist/db-content-api/utilities/data/index.d.ts +1 -1
- package/dist/db-content-api/utilities/data/index.js +45 -20
- package/dist/db-content-api/utilities/joins.js +10 -4
- package/dist/db-content-api/utilities/meta/buildLocalizedPaths.js +14 -6
- package/dist/db-content-api/utilities/meta/buildPathTypes.js +19 -2
- package/dist/db-content-api/utilities/where.js +15 -45
- package/dist/oauth/endpoints/getLoginEndpoint.js +10 -2
- package/dist/oauth/utilities/refreshTokens.js +4 -1
- package/dist/plugin/build-config.js +4 -4
- package/dist/utils/adapters/nextjs.d.ts +9 -0
- package/dist/utils/adapters/nextjs.js +59 -0
- package/dist/utils/adapters/nitro.d.ts +9 -0
- package/dist/utils/adapters/nitro.js +164 -0
- package/dist/utils/adapters/vite.d.ts +10 -0
- package/dist/utils/adapters/vite.js +32 -0
- package/dist/utils/asset-collection.d.ts +24 -0
- package/dist/utils/asset-collection.js +53 -0
- package/dist/utils/build-detection.d.ts +5 -11
- package/dist/utils/build-detection.js +74 -11
- package/dist/utils/deploy-adapter.d.ts +38 -0
- package/dist/utils/deploy-adapter.js +58 -0
- package/dist/utils/fs-utils.d.ts +6 -0
- package/dist/utils/fs-utils.js +27 -0
- package/dist/utils/s3-upload.d.ts +7 -1
- package/dist/utils/s3-upload.js +4 -3
- package/package.json +1 -1
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* TODO: Replace with real API calls when Control Plane is available
|
|
5
5
|
*/
|
|
6
|
+
import type { AuthCredential } from '../auth/credentials.js';
|
|
6
7
|
import type { Tenant } from '../types/config.js';
|
|
7
8
|
/**
|
|
8
9
|
* Error thrown when Control Plane API calls fail
|
|
@@ -85,7 +86,7 @@ export interface PerformDeploymentApiResponse {
|
|
|
85
86
|
* @param accessToken - OAuth access token
|
|
86
87
|
* @returns Array of tenant instances
|
|
87
88
|
*/
|
|
88
|
-
export declare function listTenants(
|
|
89
|
+
export declare function listTenants(credential: AuthCredential): Promise<Tenant[]>;
|
|
89
90
|
/**
|
|
90
91
|
* Create a new tenant instance
|
|
91
92
|
* Maps to: POST /v1/tenant
|
|
@@ -94,7 +95,7 @@ export declare function listTenants(accessToken: string): Promise<Tenant[]>;
|
|
|
94
95
|
* @param options - Tenant creation options
|
|
95
96
|
* @returns Newly created tenant
|
|
96
97
|
*/
|
|
97
|
-
export declare function createTenant(
|
|
98
|
+
export declare function createTenant(credential: AuthCredential, options: CreateTenantOptions): Promise<Tenant>;
|
|
98
99
|
/**
|
|
99
100
|
* Get details for a specific tenant
|
|
100
101
|
* Maps to: GET /v1/tenant/{tenant_id}
|
|
@@ -103,7 +104,7 @@ export declare function createTenant(accessToken: string, options: CreateTenantO
|
|
|
103
104
|
* @param tenantId - Tenant ID
|
|
104
105
|
* @returns Tenant details
|
|
105
106
|
*/
|
|
106
|
-
export declare function getTenantDetails(
|
|
107
|
+
export declare function getTenantDetails(credential: AuthCredential, tenantId: string): Promise<Tenant>;
|
|
107
108
|
/**
|
|
108
109
|
* Create a new deployment and get signed upload URLs
|
|
109
110
|
* Maps to: POST /v1/tenant/{tenant_id}/deploy/create
|
|
@@ -113,7 +114,7 @@ export declare function getTenantDetails(accessToken: string, tenantId: string):
|
|
|
113
114
|
* @param options - Deployment creation options
|
|
114
115
|
* @returns Deployment ID and upload URLs
|
|
115
116
|
*/
|
|
116
|
-
export declare function createDeployment(
|
|
117
|
+
export declare function createDeployment(credential: AuthCredential, tenantId: string, options: CreateDeploymentOptions): Promise<CreateDeploymentResponse>;
|
|
117
118
|
/**
|
|
118
119
|
* Perform deployment for a created deployment ID
|
|
119
120
|
* Maps to: POST /v1/tenant/{tenant_id}/deploy/perform
|
|
@@ -123,7 +124,7 @@ export declare function createDeployment(accessToken: string, tenantId: string,
|
|
|
123
124
|
* @param options - Deployment perform options
|
|
124
125
|
* @returns Deployment status and message
|
|
125
126
|
*/
|
|
126
|
-
export declare function performDeployment(
|
|
127
|
+
export declare function performDeployment(credential: AuthCredential, tenantId: string, options: PerformDeploymentOptions): Promise<PerformDeploymentResponse>;
|
|
127
128
|
/**
|
|
128
129
|
* A single environment returned by the bootstrap endpoint
|
|
129
130
|
*/
|
|
@@ -150,7 +151,7 @@ export type BootstrapInfo = {
|
|
|
150
151
|
* @param cmsResourceId - CMS Resource ID (project ID)
|
|
151
152
|
* @param environmentName - Optional environment name filter
|
|
152
153
|
*/
|
|
153
|
-
export declare function getBootstrapInfo(
|
|
154
|
+
export declare function getBootstrapInfo(credential: AuthCredential, cmsResourceId: string, environmentName?: string): Promise<BootstrapInfo>;
|
|
154
155
|
/**
|
|
155
156
|
* Resolve a CMS Resource ID from a legacy dataset (content system) ID.
|
|
156
157
|
* Maps to: GET /v1/cms/dataset/:datasetId
|
|
@@ -158,5 +159,5 @@ export declare function getBootstrapInfo(accessToken: string, cmsResourceId: str
|
|
|
158
159
|
* Used during upgrade migration to convert old FIGMA_CONTENT_API_CONTENT_SYSTEM_ID
|
|
159
160
|
* into the new FIGMA_PROJECT_ID (CMS Resource ID).
|
|
160
161
|
*/
|
|
161
|
-
export declare function getCmsResourceId(
|
|
162
|
+
export declare function getCmsResourceId(credential: AuthCredential, datasetId: string): Promise<string>;
|
|
162
163
|
//# sourceMappingURL=control-plane.d.ts.map
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* Control Plane API Client
|
|
3
3
|
*
|
|
4
4
|
* TODO: Replace with real API calls when Control Plane is available
|
|
5
|
-
*/ import {
|
|
5
|
+
*/ import { getAuthHeaders } from '../auth/credentials.js';
|
|
6
|
+
import { getEnvConfig } from '../constants.js';
|
|
6
7
|
import * as log from '../utils/log.js';
|
|
7
8
|
/**
|
|
8
9
|
* Get the Control Plane API base URL based on environment
|
|
@@ -25,7 +26,7 @@ import * as log from '../utils/log.js';
|
|
|
25
26
|
*
|
|
26
27
|
* @param accessToken - OAuth access token
|
|
27
28
|
* @returns Array of tenant instances
|
|
28
|
-
*/ export async function listTenants(
|
|
29
|
+
*/ export async function listTenants(credential) {
|
|
29
30
|
const shouldMock = process.env.FIGMA_MOCK_CONTROL_PLANE === 'true';
|
|
30
31
|
if (shouldMock) {
|
|
31
32
|
// MOCK IMPLEMENTATION: Return sample tenants for testing
|
|
@@ -53,9 +54,7 @@ import * as log from '../utils/log.js';
|
|
|
53
54
|
const response = await controlPlaneFetch({
|
|
54
55
|
context: 'list tenants',
|
|
55
56
|
options: {
|
|
56
|
-
headers:
|
|
57
|
-
Authorization: `Bearer ${accessToken}`
|
|
58
|
-
}
|
|
57
|
+
headers: getAuthHeaders(credential)
|
|
59
58
|
},
|
|
60
59
|
url: `${getControlPlaneBaseUrl()}/v1/tenant`
|
|
61
60
|
});
|
|
@@ -68,7 +67,7 @@ import * as log from '../utils/log.js';
|
|
|
68
67
|
* @param accessToken - OAuth access token
|
|
69
68
|
* @param options - Tenant creation options
|
|
70
69
|
* @returns Newly created tenant
|
|
71
|
-
*/ export async function createTenant(
|
|
70
|
+
*/ export async function createTenant(credential, options) {
|
|
72
71
|
// Check if control plane API should be mocked
|
|
73
72
|
const shouldMock = process.env.FIGMA_MOCK_CONTROL_PLANE === 'true';
|
|
74
73
|
if (shouldMock) {
|
|
@@ -94,7 +93,7 @@ import * as log from '../utils/log.js';
|
|
|
94
93
|
name: options.name
|
|
95
94
|
}),
|
|
96
95
|
headers: {
|
|
97
|
-
|
|
96
|
+
...getAuthHeaders(credential),
|
|
98
97
|
'Content-Type': 'application/json'
|
|
99
98
|
},
|
|
100
99
|
method: 'POST'
|
|
@@ -110,7 +109,7 @@ import * as log from '../utils/log.js';
|
|
|
110
109
|
* @param accessToken - OAuth access token
|
|
111
110
|
* @param tenantId - Tenant ID
|
|
112
111
|
* @returns Tenant details
|
|
113
|
-
*/ export async function getTenantDetails(
|
|
112
|
+
*/ export async function getTenantDetails(credential, tenantId) {
|
|
114
113
|
// Check if control plane API should be mocked
|
|
115
114
|
const shouldMock = process.env.FIGMA_MOCK_CONTROL_PLANE === 'true';
|
|
116
115
|
if (shouldMock) {
|
|
@@ -129,9 +128,7 @@ import * as log from '../utils/log.js';
|
|
|
129
128
|
const response = await controlPlaneFetch({
|
|
130
129
|
context: 'get tenant details',
|
|
131
130
|
options: {
|
|
132
|
-
headers:
|
|
133
|
-
Authorization: `Bearer ${accessToken}`
|
|
134
|
-
}
|
|
131
|
+
headers: getAuthHeaders(credential)
|
|
135
132
|
},
|
|
136
133
|
url: `${getControlPlaneBaseUrl()}/v1/tenant/${tenantId}`
|
|
137
134
|
});
|
|
@@ -145,7 +142,7 @@ import * as log from '../utils/log.js';
|
|
|
145
142
|
* @param tenantId - Tenant ID
|
|
146
143
|
* @param options - Deployment creation options
|
|
147
144
|
* @returns Deployment ID and upload URLs
|
|
148
|
-
*/ export async function createDeployment(
|
|
145
|
+
*/ export async function createDeployment(credential, tenantId, options) {
|
|
149
146
|
// Check if control plane API should be mocked
|
|
150
147
|
const shouldMock = process.env.FIGMA_MOCK_CONTROL_PLANE === 'true';
|
|
151
148
|
if (shouldMock) {
|
|
@@ -179,7 +176,7 @@ import * as log from '../utils/log.js';
|
|
|
179
176
|
static_assets: options.staticAssets
|
|
180
177
|
}),
|
|
181
178
|
headers: {
|
|
182
|
-
|
|
179
|
+
...getAuthHeaders(credential),
|
|
183
180
|
'Content-Type': 'application/json'
|
|
184
181
|
},
|
|
185
182
|
method: 'POST'
|
|
@@ -202,7 +199,7 @@ import * as log from '../utils/log.js';
|
|
|
202
199
|
* @param tenantId - Tenant ID
|
|
203
200
|
* @param options - Deployment perform options
|
|
204
201
|
* @returns Deployment status and message
|
|
205
|
-
*/ export async function performDeployment(
|
|
202
|
+
*/ export async function performDeployment(credential, tenantId, options) {
|
|
206
203
|
const shouldMock = process.env.FIGMA_MOCK_CONTROL_PLANE === 'true';
|
|
207
204
|
if (shouldMock) {
|
|
208
205
|
// MOCK IMPLEMENTATION: Return mock deployment status
|
|
@@ -225,7 +222,7 @@ import * as log from '../utils/log.js';
|
|
|
225
222
|
deployment_id: options.deploymentId
|
|
226
223
|
}),
|
|
227
224
|
headers: {
|
|
228
|
-
|
|
225
|
+
...getAuthHeaders(credential),
|
|
229
226
|
'Content-Type': 'application/json'
|
|
230
227
|
},
|
|
231
228
|
method: 'POST'
|
|
@@ -247,7 +244,7 @@ import * as log from '../utils/log.js';
|
|
|
247
244
|
* @param accessToken - OAuth access token
|
|
248
245
|
* @param cmsResourceId - CMS Resource ID (project ID)
|
|
249
246
|
* @param environmentName - Optional environment name filter
|
|
250
|
-
*/ export async function getBootstrapInfo(
|
|
247
|
+
*/ export async function getBootstrapInfo(credential, cmsResourceId, environmentName) {
|
|
251
248
|
const baseUrl = getControlPlaneBaseUrl();
|
|
252
249
|
let url = `${baseUrl}/v1/cms/${cmsResourceId}/bootstrap`;
|
|
253
250
|
if (environmentName) {
|
|
@@ -257,9 +254,7 @@ import * as log from '../utils/log.js';
|
|
|
257
254
|
const response = await controlPlaneFetch({
|
|
258
255
|
context: 'get bootstrap info',
|
|
259
256
|
options: {
|
|
260
|
-
headers:
|
|
261
|
-
Authorization: `Bearer ${accessToken}`
|
|
262
|
-
}
|
|
257
|
+
headers: getAuthHeaders(credential)
|
|
263
258
|
},
|
|
264
259
|
url
|
|
265
260
|
});
|
|
@@ -282,15 +277,13 @@ import * as log from '../utils/log.js';
|
|
|
282
277
|
*
|
|
283
278
|
* Used during upgrade migration to convert old FIGMA_CONTENT_API_CONTENT_SYSTEM_ID
|
|
284
279
|
* into the new FIGMA_PROJECT_ID (CMS Resource ID).
|
|
285
|
-
*/ export async function getCmsResourceId(
|
|
280
|
+
*/ export async function getCmsResourceId(credential, datasetId) {
|
|
286
281
|
const url = `${getControlPlaneBaseUrl()}/v1/cms/dataset/${datasetId}`;
|
|
287
282
|
log.debug(`Calling getCmsResourceId API at ${url}`);
|
|
288
283
|
const response = await controlPlaneFetch({
|
|
289
284
|
context: 'get CMS resource ID from dataset',
|
|
290
285
|
options: {
|
|
291
|
-
headers:
|
|
292
|
-
Authorization: `Bearer ${accessToken}`
|
|
293
|
-
}
|
|
286
|
+
headers: getAuthHeaders(credential)
|
|
294
287
|
},
|
|
295
288
|
url
|
|
296
289
|
});
|
package/dist/api/figma-api.d.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Client for Figma REST API (Pixie) endpoints
|
|
5
5
|
* Handles project token generation and other CMS-related API calls
|
|
6
6
|
*/
|
|
7
|
+
import type { AuthCredential } from '../auth/credentials.js';
|
|
7
8
|
import type { ProjectToken } from '../auth/types.js';
|
|
8
9
|
/**
|
|
9
10
|
* User info from Figma API /v1/me endpoint
|
|
@@ -36,7 +37,7 @@ export declare class FigmaApiError extends Error {
|
|
|
36
37
|
* @returns ProjectToken with JWT and expiry information
|
|
37
38
|
* @throws {FigmaApiError} If the API call fails
|
|
38
39
|
*/
|
|
39
|
-
export declare function getProjectToken(
|
|
40
|
+
export declare function getProjectToken(credential: AuthCredential, tenantId: string): Promise<ProjectToken>;
|
|
40
41
|
/**
|
|
41
42
|
* Get user info from Figma API
|
|
42
43
|
*
|
|
@@ -47,5 +48,5 @@ export declare function getProjectToken(accessToken: string, tenantId: string):
|
|
|
47
48
|
* @returns FigmaUserInfo with user profile data
|
|
48
49
|
* @throws {FigmaApiError} If the API call fails
|
|
49
50
|
*/
|
|
50
|
-
export declare function getUserInfo(
|
|
51
|
+
export declare function getUserInfo(credential: AuthCredential): Promise<FigmaUserInfo>;
|
|
51
52
|
//# sourceMappingURL=figma-api.d.ts.map
|
package/dist/api/figma-api.js
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Client for Figma REST API (Pixie) endpoints
|
|
5
5
|
* Handles project token generation and other CMS-related API calls
|
|
6
|
-
*/ import {
|
|
6
|
+
*/ import { getAuthHeaders } from '../auth/credentials.js';
|
|
7
|
+
import { getEnvConfig } from '../constants.js';
|
|
7
8
|
import * as log from '../utils/log.js';
|
|
8
9
|
/**
|
|
9
10
|
* Error thrown when Figma API calls fail
|
|
@@ -28,7 +29,7 @@ import * as log from '../utils/log.js';
|
|
|
28
29
|
* @param tenantId - The tenant/CMS ID
|
|
29
30
|
* @returns ProjectToken with JWT and expiry information
|
|
30
31
|
* @throws {FigmaApiError} If the API call fails
|
|
31
|
-
*/ export async function getProjectToken(
|
|
32
|
+
*/ export async function getProjectToken(credential, tenantId) {
|
|
32
33
|
// Priority 1: Check for direct token value from environment
|
|
33
34
|
const envTokenValue = process.env.FIGMA_MOCK_PROJECT_TOKEN_VALUE;
|
|
34
35
|
if (envTokenValue) {
|
|
@@ -87,9 +88,7 @@ import * as log from '../utils/log.js';
|
|
|
87
88
|
const baseUrl = process.env.FIGMA_API_BASE_URL || getEnvConfig().apiBaseUrl;
|
|
88
89
|
const url = `${baseUrl}/v1/cms/${tenantId}/token/`;
|
|
89
90
|
const response = await fetch(url, {
|
|
90
|
-
headers:
|
|
91
|
-
Authorization: `Bearer ${accessToken}`
|
|
92
|
-
},
|
|
91
|
+
headers: getAuthHeaders(credential),
|
|
93
92
|
method: 'POST'
|
|
94
93
|
});
|
|
95
94
|
if (!response.ok) {
|
|
@@ -197,14 +196,12 @@ import * as log from '../utils/log.js';
|
|
|
197
196
|
* @param accessToken - OAuth access token for authentication
|
|
198
197
|
* @returns FigmaUserInfo with user profile data
|
|
199
198
|
* @throws {FigmaApiError} If the API call fails
|
|
200
|
-
*/ export async function getUserInfo(
|
|
199
|
+
*/ export async function getUserInfo(credential) {
|
|
201
200
|
const baseUrl = process.env.FIGMA_API_BASE_URL || getEnvConfig().apiBaseUrl;
|
|
202
201
|
const url = `${baseUrl}/v1/me`;
|
|
203
202
|
try {
|
|
204
203
|
const response = await fetch(url, {
|
|
205
|
-
headers:
|
|
206
|
-
Authorization: `Bearer ${accessToken}`
|
|
207
|
-
}
|
|
204
|
+
headers: getAuthHeaders(credential)
|
|
208
205
|
});
|
|
209
206
|
if (!response.ok) {
|
|
210
207
|
throw new FigmaApiError(`Failed to get user info: ${response.status} ${response.statusText}`, response.status);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Access Tokens types for CLI authentication
|
|
3
|
+
*
|
|
4
|
+
* Distinguishes between OAuth tokens (Authorization: Bearer) and
|
|
5
|
+
* Plan Access Tokens (X-Figma-Token header).
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Represents an authenticated credential — either OAuth or PAT
|
|
9
|
+
*/
|
|
10
|
+
export type AuthCredential = {
|
|
11
|
+
token: string;
|
|
12
|
+
type: 'oauth';
|
|
13
|
+
} | {
|
|
14
|
+
token: string;
|
|
15
|
+
type: 'plan_access_token';
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Build the correct auth headers for a credential
|
|
19
|
+
*/
|
|
20
|
+
export declare function getAuthHeaders(credential: AuthCredential): Record<string, string>;
|
|
21
|
+
//# sourceMappingURL=credentials.d.ts.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Access Tokens types for CLI authentication
|
|
3
|
+
*
|
|
4
|
+
* Distinguishes between OAuth tokens (Authorization: Bearer) and
|
|
5
|
+
* Plan Access Tokens (X-Figma-Token header).
|
|
6
|
+
*/ /**
|
|
7
|
+
* Represents an authenticated credential — either OAuth or PAT
|
|
8
|
+
*/ /**
|
|
9
|
+
* Build the correct auth headers for a credential
|
|
10
|
+
*/ export function getAuthHeaders(credential) {
|
|
11
|
+
if (credential.type === 'plan_access_token') {
|
|
12
|
+
return {
|
|
13
|
+
'X-Figma-Token': credential.token
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
Authorization: `Bearer ${credential.token}`
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=credentials.js.map
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { AuthCredential } from './credentials.js';
|
|
1
2
|
import type { TokenStore } from './token-store.js';
|
|
2
3
|
import type { FigmaTokens } from './types.js';
|
|
3
4
|
/**
|
|
@@ -55,13 +56,21 @@ export declare function executeOAuthFlow(tokenStore: TokenStore, options?: OAuth
|
|
|
55
56
|
* refreshes using the refresh token. If no tokens exist, returns null.
|
|
56
57
|
*
|
|
57
58
|
* @param tokenStore - Token store to use
|
|
58
|
-
* @returns Promise resolving to access token or null if no valid tokens
|
|
59
|
+
* @returns Promise resolving to AuthCredential (wrapped access token) or null if no valid tokens
|
|
59
60
|
* @throws OAuthFlowError if refresh fails
|
|
60
61
|
*/
|
|
61
|
-
export declare function
|
|
62
|
+
export declare function getValidOAuthAccessToken(tokenStore: TokenStore): Promise<AuthCredential | null>;
|
|
62
63
|
/**
|
|
63
|
-
*
|
|
64
|
+
* Get a valid auth credential, checking process.env for plan access token
|
|
65
|
+
* first before checking tokenStore for OAuth tokens.
|
|
66
|
+
* *
|
|
67
|
+
* @param tokenStore - Token store to use for OAuth tokens
|
|
68
|
+
* @returns Promise resolving to AuthCredential or null
|
|
69
|
+
*/
|
|
70
|
+
export declare function getValidCredential(tokenStore: TokenStore): Promise<AuthCredential | null>;
|
|
71
|
+
/**
|
|
72
|
+
* Like getValidCredential but returns null instead of throwing on refresh failure.
|
|
64
73
|
* Use in commands that want to fall through to a login prompt on failure.
|
|
65
74
|
*/
|
|
66
|
-
export declare function
|
|
75
|
+
export declare function tryGetCredential(tokenStore: TokenStore): Promise<AuthCredential | null>;
|
|
67
76
|
//# sourceMappingURL=oauth-flow.d.ts.map
|
package/dist/auth/oauth-flow.js
CHANGED
|
@@ -143,12 +143,16 @@ import { exchangeCodeForTokens, refreshAccessToken, TokenRefreshError } from './
|
|
|
143
143
|
* refreshes using the refresh token. If no tokens exist, returns null.
|
|
144
144
|
*
|
|
145
145
|
* @param tokenStore - Token store to use
|
|
146
|
-
* @returns Promise resolving to access token or null if no valid tokens
|
|
146
|
+
* @returns Promise resolving to AuthCredential (wrapped access token) or null if no valid tokens
|
|
147
147
|
* @throws OAuthFlowError if refresh fails
|
|
148
|
-
*/ export async function
|
|
148
|
+
*/ export async function getValidOAuthAccessToken(tokenStore) {
|
|
149
149
|
// Check if we have valid tokens
|
|
150
150
|
if (tokenStore.hasValidTokens()) {
|
|
151
|
-
|
|
151
|
+
const token = tokenStore.getAccessToken();
|
|
152
|
+
return token ? {
|
|
153
|
+
type: 'oauth',
|
|
154
|
+
token
|
|
155
|
+
} : null;
|
|
152
156
|
}
|
|
153
157
|
// Check if we have a refresh token
|
|
154
158
|
const refreshToken = tokenStore.getRefreshToken();
|
|
@@ -159,7 +163,10 @@ import { exchangeCodeForTokens, refreshAccessToken, TokenRefreshError } from './
|
|
|
159
163
|
try {
|
|
160
164
|
const tokens = await refreshAccessToken(refreshToken);
|
|
161
165
|
tokenStore.setTokens(tokens);
|
|
162
|
-
return
|
|
166
|
+
return {
|
|
167
|
+
type: 'oauth',
|
|
168
|
+
token: tokens.accessToken
|
|
169
|
+
};
|
|
163
170
|
} catch (error) {
|
|
164
171
|
const isAuthFailure = error instanceof TokenRefreshError && (error.statusCode === 401 || error.statusCode === 403 || error.statusCode === 400 && error.errorCode === 'invalid_grant');
|
|
165
172
|
if (isAuthFailure) {
|
|
@@ -167,7 +174,10 @@ import { exchangeCodeForTokens, refreshAccessToken, TokenRefreshError } from './
|
|
|
167
174
|
try {
|
|
168
175
|
const tokens = await refreshAccessToken(refreshToken);
|
|
169
176
|
tokenStore.setTokens(tokens);
|
|
170
|
-
return
|
|
177
|
+
return {
|
|
178
|
+
type: 'oauth',
|
|
179
|
+
token: tokens.accessToken
|
|
180
|
+
};
|
|
171
181
|
} catch {
|
|
172
182
|
// Retry also failed — token is genuinely revoked
|
|
173
183
|
tokenStore.clearTokens();
|
|
@@ -177,11 +187,27 @@ import { exchangeCodeForTokens, refreshAccessToken, TokenRefreshError } from './
|
|
|
177
187
|
}
|
|
178
188
|
}
|
|
179
189
|
/**
|
|
180
|
-
*
|
|
190
|
+
* Get a valid auth credential, checking process.env for plan access token
|
|
191
|
+
* first before checking tokenStore for OAuth tokens.
|
|
192
|
+
* *
|
|
193
|
+
* @param tokenStore - Token store to use for OAuth tokens
|
|
194
|
+
* @returns Promise resolving to AuthCredential or null
|
|
195
|
+
*/ export async function getValidCredential(tokenStore) {
|
|
196
|
+
const envFigmaAccessToken = process.env.FIGMA_ACCESS_TOKEN;
|
|
197
|
+
if (envFigmaAccessToken) {
|
|
198
|
+
return {
|
|
199
|
+
type: 'plan_access_token',
|
|
200
|
+
token: envFigmaAccessToken
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
return getValidOAuthAccessToken(tokenStore);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Like getValidCredential but returns null instead of throwing on refresh failure.
|
|
181
207
|
* Use in commands that want to fall through to a login prompt on failure.
|
|
182
|
-
*/ export async function
|
|
208
|
+
*/ export async function tryGetCredential(tokenStore) {
|
|
183
209
|
try {
|
|
184
|
-
return await
|
|
210
|
+
return await getValidCredential(tokenStore);
|
|
185
211
|
} catch {
|
|
186
212
|
return null;
|
|
187
213
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import { getInfraEnvironment } from '../constants.js';
|
|
9
9
|
import * as log from '../utils/log.js';
|
|
10
10
|
import { JWTValidationError, validateProjectToken } from './jwt-validator.js';
|
|
11
|
-
import {
|
|
11
|
+
import { getValidCredential } from './oauth-flow.js';
|
|
12
12
|
/**
|
|
13
13
|
* Error during project token operations
|
|
14
14
|
*/ export class ProjectTokenError extends Error {
|
|
@@ -71,18 +71,18 @@ import { getValidAccessToken } from './oauth-flow.js';
|
|
|
71
71
|
}
|
|
72
72
|
// We need to refresh the project token
|
|
73
73
|
// An oauth access token is required for the call
|
|
74
|
-
let
|
|
74
|
+
let credential;
|
|
75
75
|
try {
|
|
76
|
-
|
|
76
|
+
credential = await getValidCredential(tokenStore);
|
|
77
77
|
} catch (error) {
|
|
78
78
|
throw new ProjectTokenError('Failed to get valid access token for project token refresh', error instanceof Error ? error : undefined);
|
|
79
79
|
}
|
|
80
|
-
if (!
|
|
80
|
+
if (!credential) {
|
|
81
81
|
// No valid user tokens available - user needs to authenticate
|
|
82
82
|
return null;
|
|
83
83
|
}
|
|
84
84
|
// Fetch a new project token from the Figma API
|
|
85
|
-
const projectToken = await fetchProjectToken(
|
|
85
|
+
const projectToken = await fetchProjectToken(credential, tenantId);
|
|
86
86
|
// Validate the JWT signature and claims (skip for mocks)
|
|
87
87
|
const hasEnvToken = !!process.env.FIGMA_MOCK_PROJECT_TOKEN_VALUE;
|
|
88
88
|
const shouldMock = process.env.FIGMA_MOCK_PROJECT_TOKEN !== 'false';
|
package/dist/cli.js
CHANGED
|
@@ -29,6 +29,10 @@ class Main {
|
|
|
29
29
|
constructor(){
|
|
30
30
|
// @ts-expect-error bad typings
|
|
31
31
|
this.args = arg({
|
|
32
|
+
// Hidden flag — intentionally not displayed in help output yet.
|
|
33
|
+
// Auto-detection covers most cases; this is an escape hatch for testing.
|
|
34
|
+
// May expose in help text once multi-framework support is public.
|
|
35
|
+
'--adapter': String,
|
|
32
36
|
'--all': Boolean,
|
|
33
37
|
'--debug': Boolean,
|
|
34
38
|
'--dry-run': Boolean,
|
|
@@ -106,6 +110,7 @@ class Main {
|
|
|
106
110
|
case 'deploy':
|
|
107
111
|
await deployCommand({
|
|
108
112
|
id: this.args['--id'],
|
|
113
|
+
adapter: this.args['--adapter'],
|
|
109
114
|
debug: this.args['--debug'],
|
|
110
115
|
env: this.args['--env'],
|
|
111
116
|
skipBuild: this.args['--skip-build'],
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import type { AdapterName } from '../utils/deploy-adapter.js';
|
|
1
2
|
/**
|
|
2
3
|
* Options for deploy command
|
|
3
4
|
*/
|
|
4
5
|
export interface DeployCommandOptions {
|
|
6
|
+
/** Framework adapter (nextjs, nitro, vite). Auto-detected if omitted. */
|
|
7
|
+
adapter?: AdapterName;
|
|
5
8
|
/** Enable debug mode */
|
|
6
9
|
debug?: boolean;
|
|
7
10
|
/** Figma environment name (e.g. 'production', 'staging') */
|