@payloadcms/figma 0.0.1-alpha.41 → 0.0.1-alpha.43

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.
Files changed (139) hide show
  1. package/dist/auth/oauth-flow.d.ts.map +1 -1
  2. package/dist/auth/oauth-flow.js +6 -3
  3. package/dist/auth/oauth-flow.js.map +1 -1
  4. package/dist/auth/refresh.d.ts +2 -1
  5. package/dist/auth/refresh.d.ts.map +1 -1
  6. package/dist/auth/refresh.js +11 -3
  7. package/dist/auth/refresh.js.map +1 -1
  8. package/dist/auth/token-store.d.ts +6 -4
  9. package/dist/auth/token-store.d.ts.map +1 -1
  10. package/dist/auth/token-store.js +17 -14
  11. package/dist/auth/token-store.js.map +1 -1
  12. package/dist/auth/types.d.ts +7 -4
  13. package/dist/auth/types.d.ts.map +1 -1
  14. package/dist/auth/types.js.map +1 -1
  15. package/dist/cli.js +8 -6
  16. package/dist/cli.js.map +1 -1
  17. package/dist/commands/deploy.d.ts.map +1 -1
  18. package/dist/commands/deploy.js +2 -1
  19. package/dist/commands/deploy.js.map +1 -1
  20. package/dist/commands/init.d.ts.map +1 -1
  21. package/dist/commands/init.js +12 -1
  22. package/dist/commands/init.js.map +1 -1
  23. package/dist/commands/list-tokens.d.ts +3 -3
  24. package/dist/commands/list-tokens.d.ts.map +1 -1
  25. package/dist/commands/list-tokens.js +20 -8
  26. package/dist/commands/list-tokens.js.map +1 -1
  27. package/dist/commands/login.d.ts.map +1 -1
  28. package/dist/commands/login.js +12 -4
  29. package/dist/commands/login.js.map +1 -1
  30. package/dist/commands/logout.d.ts +5 -4
  31. package/dist/commands/logout.d.ts.map +1 -1
  32. package/dist/commands/logout.js +55 -12
  33. package/dist/commands/logout.js.map +1 -1
  34. package/dist/constants.d.ts +1 -1
  35. package/dist/constants.d.ts.map +1 -1
  36. package/dist/constants.js +19 -4
  37. package/dist/constants.js.map +1 -1
  38. package/dist/db-content-api/generated/content-api-types.d.ts +166 -277
  39. package/dist/db-content-api/generated/content-api-types.d.ts.map +1 -1
  40. package/dist/db-content-api/generated/content-api-types.js.map +1 -1
  41. package/dist/db-content-api/index.d.ts.map +1 -1
  42. package/dist/db-content-api/index.js +116 -64
  43. package/dist/db-content-api/index.js.map +1 -1
  44. package/dist/db-content-api/temp-utilities/unwrapDocument.d.ts +31 -1
  45. package/dist/db-content-api/temp-utilities/unwrapDocument.d.ts.map +1 -1
  46. package/dist/db-content-api/temp-utilities/unwrapDocument.js +24 -24
  47. package/dist/db-content-api/temp-utilities/unwrapDocument.js.map +1 -1
  48. package/dist/db-content-api/utilities/data/castFieldValue.d.ts.map +1 -1
  49. package/dist/db-content-api/utilities/data/castFieldValue.js +4 -1
  50. package/dist/db-content-api/utilities/data/castFieldValue.js.map +1 -1
  51. package/dist/db-content-api/utilities/data/index.d.ts +2 -0
  52. package/dist/db-content-api/utilities/data/index.d.ts.map +1 -1
  53. package/dist/db-content-api/utilities/data/index.js +23 -2
  54. package/dist/db-content-api/utilities/data/index.js.map +1 -1
  55. package/dist/db-content-api/utilities/meta/buildLocalizedPaths.d.ts +11 -0
  56. package/dist/db-content-api/utilities/meta/buildLocalizedPaths.d.ts.map +1 -0
  57. package/dist/db-content-api/utilities/meta/buildLocalizedPaths.js +55 -0
  58. package/dist/db-content-api/utilities/meta/buildLocalizedPaths.js.map +1 -0
  59. package/dist/db-content-api/utilities/meta/buildMeta.d.ts +22 -0
  60. package/dist/db-content-api/utilities/meta/buildMeta.d.ts.map +1 -0
  61. package/dist/db-content-api/utilities/meta/buildMeta.js +30 -0
  62. package/dist/db-content-api/utilities/meta/buildMeta.js.map +1 -0
  63. package/dist/db-content-api/utilities/meta/buildPathTypes.d.ts +7 -0
  64. package/dist/db-content-api/utilities/meta/buildPathTypes.d.ts.map +1 -0
  65. package/dist/db-content-api/utilities/meta/buildPathTypes.js +151 -0
  66. package/dist/db-content-api/utilities/meta/buildPathTypes.js.map +1 -0
  67. package/dist/db-content-api/utilities/meta/index.d.ts +5 -0
  68. package/dist/db-content-api/utilities/meta/index.d.ts.map +1 -0
  69. package/dist/db-content-api/utilities/meta/index.js +5 -0
  70. package/dist/db-content-api/utilities/meta/index.js.map +1 -0
  71. package/dist/db-content-api/utilities/where.d.ts.map +1 -1
  72. package/dist/db-content-api/utilities/where.js +17 -3
  73. package/dist/db-content-api/utilities/where.js.map +1 -1
  74. package/dist/oauth/components/LogoutButton/index.d.ts.map +1 -1
  75. package/dist/oauth/components/LogoutButton/index.js +5 -3
  76. package/dist/oauth/components/LogoutButton/index.js.map +1 -1
  77. package/dist/oauth/endpoints/getLoginEndpoint.d.ts.map +1 -1
  78. package/dist/oauth/endpoints/getLoginEndpoint.js +17 -7
  79. package/dist/oauth/endpoints/getLoginEndpoint.js.map +1 -1
  80. package/dist/oauth/endpoints/getLogoutEndpoint.d.ts.map +1 -1
  81. package/dist/oauth/endpoints/getLogoutEndpoint.js +7 -4
  82. package/dist/oauth/endpoints/getLogoutEndpoint.js.map +1 -1
  83. package/dist/plugin/build-config.js +3 -3
  84. package/dist/plugin/build-config.js.map +1 -1
  85. package/dist/storage-content-api/api-types.d.ts +8 -1
  86. package/dist/storage-content-api/api-types.d.ts.map +1 -1
  87. package/dist/storage-content-api/api-types.js.map +1 -1
  88. package/dist/storage-content-api/client-uploads/ClientUploadHandler.d.ts.map +1 -1
  89. package/dist/storage-content-api/client-uploads/ClientUploadHandler.js +3 -3
  90. package/dist/storage-content-api/client-uploads/ClientUploadHandler.js.map +1 -1
  91. package/dist/storage-content-api/client-uploads/generateSignedURL.d.ts.map +1 -1
  92. package/dist/storage-content-api/client-uploads/generateSignedURL.js +9 -1
  93. package/dist/storage-content-api/client-uploads/generateSignedURL.js.map +1 -1
  94. package/dist/storage-content-api/generateURL.d.ts.map +1 -1
  95. package/dist/storage-content-api/generateURL.js +3 -2
  96. package/dist/storage-content-api/generateURL.js.map +1 -1
  97. package/dist/storage-content-api/handleDelete.d.ts.map +1 -1
  98. package/dist/storage-content-api/handleDelete.js +4 -2
  99. package/dist/storage-content-api/handleDelete.js.map +1 -1
  100. package/dist/storage-content-api/handleUpload.d.ts +1 -1
  101. package/dist/storage-content-api/handleUpload.d.ts.map +1 -1
  102. package/dist/storage-content-api/handleUpload.js +11 -3
  103. package/dist/storage-content-api/handleUpload.js.map +1 -1
  104. package/dist/storage-content-api/staticHandler.js +1 -0
  105. package/dist/storage-content-api/staticHandler.js.map +1 -1
  106. package/dist/storage-content-api/utilities/getSafeFilename.d.ts +12 -0
  107. package/dist/storage-content-api/utilities/getSafeFilename.d.ts.map +1 -0
  108. package/dist/storage-content-api/utilities/getSafeFilename.js +61 -0
  109. package/dist/storage-content-api/utilities/getSafeFilename.js.map +1 -0
  110. package/dist/storage-content-api/utilities/index.d.ts +2 -0
  111. package/dist/storage-content-api/utilities/index.d.ts.map +1 -0
  112. package/dist/storage-content-api/utilities/index.js +3 -0
  113. package/dist/storage-content-api/utilities/index.js.map +1 -0
  114. package/dist/templates/.env.example +11 -0
  115. package/dist/utils/env-management.d.ts +9 -1
  116. package/dist/utils/env-management.d.ts.map +1 -1
  117. package/dist/utils/env-management.js +39 -17
  118. package/dist/utils/env-management.js.map +1 -1
  119. package/dist/utils/format-env-suffix.d.ts +12 -0
  120. package/dist/utils/format-env-suffix.d.ts.map +1 -0
  121. package/dist/utils/format-env-suffix.js +13 -0
  122. package/dist/utils/format-env-suffix.js.map +1 -0
  123. package/dist/utils/lambda-config.js +26 -12
  124. package/dist/utils/lambda-config.js.map +1 -1
  125. package/dist/utils/messages.d.ts.map +1 -1
  126. package/dist/utils/messages.js +1 -2
  127. package/dist/utils/messages.js.map +1 -1
  128. package/dist/utils/project.d.ts.map +1 -1
  129. package/dist/utils/project.js +3 -0
  130. package/dist/utils/project.js.map +1 -1
  131. package/package.json +2 -2
  132. package/dist/db-content-api/temp-utilities/pagination.d.ts +0 -13
  133. package/dist/db-content-api/temp-utilities/pagination.d.ts.map +0 -1
  134. package/dist/db-content-api/temp-utilities/pagination.js +0 -45
  135. package/dist/db-content-api/temp-utilities/pagination.js.map +0 -1
  136. package/dist/oauth/utilities/getAdminPath.d.ts +0 -8
  137. package/dist/oauth/utilities/getAdminPath.d.ts.map +0 -1
  138. package/dist/oauth/utilities/getAdminPath.js +0 -9
  139. package/dist/oauth/utilities/getAdminPath.js.map +0 -1
