@payloadcms/figma 0.0.1-alpha.18 → 0.0.1-alpha.19
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.js +2 -2
- package/dist/api/control-plane.js.map +1 -1
- package/dist/auth/crypto-utils.d.ts.map +1 -1
- package/dist/auth/crypto-utils.js +5 -5
- package/dist/auth/crypto-utils.js.map +1 -1
- package/dist/auth/token-store.d.ts.map +1 -1
- package/dist/auth/token-store.js +3 -0
- package/dist/auth/token-store.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +14 -76
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/login.d.ts +8 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +10 -4
- package/dist/commands/login.js.map +1 -1
- package/dist/db-adapter.d.ts.map +1 -1
- package/dist/db-adapter.js +5 -2
- package/dist/db-adapter.js.map +1 -1
- package/dist/oauth/components/LoginButton/index.d.ts.map +1 -1
- package/dist/oauth/components/LoginButton/index.js +50 -6
- package/dist/oauth/components/LoginButton/index.js.map +1 -1
- package/dist/oauth/components/LoginButton/index.scss +50 -3
- package/package.json +2 -2
|
@@ -152,10 +152,10 @@ import * as log from '../utils/log.js';
|
|
|
152
152
|
* @returns Deployment ID and upload URLs
|
|
153
153
|
*/ export async function createDeployment(accessToken, tenantId, options) {
|
|
154
154
|
// Check if control plane API should be mocked
|
|
155
|
-
const shouldMock = process.env.FIGMA_MOCK_CONTROL_PLANE
|
|
155
|
+
const shouldMock = process.env.FIGMA_MOCK_CONTROL_PLANE === 'true';
|
|
156
156
|
if (shouldMock) {
|
|
157
157
|
// MOCK IMPLEMENTATION: Generate mock deployment and signed URLs
|
|
158
|
-
log.debug('Using mock Control Plane API for createDeployment (FIGMA_MOCK_CONTROL_PLANE
|
|
158
|
+
log.debug('Using mock Control Plane API for createDeployment (FIGMA_MOCK_CONTROL_PLANE === "true")');
|
|
159
159
|
const deploymentId = `deploy_${Math.random().toString(36).substring(2, 11)}`;
|
|
160
160
|
const mockBucket = 'figma-cms-deployments-mock';
|
|
161
161
|
const mockRegion = 'us-west-2';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/api/control-plane.ts"],"sourcesContent":["/**\n * Control Plane API Client\n *\n * TODO: Replace with real API calls when Control Plane is available\n */\n\nimport type { Tenant } from '../types/config.js'\n\nimport { getEnvironment } from '../constants.js'\nimport * as log from '../utils/log.js'\n\n/**\n * Control Plane API base URLs\n */\nconst CONTROL_PLANE_API_URLS = {\n production: 'https://api.figma.com',\n staging: process.env.FIGMA_API_URL || 'https://api.staging.figma.com',\n}\n\n/**\n * Get the Control Plane API base URL based on environment\n */\nfunction getControlPlaneBaseUrl(): string {\n return process.env.FIGMA_API_BASE_URL || CONTROL_PLANE_API_URLS[getEnvironment()]\n}\n\n/**\n * Error thrown when Control Plane API calls fail\n */\nexport class ControlPlaneError extends Error {\n constructor(\n message: string,\n public statusCode?: number,\n public cause?: Error,\n ) {\n super(message)\n this.name = 'ControlPlaneError'\n }\n}\n\n/**\n * Options for creating a new tenant\n */\nexport interface CreateTenantOptions {\n /** Name for the new CMS instance */\n name: string\n /** Optional parent ID */\n parentId?: string\n /** Optional parent type */\n parentType?: 'org' | 'team' | 'workspace'\n}\n\n/**\n * Options for creating a new deployment\n */\nexport interface CreateDeploymentOptions {\n /** List of static asset paths that need upload URLs */\n staticAssets: string[]\n}\n\n/**\n * Response from creating a new deployment\n */\nexport interface CreateDeploymentResponse {\n /** Upload URL for the Lambda function code zip */\n codeUploadUrl: string\n /** Unique deployment ID */\n deploymentId: string\n /** Map of static asset paths to their signed S3 upload URLs */\n staticAssetUploadUrls: Record<string, string>\n}\n\nexport interface CreateDeploymentApiResponse {\n error: boolean\n meta: {\n deployment_id: string\n lambda_zip_upload_url: string\n static_asset_upload_urls: Record<string, string>\n }\n status: number\n}\n\n/**\n * Options for performing a deployment\n */\nexport interface PerformDeploymentOptions {\n /** Deployment ID from createDeployment */\n deploymentId: string\n}\n\n/**\n * Response from performing a deployment\n */\nexport interface PerformDeploymentResponse {\n /** Deployment ID that was deployed */\n deploymentId: string\n /** Status message */\n message: string\n}\n\nexport interface PerformDeploymentApiResponse {\n error: boolean\n meta: {\n deployment_id: string\n message: string\n status: string\n }\n status: number\n}\n\n/**\n * List all tenant instances for the authenticated user\n * Maps to: GET /v1/tenant\n *\n * @param accessToken - OAuth access token\n * @returns Array of tenant instances\n */\nexport async function listTenants(accessToken: string): Promise<Tenant[]> {\n // Check if control plane API should be mocked\n // Default to true until real API is available\n const shouldMock = process.env.FIGMA_MOCK_CONTROL_PLANE !== 'false'\n\n if (shouldMock) {\n // MOCK IMPLEMENTATION: Return sample tenants for testing\n log.debug('Using mock Control Plane API for listTenants (FIGMA_MOCK_CONTROL_PLANE != \"false\")')\n return [\n {\n id: 'tenant_abc123',\n createdAt: '2025-01-15T10:00:00Z',\n domain: 'my-blog.figmacms.com',\n parentId: 'team_456',\n parentType: 'team',\n status: 'active',\n },\n {\n id: 'tenant_def456',\n createdAt: '2025-01-10T14:30:00Z',\n domain: 'my-store.figmacms.com',\n parentId: 'team_456',\n parentType: 'team',\n status: 'active',\n },\n ]\n }\n\n // REAL API IMPLEMENTATION\n const response = await fetch(`${getControlPlaneBaseUrl()}/v1/tenant`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n })\n\n if (!response.ok) {\n throw new ControlPlaneError(\n `Failed to list tenants: ${response.status} ${response.statusText}`,\n response.status,\n )\n }\n\n return response.json()\n}\n\n/**\n * Create a new tenant instance\n * Maps to: POST /v1/tenant\n *\n * @param accessToken - OAuth access token\n * @param options - Tenant creation options\n * @returns Newly created tenant\n */\nexport async function createTenant(\n accessToken: string,\n options: CreateTenantOptions,\n): Promise<Tenant> {\n // Check if control plane API should be mocked\n const shouldMock = process.env.FIGMA_MOCK_CONTROL_PLANE !== 'false'\n\n if (shouldMock) {\n // MOCK IMPLEMENTATION: Generate mock tenant for testing\n log.debug('Using mock Control Plane API for createTenant (FIGMA_MOCK_CONTROL_PLANE != \"false\")')\n const tenantId = `tenant_${Math.random().toString(36).substring(2, 11)}`\n const slug = options.name.toLowerCase().replace(/[^a-z0-9]+/g, '-')\n const domain = `${slug}.figmacms.com`\n\n return {\n id: tenantId,\n createdAt: new Date().toISOString(),\n domain,\n parentId: options.parentId || 'team_456',\n parentType: options.parentType || 'team',\n status: 'provisioning',\n }\n }\n\n // REAL API IMPLEMENTATION\n const response = await fetch(`${getControlPlaneBaseUrl()}/v1/tenant`, {\n body: JSON.stringify({ name: options.name }),\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n })\n\n if (!response.ok) {\n throw new ControlPlaneError(\n `Failed to create tenant: ${response.status} ${response.statusText}`,\n response.status,\n )\n }\n\n return response.json()\n}\n\n/**\n * Get details for a specific tenant\n * Maps to: GET /v1/tenant/{tenant_id}\n *\n * @param accessToken - OAuth access token\n * @param tenantId - Tenant ID\n * @returns Tenant details\n */\nexport async function getTenantDetails(accessToken: string, tenantId: string): Promise<Tenant> {\n // Check if control plane API should be mocked\n const shouldMock = process.env.FIGMA_MOCK_CONTROL_PLANE !== 'false'\n\n if (shouldMock) {\n // MOCK IMPLEMENTATION: Return mock tenant details for testing\n log.debug(\n 'Using mock Control Plane API for getTenantDetails (FIGMA_MOCK_CONTROL_PLANE != \"false\")',\n )\n return {\n id: tenantId,\n createdAt: '2025-01-15T10:00:00Z',\n domain: 'example.figmacms.com',\n parentId: 'team_456',\n parentType: 'team',\n status: 'active',\n }\n }\n\n // REAL API IMPLEMENTATION\n const response = await fetch(`${getControlPlaneBaseUrl()}/v1/tenant/${tenantId}`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n })\n\n if (!response.ok) {\n throw new ControlPlaneError(\n `Failed to get tenant details: ${response.status} ${response.statusText}`,\n response.status,\n )\n }\n\n return response.json()\n}\n\n/**\n * Create a new deployment and get signed upload URLs\n * Maps to: POST /v1/tenant/{tenant_id}/deploy/create\n *\n * @param accessToken - OAuth access token\n * @param tenantId - Tenant ID\n * @param options - Deployment creation options\n * @returns Deployment ID and upload URLs\n */\nexport async function createDeployment(\n accessToken: string,\n tenantId: string,\n options: CreateDeploymentOptions,\n): Promise<CreateDeploymentResponse> {\n // Check if control plane API should be mocked\n const shouldMock = process.env.FIGMA_MOCK_CONTROL_PLANE !== 'false'\n\n if (shouldMock) {\n // MOCK IMPLEMENTATION: Generate mock deployment and signed URLs\n log.debug(\n 'Using mock Control Plane API for createDeployment (FIGMA_MOCK_CONTROL_PLANE != \"false\")',\n )\n\n const deploymentId = `deploy_${Math.random().toString(36).substring(2, 11)}`\n const mockBucket = 'figma-cms-deployments-mock'\n const mockRegion = 'us-west-2'\n const mockBaseUrl = `https://${mockBucket}.s3.${mockRegion}.amazonaws.com`\n\n // Generate mock signed URLs for static assets\n const staticAssetUploadUrls: Record<string, string> = {}\n for (const assetPath of options.staticAssets) {\n const encodedPath = encodeURIComponent(assetPath)\n staticAssetUploadUrls[assetPath] =\n `${mockBaseUrl}/${tenantId}/${deploymentId}/static/${encodedPath}?X-Amz-Signature=mock`\n }\n\n // Generate mock signed URL for code zip\n const codeUploadUrl = `${mockBaseUrl}/${tenantId}/${deploymentId}/lambda.zip?X-Amz-Signature=mock`\n\n return {\n codeUploadUrl,\n deploymentId,\n staticAssetUploadUrls,\n }\n }\n\n const url = `${getControlPlaneBaseUrl()}/v1/cms/tenant/${tenantId}/deploy/create`\n\n log.debug(`Calling createDeployment API at ${url}`)\n\n // REAL API IMPLEMENTATION\n const response = await fetch(url, {\n body: JSON.stringify({ static_assets: options.staticAssets }),\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n })\n\n if (!response.ok) {\n throw new ControlPlaneError(\n `Failed to create deployment: ${response.status} ${response.statusText}`,\n response.status,\n )\n }\n\n const data = (await response.json()) as CreateDeploymentApiResponse\n\n // Map API response format to our interface\n return {\n codeUploadUrl: data.meta.lambda_zip_upload_url,\n deploymentId: data.meta.deployment_id,\n staticAssetUploadUrls: data.meta.static_asset_upload_urls,\n }\n}\n\n/**\n * Perform deployment for a created deployment ID\n * Maps to: POST /v1/tenant/{tenant_id}/deploy/perform\n *\n * @param accessToken - OAuth access token\n * @param tenantId - Tenant ID\n * @param options - Deployment perform options\n * @returns Deployment status and message\n */\nexport async function performDeployment(\n accessToken: string,\n tenantId: string,\n options: PerformDeploymentOptions,\n): Promise<PerformDeploymentResponse> {\n // Check if control plane API should be mocked\n // THIS ONE DIFFERS FROM THE OTHERS AS IT DEFAULTS TO ACTUAL API\n const shouldMock = process.env.FIGMA_MOCK_CONTROL_PLANE === 'true'\n\n if (shouldMock) {\n // MOCK IMPLEMENTATION: Return mock deployment status\n log.debug(\n 'Using mock Control Plane API for performDeployment (FIGMA_MOCK_CONTROL_PLANE != \"false\")',\n )\n\n return {\n deploymentId: options.deploymentId,\n message: 'Deployment initiated successfully',\n }\n }\n\n const url = `${getControlPlaneBaseUrl()}/v1/cms/tenant/${tenantId}/deploy/perform`\n log.debug(`Calling performDeployment API at ${url}`)\n\n // REAL API IMPLEMENTATION\n const response = await fetch(url, {\n body: JSON.stringify({ deployment_id: options.deploymentId }),\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n })\n\n if (!response.ok) {\n throw new ControlPlaneError(\n `Failed to perform deployment: ${response.status} ${response.statusText}`,\n response.status,\n )\n }\n\n const data = (await response.json()) as PerformDeploymentApiResponse\n\n // Map API response to our interface\n return {\n deploymentId: data.meta.deployment_id,\n message: data.meta.message || 'Deployment initiated',\n }\n}\n"],"names":["getEnvironment","log","CONTROL_PLANE_API_URLS","production","staging","process","env","FIGMA_API_URL","getControlPlaneBaseUrl","FIGMA_API_BASE_URL","ControlPlaneError","Error","message","statusCode","cause","name","listTenants","accessToken","shouldMock","FIGMA_MOCK_CONTROL_PLANE","debug","id","createdAt","domain","parentId","parentType","status","response","fetch","headers","Authorization","ok","statusText","json","createTenant","options","tenantId","Math","random","toString","substring","slug","toLowerCase","replace","Date","toISOString","body","JSON","stringify","method","getTenantDetails","createDeployment","deploymentId","mockBucket","mockRegion","mockBaseUrl","staticAssetUploadUrls","assetPath","staticAssets","encodedPath","encodeURIComponent","codeUploadUrl","url","static_assets","data","meta","lambda_zip_upload_url","deployment_id","static_asset_upload_urls","performDeployment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/api/control-plane.ts"],"sourcesContent":["/**\n * Control Plane API Client\n *\n * TODO: Replace with real API calls when Control Plane is available\n */\n\nimport type { Tenant } from '../types/config.js'\n\nimport { getEnvironment } from '../constants.js'\nimport * as log from '../utils/log.js'\n\n/**\n * Control Plane API base URLs\n */\nconst CONTROL_PLANE_API_URLS = {\n production: 'https://api.figma.com',\n staging: process.env.FIGMA_API_URL || 'https://api.staging.figma.com',\n}\n\n/**\n * Get the Control Plane API base URL based on environment\n */\nfunction getControlPlaneBaseUrl(): string {\n return process.env.FIGMA_API_BASE_URL || CONTROL_PLANE_API_URLS[getEnvironment()]\n}\n\n/**\n * Error thrown when Control Plane API calls fail\n */\nexport class ControlPlaneError extends Error {\n constructor(\n message: string,\n public statusCode?: number,\n public cause?: Error,\n ) {\n super(message)\n this.name = 'ControlPlaneError'\n }\n}\n\n/**\n * Options for creating a new tenant\n */\nexport interface CreateTenantOptions {\n /** Name for the new CMS instance */\n name: string\n /** Optional parent ID */\n parentId?: string\n /** Optional parent type */\n parentType?: 'org' | 'team' | 'workspace'\n}\n\n/**\n * Options for creating a new deployment\n */\nexport interface CreateDeploymentOptions {\n /** List of static asset paths that need upload URLs */\n staticAssets: string[]\n}\n\n/**\n * Response from creating a new deployment\n */\nexport interface CreateDeploymentResponse {\n /** Upload URL for the Lambda function code zip */\n codeUploadUrl: string\n /** Unique deployment ID */\n deploymentId: string\n /** Map of static asset paths to their signed S3 upload URLs */\n staticAssetUploadUrls: Record<string, string>\n}\n\nexport interface CreateDeploymentApiResponse {\n error: boolean\n meta: {\n deployment_id: string\n lambda_zip_upload_url: string\n static_asset_upload_urls: Record<string, string>\n }\n status: number\n}\n\n/**\n * Options for performing a deployment\n */\nexport interface PerformDeploymentOptions {\n /** Deployment ID from createDeployment */\n deploymentId: string\n}\n\n/**\n * Response from performing a deployment\n */\nexport interface PerformDeploymentResponse {\n /** Deployment ID that was deployed */\n deploymentId: string\n /** Status message */\n message: string\n}\n\nexport interface PerformDeploymentApiResponse {\n error: boolean\n meta: {\n deployment_id: string\n message: string\n status: string\n }\n status: number\n}\n\n/**\n * List all tenant instances for the authenticated user\n * Maps to: GET /v1/tenant\n *\n * @param accessToken - OAuth access token\n * @returns Array of tenant instances\n */\nexport async function listTenants(accessToken: string): Promise<Tenant[]> {\n // Check if control plane API should be mocked\n // Default to true until real API is available\n const shouldMock = process.env.FIGMA_MOCK_CONTROL_PLANE !== 'false'\n\n if (shouldMock) {\n // MOCK IMPLEMENTATION: Return sample tenants for testing\n log.debug('Using mock Control Plane API for listTenants (FIGMA_MOCK_CONTROL_PLANE != \"false\")')\n return [\n {\n id: 'tenant_abc123',\n createdAt: '2025-01-15T10:00:00Z',\n domain: 'my-blog.figmacms.com',\n parentId: 'team_456',\n parentType: 'team',\n status: 'active',\n },\n {\n id: 'tenant_def456',\n createdAt: '2025-01-10T14:30:00Z',\n domain: 'my-store.figmacms.com',\n parentId: 'team_456',\n parentType: 'team',\n status: 'active',\n },\n ]\n }\n\n // REAL API IMPLEMENTATION\n const response = await fetch(`${getControlPlaneBaseUrl()}/v1/tenant`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n })\n\n if (!response.ok) {\n throw new ControlPlaneError(\n `Failed to list tenants: ${response.status} ${response.statusText}`,\n response.status,\n )\n }\n\n return response.json()\n}\n\n/**\n * Create a new tenant instance\n * Maps to: POST /v1/tenant\n *\n * @param accessToken - OAuth access token\n * @param options - Tenant creation options\n * @returns Newly created tenant\n */\nexport async function createTenant(\n accessToken: string,\n options: CreateTenantOptions,\n): Promise<Tenant> {\n // Check if control plane API should be mocked\n const shouldMock = process.env.FIGMA_MOCK_CONTROL_PLANE !== 'false'\n\n if (shouldMock) {\n // MOCK IMPLEMENTATION: Generate mock tenant for testing\n log.debug('Using mock Control Plane API for createTenant (FIGMA_MOCK_CONTROL_PLANE != \"false\")')\n const tenantId = `tenant_${Math.random().toString(36).substring(2, 11)}`\n const slug = options.name.toLowerCase().replace(/[^a-z0-9]+/g, '-')\n const domain = `${slug}.figmacms.com`\n\n return {\n id: tenantId,\n createdAt: new Date().toISOString(),\n domain,\n parentId: options.parentId || 'team_456',\n parentType: options.parentType || 'team',\n status: 'provisioning',\n }\n }\n\n // REAL API IMPLEMENTATION\n const response = await fetch(`${getControlPlaneBaseUrl()}/v1/tenant`, {\n body: JSON.stringify({ name: options.name }),\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n })\n\n if (!response.ok) {\n throw new ControlPlaneError(\n `Failed to create tenant: ${response.status} ${response.statusText}`,\n response.status,\n )\n }\n\n return response.json()\n}\n\n/**\n * Get details for a specific tenant\n * Maps to: GET /v1/tenant/{tenant_id}\n *\n * @param accessToken - OAuth access token\n * @param tenantId - Tenant ID\n * @returns Tenant details\n */\nexport async function getTenantDetails(accessToken: string, tenantId: string): Promise<Tenant> {\n // Check if control plane API should be mocked\n const shouldMock = process.env.FIGMA_MOCK_CONTROL_PLANE !== 'false'\n\n if (shouldMock) {\n // MOCK IMPLEMENTATION: Return mock tenant details for testing\n log.debug(\n 'Using mock Control Plane API for getTenantDetails (FIGMA_MOCK_CONTROL_PLANE != \"false\")',\n )\n return {\n id: tenantId,\n createdAt: '2025-01-15T10:00:00Z',\n domain: 'example.figmacms.com',\n parentId: 'team_456',\n parentType: 'team',\n status: 'active',\n }\n }\n\n // REAL API IMPLEMENTATION\n const response = await fetch(`${getControlPlaneBaseUrl()}/v1/tenant/${tenantId}`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n })\n\n if (!response.ok) {\n throw new ControlPlaneError(\n `Failed to get tenant details: ${response.status} ${response.statusText}`,\n response.status,\n )\n }\n\n return response.json()\n}\n\n/**\n * Create a new deployment and get signed upload URLs\n * Maps to: POST /v1/tenant/{tenant_id}/deploy/create\n *\n * @param accessToken - OAuth access token\n * @param tenantId - Tenant ID\n * @param options - Deployment creation options\n * @returns Deployment ID and upload URLs\n */\nexport async function createDeployment(\n accessToken: string,\n tenantId: string,\n options: CreateDeploymentOptions,\n): Promise<CreateDeploymentResponse> {\n // Check if control plane API should be mocked\n const shouldMock = process.env.FIGMA_MOCK_CONTROL_PLANE === 'true'\n\n if (shouldMock) {\n // MOCK IMPLEMENTATION: Generate mock deployment and signed URLs\n log.debug(\n 'Using mock Control Plane API for createDeployment (FIGMA_MOCK_CONTROL_PLANE === \"true\")',\n )\n\n const deploymentId = `deploy_${Math.random().toString(36).substring(2, 11)}`\n const mockBucket = 'figma-cms-deployments-mock'\n const mockRegion = 'us-west-2'\n const mockBaseUrl = `https://${mockBucket}.s3.${mockRegion}.amazonaws.com`\n\n // Generate mock signed URLs for static assets\n const staticAssetUploadUrls: Record<string, string> = {}\n for (const assetPath of options.staticAssets) {\n const encodedPath = encodeURIComponent(assetPath)\n staticAssetUploadUrls[assetPath] =\n `${mockBaseUrl}/${tenantId}/${deploymentId}/static/${encodedPath}?X-Amz-Signature=mock`\n }\n\n // Generate mock signed URL for code zip\n const codeUploadUrl = `${mockBaseUrl}/${tenantId}/${deploymentId}/lambda.zip?X-Amz-Signature=mock`\n\n return {\n codeUploadUrl,\n deploymentId,\n staticAssetUploadUrls,\n }\n }\n\n const url = `${getControlPlaneBaseUrl()}/v1/cms/tenant/${tenantId}/deploy/create`\n\n log.debug(`Calling createDeployment API at ${url}`)\n\n // REAL API IMPLEMENTATION\n const response = await fetch(url, {\n body: JSON.stringify({ static_assets: options.staticAssets }),\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n })\n\n if (!response.ok) {\n throw new ControlPlaneError(\n `Failed to create deployment: ${response.status} ${response.statusText}`,\n response.status,\n )\n }\n\n const data = (await response.json()) as CreateDeploymentApiResponse\n\n // Map API response format to our interface\n return {\n codeUploadUrl: data.meta.lambda_zip_upload_url,\n deploymentId: data.meta.deployment_id,\n staticAssetUploadUrls: data.meta.static_asset_upload_urls,\n }\n}\n\n/**\n * Perform deployment for a created deployment ID\n * Maps to: POST /v1/tenant/{tenant_id}/deploy/perform\n *\n * @param accessToken - OAuth access token\n * @param tenantId - Tenant ID\n * @param options - Deployment perform options\n * @returns Deployment status and message\n */\nexport async function performDeployment(\n accessToken: string,\n tenantId: string,\n options: PerformDeploymentOptions,\n): Promise<PerformDeploymentResponse> {\n // Check if control plane API should be mocked\n // THIS ONE DIFFERS FROM THE OTHERS AS IT DEFAULTS TO ACTUAL API\n const shouldMock = process.env.FIGMA_MOCK_CONTROL_PLANE === 'true'\n\n if (shouldMock) {\n // MOCK IMPLEMENTATION: Return mock deployment status\n log.debug(\n 'Using mock Control Plane API for performDeployment (FIGMA_MOCK_CONTROL_PLANE != \"false\")',\n )\n\n return {\n deploymentId: options.deploymentId,\n message: 'Deployment initiated successfully',\n }\n }\n\n const url = `${getControlPlaneBaseUrl()}/v1/cms/tenant/${tenantId}/deploy/perform`\n log.debug(`Calling performDeployment API at ${url}`)\n\n // REAL API IMPLEMENTATION\n const response = await fetch(url, {\n body: JSON.stringify({ deployment_id: options.deploymentId }),\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n })\n\n if (!response.ok) {\n throw new ControlPlaneError(\n `Failed to perform deployment: ${response.status} ${response.statusText}`,\n response.status,\n )\n }\n\n const data = (await response.json()) as PerformDeploymentApiResponse\n\n // Map API response to our interface\n return {\n deploymentId: data.meta.deployment_id,\n message: data.meta.message || 'Deployment initiated',\n }\n}\n"],"names":["getEnvironment","log","CONTROL_PLANE_API_URLS","production","staging","process","env","FIGMA_API_URL","getControlPlaneBaseUrl","FIGMA_API_BASE_URL","ControlPlaneError","Error","message","statusCode","cause","name","listTenants","accessToken","shouldMock","FIGMA_MOCK_CONTROL_PLANE","debug","id","createdAt","domain","parentId","parentType","status","response","fetch","headers","Authorization","ok","statusText","json","createTenant","options","tenantId","Math","random","toString","substring","slug","toLowerCase","replace","Date","toISOString","body","JSON","stringify","method","getTenantDetails","createDeployment","deploymentId","mockBucket","mockRegion","mockBaseUrl","staticAssetUploadUrls","assetPath","staticAssets","encodedPath","encodeURIComponent","codeUploadUrl","url","static_assets","data","meta","lambda_zip_upload_url","deployment_id","static_asset_upload_urls","performDeployment"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crypto-utils.d.ts","sourceRoot":"","sources":["../../src/auth/crypto-utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"crypto-utils.d.ts","sourceRoot":"","sources":["../../src/auth/crypto-utils.ts"],"names":[],"mappings":"AAoEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAe5C"}
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import Conf from 'conf';
|
|
2
2
|
import crypto from 'crypto';
|
|
3
3
|
import os from 'os';
|
|
4
|
-
// Configuration store for cryptographic salt
|
|
5
|
-
const cryptoConf = new Conf({
|
|
6
|
-
configName: 'payloadcms-figma-crypto',
|
|
7
|
-
projectName: 'payloadcms-figma'
|
|
8
|
-
});
|
|
9
4
|
/**
|
|
10
5
|
* Get or generate a random salt for key derivation
|
|
11
6
|
*
|
|
@@ -15,6 +10,11 @@ const cryptoConf = new Conf({
|
|
|
15
10
|
*
|
|
16
11
|
* @returns 32-byte hex string (64 characters)
|
|
17
12
|
*/ function getOrCreateSalt() {
|
|
13
|
+
// Configuration store for cryptographic salt
|
|
14
|
+
const cryptoConf = new Conf({
|
|
15
|
+
configName: 'payloadcms-figma-crypto',
|
|
16
|
+
projectName: 'payloadcms-figma'
|
|
17
|
+
});
|
|
18
18
|
let salt = cryptoConf.get('salt');
|
|
19
19
|
if (!salt) {
|
|
20
20
|
// Generate cryptographically secure random salt (32 bytes = 256 bits)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/auth/crypto-utils.ts"],"sourcesContent":["import Conf from 'conf'\nimport crypto from 'crypto'\nimport os from 'os'\n\n
|
|
1
|
+
{"version":3,"sources":["../../src/auth/crypto-utils.ts"],"sourcesContent":["import Conf from 'conf'\nimport crypto from 'crypto'\nimport os from 'os'\n\n/**\n * Get or generate a random salt for key derivation\n *\n * Generates a cryptographically secure random salt on first run and persists it\n * for future use. This ensures the encryption key is unique per machine and not\n * reproducible even if machine identifiers are known.\n *\n * @returns 32-byte hex string (64 characters)\n */\nfunction getOrCreateSalt(): string {\n // Configuration store for cryptographic salt\n const cryptoConf = new Conf<{ salt: string }>({\n configName: 'payloadcms-figma-crypto',\n projectName: 'payloadcms-figma',\n })\n let salt = cryptoConf.get('salt')\n if (!salt) {\n // Generate cryptographically secure random salt (32 bytes = 256 bits)\n salt = crypto.randomBytes(32).toString('hex')\n cryptoConf.set('salt', salt)\n }\n return salt\n}\n\n/**\n * Gather machine-specific entropy sources\n *\n * Collects multiple machine and user identifiers to create a unique input\n * for key derivation. More entropy sources make the key harder to guess.\n *\n * @returns Combined machine identifier string\n * @throws Error if unable to gather sufficient entropy\n */\nfunction gatherMachineEntropy(): string {\n try {\n const userInfo = os.userInfo()\n const networkInterfaces = os.networkInterfaces()\n\n // Get MAC address from first available network interface (if available)\n const macAddress = Object.values(networkInterfaces)\n .flat()\n .find((iface) => iface && !iface.internal && iface.mac !== '00:00:00:00:00:00')?.mac\n\n const entropy = [\n os.hostname(), // Machine hostname\n os.homedir(), // User home directory path\n userInfo.username, // OS username\n os.platform(), // Operating system platform\n os.arch(), // CPU architecture\n macAddress, // MAC address (if available)\n ].filter(Boolean) // Remove any undefined values\n\n if (entropy.length < 4) {\n throw new Error('Insufficient machine entropy available')\n }\n\n return entropy.join('::')\n } catch (error) {\n throw new Error(\n `Failed to gather machine entropy: ${error instanceof Error ? error.message : 'Unknown error'}`,\n )\n }\n}\n\n/**\n * Derive a machine-specific encryption key for token storage\n *\n * Creates a deterministic encryption key using PBKDF2 with machine-specific\n * identifiers and a random salt. This provides stronger security than simple\n * hashing by making brute force attacks computationally expensive.\n *\n * Security model - What this protects against:\n * ✅ Accidental file exposure (cloud backups, shared drives)\n * ✅ Non-technical users reading token files\n * ✅ Brute force attacks (100k PBKDF2 iterations)\n * ✅ Key guessing even with known machine identifiers (random salt)\n *\n * Security model - What this DOES NOT protect against:\n * ❌ Local user compromise (same user can run this function)\n * ❌ Root/admin access attacks\n * ❌ Sophisticated attackers with system access\n *\n * For stronger security, use OS keychain (@napi-rs/keyring) instead.\n * This is a fallback for environments without keychain access.\n *\n * Implementation details:\n * - Uses PBKDF2 with SHA-256 and 100,000 iterations (~500ms-1s)\n * - Combines multiple machine identifiers for entropy\n * - Uses persistent random salt unique to each machine\n * - Produces consistent key for same machine (deterministic)\n * - Tokens are not portable between machines (by design)\n *\n * @returns 64-character hex string (32-byte key) suitable for AES-256 encryption\n * @throws Error if unable to derive key due to missing machine information\n */\nexport function deriveEncryptionKey(): string {\n const machineId = gatherMachineEntropy()\n const salt = getOrCreateSalt()\n\n // PBKDF2 with 100k iterations provides strong security against brute force\n // while remaining performant for CLI use (~500ms-1s key derivation time)\n const key = crypto.pbkdf2Sync(\n machineId, // Password (machine identifiers)\n salt, // Salt (random, persisted)\n 100000, // Iterations (100k for strong security)\n 32, // Key length (32 bytes = 256 bits for AES-256)\n 'sha256', // Hash algorithm\n )\n\n return key.toString('hex')\n}\n"],"names":["Conf","crypto","os","getOrCreateSalt","cryptoConf","configName","projectName","salt","get","randomBytes","toString","set","gatherMachineEntropy","userInfo","networkInterfaces","macAddress","Object","values","flat","find","iface","internal","mac","entropy","hostname","homedir","username","platform","arch","filter","Boolean","length","Error","join","error","message","deriveEncryptionKey","machineId","key","pbkdf2Sync"],"mappings":"AAAA,OAAOA,UAAU,OAAM;AACvB,OAAOC,YAAY,SAAQ;AAC3B,OAAOC,QAAQ,KAAI;AAEnB;;;;;;;;CAQC,GACD,SAASC;IACP,6CAA6C;IAC7C,MAAMC,aAAa,IAAIJ,KAAuB;QAC5CK,YAAY;QACZC,aAAa;IACf;IACA,IAAIC,OAAOH,WAAWI,GAAG,CAAC;IAC1B,IAAI,CAACD,MAAM;QACT,sEAAsE;QACtEA,OAAON,OAAOQ,WAAW,CAAC,IAAIC,QAAQ,CAAC;QACvCN,WAAWO,GAAG,CAAC,QAAQJ;IACzB;IACA,OAAOA;AACT;AAEA;;;;;;;;CAQC,GACD,SAASK;IACP,IAAI;QACF,MAAMC,WAAWX,GAAGW,QAAQ;QAC5B,MAAMC,oBAAoBZ,GAAGY,iBAAiB;QAE9C,wEAAwE;QACxE,MAAMC,aAAaC,OAAOC,MAAM,CAACH,mBAC9BI,IAAI,GACJC,IAAI,CAAC,CAACC,QAAUA,SAAS,CAACA,MAAMC,QAAQ,IAAID,MAAME,GAAG,KAAK,sBAAsBA;QAEnF,MAAMC,UAAU;YACdrB,GAAGsB,QAAQ;YACXtB,GAAGuB,OAAO;YACVZ,SAASa,QAAQ;YACjBxB,GAAGyB,QAAQ;YACXzB,GAAG0B,IAAI;YACPb;SACD,CAACc,MAAM,CAACC,SAAS,8BAA8B;;QAEhD,IAAIP,QAAQQ,MAAM,GAAG,GAAG;YACtB,MAAM,IAAIC,MAAM;QAClB;QAEA,OAAOT,QAAQU,IAAI,CAAC;IACtB,EAAE,OAAOC,OAAO;QACd,MAAM,IAAIF,MACR,CAAC,kCAAkC,EAAEE,iBAAiBF,QAAQE,MAAMC,OAAO,GAAG,iBAAiB;IAEnG;AACF;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BC,GACD,OAAO,SAASC;IACd,MAAMC,YAAYzB;IAClB,MAAML,OAAOJ;IAEb,2EAA2E;IAC3E,yEAAyE;IACzE,MAAMmC,MAAMrC,OAAOsC,UAAU,CAC3BF,WACA9B,MACA,QACA,IACA;IAGF,OAAO+B,IAAI5B,QAAQ,CAAC;AACtB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-store.d.ts","sourceRoot":"","sources":["../../src/auth/token-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAKzF;;;;;;;;;;GAUG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAA4E;gBAE9E,OAAO,CAAC,EAAE,gBAAgB;
|
|
1
|
+
{"version":3,"file":"token-store.d.ts","sourceRoot":"","sources":["../../src/auth/token-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAKzF;;;;;;;;;;GAUG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAA4E;gBAE9E,OAAO,CAAC,EAAE,gBAAgB;IActC;;;OAGG;IACH,SAAS,IAAI,WAAW,GAAG,IAAI;IAK/B;;;OAGG;IACH,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAIpC;;OAEG;IACH,WAAW,IAAI,IAAI;IAInB;;;OAGG;IACH,cAAc,IAAI,OAAO;IAQzB;;;;OAIG;IACH,SAAS,IAAI,OAAO;IAcpB;;;OAGG;IACH,cAAc,IAAI,IAAI,GAAG,MAAM;IAQ/B;;;OAGG;IACH,eAAe,IAAI,IAAI,GAAG,MAAM;IAKhC;;;;;OAKG;IACH,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAe/D;;;OAGG;IACH,cAAc,IAAI,MAAM;IAIxB;;;;;OAKG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,YAAY;IAiBtD;;;;OAIG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,GAAG,IAAI;IAMnE;;;OAGG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAMzC;;OAEG;IACH,qBAAqB,IAAI,IAAI;IAI7B;;;;;OAKG;IACH,qBAAqB,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO;IAQ1D;;;;OAIG;IACH,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAQ/C;;;;OAIG;IACH,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAK1D;;;OAGG;IACH,2BAA2B,IAAI,MAAM,EAAE;CAIxC"}
|
package/dist/auth/token-store.js
CHANGED
|
@@ -14,6 +14,9 @@ import { deriveEncryptionKey } from './crypto-utils.js';
|
|
|
14
14
|
*/ export class TokenStore {
|
|
15
15
|
config;
|
|
16
16
|
constructor(options){
|
|
17
|
+
if (process.env.AWS_EXECUTION_ENV) {
|
|
18
|
+
throw new Error('TokenStore cannot be used in AWS Lambda environments');
|
|
19
|
+
}
|
|
17
20
|
this.config = new Conf({
|
|
18
21
|
configName: options?.configName || 'payloadcms-figma',
|
|
19
22
|
projectName: 'payloadcms-figma',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/auth/token-store.ts"],"sourcesContent":["/* eslint-disable perfectionist/sort-classes */\nimport Conf from 'conf'\n\nimport type { FigmaTokens, JWTPayload, ProjectToken, TokenStoreConfig } from './types.js'\n\nimport { TOKEN_EXPIRY_BUFFER_SECONDS } from '../config/oauth.js'\nimport { deriveEncryptionKey } from './crypto-utils.js'\n\n/**\n * Secure storage manager for Figma OAuth2 tokens\n *\n * Uses the `conf` library to store tokens in an OS-specific secure location:\n * - macOS: ~/Library/Preferences/payloadcms-figma\n * - Linux: ~/.config/payloadcms-figma or $XDG_CONFIG_HOME/payloadcms-figma\n * - Windows: %APPDATA%/payloadcms-figma/Config\n *\n * Tokens are encrypted at rest with a machine-specific key and file permissions\n * are set to 0600 (owner read/write only)\n */\nexport class TokenStore {\n private config: Conf<{ projectTokens: Record<string, ProjectToken>; tokens: FigmaTokens }>\n\n constructor(options?: TokenStoreConfig) {\n this.config = new Conf<{ projectTokens: Record<string, ProjectToken>; tokens: FigmaTokens }>({\n configName: options?.configName || 'payloadcms-figma',\n projectName: 'payloadcms-figma',\n // Enable encryption with machine-specific key for better security\n encryptionKey: options?.encryptionKey || deriveEncryptionKey(),\n // Clear schema to avoid validation issues\n clearInvalidConfig: true,\n })\n }\n\n /**\n * Retrieve stored tokens\n * @returns FigmaTokens if stored, null otherwise\n */\n getTokens(): FigmaTokens | null {\n const tokens = this.config.get('tokens')\n return tokens || null\n }\n\n /**\n * Store OAuth2 tokens securely\n * @param tokens - Figma OAuth2 tokens to store\n */\n setTokens(tokens: FigmaTokens): void {\n this.config.set('tokens', tokens)\n }\n\n /**\n * Clear all stored tokens (used for logout)\n */\n clearTokens(): void {\n this.config.delete('tokens')\n }\n\n /**\n * Check if valid (non-expired) tokens exist\n * @returns true if tokens exist and are not expired\n */\n hasValidTokens(): boolean {\n const tokens = this.getTokens()\n if (!tokens) {\n return false\n }\n return !this.isExpired()\n }\n\n /**\n * Check if the current access token is expired\n * Includes a buffer time to avoid using tokens that are about to expire\n * @returns true if token is expired or will expire within buffer time\n */\n isExpired(): boolean {\n // Access config directly to avoid circular dependency with getTokens()\n const tokens = this.config.get('tokens')\n if (!tokens) {\n return true\n }\n\n const now = Date.now()\n const bufferMs = TOKEN_EXPIRY_BUFFER_SECONDS * 1000\n const expiryWithBuffer = tokens.expiresAt - bufferMs\n\n return now >= expiryWithBuffer\n }\n\n /**\n * Get the access token if it exists and is valid\n * @returns Access token string or null if expired/missing\n */\n getAccessToken(): null | string {\n if (!this.hasValidTokens()) {\n return null\n }\n const tokens = this.getTokens()\n return tokens?.accessToken || null\n }\n\n /**\n * Get the refresh token if it exists\n * @returns Refresh token string or null if missing\n */\n getRefreshToken(): null | string {\n const tokens = this.getTokens()\n return tokens?.refreshToken || null\n }\n\n /**\n * Update just the access token after a refresh\n * Preserves the existing refresh token and other metadata\n * @param accessToken - New access token\n * @param expiresIn - Expiration time in seconds\n */\n updateAccessToken(accessToken: string, expiresIn: number): void {\n const existingTokens = this.getTokens()\n if (!existingTokens) {\n throw new Error('Cannot update access token: no existing tokens found')\n }\n\n const expiresAt = Date.now() + expiresIn * 1000\n\n this.setTokens({\n ...existingTokens,\n accessToken,\n expiresAt,\n })\n }\n\n /**\n * Get the path to the config file (useful for debugging)\n * @returns Absolute path to the token storage file\n */\n getStoragePath(): string {\n return this.config.path\n }\n\n /**\n * Retrieve a project token for a specific tenant\n * Automatically removes expired tokens from storage\n * @param tenantId - The tenant/CMS ID\n * @returns ProjectToken if stored and valid, null otherwise\n */\n getProjectToken(tenantId: string): null | ProjectToken {\n const projectTokens = this.config.get('projectTokens') || {}\n const projectToken = projectTokens[tenantId]\n\n if (!projectToken) {\n return null\n }\n\n // Auto-cleanup expired project token\n if (this.isProjectTokenExpired(projectToken)) {\n this.clearProjectToken(tenantId)\n return null\n }\n\n return projectToken\n }\n\n /**\n * Store a project token for a specific tenant\n * @param tenantId - The tenant/CMS ID\n * @param projectToken - The project token to store\n */\n setProjectToken(tenantId: string, projectToken: ProjectToken): void {\n const projectTokens = this.config.get('projectTokens') || {}\n projectTokens[tenantId] = projectToken\n this.config.set('projectTokens', projectTokens)\n }\n\n /**\n * Clear a project token for a specific tenant\n * @param tenantId - The tenant/CMS ID\n */\n clearProjectToken(tenantId: string): void {\n const projectTokens = this.config.get('projectTokens') || {}\n delete projectTokens[tenantId]\n this.config.set('projectTokens', projectTokens)\n }\n\n /**\n * Clear all project tokens\n */\n clearAllProjectTokens(): void {\n this.config.delete('projectTokens')\n }\n\n /**\n * Check if a project token is expired\n * Includes a buffer time to avoid using tokens that are about to expire\n * @param projectToken - The project token to check\n * @returns true if token is expired or will expire within buffer time\n */\n isProjectTokenExpired(projectToken: ProjectToken): boolean {\n const now = Date.now()\n const bufferMs = TOKEN_EXPIRY_BUFFER_SECONDS * 1000\n const expiryWithBuffer = projectToken.expiresAt - bufferMs\n\n return now >= expiryWithBuffer\n }\n\n /**\n * Check if a valid (non-expired) project token exists for a tenant\n * @param tenantId - The tenant/CMS ID\n * @returns true if token exists and is not expired\n */\n hasValidProjectToken(tenantId: string): boolean {\n const projectToken = this.getProjectToken(tenantId)\n if (!projectToken) {\n return false\n }\n return !this.isProjectTokenExpired(projectToken)\n }\n\n /**\n * Get validated JWT claims from a project token\n * @param tenantId - The tenant/CMS ID\n * @returns JWT payload claims or null if token not found or has no claims\n */\n getProjectTokenClaims(tenantId: string): JWTPayload | null {\n const projectToken = this.getProjectToken(tenantId)\n return projectToken?.claims || null\n }\n\n /**\n * Get all tenant IDs that have stored project tokens\n * @returns Array of tenant IDs\n */\n getAllProjectTokenTenantIds(): string[] {\n const projectTokens = this.config.get('projectTokens') || {}\n return Object.keys(projectTokens)\n }\n}\n"],"names":["Conf","TOKEN_EXPIRY_BUFFER_SECONDS","deriveEncryptionKey","TokenStore","config","options","configName","projectName","encryptionKey","clearInvalidConfig","getTokens","tokens","get","setTokens","set","clearTokens","delete","hasValidTokens","isExpired","now","Date","bufferMs","expiryWithBuffer","expiresAt","getAccessToken","accessToken","getRefreshToken","refreshToken","updateAccessToken","expiresIn","existingTokens","Error","getStoragePath","path","getProjectToken","tenantId","projectTokens","projectToken","isProjectTokenExpired","clearProjectToken","setProjectToken","clearAllProjectTokens","hasValidProjectToken","getProjectTokenClaims","claims","getAllProjectTokenTenantIds","Object","keys"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/auth/token-store.ts"],"sourcesContent":["/* eslint-disable perfectionist/sort-classes */\nimport Conf from 'conf'\n\nimport type { FigmaTokens, JWTPayload, ProjectToken, TokenStoreConfig } from './types.js'\n\nimport { TOKEN_EXPIRY_BUFFER_SECONDS } from '../config/oauth.js'\nimport { deriveEncryptionKey } from './crypto-utils.js'\n\n/**\n * Secure storage manager for Figma OAuth2 tokens\n *\n * Uses the `conf` library to store tokens in an OS-specific secure location:\n * - macOS: ~/Library/Preferences/payloadcms-figma\n * - Linux: ~/.config/payloadcms-figma or $XDG_CONFIG_HOME/payloadcms-figma\n * - Windows: %APPDATA%/payloadcms-figma/Config\n *\n * Tokens are encrypted at rest with a machine-specific key and file permissions\n * are set to 0600 (owner read/write only)\n */\nexport class TokenStore {\n private config: Conf<{ projectTokens: Record<string, ProjectToken>; tokens: FigmaTokens }>\n\n constructor(options?: TokenStoreConfig) {\n if (process.env.AWS_EXECUTION_ENV) {\n throw new Error('TokenStore cannot be used in AWS Lambda environments')\n }\n this.config = new Conf<{ projectTokens: Record<string, ProjectToken>; tokens: FigmaTokens }>({\n configName: options?.configName || 'payloadcms-figma',\n projectName: 'payloadcms-figma',\n // Enable encryption with machine-specific key for better security\n encryptionKey: options?.encryptionKey || deriveEncryptionKey(),\n // Clear schema to avoid validation issues\n clearInvalidConfig: true,\n })\n }\n\n /**\n * Retrieve stored tokens\n * @returns FigmaTokens if stored, null otherwise\n */\n getTokens(): FigmaTokens | null {\n const tokens = this.config.get('tokens')\n return tokens || null\n }\n\n /**\n * Store OAuth2 tokens securely\n * @param tokens - Figma OAuth2 tokens to store\n */\n setTokens(tokens: FigmaTokens): void {\n this.config.set('tokens', tokens)\n }\n\n /**\n * Clear all stored tokens (used for logout)\n */\n clearTokens(): void {\n this.config.delete('tokens')\n }\n\n /**\n * Check if valid (non-expired) tokens exist\n * @returns true if tokens exist and are not expired\n */\n hasValidTokens(): boolean {\n const tokens = this.getTokens()\n if (!tokens) {\n return false\n }\n return !this.isExpired()\n }\n\n /**\n * Check if the current access token is expired\n * Includes a buffer time to avoid using tokens that are about to expire\n * @returns true if token is expired or will expire within buffer time\n */\n isExpired(): boolean {\n // Access config directly to avoid circular dependency with getTokens()\n const tokens = this.config.get('tokens')\n if (!tokens) {\n return true\n }\n\n const now = Date.now()\n const bufferMs = TOKEN_EXPIRY_BUFFER_SECONDS * 1000\n const expiryWithBuffer = tokens.expiresAt - bufferMs\n\n return now >= expiryWithBuffer\n }\n\n /**\n * Get the access token if it exists and is valid\n * @returns Access token string or null if expired/missing\n */\n getAccessToken(): null | string {\n if (!this.hasValidTokens()) {\n return null\n }\n const tokens = this.getTokens()\n return tokens?.accessToken || null\n }\n\n /**\n * Get the refresh token if it exists\n * @returns Refresh token string or null if missing\n */\n getRefreshToken(): null | string {\n const tokens = this.getTokens()\n return tokens?.refreshToken || null\n }\n\n /**\n * Update just the access token after a refresh\n * Preserves the existing refresh token and other metadata\n * @param accessToken - New access token\n * @param expiresIn - Expiration time in seconds\n */\n updateAccessToken(accessToken: string, expiresIn: number): void {\n const existingTokens = this.getTokens()\n if (!existingTokens) {\n throw new Error('Cannot update access token: no existing tokens found')\n }\n\n const expiresAt = Date.now() + expiresIn * 1000\n\n this.setTokens({\n ...existingTokens,\n accessToken,\n expiresAt,\n })\n }\n\n /**\n * Get the path to the config file (useful for debugging)\n * @returns Absolute path to the token storage file\n */\n getStoragePath(): string {\n return this.config.path\n }\n\n /**\n * Retrieve a project token for a specific tenant\n * Automatically removes expired tokens from storage\n * @param tenantId - The tenant/CMS ID\n * @returns ProjectToken if stored and valid, null otherwise\n */\n getProjectToken(tenantId: string): null | ProjectToken {\n const projectTokens = this.config.get('projectTokens') || {}\n const projectToken = projectTokens[tenantId]\n\n if (!projectToken) {\n return null\n }\n\n // Auto-cleanup expired project token\n if (this.isProjectTokenExpired(projectToken)) {\n this.clearProjectToken(tenantId)\n return null\n }\n\n return projectToken\n }\n\n /**\n * Store a project token for a specific tenant\n * @param tenantId - The tenant/CMS ID\n * @param projectToken - The project token to store\n */\n setProjectToken(tenantId: string, projectToken: ProjectToken): void {\n const projectTokens = this.config.get('projectTokens') || {}\n projectTokens[tenantId] = projectToken\n this.config.set('projectTokens', projectTokens)\n }\n\n /**\n * Clear a project token for a specific tenant\n * @param tenantId - The tenant/CMS ID\n */\n clearProjectToken(tenantId: string): void {\n const projectTokens = this.config.get('projectTokens') || {}\n delete projectTokens[tenantId]\n this.config.set('projectTokens', projectTokens)\n }\n\n /**\n * Clear all project tokens\n */\n clearAllProjectTokens(): void {\n this.config.delete('projectTokens')\n }\n\n /**\n * Check if a project token is expired\n * Includes a buffer time to avoid using tokens that are about to expire\n * @param projectToken - The project token to check\n * @returns true if token is expired or will expire within buffer time\n */\n isProjectTokenExpired(projectToken: ProjectToken): boolean {\n const now = Date.now()\n const bufferMs = TOKEN_EXPIRY_BUFFER_SECONDS * 1000\n const expiryWithBuffer = projectToken.expiresAt - bufferMs\n\n return now >= expiryWithBuffer\n }\n\n /**\n * Check if a valid (non-expired) project token exists for a tenant\n * @param tenantId - The tenant/CMS ID\n * @returns true if token exists and is not expired\n */\n hasValidProjectToken(tenantId: string): boolean {\n const projectToken = this.getProjectToken(tenantId)\n if (!projectToken) {\n return false\n }\n return !this.isProjectTokenExpired(projectToken)\n }\n\n /**\n * Get validated JWT claims from a project token\n * @param tenantId - The tenant/CMS ID\n * @returns JWT payload claims or null if token not found or has no claims\n */\n getProjectTokenClaims(tenantId: string): JWTPayload | null {\n const projectToken = this.getProjectToken(tenantId)\n return projectToken?.claims || null\n }\n\n /**\n * Get all tenant IDs that have stored project tokens\n * @returns Array of tenant IDs\n */\n getAllProjectTokenTenantIds(): string[] {\n const projectTokens = this.config.get('projectTokens') || {}\n return Object.keys(projectTokens)\n }\n}\n"],"names":["Conf","TOKEN_EXPIRY_BUFFER_SECONDS","deriveEncryptionKey","TokenStore","config","options","process","env","AWS_EXECUTION_ENV","Error","configName","projectName","encryptionKey","clearInvalidConfig","getTokens","tokens","get","setTokens","set","clearTokens","delete","hasValidTokens","isExpired","now","Date","bufferMs","expiryWithBuffer","expiresAt","getAccessToken","accessToken","getRefreshToken","refreshToken","updateAccessToken","expiresIn","existingTokens","getStoragePath","path","getProjectToken","tenantId","projectTokens","projectToken","isProjectTokenExpired","clearProjectToken","setProjectToken","clearAllProjectTokens","hasValidProjectToken","getProjectTokenClaims","claims","getAllProjectTokenTenantIds","Object","keys"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AA0BA;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,wBAAwB;IACxB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,gDAAgD;IAChD,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,gEAAgE;IAChE,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,mDAAmD;IACnD,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,mDAAmD;IACnD,GAAG,CAAC,EAAE,OAAO,CAAA;CACd;AAiDD;;;;;;;;;;GAUG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsR5E"}
|
package/dist/commands/init.js
CHANGED
|
@@ -2,7 +2,6 @@ import * as p from '@clack/prompts';
|
|
|
2
2
|
import fs from 'fs/promises';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import pc from 'picocolors';
|
|
5
|
-
import { ControlPlaneError, getTenantDetails } from '../api/control-plane.js';
|
|
6
5
|
import { FigmaApiError } from '../api/figma-api.js';
|
|
7
6
|
import { getValidAccessToken } from '../auth/oauth-flow.js';
|
|
8
7
|
import { getValidProjectToken, ProjectTokenError } from '../auth/project-token.js';
|
|
@@ -61,45 +60,30 @@ import { loginCommand } from './login.js';
|
|
|
61
60
|
// Check authentication
|
|
62
61
|
const tokenStore = new TokenStore();
|
|
63
62
|
const s = p.spinner();
|
|
64
|
-
let accessToken;
|
|
65
63
|
if (options.skipAuth) {
|
|
66
64
|
// Skip authentication for testing/development
|
|
67
65
|
p.log.warn(pc.yellow('Skipping authentication (--skip-auth mode)'));
|
|
68
|
-
accessToken = 'mock-access-token';
|
|
69
66
|
} else {
|
|
70
67
|
try {
|
|
71
68
|
// Check for valid cached tokens first (no API call needed)
|
|
72
|
-
if (tokenStore.hasValidTokens()) {
|
|
73
|
-
// Use cached token silently - no spinner needed
|
|
74
|
-
accessToken = tokenStore.getAccessToken();
|
|
75
|
-
} else {
|
|
69
|
+
if (!tokenStore.hasValidTokens()) {
|
|
76
70
|
// Need to refresh or authenticate - show spinner for API call
|
|
77
71
|
s.start('Checking authentication...');
|
|
78
72
|
const token = await getValidAccessToken(tokenStore);
|
|
79
73
|
if (!token) {
|
|
80
74
|
s.stop(pc.yellow('⚠ Not authenticated'));
|
|
81
75
|
p.log.info('Authentication required to continue');
|
|
82
|
-
// Prompt user to authenticate now
|
|
83
|
-
const shouldAuth = await p.confirm({
|
|
84
|
-
initialValue: true,
|
|
85
|
-
message: 'Would you like to authenticate now?'
|
|
86
|
-
});
|
|
87
|
-
if (p.isCancel(shouldAuth) || !shouldAuth) {
|
|
88
|
-
p.cancel('Operation cancelled');
|
|
89
|
-
process.exit(0);
|
|
90
|
-
}
|
|
91
76
|
// Run login command
|
|
92
|
-
await loginCommand(
|
|
77
|
+
await loginCommand({
|
|
78
|
+
showNextSteps: false
|
|
79
|
+
});
|
|
93
80
|
// Get token after auth
|
|
94
81
|
const newToken = await getValidAccessToken(tokenStore);
|
|
95
82
|
if (!newToken) {
|
|
96
83
|
p.log.error('Authentication failed');
|
|
97
84
|
process.exit(1);
|
|
98
85
|
}
|
|
99
|
-
accessToken = newToken;
|
|
100
|
-
p.log.success(pc.green('✓ Authenticated'));
|
|
101
86
|
} else {
|
|
102
|
-
accessToken = token;
|
|
103
87
|
s.stop(pc.green('✓ Authenticated'));
|
|
104
88
|
}
|
|
105
89
|
}
|
|
@@ -113,57 +97,13 @@ import { loginCommand } from './login.js';
|
|
|
113
97
|
// Note: We no longer check for figma.config.json here
|
|
114
98
|
// Instead, the AST detection will check if figma object already exists in payload.config.ts
|
|
115
99
|
// and skip modification if it does (unless --force is used)
|
|
116
|
-
// Step 3: Get CMS ID
|
|
100
|
+
// Step 3: Get CMS ID (required argument)
|
|
117
101
|
log.debug('Configuring Project...');
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
// Prompt for ID if not provided
|
|
122
|
-
if (!tenantId) {
|
|
123
|
-
const input = await p.text({
|
|
124
|
-
message: 'Enter your CMS ID:',
|
|
125
|
-
placeholder: 'tenant_abc123',
|
|
126
|
-
validate: (value)=>{
|
|
127
|
-
if (!value || typeof value !== 'string') {
|
|
128
|
-
return 'CMS ID is required';
|
|
129
|
-
}
|
|
130
|
-
return undefined;
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
if (p.isCancel(input)) {
|
|
134
|
-
p.cancel('Operation cancelled');
|
|
135
|
-
process.exit(0);
|
|
136
|
-
}
|
|
137
|
-
tenantId = input;
|
|
138
|
-
}
|
|
139
|
-
// Try to fetch tenant details
|
|
140
|
-
try {
|
|
141
|
-
log.debug('Using mock Control Plane API (no real network calls)');
|
|
142
|
-
selectedTenant = await getTenantDetails(accessToken, tenantId);
|
|
143
|
-
log.debug(`Using: ${selectedTenant.domain}`);
|
|
144
|
-
} catch (error) {
|
|
145
|
-
p.log.error(pc.red('✗ Failed to fetch CMS details'));
|
|
146
|
-
// Check if permission error (403)
|
|
147
|
-
if (error instanceof ControlPlaneError && error.statusCode === 403) {
|
|
148
|
-
p.log.error('You do not have permission to access the provided CMS ID. Please try again.');
|
|
149
|
-
} else if (error instanceof ControlPlaneError && error.statusCode === 404) {
|
|
150
|
-
p.log.error('Tenant ID not found. Verify the ID is correct.');
|
|
151
|
-
} else {
|
|
152
|
-
p.log.error(error instanceof Error ? error.message : 'Unknown error');
|
|
153
|
-
}
|
|
154
|
-
// Clear tenantId to prompt again
|
|
155
|
-
tenantId = undefined;
|
|
156
|
-
// Ask if they want to retry
|
|
157
|
-
const shouldRetry = await p.confirm({
|
|
158
|
-
initialValue: true,
|
|
159
|
-
message: 'Would you like to try a different CMS ID?'
|
|
160
|
-
});
|
|
161
|
-
if (p.isCancel(shouldRetry) || !shouldRetry) {
|
|
162
|
-
p.cancel('Operation cancelled');
|
|
163
|
-
process.exit(1);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
102
|
+
if (!options.id) {
|
|
103
|
+
p.log.error('CMS ID is required. Use --id <tenant_id>');
|
|
104
|
+
process.exit(1);
|
|
166
105
|
}
|
|
106
|
+
const tenantId = options.id;
|
|
167
107
|
// Step 4: Detect or scaffold Payload project
|
|
168
108
|
const isInProject = await isInProjectDirectory();
|
|
169
109
|
if (isInProject) {
|
|
@@ -196,7 +136,7 @@ import { loginCommand } from './login.js';
|
|
|
196
136
|
}
|
|
197
137
|
s.start('Checking Payload configuration...');
|
|
198
138
|
const modResult = await ensurePayloadFigmaConfig(process.cwd(), projectInfo.packageManager || 'pnpm', {
|
|
199
|
-
contentSystemId:
|
|
139
|
+
contentSystemId: tenantId,
|
|
200
140
|
region: options.region || 'us-east-1',
|
|
201
141
|
useContentSystem: !options.noContentSystem
|
|
202
142
|
});
|
|
@@ -241,14 +181,12 @@ import { loginCommand } from './login.js';
|
|
|
241
181
|
}
|
|
242
182
|
// Generate project token (unless skipping auth)
|
|
243
183
|
if (!options.skipAuth) {
|
|
244
|
-
await generateProjectTokenWithFeedback(tokenStore,
|
|
184
|
+
await generateProjectTokenWithFeedback(tokenStore, tenantId, s);
|
|
245
185
|
}
|
|
246
186
|
// Success message for existing project
|
|
247
187
|
p.outro(pc.green('✓ Project initialized successfully!'));
|
|
248
188
|
const nextSteps = [
|
|
249
|
-
|
|
250
|
-
'Start development server: `pnpm dev`',
|
|
251
|
-
`Access your CMS at: ${pc.cyan(`https://${selectedTenant.domain}`)}`
|
|
189
|
+
'Start development server: `pnpm dev`'
|
|
252
190
|
].filter(Boolean);
|
|
253
191
|
p.note(nextSteps.join('\n'), 'Next Steps');
|
|
254
192
|
} else {
|
|
@@ -300,7 +238,7 @@ import { loginCommand } from './login.js';
|
|
|
300
238
|
// Modify Payload configuration
|
|
301
239
|
s.start('Checking Payload configuration...');
|
|
302
240
|
const modResult = await ensurePayloadFigmaConfig(fullPath, 'pnpm', {
|
|
303
|
-
contentSystemId:
|
|
241
|
+
contentSystemId: tenantId,
|
|
304
242
|
region: options.region || 'us-east-1',
|
|
305
243
|
useContentSystem: !options.noContentSystem
|
|
306
244
|
});
|
|
@@ -325,7 +263,7 @@ import { loginCommand } from './login.js';
|
|
|
325
263
|
}
|
|
326
264
|
// Generate project token (unless skipping auth)
|
|
327
265
|
if (!options.skipAuth) {
|
|
328
|
-
await generateProjectTokenWithFeedback(tokenStore,
|
|
266
|
+
await generateProjectTokenWithFeedback(tokenStore, tenantId, s);
|
|
329
267
|
}
|
|
330
268
|
// Initialize git repository (after all files including lock file are ready)
|
|
331
269
|
initializeGitRepo(fullPath);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/init.ts"],"sourcesContent":["import * as p from '@clack/prompts'\nimport fs from 'fs/promises'\nimport path from 'path'\nimport pc from 'picocolors'\n\nimport type { Tenant } from '../types/config.js'\n\nimport { ControlPlaneError, getTenantDetails } from '../api/control-plane.js'\nimport { FigmaApiError } from '../api/figma-api.js'\nimport { getValidAccessToken } from '../auth/oauth-flow.js'\nimport { getValidProjectToken, ProjectTokenError } from '../auth/project-token.js'\nimport { TokenStore } from '../auth/token-store.js'\nimport { isDebug } from '../utils/is-debug.js'\nimport * as log from '../utils/log.js'\nimport {\n displayManualInstructions,\n ensurePayloadFigmaConfig,\n} from '../utils/payload-config-modifier.js'\nimport {\n detectPayloadProject,\n hasRequiredDependencies,\n initializeGitRepo,\n installDependencies,\n isInProjectDirectory,\n scaffoldProject,\n validatePayloadVersion,\n} from '../utils/project.js'\nimport { loginCommand } from './login.js'\n\n/**\n * Options for init command\n */\nexport interface InitCommandOptions {\n /** Enable debug mode */\n debug?: boolean\n /** Force reconfiguration of existing project */\n force?: boolean\n /** Tenant ID to use (optional - will prompt if not provided) */\n id?: string\n /** Project name (for scaffolding) */\n name?: string\n /** Disable Content System (defaults to enabled) */\n noContentSystem?: boolean\n /** AWS region for deployment (defaults to us-east-1) */\n region?: string\n /** Skip authentication check (for testing/development) */\n skipAuth?: boolean\n /** Skip prompts and use defaults where possible */\n yes?: boolean\n}\n\n/**\n * Generate and store project token for a tenant\n * Non-blocking - will show warning but not exit on failure\n * Only shows feedback if DEBUG mode is enabled, otherwise runs silently\n *\n * @param tokenStore - Token store instance\n * @param tenantId - Tenant ID to generate token for\n * @param spinner - Clack spinner instance for status updates (only used in debug mode)\n */\nasync function generateProjectTokenWithFeedback(\n tokenStore: TokenStore,\n tenantId: string,\n spinner: ReturnType<typeof p.spinner>,\n): Promise<void> {\n if (isDebug()) {\n spinner.start('Generating project token...')\n }\n\n try {\n const projectToken = await getValidProjectToken(tokenStore, tenantId)\n if (isDebug()) {\n if (projectToken) {\n spinner.stop(pc.green('✓ Project token generated'))\n } else {\n spinner.stop(pc.yellow('⚠ Project token not generated (authentication required)'))\n }\n }\n } catch (error) {\n if (isDebug()) {\n spinner.stop(pc.yellow('⚠ Project token generation failed'))\n }\n // Always show failures, even without debug\n if (error instanceof ProjectTokenError || error instanceof FigmaApiError) {\n log.warning(error.message)\n p.note(\n 'Project token is used for authenticating to the Content API.\\nYou can continue without it, but may need to regenerate later.',\n 'Note',\n )\n } else {\n log.warning(\n `Unable to retrieve project token: ${error instanceof Error ? error.message : 'Unknown error'}`,\n )\n }\n // Don't exit - token generation failure shouldn't block initialization\n }\n}\n\n/**\n * Handle the `init` command\n *\n * Sets up a project by:\n * 1. Checking authentication\n * 2. Detecting/scaffolding Payload project\n * 3. Fetching tenant details\n * 4. Storing configuration\n *\n * @param options - Command options\n */\nexport async function initCommand(options: InitCommandOptions): Promise<void> {\n // Check authentication\n const tokenStore = new TokenStore()\n const s = p.spinner()\n\n let accessToken: string\n\n if (options.skipAuth) {\n // Skip authentication for testing/development\n p.log.warn(pc.yellow('Skipping authentication (--skip-auth mode)'))\n accessToken = 'mock-access-token'\n } else {\n try {\n // Check for valid cached tokens first (no API call needed)\n if (tokenStore.hasValidTokens()) {\n // Use cached token silently - no spinner needed\n accessToken = tokenStore.getAccessToken()!\n } else {\n // Need to refresh or authenticate - show spinner for API call\n s.start('Checking authentication...')\n const token = await getValidAccessToken(tokenStore)\n if (!token) {\n s.stop(pc.yellow('⚠ Not authenticated'))\n p.log.info('Authentication required to continue')\n\n // Prompt user to authenticate now\n const shouldAuth = await p.confirm({\n initialValue: true,\n message: 'Would you like to authenticate now?',\n })\n\n if (p.isCancel(shouldAuth) || !shouldAuth) {\n p.cancel('Operation cancelled')\n process.exit(0)\n }\n\n // Run login command\n await loginCommand()\n\n // Get token after auth\n const newToken = await getValidAccessToken(tokenStore)\n if (!newToken) {\n p.log.error('Authentication failed')\n process.exit(1)\n }\n accessToken = newToken\n p.log.success(pc.green('✓ Authenticated'))\n } else {\n accessToken = token\n s.stop(pc.green('✓ Authenticated'))\n }\n }\n } catch (error) {\n s.stop(pc.red('✗ Authentication failed'))\n log.error(error instanceof Error ? error.message : 'Unknown error')\n p.note('Run `figma auth` to authenticate', 'Tip')\n process.exit(1)\n }\n }\n\n // Note: We no longer check for figma.config.json here\n // Instead, the AST detection will check if figma object already exists in payload.config.ts\n // and skip modification if it does (unless --force is used)\n\n // Step 3: Get CMS ID with retry loop\n log.debug('Configuring Project...')\n\n let tenantId = options.id\n let selectedTenant: Tenant | undefined\n\n while (!selectedTenant) {\n // Prompt for ID if not provided\n if (!tenantId) {\n const input = await p.text({\n message: 'Enter your CMS ID:',\n placeholder: 'tenant_abc123',\n validate: (value) => {\n if (!value || typeof value !== 'string') {\n return 'CMS ID is required'\n }\n return undefined\n },\n })\n\n if (p.isCancel(input)) {\n p.cancel('Operation cancelled')\n process.exit(0)\n }\n\n tenantId = input\n }\n\n // Try to fetch tenant details\n try {\n log.debug('Using mock Control Plane API (no real network calls)')\n selectedTenant = await getTenantDetails(accessToken, tenantId)\n log.debug(`Using: ${selectedTenant.domain}`)\n } catch (error) {\n p.log.error(pc.red('✗ Failed to fetch CMS details'))\n\n // Check if permission error (403)\n if (error instanceof ControlPlaneError && error.statusCode === 403) {\n p.log.error('You do not have permission to access the provided CMS ID. Please try again.')\n } else if (error instanceof ControlPlaneError && error.statusCode === 404) {\n p.log.error('Tenant ID not found. Verify the ID is correct.')\n } else {\n p.log.error(error instanceof Error ? error.message : 'Unknown error')\n }\n\n // Clear tenantId to prompt again\n tenantId = undefined\n\n // Ask if they want to retry\n const shouldRetry = await p.confirm({\n initialValue: true,\n message: 'Would you like to try a different CMS ID?',\n })\n\n if (p.isCancel(shouldRetry) || !shouldRetry) {\n p.cancel('Operation cancelled')\n process.exit(1)\n }\n }\n }\n\n // Step 4: Detect or scaffold Payload project\n const isInProject = await isInProjectDirectory()\n\n if (isInProject) {\n // ===== EXISTING PROJECT FLOW =====\n log.debug('Project directory detected')\n\n // Detect Payload\n const projectInfo = await detectPayloadProject()\n\n if (projectInfo.hasPayload) {\n // Validate existing Payload version\n if (projectInfo.payloadVersion && !validatePayloadVersion(projectInfo.payloadVersion)) {\n p.log.warn(\n pc.yellow(\n `Payload version ${projectInfo.payloadVersion} detected. Version 3.x is required.`,\n ),\n )\n p.note('Upgrade to Payload 3.x before continuing', 'Action Required')\n process.exit(1)\n }\n\n p.log.success(pc.green(`✓ Payload ${projectInfo.payloadVersion || 'detected'}`))\n\n // Check dependencies\n s.start('Checking dependencies...')\n const hasDeps = await hasRequiredDependencies(process.cwd())\n s.stop(pc.green('✓ Dependencies checked'))\n\n if (!hasDeps) {\n const shouldInstall = await p.confirm({\n initialValue: true,\n message: 'Install dependencies now?',\n })\n\n if (!p.isCancel(shouldInstall) && shouldInstall) {\n s.start('Installing dependencies...')\n await installDependencies(process.cwd(), projectInfo.packageManager || 'pnpm')\n s.stop(pc.green('✓ Dependencies installed'))\n }\n }\n\n s.start('Checking Payload configuration...')\n const modResult = await ensurePayloadFigmaConfig(\n process.cwd(),\n projectInfo.packageManager || 'pnpm',\n {\n contentSystemId: selectedTenant.id,\n region: options.region || 'us-east-1',\n useContentSystem: !options.noContentSystem,\n },\n )\n\n if (!modResult.success) {\n s.stop(pc.red('✗ Configuration check failed'))\n displayManualInstructions(modResult.error || 'Unknown error')\n process.exit(1)\n }\n\n if (modResult.modified) {\n s.stop(pc.green('✓ Payload configuration updated'))\n if (modResult.changes.length > 0) {\n modResult.changes.forEach((change) => log.debug(pc.dim(` → ${change}`)))\n }\n } else {\n s.stop(pc.green('✓ Payload configuration valid'))\n }\n\n // Display warnings if any\n if (modResult.warnings && modResult.warnings.length > 0) {\n modResult.warnings.forEach((warning) => {\n p.log.warn(pc.yellow(`⚠ ${warning}`))\n })\n }\n } else {\n // Has package.json but no Payload - offer to add Payload\n p.log.warn(pc.yellow('⚠ No Payload detected in this project'))\n\n const shouldAddPayload = await p.confirm({\n initialValue: true,\n message: 'Would you like to add Payload to this project?',\n })\n\n if (p.isCancel(shouldAddPayload)) {\n p.cancel('Operation cancelled')\n process.exit(0)\n }\n\n if (!shouldAddPayload) {\n p.log.error('Payload is required to use Figma CMS')\n process.exit(1)\n }\n\n // TODO: Add Payload to existing project (future enhancement)\n p.log.error('Adding Payload to existing projects is not yet supported')\n p.note('Create a new project or manually add Payload dependencies', 'Action Required')\n process.exit(1)\n }\n\n // Generate project token (unless skipping auth)\n if (!options.skipAuth) {\n await generateProjectTokenWithFeedback(tokenStore, selectedTenant.id, s)\n }\n\n // Success message for existing project\n p.outro(pc.green('✓ Project initialized successfully!'))\n\n const nextSteps = [\n selectedTenant.status === 'provisioning'\n ? 'Wait for CMS provisioning to complete (check status with `@payloadcms/figma list`)'\n : undefined,\n 'Start development server: `pnpm dev`',\n `Access your CMS at: ${pc.cyan(`https://${selectedTenant.domain}`)}`,\n ].filter(Boolean)\n\n p.note(nextSteps.join('\\n'), 'Next Steps')\n } else {\n // ===== NEW PROJECT FLOW =====\n // p.log.info('No project detected - Creating New Project')\n\n // Prompt for path\n const projectPathInput = await p.text({\n initialValue: './',\n message: 'Enter path to create project:',\n placeholder: './my-cms-project',\n validate: (value) => {\n if (!value) {\n return 'Path is required'\n }\n // Allow relative or absolute paths\n return undefined\n },\n })\n\n if (p.isCancel(projectPathInput)) {\n p.cancel('Operation cancelled')\n process.exit(0)\n }\n\n const projectPath = projectPathInput\n const fullPath = path.resolve(process.cwd(), projectPath)\n\n // Get project name from path or prompt\n const projectName = options.name || path.basename(fullPath)\n\n // Create directory\n try {\n await fs.mkdir(fullPath, { recursive: true })\n } catch (error) {\n p.log.error(\n `Failed to create directory: ${error instanceof Error ? error.message : 'Unknown error'}`,\n )\n process.exit(1)\n }\n\n // Scaffold project\n s.start('Downloading template from GitHub...')\n try {\n await scaffoldProject(fullPath, projectName)\n s.stop(pc.green('✓ Template downloaded'))\n\n s.start('Installing dependencies...')\n await installDependencies(fullPath, 'pnpm')\n s.stop(pc.green('✓ Dependencies installed'))\n } catch (error) {\n s.stop(pc.red('✗ Failed'))\n log.error(error instanceof Error ? error.message : 'Unknown error')\n process.exit(1)\n }\n\n // Modify Payload configuration\n s.start('Checking Payload configuration...')\n const modResult = await ensurePayloadFigmaConfig(fullPath, 'pnpm', {\n contentSystemId: selectedTenant.id,\n region: options.region || 'us-east-1',\n useContentSystem: !options.noContentSystem,\n })\n\n if (!modResult.success) {\n s.stop(pc.red('✗ Configuration check failed'))\n displayManualInstructions(modResult.error || 'Unknown error')\n process.exit(1)\n }\n\n if (modResult.modified) {\n s.stop(pc.green('✓ Payload configuration updated'))\n if (modResult.changes.length > 0) {\n modResult.changes.forEach((change) => log.debug(pc.dim(` → ${change}`)))\n }\n } else {\n s.stop(pc.green('✓ Payload configuration valid'))\n }\n\n // Display warnings if any\n if (modResult.warnings && modResult.warnings.length > 0) {\n modResult.warnings.forEach((warning) => {\n p.log.warn(pc.yellow(`⚠ ${warning}`))\n })\n }\n\n // Generate project token (unless skipping auth)\n if (!options.skipAuth) {\n await generateProjectTokenWithFeedback(tokenStore, selectedTenant.id, s)\n }\n\n // Initialize git repository (after all files including lock file are ready)\n initializeGitRepo(fullPath)\n\n // Success message for NEW project\n p.log.step(pc.bgGreen(pc.black(' Project created successfully! ')))\n\n const relativePath = path.relative(process.cwd(), fullPath)\n const nextSteps: string[] = []\n\n // Only show cd command if user needs to navigate\n if (relativePath && relativePath !== '.') {\n nextSteps.push(`cd ${relativePath}`)\n }\n\n nextSteps.push(\n 'pnpm dev or follow directions in README.md',\n '',\n 'Documentation:',\n '- Getting Started: https://payloadcms.com/docs/getting-started/what-is-payload',\n '- Configuration: https://payloadcms.com/docs/configuration/overview',\n )\n\n p.note(nextSteps.join('\\n'), 'Next Steps')\n p.outro(pc.green('✓ Done'))\n }\n}\n"],"names":["p","fs","path","pc","ControlPlaneError","getTenantDetails","FigmaApiError","getValidAccessToken","getValidProjectToken","ProjectTokenError","TokenStore","isDebug","log","displayManualInstructions","ensurePayloadFigmaConfig","detectPayloadProject","hasRequiredDependencies","initializeGitRepo","installDependencies","isInProjectDirectory","scaffoldProject","validatePayloadVersion","loginCommand","generateProjectTokenWithFeedback","tokenStore","tenantId","spinner","start","projectToken","stop","green","yellow","error","warning","message","note","Error","initCommand","options","s","accessToken","skipAuth","warn","hasValidTokens","getAccessToken","token","info","shouldAuth","confirm","initialValue","isCancel","cancel","process","exit","newToken","success","red","debug","id","selectedTenant","input","text","placeholder","validate","value","undefined","domain","statusCode","shouldRetry","isInProject","projectInfo","hasPayload","payloadVersion","hasDeps","cwd","shouldInstall","packageManager","modResult","contentSystemId","region","useContentSystem","noContentSystem","modified","changes","length","forEach","change","dim","warnings","shouldAddPayload","outro","nextSteps","status","cyan","filter","Boolean","join","projectPathInput","projectPath","fullPath","resolve","projectName","name","basename","mkdir","recursive","step","bgGreen","black","relativePath","relative","push"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/commands/init.ts"],"sourcesContent":["import * as p from '@clack/prompts'\nimport fs from 'fs/promises'\nimport path from 'path'\nimport pc from 'picocolors'\n\nimport { FigmaApiError } from '../api/figma-api.js'\nimport { getValidAccessToken } from '../auth/oauth-flow.js'\nimport { getValidProjectToken, ProjectTokenError } from '../auth/project-token.js'\nimport { TokenStore } from '../auth/token-store.js'\nimport { isDebug } from '../utils/is-debug.js'\nimport * as log from '../utils/log.js'\nimport {\n displayManualInstructions,\n ensurePayloadFigmaConfig,\n} from '../utils/payload-config-modifier.js'\nimport {\n detectPayloadProject,\n hasRequiredDependencies,\n initializeGitRepo,\n installDependencies,\n isInProjectDirectory,\n scaffoldProject,\n validatePayloadVersion,\n} from '../utils/project.js'\nimport { loginCommand } from './login.js'\n\n/**\n * Options for init command\n */\nexport interface InitCommandOptions {\n /** Enable debug mode */\n debug?: boolean\n /** Force reconfiguration of existing project */\n force?: boolean\n /** Tenant ID to use (optional - will prompt if not provided) */\n id?: string\n /** Project name (for scaffolding) */\n name?: string\n /** Disable Content System (defaults to enabled) */\n noContentSystem?: boolean\n /** AWS region for deployment (defaults to us-east-1) */\n region?: string\n /** Skip authentication check (for testing/development) */\n skipAuth?: boolean\n /** Skip prompts and use defaults where possible */\n yes?: boolean\n}\n\n/**\n * Generate and store project token for a tenant\n * Non-blocking - will show warning but not exit on failure\n * Only shows feedback if DEBUG mode is enabled, otherwise runs silently\n *\n * @param tokenStore - Token store instance\n * @param tenantId - Tenant ID to generate token for\n * @param spinner - Clack spinner instance for status updates (only used in debug mode)\n */\nasync function generateProjectTokenWithFeedback(\n tokenStore: TokenStore,\n tenantId: string,\n spinner: ReturnType<typeof p.spinner>,\n): Promise<void> {\n if (isDebug()) {\n spinner.start('Generating project token...')\n }\n\n try {\n const projectToken = await getValidProjectToken(tokenStore, tenantId)\n if (isDebug()) {\n if (projectToken) {\n spinner.stop(pc.green('✓ Project token generated'))\n } else {\n spinner.stop(pc.yellow('⚠ Project token not generated (authentication required)'))\n }\n }\n } catch (error) {\n if (isDebug()) {\n spinner.stop(pc.yellow('⚠ Project token generation failed'))\n }\n // Always show failures, even without debug\n if (error instanceof ProjectTokenError || error instanceof FigmaApiError) {\n log.warning(error.message)\n p.note(\n 'Project token is used for authenticating to the Content API.\\nYou can continue without it, but may need to regenerate later.',\n 'Note',\n )\n } else {\n log.warning(\n `Unable to retrieve project token: ${error instanceof Error ? error.message : 'Unknown error'}`,\n )\n }\n // Don't exit - token generation failure shouldn't block initialization\n }\n}\n\n/**\n * Handle the `init` command\n *\n * Sets up a project by:\n * 1. Checking authentication\n * 2. Detecting/scaffolding Payload project\n * 3. Fetching tenant details\n * 4. Storing configuration\n *\n * @param options - Command options\n */\nexport async function initCommand(options: InitCommandOptions): Promise<void> {\n // Check authentication\n const tokenStore = new TokenStore()\n const s = p.spinner()\n\n if (options.skipAuth) {\n // Skip authentication for testing/development\n p.log.warn(pc.yellow('Skipping authentication (--skip-auth mode)'))\n } else {\n try {\n // Check for valid cached tokens first (no API call needed)\n if (!tokenStore.hasValidTokens()) {\n // Need to refresh or authenticate - show spinner for API call\n s.start('Checking authentication...')\n const token = await getValidAccessToken(tokenStore)\n if (!token) {\n s.stop(pc.yellow('⚠ Not authenticated'))\n p.log.info('Authentication required to continue')\n\n // Run login command\n await loginCommand({ showNextSteps: false })\n\n // Get token after auth\n const newToken = await getValidAccessToken(tokenStore)\n if (!newToken) {\n p.log.error('Authentication failed')\n process.exit(1)\n }\n } else {\n s.stop(pc.green('✓ Authenticated'))\n }\n }\n } catch (error) {\n s.stop(pc.red('✗ Authentication failed'))\n log.error(error instanceof Error ? error.message : 'Unknown error')\n p.note('Run `figma auth` to authenticate', 'Tip')\n process.exit(1)\n }\n }\n\n // Note: We no longer check for figma.config.json here\n // Instead, the AST detection will check if figma object already exists in payload.config.ts\n // and skip modification if it does (unless --force is used)\n\n // Step 3: Get CMS ID (required argument)\n log.debug('Configuring Project...')\n\n if (!options.id) {\n p.log.error('CMS ID is required. Use --id <tenant_id>')\n process.exit(1)\n }\n\n const tenantId = options.id\n\n // Step 4: Detect or scaffold Payload project\n const isInProject = await isInProjectDirectory()\n\n if (isInProject) {\n // ===== EXISTING PROJECT FLOW =====\n log.debug('Project directory detected')\n\n // Detect Payload\n const projectInfo = await detectPayloadProject()\n\n if (projectInfo.hasPayload) {\n // Validate existing Payload version\n if (projectInfo.payloadVersion && !validatePayloadVersion(projectInfo.payloadVersion)) {\n p.log.warn(\n pc.yellow(\n `Payload version ${projectInfo.payloadVersion} detected. Version 3.x is required.`,\n ),\n )\n p.note('Upgrade to Payload 3.x before continuing', 'Action Required')\n process.exit(1)\n }\n\n p.log.success(pc.green(`✓ Payload ${projectInfo.payloadVersion || 'detected'}`))\n\n // Check dependencies\n s.start('Checking dependencies...')\n const hasDeps = await hasRequiredDependencies(process.cwd())\n s.stop(pc.green('✓ Dependencies checked'))\n\n if (!hasDeps) {\n const shouldInstall = await p.confirm({\n initialValue: true,\n message: 'Install dependencies now?',\n })\n\n if (!p.isCancel(shouldInstall) && shouldInstall) {\n s.start('Installing dependencies...')\n await installDependencies(process.cwd(), projectInfo.packageManager || 'pnpm')\n s.stop(pc.green('✓ Dependencies installed'))\n }\n }\n\n s.start('Checking Payload configuration...')\n const modResult = await ensurePayloadFigmaConfig(\n process.cwd(),\n projectInfo.packageManager || 'pnpm',\n {\n contentSystemId: tenantId,\n region: options.region || 'us-east-1',\n useContentSystem: !options.noContentSystem,\n },\n )\n\n if (!modResult.success) {\n s.stop(pc.red('✗ Configuration check failed'))\n displayManualInstructions(modResult.error || 'Unknown error')\n process.exit(1)\n }\n\n if (modResult.modified) {\n s.stop(pc.green('✓ Payload configuration updated'))\n if (modResult.changes.length > 0) {\n modResult.changes.forEach((change) => log.debug(pc.dim(` → ${change}`)))\n }\n } else {\n s.stop(pc.green('✓ Payload configuration valid'))\n }\n\n // Display warnings if any\n if (modResult.warnings && modResult.warnings.length > 0) {\n modResult.warnings.forEach((warning) => {\n p.log.warn(pc.yellow(`⚠ ${warning}`))\n })\n }\n } else {\n // Has package.json but no Payload - offer to add Payload\n p.log.warn(pc.yellow('⚠ No Payload detected in this project'))\n\n const shouldAddPayload = await p.confirm({\n initialValue: true,\n message: 'Would you like to add Payload to this project?',\n })\n\n if (p.isCancel(shouldAddPayload)) {\n p.cancel('Operation cancelled')\n process.exit(0)\n }\n\n if (!shouldAddPayload) {\n p.log.error('Payload is required to use Figma CMS')\n process.exit(1)\n }\n\n // TODO: Add Payload to existing project (future enhancement)\n p.log.error('Adding Payload to existing projects is not yet supported')\n p.note('Create a new project or manually add Payload dependencies', 'Action Required')\n process.exit(1)\n }\n\n // Generate project token (unless skipping auth)\n if (!options.skipAuth) {\n await generateProjectTokenWithFeedback(tokenStore, tenantId, s)\n }\n\n // Success message for existing project\n p.outro(pc.green('✓ Project initialized successfully!'))\n\n const nextSteps = ['Start development server: `pnpm dev`'].filter(Boolean)\n\n p.note(nextSteps.join('\\n'), 'Next Steps')\n } else {\n // ===== NEW PROJECT FLOW =====\n // p.log.info('No project detected - Creating New Project')\n\n // Prompt for path\n const projectPathInput = await p.text({\n initialValue: './',\n message: 'Enter path to create project:',\n placeholder: './my-cms-project',\n validate: (value) => {\n if (!value) {\n return 'Path is required'\n }\n // Allow relative or absolute paths\n return undefined\n },\n })\n\n if (p.isCancel(projectPathInput)) {\n p.cancel('Operation cancelled')\n process.exit(0)\n }\n\n const projectPath = projectPathInput\n const fullPath = path.resolve(process.cwd(), projectPath)\n\n // Get project name from path or prompt\n const projectName = options.name || path.basename(fullPath)\n\n // Create directory\n try {\n await fs.mkdir(fullPath, { recursive: true })\n } catch (error) {\n p.log.error(\n `Failed to create directory: ${error instanceof Error ? error.message : 'Unknown error'}`,\n )\n process.exit(1)\n }\n\n // Scaffold project\n s.start('Downloading template from GitHub...')\n try {\n await scaffoldProject(fullPath, projectName)\n s.stop(pc.green('✓ Template downloaded'))\n\n s.start('Installing dependencies...')\n await installDependencies(fullPath, 'pnpm')\n s.stop(pc.green('✓ Dependencies installed'))\n } catch (error) {\n s.stop(pc.red('✗ Failed'))\n log.error(error instanceof Error ? error.message : 'Unknown error')\n process.exit(1)\n }\n\n // Modify Payload configuration\n s.start('Checking Payload configuration...')\n const modResult = await ensurePayloadFigmaConfig(fullPath, 'pnpm', {\n contentSystemId: tenantId,\n region: options.region || 'us-east-1',\n useContentSystem: !options.noContentSystem,\n })\n\n if (!modResult.success) {\n s.stop(pc.red('✗ Configuration check failed'))\n displayManualInstructions(modResult.error || 'Unknown error')\n process.exit(1)\n }\n\n if (modResult.modified) {\n s.stop(pc.green('✓ Payload configuration updated'))\n if (modResult.changes.length > 0) {\n modResult.changes.forEach((change) => log.debug(pc.dim(` → ${change}`)))\n }\n } else {\n s.stop(pc.green('✓ Payload configuration valid'))\n }\n\n // Display warnings if any\n if (modResult.warnings && modResult.warnings.length > 0) {\n modResult.warnings.forEach((warning) => {\n p.log.warn(pc.yellow(`⚠ ${warning}`))\n })\n }\n\n // Generate project token (unless skipping auth)\n if (!options.skipAuth) {\n await generateProjectTokenWithFeedback(tokenStore, tenantId, s)\n }\n\n // Initialize git repository (after all files including lock file are ready)\n initializeGitRepo(fullPath)\n\n // Success message for NEW project\n p.log.step(pc.bgGreen(pc.black(' Project created successfully! ')))\n\n const relativePath = path.relative(process.cwd(), fullPath)\n const nextSteps: string[] = []\n\n // Only show cd command if user needs to navigate\n if (relativePath && relativePath !== '.') {\n nextSteps.push(`cd ${relativePath}`)\n }\n\n nextSteps.push(\n 'pnpm dev or follow directions in README.md',\n '',\n 'Documentation:',\n '- Getting Started: https://payloadcms.com/docs/getting-started/what-is-payload',\n '- Configuration: https://payloadcms.com/docs/configuration/overview',\n )\n\n p.note(nextSteps.join('\\n'), 'Next Steps')\n p.outro(pc.green('✓ Done'))\n }\n}\n"],"names":["p","fs","path","pc","FigmaApiError","getValidAccessToken","getValidProjectToken","ProjectTokenError","TokenStore","isDebug","log","displayManualInstructions","ensurePayloadFigmaConfig","detectPayloadProject","hasRequiredDependencies","initializeGitRepo","installDependencies","isInProjectDirectory","scaffoldProject","validatePayloadVersion","loginCommand","generateProjectTokenWithFeedback","tokenStore","tenantId","spinner","start","projectToken","stop","green","yellow","error","warning","message","note","Error","initCommand","options","s","skipAuth","warn","hasValidTokens","token","info","showNextSteps","newToken","process","exit","red","debug","id","isInProject","projectInfo","hasPayload","payloadVersion","success","hasDeps","cwd","shouldInstall","confirm","initialValue","isCancel","packageManager","modResult","contentSystemId","region","useContentSystem","noContentSystem","modified","changes","length","forEach","change","dim","warnings","shouldAddPayload","cancel","outro","nextSteps","filter","Boolean","join","projectPathInput","text","placeholder","validate","value","undefined","projectPath","fullPath","resolve","projectName","name","basename","mkdir","recursive","step","bgGreen","black","relativePath","relative","push"],"mappings":"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"}
|
package/dist/commands/login.d.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
+
type LoginArgs = {
|
|
2
|
+
/** Set this to show next steps after login
|
|
3
|
+
* @default true
|
|
4
|
+
*/
|
|
5
|
+
showNextSteps: boolean;
|
|
6
|
+
};
|
|
1
7
|
/**
|
|
2
8
|
* Handle the `@payloadcms/figma login` command
|
|
3
9
|
*
|
|
4
10
|
* Authenticates the user with Figma OAuth2 and stores tokens locally.
|
|
5
11
|
* If valid tokens already exist, shows an error message.
|
|
6
12
|
*/
|
|
7
|
-
export declare function loginCommand(): Promise<void>;
|
|
13
|
+
export declare function loginCommand(args?: LoginArgs): Promise<void>;
|
|
14
|
+
export {};
|
|
8
15
|
//# sourceMappingURL=login.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAQA;;;;;GAKG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAQA,KAAK,SAAS,GAAG;IACf;;OAEG;IACH,aAAa,EAAE,OAAO,CAAA;CACvB,CAAA;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,IAAI,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BlE"}
|
package/dist/commands/login.js
CHANGED
|
@@ -9,7 +9,10 @@ import * as log from '../utils/log.js';
|
|
|
9
9
|
*
|
|
10
10
|
* Authenticates the user with Figma OAuth2 and stores tokens locally.
|
|
11
11
|
* If valid tokens already exist, shows an error message.
|
|
12
|
-
*/ export async function loginCommand() {
|
|
12
|
+
*/ export async function loginCommand(args) {
|
|
13
|
+
const { showNextSteps } = args || {
|
|
14
|
+
showNextSteps: false
|
|
15
|
+
};
|
|
13
16
|
const tokenStore = new TokenStore();
|
|
14
17
|
// Check for existing valid tokens
|
|
15
18
|
try {
|
|
@@ -30,12 +33,13 @@ import * as log from '../utils/log.js';
|
|
|
30
33
|
}
|
|
31
34
|
// Start OAuth flow
|
|
32
35
|
await handleAuthentication({
|
|
36
|
+
showNextSteps,
|
|
33
37
|
tokenStore
|
|
34
38
|
});
|
|
35
39
|
}
|
|
36
40
|
/**
|
|
37
41
|
* Handle authentication flow
|
|
38
|
-
*/ async function handleAuthentication({ tokenStore }) {
|
|
42
|
+
*/ async function handleAuthentication({ showNextSteps, tokenStore }) {
|
|
39
43
|
try {
|
|
40
44
|
// Execute OAuth flow
|
|
41
45
|
const result = await executeOAuthFlow(tokenStore, {
|
|
@@ -48,8 +52,10 @@ import * as log from '../utils/log.js';
|
|
|
48
52
|
log.debug(`User ID: ${result.userId}`);
|
|
49
53
|
}
|
|
50
54
|
log.debug(`Token storage: ${pc.dim(tokenStore.getStoragePath())}`);
|
|
51
|
-
// Show next steps
|
|
52
|
-
|
|
55
|
+
// Show next steps unless disabled
|
|
56
|
+
if (showNextSteps !== false) {
|
|
57
|
+
p.note(` ${pc.cyan('@payloadcms/figma init')} Create a new CMS instance`, 'Next Steps');
|
|
58
|
+
}
|
|
53
59
|
} catch (error) {
|
|
54
60
|
if (error instanceof OAuthFlowError) {
|
|
55
61
|
log.error(error.message);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/login.ts"],"sourcesContent":["import * as p from '@clack/prompts'\nimport pc from 'picocolors'\n\nimport { executeOAuthFlow, getValidAccessToken, OAuthFlowError } from '../auth/oauth-flow.js'\nimport { TokenStore } from '../auth/token-store.js'\nimport { OAUTH_CONFIG } from '../config/oauth.js'\nimport * as log from '../utils/log.js'\n\n/**\n * Handle the `@payloadcms/figma login` command\n *\n * Authenticates the user with Figma OAuth2 and stores tokens locally.\n * If valid tokens already exist, shows an error message.\n */\nexport async function loginCommand(): Promise<void> {\n const tokenStore = new TokenStore()\n\n // Check for existing valid tokens\n try {\n const existingToken = await getValidAccessToken(tokenStore)\n if (existingToken) {\n const tokens = tokenStore.getTokens()\n p.log.warn(pc.yellow('Already logged in'))\n if (tokens?.userId) {\n log.info(`User ID: ${tokens.userId}`)\n }\n log.info(`Token storage: ${pc.dim(tokenStore.getStoragePath())}`)\n p.note(`To re-authenticate, first run ${pc.cyan('@payloadcms/figma logout')}`, 'Tip')\n return\n }\n } catch {\n // Token refresh failed - continue with new auth flow\n log.warning('Existing tokens are invalid. Starting new authentication...')\n }\n\n // Start OAuth flow\n await handleAuthentication({\n tokenStore,\n })\n}\n\n/**\n * Handle authentication flow\n */\nasync function handleAuthentication({
|
|
1
|
+
{"version":3,"sources":["../../src/commands/login.ts"],"sourcesContent":["import * as p from '@clack/prompts'\nimport pc from 'picocolors'\n\nimport { executeOAuthFlow, getValidAccessToken, OAuthFlowError } from '../auth/oauth-flow.js'\nimport { TokenStore } from '../auth/token-store.js'\nimport { OAUTH_CONFIG } from '../config/oauth.js'\nimport * as log from '../utils/log.js'\n\ntype LoginArgs = {\n /** Set this to show next steps after login\n * @default true\n */\n showNextSteps: boolean\n}\n\n/**\n * Handle the `@payloadcms/figma login` command\n *\n * Authenticates the user with Figma OAuth2 and stores tokens locally.\n * If valid tokens already exist, shows an error message.\n */\nexport async function loginCommand(args?: LoginArgs): Promise<void> {\n const { showNextSteps } = args || { showNextSteps: false }\n const tokenStore = new TokenStore()\n\n // Check for existing valid tokens\n try {\n const existingToken = await getValidAccessToken(tokenStore)\n if (existingToken) {\n const tokens = tokenStore.getTokens()\n p.log.warn(pc.yellow('Already logged in'))\n if (tokens?.userId) {\n log.info(`User ID: ${tokens.userId}`)\n }\n log.info(`Token storage: ${pc.dim(tokenStore.getStoragePath())}`)\n p.note(`To re-authenticate, first run ${pc.cyan('@payloadcms/figma logout')}`, 'Tip')\n return\n }\n } catch {\n // Token refresh failed - continue with new auth flow\n log.warning('Existing tokens are invalid. Starting new authentication...')\n }\n\n // Start OAuth flow\n await handleAuthentication({\n showNextSteps,\n tokenStore,\n })\n}\n\n/**\n * Handle authentication flow\n */\nasync function handleAuthentication({\n showNextSteps,\n tokenStore,\n}: {\n showNextSteps: boolean\n tokenStore: TokenStore\n}): Promise<void> {\n try {\n // Execute OAuth flow\n const result = await executeOAuthFlow(tokenStore, {\n clientId: OAUTH_CONFIG.clientId,\n redirectUri: OAUTH_CONFIG.redirectUri,\n scopes: OAUTH_CONFIG.scopes,\n })\n\n p.log.success(pc.green('✓ You are now authenticated with Figma'))\n\n if (result.userId) {\n log.debug(`User ID: ${result.userId}`)\n }\n\n log.debug(`Token storage: ${pc.dim(tokenStore.getStoragePath())}`)\n\n // Show next steps unless disabled\n if (showNextSteps !== false) {\n p.note(` ${pc.cyan('@payloadcms/figma init')} Create a new CMS instance`, 'Next Steps')\n }\n } catch (error) {\n if (error instanceof OAuthFlowError) {\n log.error(error.message)\n\n if (error.cause) {\n log.debug(`Cause: ${error.cause.message}`)\n }\n } else {\n log.error(error instanceof Error ? error.message : 'Unknown error')\n }\n\n process.exit(1)\n }\n}\n"],"names":["p","pc","executeOAuthFlow","getValidAccessToken","OAuthFlowError","TokenStore","OAUTH_CONFIG","log","loginCommand","args","showNextSteps","tokenStore","existingToken","tokens","getTokens","warn","yellow","userId","info","dim","getStoragePath","note","cyan","warning","handleAuthentication","result","clientId","redirectUri","scopes","success","green","debug","error","message","cause","Error","process","exit"],"mappings":"AAAA,YAAYA,OAAO,iBAAgB;AACnC,OAAOC,QAAQ,aAAY;AAE3B,SAASC,gBAAgB,EAAEC,mBAAmB,EAAEC,cAAc,QAAQ,wBAAuB;AAC7F,SAASC,UAAU,QAAQ,yBAAwB;AACnD,SAASC,YAAY,QAAQ,qBAAoB;AACjD,YAAYC,SAAS,kBAAiB;AAStC;;;;;CAKC,GACD,OAAO,eAAeC,aAAaC,IAAgB;IACjD,MAAM,EAAEC,aAAa,EAAE,GAAGD,QAAQ;QAAEC,eAAe;IAAM;IACzD,MAAMC,aAAa,IAAIN;IAEvB,kCAAkC;IAClC,IAAI;QACF,MAAMO,gBAAgB,MAAMT,oBAAoBQ;QAChD,IAAIC,eAAe;YACjB,MAAMC,SAASF,WAAWG,SAAS;YACnCd,EAAEO,GAAG,CAACQ,IAAI,CAACd,GAAGe,MAAM,CAAC;YACrB,IAAIH,QAAQI,QAAQ;gBAClBV,IAAIW,IAAI,CAAC,CAAC,SAAS,EAAEL,OAAOI,MAAM,EAAE;YACtC;YACAV,IAAIW,IAAI,CAAC,CAAC,eAAe,EAAEjB,GAAGkB,GAAG,CAACR,WAAWS,cAAc,KAAK;YAChEpB,EAAEqB,IAAI,CAAC,CAAC,8BAA8B,EAAEpB,GAAGqB,IAAI,CAAC,6BAA6B,EAAE;YAC/E;QACF;IACF,EAAE,OAAM;QACN,qDAAqD;QACrDf,IAAIgB,OAAO,CAAC;IACd;IAEA,mBAAmB;IACnB,MAAMC,qBAAqB;QACzBd;QACAC;IACF;AACF;AAEA;;CAEC,GACD,eAAea,qBAAqB,EAClCd,aAAa,EACbC,UAAU,EAIX;IACC,IAAI;QACF,qBAAqB;QACrB,MAAMc,SAAS,MAAMvB,iBAAiBS,YAAY;YAChDe,UAAUpB,aAAaoB,QAAQ;YAC/BC,aAAarB,aAAaqB,WAAW;YACrCC,QAAQtB,aAAasB,MAAM;QAC7B;QAEA5B,EAAEO,GAAG,CAACsB,OAAO,CAAC5B,GAAG6B,KAAK,CAAC;QAEvB,IAAIL,OAAOR,MAAM,EAAE;YACjBV,IAAIwB,KAAK,CAAC,CAAC,SAAS,EAAEN,OAAOR,MAAM,EAAE;QACvC;QAEAV,IAAIwB,KAAK,CAAC,CAAC,eAAe,EAAE9B,GAAGkB,GAAG,CAACR,WAAWS,cAAc,KAAK;QAEjE,kCAAkC;QAClC,IAAIV,kBAAkB,OAAO;YAC3BV,EAAEqB,IAAI,CAAC,CAAC,EAAE,EAAEpB,GAAGqB,IAAI,CAAC,0BAA0B,2BAA2B,CAAC,EAAE;QAC9E;IACF,EAAE,OAAOU,OAAO;QACd,IAAIA,iBAAiB5B,gBAAgB;YACnCG,IAAIyB,KAAK,CAACA,MAAMC,OAAO;YAEvB,IAAID,MAAME,KAAK,EAAE;gBACf3B,IAAIwB,KAAK,CAAC,CAAC,OAAO,EAAEC,MAAME,KAAK,CAACD,OAAO,EAAE;YAC3C;QACF,OAAO;YACL1B,IAAIyB,KAAK,CAACA,iBAAiBG,QAAQH,MAAMC,OAAO,GAAG;QACrD;QAEAG,QAAQC,IAAI,CAAC;IACf;AACF"}
|
package/dist/db-adapter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-adapter.d.ts","sourceRoot":"","sources":["../src/db-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EAanB,kBAAkB,EAqBnB,MAAM,SAAS,CAAA;AAchB,UAAU,gCAAgC;IACxC,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,CAAC,GAAG,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;CACvD,GAAG,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"db-adapter.d.ts","sourceRoot":"","sources":["../src/db-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EAanB,kBAAkB,EAqBnB,MAAM,SAAS,CAAA;AAchB,UAAU,gCAAgC;IACxC,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,CAAC,GAAG,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;CACvD,GAAG,mBAAmB,CAAA;AAqzBvB,eAAO,MAAM,iBAAiB,SAAU,gCAAgC,KAAG,kBA6C1E,CAAA"}
|
package/dist/db-adapter.js
CHANGED
|
@@ -692,9 +692,12 @@ const request = async function(path, body = {}) {
|
|
|
692
692
|
...body
|
|
693
693
|
}),
|
|
694
694
|
headers: {
|
|
695
|
-
Authorization: `Bearer ${this.projectToken}`,
|
|
696
695
|
'Content-Type': 'application/json',
|
|
697
|
-
|
|
696
|
+
...this.contentApiKey ? {
|
|
697
|
+
'X-Api-Key': this.contentApiKey
|
|
698
|
+
} : {
|
|
699
|
+
Authorization: `Bearer ${this.projectToken}`
|
|
700
|
+
}
|
|
698
701
|
},
|
|
699
702
|
method: 'POST'
|
|
700
703
|
});
|
package/dist/db-adapter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/db-adapter.ts"],"sourcesContent":["import type {\n BaseDatabaseAdapter,\n BeginTransaction,\n Collection,\n CollectionSlug,\n CommitTransaction,\n Config,\n Count,\n CountGlobalVersions,\n CountVersions,\n Create,\n CreateGlobal,\n CreateGlobalVersion,\n CreateVersion,\n DatabaseAdapterObj,\n DeleteMany,\n DeleteOne,\n DeleteVersions,\n Find,\n FindDistinct,\n FindGlobal,\n FindGlobalVersions,\n FindOne,\n FindVersions,\n FlattenedField,\n QueryDrafts,\n SanitizedConfig,\n SanitizedGlobalConfig,\n UpdateGlobal,\n UpdateGlobalVersion,\n UpdateMany,\n UpdateOne,\n UpdateVersion,\n Upsert,\n Where,\n} from 'payload'\n\nimport { randomUUID } from 'crypto'\nimport {\n buildVersionCollectionFields,\n buildVersionGlobalFields,\n combineQueries,\n createArrayFromCommaDelineated,\n createDatabaseAdapter,\n getFieldByPath,\n} from 'payload'\n// import { fieldShouldBeLocalized } from 'payload/shared'\n// import { db, uuid } from './db'\n\ninterface ContentAPIDatabaseAdapterOptions {\n contentApiKey: string\n contentApiUrl: string\n contentSystemId: string\n projectToken: string\n}\n\nexport type ContentAPIAdapter = {\n contentApiKey: string\n contentApiUrl: string\n contentSystemId: string\n projectToken: string\n request<T = any>(path: string, body?: any): Promise<T>\n} & BaseDatabaseAdapter\n\nconst slugIsGlobal = (slug: string) => slug.startsWith('_global-')\n\nconst getGlobalSlug = (slug: string) => `_global-${slug}`\n\n// Transform Payload Where format to Content API WhereClause format\nfunction transformWhereClause(where: undefined | Where): any {\n if (!where) {\n return undefined\n }\n\n // Handle and/or logical operators\n if (where.and) {\n return {\n and: where.and.map(transformWhereClause).filter(Boolean),\n }\n }\n\n if (where.or) {\n return {\n or: where.or.map(transformWhereClause).filter(Boolean),\n }\n }\n\n // Transform field conditions\n const transformedClauses: any[] = []\n\n for (const [field, condition] of Object.entries(where)) {\n if (field === 'and' || field === 'or') {\n continue\n }\n\n if (Array.isArray(condition)) {\n // Handle nested and/or arrays\n transformedClauses.push({\n [field]: condition.map(transformWhereClause).filter(Boolean),\n })\n } else if (typeof condition === 'object' && condition !== null) {\n // Handle field operators like { equals: 'value' }, { greater_than: 10 }\n for (const [operator, value] of Object.entries(condition)) {\n transformedClauses.push({\n operator: operator as any, // Map Payload operators to Content API operators\n path: field,\n value,\n })\n }\n } else {\n // Handle direct field values like { status: 'published' }\n transformedClauses.push({\n operator: 'equals',\n path: field,\n value: condition,\n })\n }\n }\n\n if (transformedClauses.length === 1) {\n return transformedClauses[0]\n } else if (transformedClauses.length > 1) {\n return {\n and: transformedClauses,\n }\n }\n\n return undefined\n}\n\nconst formatDocument = (doc: any) => {\n if (!doc) {\n return null\n }\n\n const { id, data, ...meta } = doc\n\n return {\n id,\n _meta: meta,\n ...data,\n }\n}\n\nasync function init(this: ContentAPIAdapter) {\n console.log('🔍 [DB_CONTENT_API] init() called')\n console.log('🔍 [DB_CONTENT_API] this:', this)\n console.log(\n '🔍 [DB_CONTENT_API] payload collections:',\n this.payload.config.collections.map((c) => c.slug),\n )\n\n // Create collections in content API\n for (const collection of this.payload.config.collections) {\n try {\n console.log(`🔧 [DB_CONTENT_API] Creating collection: ${collection.slug}`)\n const response = await this.request('/api/v0/collections', {\n contentSystemId: this.contentSystemId,\n key: collection.slug,\n })\n\n if (response.error) {\n console.error(\n `[DB_CONTENT_API] create collection ${collection.slug} failure`,\n response.error,\n )\n } else {\n console.log(`✅ [DB_CONTENT_API] Created collection: ${collection.slug}`)\n }\n } catch (error) {\n console.warn(`⚠️ [DB_CONTENT_API] Failed to create collection ${collection.slug}:`, error)\n }\n }\n\n // Create globals as collections (with _global- prefix)\n for (const global of this.payload.config.globals) {\n try {\n const globalKey = getGlobalSlug(global.slug)\n console.log(`🔧 [DB_CONTENT_API] Creating global collection: ${globalKey}`)\n const response = await this.request('/api/v0/collections', {\n contentSystemId: this.contentSystemId,\n key: globalKey,\n })\n\n if (response.error) {\n console.error(\n `[DB_CONTENT_API] create global collection ${globalKey} failure`,\n response.error,\n )\n } else {\n console.log(`✅ [DB_CONTENT_API] Created global collection: ${globalKey}`)\n }\n } catch (error) {\n console.warn(`⚠️ [DB_CONTENT_API] Failed to create global collection ${global.slug}:`, error)\n }\n }\n\n console.log(\n '🔍 [DB_CONTENT_API] payload globals:',\n this.payload.config.globals.map((g) => g.slug),\n )\n}\n\nconst find: Find = async function find(\n this: ContentAPIAdapter,\n { collection, limit, page = 1, req, sort, where, ...args },\n) {\n console.log(\n '🔍 [DB_CONTENT_API] find() called with:',\n collection,\n JSON.stringify(transformWhereClause(where), null, 2),\n { limit, page, sort, ...args },\n )\n\n try {\n const response = await this.request<any>('/api/v0/documents:find', {\n collectionKey: collection,\n contentSystemId: this.contentSystemId,\n limit,\n offset: (page - 1) * (limit || 10),\n sort: sort\n ? [sort].flat().map((s: any) => ({\n direction: Object.values(s)[0] === -1 ? 'dsc' : 'asc',\n path: Object.keys(s)[0],\n }))\n : undefined,\n where: transformWhereClause(where),\n })\n\n if (response.error) {\n console.error('[DB_CONTENT_API] find() failure', response.error?.message || response.error)\n }\n\n const docs = response.result?.data || []\n const pagination = response.result?.pagination\n const totalDocs = pagination?.total || docs.length\n const actualLimit = limit || 10\n const totalPages = Math.ceil(totalDocs / actualLimit)\n const hasNextPage = page < totalPages\n\n const result = {\n docs: docs.map(formatDocument),\n hasNextPage,\n hasPrevPage: page > 1,\n limit: actualLimit,\n nextPage: hasNextPage ? page + 1 : null,\n page,\n pagingCounter: 1,\n prevPage: page > 1 ? page - 1 : null,\n totalDocs,\n totalPages,\n }\n console.log('[DB_CONTENT_API] find() result:', result)\n return result\n } catch (error) {\n console.error(`❌ [DB_CONTENT_API] Error in find():`, error)\n const docs: any[] = []\n const hasNextPage = false\n const totalPages = 1\n\n return {\n docs,\n hasNextPage,\n hasPrevPage: page > 1,\n limit: limit || docs.length,\n nextPage: hasNextPage ? page + 1 : null,\n page,\n pagingCounter: 1,\n prevPage: page > 1 ? page - 1 : null,\n totalDocs: docs.length,\n totalPages,\n }\n }\n}\n\nconst findVersions: FindVersions = async function findVersions(\n this: ContentAPIAdapter,\n { collection, limit, page = 1, req, where, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] findVersions() called with:', {\n collection,\n limit,\n page,\n where,\n ...args,\n })\n\n const docs: any[] = []\n const hasNextPage = false\n const result = {\n docs,\n hasNextPage,\n hasPrevPage: page > 1,\n limit: limit || docs.length,\n nextPage: hasNextPage ? page + 1 : null,\n page,\n pagingCounter: 1,\n prevPage: page > 1 ? page - 1 : null,\n totalDocs: docs.length,\n totalPages: limit && docs.length ? Math.ceil(docs.length / limit) : 1,\n }\n console.log('[DB_CONTENT_API] findVersions() result:', result)\n return result\n}\n\nconst queryDrafts: QueryDrafts = async function queryDrafts(\n this: ContentAPIAdapter,\n { collection, limit, page = 1, req, where, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] queryDrafts() called with:', {\n collection,\n limit,\n page,\n where,\n ...args,\n })\n\n const docs: any[] = []\n const hasNextPage = false\n const result = {\n docs,\n hasNextPage,\n hasPrevPage: page > 1,\n limit: limit || docs.length,\n nextPage: hasNextPage ? page + 1 : null,\n page,\n pagingCounter: 1,\n prevPage: page > 1 ? page - 1 : null,\n totalDocs: docs.length,\n totalPages: limit && docs.length ? Math.ceil(docs.length / limit) : 1,\n }\n console.log('[DB_CONTENT_API] queryDrafts() result:', result)\n return result\n}\n\nconst createVersion: CreateVersion = async function createVersion(\n this: ContentAPIAdapter,\n { collectionSlug, req, versionData, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] createVersion() called with:', {\n collectionSlug,\n versionData,\n ...args,\n })\n\n const result = {} as any\n console.log('[DB_CONTENT_API] createVersion() result:', result)\n return result\n}\n\nconst updateVersion: UpdateVersion = async function updateVersion(\n this: ContentAPIAdapter,\n { id, collection, req, versionData, where, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] updateVersion() called with:', {\n id,\n collection,\n versionData,\n ...args,\n })\n\n const result = {} as any\n console.log('[DB_CONTENT_API] updateVersion() result:', result)\n return result\n}\n\nconst deleteVersions: DeleteVersions = async function deleteVersions(\n this: ContentAPIAdapter,\n { collection, req, where, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] deleteVersions() called with:', { collection, where, ...args })\n\n const versionsToDelete: any[] = []\n const versionCollection = 'versions'\n\n console.log(\n `🗑️ [DB_CONTENT_API] Deleted ${versionsToDelete.length} versions from ${versionCollection}`,\n )\n\n // return versionsToDelete.length\n}\n\nconst findOne: FindOne = async function findOne(\n this: ContentAPIAdapter,\n { collection, req, where, ...args },\n) {\n console.log(\n '🔍 [DB_CONTENT_API] findOne() called with:',\n collection,\n JSON.stringify(transformWhereClause(where), null, 2),\n args,\n req?.body,\n )\n\n try {\n const response = await this.request<any>('/api/v0/documents:find', {\n collectionKey: collection,\n contentSystemId: this.contentSystemId,\n limit: 1,\n offset: 0,\n where: transformWhereClause(where),\n })\n\n if (response.error) {\n console.error('[DB_CONTENT_API] findOne() failure', response.error?.message || response.error)\n }\n\n const docs = response.result?.data || []\n const result = docs.length > 0 ? docs[0] : null\n console.log('[DB_CONTENT_API] findOne() result:', result)\n return formatDocument(result)\n } catch (error) {\n console.error(`❌ [DB_CONTENT_API] Error in findOne():`, error)\n return null\n }\n}\n\nconst updateMany: UpdateMany = async function updateMany(\n this: ContentAPIAdapter,\n { collection, data, req, where, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] updateMany() called with:', { collection, data, where, ...args })\n try {\n const response = await this.request<any>('/api/v0/documents:update', {\n collectionKey: collection,\n contentSystemId: this.contentSystemId,\n createOnMissing: false,\n data,\n where: transformWhereClause(where),\n })\n\n if (response.error) {\n console.error(\n '[DB_CONTENT_API] updateMany() failure',\n response.error?.message || response.error,\n )\n }\n\n // Return array of updated documents if available, otherwise return placeholder\n const result = response.result?.data || []\n console.log('[DB_CONTENT_API] updateMany() result:', result)\n return result\n } catch (error) {\n console.error(`❌ [DB_CONTENT_API] Error in updateMany():`, error)\n return []\n }\n}\n\nconst updateOne: UpdateOne = async function updateOne(\n this: ContentAPIAdapter,\n { id, collection, data, req, where = {}, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] updateOne() called with:', {\n id,\n collection,\n data,\n where,\n ...args,\n })\n try {\n const whereClause = id\n ? { operator: 'equals', path: 'id', value: id }\n : transformWhereClause(where)\n const response = await this.request<any>('/api/v0/documents:update', {\n collectionKey: collection,\n contentSystemId: this.contentSystemId,\n createOnMissing: false,\n data,\n returning: { exclude: [] },\n where: whereClause,\n })\n\n if (response.error) {\n console.error(\n '[DB_CONTENT_API] updateOne() failure',\n response.error?.message || response.error,\n )\n }\n\n const result = response.result?.data || { id, ...data }\n console.log('[DB_CONTENT_API] updateOne() result:', result)\n return result\n } catch (error) {\n console.error(`❌ [DB_CONTENT_API] Error in updateOne():`, error)\n return { id, ...data }\n }\n}\n\nconst deleteMany: DeleteMany = async function deleteMany(\n this: ContentAPIAdapter,\n { collection, req, where, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] deleteMany() called with:', { collection, where, ...args })\n try {\n const response = await this.request<any>('/api/v0/documents:delete', {\n collectionKey: collection,\n contentSystemId: this.contentSystemId,\n returning: false,\n where: transformWhereClause(where),\n })\n\n if (response.error) {\n console.error(\n '[DB_CONTENT_API] deleteMany() failure',\n response.error?.message || response.error,\n )\n }\n\n const deletedCount = response.result?.count || 0\n console.log(`🗑️ [DB_CONTENT_API] Deleted ${deletedCount} documents from ${collection}`)\n } catch (error) {\n console.error(`❌ [DB_CONTENT_API] Error in deleteMany():`, error)\n }\n}\n\nconst deleteOne: DeleteOne = async function deleteOne(\n this: ContentAPIAdapter,\n { collection, req, where, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] deleteOne() called with:', { collection, where, ...args })\n try {\n const response = await this.request<any>('/api/v0/documents:delete', {\n collectionKey: collection,\n contentSystemId: this.contentSystemId,\n returning: { exclude: [] },\n where: transformWhereClause(where),\n })\n\n if (response.error) {\n console.error(\n '[DB_CONTENT_API] deleteOne() failure',\n response.error?.message || response.error,\n )\n }\n\n const deletedDocs = response.result?.data || []\n const docId = deletedDocs.length > 0 ? deletedDocs[0].id : 'unknown'\n const result = deletedDocs.length > 0 ? deletedDocs[0] : {}\n\n console.log(`🗑️ [DB_CONTENT_API] Deleted document ${docId} from ${collection}`)\n console.log('[DB_CONTENT_API] deleteOne() result:', result)\n return result\n } catch (error) {\n console.error(`❌ [DB_CONTENT_API] Error in deleteOne():`, error)\n return {}\n }\n}\n\nconst create: Create = async function create(\n this: ContentAPIAdapter,\n { collection, data, req, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] create() called with:', { collection, data, ...args })\n try {\n const randomKey = randomUUID()\n const response = await this.request<any>('/api/v0/documents:create', {\n collectionKey: collection,\n contentSystemId: this.contentSystemId,\n data,\n key: data.key || data.id || `doc-${randomKey}`,\n })\n\n if (response.error) {\n console.error('[DB_CONTENT_API] create() failure', response.error?.message || response.error)\n }\n\n const result = response.result?.data || response.result || { id: `doc-${randomKey}`, ...data }\n console.log('[DB_CONTENT_API] create() result:', result)\n return result\n } catch (error) {\n console.error(`❌ [DB_CONTENT_API] Error in create():`, error)\n return { id: `doc-${randomUUID()}`, ...data }\n }\n}\n\nconst count: Count = async function count(\n this: ContentAPIAdapter,\n { collection, req, where = {}, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] count() called with:', { collection, where, ...args })\n try {\n const response = await this.request<any>('/api/v0/documents:count', {\n collectionKey: collection,\n contentSystemId: this.contentSystemId,\n where: transformWhereClause(where),\n })\n\n if (response.error) {\n console.error('[DB_CONTENT_API] count() failure', response.error?.message || response.error)\n }\n\n const result = { totalDocs: response.result?.count || 0 }\n console.log('[DB_CONTENT_API] count() result:', result)\n return result\n } catch (error) {\n console.error(`❌ [DB_CONTENT_API] Error in count():`, error)\n return { totalDocs: 0 }\n }\n}\n\nconst countVersions: CountVersions = async function countVersions(\n this: ContentAPIAdapter,\n { collection, req, where, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] countVersions() called with:', { collection, where, ...args })\n\n const result = { totalDocs: 0 }\n console.log('[DB_CONTENT_API] countVersions() result:', result)\n return result\n}\n\nconst upsert: Upsert = async function upsert(\n this: ContentAPIAdapter,\n { collection, data, req, where, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] upsert() called with:', { collection, data, where, ...args })\n try {\n // Try to update first\n const updateResponse = await this.request<any>('/api/v0/documents:update', {\n collectionKey: collection,\n contentSystemId: this.contentSystemId,\n createOnMissing: { documentKey: `upsert-${Date.now()}` },\n data,\n returning: { exclude: [] },\n where: transformWhereClause(where),\n })\n\n if (!updateResponse.success) {\n console.log('[DB_CONTENT_API] upsert() failure', updateResponse.error)\n }\n\n const result = updateResponse.result?.data || { ...data }\n console.log('[DB_CONTENT_API] upsert() result:', result)\n return result\n } catch (error) {\n console.error(`❌ [DB_CONTENT_API] Error in upsert():`, error)\n return { ...data }\n }\n}\n\nconst createGlobal: CreateGlobal = async function createGlobal(\n this: ContentAPIAdapter,\n { slug, data, req, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] createGlobal() called with:', { slug, data, ...args })\n\n try {\n const globalKey = getGlobalSlug(slug)\n const response = await this.request<any>('/api/v0/documents:create', {\n collectionKey: globalKey,\n contentSystemId: this.contentSystemId,\n data,\n key: `global-${slug}`,\n })\n\n if (response.error) {\n console.error(\n '[DB_CONTENT_API] createGlobal() failure',\n response.error?.message || response.error,\n )\n }\n\n const result = response.result?.data || response.result || { id: `global-${slug}`, ...data }\n console.log('[DB_CONTENT_API] createGlobal() result:', result)\n return result\n } catch (error) {\n console.error(`❌ [DB_CONTENT_API] Error in createGlobal():`, error)\n return { id: `global-${slug}`, ...data }\n }\n}\n\nconst findGlobal: FindGlobal = async function findGlobal(\n this: ContentAPIAdapter,\n { slug, req, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] findGlobal() called with:', { slug, ...args })\n\n try {\n const globalKey = getGlobalSlug(slug)\n const response = await this.request<any>('/api/v0/documents:find', {\n collectionKey: globalKey,\n contentSystemId: this.contentSystemId,\n limit: 1,\n offset: 0,\n })\n\n if (response.error) {\n console.error(\n '[DB_CONTENT_API] findGlobal() failure',\n response.error?.message || response.error,\n )\n }\n\n const docs = response.result?.data || []\n const result = docs.length > 0 ? docs[0] : null\n console.log('[DB_CONTENT_API] findGlobal() result:', result)\n return formatDocument(result)\n } catch (error) {\n console.error(`❌ [DB_CONTENT_API] Error in findGlobal():`, error)\n return null\n }\n}\n\nconst findDistinct: FindDistinct = async function findDistinct(\n this: ContentAPIAdapter,\n { collection, field, limit, page = 1, req, where, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] findDistinct() called with:', {\n collection,\n field,\n limit,\n page,\n where,\n ...args,\n })\n\n const distinctValues: any[] = []\n const paginatedValues: any[] = []\n const endIndex = 0\n const totalDocs = 0\n\n console.log(\n `📊 [DB_CONTENT_API] findDistinct result: ${distinctValues.length} distinct values for ${field}`,\n )\n\n return {\n hasNextPage: limit ? endIndex < totalDocs : false,\n hasPrevPage: page > 1,\n limit: limit || totalDocs,\n nextPage: limit && endIndex < totalDocs ? page + 1 : null,\n page,\n pagingCounter: 1,\n prevPage: page > 1 ? page - 1 : null,\n totalDocs,\n totalPages: limit ? Math.ceil(totalDocs / limit) : 1,\n values: paginatedValues,\n }\n}\n\nconst updateGlobal: UpdateGlobal = async function updateGlobal(\n this: ContentAPIAdapter,\n { slug, data, req, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] updateGlobal() called with:', { slug, data, ...args })\n\n try {\n const globalKey = getGlobalSlug(slug)\n const response = await this.request<any>('/api/v0/documents:update', {\n collectionKey: globalKey,\n contentSystemId: this.contentSystemId,\n createOnMissing: { documentKey: `global-${slug}` },\n data,\n returning: { exclude: [] },\n where: { operator: 'equals', path: 'key', value: `global-${slug}` },\n })\n\n if (response.error) {\n console.error(\n '[DB_CONTENT_API] updateGlobal() failure',\n response.error?.message || response.error,\n )\n }\n\n const result = response.result?.data || { id: `global-${slug}`, ...data }\n console.log('[DB_CONTENT_API] updateGlobal() result:', result)\n return result\n } catch (error) {\n console.error(`❌ [DB_CONTENT_API] Error in updateGlobal():`, error)\n return { id: `global-${slug}`, ...data }\n }\n}\n\nconst findGlobalVersions: FindGlobalVersions = async function findGlobalVersions(\n this: ContentAPIAdapter,\n { limit, page = 1, req, where, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] findGlobalVersions() called with:', {\n limit,\n page,\n where,\n ...args,\n })\n\n const docs: any[] = []\n const hasNextPage = false\n const result = {\n docs,\n hasNextPage,\n hasPrevPage: page > 1,\n limit: limit || docs.length,\n nextPage: hasNextPage ? page + 1 : null,\n page,\n pagingCounter: 1,\n prevPage: page > 1 ? page - 1 : null,\n totalDocs: docs.length,\n totalPages: limit && docs.length ? Math.ceil(docs.length / limit) : 1,\n }\n console.log('[DB_CONTENT_API] findGlobalVersions() result:', result)\n return result\n}\n\nconst createGlobalVersion: CreateGlobalVersion = async function createGlobalVersion(\n this: ContentAPIAdapter,\n { req, versionData, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] createGlobalVersion() called with:', { versionData, ...args })\n\n const result = {} as any\n console.log('[DB_CONTENT_API] createGlobalVersion() result:', result)\n return result\n}\n\nconst updateGlobalVersion: UpdateGlobalVersion = async function updateGlobalVersion(\n this: ContentAPIAdapter,\n { id, req, versionData, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] updateGlobalVersion() called with:', {\n id,\n versionData,\n ...args,\n })\n\n const result = {} as any\n console.log('[DB_CONTENT_API] updateGlobalVersion() result:', result)\n return result\n}\n\nconst countGlobalVersions: CountGlobalVersions = async function countGlobalVersions(\n this: ContentAPIAdapter,\n { req, where, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] countGlobalVersions() called with:', { where, ...args })\n\n const totalDocs = 0\n const globalVersionsSlug = 'global-versions'\n\n console.log(\n `📊 [DB_CONTENT_API] countGlobalVersions result: ${totalDocs} versions in ${globalVersionsSlug}`,\n )\n\n const result = { totalDocs }\n console.log('[DB_CONTENT_API] countGlobalVersions() result:', result)\n return result\n}\n\nconst request = async function <T = any>(\n this: ContentAPIAdapter,\n path: string,\n body = {},\n): Promise<T> {\n console.log('🔍 [DB_CONTENT_API] request() called with:', { body, path })\n const res = await fetch(`${this.contentApiUrl}${path}`, {\n body: JSON.stringify({\n contentSystemId: this.contentSystemId,\n ...body,\n }),\n headers: {\n Authorization: `Bearer ${this.projectToken}`,\n 'Content-Type': 'application/json',\n 'X-Api-Key': this.contentApiKey,\n },\n method: 'POST',\n })\n\n return res.json() as T\n}\n\nconst beginTransaction: BeginTransaction = async function (options?: Record<string, any>) {\n console.log('🔍 [DB_CONTENT_API] beginTransaction() called', options)\n return null\n}\n\nconst commitTransaction: CommitTransaction = async function (\n id: number | Promise<number | string> | string,\n) {\n console.log('🔍 [DB_CONTENT_API] commitTransaction() called', id)\n}\n\nexport const contentAPIAdapter = (opts: ContentAPIDatabaseAdapterOptions): DatabaseAdapterObj => {\n return {\n name: 'content_api',\n defaultIDType: 'text',\n init: ({ payload }) => {\n return createDatabaseAdapter<ContentAPIAdapter>({\n name: 'content_api',\n beginTransaction,\n commitTransaction,\n contentApiKey: opts.contentApiKey,\n contentApiUrl: opts.contentApiUrl,\n contentSystemId: opts.contentSystemId,\n count,\n countGlobalVersions,\n countVersions,\n create,\n createGlobal,\n createGlobalVersion,\n createVersion,\n defaultIDType: 'text',\n deleteMany,\n deleteOne,\n deleteVersions,\n find,\n findDistinct,\n findGlobal,\n findGlobalVersions,\n findOne,\n findVersions,\n init,\n packageName: '@payloadcms/db-content-api',\n payload,\n projectToken: opts.projectToken,\n queryDrafts,\n request,\n rollbackTransaction: async () => {},\n updateGlobal,\n updateGlobalVersion,\n updateMany,\n updateOne,\n updateVersion,\n upsert,\n })\n },\n }\n}\n"],"names":["randomUUID","createDatabaseAdapter","slugIsGlobal","slug","startsWith","getGlobalSlug","transformWhereClause","where","undefined","and","map","filter","Boolean","or","transformedClauses","field","condition","Object","entries","Array","isArray","push","operator","value","path","length","formatDocument","doc","id","data","meta","_meta","init","console","log","payload","config","collections","c","collection","response","request","contentSystemId","key","error","warn","global","globals","globalKey","g","find","limit","page","req","sort","args","JSON","stringify","collectionKey","offset","flat","s","direction","values","keys","message","docs","result","pagination","totalDocs","total","actualLimit","totalPages","Math","ceil","hasNextPage","hasPrevPage","nextPage","pagingCounter","prevPage","findVersions","queryDrafts","createVersion","collectionSlug","versionData","updateVersion","deleteVersions","versionsToDelete","versionCollection","findOne","body","updateMany","createOnMissing","updateOne","whereClause","returning","exclude","deleteMany","deletedCount","count","deleteOne","deletedDocs","docId","create","randomKey","countVersions","upsert","updateResponse","documentKey","Date","now","success","createGlobal","findGlobal","findDistinct","distinctValues","paginatedValues","endIndex","updateGlobal","findGlobalVersions","createGlobalVersion","updateGlobalVersion","countGlobalVersions","globalVersionsSlug","res","fetch","contentApiUrl","headers","Authorization","projectToken","contentApiKey","method","json","beginTransaction","options","commitTransaction","contentAPIAdapter","opts","name","defaultIDType","packageName","rollbackTransaction"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/db-adapter.ts"],"sourcesContent":["import type {\n BaseDatabaseAdapter,\n BeginTransaction,\n Collection,\n CollectionSlug,\n CommitTransaction,\n Config,\n Count,\n CountGlobalVersions,\n CountVersions,\n Create,\n CreateGlobal,\n CreateGlobalVersion,\n CreateVersion,\n DatabaseAdapterObj,\n DeleteMany,\n DeleteOne,\n DeleteVersions,\n Find,\n FindDistinct,\n FindGlobal,\n FindGlobalVersions,\n FindOne,\n FindVersions,\n FlattenedField,\n QueryDrafts,\n SanitizedConfig,\n SanitizedGlobalConfig,\n UpdateGlobal,\n UpdateGlobalVersion,\n UpdateMany,\n UpdateOne,\n UpdateVersion,\n Upsert,\n Where,\n} from 'payload'\n\nimport { randomUUID } from 'crypto'\nimport {\n buildVersionCollectionFields,\n buildVersionGlobalFields,\n combineQueries,\n createArrayFromCommaDelineated,\n createDatabaseAdapter,\n getFieldByPath,\n} from 'payload'\n// import { fieldShouldBeLocalized } from 'payload/shared'\n// import { db, uuid } from './db'\n\ninterface ContentAPIDatabaseAdapterOptions {\n contentApiKey: string\n contentApiUrl: string\n contentSystemId: string\n projectToken: string\n}\n\nexport type ContentAPIAdapter = {\n contentApiKey: string\n contentApiUrl: string\n contentSystemId: string\n projectToken: string\n request<T = any>(path: string, body?: any): Promise<T>\n} & BaseDatabaseAdapter\n\nconst slugIsGlobal = (slug: string) => slug.startsWith('_global-')\n\nconst getGlobalSlug = (slug: string) => `_global-${slug}`\n\n// Transform Payload Where format to Content API WhereClause format\nfunction transformWhereClause(where: undefined | Where): any {\n if (!where) {\n return undefined\n }\n\n // Handle and/or logical operators\n if (where.and) {\n return {\n and: where.and.map(transformWhereClause).filter(Boolean),\n }\n }\n\n if (where.or) {\n return {\n or: where.or.map(transformWhereClause).filter(Boolean),\n }\n }\n\n // Transform field conditions\n const transformedClauses: any[] = []\n\n for (const [field, condition] of Object.entries(where)) {\n if (field === 'and' || field === 'or') {\n continue\n }\n\n if (Array.isArray(condition)) {\n // Handle nested and/or arrays\n transformedClauses.push({\n [field]: condition.map(transformWhereClause).filter(Boolean),\n })\n } else if (typeof condition === 'object' && condition !== null) {\n // Handle field operators like { equals: 'value' }, { greater_than: 10 }\n for (const [operator, value] of Object.entries(condition)) {\n transformedClauses.push({\n operator: operator as any, // Map Payload operators to Content API operators\n path: field,\n value,\n })\n }\n } else {\n // Handle direct field values like { status: 'published' }\n transformedClauses.push({\n operator: 'equals',\n path: field,\n value: condition,\n })\n }\n }\n\n if (transformedClauses.length === 1) {\n return transformedClauses[0]\n } else if (transformedClauses.length > 1) {\n return {\n and: transformedClauses,\n }\n }\n\n return undefined\n}\n\nconst formatDocument = (doc: any) => {\n if (!doc) {\n return null\n }\n\n const { id, data, ...meta } = doc\n\n return {\n id,\n _meta: meta,\n ...data,\n }\n}\n\nasync function init(this: ContentAPIAdapter) {\n console.log('🔍 [DB_CONTENT_API] init() called')\n console.log('🔍 [DB_CONTENT_API] this:', this)\n console.log(\n '🔍 [DB_CONTENT_API] payload collections:',\n this.payload.config.collections.map((c) => c.slug),\n )\n\n // Create collections in content API\n for (const collection of this.payload.config.collections) {\n try {\n console.log(`🔧 [DB_CONTENT_API] Creating collection: ${collection.slug}`)\n const response = await this.request('/api/v0/collections', {\n contentSystemId: this.contentSystemId,\n key: collection.slug,\n })\n\n if (response.error) {\n console.error(\n `[DB_CONTENT_API] create collection ${collection.slug} failure`,\n response.error,\n )\n } else {\n console.log(`✅ [DB_CONTENT_API] Created collection: ${collection.slug}`)\n }\n } catch (error) {\n console.warn(`⚠️ [DB_CONTENT_API] Failed to create collection ${collection.slug}:`, error)\n }\n }\n\n // Create globals as collections (with _global- prefix)\n for (const global of this.payload.config.globals) {\n try {\n const globalKey = getGlobalSlug(global.slug)\n console.log(`🔧 [DB_CONTENT_API] Creating global collection: ${globalKey}`)\n const response = await this.request('/api/v0/collections', {\n contentSystemId: this.contentSystemId,\n key: globalKey,\n })\n\n if (response.error) {\n console.error(\n `[DB_CONTENT_API] create global collection ${globalKey} failure`,\n response.error,\n )\n } else {\n console.log(`✅ [DB_CONTENT_API] Created global collection: ${globalKey}`)\n }\n } catch (error) {\n console.warn(`⚠️ [DB_CONTENT_API] Failed to create global collection ${global.slug}:`, error)\n }\n }\n\n console.log(\n '🔍 [DB_CONTENT_API] payload globals:',\n this.payload.config.globals.map((g) => g.slug),\n )\n}\n\nconst find: Find = async function find(\n this: ContentAPIAdapter,\n { collection, limit, page = 1, req, sort, where, ...args },\n) {\n console.log(\n '🔍 [DB_CONTENT_API] find() called with:',\n collection,\n JSON.stringify(transformWhereClause(where), null, 2),\n { limit, page, sort, ...args },\n )\n\n try {\n const response = await this.request<any>('/api/v0/documents:find', {\n collectionKey: collection,\n contentSystemId: this.contentSystemId,\n limit,\n offset: (page - 1) * (limit || 10),\n sort: sort\n ? [sort].flat().map((s: any) => ({\n direction: Object.values(s)[0] === -1 ? 'dsc' : 'asc',\n path: Object.keys(s)[0],\n }))\n : undefined,\n where: transformWhereClause(where),\n })\n\n if (response.error) {\n console.error('[DB_CONTENT_API] find() failure', response.error?.message || response.error)\n }\n\n const docs = response.result?.data || []\n const pagination = response.result?.pagination\n const totalDocs = pagination?.total || docs.length\n const actualLimit = limit || 10\n const totalPages = Math.ceil(totalDocs / actualLimit)\n const hasNextPage = page < totalPages\n\n const result = {\n docs: docs.map(formatDocument),\n hasNextPage,\n hasPrevPage: page > 1,\n limit: actualLimit,\n nextPage: hasNextPage ? page + 1 : null,\n page,\n pagingCounter: 1,\n prevPage: page > 1 ? page - 1 : null,\n totalDocs,\n totalPages,\n }\n console.log('[DB_CONTENT_API] find() result:', result)\n return result\n } catch (error) {\n console.error(`❌ [DB_CONTENT_API] Error in find():`, error)\n const docs: any[] = []\n const hasNextPage = false\n const totalPages = 1\n\n return {\n docs,\n hasNextPage,\n hasPrevPage: page > 1,\n limit: limit || docs.length,\n nextPage: hasNextPage ? page + 1 : null,\n page,\n pagingCounter: 1,\n prevPage: page > 1 ? page - 1 : null,\n totalDocs: docs.length,\n totalPages,\n }\n }\n}\n\nconst findVersions: FindVersions = async function findVersions(\n this: ContentAPIAdapter,\n { collection, limit, page = 1, req, where, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] findVersions() called with:', {\n collection,\n limit,\n page,\n where,\n ...args,\n })\n\n const docs: any[] = []\n const hasNextPage = false\n const result = {\n docs,\n hasNextPage,\n hasPrevPage: page > 1,\n limit: limit || docs.length,\n nextPage: hasNextPage ? page + 1 : null,\n page,\n pagingCounter: 1,\n prevPage: page > 1 ? page - 1 : null,\n totalDocs: docs.length,\n totalPages: limit && docs.length ? Math.ceil(docs.length / limit) : 1,\n }\n console.log('[DB_CONTENT_API] findVersions() result:', result)\n return result\n}\n\nconst queryDrafts: QueryDrafts = async function queryDrafts(\n this: ContentAPIAdapter,\n { collection, limit, page = 1, req, where, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] queryDrafts() called with:', {\n collection,\n limit,\n page,\n where,\n ...args,\n })\n\n const docs: any[] = []\n const hasNextPage = false\n const result = {\n docs,\n hasNextPage,\n hasPrevPage: page > 1,\n limit: limit || docs.length,\n nextPage: hasNextPage ? page + 1 : null,\n page,\n pagingCounter: 1,\n prevPage: page > 1 ? page - 1 : null,\n totalDocs: docs.length,\n totalPages: limit && docs.length ? Math.ceil(docs.length / limit) : 1,\n }\n console.log('[DB_CONTENT_API] queryDrafts() result:', result)\n return result\n}\n\nconst createVersion: CreateVersion = async function createVersion(\n this: ContentAPIAdapter,\n { collectionSlug, req, versionData, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] createVersion() called with:', {\n collectionSlug,\n versionData,\n ...args,\n })\n\n const result = {} as any\n console.log('[DB_CONTENT_API] createVersion() result:', result)\n return result\n}\n\nconst updateVersion: UpdateVersion = async function updateVersion(\n this: ContentAPIAdapter,\n { id, collection, req, versionData, where, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] updateVersion() called with:', {\n id,\n collection,\n versionData,\n ...args,\n })\n\n const result = {} as any\n console.log('[DB_CONTENT_API] updateVersion() result:', result)\n return result\n}\n\nconst deleteVersions: DeleteVersions = async function deleteVersions(\n this: ContentAPIAdapter,\n { collection, req, where, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] deleteVersions() called with:', { collection, where, ...args })\n\n const versionsToDelete: any[] = []\n const versionCollection = 'versions'\n\n console.log(\n `🗑️ [DB_CONTENT_API] Deleted ${versionsToDelete.length} versions from ${versionCollection}`,\n )\n\n // return versionsToDelete.length\n}\n\nconst findOne: FindOne = async function findOne(\n this: ContentAPIAdapter,\n { collection, req, where, ...args },\n) {\n console.log(\n '🔍 [DB_CONTENT_API] findOne() called with:',\n collection,\n JSON.stringify(transformWhereClause(where), null, 2),\n args,\n req?.body,\n )\n\n try {\n const response = await this.request<any>('/api/v0/documents:find', {\n collectionKey: collection,\n contentSystemId: this.contentSystemId,\n limit: 1,\n offset: 0,\n where: transformWhereClause(where),\n })\n\n if (response.error) {\n console.error('[DB_CONTENT_API] findOne() failure', response.error?.message || response.error)\n }\n\n const docs = response.result?.data || []\n const result = docs.length > 0 ? docs[0] : null\n console.log('[DB_CONTENT_API] findOne() result:', result)\n return formatDocument(result)\n } catch (error) {\n console.error(`❌ [DB_CONTENT_API] Error in findOne():`, error)\n return null\n }\n}\n\nconst updateMany: UpdateMany = async function updateMany(\n this: ContentAPIAdapter,\n { collection, data, req, where, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] updateMany() called with:', { collection, data, where, ...args })\n try {\n const response = await this.request<any>('/api/v0/documents:update', {\n collectionKey: collection,\n contentSystemId: this.contentSystemId,\n createOnMissing: false,\n data,\n where: transformWhereClause(where),\n })\n\n if (response.error) {\n console.error(\n '[DB_CONTENT_API] updateMany() failure',\n response.error?.message || response.error,\n )\n }\n\n // Return array of updated documents if available, otherwise return placeholder\n const result = response.result?.data || []\n console.log('[DB_CONTENT_API] updateMany() result:', result)\n return result\n } catch (error) {\n console.error(`❌ [DB_CONTENT_API] Error in updateMany():`, error)\n return []\n }\n}\n\nconst updateOne: UpdateOne = async function updateOne(\n this: ContentAPIAdapter,\n { id, collection, data, req, where = {}, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] updateOne() called with:', {\n id,\n collection,\n data,\n where,\n ...args,\n })\n try {\n const whereClause = id\n ? { operator: 'equals', path: 'id', value: id }\n : transformWhereClause(where)\n const response = await this.request<any>('/api/v0/documents:update', {\n collectionKey: collection,\n contentSystemId: this.contentSystemId,\n createOnMissing: false,\n data,\n returning: { exclude: [] },\n where: whereClause,\n })\n\n if (response.error) {\n console.error(\n '[DB_CONTENT_API] updateOne() failure',\n response.error?.message || response.error,\n )\n }\n\n const result = response.result?.data || { id, ...data }\n console.log('[DB_CONTENT_API] updateOne() result:', result)\n return result\n } catch (error) {\n console.error(`❌ [DB_CONTENT_API] Error in updateOne():`, error)\n return { id, ...data }\n }\n}\n\nconst deleteMany: DeleteMany = async function deleteMany(\n this: ContentAPIAdapter,\n { collection, req, where, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] deleteMany() called with:', { collection, where, ...args })\n try {\n const response = await this.request<any>('/api/v0/documents:delete', {\n collectionKey: collection,\n contentSystemId: this.contentSystemId,\n returning: false,\n where: transformWhereClause(where),\n })\n\n if (response.error) {\n console.error(\n '[DB_CONTENT_API] deleteMany() failure',\n response.error?.message || response.error,\n )\n }\n\n const deletedCount = response.result?.count || 0\n console.log(`🗑️ [DB_CONTENT_API] Deleted ${deletedCount} documents from ${collection}`)\n } catch (error) {\n console.error(`❌ [DB_CONTENT_API] Error in deleteMany():`, error)\n }\n}\n\nconst deleteOne: DeleteOne = async function deleteOne(\n this: ContentAPIAdapter,\n { collection, req, where, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] deleteOne() called with:', { collection, where, ...args })\n try {\n const response = await this.request<any>('/api/v0/documents:delete', {\n collectionKey: collection,\n contentSystemId: this.contentSystemId,\n returning: { exclude: [] },\n where: transformWhereClause(where),\n })\n\n if (response.error) {\n console.error(\n '[DB_CONTENT_API] deleteOne() failure',\n response.error?.message || response.error,\n )\n }\n\n const deletedDocs = response.result?.data || []\n const docId = deletedDocs.length > 0 ? deletedDocs[0].id : 'unknown'\n const result = deletedDocs.length > 0 ? deletedDocs[0] : {}\n\n console.log(`🗑️ [DB_CONTENT_API] Deleted document ${docId} from ${collection}`)\n console.log('[DB_CONTENT_API] deleteOne() result:', result)\n return result\n } catch (error) {\n console.error(`❌ [DB_CONTENT_API] Error in deleteOne():`, error)\n return {}\n }\n}\n\nconst create: Create = async function create(\n this: ContentAPIAdapter,\n { collection, data, req, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] create() called with:', { collection, data, ...args })\n try {\n const randomKey = randomUUID()\n const response = await this.request<any>('/api/v0/documents:create', {\n collectionKey: collection,\n contentSystemId: this.contentSystemId,\n data,\n key: data.key || data.id || `doc-${randomKey}`,\n })\n\n if (response.error) {\n console.error('[DB_CONTENT_API] create() failure', response.error?.message || response.error)\n }\n\n const result = response.result?.data || response.result || { id: `doc-${randomKey}`, ...data }\n console.log('[DB_CONTENT_API] create() result:', result)\n return result\n } catch (error) {\n console.error(`❌ [DB_CONTENT_API] Error in create():`, error)\n return { id: `doc-${randomUUID()}`, ...data }\n }\n}\n\nconst count: Count = async function count(\n this: ContentAPIAdapter,\n { collection, req, where = {}, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] count() called with:', { collection, where, ...args })\n try {\n const response = await this.request<any>('/api/v0/documents:count', {\n collectionKey: collection,\n contentSystemId: this.contentSystemId,\n where: transformWhereClause(where),\n })\n\n if (response.error) {\n console.error('[DB_CONTENT_API] count() failure', response.error?.message || response.error)\n }\n\n const result = { totalDocs: response.result?.count || 0 }\n console.log('[DB_CONTENT_API] count() result:', result)\n return result\n } catch (error) {\n console.error(`❌ [DB_CONTENT_API] Error in count():`, error)\n return { totalDocs: 0 }\n }\n}\n\nconst countVersions: CountVersions = async function countVersions(\n this: ContentAPIAdapter,\n { collection, req, where, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] countVersions() called with:', { collection, where, ...args })\n\n const result = { totalDocs: 0 }\n console.log('[DB_CONTENT_API] countVersions() result:', result)\n return result\n}\n\nconst upsert: Upsert = async function upsert(\n this: ContentAPIAdapter,\n { collection, data, req, where, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] upsert() called with:', { collection, data, where, ...args })\n try {\n // Try to update first\n const updateResponse = await this.request<any>('/api/v0/documents:update', {\n collectionKey: collection,\n contentSystemId: this.contentSystemId,\n createOnMissing: { documentKey: `upsert-${Date.now()}` },\n data,\n returning: { exclude: [] },\n where: transformWhereClause(where),\n })\n\n if (!updateResponse.success) {\n console.log('[DB_CONTENT_API] upsert() failure', updateResponse.error)\n }\n\n const result = updateResponse.result?.data || { ...data }\n console.log('[DB_CONTENT_API] upsert() result:', result)\n return result\n } catch (error) {\n console.error(`❌ [DB_CONTENT_API] Error in upsert():`, error)\n return { ...data }\n }\n}\n\nconst createGlobal: CreateGlobal = async function createGlobal(\n this: ContentAPIAdapter,\n { slug, data, req, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] createGlobal() called with:', { slug, data, ...args })\n\n try {\n const globalKey = getGlobalSlug(slug)\n const response = await this.request<any>('/api/v0/documents:create', {\n collectionKey: globalKey,\n contentSystemId: this.contentSystemId,\n data,\n key: `global-${slug}`,\n })\n\n if (response.error) {\n console.error(\n '[DB_CONTENT_API] createGlobal() failure',\n response.error?.message || response.error,\n )\n }\n\n const result = response.result?.data || response.result || { id: `global-${slug}`, ...data }\n console.log('[DB_CONTENT_API] createGlobal() result:', result)\n return result\n } catch (error) {\n console.error(`❌ [DB_CONTENT_API] Error in createGlobal():`, error)\n return { id: `global-${slug}`, ...data }\n }\n}\n\nconst findGlobal: FindGlobal = async function findGlobal(\n this: ContentAPIAdapter,\n { slug, req, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] findGlobal() called with:', { slug, ...args })\n\n try {\n const globalKey = getGlobalSlug(slug)\n const response = await this.request<any>('/api/v0/documents:find', {\n collectionKey: globalKey,\n contentSystemId: this.contentSystemId,\n limit: 1,\n offset: 0,\n })\n\n if (response.error) {\n console.error(\n '[DB_CONTENT_API] findGlobal() failure',\n response.error?.message || response.error,\n )\n }\n\n const docs = response.result?.data || []\n const result = docs.length > 0 ? docs[0] : null\n console.log('[DB_CONTENT_API] findGlobal() result:', result)\n return formatDocument(result)\n } catch (error) {\n console.error(`❌ [DB_CONTENT_API] Error in findGlobal():`, error)\n return null\n }\n}\n\nconst findDistinct: FindDistinct = async function findDistinct(\n this: ContentAPIAdapter,\n { collection, field, limit, page = 1, req, where, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] findDistinct() called with:', {\n collection,\n field,\n limit,\n page,\n where,\n ...args,\n })\n\n const distinctValues: any[] = []\n const paginatedValues: any[] = []\n const endIndex = 0\n const totalDocs = 0\n\n console.log(\n `📊 [DB_CONTENT_API] findDistinct result: ${distinctValues.length} distinct values for ${field}`,\n )\n\n return {\n hasNextPage: limit ? endIndex < totalDocs : false,\n hasPrevPage: page > 1,\n limit: limit || totalDocs,\n nextPage: limit && endIndex < totalDocs ? page + 1 : null,\n page,\n pagingCounter: 1,\n prevPage: page > 1 ? page - 1 : null,\n totalDocs,\n totalPages: limit ? Math.ceil(totalDocs / limit) : 1,\n values: paginatedValues,\n }\n}\n\nconst updateGlobal: UpdateGlobal = async function updateGlobal(\n this: ContentAPIAdapter,\n { slug, data, req, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] updateGlobal() called with:', { slug, data, ...args })\n\n try {\n const globalKey = getGlobalSlug(slug)\n const response = await this.request<any>('/api/v0/documents:update', {\n collectionKey: globalKey,\n contentSystemId: this.contentSystemId,\n createOnMissing: { documentKey: `global-${slug}` },\n data,\n returning: { exclude: [] },\n where: { operator: 'equals', path: 'key', value: `global-${slug}` },\n })\n\n if (response.error) {\n console.error(\n '[DB_CONTENT_API] updateGlobal() failure',\n response.error?.message || response.error,\n )\n }\n\n const result = response.result?.data || { id: `global-${slug}`, ...data }\n console.log('[DB_CONTENT_API] updateGlobal() result:', result)\n return result\n } catch (error) {\n console.error(`❌ [DB_CONTENT_API] Error in updateGlobal():`, error)\n return { id: `global-${slug}`, ...data }\n }\n}\n\nconst findGlobalVersions: FindGlobalVersions = async function findGlobalVersions(\n this: ContentAPIAdapter,\n { limit, page = 1, req, where, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] findGlobalVersions() called with:', {\n limit,\n page,\n where,\n ...args,\n })\n\n const docs: any[] = []\n const hasNextPage = false\n const result = {\n docs,\n hasNextPage,\n hasPrevPage: page > 1,\n limit: limit || docs.length,\n nextPage: hasNextPage ? page + 1 : null,\n page,\n pagingCounter: 1,\n prevPage: page > 1 ? page - 1 : null,\n totalDocs: docs.length,\n totalPages: limit && docs.length ? Math.ceil(docs.length / limit) : 1,\n }\n console.log('[DB_CONTENT_API] findGlobalVersions() result:', result)\n return result\n}\n\nconst createGlobalVersion: CreateGlobalVersion = async function createGlobalVersion(\n this: ContentAPIAdapter,\n { req, versionData, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] createGlobalVersion() called with:', { versionData, ...args })\n\n const result = {} as any\n console.log('[DB_CONTENT_API] createGlobalVersion() result:', result)\n return result\n}\n\nconst updateGlobalVersion: UpdateGlobalVersion = async function updateGlobalVersion(\n this: ContentAPIAdapter,\n { id, req, versionData, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] updateGlobalVersion() called with:', {\n id,\n versionData,\n ...args,\n })\n\n const result = {} as any\n console.log('[DB_CONTENT_API] updateGlobalVersion() result:', result)\n return result\n}\n\nconst countGlobalVersions: CountGlobalVersions = async function countGlobalVersions(\n this: ContentAPIAdapter,\n { req, where, ...args },\n) {\n console.log('🔍 [DB_CONTENT_API] countGlobalVersions() called with:', { where, ...args })\n\n const totalDocs = 0\n const globalVersionsSlug = 'global-versions'\n\n console.log(\n `📊 [DB_CONTENT_API] countGlobalVersions result: ${totalDocs} versions in ${globalVersionsSlug}`,\n )\n\n const result = { totalDocs }\n console.log('[DB_CONTENT_API] countGlobalVersions() result:', result)\n return result\n}\n\nconst request = async function <T = any>(\n this: ContentAPIAdapter,\n path: string,\n body = {},\n): Promise<T> {\n console.log('🔍 [DB_CONTENT_API] request() called with:', { body, path })\n const res = await fetch(`${this.contentApiUrl}${path}`, {\n body: JSON.stringify({\n contentSystemId: this.contentSystemId,\n ...body,\n }),\n headers: {\n 'Content-Type': 'application/json',\n ...(this.contentApiKey\n ? {\n 'X-Api-Key': this.contentApiKey,\n }\n : {\n Authorization: `Bearer ${this.projectToken}`,\n }),\n },\n method: 'POST',\n })\n\n return res.json() as T\n}\n\nconst beginTransaction: BeginTransaction = async function (options?: Record<string, any>) {\n console.log('🔍 [DB_CONTENT_API] beginTransaction() called', options)\n return null\n}\n\nconst commitTransaction: CommitTransaction = async function (\n id: number | Promise<number | string> | string,\n) {\n console.log('🔍 [DB_CONTENT_API] commitTransaction() called', id)\n}\n\nexport const contentAPIAdapter = (opts: ContentAPIDatabaseAdapterOptions): DatabaseAdapterObj => {\n return {\n name: 'content_api',\n defaultIDType: 'text',\n init: ({ payload }) => {\n return createDatabaseAdapter<ContentAPIAdapter>({\n name: 'content_api',\n beginTransaction,\n commitTransaction,\n contentApiKey: opts.contentApiKey,\n contentApiUrl: opts.contentApiUrl,\n contentSystemId: opts.contentSystemId,\n count,\n countGlobalVersions,\n countVersions,\n create,\n createGlobal,\n createGlobalVersion,\n createVersion,\n defaultIDType: 'text',\n deleteMany,\n deleteOne,\n deleteVersions,\n find,\n findDistinct,\n findGlobal,\n findGlobalVersions,\n findOne,\n findVersions,\n init,\n packageName: '@payloadcms/db-content-api',\n payload,\n projectToken: opts.projectToken,\n queryDrafts,\n request,\n rollbackTransaction: async () => {},\n updateGlobal,\n updateGlobalVersion,\n updateMany,\n updateOne,\n updateVersion,\n upsert,\n })\n },\n }\n}\n"],"names":["randomUUID","createDatabaseAdapter","slugIsGlobal","slug","startsWith","getGlobalSlug","transformWhereClause","where","undefined","and","map","filter","Boolean","or","transformedClauses","field","condition","Object","entries","Array","isArray","push","operator","value","path","length","formatDocument","doc","id","data","meta","_meta","init","console","log","payload","config","collections","c","collection","response","request","contentSystemId","key","error","warn","global","globals","globalKey","g","find","limit","page","req","sort","args","JSON","stringify","collectionKey","offset","flat","s","direction","values","keys","message","docs","result","pagination","totalDocs","total","actualLimit","totalPages","Math","ceil","hasNextPage","hasPrevPage","nextPage","pagingCounter","prevPage","findVersions","queryDrafts","createVersion","collectionSlug","versionData","updateVersion","deleteVersions","versionsToDelete","versionCollection","findOne","body","updateMany","createOnMissing","updateOne","whereClause","returning","exclude","deleteMany","deletedCount","count","deleteOne","deletedDocs","docId","create","randomKey","countVersions","upsert","updateResponse","documentKey","Date","now","success","createGlobal","findGlobal","findDistinct","distinctValues","paginatedValues","endIndex","updateGlobal","findGlobalVersions","createGlobalVersion","updateGlobalVersion","countGlobalVersions","globalVersionsSlug","res","fetch","contentApiUrl","headers","contentApiKey","Authorization","projectToken","method","json","beginTransaction","options","commitTransaction","contentAPIAdapter","opts","name","defaultIDType","packageName","rollbackTransaction"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/oauth/components/LoginButton/index.tsx"],"names":[],"mappings":"AAIA,OAAO,KAA8B,MAAM,OAAO,CAAA;AAElD,OAAO,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/oauth/components/LoginButton/index.tsx"],"names":[],"mappings":"AAIA,OAAO,KAA8B,MAAM,OAAO,CAAA;AAElD,OAAO,cAAc,CAAA;AAgDrB,KAAK,uBAAuB,GAAG;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAqDhE,CAAA"}
|
|
@@ -1,10 +1,49 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useConfig } from '@payloadcms/ui';
|
|
4
4
|
import { useSearchParams } from 'next/navigation.js';
|
|
5
5
|
import React, { useEffect, useState } from 'react';
|
|
6
6
|
import './index.scss';
|
|
7
7
|
const baseClass = 'oauth-login';
|
|
8
|
+
// Figma logo SVG colored version
|
|
9
|
+
// const FigmaIcon: React.FC = () => (
|
|
10
|
+
// <svg fill="none" height="27" viewBox="0 0 400 600" width="18">
|
|
11
|
+
// <path
|
|
12
|
+
// d="M0 500C0 444.772 44.772 400 100 400H200V500C200 555.228 155.228 600 100 600C44.772 600 0 555.228 0 500Z"
|
|
13
|
+
// fill="#24CB71"
|
|
14
|
+
// />
|
|
15
|
+
// <path
|
|
16
|
+
// d="M200 0V200H300C355.228 200 400 155.228 400 100C400 44.772 355.228 0 300 0H200Z"
|
|
17
|
+
// fill="#FF7237"
|
|
18
|
+
// />
|
|
19
|
+
// <path
|
|
20
|
+
// d="M299.167 400C354.395 400 399.167 355.228 399.167 300C399.167 244.772 354.395 200 299.167 200C243.939 200 199.167 244.772 199.167 300C199.167 355.228 243.939 400 299.167 400Z"
|
|
21
|
+
// fill="#00B6FF"
|
|
22
|
+
// />
|
|
23
|
+
// <path
|
|
24
|
+
// d="M0 100C0 155.228 44.772 200 100 200H200V0H100C44.772 0 0 44.772 0 100Z"
|
|
25
|
+
// fill="#FF3737"
|
|
26
|
+
// />
|
|
27
|
+
// <path
|
|
28
|
+
// d="M0 300C0 355.228 44.772 400 100 400H200V200H100C44.772 200 0 244.772 0 300Z"
|
|
29
|
+
// fill="#874FFF"
|
|
30
|
+
// />
|
|
31
|
+
// </svg>
|
|
32
|
+
// )
|
|
33
|
+
// Figma logo SVG monochrome version
|
|
34
|
+
const FigmaIcon = ()=>/*#__PURE__*/ _jsx("svg", {
|
|
35
|
+
fill: "none",
|
|
36
|
+
height: "20px",
|
|
37
|
+
viewBox: "0 0 15 15",
|
|
38
|
+
width: "20px",
|
|
39
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
40
|
+
children: /*#__PURE__*/ _jsx("path", {
|
|
41
|
+
clipRule: "evenodd",
|
|
42
|
+
d: "M7.00005 2.04999H5.52505C4.71043 2.04999 4.05005 2.71037 4.05005 3.52499C4.05005 4.33961 4.71043 4.99999 5.52505 4.99999H7.00005V2.04999ZM7.00005 1.04999H8.00005H9.47505C10.842 1.04999 11.95 2.15808 11.95 3.52499C11.95 4.33163 11.5642 5.04815 10.9669 5.49999C11.5642 5.95184 11.95 6.66836 11.95 7.475C11.95 8.8419 10.842 9.95 9.47505 9.95C8.92236 9.95 8.41198 9.76884 8.00005 9.46266V9.95L8.00005 11.425C8.00005 12.7919 6.89195 13.9 5.52505 13.9C4.15814 13.9 3.05005 12.7919 3.05005 11.425C3.05005 10.6183 3.43593 9.90184 4.03317 9.44999C3.43593 8.99814 3.05005 8.28163 3.05005 7.475C3.05005 6.66836 3.43594 5.95184 4.03319 5.5C3.43594 5.04815 3.05005 4.33163 3.05005 3.52499C3.05005 2.15808 4.15814 1.04999 5.52505 1.04999H7.00005ZM8.00005 2.04999V4.99999H9.47505C10.2897 4.99999 10.95 4.33961 10.95 3.52499C10.95 2.71037 10.2897 2.04999 9.47505 2.04999H8.00005ZM5.52505 8.94998H7.00005L7.00005 7.4788L7.00005 7.475L7.00005 7.4712V6H5.52505C4.71043 6 4.05005 6.66038 4.05005 7.475C4.05005 8.28767 4.70727 8.94684 5.5192 8.94999L5.52505 8.94998ZM4.05005 11.425C4.05005 10.6123 4.70727 9.95315 5.5192 9.94999L5.52505 9.95H7.00005L7.00005 11.425C7.00005 12.2396 6.33967 12.9 5.52505 12.9C4.71043 12.9 4.05005 12.2396 4.05005 11.425ZM8.00005 7.47206C8.00164 6.65879 8.66141 6 9.47505 6C10.2897 6 10.95 6.66038 10.95 7.475C10.95 8.28962 10.2897 8.95 9.47505 8.95C8.66141 8.95 8.00164 8.29121 8.00005 7.47794V7.47206Z",
|
|
43
|
+
fill: "#FFFFFF",
|
|
44
|
+
fillRule: "evenodd"
|
|
45
|
+
})
|
|
46
|
+
});
|
|
8
47
|
export const DefaultLoginButton = ({ disabled, endpointSlug })=>{
|
|
9
48
|
const { config: { admin: { user: userSlug }, routes: { api }, serverURL } } = useConfig();
|
|
10
49
|
const [authorizeURL, setAuthorizeURL] = useState('');
|
|
@@ -40,11 +79,16 @@ export const DefaultLoginButton = ({ disabled, endpointSlug })=>{
|
|
|
40
79
|
}
|
|
41
80
|
return /*#__PURE__*/ _jsx("div", {
|
|
42
81
|
className: baseClass,
|
|
43
|
-
children: /*#__PURE__*/
|
|
82
|
+
children: /*#__PURE__*/ _jsxs("a", {
|
|
44
83
|
className: `${baseClass}__btn`,
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
84
|
+
href: authorizeURL,
|
|
85
|
+
children: [
|
|
86
|
+
/*#__PURE__*/ _jsx(FigmaIcon, {}),
|
|
87
|
+
/*#__PURE__*/ _jsx("span", {
|
|
88
|
+
className: `${baseClass}__text`,
|
|
89
|
+
children: "Log in with Figma"
|
|
90
|
+
})
|
|
91
|
+
]
|
|
48
92
|
})
|
|
49
93
|
});
|
|
50
94
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/oauth/components/LoginButton/index.tsx"],"sourcesContent":["'use client'\n\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../../src/oauth/components/LoginButton/index.tsx"],"sourcesContent":["'use client'\n\nimport { useConfig } from '@payloadcms/ui'\nimport { useSearchParams } from 'next/navigation.js'\nimport React, { useEffect, useState } from 'react'\n\nimport './index.scss'\n\nconst baseClass = 'oauth-login'\n\n// Figma logo SVG colored version\n// const FigmaIcon: React.FC = () => (\n// <svg fill=\"none\" height=\"27\" viewBox=\"0 0 400 600\" width=\"18\">\n// <path\n// d=\"M0 500C0 444.772 44.772 400 100 400H200V500C200 555.228 155.228 600 100 600C44.772 600 0 555.228 0 500Z\"\n// fill=\"#24CB71\"\n// />\n// <path\n// d=\"M200 0V200H300C355.228 200 400 155.228 400 100C400 44.772 355.228 0 300 0H200Z\"\n// fill=\"#FF7237\"\n// />\n// <path\n// d=\"M299.167 400C354.395 400 399.167 355.228 399.167 300C399.167 244.772 354.395 200 299.167 200C243.939 200 199.167 244.772 199.167 300C199.167 355.228 243.939 400 299.167 400Z\"\n// fill=\"#00B6FF\"\n// />\n// <path\n// d=\"M0 100C0 155.228 44.772 200 100 200H200V0H100C44.772 0 0 44.772 0 100Z\"\n// fill=\"#FF3737\"\n// />\n// <path\n// d=\"M0 300C0 355.228 44.772 400 100 400H200V200H100C44.772 200 0 244.772 0 300Z\"\n// fill=\"#874FFF\"\n// />\n// </svg>\n// )\n\n// Figma logo SVG monochrome version\nconst FigmaIcon: React.FC = () => (\n <svg\n fill=\"none\"\n height=\"20px\"\n viewBox=\"0 0 15 15\"\n width=\"20px\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n clipRule=\"evenodd\"\n d=\"M7.00005 2.04999H5.52505C4.71043 2.04999 4.05005 2.71037 4.05005 3.52499C4.05005 4.33961 4.71043 4.99999 5.52505 4.99999H7.00005V2.04999ZM7.00005 1.04999H8.00005H9.47505C10.842 1.04999 11.95 2.15808 11.95 3.52499C11.95 4.33163 11.5642 5.04815 10.9669 5.49999C11.5642 5.95184 11.95 6.66836 11.95 7.475C11.95 8.8419 10.842 9.95 9.47505 9.95C8.92236 9.95 8.41198 9.76884 8.00005 9.46266V9.95L8.00005 11.425C8.00005 12.7919 6.89195 13.9 5.52505 13.9C4.15814 13.9 3.05005 12.7919 3.05005 11.425C3.05005 10.6183 3.43593 9.90184 4.03317 9.44999C3.43593 8.99814 3.05005 8.28163 3.05005 7.475C3.05005 6.66836 3.43594 5.95184 4.03319 5.5C3.43594 5.04815 3.05005 4.33163 3.05005 3.52499C3.05005 2.15808 4.15814 1.04999 5.52505 1.04999H7.00005ZM8.00005 2.04999V4.99999H9.47505C10.2897 4.99999 10.95 4.33961 10.95 3.52499C10.95 2.71037 10.2897 2.04999 9.47505 2.04999H8.00005ZM5.52505 8.94998H7.00005L7.00005 7.4788L7.00005 7.475L7.00005 7.4712V6H5.52505C4.71043 6 4.05005 6.66038 4.05005 7.475C4.05005 8.28767 4.70727 8.94684 5.5192 8.94999L5.52505 8.94998ZM4.05005 11.425C4.05005 10.6123 4.70727 9.95315 5.5192 9.94999L5.52505 9.95H7.00005L7.00005 11.425C7.00005 12.2396 6.33967 12.9 5.52505 12.9C4.71043 12.9 4.05005 12.2396 4.05005 11.425ZM8.00005 7.47206C8.00164 6.65879 8.66141 6 9.47505 6C10.2897 6 10.95 6.66038 10.95 7.475C10.95 8.28962 10.2897 8.95 9.47505 8.95C8.66141 8.95 8.00164 8.29121 8.00005 7.47794V7.47206Z\"\n fill=\"#FFFFFF\"\n fillRule=\"evenodd\"\n />\n </svg>\n)\n\ntype DefaultLoginButtonProps = {\n disabled?: boolean\n endpointSlug: string\n}\n\nexport const DefaultLoginButton: React.FC<DefaultLoginButtonProps> = ({\n disabled,\n endpointSlug,\n}: {\n disabled?: boolean\n endpointSlug: string\n}) => {\n const {\n config: {\n admin: { user: userSlug },\n routes: { api },\n serverURL,\n },\n } = useConfig()\n const [authorizeURL, setAuthorizeURL] = useState('')\n\n const searchParams = useSearchParams()\n const payloadRedirect = searchParams.get('redirect')\n\n useEffect(() => {\n if (payloadRedirect && !disabled) {\n // set cookie to redirect to the original page\n document.cookie = `payloadRedirect=${payloadRedirect}; path=/`\n }\n }, [payloadRedirect, disabled])\n\n useEffect(() => {\n const getAuthorizeURL = async () => {\n const serverURLFromWindow = window.location.origin\n const data = await fetch(\n `${serverURL}${api}/${userSlug}/${endpointSlug}/meta?serverURL=${serverURLFromWindow}`,\n ).then((res) => res.json())\n\n if (!disabled) {\n setAuthorizeURL(data.authorizeURL)\n }\n }\n\n void getAuthorizeURL()\n }, [api, serverURL, userSlug, disabled, endpointSlug])\n\n if (disabled) {\n return null\n }\n\n return (\n <div className={baseClass}>\n <a className={`${baseClass}__btn`} href={authorizeURL}>\n <FigmaIcon />\n <span className={`${baseClass}__text`}>Log in with Figma</span>\n </a>\n </div>\n )\n}\n"],"names":["useConfig","useSearchParams","React","useEffect","useState","baseClass","FigmaIcon","svg","fill","height","viewBox","width","xmlns","path","clipRule","d","fillRule","DefaultLoginButton","disabled","endpointSlug","config","admin","user","userSlug","routes","api","serverURL","authorizeURL","setAuthorizeURL","searchParams","payloadRedirect","get","document","cookie","getAuthorizeURL","serverURLFromWindow","window","location","origin","data","fetch","then","res","json","div","className","a","href","span"],"mappings":"AAAA;;AAEA,SAASA,SAAS,QAAQ,iBAAgB;AAC1C,SAASC,eAAe,QAAQ,qBAAoB;AACpD,OAAOC,SAASC,SAAS,EAAEC,QAAQ,QAAQ,QAAO;AAElD,OAAO,eAAc;AAErB,MAAMC,YAAY;AAElB,iCAAiC;AACjC,sCAAsC;AACtC,mEAAmE;AACnE,YAAY;AACZ,oHAAoH;AACpH,uBAAuB;AACvB,SAAS;AACT,YAAY;AACZ,2FAA2F;AAC3F,uBAAuB;AACvB,SAAS;AACT,YAAY;AACZ,0LAA0L;AAC1L,uBAAuB;AACvB,SAAS;AACT,YAAY;AACZ,mFAAmF;AACnF,uBAAuB;AACvB,SAAS;AACT,YAAY;AACZ,wFAAwF;AACxF,uBAAuB;AACvB,SAAS;AACT,WAAW;AACX,IAAI;AAEJ,oCAAoC;AACpC,MAAMC,YAAsB,kBAC1B,KAACC;QACCC,MAAK;QACLC,QAAO;QACPC,SAAQ;QACRC,OAAM;QACNC,OAAM;kBAEN,cAAA,KAACC;YACCC,UAAS;YACTC,GAAE;YACFP,MAAK;YACLQ,UAAS;;;AAUf,OAAO,MAAMC,qBAAwD,CAAC,EACpEC,QAAQ,EACRC,YAAY,EAIb;IACC,MAAM,EACJC,QAAQ,EACNC,OAAO,EAAEC,MAAMC,QAAQ,EAAE,EACzBC,QAAQ,EAAEC,GAAG,EAAE,EACfC,SAAS,EACV,EACF,GAAG1B;IACJ,MAAM,CAAC2B,cAAcC,gBAAgB,GAAGxB,SAAS;IAEjD,MAAMyB,eAAe5B;IACrB,MAAM6B,kBAAkBD,aAAaE,GAAG,CAAC;IAEzC5B,UAAU;QACR,IAAI2B,mBAAmB,CAACZ,UAAU;YAChC,8CAA8C;YAC9Cc,SAASC,MAAM,GAAG,CAAC,gBAAgB,EAAEH,gBAAgB,QAAQ,CAAC;QAChE;IACF,GAAG;QAACA;QAAiBZ;KAAS;IAE9Bf,UAAU;QACR,MAAM+B,kBAAkB;YACtB,MAAMC,sBAAsBC,OAAOC,QAAQ,CAACC,MAAM;YAClD,MAAMC,OAAO,MAAMC,MACjB,GAAGd,YAAYD,IAAI,CAAC,EAAEF,SAAS,CAAC,EAAEJ,aAAa,gBAAgB,EAAEgB,qBAAqB,EACtFM,IAAI,CAAC,CAACC,MAAQA,IAAIC,IAAI;YAExB,IAAI,CAACzB,UAAU;gBACbU,gBAAgBW,KAAKZ,YAAY;YACnC;QACF;QAEA,KAAKO;IACP,GAAG;QAACT;QAAKC;QAAWH;QAAUL;QAAUC;KAAa;IAErD,IAAID,UAAU;QACZ,OAAO;IACT;IAEA,qBACE,KAAC0B;QAAIC,WAAWxC;kBACd,cAAA,MAACyC;YAAED,WAAW,GAAGxC,UAAU,KAAK,CAAC;YAAE0C,MAAMpB;;8BACvC,KAACrB;8BACD,KAAC0C;oBAAKH,WAAW,GAAGxC,UAAU,MAAM,CAAC;8BAAE;;;;;AAI/C,EAAC"}
|
|
@@ -1,10 +1,57 @@
|
|
|
1
1
|
.oauth-login {
|
|
2
2
|
display: flex;
|
|
3
3
|
justify-content: center;
|
|
4
|
+
padding: 1rem 0;
|
|
4
5
|
|
|
5
|
-
&__btn
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
&__btn {
|
|
7
|
+
display: inline-flex;
|
|
8
|
+
align-items: center;
|
|
9
|
+
justify-content: center;
|
|
10
|
+
gap: 0.75rem;
|
|
11
|
+
padding: 0.75rem 1.5rem;
|
|
12
|
+
min-height: 3rem;
|
|
13
|
+
background-color: #4d49fc;
|
|
14
|
+
color: #ffffff;
|
|
15
|
+
border: none;
|
|
16
|
+
border-radius: 0.5rem;
|
|
17
|
+
font-size: 1rem;
|
|
18
|
+
font-weight: 450;
|
|
19
|
+
letter-spacing: 0.05px;
|
|
20
|
+
text-decoration: none;
|
|
21
|
+
cursor: pointer;
|
|
22
|
+
transition: background-color 0.2s ease, transform 0.1s ease;
|
|
23
|
+
box-shadow: none;
|
|
24
|
+
|
|
25
|
+
&:hover {
|
|
26
|
+
background-color: #4440e8;
|
|
27
|
+
transform: translateY(-1px);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
&:active {
|
|
31
|
+
background-color: #3c38d4;
|
|
32
|
+
transform: translateY(0);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
&:focus {
|
|
36
|
+
outline: none;
|
|
37
|
+
box-shadow: 0 0 0 2px rgba(77, 73, 252, 0.4);
|
|
8
38
|
}
|
|
9
39
|
}
|
|
40
|
+
|
|
41
|
+
&__icon {
|
|
42
|
+
flex-shrink: 0;
|
|
43
|
+
width: 20px;
|
|
44
|
+
height: 20px;
|
|
45
|
+
display: flex;
|
|
46
|
+
align-items: center;
|
|
47
|
+
justify-content: center;
|
|
48
|
+
color: #ffffff;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
&__text {
|
|
52
|
+
white-space: nowrap;
|
|
53
|
+
line-height: 1rem;
|
|
54
|
+
font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
|
|
55
|
+
Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
56
|
+
}
|
|
10
57
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@payloadcms/figma",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.19",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"registry": "https://registry.npmjs.org/"
|
|
54
54
|
},
|
|
55
55
|
"scripts": {
|
|
56
|
-
"build": "pnpm build:swc && pnpm build:types",
|
|
56
|
+
"build": "pnpm build:swc && pnpm build:types && pnpm copyfiles",
|
|
57
57
|
"build:swc": "swc ./src -d ./dist --config-file .swcrc --strip-leading-paths",
|
|
58
58
|
"build:types": "tsc",
|
|
59
59
|
"clean": "rimraf -g \"{dist,*.tsbuildinfo,package}\"",
|