@payloadcms/figma 0.0.1-alpha.67 → 0.0.1-alpha.69

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.
@@ -1,4 +1,4 @@
1
- import type { BaseDatabaseAdapter, DatabaseAdapterObj } from 'payload';
1
+ import type { BaseDatabaseAdapter, CreateArgs, DatabaseAdapterObj } from 'payload';
2
2
  import createClient from 'openapi-fetch';
3
3
  import type { paths } from './generated/content-api-types.js';
4
4
  import { type AuthMode } from './utilities/auth.js';
@@ -7,8 +7,21 @@ type ContentAPIOptions = {
7
7
  auth: AuthMode;
8
8
  contentSystemId: string;
9
9
  environmentName?: string;
10
+ notifyLocalJobQueue: boolean;
10
11
  url: string;
11
12
  };
13
+ /**
14
+ * Heads-up logged locally whenever a job is queued. Queued jobs are executed by Figma's deployed runner, so
15
+ * if a deployed environment exists its runner can pick up anything in the queue. The developer
16
+ * needs to know that a job they just created locally may run on their deployed app instead of their machine.
17
+ */
18
+ export declare const LOCAL_JOB_QUEUE_NOTICE: string;
19
+ /**
20
+ * Logs {@link LOCAL_JOB_QUEUE_NOTICE} for every job queued locally: if a deployed
21
+ * environment exists, its runner can pick up anything in the queue. No-op when
22
+ * `notifyLocalJobQueue` is false (i.e. not a local runtime).
23
+ */
24
+ export declare function maybeNotifyLocalJobQueue(adapter: ContentAPIAdapter, args: CreateArgs): void;
12
25
  export type ContentAPIAdapter = {
13
26
  auth: AuthMode;
14
27
  clearDatabase: () => Promise<void>;
@@ -16,6 +29,7 @@ export type ContentAPIAdapter = {
16
29
  contentSystemId: string;
17
30
  environmentName?: string;
18
31
  idType: 'uuid';
32
+ notifyLocalJobQueue: boolean;
19
33
  url: string;
20
34
  } & BaseDatabaseAdapter;
21
35
  export declare const contentAPIAdapter: (opts: ContentAPIOptions) => DatabaseAdapterObj;
@@ -14,6 +14,24 @@ import { addFallbackLocale } from './utilities/locale/index.js';
14
14
  import { buildMeta } from './utilities/meta/buildMeta.js';
15
15
  import { normalizeLocaleInWhere } from './utilities/meta/normalizeLocaleInWhere.js';
16
16
  import { convertPayloadWhereToContentAPI } from './utilities/where.js';
17
+ /**
18
+ * Heads-up logged locally whenever a job is queued. Queued jobs are executed by Figma's deployed runner, so
19
+ * if a deployed environment exists its runner can pick up anything in the queue. The developer
20
+ * needs to know that a job they just created locally may run on their deployed app instead of their machine.
21
+ */ export const LOCAL_JOB_QUEUE_NOTICE = "A job was queued locally. Queued jobs may be run by Figma's deployed runner, not your local " + 'dev server. If this app has a deployed environment, your deployed app may pick this ' + 'job up and run it against deployed code. If this app has no deployed ' + 'environment, the job will not run automatically. To test job logic against your local ' + 'code, call the function your task runs directly instead of queueing a job. ';
22
+ /**
23
+ * Logs {@link LOCAL_JOB_QUEUE_NOTICE} for every job queued locally: if a deployed
24
+ * environment exists, its runner can pick up anything in the queue. No-op when
25
+ * `notifyLocalJobQueue` is false (i.e. not a local runtime).
26
+ */ export function maybeNotifyLocalJobQueue(adapter, args) {
27
+ if (!adapter.notifyLocalJobQueue) {
28
+ return;
29
+ }
30
+ if (args.collection !== 'payload-jobs') {
31
+ return;
32
+ }
33
+ adapter.payload.logger.warn(LOCAL_JOB_QUEUE_NOTICE);
34
+ }
17
35
  async function syncCollections() {
18
36
  let existingIds;
19
37
  try {
@@ -544,6 +562,7 @@ async function create(args) {
544
562
  if (!response) {
545
563
  throw new Error('No response from create');
546
564
  }
565
+ maybeNotifyLocalJobQueue(this, args);
547
566
  return unwrapDocument({
548
567
  collectionSlug: args.collection,
549
568
  doc: response.result,
@@ -878,6 +897,7 @@ export const contentAPIAdapter = (opts)=>({
878
897
  findVersions: findVersions,
879
898
  idType: 'uuid',
880
899
  init,
900
+ notifyLocalJobQueue: opts.notifyLocalJobQueue,
881
901
  packageName: '@payloadcms/db-content-api',
882
902
  payload,
883
903
  queryDrafts: queryDrafts,
@@ -9,15 +9,30 @@ export interface CmsOAuthCodeMessage {
9
9
  * value the iframe sent on its outbound `mint-cms-oauth-code` request.
10
10
  */
11
11
  export declare const parseCmsOAuthCodeMessage: (data: unknown) => CmsOAuthCodeMessage | null;
12
+ export interface ParentOriginSignals {
13
+ /**
14
+ * `ancestorOrigins[0]`: immediate embedder origin. `undefined` where the
15
+ * browser lacks `Location.ancestorOrigins`.
16
+ */
17
+ ancestorOrigin: null | string | undefined;
18
+ /** `window.location.origin` — this iframe's own origin. */
19
+ ownOrigin: null | string | undefined;
20
+ /** `document.referrer`. */
21
+ referrer: null | string | undefined;
22
+ }
12
23
  /**
13
- * Derive a tight `targetOrigin` for `window.parent.postMessage` from the
14
- * iframe's `document.referrer`. If the referrer is a Figma origin we return
15
- * it verbatim; otherwise (stripped by Referrer-Policy, malformed, or hostile)
16
- * we fall back to '*'. The outbound payload contains the server-signed
17
- * `state` from /meta no secrets to leak — so '*' is acceptable; the
18
- * inbound origin check is the load-bearing security control.
24
+ * Resolve the exact origin for `window.parent.postMessage`, or `null` if we
25
+ * can't establish a trusted embedder (caller must then NOT post). We never
26
+ * target `'*'`: the payload embeds PKCE material in `state`.
27
+ *
28
+ * 1. `ancestorOrigin` present (browser-set, unspoofable): trust iff Figma,
29
+ * else `null` no fall-through to weaker signals.
30
+ * 2. No `ancestorOrigins`: fall back to `referrer`, but only if
31
+ * it's a Figma origin and not our own. (Payload's `/admin` -> `/admin/login`
32
+ * 307 leaves `referrer` as our own origin, never the embedder.)
33
+ * 3. Otherwise `null`.
19
34
  */
20
- export declare const pickParentTargetOrigin: (referrer: null | string | undefined) => string;
35
+ export declare const resolveParentTargetOrigin: ({ ancestorOrigin, ownOrigin, referrer, }: ParentOriginSignals) => null | string;
21
36
  export interface IframeAutoLoginDeps {
22
37
  doFetch: typeof fetch;
23
38
  /**
@@ -36,7 +51,11 @@ export interface IframeAutoLoginDeps {
36
51
  * the host is expected to apply its own timeout.
37
52
  */
38
53
  onFailed?: () => void;
39
- parentReferrer: null | string | undefined;
54
+ /**
55
+ * Exact origin for `postMessage`, from `resolveParentTargetOrigin`. `null`
56
+ * means no trusted embedder: don't post, trigger `onFailed`. Never `'*'`.
57
+ */
58
+ parentTargetOrigin: null | string;
40
59
  postMessageToParent: (message: unknown, targetOrigin: string) => void;
41
60
  win: Pick<Window, 'addEventListener' | 'removeEventListener'>;
42
61
  }
@@ -24,22 +24,31 @@ import { isFigmaOrigin } from '../../utilities/figmaHostnames.js';
24
24
  };
25
25
  };
26
26
  /**
27
- * Derive a tight `targetOrigin` for `window.parent.postMessage` from the
28
- * iframe's `document.referrer`. If the referrer is a Figma origin we return
29
- * it verbatim; otherwise (stripped by Referrer-Policy, malformed, or hostile)
30
- * we fall back to '*'. The outbound payload contains the server-signed
31
- * `state` from /meta no secrets to leak — so '*' is acceptable; the
32
- * inbound origin check is the load-bearing security control.
33
- */ export const pickParentTargetOrigin = (referrer)=>{
34
- if (!referrer) {
35
- return '*';
27
+ * Resolve the exact origin for `window.parent.postMessage`, or `null` if we
28
+ * can't establish a trusted embedder (caller must then NOT post). We never
29
+ * target `'*'`: the payload embeds PKCE material in `state`.
30
+ *
31
+ * 1. `ancestorOrigin` present (browser-set, unspoofable): trust iff Figma,
32
+ * else `null` no fall-through to weaker signals.
33
+ * 2. No `ancestorOrigins`: fall back to `referrer`, but only if
34
+ * it's a Figma origin and not our own. (Payload's `/admin` -> `/admin/login`
35
+ * 307 leaves `referrer` as our own origin, never the embedder.)
36
+ * 3. Otherwise `null`.
37
+ */ export const resolveParentTargetOrigin = ({ ancestorOrigin, ownOrigin, referrer })=>{
38
+ if (ancestorOrigin != null) {
39
+ return isFigmaOrigin(ancestorOrigin) ? ancestorOrigin : null;
36
40
  }
37
- try {
38
- const candidate = new URL(referrer).origin;
39
- return isFigmaOrigin(candidate) ? candidate : '*';
40
- } catch {
41
- return '*';
41
+ if (referrer) {
42
+ try {
43
+ const candidate = new URL(referrer).origin;
44
+ if (candidate !== ownOrigin && isFigmaOrigin(candidate)) {
45
+ return candidate;
46
+ }
47
+ } catch {
48
+ // unparseable referrer — fall through
49
+ }
42
50
  }
51
+ return null;
43
52
  };
44
53
  /**
45
54
  * Wire up the iframe auto-login flow:
@@ -122,6 +131,14 @@ import { isFigmaOrigin } from '../../utilities/figmaHostnames.js';
122
131
  if (abortController.signal.aborted) {
123
132
  return;
124
133
  }
134
+ // No trusted embedder origin: refuse to post (don't broadcast PKCE-bearing
135
+ // `state` to '*'). See `resolveParentTargetOrigin`.
136
+ if (deps.parentTargetOrigin === null) {
137
+ // eslint-disable-next-line no-console -- surface auto-login failures to dev tools
138
+ console.warn('[payload iframe auto-login] could not determine a trusted parent origin — falling back to manual login');
139
+ deps.onFailed?.();
140
+ return;
141
+ }
125
142
  flow = {
126
143
  redirectUri: redirect,
127
144
  state
@@ -134,7 +151,7 @@ import { isFigmaOrigin } from '../../utilities/figmaHostnames.js';
134
151
  redirect_uri: redirect,
135
152
  scope,
136
153
  state
137
- }, pickParentTargetOrigin(deps.parentReferrer));
154
+ }, deps.parentTargetOrigin);
138
155
  } catch (err) {
139
156
  if (abortController.signal.aborted) {
140
157
  return;
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useConfig } from '@payloadcms/ui';
4
4
  import { useSearchParams } from 'next/navigation.js';
5
5
  import React, { useEffect, useState } from 'react';
6
- import { setupIframeAutoLogin } from './iframeAutoLogin.js';
6
+ import { resolveParentTargetOrigin, setupIframeAutoLogin } from './iframeAutoLogin.js';
7
7
  import './index.scss';
8
8
  const baseClass = 'oauth-login';
9
9
  // Max time we wait for the parent (figma.com) to respond with a code after
@@ -82,6 +82,10 @@ export const DefaultLoginButton = ({ disabled, endpointSlug })=>{
82
82
  console.warn(`[payload iframe auto-login] parent did not reply with cms-oauth-code within ${AUTO_LOGIN_PARENT_REPLY_TIMEOUT_MS}ms — falling back to manual login`);
83
83
  setAutoLoginFailed(true);
84
84
  }, AUTO_LOGIN_PARENT_REPLY_TIMEOUT_MS);
85
+ // ancestorOrigins[0] is the immediate embedder's origin (browser-set,
86
+ // unspoofable) where supported; undefined on browsers that don't implement
87
+ // the non-standard Location.ancestorOrigins (older Firefox, pre-148).
88
+ const ancestorOrigins = window.location.ancestorOrigins;
85
89
  const cleanup = setupIframeAutoLogin({
86
90
  doFetch: window.fetch.bind(window),
87
91
  metaUrl: `${serverURL}${api}/${userSlug}/${endpointSlug}/meta?serverURL=${window.location.origin}`,
@@ -89,7 +93,11 @@ export const DefaultLoginButton = ({ disabled, endpointSlug })=>{
89
93
  window.location.href = url;
90
94
  },
91
95
  onFailed: ()=>setAutoLoginFailed(true),
92
- parentReferrer: document.referrer,
96
+ parentTargetOrigin: resolveParentTargetOrigin({
97
+ ancestorOrigin: ancestorOrigins?.[0],
98
+ ownOrigin: window.location.origin,
99
+ referrer: document.referrer
100
+ }),
93
101
  postMessageToParent: (msg, target)=>window.parent.postMessage(msg, target),
94
102
  win: window
95
103
  });
@@ -1,4 +1,13 @@
1
1
  import type { Config, SanitizedConfig } from 'payload';
2
+ /**
3
+ * Worker-trusted marker injected by Figma's sites-worker after it validates the
4
+ * X-Figma-Job-Queues-Auth-Bypass secret on a Payload jobs endpoint. The default
5
+ * `jobs.access.run` below honors this marker so Sinatra (async-job-workflow)
6
+ * can drive job runs without the bypass secret ever reaching tenant code.
7
+ *
8
+ * KEEP_IN_SYNC(cloudflare/wrangler/sites-worker/src/auth.ts): FIGMA_INTERNAL_FORWARDED_HAS_AUTH_BYPASS_HEADER
9
+ */
10
+ export declare const FIGMA_INTERNAL_FORWARDED_HAS_AUTH_BYPASS_HEADER = "figma-internal-forwarded-has-auth-bypass";
2
11
  /**
3
12
  * Configuration type for Payload projects on the Figma platform.
4
13
  *
@@ -20,6 +20,14 @@ import * as log from '../utils/log.js';
20
20
  import { logMissingCliAuth } from './auth-preflight.js';
21
21
  import { logMissingContentSystemId } from './bootstrap-preflight.js';
22
22
  import { getDevCookieNames } from './dev-cookie-names.js';
23
+ /**
24
+ * Worker-trusted marker injected by Figma's sites-worker after it validates the
25
+ * X-Figma-Job-Queues-Auth-Bypass secret on a Payload jobs endpoint. The default
26
+ * `jobs.access.run` below honors this marker so Sinatra (async-job-workflow)
27
+ * can drive job runs without the bypass secret ever reaching tenant code.
28
+ *
29
+ * KEEP_IN_SYNC(cloudflare/wrangler/sites-worker/src/auth.ts): FIGMA_INTERNAL_FORWARDED_HAS_AUTH_BYPASS_HEADER
30
+ */ export const FIGMA_INTERNAL_FORWARDED_HAS_AUTH_BYPASS_HEADER = 'figma-internal-forwarded-has-auth-bypass';
23
31
  /**
24
32
  * Fields added to users collection for Figma profile info
25
33
  */ const figmaUserFields = [
@@ -205,6 +213,10 @@ export async function buildFigmaConfig(config) {
205
213
  }
206
214
  const url = process.env.FIGMA_CONTENT_API_URL || envConfig.contentApiUrl;
207
215
  const isProduction = process.env.NODE_ENV === 'production';
216
+ // The deployed Lambda runs all queued jobs; locally there is no runner, so the db adapter logs
217
+ // a heads-up whenever a job is queued. Deployed environments set DISABLE_LOCAL_JOB_QUEUE_NOTIFICATIONS=true
218
+ // (injected by the control plane); end-users can also set it locally to silence the notice.
219
+ const notifyLocalJobQueue = process.env.DISABLE_LOCAL_JOB_QUEUE_NOTIFICATIONS !== 'true';
208
220
  const usesTokenStoreAuth = !process.env.FIGMA_CONTENT_API_ACCESS_KEY && process.env.FIGMA_DEV_JWT !== 'true';
209
221
  if (usesTokenStoreAuth) {
210
222
  logMissingCliAuth(getTokenStore());
@@ -221,6 +233,7 @@ export async function buildFigmaConfig(config) {
221
233
  },
222
234
  contentSystemId,
223
235
  environmentName: process.env.FIGMA_ENVIRONMENT_NAME,
236
+ notifyLocalJobQueue,
224
237
  url
225
238
  });
226
239
  } else if (process.env.FIGMA_DEV_JWT === 'true') {
@@ -230,6 +243,7 @@ export async function buildFigmaConfig(config) {
230
243
  },
231
244
  contentSystemId,
232
245
  environmentName: process.env.FIGMA_ENVIRONMENT_NAME,
246
+ notifyLocalJobQueue,
233
247
  url
234
248
  });
235
249
  } else {
@@ -240,9 +254,11 @@ export async function buildFigmaConfig(config) {
240
254
  },
241
255
  contentSystemId,
242
256
  environmentName: process.env.FIGMA_ENVIRONMENT_NAME,
257
+ notifyLocalJobQueue,
243
258
  url
244
259
  });
245
260
  }
261
+ const userJobsAccessRun = config.jobs?.access?.run;
246
262
  // Build complete config with Figma platform defaults
247
263
  const configWithFigmaDefaults = {
248
264
  ...config,
@@ -267,6 +283,25 @@ export async function buildFigmaConfig(config) {
267
283
  health,
268
284
  schema
269
285
  ],
286
+ // Gate /api/payload-jobs/run and /api/payload-jobs/handle-schedules. Honor the
287
+ // sites-worker trust marker so Figma infra job runs never break, defer to the
288
+ // tenant's jobs.access.run if they set one, otherwise fall back to Payload's
289
+ // "logged-in user" default so the admin "Run jobs" UI keeps working.
290
+ jobs: {
291
+ ...config.jobs ?? {},
292
+ access: {
293
+ ...config.jobs?.access ?? {},
294
+ run: (args)=>{
295
+ if (args.req.headers.get(FIGMA_INTERNAL_FORWARDED_HAS_AUTH_BYPASS_HEADER) === '1') {
296
+ return true;
297
+ }
298
+ if (userJobsAccessRun) {
299
+ return userJobsAccessRun(args);
300
+ }
301
+ return !!args.req.user;
302
+ }
303
+ }
304
+ },
270
305
  ...isProduction && !config.logger ? {
271
306
  logger: {
272
307
  options: {}
@@ -34,6 +34,7 @@ export const ContentApiClientUploadHandler = createClientUploadHandler({
34
34
  return {
35
35
  clientUploaded: true,
36
36
  filename: uploadFilename,
37
+ mimeType: file.type,
37
38
  prefix
38
39
  };
39
40
  }
@@ -1,16 +1,16 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
+ import { parseClientUploadContext } from './utilities/index.js';
3
4
  const PART_SIZE = 64 * 1024 * 1024 // 64MB per part
4
5
  ;
5
6
  const MAX_FILE_SIZE_BEFORE_MULTIPART = 100 * 1024 * 1024 // 100MB
6
7
  ;
7
8
  export const getHandleUpload = ({ client, collection, prefix = '' })=>{
8
9
  return async ({ clientUploadContext, data, file })=>{
9
- // Skip if client already uploaded THIS SPECIFIC file
10
- // clientUploadContext.filename contains the original filename that was client-uploaded
11
- // Resized versions (different filename) should still be uploaded
12
- const clientUploadedFilename = clientUploadContext && typeof clientUploadContext === 'object' && 'filename' in clientUploadContext ? clientUploadContext.filename : undefined;
13
- const isOriginalClientUploaded = clientUploadContext && typeof clientUploadContext === 'object' && 'clientUploaded' in clientUploadContext && clientUploadContext.clientUploaded && file.filename === clientUploadedFilename;
10
+ // Skip if the client already uploaded THIS SPECIFIC file. Resized versions
11
+ // (different filename) should still be uploaded.
12
+ const context = parseClientUploadContext(clientUploadContext);
13
+ const isOriginalClientUploaded = context.clientUploaded === true && file.filename === context.filename;
14
14
  if (isOriginalClientUploaded) {
15
15
  return data;
16
16
  }
@@ -1,5 +1,7 @@
1
1
  import { getFilePrefix } from '@payloadcms/plugin-cloud-storage/utilities';
2
2
  import path from 'path';
3
+ import { isImage } from 'payload/shared';
4
+ import { parseClientUploadContext } from './utilities/index.js';
3
5
  export const getHandler = ({ client, collection })=>{
4
6
  return async (req, { params: { clientUploadContext, filename } })=>{
5
7
  try {
@@ -23,6 +25,28 @@ export const getHandler = ({ client, collection })=>{
23
25
  status: 500
24
26
  });
25
27
  }
28
+ // On a client-upload fetch-back, core reads this response body into req.file.data to
29
+ // size the image; a 302's empty body crashes getImageSize. Return real bytes for
30
+ // images (and unknown mimetypes, to be safe), but keep the redirect otherwise so we
31
+ // don't download large non-images server-side.
32
+ if (clientUploadContext) {
33
+ const { mimeType } = parseClientUploadContext(clientUploadContext);
34
+ if (!mimeType || isImage(mimeType)) {
35
+ const fileResponse = await fetch(data.url);
36
+ if (!fileResponse.ok) {
37
+ req.payload.logger.error(`Failed to fetch file for client-upload buffer fetch-back: ${fileResponse.status}`);
38
+ return new Response('Internal Server Error', {
39
+ status: 500
40
+ });
41
+ }
42
+ const contentType = fileResponse.headers.get('Content-Type') ?? mimeType ?? 'application/octet-stream';
43
+ return new Response(await fileResponse.arrayBuffer(), {
44
+ headers: {
45
+ 'Content-Type': contentType
46
+ }
47
+ });
48
+ }
49
+ }
26
50
  return Response.redirect(data.url, 302);
27
51
  } catch (err) {
28
52
  req.payload.logger.error({
@@ -1,2 +1,3 @@
1
1
  export { getSafeFilename } from './getSafeFilename.js';
2
+ export { type ContentApiClientUploadContext, parseClientUploadContext, } from './parseClientUploadContext.js';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1,3 +1,4 @@
1
1
  export { getSafeFilename } from './getSafeFilename.js';
2
+ export { parseClientUploadContext } from './parseClientUploadContext.js';
2
3
 
3
4
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The shape of the `clientUploadContext` produced by this adapter's client upload
3
+ * handler. The plugin's `StaticHandler`/`HandleUpload` types expose it as `unknown`
4
+ * (it is deserialized from a JSON form field and is adapter-specific), so it must be
5
+ * narrowed at runtime before use.
6
+ */
7
+ export type ContentApiClientUploadContext = {
8
+ clientUploaded?: boolean;
9
+ filename?: string;
10
+ mimeType?: string;
11
+ prefix?: string;
12
+ };
13
+ /**
14
+ * Safely narrows an `unknown` clientUploadContext into the adapter's known shape,
15
+ * keeping only properties that are actually present with the expected type. Returns
16
+ * an empty object for any non-object input.
17
+ */
18
+ export declare const parseClientUploadContext: (context: unknown) => ContentApiClientUploadContext;
19
+ //# sourceMappingURL=parseClientUploadContext.d.ts.map
@@ -0,0 +1,30 @@
1
+ /**
2
+ * The shape of the `clientUploadContext` produced by this adapter's client upload
3
+ * handler. The plugin's `StaticHandler`/`HandleUpload` types expose it as `unknown`
4
+ * (it is deserialized from a JSON form field and is adapter-specific), so it must be
5
+ * narrowed at runtime before use.
6
+ */ /**
7
+ * Safely narrows an `unknown` clientUploadContext into the adapter's known shape,
8
+ * keeping only properties that are actually present with the expected type. Returns
9
+ * an empty object for any non-object input.
10
+ */ export const parseClientUploadContext = (context)=>{
11
+ if (!context || typeof context !== 'object') {
12
+ return {};
13
+ }
14
+ const result = {};
15
+ if ('clientUploaded' in context && typeof context.clientUploaded === 'boolean') {
16
+ result.clientUploaded = context.clientUploaded;
17
+ }
18
+ if ('filename' in context && typeof context.filename === 'string') {
19
+ result.filename = context.filename;
20
+ }
21
+ if ('mimeType' in context && typeof context.mimeType === 'string') {
22
+ result.mimeType = context.mimeType;
23
+ }
24
+ if ('prefix' in context && typeof context.prefix === 'string') {
25
+ result.prefix = context.prefix;
26
+ }
27
+ return result;
28
+ };
29
+
30
+ //# sourceMappingURL=parseClientUploadContext.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payloadcms/figma",
3
- "version": "0.0.1-alpha.67",
3
+ "version": "0.0.1-alpha.69",
4
4
  "license": "SEE LICENSE IN LICENSE.md",
5
5
  "type": "module",
6
6
  "exports": {