@@ -0,0 +1,5 @@
1
+ export { buildLocalizedPaths } from './buildLocalizedPaths.js';
2
+ export { buildMeta } from './buildMeta.js';
3
+ export type { BuildMetaOptions, ContentAPIMeta } from './buildMeta.js';
4
+ export { buildPathTypes } from './buildPathTypes.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/db-content-api/utilities/meta/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA"}
@@ -0,0 +1,5 @@
1
+ export { buildLocalizedPaths } from './buildLocalizedPaths.js';
2
+ export { buildMeta } from './buildMeta.js';
3
+ export { buildPathTypes } from './buildPathTypes.js';
4
+
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/db-content-api/utilities/meta/index.ts"],"sourcesContent":["export { buildLocalizedPaths } from './buildLocalizedPaths.js'\nexport { buildMeta } from './buildMeta.js'\nexport type { BuildMetaOptions, ContentAPIMeta } from './buildMeta.js'\nexport { buildPathTypes } from './buildPathTypes.js'\n"],"names":["buildLocalizedPaths","buildMeta","buildPathTypes"],"mappings":"AAAA,SAASA,mBAAmB,QAAQ,2BAA0B;AAC9D,SAASC,SAAS,QAAQ,iBAAgB;AAE1C,SAASC,cAAc,QAAQ,sBAAqB"}
@@ -1 +1 @@
1
- {"version":3,"file":"where.d.ts","sourceRoot":"","sources":["../../../src/db-content-api/utilities/where.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAEpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AAEnE,KAAK,WAAW,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,aAAa,CAAC,CAAA;AASvD,KAAK,cAAc,GAAG;IACpB,yEAAyE;IACzE,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,mFAAmF;IACnF,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B,CAAA;AAED,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,SAAS,GAAG,KAAK,EACxB,OAAO,GAAE,cAAmB,GAC3B,WAAW,CA4Gb"}
1
+ {"version":3,"file":"where.d.ts","sourceRoot":"","sources":["../../../src/db-content-api/utilities/where.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAEpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAA;AAEnE,KAAK,WAAW,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,aAAa,CAAC,CAAA;AASvD,KAAK,cAAc,GAAG;IACpB,yEAAyE;IACzE,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,mFAAmF;IACnF,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B,CAAA;AAED,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,SAAS,GAAG,KAAK,EACxB,OAAO,GAAE,cAAmB,GAC3B,WAAW,CA6Hb"}
@@ -70,6 +70,19 @@ export function convertPayloadWhereToContentAPI(where, options = {}) {
70
70
  }
71
71
  // Convert field conditions: { fieldName: { operator: value } }
72
72
  // to: { path: fieldName, operator, value }
73
+ // Handle Payload's shorthand: { fieldName: value } → { fieldName: { equals: value } }
74
+ // If value is a primitive (string, number, boolean, null) or not a plain object,
75
+ // treat it as an implicit 'equals' operator
76
+ const isPrimitive = value === null || typeof value !== 'object' || Array.isArray(value);
77
+ if (isPrimitive) {
78
+ // Shorthand format: { id: "some-value" } means { id: { equals: "some-value" } }
79
+ conditions.push({
80
+ operator: 'equals',
81
+ path: fieldPath,
82
+ value
83
+ });
84
+ continue;
85
+ }
73
86
  const operators = value;
74
87
  // Skip empty operator objects { fieldName: {} }
75
88
  if (Object.keys(operators).length === 0) {
@@ -82,9 +95,10 @@ export function convertPayloadWhereToContentAPI(where, options = {}) {
82
95
  continue;
83
96
  }
84
97
  let finalValue = operatorValue;
85
- // Add wildcards for contains/like operators (Payload doesn't add them)
86
- if ((op === 'contains' || op === 'like') && typeof operatorValue === 'string') {
87
- finalValue = `%${operatorValue}%`;
98
+ // Convert string booleans to actual booleans for exists operator
99
+ // REST API sends "true"/"false" as strings, but Content API requires boolean
100
+ if (op === 'exists' && typeof operatorValue === 'string') {
101
+ finalValue = operatorValue === 'true';
88
102
  }
89
103
  conditions.push({
90
104
  operator: op,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/db-content-api/utilities/where.ts"],"sourcesContent":["import type { Where } from 'payload'\n\nimport type { components } from '../generated/content-api-types.js'\n\ntype WhereClause = components['schemas']['WhereClause']\n\n// Payload's format: { fieldName: { operator: value }, and: [...], or: [...] }\n// Content API expects: { and: [{ path, operator, value }], or: [{ path, operator, value }] }\n//\n// The format stays different. This allows the Content API to evolve its filter schema,\n// for example to support composite types like Point, which are not lexicographically sortable.\n// Semantics must remain identical to Payload.\n\ntype ConvertOptions = {\n /** Internal flag to track if we're inside a logical operator (and/or) */\n insideLogicalOperator?: boolean\n /** If true, transform 'parent' field to 'documentId' (used for version queries) */\n parentToDocumentId?: boolean\n}\n\nexport function convertPayloadWhereToContentAPI(\n where: undefined | Where,\n options: ConvertOptions = {},\n): WhereClause {\n // Empty where {} should be { and: [] } not undefined\n // Content API requires a where clause structure even for \"no filter\"\n if (!where || Object.keys(where).length === 0) {\n return { and: [] }\n }\n\n // Extract the condition type (the variant with 'path', 'operator', 'value') from WhereClause union\n type WhereCondition = Extract<WhereClause, { path: string }>\n const conditions: WhereClause[] = []\n\n for (const [key, value] of Object.entries(where)) {\n if (key === 'and') {\n // Recursively convert nested 'and' conditions, preserving options\n const nestedConditions = (value as Where[])\n .map((item) =>\n convertPayloadWhereToContentAPI(item, { ...options, insideLogicalOperator: true }),\n )\n // TODO: A better solution would be to make the `where` schema of `zod` in `content-api`\n // more permissive. For now I'll do it this way because I have an idea to simplify\n // everything we're doing with `where` (Post EAP) anyway.\n // Filter out empty conditions { and: [] } that would be invalid\n .filter((condition) => {\n if ('and' in condition) {\n return condition.and.length > 0\n }\n if ('or' in condition) {\n return condition.or.length > 0\n }\n return true // Keep path/operator/value conditions\n })\n\n // If filtering resulted in no conditions, return empty and\n if (nestedConditions.length === 0) {\n return { and: [] }\n }\n\n return { and: nestedConditions }\n } else if (key === 'or') {\n // Recursively convert nested 'or' conditions, preserving options\n const nestedConditions = (value as Where[])\n .map((item) =>\n convertPayloadWhereToContentAPI(item, { ...options, insideLogicalOperator: true }),\n )\n // Filter out empty conditions { and: [] } or { or: [] } that would be invalid\n .filter((condition) => {\n if ('and' in condition) {\n return condition.and.length > 0\n }\n if ('or' in condition) {\n return condition.or.length > 0\n }\n return true // Keep path/operator/value conditions\n })\n\n // If filtering resulted in no conditions, return empty and\n if (nestedConditions.length === 0) {\n return { and: [] }\n }\n\n return { or: nestedConditions }\n } else {\n // TODO: fix this in content api\n // WORKAROUND: Payload uses 'parent' for version queries, but Content API expects 'documentId'\n let fieldPath = key\n if (options.parentToDocumentId && key === 'parent') {\n fieldPath = 'documentId'\n }\n\n // Convert field conditions: { fieldName: { operator: value } }\n // to: { path: fieldName, operator, value }\n const operators = value as Record<string, unknown>\n\n // Skip empty operator objects { fieldName: {} }\n if (Object.keys(operators).length === 0) {\n continue\n }\n\n for (const [op, operatorValue] of Object.entries(operators)) {\n // Skip operators with undefined values (e.g., { equals: undefined })\n // This can happen when Payload sends incomplete where clauses\n if (operatorValue === undefined) {\n continue\n }\n\n let finalValue = operatorValue\n\n // Add wildcards for contains/like operators (Payload doesn't add them)\n if ((op === 'contains' || op === 'like') && typeof operatorValue === 'string') {\n finalValue = `%${operatorValue}%`\n }\n\n conditions.push({\n operator: op as WhereCondition['operator'],\n path: fieldPath,\n value: finalValue,\n } as WhereCondition)\n }\n }\n }\n\n // If inside a logical operator (and/or), return conditions directly\n // Otherwise, wrap in 'and' to match WhereClause type\n if (options.insideLogicalOperator && conditions.length === 1) {\n return conditions[0]\n }\n\n return { and: conditions }\n}\n"],"names":["convertPayloadWhereToContentAPI","where","options","Object","keys","length","and","conditions","key","value","entries","nestedConditions","map","item","insideLogicalOperator","filter","condition","or","fieldPath","parentToDocumentId","operators","op","operatorValue","undefined","finalValue","push","operator","path"],"mappings":"AAoBA,OAAO,SAASA,gCACdC,KAAwB,EACxBC,UAA0B,CAAC,CAAC;IAE5B,qDAAqD;IACrD,qEAAqE;IACrE,IAAI,CAACD,SAASE,OAAOC,IAAI,CAACH,OAAOI,MAAM,KAAK,GAAG;QAC7C,OAAO;YAAEC,KAAK,EAAE;QAAC;IACnB;IAIA,MAAMC,aAA4B,EAAE;IAEpC,KAAK,MAAM,CAACC,KAAKC,MAAM,IAAIN,OAAOO,OAAO,CAACT,OAAQ;QAChD,IAAIO,QAAQ,OAAO;YACjB,kEAAkE;YAClE,MAAMG,mBAAmB,AAACF,MACvBG,GAAG,CAAC,CAACC,OACJb,gCAAgCa,MAAM;oBAAE,GAAGX,OAAO;oBAAEY,uBAAuB;gBAAK,GAElF,wFAAwF;YACxF,kFAAkF;YAClF,yDAAyD;YACzD,gEAAgE;aAC/DC,MAAM,CAAC,CAACC;gBACP,IAAI,SAASA,WAAW;oBACtB,OAAOA,UAAUV,GAAG,CAACD,MAAM,GAAG;gBAChC;gBACA,IAAI,QAAQW,WAAW;oBACrB,OAAOA,UAAUC,EAAE,CAACZ,MAAM,GAAG;gBAC/B;gBACA,OAAO,KAAK,sCAAsC;;YACpD;YAEF,2DAA2D;YAC3D,IAAIM,iBAAiBN,MAAM,KAAK,GAAG;gBACjC,OAAO;oBAAEC,KAAK,EAAE;gBAAC;YACnB;YAEA,OAAO;gBAAEA,KAAKK;YAAiB;QACjC,OAAO,IAAIH,QAAQ,MAAM;YACvB,iEAAiE;YACjE,MAAMG,mBAAmB,AAACF,MACvBG,GAAG,CAAC,CAACC,OACJb,gCAAgCa,MAAM;oBAAE,GAAGX,OAAO;oBAAEY,uBAAuB;gBAAK,GAElF,8EAA8E;aAC7EC,MAAM,CAAC,CAACC;gBACP,IAAI,SAASA,WAAW;oBACtB,OAAOA,UAAUV,GAAG,CAACD,MAAM,GAAG;gBAChC;gBACA,IAAI,QAAQW,WAAW;oBACrB,OAAOA,UAAUC,EAAE,CAACZ,MAAM,GAAG;gBAC/B;gBACA,OAAO,KAAK,sCAAsC;;YACpD;YAEF,2DAA2D;YAC3D,IAAIM,iBAAiBN,MAAM,KAAK,GAAG;gBACjC,OAAO;oBAAEC,KAAK,EAAE;gBAAC;YACnB;YAEA,OAAO;gBAAEW,IAAIN;YAAiB;QAChC,OAAO;YACL,gCAAgC;YAChC,8FAA8F;YAC9F,IAAIO,YAAYV;YAChB,IAAIN,QAAQiB,kBAAkB,IAAIX,QAAQ,UAAU;gBAClDU,YAAY;YACd;YAEA,+DAA+D;YAC/D,2CAA2C;YAC3C,MAAME,YAAYX;YAElB,gDAAgD;YAChD,IAAIN,OAAOC,IAAI,CAACgB,WAAWf,MAAM,KAAK,GAAG;gBACvC;YACF;YAEA,KAAK,MAAM,CAACgB,IAAIC,cAAc,IAAInB,OAAOO,OAAO,CAACU,WAAY;gBAC3D,qEAAqE;gBACrE,8DAA8D;gBAC9D,IAAIE,kBAAkBC,WAAW;oBAC/B;gBACF;gBAEA,IAAIC,aAAaF;gBAEjB,uEAAuE;gBACvE,IAAI,AAACD,CAAAA,OAAO,cAAcA,OAAO,MAAK,KAAM,OAAOC,kBAAkB,UAAU;oBAC7EE,aAAa,CAAC,CAAC,EAAEF,cAAc,CAAC,CAAC;gBACnC;gBAEAf,WAAWkB,IAAI,CAAC;oBACdC,UAAUL;oBACVM,MAAMT;oBACNT,OAAOe;gBACT;YACF;QACF;IACF;IAEA,oEAAoE;IACpE,qDAAqD;IACrD,IAAItB,QAAQY,qBAAqB,IAAIP,WAAWF,MAAM,KAAK,GAAG;QAC5D,OAAOE,UAAU,CAAC,EAAE;IACtB;IAEA,OAAO;QAAED,KAAKC;IAAW;AAC3B"}
1
+ {"version":3,"sources":["../../../src/db-content-api/utilities/where.ts"],"sourcesContent":["import type { Where } from 'payload'\n\nimport type { components } from '../generated/content-api-types.js'\n\ntype WhereClause = components['schemas']['WhereClause']\n\n// Payload's format: { fieldName: { operator: value }, and: [...], or: [...] }\n// Content API expects: { and: [{ path, operator, value }], or: [{ path, operator, value }] }\n//\n// The format stays different. This allows the Content API to evolve its filter schema,\n// for example to support composite types like Point, which are not lexicographically sortable.\n// Semantics must remain identical to Payload.\n\ntype ConvertOptions = {\n /** Internal flag to track if we're inside a logical operator (and/or) */\n insideLogicalOperator?: boolean\n /** If true, transform 'parent' field to 'documentId' (used for version queries) */\n parentToDocumentId?: boolean\n}\n\nexport function convertPayloadWhereToContentAPI(\n where: undefined | Where,\n options: ConvertOptions = {},\n): WhereClause {\n // Empty where {} should be { and: [] } not undefined\n // Content API requires a where clause structure even for \"no filter\"\n if (!where || Object.keys(where).length === 0) {\n return { and: [] }\n }\n\n // Extract the condition type (the variant with 'path', 'operator', 'value') from WhereClause union\n type WhereCondition = Extract<WhereClause, { path: string }>\n const conditions: WhereClause[] = []\n\n for (const [key, value] of Object.entries(where)) {\n if (key === 'and') {\n // Recursively convert nested 'and' conditions, preserving options\n const nestedConditions = (value as Where[])\n .map((item) =>\n convertPayloadWhereToContentAPI(item, { ...options, insideLogicalOperator: true }),\n )\n // TODO: A better solution would be to make the `where` schema of `zod` in `content-api`\n // more permissive. For now I'll do it this way because I have an idea to simplify\n // everything we're doing with `where` (Post EAP) anyway.\n // Filter out empty conditions { and: [] } that would be invalid\n .filter((condition) => {\n if ('and' in condition) {\n return condition.and.length > 0\n }\n if ('or' in condition) {\n return condition.or.length > 0\n }\n return true // Keep path/operator/value conditions\n })\n\n // If filtering resulted in no conditions, return empty and\n if (nestedConditions.length === 0) {\n return { and: [] }\n }\n\n return { and: nestedConditions }\n } else if (key === 'or') {\n // Recursively convert nested 'or' conditions, preserving options\n const nestedConditions = (value as Where[])\n .map((item) =>\n convertPayloadWhereToContentAPI(item, { ...options, insideLogicalOperator: true }),\n )\n // Filter out empty conditions { and: [] } or { or: [] } that would be invalid\n .filter((condition) => {\n if ('and' in condition) {\n return condition.and.length > 0\n }\n if ('or' in condition) {\n return condition.or.length > 0\n }\n return true // Keep path/operator/value conditions\n })\n\n // If filtering resulted in no conditions, return empty and\n if (nestedConditions.length === 0) {\n return { and: [] }\n }\n\n return { or: nestedConditions }\n } else {\n // TODO: fix this in content api\n // WORKAROUND: Payload uses 'parent' for version queries, but Content API expects 'documentId'\n let fieldPath = key\n if (options.parentToDocumentId && key === 'parent') {\n fieldPath = 'documentId'\n }\n\n // Convert field conditions: { fieldName: { operator: value } }\n // to: { path: fieldName, operator, value }\n\n // Handle Payload's shorthand: { fieldName: value } → { fieldName: { equals: value } }\n // If value is a primitive (string, number, boolean, null) or not a plain object,\n // treat it as an implicit 'equals' operator\n const isPrimitive = value === null || typeof value !== 'object' || Array.isArray(value)\n\n if (isPrimitive) {\n // Shorthand format: { id: \"some-value\" } means { id: { equals: \"some-value\" } }\n conditions.push({\n operator: 'equals',\n path: fieldPath,\n value,\n } as WhereCondition)\n continue\n }\n\n const operators = value as Record<string, unknown>\n\n // Skip empty operator objects { fieldName: {} }\n if (Object.keys(operators).length === 0) {\n continue\n }\n\n for (const [op, operatorValue] of Object.entries(operators)) {\n // Skip operators with undefined values (e.g., { equals: undefined })\n // This can happen when Payload sends incomplete where clauses\n if (operatorValue === undefined) {\n continue\n }\n\n let finalValue = operatorValue\n\n // Convert string booleans to actual booleans for exists operator\n // REST API sends \"true\"/\"false\" as strings, but Content API requires boolean\n if (op === 'exists' && typeof operatorValue === 'string') {\n finalValue = operatorValue === 'true'\n }\n\n conditions.push({\n operator: op as WhereCondition['operator'],\n path: fieldPath,\n value: finalValue,\n } as WhereCondition)\n }\n }\n }\n\n // If inside a logical operator (and/or), return conditions directly\n // Otherwise, wrap in 'and' to match WhereClause type\n if (options.insideLogicalOperator && conditions.length === 1) {\n return conditions[0]\n }\n\n return { and: conditions }\n}\n"],"names":["convertPayloadWhereToContentAPI","where","options","Object","keys","length","and","conditions","key","value","entries","nestedConditions","map","item","insideLogicalOperator","filter","condition","or","fieldPath","parentToDocumentId","isPrimitive","Array","isArray","push","operator","path","operators","op","operatorValue","undefined","finalValue"],"mappings":"AAoBA,OAAO,SAASA,gCACdC,KAAwB,EACxBC,UAA0B,CAAC,CAAC;IAE5B,qDAAqD;IACrD,qEAAqE;IACrE,IAAI,CAACD,SAASE,OAAOC,IAAI,CAACH,OAAOI,MAAM,KAAK,GAAG;QAC7C,OAAO;YAAEC,KAAK,EAAE;QAAC;IACnB;IAIA,MAAMC,aAA4B,EAAE;IAEpC,KAAK,MAAM,CAACC,KAAKC,MAAM,IAAIN,OAAOO,OAAO,CAACT,OAAQ;QAChD,IAAIO,QAAQ,OAAO;YACjB,kEAAkE;YAClE,MAAMG,mBAAmB,AAACF,MACvBG,GAAG,CAAC,CAACC,OACJb,gCAAgCa,MAAM;oBAAE,GAAGX,OAAO;oBAAEY,uBAAuB;gBAAK,GAElF,wFAAwF;YACxF,kFAAkF;YAClF,yDAAyD;YACzD,gEAAgE;aAC/DC,MAAM,CAAC,CAACC;gBACP,IAAI,SAASA,WAAW;oBACtB,OAAOA,UAAUV,GAAG,CAACD,MAAM,GAAG;gBAChC;gBACA,IAAI,QAAQW,WAAW;oBACrB,OAAOA,UAAUC,EAAE,CAACZ,MAAM,GAAG;gBAC/B;gBACA,OAAO,KAAK,sCAAsC;;YACpD;YAEF,2DAA2D;YAC3D,IAAIM,iBAAiBN,MAAM,KAAK,GAAG;gBACjC,OAAO;oBAAEC,KAAK,EAAE;gBAAC;YACnB;YAEA,OAAO;gBAAEA,KAAKK;YAAiB;QACjC,OAAO,IAAIH,QAAQ,MAAM;YACvB,iEAAiE;YACjE,MAAMG,mBAAmB,AAACF,MACvBG,GAAG,CAAC,CAACC,OACJb,gCAAgCa,MAAM;oBAAE,GAAGX,OAAO;oBAAEY,uBAAuB;gBAAK,GAElF,8EAA8E;aAC7EC,MAAM,CAAC,CAACC;gBACP,IAAI,SAASA,WAAW;oBACtB,OAAOA,UAAUV,GAAG,CAACD,MAAM,GAAG;gBAChC;gBACA,IAAI,QAAQW,WAAW;oBACrB,OAAOA,UAAUC,EAAE,CAACZ,MAAM,GAAG;gBAC/B;gBACA,OAAO,KAAK,sCAAsC;;YACpD;YAEF,2DAA2D;YAC3D,IAAIM,iBAAiBN,MAAM,KAAK,GAAG;gBACjC,OAAO;oBAAEC,KAAK,EAAE;gBAAC;YACnB;YAEA,OAAO;gBAAEW,IAAIN;YAAiB;QAChC,OAAO;YACL,gCAAgC;YAChC,8FAA8F;YAC9F,IAAIO,YAAYV;YAChB,IAAIN,QAAQiB,kBAAkB,IAAIX,QAAQ,UAAU;gBAClDU,YAAY;YACd;YAEA,+DAA+D;YAC/D,2CAA2C;YAE3C,sFAAsF;YACtF,iFAAiF;YACjF,4CAA4C;YAC5C,MAAME,cAAcX,UAAU,QAAQ,OAAOA,UAAU,YAAYY,MAAMC,OAAO,CAACb;YAEjF,IAAIW,aAAa;gBACf,gFAAgF;gBAChFb,WAAWgB,IAAI,CAAC;oBACdC,UAAU;oBACVC,MAAMP;oBACNT;gBACF;gBACA;YACF;YAEA,MAAMiB,YAAYjB;YAElB,gDAAgD;YAChD,IAAIN,OAAOC,IAAI,CAACsB,WAAWrB,MAAM,KAAK,GAAG;gBACvC;YACF;YAEA,KAAK,MAAM,CAACsB,IAAIC,cAAc,IAAIzB,OAAOO,OAAO,CAACgB,WAAY;gBAC3D,qEAAqE;gBACrE,8DAA8D;gBAC9D,IAAIE,kBAAkBC,WAAW;oBAC/B;gBACF;gBAEA,IAAIC,aAAaF;gBAEjB,iEAAiE;gBACjE,6EAA6E;gBAC7E,IAAID,OAAO,YAAY,OAAOC,kBAAkB,UAAU;oBACxDE,aAAaF,kBAAkB;gBACjC;gBAEArB,WAAWgB,IAAI,CAAC;oBACdC,UAAUG;oBACVF,MAAMP;oBACNT,OAAOqB;gBACT;YACF;QACF;IACF;IAEA,oEAAoE;IACpE,qDAAqD;IACrD,IAAI5B,QAAQY,qBAAqB,IAAIP,WAAWF,MAAM,KAAK,GAAG;QAC5D,OAAOE,UAAU,CAAC,EAAE;IACtB;IAEA,OAAO;QAAED,KAAKC;IAAW;AAC3B"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/oauth/components/LogoutButton/index.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,cAAc,CAAA;AAIrB,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CA0D/E,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/oauth/components/LogoutButton/index.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,cAAc,CAAA;AAIrB,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CA6D/E,CAAA"}
@@ -1,8 +1,8 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { Logout, useConfig } from '@payloadcms/ui';
4
+ import { formatAdminURL } from 'payload/shared';
4
5
  import React from 'react';
5
- import { getAdminPath } from '../../utilities/getAdminPath.js';
6
6
  import './index.scss';
7
7
  const baseClass = 'oauth-logout';
8
8
  export const LogoutButton = ({ disabled, endpointSlug })=>{
@@ -16,8 +16,10 @@ export const LogoutButton = ({ disabled, endpointSlug })=>{
16
16
  if (port) {
17
17
  redirectToSet += `:${port}`;
18
18
  }
19
- redirectToSet += getAdminPath(config);
20
- setRedirect(redirectToSet);
19
+ setRedirect(formatAdminURL({
20
+ adminRoute: config.routes.admin,
21
+ serverURL: redirectToSet
22
+ }));
21
23
  }, [
22
24
  config
23
25
  ]);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/oauth/components/LogoutButton/index.tsx"],"sourcesContent":["'use client'\n\nimport { Logout, useConfig } from '@payloadcms/ui'\nimport React from 'react'\n\nimport { getAdminPath } from '../../utilities/getAdminPath.js'\nimport './index.scss'\n\nconst baseClass = 'oauth-logout'\n\nexport const LogoutButton: React.FC<{ disabled?: boolean; endpointSlug: string }> = ({\n disabled,\n endpointSlug,\n}) => {\n const {\n config,\n config: {\n admin: { user: userSlug },\n routes: { api },\n serverURL,\n },\n } = useConfig()\n\n const [redirect, setRedirect] = React.useState('')\n React.useEffect(() => {\n const protocol = window.location.protocol\n const domain = window.location.hostname\n const port = window.location.port\n\n let redirectToSet = `${protocol}//${domain}`\n if (port) {\n redirectToSet += `:${port}`\n }\n\n redirectToSet += getAdminPath(config)\n\n setRedirect(redirectToSet)\n }, [config])\n\n if (!redirect) {\n return null\n }\n\n if (disabled) {\n return <Logout />\n }\n\n return (\n <div className={baseClass}>\n <a\n aria-label=\"Logout\"\n href={`${serverURL}${api}/${userSlug}/${endpointSlug}/logout?redirect=${redirect}`}\n >\n <svg\n className=\"icon icon--logout\"\n fill=\"none\"\n viewBox=\"0 0 25 25\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path className=\"stroke\" d=\"M10 5H18V19H10\" />\n <g>\n <path className=\"stroke\" d=\"M8 8.5L4.46447 12.0355L8 15.5711\" />\n <line className=\"stroke\" x1=\"5\" x2=\"13\" y1=\"12\" y2=\"12\" />\n </g>\n </svg>\n </a>\n </div>\n )\n}\n"],"names":["Logout","useConfig","React","getAdminPath","baseClass","LogoutButton","disabled","endpointSlug","config","admin","user","userSlug","routes","api","serverURL","redirect","setRedirect","useState","useEffect","protocol","window","location","domain","hostname","port","redirectToSet","div","className","a","aria-label","href","svg","fill","viewBox","xmlns","path","d","g","line","x1","x2","y1","y2"],"mappings":"AAAA;;AAEA,SAASA,MAAM,EAAEC,SAAS,QAAQ,iBAAgB;AAClD,OAAOC,WAAW,QAAO;AAEzB,SAASC,YAAY,QAAQ,kCAAiC;AAC9D,OAAO,eAAc;AAErB,MAAMC,YAAY;AAElB,OAAO,MAAMC,eAAuE,CAAC,EACnFC,QAAQ,EACRC,YAAY,EACb;IACC,MAAM,EACJC,MAAM,EACNA,QAAQ,EACNC,OAAO,EAAEC,MAAMC,QAAQ,EAAE,EACzBC,QAAQ,EAAEC,GAAG,EAAE,EACfC,SAAS,EACV,EACF,GAAGb;IAEJ,MAAM,CAACc,UAAUC,YAAY,GAAGd,MAAMe,QAAQ,CAAC;IAC/Cf,MAAMgB,SAAS,CAAC;QACd,MAAMC,WAAWC,OAAOC,QAAQ,CAACF,QAAQ;QACzC,MAAMG,SAASF,OAAOC,QAAQ,CAACE,QAAQ;QACvC,MAAMC,OAAOJ,OAAOC,QAAQ,CAACG,IAAI;QAEjC,IAAIC,gBAAgB,GAAGN,SAAS,EAAE,EAAEG,QAAQ;QAC5C,IAAIE,MAAM;YACRC,iBAAiB,CAAC,CAAC,EAAED,MAAM;QAC7B;QAEAC,iBAAiBtB,aAAaK;QAE9BQ,YAAYS;IACd,GAAG;QAACjB;KAAO;IAEX,IAAI,CAACO,UAAU;QACb,OAAO;IACT;IAEA,IAAIT,UAAU;QACZ,qBAAO,KAACN;IACV;IAEA,qBACE,KAAC0B;QAAIC,WAAWvB;kBACd,cAAA,KAACwB;YACCC,cAAW;YACXC,MAAM,GAAGhB,YAAYD,IAAI,CAAC,EAAEF,SAAS,CAAC,EAAEJ,aAAa,iBAAiB,EAAEQ,UAAU;sBAElF,cAAA,MAACgB;gBACCJ,WAAU;gBACVK,MAAK;gBACLC,SAAQ;gBACRC,OAAM;;kCAEN,KAACC;wBAAKR,WAAU;wBAASS,GAAE;;kCAC3B,MAACC;;0CACC,KAACF;gCAAKR,WAAU;gCAASS,GAAE;;0CAC3B,KAACE;gCAAKX,WAAU;gCAASY,IAAG;gCAAIC,IAAG;gCAAKC,IAAG;gCAAKC,IAAG;;;;;;;;AAM/D,EAAC"}
1
+ {"version":3,"sources":["../../../../src/oauth/components/LogoutButton/index.tsx"],"sourcesContent":["'use client'\n\nimport { Logout, useConfig } from '@payloadcms/ui'\nimport { formatAdminURL } from 'payload/shared'\nimport React from 'react'\n\nimport './index.scss'\n\nconst baseClass = 'oauth-logout'\n\nexport const LogoutButton: React.FC<{ disabled?: boolean; endpointSlug: string }> = ({\n disabled,\n endpointSlug,\n}) => {\n const {\n config,\n config: {\n admin: { user: userSlug },\n routes: { api },\n serverURL,\n },\n } = useConfig()\n\n const [redirect, setRedirect] = React.useState('')\n React.useEffect(() => {\n const protocol = window.location.protocol\n const domain = window.location.hostname\n const port = window.location.port\n\n let redirectToSet = `${protocol}//${domain}`\n if (port) {\n redirectToSet += `:${port}`\n }\n\n setRedirect(\n formatAdminURL({\n adminRoute: config.routes.admin,\n serverURL: redirectToSet,\n }),\n )\n }, [config])\n\n if (!redirect) {\n return null\n }\n\n if (disabled) {\n return <Logout />\n }\n\n return (\n <div className={baseClass}>\n <a\n aria-label=\"Logout\"\n href={`${serverURL}${api}/${userSlug}/${endpointSlug}/logout?redirect=${redirect}`}\n >\n <svg\n className=\"icon icon--logout\"\n fill=\"none\"\n viewBox=\"0 0 25 25\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path className=\"stroke\" d=\"M10 5H18V19H10\" />\n <g>\n <path className=\"stroke\" d=\"M8 8.5L4.46447 12.0355L8 15.5711\" />\n <line className=\"stroke\" x1=\"5\" x2=\"13\" y1=\"12\" y2=\"12\" />\n </g>\n </svg>\n </a>\n </div>\n )\n}\n"],"names":["Logout","useConfig","formatAdminURL","React","baseClass","LogoutButton","disabled","endpointSlug","config","admin","user","userSlug","routes","api","serverURL","redirect","setRedirect","useState","useEffect","protocol","window","location","domain","hostname","port","redirectToSet","adminRoute","div","className","a","aria-label","href","svg","fill","viewBox","xmlns","path","d","g","line","x1","x2","y1","y2"],"mappings":"AAAA;;AAEA,SAASA,MAAM,EAAEC,SAAS,QAAQ,iBAAgB;AAClD,SAASC,cAAc,QAAQ,iBAAgB;AAC/C,OAAOC,WAAW,QAAO;AAEzB,OAAO,eAAc;AAErB,MAAMC,YAAY;AAElB,OAAO,MAAMC,eAAuE,CAAC,EACnFC,QAAQ,EACRC,YAAY,EACb;IACC,MAAM,EACJC,MAAM,EACNA,QAAQ,EACNC,OAAO,EAAEC,MAAMC,QAAQ,EAAE,EACzBC,QAAQ,EAAEC,GAAG,EAAE,EACfC,SAAS,EACV,EACF,GAAGb;IAEJ,MAAM,CAACc,UAAUC,YAAY,GAAGb,MAAMc,QAAQ,CAAC;IAC/Cd,MAAMe,SAAS,CAAC;QACd,MAAMC,WAAWC,OAAOC,QAAQ,CAACF,QAAQ;QACzC,MAAMG,SAASF,OAAOC,QAAQ,CAACE,QAAQ;QACvC,MAAMC,OAAOJ,OAAOC,QAAQ,CAACG,IAAI;QAEjC,IAAIC,gBAAgB,GAAGN,SAAS,EAAE,EAAEG,QAAQ;QAC5C,IAAIE,MAAM;YACRC,iBAAiB,CAAC,CAAC,EAAED,MAAM;QAC7B;QAEAR,YACEd,eAAe;YACbwB,YAAYlB,OAAOI,MAAM,CAACH,KAAK;YAC/BK,WAAWW;QACb;IAEJ,GAAG;QAACjB;KAAO;IAEX,IAAI,CAACO,UAAU;QACb,OAAO;IACT;IAEA,IAAIT,UAAU;QACZ,qBAAO,KAACN;IACV;IAEA,qBACE,KAAC2B;QAAIC,WAAWxB;kBACd,cAAA,KAACyB;YACCC,cAAW;YACXC,MAAM,GAAGjB,YAAYD,IAAI,CAAC,EAAEF,SAAS,CAAC,EAAEJ,aAAa,iBAAiB,EAAEQ,UAAU;sBAElF,cAAA,MAACiB;gBACCJ,WAAU;gBACVK,MAAK;gBACLC,SAAQ;gBACRC,OAAM;;kCAEN,KAACC;wBAAKR,WAAU;wBAASS,GAAE;;kCAC3B,MAACC;;0CACC,KAACF;gCAAKR,WAAU;gCAASS,GAAE;;0CAC3B,KAACE;gCAAKX,WAAU;gCAASY,IAAG;gCAAIC,IAAG;gCAAKC,IAAG;gCAAKC,IAAG;;;;;;;;AAM/D,EAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"getLoginEndpoint.d.ts","sourceRoot":"","sources":["../../../src/oauth/endpoints/getLoginEndpoint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAKzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAY,MAAM,aAAa,CAAA;AAS7E,UAAU,IAAI;IACZ,UAAU,EAAE,gBAAgB,CAAA;IAC5B,iBAAiB,EAAE,iBAAiB,CAAA;IACpC,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,aAAa,CAAA;IAC5B,QAAQ,EAAE,QAAQ,CAAA;CACnB;AAID,eAAO,MAAM,gBAAgB,8EAM1B,IAAI,KAAG,QAkPR,CAAA"}
1
+ {"version":3,"file":"getLoginEndpoint.d.ts","sourceRoot":"","sources":["../../../src/oauth/endpoints/getLoginEndpoint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAKzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAY,MAAM,aAAa,CAAA;AAQ7E,UAAU,IAAI;IACZ,UAAU,EAAE,gBAAgB,CAAA;IAC5B,iBAAiB,EAAE,iBAAiB,CAAA;IACpC,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,aAAa,CAAA;IAC5B,QAAQ,EAAE,QAAQ,CAAA;CACnB;AAID,eAAO,MAAM,gBAAgB,8EAM1B,IAAI,KAAG,QA4PR,CAAA"}
@@ -1,16 +1,15 @@
1
1
  import { APIError, generateCookie, parseCookies } from 'payload';
2
- import { getSafeRedirect } from 'payload/shared';
2
+ import { formatAdminURL, getSafeRedirect } from 'payload/shared';
3
3
  import { getProjectToken } from '../../api/figma-api.js';
4
4
  import { createCookieOptions } from '../utilities/createCookieOptions.js';
5
5
  import { createDebugLogger } from '../utilities/createDebugLogger.js';
6
6
  import { extractOrigin } from '../utilities/extractOrigin.js';
7
- import { getAdminPath } from '../utilities/getAdminPath.js';
8
7
  import { getCookieExpiration } from '../utilities/getCookieExpiration.js';
9
8
  const isAbsoluteURL = (url)=>/^[a-z][a-z\d+.-]*:/.test(url);
10
9
  export const getLoginEndpoint = ({ collection, collectionOptions, endpointSlug, pluginOptions, strategy })=>({
11
10
  handler: async (req)=>{
12
11
  const { config } = req.payload;
13
- const adminPath = getAdminPath(config);
12
+ const adminRoute = config.routes?.admin || '/admin';
14
13
  try {
15
14
  await strategy.ensureMeta();
16
15
  const path = req.pathname;
@@ -37,9 +36,16 @@ export const getLoginEndpoint = ({ collection, collectionOptions, endpointSlug,
37
36
  }
38
37
  const stateRaw = jsonBody.state;
39
38
  const state = JSON.parse(Buffer.from(stateRaw, 'base64').toString('utf-8'));
40
- const redirectDestination = state.serverURL || pluginOptions.redirectServerURL || config.serverURL;
41
- let failedRedirect = `${redirectDestination}${adminPath}/login`;
42
- let redirectToUse = `${redirectDestination}${adminPath}`;
39
+ const redirectServerURL = state.serverURL || pluginOptions.redirectServerURL || config.serverURL;
40
+ let failedRedirect = formatAdminURL({
41
+ adminRoute,
42
+ path: '/login',
43
+ serverURL: redirectServerURL
44
+ });
45
+ let redirectToUse = formatAdminURL({
46
+ adminRoute,
47
+ serverURL: redirectServerURL
48
+ });
43
49
  if (state.redirect) {
44
50
  redirectToUse = state.redirect;
45
51
  }
@@ -126,7 +132,11 @@ export const getLoginEndpoint = ({ collection, collectionOptions, endpointSlug,
126
132
  code,
127
133
  code_verifier: req.payload.decrypt(state.verifier),
128
134
  grant_type: 'authorization_code',
129
- redirect_uri: `${redirectDestination}${config?.routes?.api || '/api'}/${collection.slug}/${endpointSlug}/login`
135
+ redirect_uri: formatAdminURL({
136
+ apiRoute: config.routes?.api || '/api',
137
+ path: `/${collection.slug}/${endpointSlug}/login`,
138
+ serverURL: redirectServerURL
139
+ })
130
140
  };
131
141
  if (strategy.collectionOptions.clientSecret) {
132
142
  body.client_secret = strategy.collectionOptions.clientSecret;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/oauth/endpoints/getLoginEndpoint.ts"],"sourcesContent":["import type { CollectionConfig, Endpoint } from 'payload'\n\nimport { APIError, generateCookie, parseCookies } from 'payload'\nimport { getSafeRedirect } from 'payload/shared'\n\nimport type { Strategy } from '../strategy/index.js'\nimport type { CollectionOptions, PluginOptions, StateObj } from '../types.js'\n\nimport { getProjectToken } from '../../api/figma-api.js'\nimport { createCookieOptions } from '../utilities/createCookieOptions.js'\nimport { createDebugLogger } from '../utilities/createDebugLogger.js'\nimport { extractOrigin } from '../utilities/extractOrigin.js'\nimport { getAdminPath } from '../utilities/getAdminPath.js'\nimport { getCookieExpiration } from '../utilities/getCookieExpiration.js'\n\ninterface Args {\n collection: CollectionConfig\n collectionOptions: CollectionOptions\n endpointSlug: string\n pluginOptions: PluginOptions\n strategy: Strategy\n}\n\nconst isAbsoluteURL = (url: string) => /^[a-z][a-z\\d+.-]*:/.test(url)\n\nexport const getLoginEndpoint = ({\n collection,\n collectionOptions,\n endpointSlug,\n pluginOptions,\n strategy,\n}: Args): Endpoint => ({\n handler: async (req) => {\n const { config } = req.payload\n const adminPath = getAdminPath(config)\n try {\n await strategy.ensureMeta()\n\n const path = req.pathname\n const debugLogger = createDebugLogger(req.payload, pluginOptions.debug)\n\n let jsonBody: Record<string, unknown> = {}\n\n const contentType = req.headers.get('content-type')\n\n // Type narrow PayloadRequst's Partial<Request>\n if (typeof req.json !== 'function' || typeof req.formData !== 'function') {\n debugLogger.info({\n msg: 'Request does not have json or formData methods',\n path,\n })\n\n return Response.redirect(`${pluginOptions.redirectServerURL || config.serverURL}/login`)\n }\n\n if (collectionOptions.authorizationURLParams?.response_mode === 'query') {\n if (Object.keys(req.query).length > 0) {\n jsonBody = req.query\n }\n } else if (contentType === 'application/json') {\n jsonBody = await req.json()\n } else if (contentType === 'application/x-www-form-urlencoded') {\n const formData = await req.formData()\n jsonBody = Object.fromEntries(formData.entries())\n }\n\n const stateRaw = jsonBody.state as string\n const state: StateObj = JSON.parse(Buffer.from(stateRaw, 'base64').toString('utf-8'))\n\n const redirectDestination =\n state.serverURL || pluginOptions.redirectServerURL || config.serverURL\n let failedRedirect = `${redirectDestination}${adminPath}/login`\n let redirectToUse = `${redirectDestination}${adminPath}`\n\n if (state.redirect) {\n redirectToUse = state.redirect\n }\n\n if (state.failedRedirect) {\n failedRedirect = state.failedRedirect\n }\n\n failedRedirect = getSafeRedirect({ allowAbsoluteUrls: true, redirectTo: failedRedirect })\n redirectToUse = getSafeRedirect({ allowAbsoluteUrls: true, redirectTo: redirectToUse })\n\n if (!isAbsoluteURL(failedRedirect)) {\n return Response.json({ error: 'Invalid failed redirect provided' }, { status: 403 })\n }\n if (!isAbsoluteURL(redirectToUse)) {\n return Response.json({ error: 'Invalid redirect provided' }, { status: 403 })\n }\n\n if (Array.isArray(req.payload.config.csrf) && req.payload.config.csrf.length > 0) {\n const failedRedirectOrigin = extractOrigin(failedRedirect)\n const redirectToUseOrigin = extractOrigin(redirectToUse)\n\n if (failedRedirectOrigin && !req.payload.config.csrf.includes(failedRedirectOrigin)) {\n req.payload.logger.error(\n `Failed redirect origin ${failedRedirectOrigin} is not allowed by CSRF configuration.`,\n )\n return Response.json(\n { error: 'Failed redirect origin is not allowed by CSRF configuration.' },\n { status: 403 },\n )\n }\n\n if (redirectToUseOrigin && !req.payload.config.csrf.includes(redirectToUseOrigin)) {\n req.payload.logger.error(\n `Redirect origin ${redirectToUseOrigin} is not allowed by CSRF configuration.`,\n )\n return Response.json(\n { error: 'Redirect origin is not allowed by CSRF configuration.' },\n { status: 403 },\n )\n }\n }\n\n // Verify signature\n if (strategy.name !== req.payload.decrypt(state.sig)) {\n req.payload.logger.error('Signature mismatch. Failing login and redirecting.')\n return Response.redirect(failedRedirect)\n }\n\n if (!strategy.meta?.token_endpoint) {\n debugLogger.error({\n msg: `No metadata was obtained from the identity provider. Failing login and redirecting.`,\n path,\n })\n return Response.redirect(failedRedirect)\n }\n\n debugLogger.info({ body: jsonBody, msg: 'Received login response body', path })\n\n if (!jsonBody?.code) {\n debugLogger.error({\n msg: `No authorization code present in body. Failing login and redirecting.`,\n path,\n })\n return Response.redirect(failedRedirect)\n }\n\n // Exchange `code` from body for refresh token\n const { code } = jsonBody\n\n if (typeof code !== 'string') {\n debugLogger.error({\n msg: `Authorization code present in body is not a string. Failing login and redirecting.`,\n path,\n })\n return Response.redirect(failedRedirect)\n }\n\n const body: Record<string, string> = {\n client_id: strategy.clientID,\n code,\n code_verifier: req.payload.decrypt(state.verifier),\n grant_type: 'authorization_code',\n redirect_uri: `${redirectDestination}${config?.routes?.api || '/api'}/${\n collection.slug\n }/${endpointSlug}/login`,\n }\n\n if (strategy.collectionOptions.clientSecret) {\n body.client_secret = strategy.collectionOptions.clientSecret\n }\n\n debugLogger.info({\n msg: 'Exchanging code for access token',\n path,\n requestBody: body,\n })\n\n const tokenRes = await fetch(strategy.meta?.token_endpoint, {\n body: new URLSearchParams(body),\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n method: 'POST',\n }).then((r) => r.json())\n\n debugLogger.info({ msg: 'Token Response', path, tokenRes })\n\n const { access_token, error, error_description, expires_in: refreshTokenExpires } = tokenRes\n\n debugLogger.info({ msg: 'tokenResss', tokenRes })\n\n // Swap for project token\n const project_token = await getProjectToken(\n tokenRes.access_token,\n config.custom.figma.contentSystemId,\n )\n const refresh_token = access_token\n\n // Store project token as access_token\n\n const token = project_token.token\n const expiresIn = project_token.expiresAt\n\n if (!token) {\n const errMsg = `No ${\n collectionOptions.token || 'access_token'\n } was returned from the identity provider.`\n req.payload.logger.error({ msg: errMsg, path })\n throw new APIError(errMsg)\n }\n\n const cookieOptions = createCookieOptions({ collection, headers: req.headers, pluginOptions })\n\n if (error) {\n req.payload.logger.error('Error swapping access code with access token:')\n req.payload.logger.error({ err: error, error_description })\n return Response.redirect(failedRedirect)\n }\n\n // get the payloadRedirect cookie value\n const cookies = parseCookies(req.headers)\n\n const payloadRedirect =\n 'payloadRedirect' in cookies ? (cookies.payloadRedirect as string) : ''\n\n if (!req.responseHeaders) {\n req.responseHeaders = new Headers()\n }\n\n if (payloadRedirect) {\n if (isAbsoluteURL(payloadRedirect)) {\n redirectToUse = payloadRedirect\n } else {\n redirectToUse += payloadRedirect\n }\n\n req.responseHeaders.append(\n 'Set-Cookie',\n `payloadRedirect=${redirectToUse}; Max-Age=0; Path=/;`,\n )\n }\n\n if (refresh_token && !collectionOptions.usePayloadJWT) {\n debugLogger.info('Setting refresh token cookie')\n const refreshCookie = generateCookie({\n returnCookieAsObject: false,\n ...cookieOptions,\n name: `${strategy.cookieName}-refresh`,\n value: refresh_token,\n // Default to 1 year if no expiration\n expires: getCookieExpiration(cookieOptions?.expires ?? refreshTokenExpires ?? 31_556_952),\n }) as string\n\n req.responseHeaders.append('Set-Cookie', refreshCookie)\n }\n\n const tokenExpires = cookieOptions?.expires\n ? getCookieExpiration(cookieOptions.expires)\n : new Date(expiresIn) // Project token uses epoch time\n const tokenCookie = generateCookie({\n ...cookieOptions,\n name: strategy.cookieName,\n expires: tokenExpires,\n returnCookieAsObject: false,\n value: token,\n }) as string\n\n req.responseHeaders.append('Set-Cookie', tokenCookie)\n\n return Response.redirect(redirectToUse)\n } catch (err: unknown) {\n req.payload.logger.error({ err, msg: 'Error while attempting to login', path: req.pathname })\n\n return Response.json({ error: 'Error while attempting to login' }, { status: 500 })\n }\n },\n method: collectionOptions.authorizationURLParams?.response_mode === 'query' ? 'get' : 'post',\n path: `/${endpointSlug}/login`,\n})\n"],"names":["APIError","generateCookie","parseCookies","getSafeRedirect","getProjectToken","createCookieOptions","createDebugLogger","extractOrigin","getAdminPath","getCookieExpiration","isAbsoluteURL","url","test","getLoginEndpoint","collection","collectionOptions","endpointSlug","pluginOptions","strategy","handler","req","config","payload","adminPath","ensureMeta","path","pathname","debugLogger","debug","jsonBody","contentType","headers","get","json","formData","info","msg","Response","redirect","redirectServerURL","serverURL","authorizationURLParams","response_mode","Object","keys","query","length","fromEntries","entries","stateRaw","state","JSON","parse","Buffer","from","toString","redirectDestination","failedRedirect","redirectToUse","allowAbsoluteUrls","redirectTo","error","status","Array","isArray","csrf","failedRedirectOrigin","redirectToUseOrigin","includes","logger","name","decrypt","sig","meta","token_endpoint","body","code","client_id","clientID","code_verifier","verifier","grant_type","redirect_uri","routes","api","slug","clientSecret","client_secret","requestBody","tokenRes","fetch","URLSearchParams","method","then","r","access_token","error_description","expires_in","refreshTokenExpires","project_token","custom","figma","contentSystemId","refresh_token","token","expiresIn","expiresAt","errMsg","cookieOptions","err","cookies","payloadRedirect","responseHeaders","Headers","append","usePayloadJWT","refreshCookie","returnCookieAsObject","cookieName","value","expires","tokenExpires","Date","tokenCookie"],"mappings":"AAEA,SAASA,QAAQ,EAAEC,cAAc,EAAEC,YAAY,QAAQ,UAAS;AAChE,SAASC,eAAe,QAAQ,iBAAgB;AAKhD,SAASC,eAAe,QAAQ,yBAAwB;AACxD,SAASC,mBAAmB,QAAQ,sCAAqC;AACzE,SAASC,iBAAiB,QAAQ,oCAAmC;AACrE,SAASC,aAAa,QAAQ,gCAA+B;AAC7D,SAASC,YAAY,QAAQ,+BAA8B;AAC3D,SAASC,mBAAmB,QAAQ,sCAAqC;AAUzE,MAAMC,gBAAgB,CAACC,MAAgB,qBAAqBC,IAAI,CAACD;AAEjE,OAAO,MAAME,mBAAmB,CAAC,EAC/BC,UAAU,EACVC,iBAAiB,EACjBC,YAAY,EACZC,aAAa,EACbC,QAAQ,EACH,GAAgB,CAAA;QACrBC,SAAS,OAAOC;YACd,MAAM,EAAEC,MAAM,EAAE,GAAGD,IAAIE,OAAO;YAC9B,MAAMC,YAAYf,aAAaa;YAC/B,IAAI;gBACF,MAAMH,SAASM,UAAU;gBAEzB,MAAMC,OAAOL,IAAIM,QAAQ;gBACzB,MAAMC,cAAcrB,kBAAkBc,IAAIE,OAAO,EAAEL,cAAcW,KAAK;gBAEtE,IAAIC,WAAoC,CAAC;gBAEzC,MAAMC,cAAcV,IAAIW,OAAO,CAACC,GAAG,CAAC;gBAEpC,+CAA+C;gBAC/C,IAAI,OAAOZ,IAAIa,IAAI,KAAK,cAAc,OAAOb,IAAIc,QAAQ,KAAK,YAAY;oBACxEP,YAAYQ,IAAI,CAAC;wBACfC,KAAK;wBACLX;oBACF;oBAEA,OAAOY,SAASC,QAAQ,CAAC,GAAGrB,cAAcsB,iBAAiB,IAAIlB,OAAOmB,SAAS,CAAC,MAAM,CAAC;gBACzF;gBAEA,IAAIzB,kBAAkB0B,sBAAsB,EAAEC,kBAAkB,SAAS;oBACvE,IAAIC,OAAOC,IAAI,CAACxB,IAAIyB,KAAK,EAAEC,MAAM,GAAG,GAAG;wBACrCjB,WAAWT,IAAIyB,KAAK;oBACtB;gBACF,OAAO,IAAIf,gBAAgB,oBAAoB;oBAC7CD,WAAW,MAAMT,IAAIa,IAAI;gBAC3B,OAAO,IAAIH,gBAAgB,qCAAqC;oBAC9D,MAAMI,WAAW,MAAMd,IAAIc,QAAQ;oBACnCL,WAAWc,OAAOI,WAAW,CAACb,SAASc,OAAO;gBAChD;gBAEA,MAAMC,WAAWpB,SAASqB,KAAK;gBAC/B,MAAMA,QAAkBC,KAAKC,KAAK,CAACC,OAAOC,IAAI,CAACL,UAAU,UAAUM,QAAQ,CAAC;gBAE5E,MAAMC,sBACJN,MAAMV,SAAS,IAAIvB,cAAcsB,iBAAiB,IAAIlB,OAAOmB,SAAS;gBACxE,IAAIiB,iBAAiB,GAAGD,sBAAsBjC,UAAU,MAAM,CAAC;gBAC/D,IAAImC,gBAAgB,GAAGF,sBAAsBjC,WAAW;gBAExD,IAAI2B,MAAMZ,QAAQ,EAAE;oBAClBoB,gBAAgBR,MAAMZ,QAAQ;gBAChC;gBAEA,IAAIY,MAAMO,cAAc,EAAE;oBACxBA,iBAAiBP,MAAMO,cAAc;gBACvC;gBAEAA,iBAAiBtD,gBAAgB;oBAAEwD,mBAAmB;oBAAMC,YAAYH;gBAAe;gBACvFC,gBAAgBvD,gBAAgB;oBAAEwD,mBAAmB;oBAAMC,YAAYF;gBAAc;gBAErF,IAAI,CAAChD,cAAc+C,iBAAiB;oBAClC,OAAOpB,SAASJ,IAAI,CAAC;wBAAE4B,OAAO;oBAAmC,GAAG;wBAAEC,QAAQ;oBAAI;gBACpF;gBACA,IAAI,CAACpD,cAAcgD,gBAAgB;oBACjC,OAAOrB,SAASJ,IAAI,CAAC;wBAAE4B,OAAO;oBAA4B,GAAG;wBAAEC,QAAQ;oBAAI;gBAC7E;gBAEA,IAAIC,MAAMC,OAAO,CAAC5C,IAAIE,OAAO,CAACD,MAAM,CAAC4C,IAAI,KAAK7C,IAAIE,OAAO,CAACD,MAAM,CAAC4C,IAAI,CAACnB,MAAM,GAAG,GAAG;oBAChF,MAAMoB,uBAAuB3D,cAAckD;oBAC3C,MAAMU,sBAAsB5D,cAAcmD;oBAE1C,IAAIQ,wBAAwB,CAAC9C,IAAIE,OAAO,CAACD,MAAM,CAAC4C,IAAI,CAACG,QAAQ,CAACF,uBAAuB;wBACnF9C,IAAIE,OAAO,CAAC+C,MAAM,CAACR,KAAK,CACtB,CAAC,uBAAuB,EAAEK,qBAAqB,sCAAsC,CAAC;wBAExF,OAAO7B,SAASJ,IAAI,CAClB;4BAAE4B,OAAO;wBAA+D,GACxE;4BAAEC,QAAQ;wBAAI;oBAElB;oBAEA,IAAIK,uBAAuB,CAAC/C,IAAIE,OAAO,CAACD,MAAM,CAAC4C,IAAI,CAACG,QAAQ,CAACD,sBAAsB;wBACjF/C,IAAIE,OAAO,CAAC+C,MAAM,CAACR,KAAK,CACtB,CAAC,gBAAgB,EAAEM,oBAAoB,sCAAsC,CAAC;wBAEhF,OAAO9B,SAASJ,IAAI,CAClB;4BAAE4B,OAAO;wBAAwD,GACjE;4BAAEC,QAAQ;wBAAI;oBAElB;gBACF;gBAEA,mBAAmB;gBACnB,IAAI5C,SAASoD,IAAI,KAAKlD,IAAIE,OAAO,CAACiD,OAAO,CAACrB,MAAMsB,GAAG,GAAG;oBACpDpD,IAAIE,OAAO,CAAC+C,MAAM,CAACR,KAAK,CAAC;oBACzB,OAAOxB,SAASC,QAAQ,CAACmB;gBAC3B;gBAEA,IAAI,CAACvC,SAASuD,IAAI,EAAEC,gBAAgB;oBAClC/C,YAAYkC,KAAK,CAAC;wBAChBzB,KAAK,CAAC,mFAAmF,CAAC;wBAC1FX;oBACF;oBACA,OAAOY,SAASC,QAAQ,CAACmB;gBAC3B;gBAEA9B,YAAYQ,IAAI,CAAC;oBAAEwC,MAAM9C;oBAAUO,KAAK;oBAAgCX;gBAAK;gBAE7E,IAAI,CAACI,UAAU+C,MAAM;oBACnBjD,YAAYkC,KAAK,CAAC;wBAChBzB,KAAK,CAAC,qEAAqE,CAAC;wBAC5EX;oBACF;oBACA,OAAOY,SAASC,QAAQ,CAACmB;gBAC3B;gBAEA,8CAA8C;gBAC9C,MAAM,EAAEmB,IAAI,EAAE,GAAG/C;gBAEjB,IAAI,OAAO+C,SAAS,UAAU;oBAC5BjD,YAAYkC,KAAK,CAAC;wBAChBzB,KAAK,CAAC,kFAAkF,CAAC;wBACzFX;oBACF;oBACA,OAAOY,SAASC,QAAQ,CAACmB;gBAC3B;gBAEA,MAAMkB,OAA+B;oBACnCE,WAAW3D,SAAS4D,QAAQ;oBAC5BF;oBACAG,eAAe3D,IAAIE,OAAO,CAACiD,OAAO,CAACrB,MAAM8B,QAAQ;oBACjDC,YAAY;oBACZC,cAAc,GAAG1B,sBAAsBnC,QAAQ8D,QAAQC,OAAO,OAAO,CAAC,EACpEtE,WAAWuE,IAAI,CAChB,CAAC,EAAErE,aAAa,MAAM,CAAC;gBAC1B;gBAEA,IAAIE,SAASH,iBAAiB,CAACuE,YAAY,EAAE;oBAC3CX,KAAKY,aAAa,GAAGrE,SAASH,iBAAiB,CAACuE,YAAY;gBAC9D;gBAEA3D,YAAYQ,IAAI,CAAC;oBACfC,KAAK;oBACLX;oBACA+D,aAAab;gBACf;gBAEA,MAAMc,WAAW,MAAMC,MAAMxE,SAASuD,IAAI,EAAEC,gBAAgB;oBAC1DC,MAAM,IAAIgB,gBAAgBhB;oBAC1B5C,SAAS;wBACP,gBAAgB;oBAClB;oBACA6D,QAAQ;gBACV,GAAGC,IAAI,CAAC,CAACC,IAAMA,EAAE7D,IAAI;gBAErBN,YAAYQ,IAAI,CAAC;oBAAEC,KAAK;oBAAkBX;oBAAMgE;gBAAS;gBAEzD,MAAM,EAAEM,YAAY,EAAElC,KAAK,EAAEmC,iBAAiB,EAAEC,YAAYC,mBAAmB,EAAE,GAAGT;gBAEpF9D,YAAYQ,IAAI,CAAC;oBAAEC,KAAK;oBAAcqD;gBAAS;gBAE/C,yBAAyB;gBACzB,MAAMU,gBAAgB,MAAM/F,gBAC1BqF,SAASM,YAAY,EACrB1E,OAAO+E,MAAM,CAACC,KAAK,CAACC,eAAe;gBAErC,MAAMC,gBAAgBR;gBAEtB,sCAAsC;gBAEtC,MAAMS,QAAQL,cAAcK,KAAK;gBACjC,MAAMC,YAAYN,cAAcO,SAAS;gBAEzC,IAAI,CAACF,OAAO;oBACV,MAAMG,SAAS,CAAC,GAAG,EACjB5F,kBAAkByF,KAAK,IAAI,eAC5B,yCAAyC,CAAC;oBAC3CpF,IAAIE,OAAO,CAAC+C,MAAM,CAACR,KAAK,CAAC;wBAAEzB,KAAKuE;wBAAQlF;oBAAK;oBAC7C,MAAM,IAAIzB,SAAS2G;gBACrB;gBAEA,MAAMC,gBAAgBvG,oBAAoB;oBAAES;oBAAYiB,SAASX,IAAIW,OAAO;oBAAEd;gBAAc;gBAE5F,IAAI4C,OAAO;oBACTzC,IAAIE,OAAO,CAAC+C,MAAM,CAACR,KAAK,CAAC;oBACzBzC,IAAIE,OAAO,CAAC+C,MAAM,CAACR,KAAK,CAAC;wBAAEgD,KAAKhD;wBAAOmC;oBAAkB;oBACzD,OAAO3D,SAASC,QAAQ,CAACmB;gBAC3B;gBAEA,uCAAuC;gBACvC,MAAMqD,UAAU5G,aAAakB,IAAIW,OAAO;gBAExC,MAAMgF,kBACJ,qBAAqBD,UAAWA,QAAQC,eAAe,GAAc;gBAEvE,IAAI,CAAC3F,IAAI4F,eAAe,EAAE;oBACxB5F,IAAI4F,eAAe,GAAG,IAAIC;gBAC5B;gBAEA,IAAIF,iBAAiB;oBACnB,IAAIrG,cAAcqG,kBAAkB;wBAClCrD,gBAAgBqD;oBAClB,OAAO;wBACLrD,iBAAiBqD;oBACnB;oBAEA3F,IAAI4F,eAAe,CAACE,MAAM,CACxB,cACA,CAAC,gBAAgB,EAAExD,cAAc,oBAAoB,CAAC;gBAE1D;gBAEA,IAAI6C,iBAAiB,CAACxF,kBAAkBoG,aAAa,EAAE;oBACrDxF,YAAYQ,IAAI,CAAC;oBACjB,MAAMiF,gBAAgBnH,eAAe;wBACnCoH,sBAAsB;wBACtB,GAAGT,aAAa;wBAChBtC,MAAM,GAAGpD,SAASoG,UAAU,CAAC,QAAQ,CAAC;wBACtCC,OAAOhB;wBACP,qCAAqC;wBACrCiB,SAAS/G,oBAAoBmG,eAAeY,WAAWtB,uBAAuB;oBAChF;oBAEA9E,IAAI4F,eAAe,CAACE,MAAM,CAAC,cAAcE;gBAC3C;gBAEA,MAAMK,eAAeb,eAAeY,UAChC/G,oBAAoBmG,cAAcY,OAAO,IACzC,IAAIE,KAAKjB,WAAW,gCAAgC;;gBACxD,MAAMkB,cAAc1H,eAAe;oBACjC,GAAG2G,aAAa;oBAChBtC,MAAMpD,SAASoG,UAAU;oBACzBE,SAASC;oBACTJ,sBAAsB;oBACtBE,OAAOf;gBACT;gBAEApF,IAAI4F,eAAe,CAACE,MAAM,CAAC,cAAcS;gBAEzC,OAAOtF,SAASC,QAAQ,CAACoB;YAC3B,EAAE,OAAOmD,KAAc;gBACrBzF,IAAIE,OAAO,CAAC+C,MAAM,CAACR,KAAK,CAAC;oBAAEgD;oBAAKzE,KAAK;oBAAmCX,MAAML,IAAIM,QAAQ;gBAAC;gBAE3F,OAAOW,SAASJ,IAAI,CAAC;oBAAE4B,OAAO;gBAAkC,GAAG;oBAAEC,QAAQ;gBAAI;YACnF;QACF;QACA8B,QAAQ7E,kBAAkB0B,sBAAsB,EAAEC,kBAAkB,UAAU,QAAQ;QACtFjB,MAAM,CAAC,CAAC,EAAET,aAAa,MAAM,CAAC;IAChC,CAAA,EAAE"}
1
+ {"version":3,"sources":["../../../src/oauth/endpoints/getLoginEndpoint.ts"],"sourcesContent":["import type { CollectionConfig, Endpoint } from 'payload'\n\nimport { APIError, generateCookie, parseCookies } from 'payload'\nimport { formatAdminURL, getSafeRedirect } from 'payload/shared'\n\nimport type { Strategy } from '../strategy/index.js'\nimport type { CollectionOptions, PluginOptions, StateObj } from '../types.js'\n\nimport { getProjectToken } from '../../api/figma-api.js'\nimport { createCookieOptions } from '../utilities/createCookieOptions.js'\nimport { createDebugLogger } from '../utilities/createDebugLogger.js'\nimport { extractOrigin } from '../utilities/extractOrigin.js'\nimport { getCookieExpiration } from '../utilities/getCookieExpiration.js'\n\ninterface Args {\n collection: CollectionConfig\n collectionOptions: CollectionOptions\n endpointSlug: string\n pluginOptions: PluginOptions\n strategy: Strategy\n}\n\nconst isAbsoluteURL = (url: string) => /^[a-z][a-z\\d+.-]*:/.test(url)\n\nexport const getLoginEndpoint = ({\n collection,\n collectionOptions,\n endpointSlug,\n pluginOptions,\n strategy,\n}: Args): Endpoint => ({\n handler: async (req) => {\n const { config } = req.payload\n const adminRoute = config.routes?.admin || '/admin'\n\n try {\n await strategy.ensureMeta()\n\n const path = req.pathname\n const debugLogger = createDebugLogger(req.payload, pluginOptions.debug)\n\n let jsonBody: Record<string, unknown> = {}\n\n const contentType = req.headers.get('content-type')\n\n // Type narrow PayloadRequst's Partial<Request>\n if (typeof req.json !== 'function' || typeof req.formData !== 'function') {\n debugLogger.info({\n msg: 'Request does not have json or formData methods',\n path,\n })\n\n return Response.redirect(`${pluginOptions.redirectServerURL || config.serverURL}/login`)\n }\n\n if (collectionOptions.authorizationURLParams?.response_mode === 'query') {\n if (Object.keys(req.query).length > 0) {\n jsonBody = req.query\n }\n } else if (contentType === 'application/json') {\n jsonBody = await req.json()\n } else if (contentType === 'application/x-www-form-urlencoded') {\n const formData = await req.formData()\n jsonBody = Object.fromEntries(formData.entries())\n }\n\n const stateRaw = jsonBody.state as string\n const state: StateObj = JSON.parse(Buffer.from(stateRaw, 'base64').toString('utf-8'))\n\n const redirectServerURL =\n state.serverURL || pluginOptions.redirectServerURL || config.serverURL\n let failedRedirect = formatAdminURL({\n adminRoute,\n path: '/login',\n serverURL: redirectServerURL,\n })\n let redirectToUse = formatAdminURL({\n adminRoute,\n serverURL: redirectServerURL,\n })\n\n if (state.redirect) {\n redirectToUse = state.redirect\n }\n\n if (state.failedRedirect) {\n failedRedirect = state.failedRedirect\n }\n\n failedRedirect = getSafeRedirect({ allowAbsoluteUrls: true, redirectTo: failedRedirect })\n redirectToUse = getSafeRedirect({ allowAbsoluteUrls: true, redirectTo: redirectToUse })\n\n if (!isAbsoluteURL(failedRedirect)) {\n return Response.json({ error: 'Invalid failed redirect provided' }, { status: 403 })\n }\n if (!isAbsoluteURL(redirectToUse)) {\n return Response.json({ error: 'Invalid redirect provided' }, { status: 403 })\n }\n\n if (Array.isArray(req.payload.config.csrf) && req.payload.config.csrf.length > 0) {\n const failedRedirectOrigin = extractOrigin(failedRedirect)\n const redirectToUseOrigin = extractOrigin(redirectToUse)\n\n if (failedRedirectOrigin && !req.payload.config.csrf.includes(failedRedirectOrigin)) {\n req.payload.logger.error(\n `Failed redirect origin ${failedRedirectOrigin} is not allowed by CSRF configuration.`,\n )\n return Response.json(\n { error: 'Failed redirect origin is not allowed by CSRF configuration.' },\n { status: 403 },\n )\n }\n\n if (redirectToUseOrigin && !req.payload.config.csrf.includes(redirectToUseOrigin)) {\n req.payload.logger.error(\n `Redirect origin ${redirectToUseOrigin} is not allowed by CSRF configuration.`,\n )\n return Response.json(\n { error: 'Redirect origin is not allowed by CSRF configuration.' },\n { status: 403 },\n )\n }\n }\n\n // Verify signature\n if (strategy.name !== req.payload.decrypt(state.sig)) {\n req.payload.logger.error('Signature mismatch. Failing login and redirecting.')\n return Response.redirect(failedRedirect)\n }\n\n if (!strategy.meta?.token_endpoint) {\n debugLogger.error({\n msg: `No metadata was obtained from the identity provider. Failing login and redirecting.`,\n path,\n })\n return Response.redirect(failedRedirect)\n }\n\n debugLogger.info({ body: jsonBody, msg: 'Received login response body', path })\n\n if (!jsonBody?.code) {\n debugLogger.error({\n msg: `No authorization code present in body. Failing login and redirecting.`,\n path,\n })\n return Response.redirect(failedRedirect)\n }\n\n // Exchange `code` from body for refresh token\n const { code } = jsonBody\n\n if (typeof code !== 'string') {\n debugLogger.error({\n msg: `Authorization code present in body is not a string. Failing login and redirecting.`,\n path,\n })\n return Response.redirect(failedRedirect)\n }\n\n const body: Record<string, string> = {\n client_id: strategy.clientID,\n code,\n code_verifier: req.payload.decrypt(state.verifier),\n grant_type: 'authorization_code',\n redirect_uri: formatAdminURL({\n apiRoute: config.routes?.api || '/api',\n path: `/${collection.slug}/${endpointSlug}/login`,\n serverURL: redirectServerURL,\n }),\n }\n\n if (strategy.collectionOptions.clientSecret) {\n body.client_secret = strategy.collectionOptions.clientSecret\n }\n\n debugLogger.info({\n msg: 'Exchanging code for access token',\n path,\n requestBody: body,\n })\n\n const tokenRes = await fetch(strategy.meta?.token_endpoint, {\n body: new URLSearchParams(body),\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n method: 'POST',\n }).then((r) => r.json())\n\n debugLogger.info({ msg: 'Token Response', path, tokenRes })\n\n const { access_token, error, error_description, expires_in: refreshTokenExpires } = tokenRes\n\n debugLogger.info({ msg: 'tokenResss', tokenRes })\n\n // Swap for project token\n const project_token = await getProjectToken(\n tokenRes.access_token,\n config.custom.figma.contentSystemId,\n )\n const refresh_token = access_token\n\n // Store project token as access_token\n\n const token = project_token.token\n const expiresIn = project_token.expiresAt\n\n if (!token) {\n const errMsg = `No ${\n collectionOptions.token || 'access_token'\n } was returned from the identity provider.`\n req.payload.logger.error({ msg: errMsg, path })\n throw new APIError(errMsg)\n }\n\n const cookieOptions = createCookieOptions({ collection, headers: req.headers, pluginOptions })\n\n if (error) {\n req.payload.logger.error('Error swapping access code with access token:')\n req.payload.logger.error({ err: error, error_description })\n return Response.redirect(failedRedirect)\n }\n\n // get the payloadRedirect cookie value\n const cookies = parseCookies(req.headers)\n\n const payloadRedirect =\n 'payloadRedirect' in cookies ? (cookies.payloadRedirect as string) : ''\n\n if (!req.responseHeaders) {\n req.responseHeaders = new Headers()\n }\n\n if (payloadRedirect) {\n if (isAbsoluteURL(payloadRedirect)) {\n redirectToUse = payloadRedirect\n } else {\n redirectToUse += payloadRedirect\n }\n\n req.responseHeaders.append(\n 'Set-Cookie',\n `payloadRedirect=${redirectToUse}; Max-Age=0; Path=/;`,\n )\n }\n\n if (refresh_token && !collectionOptions.usePayloadJWT) {\n debugLogger.info('Setting refresh token cookie')\n const refreshCookie = generateCookie({\n returnCookieAsObject: false,\n ...cookieOptions,\n name: `${strategy.cookieName}-refresh`,\n value: refresh_token,\n // Default to 1 year if no expiration\n expires: getCookieExpiration(cookieOptions?.expires ?? refreshTokenExpires ?? 31_556_952),\n }) as string\n\n req.responseHeaders.append('Set-Cookie', refreshCookie)\n }\n\n const tokenExpires = cookieOptions?.expires\n ? getCookieExpiration(cookieOptions.expires)\n : new Date(expiresIn) // Project token uses epoch time\n const tokenCookie = generateCookie({\n ...cookieOptions,\n name: strategy.cookieName,\n expires: tokenExpires,\n returnCookieAsObject: false,\n value: token,\n }) as string\n\n req.responseHeaders.append('Set-Cookie', tokenCookie)\n\n return Response.redirect(redirectToUse)\n } catch (err: unknown) {\n req.payload.logger.error({ err, msg: 'Error while attempting to login', path: req.pathname })\n\n return Response.json({ error: 'Error while attempting to login' }, { status: 500 })\n }\n },\n method: collectionOptions.authorizationURLParams?.response_mode === 'query' ? 'get' : 'post',\n path: `/${endpointSlug}/login`,\n})\n"],"names":["APIError","generateCookie","parseCookies","formatAdminURL","getSafeRedirect","getProjectToken","createCookieOptions","createDebugLogger","extractOrigin","getCookieExpiration","isAbsoluteURL","url","test","getLoginEndpoint","collection","collectionOptions","endpointSlug","pluginOptions","strategy","handler","req","config","payload","adminRoute","routes","admin","ensureMeta","path","pathname","debugLogger","debug","jsonBody","contentType","headers","get","json","formData","info","msg","Response","redirect","redirectServerURL","serverURL","authorizationURLParams","response_mode","Object","keys","query","length","fromEntries","entries","stateRaw","state","JSON","parse","Buffer","from","toString","failedRedirect","redirectToUse","allowAbsoluteUrls","redirectTo","error","status","Array","isArray","csrf","failedRedirectOrigin","redirectToUseOrigin","includes","logger","name","decrypt","sig","meta","token_endpoint","body","code","client_id","clientID","code_verifier","verifier","grant_type","redirect_uri","apiRoute","api","slug","clientSecret","client_secret","requestBody","tokenRes","fetch","URLSearchParams","method","then","r","access_token","error_description","expires_in","refreshTokenExpires","project_token","custom","figma","contentSystemId","refresh_token","token","expiresIn","expiresAt","errMsg","cookieOptions","err","cookies","payloadRedirect","responseHeaders","Headers","append","usePayloadJWT","refreshCookie","returnCookieAsObject","cookieName","value","expires","tokenExpires","Date","tokenCookie"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"getLogoutEndpoint.d.ts","sourceRoot":"","sources":["../../../src/oauth/endpoints/getLogoutEndpoint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAKzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAOhD,UAAU,IAAI;IACZ,UAAU,EAAE,gBAAgB,CAAA;IAC5B,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,aAAa,CAAA;IAC5B,QAAQ,EAAE,QAAQ,CAAA;CACnB;AAED,eAAO,MAAM,iBAAiB,2DAK3B,IAAI,KAAG,QA4ER,CAAA"}
1
+ {"version":3,"file":"getLogoutEndpoint.d.ts","sourceRoot":"","sources":["../../../src/oauth/endpoints/getLogoutEndpoint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAMzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAMhD,UAAU,IAAI;IACZ,UAAU,EAAE,gBAAgB,CAAA;IAC5B,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,aAAa,CAAA;IAC5B,QAAQ,EAAE,QAAQ,CAAA;CACnB;AAED,eAAO,MAAM,iBAAiB,2DAK3B,IAAI,KAAG,QA+ER,CAAA"}
@@ -1,9 +1,9 @@
1
1
  import jwt from 'jsonwebtoken';
2
2
  import { parseCookies } from 'payload';
3
+ import { formatAdminURL } from 'payload/shared';
3
4
  import { clearCookie } from '../utilities/clearCookie.js';
4
5
  import { createCookieOptions } from '../utilities/createCookieOptions.js';
5
6
  import { createDebugLogger } from '../utilities/createDebugLogger.js';
6
- import { getAdminPath } from '../utilities/getAdminPath.js';
7
7
  export const getLogoutEndpoint = ({ collection, endpointSlug, pluginOptions, strategy })=>({
8
8
  handler: async (req)=>{
9
9
  const debugLogger = createDebugLogger(req.payload, pluginOptions.debug);
@@ -23,12 +23,15 @@ export const getLogoutEndpoint = ({ collection, endpointSlug, pluginOptions, str
23
23
  }
24
24
  try {
25
25
  await strategy.ensureMeta();
26
- const baseRedirectDestination = pluginOptions.redirectServerURL || config.serverURL;
27
- let successfulLogoutRedirectDest = `${baseRedirectDestination}${getAdminPath(config)}`;
26
+ const redirectServerlURL = pluginOptions.redirectServerURL || config.serverURL;
27
+ let successfulLogoutRedirectDest = formatAdminURL({
28
+ adminRoute: config.routes?.admin || '/admin',
29
+ serverURL: redirectServerlURL
30
+ });
28
31
  if (typeof req.query.redirect === 'string') {
29
32
  successfulLogoutRedirectDest = req.query.redirect;
30
33
  }
31
- if (!baseRedirectDestination && !req.query.redirect) {
34
+ if (!redirectServerlURL && !req.query.redirect) {
32
35
  debugLogger.error({
33
36
  msg: 'No redirect URL provided',
34
37
  path: req.pathname
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/oauth/endpoints/getLogoutEndpoint.ts"],"sourcesContent":["import type { CollectionConfig, Endpoint } from 'payload'\n\nimport jwt from 'jsonwebtoken'\nimport { parseCookies } from 'payload'\n\nimport type { Strategy } from '../strategy/index.js'\nimport type { PluginOptions } from '../types.js'\n\nimport { clearCookie } from '../utilities/clearCookie.js'\nimport { createCookieOptions } from '../utilities/createCookieOptions.js'\nimport { createDebugLogger } from '../utilities/createDebugLogger.js'\nimport { getAdminPath } from '../utilities/getAdminPath.js'\n\ninterface Args {\n collection: CollectionConfig\n endpointSlug: string\n pluginOptions: PluginOptions\n strategy: Strategy\n}\n\nexport const getLogoutEndpoint = ({\n collection,\n endpointSlug,\n pluginOptions,\n strategy,\n}: Args): Endpoint => ({\n handler: async (req) => {\n const debugLogger = createDebugLogger(req.payload, pluginOptions.debug)\n const { config } = req.payload\n\n if (!req) {\n debugLogger.error({ msg: 'Invalid request to logout endpoint' })\n return Response.json({ error: 'Invalid request to logout endpoint' }, { status: 400 })\n }\n\n if (!req.responseHeaders) {\n req.responseHeaders = new Headers()\n }\n\n try {\n await strategy.ensureMeta()\n\n const baseRedirectDestination = pluginOptions.redirectServerURL || config.serverURL\n\n let successfulLogoutRedirectDest = `${baseRedirectDestination}${getAdminPath(config)}`\n\n if (typeof req.query.redirect === 'string') {\n successfulLogoutRedirectDest = req.query.redirect\n }\n\n if (!baseRedirectDestination && !req.query.redirect) {\n debugLogger.error({ msg: 'No redirect URL provided', path: req.pathname })\n return Response.json({ error: 'No redirect URL provided' }, { status: 400 })\n }\n\n const cookieOptions = createCookieOptions({ collection, headers: req.headers, pluginOptions })\n\n let redirectDestination = successfulLogoutRedirectDest\n if (strategy.meta?.end_session_endpoint) {\n const cookies = parseCookies(req.headers)\n\n const token = cookies.get(strategy.cookieName)\n if (!token) {\n debugLogger.error({ msg: 'Unable to parse token from cookie.' })\n return Response.json({ error: 'Unable to parse token from cookie.' }, { status: 400 })\n }\n\n const decodedToken = jwt.decode(token)\n const sid = typeof decodedToken === 'object' && decodedToken ? decodedToken.sid : undefined\n\n const body = {\n client_id: strategy.clientID,\n logout_hint: sid,\n post_logout_redirect_uri: successfulLogoutRedirectDest,\n }\n\n const qs = new URLSearchParams(body).toString()\n redirectDestination = `${strategy.meta.end_session_endpoint}?${qs}`\n }\n\n clearCookie({\n cookieName: strategy.cookieName,\n cookieOptions,\n req,\n })\n\n clearCookie({\n cookieName: `${strategy.cookieName}-refresh`,\n cookieOptions,\n req,\n })\n\n return Response.redirect(redirectDestination)\n } catch (err: unknown) {\n req.payload.logger.error({ err, msg: 'Error while attempting to logout', path: req.pathname })\n\n return Response.json({ error: 'Error while attempting to logout' }, { status: 500 })\n }\n },\n method: 'get',\n path: `/${endpointSlug}/logout`,\n})\n"],"names":["jwt","parseCookies","clearCookie","createCookieOptions","createDebugLogger","getAdminPath","getLogoutEndpoint","collection","endpointSlug","pluginOptions","strategy","handler","req","debugLogger","payload","debug","config","error","msg","Response","json","status","responseHeaders","Headers","ensureMeta","baseRedirectDestination","redirectServerURL","serverURL","successfulLogoutRedirectDest","query","redirect","path","pathname","cookieOptions","headers","redirectDestination","meta","end_session_endpoint","cookies","token","get","cookieName","decodedToken","decode","sid","undefined","body","client_id","clientID","logout_hint","post_logout_redirect_uri","qs","URLSearchParams","toString","err","logger","method"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/oauth/endpoints/getLogoutEndpoint.ts"],"sourcesContent":["import type { CollectionConfig, Endpoint } from 'payload'\n\nimport jwt from 'jsonwebtoken'\nimport { parseCookies } from 'payload'\nimport { formatAdminURL } from 'payload/shared'\n\nimport type { Strategy } from '../strategy/index.js'\nimport type { PluginOptions } from '../types.js'\n\nimport { clearCookie } from '../utilities/clearCookie.js'\nimport { createCookieOptions } from '../utilities/createCookieOptions.js'\nimport { createDebugLogger } from '../utilities/createDebugLogger.js'\n\ninterface Args {\n collection: CollectionConfig\n endpointSlug: string\n pluginOptions: PluginOptions\n strategy: Strategy\n}\n\nexport const getLogoutEndpoint = ({\n collection,\n endpointSlug,\n pluginOptions,\n strategy,\n}: Args): Endpoint => ({\n handler: async (req) => {\n const debugLogger = createDebugLogger(req.payload, pluginOptions.debug)\n const { config } = req.payload\n\n if (!req) {\n debugLogger.error({ msg: 'Invalid request to logout endpoint' })\n return Response.json({ error: 'Invalid request to logout endpoint' }, { status: 400 })\n }\n\n if (!req.responseHeaders) {\n req.responseHeaders = new Headers()\n }\n\n try {\n await strategy.ensureMeta()\n\n const redirectServerlURL = pluginOptions.redirectServerURL || config.serverURL\n\n let successfulLogoutRedirectDest = formatAdminURL({\n adminRoute: config.routes?.admin || '/admin',\n serverURL: redirectServerlURL,\n })\n\n if (typeof req.query.redirect === 'string') {\n successfulLogoutRedirectDest = req.query.redirect\n }\n\n if (!redirectServerlURL && !req.query.redirect) {\n debugLogger.error({ msg: 'No redirect URL provided', path: req.pathname })\n return Response.json({ error: 'No redirect URL provided' }, { status: 400 })\n }\n\n const cookieOptions = createCookieOptions({ collection, headers: req.headers, pluginOptions })\n\n let redirectDestination = successfulLogoutRedirectDest\n if (strategy.meta?.end_session_endpoint) {\n const cookies = parseCookies(req.headers)\n\n const token = cookies.get(strategy.cookieName)\n if (!token) {\n debugLogger.error({ msg: 'Unable to parse token from cookie.' })\n return Response.json({ error: 'Unable to parse token from cookie.' }, { status: 400 })\n }\n\n const decodedToken = jwt.decode(token)\n const sid = typeof decodedToken === 'object' && decodedToken ? decodedToken.sid : undefined\n\n const body = {\n client_id: strategy.clientID,\n logout_hint: sid,\n post_logout_redirect_uri: successfulLogoutRedirectDest,\n }\n\n const qs = new URLSearchParams(body).toString()\n redirectDestination = `${strategy.meta.end_session_endpoint}?${qs}`\n }\n\n clearCookie({\n cookieName: strategy.cookieName,\n cookieOptions,\n req,\n })\n\n clearCookie({\n cookieName: `${strategy.cookieName}-refresh`,\n cookieOptions,\n req,\n })\n\n return Response.redirect(redirectDestination)\n } catch (err: unknown) {\n req.payload.logger.error({ err, msg: 'Error while attempting to logout', path: req.pathname })\n\n return Response.json({ error: 'Error while attempting to logout' }, { status: 500 })\n }\n },\n method: 'get',\n path: `/${endpointSlug}/logout`,\n})\n"],"names":["jwt","parseCookies","formatAdminURL","clearCookie","createCookieOptions","createDebugLogger","getLogoutEndpoint","collection","endpointSlug","pluginOptions","strategy","handler","req","debugLogger","payload","debug","config","error","msg","Response","json","status","responseHeaders","Headers","ensureMeta","redirectServerlURL","redirectServerURL","serverURL","successfulLogoutRedirectDest","adminRoute","routes","admin","query","redirect","path","pathname","cookieOptions","headers","redirectDestination","meta","end_session_endpoint","cookies","token","get","cookieName","decodedToken","decode","sid","undefined","body","client_id","clientID","logout_hint","post_logout_redirect_uri","qs","URLSearchParams","toString","err","logger","method"],"mappings":"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"}
@@ -52,7 +52,7 @@ import { contentApiStorageAdapter } from '../storage-content-api/index.js';
52
52
  db = contentAPIAdapter({
53
53
  auth: {
54
54
  mode: 'tokenStore',
55
- tokenStore: getTokenStore()
55
+ tokenStore: getTokenStore(getEnvironment())
56
56
  },
57
57
  contentSystemId,
58
58
  url
@@ -74,7 +74,7 @@ import { contentApiStorageAdapter } from '../storage-content-api/index.js';
74
74
  } : {
75
75
  auth: {
76
76
  mode: 'tokenStore',
77
- tokenStore: getTokenStore()
77
+ tokenStore: getTokenStore(getEnvironment())
78
78
  },
79
79
  baseUrl: url,
80
80
  contentSystemId
@@ -137,7 +137,7 @@ import { contentApiStorageAdapter } from '../storage-content-api/index.js';
137
137
  response_mode: 'query',
138
138
  response_type: 'code'
139
139
  },
140
- clientID: process.env.FIGMA_OAUTH_CLIENT_ID || ENV_CONFIG[env].clientId,
140
+ clientID: process.env.FIGMA_OAUTH_CLIENT_ID,
141
141
  clientSecret: process.env.FIGMA_OAUTH_CLIENT_SECRET,
142
142
  identityMetadata: ENV_CONFIG[env].identityMetadata,
143
143
  scope: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/plugin/build-config.ts"],"sourcesContent":["import type { Config, SanitizedConfig } from 'payload'\n\nimport { cloudStoragePlugin } from '@payloadcms/plugin-cloud-storage'\nimport { initClientUploads } from '@payloadcms/plugin-cloud-storage/utilities'\nimport { lexicalEditor } from '@payloadcms/richtext-lexical'\nimport { buildConfig as payloadBuildConfig } from 'payload'\n\nimport type { StorageClientConfig } from '../storage-content-api/index.js'\n\nimport { getTokenStore } from '../auth/token-store.js'\nimport { ENV_CONFIG, getEnvironment } from '../constants.js'\nimport { contentAPIAdapter } from '../db-content-api/index.js'\nimport { health } from '../endpoints/health.js'\nimport { oAuth2Plugin } from '../oauth/index.js'\nimport { createStorageClient } from '../storage-content-api/client.js'\nimport { getGenerateSignedURLHandler } from '../storage-content-api/client-uploads/generateSignedURL.js'\nimport { contentApiStorageAdapter } from '../storage-content-api/index.js'\n\n/**\n * Configuration type for Payload projects on the Figma platform.\n *\n * Differences from standard Payload Config:\n * - `db`: Omitted (auto-injected by Figma platform)\n * - `secret`: Omitted (auto-injected by Figma platform)\n * - `editor`: Optional (defaults to lexicalEditor() if not provided)\n *\n * @example\n * // Minimal config\n * const config: FigmaConfig = {\n * figma: {\n * contentSystemId: process.env.FIGMA_CONTENT_SYSTEM_ID!\n * },\n * collections: [...]\n * }\n *\n * @example\n * // With custom editor\n * const config: FigmaConfig = {\n * figma: {\n * contentSystemId: process.env.FIGMA_CONTENT_SYSTEM_ID!\n * },\n * collections: [...],\n * editor: lexicalEditor({ features: [...] })\n * }\n *\n * @example\n * // Disable Content System (use custom db)\n * const config: FigmaConfig = {\n * figma: {\n * contentSystemId: process.env.FIGMA_CONTENT_SYSTEM_ID!,\n * useContentSystem: false\n * },\n * db: mongooseAdapter({ url: process.env.DATABASE_URI }),\n * collections: [...]\n * }\n */\nexport type FigmaConfig = {\n editor?: Config['editor']\n} & {\n figma: {\n contentSystemId: string\n storage?: boolean\n useContentSystem?: boolean\n }\n} & Omit<Config, 'db' | 'editor' | 'secret'> &\n Partial<Pick<Config, 'db'>>\n\n/**\n * Figma platform wrapper for Payload's buildConfig.\n * Automatically injects:\n * - Figma database adapter\n * - Secret (platform-provided)\n * - Default lexicalEditor (if no custom editor specified)\n *\n * @param config - Payload configuration (db and secret omitted, editor optional)\n * @returns Promise<SanitizedConfig> - Built Payload configuration\n */\nexport async function buildFigmaConfig(config: FigmaConfig): Promise<SanitizedConfig> {\n // Validate required environment variable\n if (!config.figma.contentSystemId) {\n throw new Error(\n 'FIGMA_CONTENT_SYSTEM_ID is required. ' +\n 'Ensure your .env file contains: FIGMA_CONTENT_SYSTEM_ID=your-content-system-id',\n )\n }\n\n const env = getEnvironment()\n const url = process.env.FIGMA_CONTENT_API_URL || ENV_CONFIG[env].contentApiUrl\n const { contentSystemId } = config.figma\n\n // Determine database adapter based on environment\n let db: Config['db']\n\n if (config.figma.useContentSystem === false) {\n db = config.db!\n } else if (process.env.FIGMA_CONTENT_API_ACCESS_KEY) {\n db = contentAPIAdapter({\n auth: { apiKey: process.env.FIGMA_CONTENT_API_ACCESS_KEY, mode: 'apiKey' },\n contentSystemId,\n url,\n })\n } else if (process.env.FIGMA_DEV_JWT === 'true') {\n db = contentAPIAdapter({\n auth: { mode: 'devJwt' },\n contentSystemId,\n url,\n })\n } else {\n db = contentAPIAdapter({\n auth: { mode: 'tokenStore', tokenStore: getTokenStore() },\n contentSystemId,\n url,\n })\n }\n\n // Build storage plugin if there are upload collections and storage is not disabled\n const uploadCollections = (config.collections || []).filter((c) => c.upload)\n let storagePlugin: ReturnType<typeof cloudStoragePlugin> | undefined\n\n if (uploadCollections.length > 0 && config.figma.storage !== false) {\n const storageConfig: StorageClientConfig = process.env.FIGMA_CONTENT_API_ACCESS_KEY\n ? { baseUrl: url, contentApiKey: process.env.FIGMA_CONTENT_API_ACCESS_KEY }\n : process.env.FIGMA_DEV_JWT === 'true'\n ? {\n auth: { mode: 'devJwt' },\n baseUrl: url,\n contentSystemId,\n }\n : {\n auth: { mode: 'tokenStore', tokenStore: getTokenStore() },\n baseUrl: url,\n contentSystemId,\n }\n\n const adapter = contentApiStorageAdapter(storageConfig)\n const storageClient = createStorageClient(storageConfig)\n\n const collectionsMap = uploadCollections.reduce(\n (acc, c) => {\n acc[c.slug] = { adapter, disableLocalStorage: true }\n return acc\n },\n {} as Record<string, { adapter: typeof adapter; disableLocalStorage: boolean }>,\n )\n\n initClientUploads({\n clientHandler: '@payloadcms/figma/client#ContentApiClientUploadHandler',\n collections: collectionsMap,\n config: config as unknown as Config,\n enabled: true,\n serverHandler: getGenerateSignedURLHandler({ client: storageClient }),\n serverHandlerPath: '/content-api-storage-signed-url',\n })\n\n storagePlugin = cloudStoragePlugin({ collections: collectionsMap })\n }\n\n // Build complete config with Figma platform defaults\n const configWithFigmaDefaults: Config = {\n ...config,\n admin: {\n // Auto-refresh tokens before expiry to prevent unexpected logouts.\n // The project token (access token) expires in ~15 minutes, so the client\n // will automatically refresh at ~14 minutes to keep the session alive.\n autoRefresh: true,\n ...config.admin,\n },\n custom: {\n figma: config.figma || {},\n },\n db,\n editor: config.editor ?? lexicalEditor(),\n endpoints: [...(config.endpoints ?? []), health],\n secret: 'MY_SECRET',\n // Add oauth to plugins if not already present\n plugins: [\n ...(config.plugins ?? []),\n ...(storagePlugin ? [storagePlugin] : []),\n oAuth2Plugin({\n collections: [\n {\n slug: 'users',\n // Use adapter because Figma app doesn't support OIDC scopes\n authorizationURLParams: {\n response_mode: 'query',\n response_type: 'code',\n },\n clientID: process.env.FIGMA_OAUTH_CLIENT_ID || ENV_CONFIG[env].clientId,\n clientSecret: process.env.FIGMA_OAUTH_CLIENT_SECRET,\n identityMetadata: ENV_CONFIG[env].identityMetadata,\n scope: ['current_user:read'],\n token: 'id_token', // Adapter creates JWT id_token from Figma user info\n usernameField: 'email',\n },\n ],\n debug: !!process.env.DEBUG,\n disabled: false,\n }),\n ],\n }\n\n // Delegate to Payload's buildConfig\n return await payloadBuildConfig(configWithFigmaDefaults)\n}\n"],"names":["cloudStoragePlugin","initClientUploads","lexicalEditor","buildConfig","payloadBuildConfig","getTokenStore","ENV_CONFIG","getEnvironment","contentAPIAdapter","health","oAuth2Plugin","createStorageClient","getGenerateSignedURLHandler","contentApiStorageAdapter","buildFigmaConfig","config","figma","contentSystemId","Error","env","url","process","FIGMA_CONTENT_API_URL","contentApiUrl","db","useContentSystem","FIGMA_CONTENT_API_ACCESS_KEY","auth","apiKey","mode","FIGMA_DEV_JWT","tokenStore","uploadCollections","collections","filter","c","upload","storagePlugin","length","storage","storageConfig","baseUrl","contentApiKey","adapter","storageClient","collectionsMap","reduce","acc","slug","disableLocalStorage","clientHandler","enabled","serverHandler","client","serverHandlerPath","configWithFigmaDefaults","admin","autoRefresh","custom","editor","endpoints","secret","plugins","authorizationURLParams","response_mode","response_type","clientID","FIGMA_OAUTH_CLIENT_ID","clientId","clientSecret","FIGMA_OAUTH_CLIENT_SECRET","identityMetadata","scope","token","usernameField","debug","DEBUG","disabled"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/plugin/build-config.ts"],"sourcesContent":["import type { Config, SanitizedConfig } from 'payload'\n\nimport { cloudStoragePlugin } from '@payloadcms/plugin-cloud-storage'\nimport { initClientUploads } from '@payloadcms/plugin-cloud-storage/utilities'\nimport { lexicalEditor } from '@payloadcms/richtext-lexical'\nimport { buildConfig as payloadBuildConfig } from 'payload'\n\nimport type { StorageClientConfig } from '../storage-content-api/index.js'\n\nimport { getTokenStore } from '../auth/token-store.js'\nimport { ENV_CONFIG, getEnvironment } from '../constants.js'\nimport { contentAPIAdapter } from '../db-content-api/index.js'\nimport { health } from '../endpoints/health.js'\nimport { oAuth2Plugin } from '../oauth/index.js'\nimport { createStorageClient } from '../storage-content-api/client.js'\nimport { getGenerateSignedURLHandler } from '../storage-content-api/client-uploads/generateSignedURL.js'\nimport { contentApiStorageAdapter } from '../storage-content-api/index.js'\n\n/**\n * Configuration type for Payload projects on the Figma platform.\n *\n * Differences from standard Payload Config:\n * - `db`: Omitted (auto-injected by Figma platform)\n * - `secret`: Omitted (auto-injected by Figma platform)\n * - `editor`: Optional (defaults to lexicalEditor() if not provided)\n *\n * @example\n * // Minimal config\n * const config: FigmaConfig = {\n * figma: {\n * contentSystemId: process.env.FIGMA_CONTENT_SYSTEM_ID!\n * },\n * collections: [...]\n * }\n *\n * @example\n * // With custom editor\n * const config: FigmaConfig = {\n * figma: {\n * contentSystemId: process.env.FIGMA_CONTENT_SYSTEM_ID!\n * },\n * collections: [...],\n * editor: lexicalEditor({ features: [...] })\n * }\n *\n * @example\n * // Disable Content System (use custom db)\n * const config: FigmaConfig = {\n * figma: {\n * contentSystemId: process.env.FIGMA_CONTENT_SYSTEM_ID!,\n * useContentSystem: false\n * },\n * db: mongooseAdapter({ url: process.env.DATABASE_URI }),\n * collections: [...]\n * }\n */\nexport type FigmaConfig = {\n editor?: Config['editor']\n} & {\n figma: {\n contentSystemId: string\n storage?: boolean\n useContentSystem?: boolean\n }\n} & Omit<Config, 'db' | 'editor' | 'secret'> &\n Partial<Pick<Config, 'db'>>\n\n/**\n * Figma platform wrapper for Payload's buildConfig.\n * Automatically injects:\n * - Figma database adapter\n * - Secret (platform-provided)\n * - Default lexicalEditor (if no custom editor specified)\n *\n * @param config - Payload configuration (db and secret omitted, editor optional)\n * @returns Promise<SanitizedConfig> - Built Payload configuration\n */\nexport async function buildFigmaConfig(config: FigmaConfig): Promise<SanitizedConfig> {\n // Validate required environment variable\n if (!config.figma.contentSystemId) {\n throw new Error(\n 'FIGMA_CONTENT_SYSTEM_ID is required. ' +\n 'Ensure your .env file contains: FIGMA_CONTENT_SYSTEM_ID=your-content-system-id',\n )\n }\n\n const env = getEnvironment()\n const url = process.env.FIGMA_CONTENT_API_URL || ENV_CONFIG[env].contentApiUrl\n const { contentSystemId } = config.figma\n\n // Determine database adapter based on environment\n let db: Config['db']\n\n if (config.figma.useContentSystem === false) {\n db = config.db!\n } else if (process.env.FIGMA_CONTENT_API_ACCESS_KEY) {\n db = contentAPIAdapter({\n auth: { apiKey: process.env.FIGMA_CONTENT_API_ACCESS_KEY, mode: 'apiKey' },\n contentSystemId,\n url,\n })\n } else if (process.env.FIGMA_DEV_JWT === 'true') {\n db = contentAPIAdapter({\n auth: { mode: 'devJwt' },\n contentSystemId,\n url,\n })\n } else {\n db = contentAPIAdapter({\n auth: { mode: 'tokenStore', tokenStore: getTokenStore(getEnvironment()) },\n contentSystemId,\n url,\n })\n }\n\n // Build storage plugin if there are upload collections and storage is not disabled\n const uploadCollections = (config.collections || []).filter((c) => c.upload)\n let storagePlugin: ReturnType<typeof cloudStoragePlugin> | undefined\n\n if (uploadCollections.length > 0 && config.figma.storage !== false) {\n const storageConfig: StorageClientConfig = process.env.FIGMA_CONTENT_API_ACCESS_KEY\n ? { baseUrl: url, contentApiKey: process.env.FIGMA_CONTENT_API_ACCESS_KEY }\n : process.env.FIGMA_DEV_JWT === 'true'\n ? {\n auth: { mode: 'devJwt' },\n baseUrl: url,\n contentSystemId,\n }\n : {\n auth: { mode: 'tokenStore', tokenStore: getTokenStore(getEnvironment()) },\n baseUrl: url,\n contentSystemId,\n }\n\n const adapter = contentApiStorageAdapter(storageConfig)\n const storageClient = createStorageClient(storageConfig)\n\n const collectionsMap = uploadCollections.reduce(\n (acc, c) => {\n acc[c.slug] = { adapter, disableLocalStorage: true }\n return acc\n },\n {} as Record<string, { adapter: typeof adapter; disableLocalStorage: boolean }>,\n )\n\n initClientUploads({\n clientHandler: '@payloadcms/figma/client#ContentApiClientUploadHandler',\n collections: collectionsMap,\n config: config as unknown as Config,\n enabled: true,\n serverHandler: getGenerateSignedURLHandler({ client: storageClient }),\n serverHandlerPath: '/content-api-storage-signed-url',\n })\n\n storagePlugin = cloudStoragePlugin({ collections: collectionsMap })\n }\n\n // Build complete config with Figma platform defaults\n const configWithFigmaDefaults: Config = {\n ...config,\n admin: {\n // Auto-refresh tokens before expiry to prevent unexpected logouts.\n // The project token (access token) expires in ~15 minutes, so the client\n // will automatically refresh at ~14 minutes to keep the session alive.\n autoRefresh: true,\n ...config.admin,\n },\n custom: {\n figma: config.figma || {},\n },\n db,\n editor: config.editor ?? lexicalEditor(),\n endpoints: [...(config.endpoints ?? []), health],\n secret: 'MY_SECRET',\n // Add oauth to plugins if not already present\n plugins: [\n ...(config.plugins ?? []),\n ...(storagePlugin ? [storagePlugin] : []),\n oAuth2Plugin({\n collections: [\n {\n slug: 'users',\n // Use adapter because Figma app doesn't support OIDC scopes\n authorizationURLParams: {\n response_mode: 'query',\n response_type: 'code',\n },\n clientID: process.env.FIGMA_OAUTH_CLIENT_ID!,\n clientSecret: process.env.FIGMA_OAUTH_CLIENT_SECRET,\n identityMetadata: ENV_CONFIG[env].identityMetadata,\n scope: ['current_user:read'],\n token: 'id_token', // Adapter creates JWT id_token from Figma user info\n usernameField: 'email',\n },\n ],\n debug: !!process.env.DEBUG,\n disabled: false,\n }),\n ],\n }\n\n // Delegate to Payload's buildConfig\n return await payloadBuildConfig(configWithFigmaDefaults)\n}\n"],"names":["cloudStoragePlugin","initClientUploads","lexicalEditor","buildConfig","payloadBuildConfig","getTokenStore","ENV_CONFIG","getEnvironment","contentAPIAdapter","health","oAuth2Plugin","createStorageClient","getGenerateSignedURLHandler","contentApiStorageAdapter","buildFigmaConfig","config","figma","contentSystemId","Error","env","url","process","FIGMA_CONTENT_API_URL","contentApiUrl","db","useContentSystem","FIGMA_CONTENT_API_ACCESS_KEY","auth","apiKey","mode","FIGMA_DEV_JWT","tokenStore","uploadCollections","collections","filter","c","upload","storagePlugin","length","storage","storageConfig","baseUrl","contentApiKey","adapter","storageClient","collectionsMap","reduce","acc","slug","disableLocalStorage","clientHandler","enabled","serverHandler","client","serverHandlerPath","configWithFigmaDefaults","admin","autoRefresh","custom","editor","endpoints","secret","plugins","authorizationURLParams","response_mode","response_type","clientID","FIGMA_OAUTH_CLIENT_ID","clientSecret","FIGMA_OAUTH_CLIENT_SECRET","identityMetadata","scope","token","usernameField","debug","DEBUG","disabled"],"mappings":"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"}
@@ -3,10 +3,11 @@
3
3
  * These are kept separate to avoid breaking changes when the main spec is regenerated.
4
4
  */
5
5
  export type UploadPaths = {
6
- '/api/v0/uploads/{filename}': {
6
+ '/api/v0/uploads/{collectionId}/{filename}': {
7
7
  delete: {
8
8
  parameters: {
9
9
  path: {
10
+ collectionId: string;
10
11
  filename: string;
11
12
  };
12
13
  };
@@ -26,6 +27,7 @@ export type UploadPaths = {
26
27
  requestBody: {
27
28
  content: {
28
29
  'application/json': {
30
+ collectionId: string;
29
31
  expiresIn: number;
30
32
  filename: string;
31
33
  };
@@ -47,6 +49,7 @@ export type UploadPaths = {
47
49
  requestBody: {
48
50
  content: {
49
51
  'application/json': {
52
+ collectionId: string;
50
53
  filename: string;
51
54
  uploadId: string;
52
55
  };
@@ -68,6 +71,7 @@ export type UploadPaths = {
68
71
  requestBody: {
69
72
  content: {
70
73
  'application/json': {
74
+ collectionId: string;
71
75
  filename: string;
72
76
  parts: Array<{
73
77
  ETag: string;
@@ -93,6 +97,7 @@ export type UploadPaths = {
93
97
  requestBody: {
94
98
  content: {
95
99
  'application/json': {
100
+ collectionId: string;
96
101
  contentType: string;
97
102
  filename: string;
98
103
  };
@@ -114,6 +119,7 @@ export type UploadPaths = {
114
119
  requestBody: {
115
120
  content: {
116
121
  'application/json': {
122
+ collectionId: string;
117
123
  expiresIn: number;
118
124
  filename: string;
119
125
  partNumbers: number[];
@@ -140,6 +146,7 @@ export type UploadPaths = {
140
146
  requestBody: {
141
147
  content: {
142
148
  'application/json': {
149
+ collectionId: string;
143
150
  contentType?: string;
144
151
  expiresIn: number;
145
152
  filename: string;
@@ -1 +1 @@
1
- {"version":3,"file":"api-types.d.ts","sourceRoot":"","sources":["../../src/storage-content-api/api-types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api-types.d.ts","sourceRoot":"","sources":["../../src/storage-content-api/api-types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/storage-content-api/api-types.ts"],"sourcesContent":["/**\n * Upload API types extracted from Content API OpenAPI spec.\n * These are kept separate to avoid breaking changes when the main spec is regenerated.\n */\n\nexport type UploadPaths = {\n '/api/v0/uploads/{filename}': {\n delete: {\n parameters: {\n path: {\n filename: string\n }\n }\n responses: {\n 200: {\n content: {\n 'application/json': { success: true }\n }\n }\n }\n }\n }\n '/api/v0/uploads/download/sign': {\n post: {\n requestBody: {\n content: {\n 'application/json': {\n expiresIn: number\n filename: string\n }\n }\n }\n responses: {\n 200: {\n content: {\n 'application/json': { url: string }\n }\n }\n }\n }\n }\n '/api/v0/uploads/multipart/abort': {\n post: {\n requestBody: {\n content: {\n 'application/json': {\n filename: string\n uploadId: string\n }\n }\n }\n responses: {\n 200: {\n content: {\n 'application/json': { success: true }\n }\n }\n }\n }\n }\n '/api/v0/uploads/multipart/complete': {\n post: {\n requestBody: {\n content: {\n 'application/json': {\n filename: string\n parts: Array<{ ETag: string; PartNumber: number }>\n uploadId: string\n }\n }\n }\n responses: {\n 200: {\n content: {\n 'application/json': { success: true }\n }\n }\n }\n }\n }\n '/api/v0/uploads/multipart/initiate': {\n post: {\n requestBody: {\n content: {\n 'application/json': {\n contentType: string\n filename: string\n }\n }\n }\n responses: {\n 200: {\n content: {\n 'application/json': { uploadId: string }\n }\n }\n }\n }\n }\n '/api/v0/uploads/multipart/parts': {\n post: {\n requestBody: {\n content: {\n 'application/json': {\n expiresIn: number\n filename: string\n partNumbers: number[]\n uploadId: string\n }\n }\n }\n responses: {\n 200: {\n content: {\n 'application/json': {\n parts: Array<{ partNumber: number; url: string }>\n }\n }\n }\n }\n }\n }\n '/api/v0/uploads/sign': {\n post: {\n requestBody: {\n content: {\n 'application/json': {\n contentType?: string\n expiresIn: number\n filename: string\n }\n }\n }\n responses: {\n 200: {\n content: {\n 'application/json': { url: string }\n }\n }\n }\n }\n }\n}\n"],"names":[],"mappings":"AAAA;;;CAGC,GAED,WAyIC"}
1
+ {"version":3,"sources":["../../src/storage-content-api/api-types.ts"],"sourcesContent":["/**\n * Upload API types extracted from Content API OpenAPI spec.\n * These are kept separate to avoid breaking changes when the main spec is regenerated.\n */\n\nexport type UploadPaths = {\n '/api/v0/uploads/{collectionId}/{filename}': {\n delete: {\n parameters: {\n path: {\n collectionId: string\n filename: string\n }\n }\n responses: {\n 200: {\n content: {\n 'application/json': { success: true }\n }\n }\n }\n }\n }\n '/api/v0/uploads/download/sign': {\n post: {\n requestBody: {\n content: {\n 'application/json': {\n collectionId: string\n expiresIn: number\n filename: string\n }\n }\n }\n responses: {\n 200: {\n content: {\n 'application/json': { url: string }\n }\n }\n }\n }\n }\n '/api/v0/uploads/multipart/abort': {\n post: {\n requestBody: {\n content: {\n 'application/json': {\n collectionId: string\n filename: string\n uploadId: string\n }\n }\n }\n responses: {\n 200: {\n content: {\n 'application/json': { success: true }\n }\n }\n }\n }\n }\n '/api/v0/uploads/multipart/complete': {\n post: {\n requestBody: {\n content: {\n 'application/json': {\n collectionId: string\n filename: string\n parts: Array<{ ETag: string; PartNumber: number }>\n uploadId: string\n }\n }\n }\n responses: {\n 200: {\n content: {\n 'application/json': { success: true }\n }\n }\n }\n }\n }\n '/api/v0/uploads/multipart/initiate': {\n post: {\n requestBody: {\n content: {\n 'application/json': {\n collectionId: string\n contentType: string\n filename: string\n }\n }\n }\n responses: {\n 200: {\n content: {\n 'application/json': { uploadId: string }\n }\n }\n }\n }\n }\n '/api/v0/uploads/multipart/parts': {\n post: {\n requestBody: {\n content: {\n 'application/json': {\n collectionId: string\n expiresIn: number\n filename: string\n partNumbers: number[]\n uploadId: string\n }\n }\n }\n responses: {\n 200: {\n content: {\n 'application/json': {\n parts: Array<{ partNumber: number; url: string }>\n }\n }\n }\n }\n }\n }\n '/api/v0/uploads/sign': {\n post: {\n requestBody: {\n content: {\n 'application/json': {\n collectionId: string\n contentType?: string\n expiresIn: number\n filename: string\n }\n }\n }\n responses: {\n 200: {\n content: {\n 'application/json': { url: string }\n }\n }\n }\n }\n }\n}\n"],"names":[],"mappings":"AAAA;;;CAGC,GAED,WAgJC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ClientUploadHandler.d.ts","sourceRoot":"","sources":["../../../src/storage-content-api/client-uploads/ClientUploadHandler.tsx"],"names":[],"mappings":"AAGA,eAAO,MAAM,6BAA6B;;;;;;;aAoBf,OAAO,aAiBhC,CAAA"}
1
+ {"version":3,"file":"ClientUploadHandler.d.ts","sourceRoot":"","sources":["../../../src/storage-content-api/client-uploads/ClientUploadHandler.tsx"],"names":[],"mappings":"AAGA,eAAO,MAAM,6BAA6B;;;;;;;aAoBf,OAAO,aAqBhC,CAAA"}