@strapi/core 5.57.0 → 5.59.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Strapi.d.ts +28 -0
- package/dist/Strapi.d.ts.map +1 -1
- package/dist/Strapi.js +5 -0
- package/dist/Strapi.js.map +1 -1
- package/dist/Strapi.mjs +5 -0
- package/dist/Strapi.mjs.map +1 -1
- package/dist/ee/entitlements.d.ts +44 -0
- package/dist/ee/entitlements.d.ts.map +1 -0
- package/dist/ee/entitlements.js +54 -0
- package/dist/ee/entitlements.js.map +1 -0
- package/dist/ee/entitlements.mjs +51 -0
- package/dist/ee/entitlements.mjs.map +1 -0
- package/dist/ee/index.d.ts +33 -0
- package/dist/ee/index.d.ts.map +1 -1
- package/dist/ee/index.js +70 -3
- package/dist/ee/index.js.map +1 -1
- package/dist/ee/index.mjs +71 -4
- package/dist/ee/index.mjs.map +1 -1
- package/dist/ee/license.d.ts +10 -0
- package/dist/ee/license.d.ts.map +1 -1
- package/dist/ee/license.js +25 -1
- package/dist/ee/license.js.map +1 -1
- package/dist/ee/license.mjs +25 -2
- package/dist/ee/license.mjs.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/loaders/apis.d.ts.map +1 -1
- package/dist/loaders/apis.js.map +1 -1
- package/dist/loaders/apis.mjs.map +1 -1
- package/dist/loaders/plugins/get-enabled-plugins.js +2 -2
- package/dist/loaders/plugins/get-enabled-plugins.js.map +1 -1
- package/dist/loaders/plugins/get-enabled-plugins.mjs +2 -2
- package/dist/loaders/plugins/get-enabled-plugins.mjs.map +1 -1
- package/dist/middlewares/cors.d.ts.map +1 -1
- package/dist/middlewares/cors.js.map +1 -1
- package/dist/middlewares/cors.mjs.map +1 -1
- package/dist/migrations/database/5.0.0-discard-drafts.js +1 -1
- package/dist/migrations/database/5.0.0-discard-drafts.js.map +1 -1
- package/dist/migrations/database/5.0.0-discard-drafts.mjs +1 -1
- package/dist/migrations/database/5.0.0-discard-drafts.mjs.map +1 -1
- package/dist/migrations/first-published-at.js +1 -1
- package/dist/migrations/first-published-at.js.map +1 -1
- package/dist/migrations/first-published-at.mjs +1 -1
- package/dist/migrations/first-published-at.mjs.map +1 -1
- package/dist/package.json.js +18 -17
- package/dist/package.json.js.map +1 -1
- package/dist/package.json.mjs +18 -17
- package/dist/package.json.mjs.map +1 -1
- package/dist/registries/controllers.d.ts.map +1 -1
- package/dist/registries/controllers.js.map +1 -1
- package/dist/registries/controllers.mjs.map +1 -1
- package/dist/services/content-source-maps.js +6 -6
- package/dist/services/content-source-maps.js.map +1 -1
- package/dist/services/content-source-maps.mjs +6 -6
- package/dist/services/content-source-maps.mjs.map +1 -1
- package/dist/services/document-service/components.d.ts +13 -11
- package/dist/services/document-service/components.d.ts.map +1 -1
- package/dist/services/document-service/components.js +115 -66
- package/dist/services/document-service/components.js.map +1 -1
- package/dist/services/document-service/components.mjs +116 -67
- package/dist/services/document-service/components.mjs.map +1 -1
- package/dist/services/document-service/events.d.ts.map +1 -1
- package/dist/services/document-service/events.js +5 -1
- package/dist/services/document-service/events.js.map +1 -1
- package/dist/services/document-service/events.mjs +5 -1
- package/dist/services/document-service/events.mjs.map +1 -1
- package/dist/services/document-service/repository.d.ts.map +1 -1
- package/dist/services/document-service/repository.js +26 -7
- package/dist/services/document-service/repository.js.map +1 -1
- package/dist/services/document-service/repository.mjs +27 -8
- package/dist/services/document-service/repository.mjs.map +1 -1
- package/dist/services/document-service/transform/data.d.ts.map +1 -1
- package/dist/services/document-service/transform/data.js.map +1 -1
- package/dist/services/document-service/transform/data.mjs.map +1 -1
- package/dist/services/document-service/transform/fields.d.ts.map +1 -1
- package/dist/services/document-service/transform/fields.js +7 -1
- package/dist/services/document-service/transform/fields.js.map +1 -1
- package/dist/services/document-service/transform/fields.mjs +7 -1
- package/dist/services/document-service/transform/fields.mjs.map +1 -1
- package/dist/services/document-service/transform/populate.d.ts.map +1 -1
- package/dist/services/document-service/transform/populate.js +8 -1
- package/dist/services/document-service/transform/populate.js.map +1 -1
- package/dist/services/document-service/transform/populate.mjs +8 -1
- package/dist/services/document-service/transform/populate.mjs.map +1 -1
- package/dist/services/document-service/transform/relations/transform/default-locale.d.ts +4 -1
- package/dist/services/document-service/transform/relations/transform/default-locale.d.ts.map +1 -1
- package/dist/services/document-service/transform/relations/transform/default-locale.js +12 -9
- package/dist/services/document-service/transform/relations/transform/default-locale.js.map +1 -1
- package/dist/services/document-service/transform/relations/transform/default-locale.mjs +12 -10
- package/dist/services/document-service/transform/relations/transform/default-locale.mjs.map +1 -1
- package/dist/services/document-service/transform/relations/utils/map-relation.d.ts.map +1 -1
- package/dist/services/document-service/transform/relations/utils/map-relation.js +10 -4
- package/dist/services/document-service/transform/relations/utils/map-relation.js.map +1 -1
- package/dist/services/document-service/transform/relations/utils/map-relation.mjs +10 -4
- package/dist/services/document-service/transform/relations/utils/map-relation.mjs.map +1 -1
- package/dist/services/document-service/utils/clone-relations.d.ts +21 -4
- package/dist/services/document-service/utils/clone-relations.d.ts.map +1 -1
- package/dist/services/document-service/utils/clone-relations.js +619 -34
- package/dist/services/document-service/utils/clone-relations.js.map +1 -1
- package/dist/services/document-service/utils/clone-relations.mjs +619 -36
- package/dist/services/document-service/utils/clone-relations.mjs.map +1 -1
- package/dist/services/document-service/utils/unidirectional-relations.d.ts +4 -2
- package/dist/services/document-service/utils/unidirectional-relations.d.ts.map +1 -1
- package/dist/services/document-service/utils/unidirectional-relations.js +1 -10
- package/dist/services/document-service/utils/unidirectional-relations.js.map +1 -1
- package/dist/services/document-service/utils/unidirectional-relations.mjs +1 -10
- package/dist/services/document-service/utils/unidirectional-relations.mjs.map +1 -1
- package/dist/services/event-hub.d.ts.map +1 -1
- package/dist/services/event-hub.js +23 -5
- package/dist/services/event-hub.js.map +1 -1
- package/dist/services/event-hub.mjs +23 -5
- package/dist/services/event-hub.mjs.map +1 -1
- package/dist/services/webhook-store.js +2 -2
- package/dist/services/webhook-store.js.map +1 -1
- package/dist/services/webhook-store.mjs +2 -2
- package/dist/services/webhook-store.mjs.map +1 -1
- package/dist/utils/detect-customizations.d.ts +31 -0
- package/dist/utils/detect-customizations.d.ts.map +1 -0
- package/dist/utils/detect-customizations.js +173 -0
- package/dist/utils/detect-customizations.js.map +1 -0
- package/dist/utils/detect-customizations.mjs +165 -0
- package/dist/utils/detect-customizations.mjs.map +1 -0
- package/dist/utils/fetch.d.ts.map +1 -1
- package/dist/utils/fetch.js +44 -8
- package/dist/utils/fetch.js.map +1 -1
- package/dist/utils/fetch.mjs +37 -8
- package/dist/utils/fetch.mjs.map +1 -1
- package/dist/utils/transform-content-types-to-models.js +5 -5
- package/dist/utils/transform-content-types-to-models.js.map +1 -1
- package/dist/utils/transform-content-types-to-models.mjs +5 -5
- package/dist/utils/transform-content-types-to-models.mjs.map +1 -1
- package/package.json +18 -17
package/dist/ee/license.js
CHANGED
|
@@ -62,6 +62,27 @@ const DEFAULT_FEATURES = {
|
|
|
62
62
|
}
|
|
63
63
|
]
|
|
64
64
|
};
|
|
65
|
+
/**
|
|
66
|
+
* Features that can appear on a plan, in the order the admin panel lists them.
|
|
67
|
+
* Used to render entitlement rows for features a plan supports but this license
|
|
68
|
+
* does not include. `cms-ai` is deliberately absent: AI usage has its own panel.
|
|
69
|
+
*/ const PLAN_FEATURE_CATALOG = {
|
|
70
|
+
bronze: [],
|
|
71
|
+
silver: [
|
|
72
|
+
'sso',
|
|
73
|
+
'cms-advanced-preview',
|
|
74
|
+
'cms-content-releases',
|
|
75
|
+
'cms-content-history'
|
|
76
|
+
],
|
|
77
|
+
gold: [
|
|
78
|
+
'sso',
|
|
79
|
+
'cms-advanced-preview',
|
|
80
|
+
'cms-content-releases',
|
|
81
|
+
'review-workflows',
|
|
82
|
+
'cms-content-history',
|
|
83
|
+
'audit-logs'
|
|
84
|
+
]
|
|
85
|
+
};
|
|
65
86
|
const LICENSE_REGISTRY_URI = 'https://license.strapi.io';
|
|
66
87
|
// Shape of a successful (200) response from the license registry.
|
|
67
88
|
const licenseSuccessSchema = z__namespace.object({
|
|
@@ -136,7 +157,9 @@ const fetchLicense = async ({ strapi }, key, projectId)=>{
|
|
|
136
157
|
}).catch(throwShouldFallbackError);
|
|
137
158
|
const contentType = response.headers.get('Content-Type');
|
|
138
159
|
if (contentType?.includes('application/json')) {
|
|
139
|
-
|
|
160
|
+
// A body that does not parse is an outage like any other malformed response, so it keeps
|
|
161
|
+
// the stored license instead of reading as a rejection.
|
|
162
|
+
const body = await response.json().catch(throwShouldFallbackError);
|
|
140
163
|
switch(response.status){
|
|
141
164
|
case 200:
|
|
142
165
|
{
|
|
@@ -162,6 +185,7 @@ const fetchLicense = async ({ strapi }, key, projectId)=>{
|
|
|
162
185
|
|
|
163
186
|
exports.LICENSE_REGISTRY_URI = LICENSE_REGISTRY_URI;
|
|
164
187
|
exports.LicenseCheckError = LicenseCheckError;
|
|
188
|
+
exports.PLAN_FEATURE_CATALOG = PLAN_FEATURE_CATALOG;
|
|
165
189
|
exports.fetchLicense = fetchLicense;
|
|
166
190
|
exports.readLicense = readLicense;
|
|
167
191
|
exports.verifyLicense = verifyLicense;
|
package/dist/ee/license.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"license.js","sources":["../../src/ee/license.ts"],"sourcesContent":["import fs from 'fs';\nimport { join, resolve } from 'path';\nimport crypto from 'crypto';\nimport * as z from 'zod/v4';\nimport type { Core } from '@strapi/types';\n\nimport { generateInstallId } from '@strapi/utils';\n\ninterface LicenseInfo {\n type: 'bronze' | 'silver' | 'gold';\n isTrial: boolean;\n expireAt?: string;\n seats?: number;\n features?: Array<{ name: string; options?: Record<string, unknown> }>;\n subscriptionId?: string;\n planPriceId?: string;\n}\n\nconst DEFAULT_FEATURES = {\n bronze: [],\n silver: [],\n gold: [\n { name: 'sso' },\n // Set a null retention duration to allow the user to override it\n // The default of 90 days is set in the audit logs service\n { name: 'audit-logs', options: { retentionDays: null } },\n { name: 'review-workflows' },\n { name: 'cms-content-releases' },\n { name: 'cms-content-history', options: { retentionDays: 99999 } },\n { name: 'cms-advanced-preview' },\n ],\n};\n\nconst LICENSE_REGISTRY_URI = 'https://license.strapi.io';\n\n// Shape of a successful (200) response from the license registry.\nconst licenseSuccessSchema = z.object({\n data: z.object({\n license: z.string(),\n }),\n});\n\n// Shape of a bad-request (400) response from the license registry.\nconst licenseErrorSchema = z.object({\n error: z.object({\n message: z.string(),\n }),\n});\n\nconst publicKey = fs.readFileSync(resolve(__dirname, '../../resources/key.pub'));\n\nclass LicenseCheckError extends Error {\n shouldFallback = false;\n\n constructor(message: string, shouldFallback = false) {\n super(message);\n\n this.shouldFallback = shouldFallback;\n }\n}\n\nconst readLicense = (directory: string) => {\n try {\n const path = join(directory, 'license.txt');\n return fs.readFileSync(path).toString();\n } catch (error) {\n if (typeof error === 'object' && error !== null && 'code' in error && error.code !== 'ENOENT') {\n throw Error('License file not readable, review its format and access rules.');\n }\n }\n};\n\nconst verifyLicense = (license: string) => {\n const [signature, base64Content] = Buffer.from(license, 'base64').toString().split('\\n');\n\n if (!signature || !base64Content) {\n throw new Error('Invalid license.');\n }\n\n const stringifiedContent = Buffer.from(base64Content, 'base64').toString();\n\n const verify = crypto.createVerify('RSA-SHA256');\n verify.update(stringifiedContent);\n verify.end();\n\n const verified = verify.verify(publicKey, signature, 'base64');\n\n if (!verified) {\n throw new Error('Invalid license.');\n }\n\n const licenseInfo: LicenseInfo = JSON.parse(stringifiedContent);\n\n if (!licenseInfo.features) {\n licenseInfo.features = DEFAULT_FEATURES[licenseInfo.type];\n }\n\n if (!licenseInfo.isTrial) {\n licenseInfo.isTrial = false;\n }\n\n Object.freeze(licenseInfo.features);\n return licenseInfo;\n};\n\nconst createShouldFallbackError = () => {\n return new LicenseCheckError('Could not proceed to the online validation of your license.', true);\n};\n\nconst throwShouldFallbackError = () => {\n throw createShouldFallbackError();\n};\n\nconst fetchLicense = async (\n { strapi }: { strapi: Core.Strapi },\n key: string,\n projectId: string\n) => {\n const { installId: installIdFromPackageJson } = strapi.config;\n\n const response = await strapi\n .fetch(`${LICENSE_REGISTRY_URI}/api/licenses/validate`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n key,\n projectId,\n deviceId: generateInstallId(projectId, installIdFromPackageJson),\n }), // NOTE: Doing nothing on the LR with the installId\n })\n .catch(throwShouldFallbackError);\n\n const contentType = response.headers.get('Content-Type');\n\n if (contentType?.includes('application/json')) {\n const body = await response.json();\n\n switch (response.status) {\n case 200: {\n const result = licenseSuccessSchema.safeParse(body);\n if (!result.success) throw createShouldFallbackError();\n return result.data.data.license;\n }\n case 400: {\n const result = licenseErrorSchema.safeParse(body);\n if (!result.success) throw createShouldFallbackError();\n throw new LicenseCheckError(result.data.error.message);\n }\n case 404:\n throw new LicenseCheckError('The license used does not exists.');\n default:\n throw createShouldFallbackError();\n }\n } else {\n throw createShouldFallbackError();\n }\n};\n\nexport { readLicense, verifyLicense, fetchLicense, LicenseCheckError, LICENSE_REGISTRY_URI };\n"],"names":["DEFAULT_FEATURES","bronze","silver","gold","name","options","retentionDays","LICENSE_REGISTRY_URI","licenseSuccessSchema","z","object","data","license","string","licenseErrorSchema","error","message","publicKey","fs","readFileSync","resolve","__dirname","LicenseCheckError","Error","shouldFallback","readLicense","directory","path","join","toString","code","verifyLicense","signature","base64Content","Buffer","from","split","stringifiedContent","verify","crypto","createVerify","update","end","verified","licenseInfo","JSON","parse","features","type","isTrial","Object","freeze","createShouldFallbackError","throwShouldFallbackError","fetchLicense","strapi","key","projectId","installId","installIdFromPackageJson","config","response","fetch","method","headers","body","stringify","deviceId","generateInstallId","catch","contentType","get","includes","json","status","result","safeParse","success"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"license.js","sources":["../../src/ee/license.ts"],"sourcesContent":["import fs from 'fs';\nimport { join, resolve } from 'path';\nimport crypto from 'crypto';\nimport * as z from 'zod/v4';\nimport type { Core } from '@strapi/types';\n\nimport { generateInstallId } from '@strapi/utils';\n\ninterface LicenseInfo {\n type: 'bronze' | 'silver' | 'gold';\n isTrial: boolean;\n expireAt?: string;\n seats?: number;\n features?: Array<{ name: string; options?: Record<string, unknown> }>;\n subscriptionId?: string;\n planPriceId?: string;\n /** End of the subscription term, epoch milliseconds. */\n // The registry sends an ISO date string; kept open to a timestamp\n renewalDate?: string | number;\n // Present on the payload at runtime; declared here so the type reflects reality.\n licenseKey?: string;\n customerId?: string;\n}\n\nconst DEFAULT_FEATURES = {\n bronze: [],\n silver: [],\n gold: [\n { name: 'sso' },\n // Set a null retention duration to allow the user to override it\n // The default of 90 days is set in the audit logs service\n { name: 'audit-logs', options: { retentionDays: null } },\n { name: 'review-workflows' },\n { name: 'cms-content-releases' },\n { name: 'cms-content-history', options: { retentionDays: 99999 } },\n { name: 'cms-advanced-preview' },\n ],\n};\n\n/**\n * Features that can appear on a plan, in the order the admin panel lists them.\n * Used to render entitlement rows for features a plan supports but this license\n * does not include. `cms-ai` is deliberately absent: AI usage has its own panel.\n */\nexport const PLAN_FEATURE_CATALOG: Record<'bronze' | 'silver' | 'gold', string[]> = {\n bronze: [],\n silver: ['sso', 'cms-advanced-preview', 'cms-content-releases', 'cms-content-history'],\n gold: [\n 'sso',\n 'cms-advanced-preview',\n 'cms-content-releases',\n 'review-workflows',\n 'cms-content-history',\n 'audit-logs',\n ],\n};\n\nconst LICENSE_REGISTRY_URI = 'https://license.strapi.io';\n\n// Shape of a successful (200) response from the license registry.\nconst licenseSuccessSchema = z.object({\n data: z.object({\n license: z.string(),\n }),\n});\n\n// Shape of a bad-request (400) response from the license registry.\nconst licenseErrorSchema = z.object({\n error: z.object({\n message: z.string(),\n }),\n});\n\nconst publicKey = fs.readFileSync(resolve(__dirname, '../../resources/key.pub'));\n\nclass LicenseCheckError extends Error {\n shouldFallback = false;\n\n constructor(message: string, shouldFallback = false) {\n super(message);\n\n this.shouldFallback = shouldFallback;\n }\n}\n\nconst readLicense = (directory: string) => {\n try {\n const path = join(directory, 'license.txt');\n return fs.readFileSync(path).toString();\n } catch (error) {\n if (typeof error === 'object' && error !== null && 'code' in error && error.code !== 'ENOENT') {\n throw Error('License file not readable, review its format and access rules.');\n }\n }\n};\n\nconst verifyLicense = (license: string) => {\n const [signature, base64Content] = Buffer.from(license, 'base64').toString().split('\\n');\n\n if (!signature || !base64Content) {\n throw new Error('Invalid license.');\n }\n\n const stringifiedContent = Buffer.from(base64Content, 'base64').toString();\n\n const verify = crypto.createVerify('RSA-SHA256');\n verify.update(stringifiedContent);\n verify.end();\n\n const verified = verify.verify(publicKey, signature, 'base64');\n\n if (!verified) {\n throw new Error('Invalid license.');\n }\n\n const licenseInfo: LicenseInfo = JSON.parse(stringifiedContent);\n\n if (!licenseInfo.features) {\n licenseInfo.features = DEFAULT_FEATURES[licenseInfo.type];\n }\n\n if (!licenseInfo.isTrial) {\n licenseInfo.isTrial = false;\n }\n\n Object.freeze(licenseInfo.features);\n return licenseInfo;\n};\n\nconst createShouldFallbackError = () => {\n return new LicenseCheckError('Could not proceed to the online validation of your license.', true);\n};\n\nconst throwShouldFallbackError = () => {\n throw createShouldFallbackError();\n};\n\nconst fetchLicense = async (\n { strapi }: { strapi: Core.Strapi },\n key: string,\n projectId: string\n) => {\n const { installId: installIdFromPackageJson } = strapi.config;\n\n const response = await strapi\n .fetch(`${LICENSE_REGISTRY_URI}/api/licenses/validate`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n key,\n projectId,\n deviceId: generateInstallId(projectId, installIdFromPackageJson),\n }), // NOTE: Doing nothing on the LR with the installId\n })\n .catch(throwShouldFallbackError);\n\n const contentType = response.headers.get('Content-Type');\n\n if (contentType?.includes('application/json')) {\n // A body that does not parse is an outage like any other malformed response, so it keeps\n // the stored license instead of reading as a rejection.\n const body = await response.json().catch(throwShouldFallbackError);\n\n switch (response.status) {\n case 200: {\n const result = licenseSuccessSchema.safeParse(body);\n if (!result.success) throw createShouldFallbackError();\n return result.data.data.license;\n }\n case 400: {\n const result = licenseErrorSchema.safeParse(body);\n if (!result.success) throw createShouldFallbackError();\n throw new LicenseCheckError(result.data.error.message);\n }\n case 404:\n throw new LicenseCheckError('The license used does not exists.');\n default:\n throw createShouldFallbackError();\n }\n } else {\n throw createShouldFallbackError();\n }\n};\n\nexport { readLicense, verifyLicense, fetchLicense, LicenseCheckError, LICENSE_REGISTRY_URI };\n"],"names":["DEFAULT_FEATURES","bronze","silver","gold","name","options","retentionDays","PLAN_FEATURE_CATALOG","LICENSE_REGISTRY_URI","licenseSuccessSchema","z","object","data","license","string","licenseErrorSchema","error","message","publicKey","fs","readFileSync","resolve","__dirname","LicenseCheckError","Error","shouldFallback","readLicense","directory","path","join","toString","code","verifyLicense","signature","base64Content","Buffer","from","split","stringifiedContent","verify","crypto","createVerify","update","end","verified","licenseInfo","JSON","parse","features","type","isTrial","Object","freeze","createShouldFallbackError","throwShouldFallbackError","fetchLicense","strapi","key","projectId","installId","installIdFromPackageJson","config","response","fetch","method","headers","body","stringify","deviceId","generateInstallId","catch","contentType","get","includes","json","status","result","safeParse","success"],"mappings":"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"}
|
package/dist/ee/license.mjs
CHANGED
|
@@ -36,6 +36,27 @@ const DEFAULT_FEATURES = {
|
|
|
36
36
|
}
|
|
37
37
|
]
|
|
38
38
|
};
|
|
39
|
+
/**
|
|
40
|
+
* Features that can appear on a plan, in the order the admin panel lists them.
|
|
41
|
+
* Used to render entitlement rows for features a plan supports but this license
|
|
42
|
+
* does not include. `cms-ai` is deliberately absent: AI usage has its own panel.
|
|
43
|
+
*/ const PLAN_FEATURE_CATALOG = {
|
|
44
|
+
bronze: [],
|
|
45
|
+
silver: [
|
|
46
|
+
'sso',
|
|
47
|
+
'cms-advanced-preview',
|
|
48
|
+
'cms-content-releases',
|
|
49
|
+
'cms-content-history'
|
|
50
|
+
],
|
|
51
|
+
gold: [
|
|
52
|
+
'sso',
|
|
53
|
+
'cms-advanced-preview',
|
|
54
|
+
'cms-content-releases',
|
|
55
|
+
'review-workflows',
|
|
56
|
+
'cms-content-history',
|
|
57
|
+
'audit-logs'
|
|
58
|
+
]
|
|
59
|
+
};
|
|
39
60
|
const LICENSE_REGISTRY_URI = 'https://license.strapi.io';
|
|
40
61
|
// Shape of a successful (200) response from the license registry.
|
|
41
62
|
const licenseSuccessSchema = z.object({
|
|
@@ -110,7 +131,9 @@ const fetchLicense = async ({ strapi }, key, projectId)=>{
|
|
|
110
131
|
}).catch(throwShouldFallbackError);
|
|
111
132
|
const contentType = response.headers.get('Content-Type');
|
|
112
133
|
if (contentType?.includes('application/json')) {
|
|
113
|
-
|
|
134
|
+
// A body that does not parse is an outage like any other malformed response, so it keeps
|
|
135
|
+
// the stored license instead of reading as a rejection.
|
|
136
|
+
const body = await response.json().catch(throwShouldFallbackError);
|
|
114
137
|
switch(response.status){
|
|
115
138
|
case 200:
|
|
116
139
|
{
|
|
@@ -134,5 +157,5 @@ const fetchLicense = async ({ strapi }, key, projectId)=>{
|
|
|
134
157
|
}
|
|
135
158
|
};
|
|
136
159
|
|
|
137
|
-
export { LICENSE_REGISTRY_URI, LicenseCheckError, fetchLicense, readLicense, verifyLicense };
|
|
160
|
+
export { LICENSE_REGISTRY_URI, LicenseCheckError, PLAN_FEATURE_CATALOG, fetchLicense, readLicense, verifyLicense };
|
|
138
161
|
//# sourceMappingURL=license.mjs.map
|
package/dist/ee/license.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"license.mjs","sources":["../../src/ee/license.ts"],"sourcesContent":["import fs from 'fs';\nimport { join, resolve } from 'path';\nimport crypto from 'crypto';\nimport * as z from 'zod/v4';\nimport type { Core } from '@strapi/types';\n\nimport { generateInstallId } from '@strapi/utils';\n\ninterface LicenseInfo {\n type: 'bronze' | 'silver' | 'gold';\n isTrial: boolean;\n expireAt?: string;\n seats?: number;\n features?: Array<{ name: string; options?: Record<string, unknown> }>;\n subscriptionId?: string;\n planPriceId?: string;\n}\n\nconst DEFAULT_FEATURES = {\n bronze: [],\n silver: [],\n gold: [\n { name: 'sso' },\n // Set a null retention duration to allow the user to override it\n // The default of 90 days is set in the audit logs service\n { name: 'audit-logs', options: { retentionDays: null } },\n { name: 'review-workflows' },\n { name: 'cms-content-releases' },\n { name: 'cms-content-history', options: { retentionDays: 99999 } },\n { name: 'cms-advanced-preview' },\n ],\n};\n\nconst LICENSE_REGISTRY_URI = 'https://license.strapi.io';\n\n// Shape of a successful (200) response from the license registry.\nconst licenseSuccessSchema = z.object({\n data: z.object({\n license: z.string(),\n }),\n});\n\n// Shape of a bad-request (400) response from the license registry.\nconst licenseErrorSchema = z.object({\n error: z.object({\n message: z.string(),\n }),\n});\n\nconst publicKey = fs.readFileSync(resolve(__dirname, '../../resources/key.pub'));\n\nclass LicenseCheckError extends Error {\n shouldFallback = false;\n\n constructor(message: string, shouldFallback = false) {\n super(message);\n\n this.shouldFallback = shouldFallback;\n }\n}\n\nconst readLicense = (directory: string) => {\n try {\n const path = join(directory, 'license.txt');\n return fs.readFileSync(path).toString();\n } catch (error) {\n if (typeof error === 'object' && error !== null && 'code' in error && error.code !== 'ENOENT') {\n throw Error('License file not readable, review its format and access rules.');\n }\n }\n};\n\nconst verifyLicense = (license: string) => {\n const [signature, base64Content] = Buffer.from(license, 'base64').toString().split('\\n');\n\n if (!signature || !base64Content) {\n throw new Error('Invalid license.');\n }\n\n const stringifiedContent = Buffer.from(base64Content, 'base64').toString();\n\n const verify = crypto.createVerify('RSA-SHA256');\n verify.update(stringifiedContent);\n verify.end();\n\n const verified = verify.verify(publicKey, signature, 'base64');\n\n if (!verified) {\n throw new Error('Invalid license.');\n }\n\n const licenseInfo: LicenseInfo = JSON.parse(stringifiedContent);\n\n if (!licenseInfo.features) {\n licenseInfo.features = DEFAULT_FEATURES[licenseInfo.type];\n }\n\n if (!licenseInfo.isTrial) {\n licenseInfo.isTrial = false;\n }\n\n Object.freeze(licenseInfo.features);\n return licenseInfo;\n};\n\nconst createShouldFallbackError = () => {\n return new LicenseCheckError('Could not proceed to the online validation of your license.', true);\n};\n\nconst throwShouldFallbackError = () => {\n throw createShouldFallbackError();\n};\n\nconst fetchLicense = async (\n { strapi }: { strapi: Core.Strapi },\n key: string,\n projectId: string\n) => {\n const { installId: installIdFromPackageJson } = strapi.config;\n\n const response = await strapi\n .fetch(`${LICENSE_REGISTRY_URI}/api/licenses/validate`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n key,\n projectId,\n deviceId: generateInstallId(projectId, installIdFromPackageJson),\n }), // NOTE: Doing nothing on the LR with the installId\n })\n .catch(throwShouldFallbackError);\n\n const contentType = response.headers.get('Content-Type');\n\n if (contentType?.includes('application/json')) {\n const body = await response.json();\n\n switch (response.status) {\n case 200: {\n const result = licenseSuccessSchema.safeParse(body);\n if (!result.success) throw createShouldFallbackError();\n return result.data.data.license;\n }\n case 400: {\n const result = licenseErrorSchema.safeParse(body);\n if (!result.success) throw createShouldFallbackError();\n throw new LicenseCheckError(result.data.error.message);\n }\n case 404:\n throw new LicenseCheckError('The license used does not exists.');\n default:\n throw createShouldFallbackError();\n }\n } else {\n throw createShouldFallbackError();\n }\n};\n\nexport { readLicense, verifyLicense, fetchLicense, LicenseCheckError, LICENSE_REGISTRY_URI };\n"],"names":["DEFAULT_FEATURES","bronze","silver","gold","name","options","retentionDays","LICENSE_REGISTRY_URI","licenseSuccessSchema","z","object","data","license","string","licenseErrorSchema","error","message","publicKey","fs","readFileSync","resolve","__dirname","LicenseCheckError","Error","shouldFallback","readLicense","directory","path","join","toString","code","verifyLicense","signature","base64Content","Buffer","from","split","stringifiedContent","verify","crypto","createVerify","update","end","verified","licenseInfo","JSON","parse","features","type","isTrial","Object","freeze","createShouldFallbackError","throwShouldFallbackError","fetchLicense","strapi","key","projectId","installId","installIdFromPackageJson","config","response","fetch","method","headers","body","stringify","deviceId","generateInstallId","catch","contentType","get","includes","json","status","result","safeParse","success"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"license.mjs","sources":["../../src/ee/license.ts"],"sourcesContent":["import fs from 'fs';\nimport { join, resolve } from 'path';\nimport crypto from 'crypto';\nimport * as z from 'zod/v4';\nimport type { Core } from '@strapi/types';\n\nimport { generateInstallId } from '@strapi/utils';\n\ninterface LicenseInfo {\n type: 'bronze' | 'silver' | 'gold';\n isTrial: boolean;\n expireAt?: string;\n seats?: number;\n features?: Array<{ name: string; options?: Record<string, unknown> }>;\n subscriptionId?: string;\n planPriceId?: string;\n /** End of the subscription term, epoch milliseconds. */\n // The registry sends an ISO date string; kept open to a timestamp\n renewalDate?: string | number;\n // Present on the payload at runtime; declared here so the type reflects reality.\n licenseKey?: string;\n customerId?: string;\n}\n\nconst DEFAULT_FEATURES = {\n bronze: [],\n silver: [],\n gold: [\n { name: 'sso' },\n // Set a null retention duration to allow the user to override it\n // The default of 90 days is set in the audit logs service\n { name: 'audit-logs', options: { retentionDays: null } },\n { name: 'review-workflows' },\n { name: 'cms-content-releases' },\n { name: 'cms-content-history', options: { retentionDays: 99999 } },\n { name: 'cms-advanced-preview' },\n ],\n};\n\n/**\n * Features that can appear on a plan, in the order the admin panel lists them.\n * Used to render entitlement rows for features a plan supports but this license\n * does not include. `cms-ai` is deliberately absent: AI usage has its own panel.\n */\nexport const PLAN_FEATURE_CATALOG: Record<'bronze' | 'silver' | 'gold', string[]> = {\n bronze: [],\n silver: ['sso', 'cms-advanced-preview', 'cms-content-releases', 'cms-content-history'],\n gold: [\n 'sso',\n 'cms-advanced-preview',\n 'cms-content-releases',\n 'review-workflows',\n 'cms-content-history',\n 'audit-logs',\n ],\n};\n\nconst LICENSE_REGISTRY_URI = 'https://license.strapi.io';\n\n// Shape of a successful (200) response from the license registry.\nconst licenseSuccessSchema = z.object({\n data: z.object({\n license: z.string(),\n }),\n});\n\n// Shape of a bad-request (400) response from the license registry.\nconst licenseErrorSchema = z.object({\n error: z.object({\n message: z.string(),\n }),\n});\n\nconst publicKey = fs.readFileSync(resolve(__dirname, '../../resources/key.pub'));\n\nclass LicenseCheckError extends Error {\n shouldFallback = false;\n\n constructor(message: string, shouldFallback = false) {\n super(message);\n\n this.shouldFallback = shouldFallback;\n }\n}\n\nconst readLicense = (directory: string) => {\n try {\n const path = join(directory, 'license.txt');\n return fs.readFileSync(path).toString();\n } catch (error) {\n if (typeof error === 'object' && error !== null && 'code' in error && error.code !== 'ENOENT') {\n throw Error('License file not readable, review its format and access rules.');\n }\n }\n};\n\nconst verifyLicense = (license: string) => {\n const [signature, base64Content] = Buffer.from(license, 'base64').toString().split('\\n');\n\n if (!signature || !base64Content) {\n throw new Error('Invalid license.');\n }\n\n const stringifiedContent = Buffer.from(base64Content, 'base64').toString();\n\n const verify = crypto.createVerify('RSA-SHA256');\n verify.update(stringifiedContent);\n verify.end();\n\n const verified = verify.verify(publicKey, signature, 'base64');\n\n if (!verified) {\n throw new Error('Invalid license.');\n }\n\n const licenseInfo: LicenseInfo = JSON.parse(stringifiedContent);\n\n if (!licenseInfo.features) {\n licenseInfo.features = DEFAULT_FEATURES[licenseInfo.type];\n }\n\n if (!licenseInfo.isTrial) {\n licenseInfo.isTrial = false;\n }\n\n Object.freeze(licenseInfo.features);\n return licenseInfo;\n};\n\nconst createShouldFallbackError = () => {\n return new LicenseCheckError('Could not proceed to the online validation of your license.', true);\n};\n\nconst throwShouldFallbackError = () => {\n throw createShouldFallbackError();\n};\n\nconst fetchLicense = async (\n { strapi }: { strapi: Core.Strapi },\n key: string,\n projectId: string\n) => {\n const { installId: installIdFromPackageJson } = strapi.config;\n\n const response = await strapi\n .fetch(`${LICENSE_REGISTRY_URI}/api/licenses/validate`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n key,\n projectId,\n deviceId: generateInstallId(projectId, installIdFromPackageJson),\n }), // NOTE: Doing nothing on the LR with the installId\n })\n .catch(throwShouldFallbackError);\n\n const contentType = response.headers.get('Content-Type');\n\n if (contentType?.includes('application/json')) {\n // A body that does not parse is an outage like any other malformed response, so it keeps\n // the stored license instead of reading as a rejection.\n const body = await response.json().catch(throwShouldFallbackError);\n\n switch (response.status) {\n case 200: {\n const result = licenseSuccessSchema.safeParse(body);\n if (!result.success) throw createShouldFallbackError();\n return result.data.data.license;\n }\n case 400: {\n const result = licenseErrorSchema.safeParse(body);\n if (!result.success) throw createShouldFallbackError();\n throw new LicenseCheckError(result.data.error.message);\n }\n case 404:\n throw new LicenseCheckError('The license used does not exists.');\n default:\n throw createShouldFallbackError();\n }\n } else {\n throw createShouldFallbackError();\n }\n};\n\nexport { readLicense, verifyLicense, fetchLicense, LicenseCheckError, LICENSE_REGISTRY_URI };\n"],"names":["DEFAULT_FEATURES","bronze","silver","gold","name","options","retentionDays","PLAN_FEATURE_CATALOG","LICENSE_REGISTRY_URI","licenseSuccessSchema","z","object","data","license","string","licenseErrorSchema","error","message","publicKey","fs","readFileSync","resolve","__dirname","LicenseCheckError","Error","shouldFallback","readLicense","directory","path","join","toString","code","verifyLicense","signature","base64Content","Buffer","from","split","stringifiedContent","verify","crypto","createVerify","update","end","verified","licenseInfo","JSON","parse","features","type","isTrial","Object","freeze","createShouldFallbackError","throwShouldFallbackError","fetchLicense","strapi","key","projectId","installId","installIdFromPackageJson","config","response","fetch","method","headers","body","stringify","deviceId","generateInstallId","catch","contentType","get","includes","json","status","result","safeParse","success"],"mappings":"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"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAe,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AAEtD,OAAO,KAAK,EACV,oCAAoC,EACpC,sCAAsC,EACvC,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,KAAK,SAAS,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,MAAM,CAAC;AAE3B,eAAO,MAAM,YAAY,GAAI,UAAS,OAAO,CAAC,aAAa,CAAM,KAAG,IAAI,CAAC,MAaxE,CAAC;AAIF,OAAO,QAAQ,KAAK,CAAC;IACnB,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;IAE/C,UAAiB,WAAW;QAC1B,WAAW,CAAC,EAAE,WAAW,CAAC;QAE1B,IAAI,KAAK,IAAI,WAAW,CAAC;QACzB,IAAI,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE;KACrB;IAED,UAAiB,WAAW;QAC1B,WAAW,CAAC,EAAE,WAAW,CAAC;QAE1B,IAAI,KAAK,IAAI,WAAW,CAAC;QACzB,IAAI,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE;KACrB;IAKD,UAAiB,+BACf,SAAQ,oCAAoC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAe,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AAEtD,OAAO,KAAK,EACV,oCAAoC,EACpC,sCAAsC,EACvC,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,KAAK,SAAS,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,MAAM,CAAC;AAE3B,eAAO,MAAM,YAAY,GAAI,UAAS,OAAO,CAAC,aAAa,CAAM,KAAG,IAAI,CAAC,MAaxE,CAAC;AAIF,OAAO,QAAQ,KAAK,CAAC;IACnB,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;IAE/C,UAAiB,WAAW;QAC1B,WAAW,CAAC,EAAE,WAAW,CAAC;QAE1B,IAAI,KAAK,IAAI,WAAW,CAAC;QACzB,IAAI,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE;KACrB;IAED,UAAiB,WAAW;QAC1B,WAAW,CAAC,EAAE,WAAW,CAAC;QAE1B,IAAI,KAAK,IAAI,WAAW,CAAC;QACzB,IAAI,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE;KACrB;IAKD,UAAiB,+BACf,SAAQ,oCAAoC,EAAE,sCAAsC;KAAG;CAC1F"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import * as qs from 'qs';\nimport type { Core } from '@strapi/types';\n\nimport Strapi, { type StrapiOptions } from './Strapi';\nimport { destroyOnSignal, resolveWorkingDirectories, createUpdateNotifier } from './utils';\nimport type {\n ContextDelegatedResponseErrorMethods,\n ContextDelegatedResponseSuccessMethods,\n} from './services/server/koa-methods';\n\nexport { default as compileStrapi } from './compile';\nexport * as factories from './factories';\nexport * as ai from './ai';\n\nexport const createStrapi = (options: Partial<StrapiOptions> = {}): Core.Strapi => {\n const strapi = new Strapi({\n ...options,\n ...resolveWorkingDirectories(options),\n });\n\n destroyOnSignal(strapi);\n createUpdateNotifier(strapi);\n\n // TODO: deprecate and remove in next major\n global.strapi = strapi;\n\n return strapi;\n};\n\n// Augment Koa query type based on Strapi query middleware\n\ndeclare module 'koa' {\n type ParsedQuery = ReturnType<typeof qs.parse>;\n\n export interface BaseRequest {\n _querycache?: ParsedQuery;\n\n get query(): ParsedQuery;\n set query(obj: any);\n }\n\n export interface BaseContext {\n _querycache?: ParsedQuery;\n\n get query(): ParsedQuery;\n set query(obj: any);\n }\n\n // Keep Koa's context and response types in sync with the helpers registered at runtime in `koa.ts`.\n // `BaseResponse` and `BaseContext` both extend `DefaultContextDelegatedResponse`, so augmenting it\n // once covers `ctx.*` and `ctx.response.*`.\n export interface DefaultContextDelegatedResponse\n extends ContextDelegatedResponseErrorMethods
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import * as qs from 'qs';\nimport type { Core } from '@strapi/types';\n\nimport Strapi, { type StrapiOptions } from './Strapi';\nimport { destroyOnSignal, resolveWorkingDirectories, createUpdateNotifier } from './utils';\nimport type {\n ContextDelegatedResponseErrorMethods,\n ContextDelegatedResponseSuccessMethods,\n} from './services/server/koa-methods';\n\nexport { default as compileStrapi } from './compile';\nexport * as factories from './factories';\nexport * as ai from './ai';\n\nexport const createStrapi = (options: Partial<StrapiOptions> = {}): Core.Strapi => {\n const strapi = new Strapi({\n ...options,\n ...resolveWorkingDirectories(options),\n });\n\n destroyOnSignal(strapi);\n createUpdateNotifier(strapi);\n\n // TODO: deprecate and remove in next major\n global.strapi = strapi;\n\n return strapi;\n};\n\n// Augment Koa query type based on Strapi query middleware\n\ndeclare module 'koa' {\n type ParsedQuery = ReturnType<typeof qs.parse>;\n\n export interface BaseRequest {\n _querycache?: ParsedQuery;\n\n get query(): ParsedQuery;\n set query(obj: any);\n }\n\n export interface BaseContext {\n _querycache?: ParsedQuery;\n\n get query(): ParsedQuery;\n set query(obj: any);\n }\n\n // Keep Koa's context and response types in sync with the helpers registered at runtime in `koa.ts`.\n // `BaseResponse` and `BaseContext` both extend `DefaultContextDelegatedResponse`, so augmenting it\n // once covers `ctx.*` and `ctx.response.*`.\n export interface DefaultContextDelegatedResponse\n extends ContextDelegatedResponseErrorMethods, ContextDelegatedResponseSuccessMethods {}\n}\n"],"names":["createStrapi","options","strapi","Strapi","resolveWorkingDirectories","destroyOnSignal","createUpdateNotifier","global"],"mappings":";;;;;;;;;;;;;;;;;;;AAcO,MAAMA,YAAAA,GAAe,CAACC,OAAAA,GAAkC,EAAE,GAAA;IAC/D,MAAMC,MAAAA,GAAS,IAAIC,MAAAA,CAAO;AACxB,QAAA,GAAGF,OAAO;AACV,QAAA,GAAGG,6CAA0BH,OAAAA;AAC/B,KAAA,CAAA;IAEAI,uBAAAA,CAAgBH,MAAAA,CAAAA;IAChBI,0BAAAA,CAAqBJ,MAAAA,CAAAA;;AAGrBK,IAAAA,MAAAA,CAAOL,MAAM,GAAGA,MAAAA;IAEhB,OAAOA,MAAAA;AACT;;;;;;;"}
|
package/dist/index.mjs
CHANGED
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import * as qs from 'qs';\nimport type { Core } from '@strapi/types';\n\nimport Strapi, { type StrapiOptions } from './Strapi';\nimport { destroyOnSignal, resolveWorkingDirectories, createUpdateNotifier } from './utils';\nimport type {\n ContextDelegatedResponseErrorMethods,\n ContextDelegatedResponseSuccessMethods,\n} from './services/server/koa-methods';\n\nexport { default as compileStrapi } from './compile';\nexport * as factories from './factories';\nexport * as ai from './ai';\n\nexport const createStrapi = (options: Partial<StrapiOptions> = {}): Core.Strapi => {\n const strapi = new Strapi({\n ...options,\n ...resolveWorkingDirectories(options),\n });\n\n destroyOnSignal(strapi);\n createUpdateNotifier(strapi);\n\n // TODO: deprecate and remove in next major\n global.strapi = strapi;\n\n return strapi;\n};\n\n// Augment Koa query type based on Strapi query middleware\n\ndeclare module 'koa' {\n type ParsedQuery = ReturnType<typeof qs.parse>;\n\n export interface BaseRequest {\n _querycache?: ParsedQuery;\n\n get query(): ParsedQuery;\n set query(obj: any);\n }\n\n export interface BaseContext {\n _querycache?: ParsedQuery;\n\n get query(): ParsedQuery;\n set query(obj: any);\n }\n\n // Keep Koa's context and response types in sync with the helpers registered at runtime in `koa.ts`.\n // `BaseResponse` and `BaseContext` both extend `DefaultContextDelegatedResponse`, so augmenting it\n // once covers `ctx.*` and `ctx.response.*`.\n export interface DefaultContextDelegatedResponse\n extends ContextDelegatedResponseErrorMethods
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import * as qs from 'qs';\nimport type { Core } from '@strapi/types';\n\nimport Strapi, { type StrapiOptions } from './Strapi';\nimport { destroyOnSignal, resolveWorkingDirectories, createUpdateNotifier } from './utils';\nimport type {\n ContextDelegatedResponseErrorMethods,\n ContextDelegatedResponseSuccessMethods,\n} from './services/server/koa-methods';\n\nexport { default as compileStrapi } from './compile';\nexport * as factories from './factories';\nexport * as ai from './ai';\n\nexport const createStrapi = (options: Partial<StrapiOptions> = {}): Core.Strapi => {\n const strapi = new Strapi({\n ...options,\n ...resolveWorkingDirectories(options),\n });\n\n destroyOnSignal(strapi);\n createUpdateNotifier(strapi);\n\n // TODO: deprecate and remove in next major\n global.strapi = strapi;\n\n return strapi;\n};\n\n// Augment Koa query type based on Strapi query middleware\n\ndeclare module 'koa' {\n type ParsedQuery = ReturnType<typeof qs.parse>;\n\n export interface BaseRequest {\n _querycache?: ParsedQuery;\n\n get query(): ParsedQuery;\n set query(obj: any);\n }\n\n export interface BaseContext {\n _querycache?: ParsedQuery;\n\n get query(): ParsedQuery;\n set query(obj: any);\n }\n\n // Keep Koa's context and response types in sync with the helpers registered at runtime in `koa.ts`.\n // `BaseResponse` and `BaseContext` both extend `DefaultContextDelegatedResponse`, so augmenting it\n // once covers `ctx.*` and `ctx.response.*`.\n export interface DefaultContextDelegatedResponse\n extends ContextDelegatedResponseErrorMethods, ContextDelegatedResponseSuccessMethods {}\n}\n"],"names":["createStrapi","options","strapi","Strapi","resolveWorkingDirectories","destroyOnSignal","createUpdateNotifier","global"],"mappings":";;;;;;;;;;;;;;;;;;;AAcO,MAAMA,YAAAA,GAAe,CAACC,OAAAA,GAAkC,EAAE,GAAA;IAC/D,MAAMC,MAAAA,GAAS,IAAIC,MAAAA,CAAO;AACxB,QAAA,GAAGF,OAAO;AACV,QAAA,GAAGG,0BAA0BH,OAAAA;AAC/B,KAAA,CAAA;IAEAI,eAAAA,CAAgBH,MAAAA,CAAAA;IAChBI,oBAAAA,CAAqBJ,MAAAA,CAAAA;;AAGrBK,IAAAA,MAAAA,CAAOL,MAAM,GAAGA,MAAAA;IAEhB,OAAOA,MAAAA;AACT;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apis.d.ts","sourceRoot":"","sources":["../../src/loaders/apis.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAU,MAAM,eAAe,CAAC;AAkClD,wBAA8B,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"apis.d.ts","sourceRoot":"","sources":["../../src/loaders/apis.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAU,MAAM,eAAe,CAAC;AAkClD,wBAA8B,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,iBA2BzD"}
|
package/dist/loaders/apis.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apis.js","sources":["../../src/loaders/apis.ts"],"sourcesContent":["import { join, extname, basename } from 'path';\nimport fse, { existsSync } from 'fs-extra';\nimport _, { isEmpty } from 'lodash';\nimport { strings, importDefault } from '@strapi/utils';\nimport type { Core, Struct } from '@strapi/types';\nimport { getGlobalId, type ContentTypeDefinition } from '../domain/content-type';\n\ninterface API {\n bootstrap: () => void | Promise<void>;\n destroy: () => void | Promise<void>;\n register: () => void | Promise<void>;\n config: Record<string, unknown>;\n routes: Record<string, Core.Router>;\n controllers: Record<string, Core.Controller>;\n services: Record<string, Core.Service>;\n policies: Record<string, Core.Policy>;\n middlewares: Record<string, Core.Middleware>;\n contentTypes: Record<string, { schema: Struct.ContentTypeSchema }>;\n}\n\ninterface APIs {\n [key: string]: API;\n}\n\nconst DEFAULT_CONTENT_TYPE = {\n schema: {},\n actions: {},\n lifecycles: {},\n};\n\n// to handle names with numbers in it we first check if it is already in kebabCase\nconst normalizeName = (name: string) => (strings.isKebabCase(name) ? name : _.kebabCase(name));\n\nconst isDirectory = (fd: fse.Dirent) => fd.isDirectory();\nconst isDotFile = (fd: fse.Dirent) => fd.name.startsWith('.');\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nexport default async function loadAPIs(strapi: Core.Strapi) {\n if (!existsSync(strapi.dirs.dist.api)) {\n return;\n }\n\n const apisFDs = await (await fse.readdir(strapi.dirs.dist.api, { withFileTypes: true }))\n .filter(isDirectory)\n .filter(_.negate(isDotFile));\n\n const apis: APIs = {};\n\n // only load folders\n for (const apiFD of apisFDs) {\n const apiName = normalizeName(apiFD.name);\n const api = await loadAPI(apiName, join(strapi.dirs.dist.api, apiFD.name));\n\n // @ts-expect-error TODO verify that it's a valid api, not missing bootstrap, register, and destroy\n apis[apiName] = api;\n }\n\n validateContentTypesUnicity(apis);\n\n for (const apiName of Object.keys(apis)) {\n strapi.get('apis').add(apiName, apis[apiName]);\n }\n}\n\nconst validateContentTypesUnicity = (apis: APIs) => {\n const allApisSchemas = Object.values(apis).flatMap((api) => Object.values(api.contentTypes));\n\n const names: string[] = [];\n allApisSchemas.forEach(({ schema }) => {\n if (schema.info.singularName) {\n const singularName = _.kebabCase(schema.info.singularName);\n if (names.includes(singularName)) {\n throw new Error(`The singular name \"${schema.info.singularName}\" should be unique`);\n }\n names.push(singularName);\n }\n\n if (schema.info.pluralName) {\n const pluralName = _.kebabCase(schema.info.pluralName);\n if (names.includes(pluralName)) {\n throw new Error(`The plural name \"${schema.info.pluralName}\" should be unique`);\n }\n names.push(pluralName);\n }\n });\n};\n\nconst loadAPI = async (apiName: string, dir: string) => {\n const [index, config, routes, controllers, services, policies, middlewares, contentTypes] = (\n await Promise.all([\n loadIndex(dir),\n loadDir(join(dir, 'config')),\n loadDir(join(dir, 'routes')),\n loadDir(join(dir, 'controllers')),\n loadDir(join(dir, 'services')),\n loadDir(join(dir, 'policies')),\n loadDir(join(dir, 'middlewares')),\n loadContentTypes(apiName, join(dir, 'content-types')),\n ])\n ).map((result) => result?.result);\n const apiIndex = isRecord(index) ? index : {};\n\n return {\n ...apiIndex,\n config: config || {},\n routes: routes || [],\n controllers: controllers || {},\n services: services || {},\n policies: policies || {},\n middlewares: middlewares || {},\n contentTypes: contentTypes || {},\n };\n};\n\nconst loadIndex = async (dir: string) => {\n if (await fse.pathExists(join(dir, 'index.js'))) {\n return loadFile(join(dir, 'index.js'));\n }\n};\n\n// because this is async and its contents are dynamic, we must return it within an object to avoid a property called `then` being interpreted as a Promise\nconst loadContentTypes = async (apiName: string, dir: string) => {\n if (!(await fse.pathExists(dir))) {\n return;\n }\n\n const fds = await fse.readdir(dir, { withFileTypes: true });\n const contentTypes: API['contentTypes'] = {};\n\n // only load folders\n for (const fd of fds) {\n if (fd.isFile()) {\n continue;\n }\n\n const contentTypeName = normalizeName(fd.name);\n const loadedContentType = (await loadDir(join(dir, fd.name)))?.result;\n\n if (isEmpty(loadedContentType) || isEmpty(loadedContentType.schema)) {\n throw new Error(`Could not load content type found at ${dir}`);\n }\n\n const contentType = {\n ...DEFAULT_CONTENT_TYPE,\n ...loadedContentType,\n } as ContentTypeDefinition;\n\n Object.assign(contentType.schema, {\n apiName,\n collectionName: contentType.schema.collectionName || contentType.schema.info.singularName,\n globalId: getGlobalId(contentType.schema),\n });\n\n contentTypes[normalizeName(contentTypeName)] = contentType;\n }\n\n return { result: contentTypes };\n};\n\n// because this is async and its contents are dynamic, we must return it within an object to avoid a property called `then` being interpreted as a Promise\nconst loadDir = async (dir: string) => {\n if (!(await fse.pathExists(dir))) {\n return;\n }\n\n const fds = await fse.readdir(dir, { withFileTypes: true });\n\n const root: Record<string, unknown> = {};\n for (const fd of fds) {\n if (!fd.isFile() || extname(fd.name) === '.map') {\n continue;\n }\n\n const key = basename(fd.name, extname(fd.name));\n\n root[normalizeName(key)] = (await loadFile(join(dir, fd.name))).result;\n }\n\n return { result: root };\n};\n\n// because this is async and its contents are dynamic, we must return it as an array to avoid a property called `then` being interpreted as a Promise\nconst loadFile = async (file: string): Promise<{ result: unknown }> => {\n const ext = extname(file);\n\n switch (ext) {\n case '.js':\n return { result: importDefault(file) };\n case '.json':\n return { result: await fse.readJSON(file) };\n default:\n return { result: {} };\n }\n};\n"],"names":["DEFAULT_CONTENT_TYPE","schema","actions","lifecycles","normalizeName","name","strings","isKebabCase","_","kebabCase","isDirectory","fd","isDotFile","startsWith","isRecord","value","Array","isArray","loadAPIs","strapi","existsSync","dirs","dist","api","apisFDs","fse","readdir","withFileTypes","filter","negate","apis","apiFD","apiName","loadAPI","join","validateContentTypesUnicity","Object","keys","get","add","allApisSchemas","values","flatMap","contentTypes","names","forEach","info","singularName","includes","Error","push","pluralName","dir","index","config","routes","controllers","services","policies","middlewares","Promise","all","loadIndex","loadDir","loadContentTypes","map","result","apiIndex","pathExists","loadFile","fds","isFile","contentTypeName","loadedContentType","isEmpty","contentType","assign","collectionName","globalId","getGlobalId","root","extname","key","basename","file","ext","importDefault","readJSON"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"apis.js","sources":["../../src/loaders/apis.ts"],"sourcesContent":["import { join, extname, basename } from 'path';\nimport fse, { existsSync } from 'fs-extra';\nimport _, { isEmpty } from 'lodash';\nimport { strings, importDefault } from '@strapi/utils';\nimport type { Core, Struct } from '@strapi/types';\nimport { getGlobalId, type ContentTypeDefinition } from '../domain/content-type';\n\ninterface API {\n bootstrap: () => void | Promise<void>;\n destroy: () => void | Promise<void>;\n register: () => void | Promise<void>;\n config: Record<string, unknown>;\n routes: Record<string, Core.Router>;\n controllers: Record<string, Core.Controller>;\n services: Record<string, Core.Service>;\n policies: Record<string, Core.Policy>;\n middlewares: Record<string, Core.Middleware>;\n contentTypes: Record<string, { schema: Struct.ContentTypeSchema }>;\n}\n\ninterface APIs {\n [key: string]: API;\n}\n\nconst DEFAULT_CONTENT_TYPE = {\n schema: {},\n actions: {},\n lifecycles: {},\n};\n\n// to handle names with numbers in it we first check if it is already in kebabCase\nconst normalizeName = (name: string) => (strings.isKebabCase(name) ? name : _.kebabCase(name));\n\nconst isDirectory = (fd: fse.Dirent) => fd.isDirectory();\nconst isDotFile = (fd: fse.Dirent) => fd.name.startsWith('.');\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nexport default async function loadAPIs(strapi: Core.Strapi) {\n if (!existsSync(strapi.dirs.dist.api)) {\n return;\n }\n\n const apisFDs = await (\n await fse.readdir(strapi.dirs.dist.api, { withFileTypes: true })\n )\n .filter(isDirectory)\n .filter(_.negate(isDotFile));\n\n const apis: APIs = {};\n\n // only load folders\n for (const apiFD of apisFDs) {\n const apiName = normalizeName(apiFD.name);\n const api = await loadAPI(apiName, join(strapi.dirs.dist.api, apiFD.name));\n\n // @ts-expect-error TODO verify that it's a valid api, not missing bootstrap, register, and destroy\n apis[apiName] = api;\n }\n\n validateContentTypesUnicity(apis);\n\n for (const apiName of Object.keys(apis)) {\n strapi.get('apis').add(apiName, apis[apiName]);\n }\n}\n\nconst validateContentTypesUnicity = (apis: APIs) => {\n const allApisSchemas = Object.values(apis).flatMap((api) => Object.values(api.contentTypes));\n\n const names: string[] = [];\n allApisSchemas.forEach(({ schema }) => {\n if (schema.info.singularName) {\n const singularName = _.kebabCase(schema.info.singularName);\n if (names.includes(singularName)) {\n throw new Error(`The singular name \"${schema.info.singularName}\" should be unique`);\n }\n names.push(singularName);\n }\n\n if (schema.info.pluralName) {\n const pluralName = _.kebabCase(schema.info.pluralName);\n if (names.includes(pluralName)) {\n throw new Error(`The plural name \"${schema.info.pluralName}\" should be unique`);\n }\n names.push(pluralName);\n }\n });\n};\n\nconst loadAPI = async (apiName: string, dir: string) => {\n const [index, config, routes, controllers, services, policies, middlewares, contentTypes] = (\n await Promise.all([\n loadIndex(dir),\n loadDir(join(dir, 'config')),\n loadDir(join(dir, 'routes')),\n loadDir(join(dir, 'controllers')),\n loadDir(join(dir, 'services')),\n loadDir(join(dir, 'policies')),\n loadDir(join(dir, 'middlewares')),\n loadContentTypes(apiName, join(dir, 'content-types')),\n ])\n ).map((result) => result?.result);\n const apiIndex = isRecord(index) ? index : {};\n\n return {\n ...apiIndex,\n config: config || {},\n routes: routes || [],\n controllers: controllers || {},\n services: services || {},\n policies: policies || {},\n middlewares: middlewares || {},\n contentTypes: contentTypes || {},\n };\n};\n\nconst loadIndex = async (dir: string) => {\n if (await fse.pathExists(join(dir, 'index.js'))) {\n return loadFile(join(dir, 'index.js'));\n }\n};\n\n// because this is async and its contents are dynamic, we must return it within an object to avoid a property called `then` being interpreted as a Promise\nconst loadContentTypes = async (apiName: string, dir: string) => {\n if (!(await fse.pathExists(dir))) {\n return;\n }\n\n const fds = await fse.readdir(dir, { withFileTypes: true });\n const contentTypes: API['contentTypes'] = {};\n\n // only load folders\n for (const fd of fds) {\n if (fd.isFile()) {\n continue;\n }\n\n const contentTypeName = normalizeName(fd.name);\n const loadedContentType = (await loadDir(join(dir, fd.name)))?.result;\n\n if (isEmpty(loadedContentType) || isEmpty(loadedContentType.schema)) {\n throw new Error(`Could not load content type found at ${dir}`);\n }\n\n const contentType = {\n ...DEFAULT_CONTENT_TYPE,\n ...loadedContentType,\n } as ContentTypeDefinition;\n\n Object.assign(contentType.schema, {\n apiName,\n collectionName: contentType.schema.collectionName || contentType.schema.info.singularName,\n globalId: getGlobalId(contentType.schema),\n });\n\n contentTypes[normalizeName(contentTypeName)] = contentType;\n }\n\n return { result: contentTypes };\n};\n\n// because this is async and its contents are dynamic, we must return it within an object to avoid a property called `then` being interpreted as a Promise\nconst loadDir = async (dir: string) => {\n if (!(await fse.pathExists(dir))) {\n return;\n }\n\n const fds = await fse.readdir(dir, { withFileTypes: true });\n\n const root: Record<string, unknown> = {};\n for (const fd of fds) {\n if (!fd.isFile() || extname(fd.name) === '.map') {\n continue;\n }\n\n const key = basename(fd.name, extname(fd.name));\n\n root[normalizeName(key)] = (await loadFile(join(dir, fd.name))).result;\n }\n\n return { result: root };\n};\n\n// because this is async and its contents are dynamic, we must return it as an array to avoid a property called `then` being interpreted as a Promise\nconst loadFile = async (file: string): Promise<{ result: unknown }> => {\n const ext = extname(file);\n\n switch (ext) {\n case '.js':\n return { result: importDefault(file) };\n case '.json':\n return { result: await fse.readJSON(file) };\n default:\n return { result: {} };\n }\n};\n"],"names":["DEFAULT_CONTENT_TYPE","schema","actions","lifecycles","normalizeName","name","strings","isKebabCase","_","kebabCase","isDirectory","fd","isDotFile","startsWith","isRecord","value","Array","isArray","loadAPIs","strapi","existsSync","dirs","dist","api","apisFDs","fse","readdir","withFileTypes","filter","negate","apis","apiFD","apiName","loadAPI","join","validateContentTypesUnicity","Object","keys","get","add","allApisSchemas","values","flatMap","contentTypes","names","forEach","info","singularName","includes","Error","push","pluralName","dir","index","config","routes","controllers","services","policies","middlewares","Promise","all","loadIndex","loadDir","loadContentTypes","map","result","apiIndex","pathExists","loadFile","fds","isFile","contentTypeName","loadedContentType","isEmpty","contentType","assign","collectionName","globalId","getGlobalId","root","extname","key","basename","file","ext","importDefault","readJSON"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apis.mjs","sources":["../../src/loaders/apis.ts"],"sourcesContent":["import { join, extname, basename } from 'path';\nimport fse, { existsSync } from 'fs-extra';\nimport _, { isEmpty } from 'lodash';\nimport { strings, importDefault } from '@strapi/utils';\nimport type { Core, Struct } from '@strapi/types';\nimport { getGlobalId, type ContentTypeDefinition } from '../domain/content-type';\n\ninterface API {\n bootstrap: () => void | Promise<void>;\n destroy: () => void | Promise<void>;\n register: () => void | Promise<void>;\n config: Record<string, unknown>;\n routes: Record<string, Core.Router>;\n controllers: Record<string, Core.Controller>;\n services: Record<string, Core.Service>;\n policies: Record<string, Core.Policy>;\n middlewares: Record<string, Core.Middleware>;\n contentTypes: Record<string, { schema: Struct.ContentTypeSchema }>;\n}\n\ninterface APIs {\n [key: string]: API;\n}\n\nconst DEFAULT_CONTENT_TYPE = {\n schema: {},\n actions: {},\n lifecycles: {},\n};\n\n// to handle names with numbers in it we first check if it is already in kebabCase\nconst normalizeName = (name: string) => (strings.isKebabCase(name) ? name : _.kebabCase(name));\n\nconst isDirectory = (fd: fse.Dirent) => fd.isDirectory();\nconst isDotFile = (fd: fse.Dirent) => fd.name.startsWith('.');\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nexport default async function loadAPIs(strapi: Core.Strapi) {\n if (!existsSync(strapi.dirs.dist.api)) {\n return;\n }\n\n const apisFDs = await (await fse.readdir(strapi.dirs.dist.api, { withFileTypes: true }))\n .filter(isDirectory)\n .filter(_.negate(isDotFile));\n\n const apis: APIs = {};\n\n // only load folders\n for (const apiFD of apisFDs) {\n const apiName = normalizeName(apiFD.name);\n const api = await loadAPI(apiName, join(strapi.dirs.dist.api, apiFD.name));\n\n // @ts-expect-error TODO verify that it's a valid api, not missing bootstrap, register, and destroy\n apis[apiName] = api;\n }\n\n validateContentTypesUnicity(apis);\n\n for (const apiName of Object.keys(apis)) {\n strapi.get('apis').add(apiName, apis[apiName]);\n }\n}\n\nconst validateContentTypesUnicity = (apis: APIs) => {\n const allApisSchemas = Object.values(apis).flatMap((api) => Object.values(api.contentTypes));\n\n const names: string[] = [];\n allApisSchemas.forEach(({ schema }) => {\n if (schema.info.singularName) {\n const singularName = _.kebabCase(schema.info.singularName);\n if (names.includes(singularName)) {\n throw new Error(`The singular name \"${schema.info.singularName}\" should be unique`);\n }\n names.push(singularName);\n }\n\n if (schema.info.pluralName) {\n const pluralName = _.kebabCase(schema.info.pluralName);\n if (names.includes(pluralName)) {\n throw new Error(`The plural name \"${schema.info.pluralName}\" should be unique`);\n }\n names.push(pluralName);\n }\n });\n};\n\nconst loadAPI = async (apiName: string, dir: string) => {\n const [index, config, routes, controllers, services, policies, middlewares, contentTypes] = (\n await Promise.all([\n loadIndex(dir),\n loadDir(join(dir, 'config')),\n loadDir(join(dir, 'routes')),\n loadDir(join(dir, 'controllers')),\n loadDir(join(dir, 'services')),\n loadDir(join(dir, 'policies')),\n loadDir(join(dir, 'middlewares')),\n loadContentTypes(apiName, join(dir, 'content-types')),\n ])\n ).map((result) => result?.result);\n const apiIndex = isRecord(index) ? index : {};\n\n return {\n ...apiIndex,\n config: config || {},\n routes: routes || [],\n controllers: controllers || {},\n services: services || {},\n policies: policies || {},\n middlewares: middlewares || {},\n contentTypes: contentTypes || {},\n };\n};\n\nconst loadIndex = async (dir: string) => {\n if (await fse.pathExists(join(dir, 'index.js'))) {\n return loadFile(join(dir, 'index.js'));\n }\n};\n\n// because this is async and its contents are dynamic, we must return it within an object to avoid a property called `then` being interpreted as a Promise\nconst loadContentTypes = async (apiName: string, dir: string) => {\n if (!(await fse.pathExists(dir))) {\n return;\n }\n\n const fds = await fse.readdir(dir, { withFileTypes: true });\n const contentTypes: API['contentTypes'] = {};\n\n // only load folders\n for (const fd of fds) {\n if (fd.isFile()) {\n continue;\n }\n\n const contentTypeName = normalizeName(fd.name);\n const loadedContentType = (await loadDir(join(dir, fd.name)))?.result;\n\n if (isEmpty(loadedContentType) || isEmpty(loadedContentType.schema)) {\n throw new Error(`Could not load content type found at ${dir}`);\n }\n\n const contentType = {\n ...DEFAULT_CONTENT_TYPE,\n ...loadedContentType,\n } as ContentTypeDefinition;\n\n Object.assign(contentType.schema, {\n apiName,\n collectionName: contentType.schema.collectionName || contentType.schema.info.singularName,\n globalId: getGlobalId(contentType.schema),\n });\n\n contentTypes[normalizeName(contentTypeName)] = contentType;\n }\n\n return { result: contentTypes };\n};\n\n// because this is async and its contents are dynamic, we must return it within an object to avoid a property called `then` being interpreted as a Promise\nconst loadDir = async (dir: string) => {\n if (!(await fse.pathExists(dir))) {\n return;\n }\n\n const fds = await fse.readdir(dir, { withFileTypes: true });\n\n const root: Record<string, unknown> = {};\n for (const fd of fds) {\n if (!fd.isFile() || extname(fd.name) === '.map') {\n continue;\n }\n\n const key = basename(fd.name, extname(fd.name));\n\n root[normalizeName(key)] = (await loadFile(join(dir, fd.name))).result;\n }\n\n return { result: root };\n};\n\n// because this is async and its contents are dynamic, we must return it as an array to avoid a property called `then` being interpreted as a Promise\nconst loadFile = async (file: string): Promise<{ result: unknown }> => {\n const ext = extname(file);\n\n switch (ext) {\n case '.js':\n return { result: importDefault(file) };\n case '.json':\n return { result: await fse.readJSON(file) };\n default:\n return { result: {} };\n }\n};\n"],"names":["DEFAULT_CONTENT_TYPE","schema","actions","lifecycles","normalizeName","name","strings","isKebabCase","_","kebabCase","isDirectory","fd","isDotFile","startsWith","isRecord","value","Array","isArray","loadAPIs","strapi","existsSync","dirs","dist","api","apisFDs","fse","readdir","withFileTypes","filter","negate","apis","apiFD","apiName","loadAPI","join","validateContentTypesUnicity","Object","keys","get","add","allApisSchemas","values","flatMap","contentTypes","names","forEach","info","singularName","includes","Error","push","pluralName","dir","index","config","routes","controllers","services","policies","middlewares","Promise","all","loadIndex","loadDir","loadContentTypes","map","result","apiIndex","pathExists","loadFile","fds","isFile","contentTypeName","loadedContentType","isEmpty","contentType","assign","collectionName","globalId","getGlobalId","root","extname","key","basename","file","ext","importDefault","readJSON"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"apis.mjs","sources":["../../src/loaders/apis.ts"],"sourcesContent":["import { join, extname, basename } from 'path';\nimport fse, { existsSync } from 'fs-extra';\nimport _, { isEmpty } from 'lodash';\nimport { strings, importDefault } from '@strapi/utils';\nimport type { Core, Struct } from '@strapi/types';\nimport { getGlobalId, type ContentTypeDefinition } from '../domain/content-type';\n\ninterface API {\n bootstrap: () => void | Promise<void>;\n destroy: () => void | Promise<void>;\n register: () => void | Promise<void>;\n config: Record<string, unknown>;\n routes: Record<string, Core.Router>;\n controllers: Record<string, Core.Controller>;\n services: Record<string, Core.Service>;\n policies: Record<string, Core.Policy>;\n middlewares: Record<string, Core.Middleware>;\n contentTypes: Record<string, { schema: Struct.ContentTypeSchema }>;\n}\n\ninterface APIs {\n [key: string]: API;\n}\n\nconst DEFAULT_CONTENT_TYPE = {\n schema: {},\n actions: {},\n lifecycles: {},\n};\n\n// to handle names with numbers in it we first check if it is already in kebabCase\nconst normalizeName = (name: string) => (strings.isKebabCase(name) ? name : _.kebabCase(name));\n\nconst isDirectory = (fd: fse.Dirent) => fd.isDirectory();\nconst isDotFile = (fd: fse.Dirent) => fd.name.startsWith('.');\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nexport default async function loadAPIs(strapi: Core.Strapi) {\n if (!existsSync(strapi.dirs.dist.api)) {\n return;\n }\n\n const apisFDs = await (\n await fse.readdir(strapi.dirs.dist.api, { withFileTypes: true })\n )\n .filter(isDirectory)\n .filter(_.negate(isDotFile));\n\n const apis: APIs = {};\n\n // only load folders\n for (const apiFD of apisFDs) {\n const apiName = normalizeName(apiFD.name);\n const api = await loadAPI(apiName, join(strapi.dirs.dist.api, apiFD.name));\n\n // @ts-expect-error TODO verify that it's a valid api, not missing bootstrap, register, and destroy\n apis[apiName] = api;\n }\n\n validateContentTypesUnicity(apis);\n\n for (const apiName of Object.keys(apis)) {\n strapi.get('apis').add(apiName, apis[apiName]);\n }\n}\n\nconst validateContentTypesUnicity = (apis: APIs) => {\n const allApisSchemas = Object.values(apis).flatMap((api) => Object.values(api.contentTypes));\n\n const names: string[] = [];\n allApisSchemas.forEach(({ schema }) => {\n if (schema.info.singularName) {\n const singularName = _.kebabCase(schema.info.singularName);\n if (names.includes(singularName)) {\n throw new Error(`The singular name \"${schema.info.singularName}\" should be unique`);\n }\n names.push(singularName);\n }\n\n if (schema.info.pluralName) {\n const pluralName = _.kebabCase(schema.info.pluralName);\n if (names.includes(pluralName)) {\n throw new Error(`The plural name \"${schema.info.pluralName}\" should be unique`);\n }\n names.push(pluralName);\n }\n });\n};\n\nconst loadAPI = async (apiName: string, dir: string) => {\n const [index, config, routes, controllers, services, policies, middlewares, contentTypes] = (\n await Promise.all([\n loadIndex(dir),\n loadDir(join(dir, 'config')),\n loadDir(join(dir, 'routes')),\n loadDir(join(dir, 'controllers')),\n loadDir(join(dir, 'services')),\n loadDir(join(dir, 'policies')),\n loadDir(join(dir, 'middlewares')),\n loadContentTypes(apiName, join(dir, 'content-types')),\n ])\n ).map((result) => result?.result);\n const apiIndex = isRecord(index) ? index : {};\n\n return {\n ...apiIndex,\n config: config || {},\n routes: routes || [],\n controllers: controllers || {},\n services: services || {},\n policies: policies || {},\n middlewares: middlewares || {},\n contentTypes: contentTypes || {},\n };\n};\n\nconst loadIndex = async (dir: string) => {\n if (await fse.pathExists(join(dir, 'index.js'))) {\n return loadFile(join(dir, 'index.js'));\n }\n};\n\n// because this is async and its contents are dynamic, we must return it within an object to avoid a property called `then` being interpreted as a Promise\nconst loadContentTypes = async (apiName: string, dir: string) => {\n if (!(await fse.pathExists(dir))) {\n return;\n }\n\n const fds = await fse.readdir(dir, { withFileTypes: true });\n const contentTypes: API['contentTypes'] = {};\n\n // only load folders\n for (const fd of fds) {\n if (fd.isFile()) {\n continue;\n }\n\n const contentTypeName = normalizeName(fd.name);\n const loadedContentType = (await loadDir(join(dir, fd.name)))?.result;\n\n if (isEmpty(loadedContentType) || isEmpty(loadedContentType.schema)) {\n throw new Error(`Could not load content type found at ${dir}`);\n }\n\n const contentType = {\n ...DEFAULT_CONTENT_TYPE,\n ...loadedContentType,\n } as ContentTypeDefinition;\n\n Object.assign(contentType.schema, {\n apiName,\n collectionName: contentType.schema.collectionName || contentType.schema.info.singularName,\n globalId: getGlobalId(contentType.schema),\n });\n\n contentTypes[normalizeName(contentTypeName)] = contentType;\n }\n\n return { result: contentTypes };\n};\n\n// because this is async and its contents are dynamic, we must return it within an object to avoid a property called `then` being interpreted as a Promise\nconst loadDir = async (dir: string) => {\n if (!(await fse.pathExists(dir))) {\n return;\n }\n\n const fds = await fse.readdir(dir, { withFileTypes: true });\n\n const root: Record<string, unknown> = {};\n for (const fd of fds) {\n if (!fd.isFile() || extname(fd.name) === '.map') {\n continue;\n }\n\n const key = basename(fd.name, extname(fd.name));\n\n root[normalizeName(key)] = (await loadFile(join(dir, fd.name))).result;\n }\n\n return { result: root };\n};\n\n// because this is async and its contents are dynamic, we must return it as an array to avoid a property called `then` being interpreted as a Promise\nconst loadFile = async (file: string): Promise<{ result: unknown }> => {\n const ext = extname(file);\n\n switch (ext) {\n case '.js':\n return { result: importDefault(file) };\n case '.json':\n return { result: await fse.readJSON(file) };\n default:\n return { result: {} };\n }\n};\n"],"names":["DEFAULT_CONTENT_TYPE","schema","actions","lifecycles","normalizeName","name","strings","isKebabCase","_","kebabCase","isDirectory","fd","isDotFile","startsWith","isRecord","value","Array","isArray","loadAPIs","strapi","existsSync","dirs","dist","api","apisFDs","fse","readdir","withFileTypes","filter","negate","apis","apiFD","apiName","loadAPI","join","validateContentTypesUnicity","Object","keys","get","add","allApisSchemas","values","flatMap","contentTypes","names","forEach","info","singularName","includes","Error","push","pluralName","dir","index","config","routes","controllers","services","policies","middlewares","Promise","all","loadIndex","loadDir","loadContentTypes","map","result","apiIndex","pathExists","loadFile","fds","isFile","contentTypeName","loadedContentType","isEmpty","contentType","assign","collectionName","globalId","getGlobalId","root","extname","key","basename","file","ext","importDefault","readJSON"],"mappings":"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"}
|
|
@@ -125,8 +125,8 @@ const getEnabledPlugins = async (strapi1, { client } = {
|
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
|
-
const declaredPluginsResolves = Object.values(declaredPlugins).map((plugin)=>plugin.pathToPlugin);
|
|
129
|
-
const installedPluginsNotAlreadyUsed = _.pickBy(installedPlugins, (p)=>!declaredPluginsResolves.
|
|
128
|
+
const declaredPluginsResolves = new Set(Object.values(declaredPlugins).map((plugin)=>plugin.pathToPlugin));
|
|
129
|
+
const installedPluginsNotAlreadyUsed = _.pickBy(installedPlugins, (p)=>!declaredPluginsResolves.has(p.pathToPlugin));
|
|
130
130
|
const allPlugins = _.defaultsDeep({}, internalPlugins, declaredPlugins, installedPluginsNotAlreadyUsed);
|
|
131
131
|
const enabledPlugins = _.pickBy(allPlugins, (plugin)=>plugin.enabled);
|
|
132
132
|
return enabledPlugins;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-enabled-plugins.js","sources":["../../../src/loaders/plugins/get-enabled-plugins.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-var-requires */\nimport { dirname, join, resolve } from 'path';\nimport { statSync, existsSync } from 'fs';\nimport { defaultsDeep, get, pickBy } from 'lodash';\nimport { strings } from '@strapi/utils';\nimport type { Core } from '@strapi/types';\nimport { getUserPluginsConfig, PluginDeclaration } from './get-user-plugins-config';\n\ninterface PluginMeta {\n enabled: boolean;\n pathToPlugin?: string;\n info: Record<string, unknown>;\n packageInfo?: Record<string, unknown>;\n}\n\ntype PluginMetas = Record<string, PluginMeta>;\n\ninterface PluginInfo {\n name: string;\n kind: string;\n}\n\n/**\n * otherwise known as \"core features\"\n *\n * NOTE: These are excluded from the content manager plugin list, as they are always enabled.\n * See admin.ts server controller on the content-manager plugin for more details.\n */\nconst INTERNAL_PLUGINS = [\n '@strapi/content-manager',\n '@strapi/content-type-builder',\n '@strapi/email',\n '@strapi/upload',\n '@strapi/i18n',\n '@strapi/content-releases',\n '@strapi/review-workflows',\n];\n\nconst isStrapiPlugin = (info: PluginInfo) => get(info, 'strapi.kind') === 'plugin';\n\nconst validatePluginName = (pluginName: string) => {\n if (!strings.isKebabCase(pluginName)) {\n throw new Error(`Plugin name \"${pluginName}\" is not in kebab (an-example-of-kebab-case)`);\n }\n};\n\nconst toDetailedDeclaration = (declaration: boolean | PluginDeclaration) => {\n if (typeof declaration === 'boolean') {\n return { enabled: declaration };\n }\n\n const detailedDeclaration: { enabled: boolean; pathToPlugin?: string } = {\n enabled: declaration.enabled,\n };\n\n if (declaration?.resolve) {\n let pathToPlugin = '';\n\n if (declaration.isModule) {\n /**\n * we only want the node_module here, not the package.json\n */\n pathToPlugin = join(declaration.resolve, '..');\n } else {\n try {\n pathToPlugin = dirname(require.resolve(declaration.resolve));\n } catch {\n pathToPlugin = resolve(strapi.dirs.app.root, declaration.resolve);\n\n if (!existsSync(pathToPlugin) || !statSync(pathToPlugin).isDirectory()) {\n throw new Error(`${declaration.resolve} couldn't be resolved`);\n }\n }\n }\n\n detailedDeclaration.pathToPlugin = pathToPlugin;\n }\n\n return detailedDeclaration;\n};\n\nexport const getEnabledPlugins = async (strapi: Core.Strapi, { client } = { client: false }) => {\n const internalPlugins: PluginMetas = {};\n\n for (const dep of INTERNAL_PLUGINS) {\n const packagePath = join(dep, 'package.json');\n\n // NOTE: internal plugins should be resolved from the strapi package\n const packageModulePath = require.resolve(packagePath, {\n paths: [require.resolve('@strapi/strapi/package.json'), process.cwd()],\n });\n\n const packageInfo = require(packageModulePath);\n\n validatePluginName(packageInfo.strapi.name);\n internalPlugins[packageInfo.strapi.name] = {\n ...toDetailedDeclaration({ enabled: true, resolve: packageModulePath, isModule: client }),\n info: packageInfo.strapi,\n packageInfo,\n };\n }\n\n const installedPlugins: PluginMetas = {};\n const dependencies = strapi.config.get('info.dependencies', {});\n\n for (const dep of Object.keys(dependencies)) {\n const packagePath = join(dep, 'package.json');\n let packageInfo;\n try {\n packageInfo = require(packagePath);\n } catch {\n continue;\n }\n\n if (isStrapiPlugin(packageInfo)) {\n validatePluginName(packageInfo.strapi.name);\n installedPlugins[packageInfo.strapi.name] = {\n ...toDetailedDeclaration({ enabled: true, resolve: packagePath, isModule: client }),\n info: {\n ...packageInfo.strapi,\n packageName: packageInfo.name,\n },\n packageInfo,\n };\n }\n }\n\n const declaredPlugins: PluginMetas = {};\n const userPluginsConfig = await getUserPluginsConfig();\n\n for (const [pluginName, declaration] of Object.entries(userPluginsConfig)) {\n validatePluginName(pluginName);\n\n declaredPlugins[pluginName] = {\n ...toDetailedDeclaration(declaration),\n info: {},\n };\n\n const { pathToPlugin } = declaredPlugins[pluginName];\n\n // for manually resolved plugins\n if (pathToPlugin) {\n const packagePath = join(pathToPlugin, 'package.json');\n const packageInfo = require(packagePath);\n\n if (isStrapiPlugin(packageInfo)) {\n declaredPlugins[pluginName].info = packageInfo.strapi || {};\n declaredPlugins[pluginName].packageInfo = packageInfo;\n }\n }\n }\n\n const declaredPluginsResolves = Object.values(declaredPlugins).map(\n (plugin) => plugin.pathToPlugin\n );\n const installedPluginsNotAlreadyUsed = pickBy(\n installedPlugins,\n (p) => !declaredPluginsResolves.includes(p.pathToPlugin)\n );\n\n const allPlugins = defaultsDeep(\n {},\n internalPlugins,\n declaredPlugins,\n installedPluginsNotAlreadyUsed\n );\n const enabledPlugins = pickBy(allPlugins, (plugin: PluginMeta) => plugin.enabled);\n\n return enabledPlugins;\n};\n"],"names":["INTERNAL_PLUGINS","isStrapiPlugin","info","get","validatePluginName","pluginName","strings","isKebabCase","Error","toDetailedDeclaration","declaration","enabled","detailedDeclaration","resolve","pathToPlugin","isModule","join","dirname","require","strapi","dirs","app","root","existsSync","statSync","isDirectory","getEnabledPlugins","client","internalPlugins","dep","packagePath","packageModulePath","paths","process","cwd","packageInfo","name","installedPlugins","dependencies","config","Object","keys","packageName","declaredPlugins","userPluginsConfig","getUserPluginsConfig","entries","declaredPluginsResolves","values","map","plugin","installedPluginsNotAlreadyUsed","pickBy","p","includes","allPlugins","defaultsDeep","enabledPlugins"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"get-enabled-plugins.js","sources":["../../../src/loaders/plugins/get-enabled-plugins.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-var-requires */\nimport { dirname, join, resolve } from 'path';\nimport { statSync, existsSync } from 'fs';\nimport { defaultsDeep, get, pickBy } from 'lodash';\nimport { strings } from '@strapi/utils';\nimport type { Core } from '@strapi/types';\nimport { getUserPluginsConfig, PluginDeclaration } from './get-user-plugins-config';\n\ninterface PluginMeta {\n enabled: boolean;\n pathToPlugin?: string;\n info: Record<string, unknown>;\n packageInfo?: Record<string, unknown>;\n}\n\ntype PluginMetas = Record<string, PluginMeta>;\n\ninterface PluginInfo {\n name: string;\n kind: string;\n}\n\n/**\n * otherwise known as \"core features\"\n *\n * NOTE: These are excluded from the content manager plugin list, as they are always enabled.\n * See admin.ts server controller on the content-manager plugin for more details.\n */\nconst INTERNAL_PLUGINS = [\n '@strapi/content-manager',\n '@strapi/content-type-builder',\n '@strapi/email',\n '@strapi/upload',\n '@strapi/i18n',\n '@strapi/content-releases',\n '@strapi/review-workflows',\n];\n\nconst isStrapiPlugin = (info: PluginInfo) => get(info, 'strapi.kind') === 'plugin';\n\nconst validatePluginName = (pluginName: string) => {\n if (!strings.isKebabCase(pluginName)) {\n throw new Error(`Plugin name \"${pluginName}\" is not in kebab (an-example-of-kebab-case)`);\n }\n};\n\nconst toDetailedDeclaration = (declaration: boolean | PluginDeclaration) => {\n if (typeof declaration === 'boolean') {\n return { enabled: declaration };\n }\n\n const detailedDeclaration: { enabled: boolean; pathToPlugin?: string } = {\n enabled: declaration.enabled,\n };\n\n if (declaration?.resolve) {\n let pathToPlugin = '';\n\n if (declaration.isModule) {\n /**\n * we only want the node_module here, not the package.json\n */\n pathToPlugin = join(declaration.resolve, '..');\n } else {\n try {\n pathToPlugin = dirname(require.resolve(declaration.resolve));\n } catch {\n pathToPlugin = resolve(strapi.dirs.app.root, declaration.resolve);\n\n if (!existsSync(pathToPlugin) || !statSync(pathToPlugin).isDirectory()) {\n throw new Error(`${declaration.resolve} couldn't be resolved`);\n }\n }\n }\n\n detailedDeclaration.pathToPlugin = pathToPlugin;\n }\n\n return detailedDeclaration;\n};\n\nexport const getEnabledPlugins = async (strapi: Core.Strapi, { client } = { client: false }) => {\n const internalPlugins: PluginMetas = {};\n\n for (const dep of INTERNAL_PLUGINS) {\n const packagePath = join(dep, 'package.json');\n\n // NOTE: internal plugins should be resolved from the strapi package\n const packageModulePath = require.resolve(packagePath, {\n paths: [require.resolve('@strapi/strapi/package.json'), process.cwd()],\n });\n\n const packageInfo = require(packageModulePath);\n\n validatePluginName(packageInfo.strapi.name);\n internalPlugins[packageInfo.strapi.name] = {\n ...toDetailedDeclaration({ enabled: true, resolve: packageModulePath, isModule: client }),\n info: packageInfo.strapi,\n packageInfo,\n };\n }\n\n const installedPlugins: PluginMetas = {};\n const dependencies = strapi.config.get('info.dependencies', {});\n\n for (const dep of Object.keys(dependencies)) {\n const packagePath = join(dep, 'package.json');\n let packageInfo;\n try {\n packageInfo = require(packagePath);\n } catch {\n continue;\n }\n\n if (isStrapiPlugin(packageInfo)) {\n validatePluginName(packageInfo.strapi.name);\n installedPlugins[packageInfo.strapi.name] = {\n ...toDetailedDeclaration({ enabled: true, resolve: packagePath, isModule: client }),\n info: {\n ...packageInfo.strapi,\n packageName: packageInfo.name,\n },\n packageInfo,\n };\n }\n }\n\n const declaredPlugins: PluginMetas = {};\n const userPluginsConfig = await getUserPluginsConfig();\n\n for (const [pluginName, declaration] of Object.entries(userPluginsConfig)) {\n validatePluginName(pluginName);\n\n declaredPlugins[pluginName] = {\n ...toDetailedDeclaration(declaration),\n info: {},\n };\n\n const { pathToPlugin } = declaredPlugins[pluginName];\n\n // for manually resolved plugins\n if (pathToPlugin) {\n const packagePath = join(pathToPlugin, 'package.json');\n const packageInfo = require(packagePath);\n\n if (isStrapiPlugin(packageInfo)) {\n declaredPlugins[pluginName].info = packageInfo.strapi || {};\n declaredPlugins[pluginName].packageInfo = packageInfo;\n }\n }\n }\n\n const declaredPluginsResolves = new Set(\n Object.values(declaredPlugins).map((plugin) => plugin.pathToPlugin)\n );\n const installedPluginsNotAlreadyUsed = pickBy(\n installedPlugins,\n (p) => !declaredPluginsResolves.has(p.pathToPlugin)\n );\n\n const allPlugins = defaultsDeep(\n {},\n internalPlugins,\n declaredPlugins,\n installedPluginsNotAlreadyUsed\n );\n const enabledPlugins = pickBy(allPlugins, (plugin: PluginMeta) => plugin.enabled);\n\n return enabledPlugins;\n};\n"],"names":["INTERNAL_PLUGINS","isStrapiPlugin","info","get","validatePluginName","pluginName","strings","isKebabCase","Error","toDetailedDeclaration","declaration","enabled","detailedDeclaration","resolve","pathToPlugin","isModule","join","dirname","require","strapi","dirs","app","root","existsSync","statSync","isDirectory","getEnabledPlugins","client","internalPlugins","dep","packagePath","packageModulePath","paths","process","cwd","packageInfo","name","installedPlugins","dependencies","config","Object","keys","packageName","declaredPlugins","userPluginsConfig","getUserPluginsConfig","entries","declaredPluginsResolves","Set","values","map","plugin","installedPluginsNotAlreadyUsed","pickBy","p","has","allPlugins","defaultsDeep","enabledPlugins"],"mappings":"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"}
|
|
@@ -123,8 +123,8 @@ const getEnabledPlugins = async (strapi1, { client } = {
|
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
|
-
const declaredPluginsResolves = Object.values(declaredPlugins).map((plugin)=>plugin.pathToPlugin);
|
|
127
|
-
const installedPluginsNotAlreadyUsed = pickBy(installedPlugins, (p)=>!declaredPluginsResolves.
|
|
126
|
+
const declaredPluginsResolves = new Set(Object.values(declaredPlugins).map((plugin)=>plugin.pathToPlugin));
|
|
127
|
+
const installedPluginsNotAlreadyUsed = pickBy(installedPlugins, (p)=>!declaredPluginsResolves.has(p.pathToPlugin));
|
|
128
128
|
const allPlugins = defaultsDeep({}, internalPlugins, declaredPlugins, installedPluginsNotAlreadyUsed);
|
|
129
129
|
const enabledPlugins = pickBy(allPlugins, (plugin)=>plugin.enabled);
|
|
130
130
|
return enabledPlugins;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-enabled-plugins.mjs","sources":["../../../src/loaders/plugins/get-enabled-plugins.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-var-requires */\nimport { dirname, join, resolve } from 'path';\nimport { statSync, existsSync } from 'fs';\nimport { defaultsDeep, get, pickBy } from 'lodash';\nimport { strings } from '@strapi/utils';\nimport type { Core } from '@strapi/types';\nimport { getUserPluginsConfig, PluginDeclaration } from './get-user-plugins-config';\n\ninterface PluginMeta {\n enabled: boolean;\n pathToPlugin?: string;\n info: Record<string, unknown>;\n packageInfo?: Record<string, unknown>;\n}\n\ntype PluginMetas = Record<string, PluginMeta>;\n\ninterface PluginInfo {\n name: string;\n kind: string;\n}\n\n/**\n * otherwise known as \"core features\"\n *\n * NOTE: These are excluded from the content manager plugin list, as they are always enabled.\n * See admin.ts server controller on the content-manager plugin for more details.\n */\nconst INTERNAL_PLUGINS = [\n '@strapi/content-manager',\n '@strapi/content-type-builder',\n '@strapi/email',\n '@strapi/upload',\n '@strapi/i18n',\n '@strapi/content-releases',\n '@strapi/review-workflows',\n];\n\nconst isStrapiPlugin = (info: PluginInfo) => get(info, 'strapi.kind') === 'plugin';\n\nconst validatePluginName = (pluginName: string) => {\n if (!strings.isKebabCase(pluginName)) {\n throw new Error(`Plugin name \"${pluginName}\" is not in kebab (an-example-of-kebab-case)`);\n }\n};\n\nconst toDetailedDeclaration = (declaration: boolean | PluginDeclaration) => {\n if (typeof declaration === 'boolean') {\n return { enabled: declaration };\n }\n\n const detailedDeclaration: { enabled: boolean; pathToPlugin?: string } = {\n enabled: declaration.enabled,\n };\n\n if (declaration?.resolve) {\n let pathToPlugin = '';\n\n if (declaration.isModule) {\n /**\n * we only want the node_module here, not the package.json\n */\n pathToPlugin = join(declaration.resolve, '..');\n } else {\n try {\n pathToPlugin = dirname(require.resolve(declaration.resolve));\n } catch {\n pathToPlugin = resolve(strapi.dirs.app.root, declaration.resolve);\n\n if (!existsSync(pathToPlugin) || !statSync(pathToPlugin).isDirectory()) {\n throw new Error(`${declaration.resolve} couldn't be resolved`);\n }\n }\n }\n\n detailedDeclaration.pathToPlugin = pathToPlugin;\n }\n\n return detailedDeclaration;\n};\n\nexport const getEnabledPlugins = async (strapi: Core.Strapi, { client } = { client: false }) => {\n const internalPlugins: PluginMetas = {};\n\n for (const dep of INTERNAL_PLUGINS) {\n const packagePath = join(dep, 'package.json');\n\n // NOTE: internal plugins should be resolved from the strapi package\n const packageModulePath = require.resolve(packagePath, {\n paths: [require.resolve('@strapi/strapi/package.json'), process.cwd()],\n });\n\n const packageInfo = require(packageModulePath);\n\n validatePluginName(packageInfo.strapi.name);\n internalPlugins[packageInfo.strapi.name] = {\n ...toDetailedDeclaration({ enabled: true, resolve: packageModulePath, isModule: client }),\n info: packageInfo.strapi,\n packageInfo,\n };\n }\n\n const installedPlugins: PluginMetas = {};\n const dependencies = strapi.config.get('info.dependencies', {});\n\n for (const dep of Object.keys(dependencies)) {\n const packagePath = join(dep, 'package.json');\n let packageInfo;\n try {\n packageInfo = require(packagePath);\n } catch {\n continue;\n }\n\n if (isStrapiPlugin(packageInfo)) {\n validatePluginName(packageInfo.strapi.name);\n installedPlugins[packageInfo.strapi.name] = {\n ...toDetailedDeclaration({ enabled: true, resolve: packagePath, isModule: client }),\n info: {\n ...packageInfo.strapi,\n packageName: packageInfo.name,\n },\n packageInfo,\n };\n }\n }\n\n const declaredPlugins: PluginMetas = {};\n const userPluginsConfig = await getUserPluginsConfig();\n\n for (const [pluginName, declaration] of Object.entries(userPluginsConfig)) {\n validatePluginName(pluginName);\n\n declaredPlugins[pluginName] = {\n ...toDetailedDeclaration(declaration),\n info: {},\n };\n\n const { pathToPlugin } = declaredPlugins[pluginName];\n\n // for manually resolved plugins\n if (pathToPlugin) {\n const packagePath = join(pathToPlugin, 'package.json');\n const packageInfo = require(packagePath);\n\n if (isStrapiPlugin(packageInfo)) {\n declaredPlugins[pluginName].info = packageInfo.strapi || {};\n declaredPlugins[pluginName].packageInfo = packageInfo;\n }\n }\n }\n\n const declaredPluginsResolves = Object.values(declaredPlugins).map(\n (plugin) => plugin.pathToPlugin\n );\n const installedPluginsNotAlreadyUsed = pickBy(\n installedPlugins,\n (p) => !declaredPluginsResolves.includes(p.pathToPlugin)\n );\n\n const allPlugins = defaultsDeep(\n {},\n internalPlugins,\n declaredPlugins,\n installedPluginsNotAlreadyUsed\n );\n const enabledPlugins = pickBy(allPlugins, (plugin: PluginMeta) => plugin.enabled);\n\n return enabledPlugins;\n};\n"],"names":["INTERNAL_PLUGINS","isStrapiPlugin","info","get","validatePluginName","pluginName","strings","isKebabCase","Error","toDetailedDeclaration","declaration","enabled","detailedDeclaration","resolve","pathToPlugin","isModule","join","dirname","require","strapi","dirs","app","root","existsSync","statSync","isDirectory","getEnabledPlugins","client","internalPlugins","dep","packagePath","packageModulePath","paths","process","cwd","packageInfo","name","installedPlugins","dependencies","config","Object","keys","packageName","declaredPlugins","userPluginsConfig","getUserPluginsConfig","entries","declaredPluginsResolves","values","map","plugin","installedPluginsNotAlreadyUsed","pickBy","p","includes","allPlugins","defaultsDeep","enabledPlugins"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"get-enabled-plugins.mjs","sources":["../../../src/loaders/plugins/get-enabled-plugins.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-var-requires */\nimport { dirname, join, resolve } from 'path';\nimport { statSync, existsSync } from 'fs';\nimport { defaultsDeep, get, pickBy } from 'lodash';\nimport { strings } from '@strapi/utils';\nimport type { Core } from '@strapi/types';\nimport { getUserPluginsConfig, PluginDeclaration } from './get-user-plugins-config';\n\ninterface PluginMeta {\n enabled: boolean;\n pathToPlugin?: string;\n info: Record<string, unknown>;\n packageInfo?: Record<string, unknown>;\n}\n\ntype PluginMetas = Record<string, PluginMeta>;\n\ninterface PluginInfo {\n name: string;\n kind: string;\n}\n\n/**\n * otherwise known as \"core features\"\n *\n * NOTE: These are excluded from the content manager plugin list, as they are always enabled.\n * See admin.ts server controller on the content-manager plugin for more details.\n */\nconst INTERNAL_PLUGINS = [\n '@strapi/content-manager',\n '@strapi/content-type-builder',\n '@strapi/email',\n '@strapi/upload',\n '@strapi/i18n',\n '@strapi/content-releases',\n '@strapi/review-workflows',\n];\n\nconst isStrapiPlugin = (info: PluginInfo) => get(info, 'strapi.kind') === 'plugin';\n\nconst validatePluginName = (pluginName: string) => {\n if (!strings.isKebabCase(pluginName)) {\n throw new Error(`Plugin name \"${pluginName}\" is not in kebab (an-example-of-kebab-case)`);\n }\n};\n\nconst toDetailedDeclaration = (declaration: boolean | PluginDeclaration) => {\n if (typeof declaration === 'boolean') {\n return { enabled: declaration };\n }\n\n const detailedDeclaration: { enabled: boolean; pathToPlugin?: string } = {\n enabled: declaration.enabled,\n };\n\n if (declaration?.resolve) {\n let pathToPlugin = '';\n\n if (declaration.isModule) {\n /**\n * we only want the node_module here, not the package.json\n */\n pathToPlugin = join(declaration.resolve, '..');\n } else {\n try {\n pathToPlugin = dirname(require.resolve(declaration.resolve));\n } catch {\n pathToPlugin = resolve(strapi.dirs.app.root, declaration.resolve);\n\n if (!existsSync(pathToPlugin) || !statSync(pathToPlugin).isDirectory()) {\n throw new Error(`${declaration.resolve} couldn't be resolved`);\n }\n }\n }\n\n detailedDeclaration.pathToPlugin = pathToPlugin;\n }\n\n return detailedDeclaration;\n};\n\nexport const getEnabledPlugins = async (strapi: Core.Strapi, { client } = { client: false }) => {\n const internalPlugins: PluginMetas = {};\n\n for (const dep of INTERNAL_PLUGINS) {\n const packagePath = join(dep, 'package.json');\n\n // NOTE: internal plugins should be resolved from the strapi package\n const packageModulePath = require.resolve(packagePath, {\n paths: [require.resolve('@strapi/strapi/package.json'), process.cwd()],\n });\n\n const packageInfo = require(packageModulePath);\n\n validatePluginName(packageInfo.strapi.name);\n internalPlugins[packageInfo.strapi.name] = {\n ...toDetailedDeclaration({ enabled: true, resolve: packageModulePath, isModule: client }),\n info: packageInfo.strapi,\n packageInfo,\n };\n }\n\n const installedPlugins: PluginMetas = {};\n const dependencies = strapi.config.get('info.dependencies', {});\n\n for (const dep of Object.keys(dependencies)) {\n const packagePath = join(dep, 'package.json');\n let packageInfo;\n try {\n packageInfo = require(packagePath);\n } catch {\n continue;\n }\n\n if (isStrapiPlugin(packageInfo)) {\n validatePluginName(packageInfo.strapi.name);\n installedPlugins[packageInfo.strapi.name] = {\n ...toDetailedDeclaration({ enabled: true, resolve: packagePath, isModule: client }),\n info: {\n ...packageInfo.strapi,\n packageName: packageInfo.name,\n },\n packageInfo,\n };\n }\n }\n\n const declaredPlugins: PluginMetas = {};\n const userPluginsConfig = await getUserPluginsConfig();\n\n for (const [pluginName, declaration] of Object.entries(userPluginsConfig)) {\n validatePluginName(pluginName);\n\n declaredPlugins[pluginName] = {\n ...toDetailedDeclaration(declaration),\n info: {},\n };\n\n const { pathToPlugin } = declaredPlugins[pluginName];\n\n // for manually resolved plugins\n if (pathToPlugin) {\n const packagePath = join(pathToPlugin, 'package.json');\n const packageInfo = require(packagePath);\n\n if (isStrapiPlugin(packageInfo)) {\n declaredPlugins[pluginName].info = packageInfo.strapi || {};\n declaredPlugins[pluginName].packageInfo = packageInfo;\n }\n }\n }\n\n const declaredPluginsResolves = new Set(\n Object.values(declaredPlugins).map((plugin) => plugin.pathToPlugin)\n );\n const installedPluginsNotAlreadyUsed = pickBy(\n installedPlugins,\n (p) => !declaredPluginsResolves.has(p.pathToPlugin)\n );\n\n const allPlugins = defaultsDeep(\n {},\n internalPlugins,\n declaredPlugins,\n installedPluginsNotAlreadyUsed\n );\n const enabledPlugins = pickBy(allPlugins, (plugin: PluginMeta) => plugin.enabled);\n\n return enabledPlugins;\n};\n"],"names":["INTERNAL_PLUGINS","isStrapiPlugin","info","get","validatePluginName","pluginName","strings","isKebabCase","Error","toDetailedDeclaration","declaration","enabled","detailedDeclaration","resolve","pathToPlugin","isModule","join","dirname","require","strapi","dirs","app","root","existsSync","statSync","isDirectory","getEnabledPlugins","client","internalPlugins","dep","packagePath","packageModulePath","paths","process","cwd","packageInfo","name","installedPlugins","dependencies","config","Object","keys","packageName","declaredPlugins","userPluginsConfig","getUserPluginsConfig","entries","declaredPluginsResolves","Set","values","map","plugin","installedPluginsNotAlreadyUsed","pickBy","p","has","allPlugins","defaultsDeep","enabledPlugins"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../src/middlewares/cors.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,MAAM,MAAM,MAAM,GAAG;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC;IAC3F,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAWF;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,GACtB,eAAe,MAAM,GAAG,SAAS,EACjC,
|
|
1
|
+
{"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../src/middlewares/cors.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,MAAM,MAAM,MAAM,GAAG;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC;IAC3F,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAWF;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,GACtB,eAAe,MAAM,GAAG,SAAS,EACjC,kBACE,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC,EACpF,MAAM,GAAG,KACR,OAAO,CAAC,MAAM,CAgChB,CAAC;AAEF,eAAO,MAAM,IAAI,EAAE,IAAI,CAAC,iBAAiB,CAAC,MAAM,CA0B/C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cors.js","sources":["../../src/middlewares/cors.ts"],"sourcesContent":["import koaCors from '@koa/cors';\n\nimport type { Core } from '@strapi/types';\n\nexport type Config = {\n enabled?: boolean;\n origin: string | string[] | ((ctx: any) => string | string[] | Promise<string | string[]>);\n expose?: string | string[];\n maxAge?: number;\n credentials?: boolean;\n methods?: string | string[];\n headers?: string | string[];\n keepHeadersOnError?: boolean;\n};\n\nconst defaults: Config = {\n origin: '*',\n maxAge: 31536000,\n credentials: true,\n methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],\n headers: ['Content-Type', 'Authorization', 'Origin', 'Accept'],\n keepHeadersOnError: false,\n};\n\n/**\n * Determines if a request origin is allowed based on the configured origin list\n * @param requestOrigin - The origin from the request header\n * @param configuredOrigin - The origin configuration (string, array, or function)\n * @param ctx - The Koa context (for function-based origin)\n * @returns The allowed origin string or empty string if blocked\n */\nexport const matchOrigin = async (\n requestOrigin: string | undefined,\n configuredOrigin:\n
|
|
1
|
+
{"version":3,"file":"cors.js","sources":["../../src/middlewares/cors.ts"],"sourcesContent":["import koaCors from '@koa/cors';\n\nimport type { Core } from '@strapi/types';\n\nexport type Config = {\n enabled?: boolean;\n origin: string | string[] | ((ctx: any) => string | string[] | Promise<string | string[]>);\n expose?: string | string[];\n maxAge?: number;\n credentials?: boolean;\n methods?: string | string[];\n headers?: string | string[];\n keepHeadersOnError?: boolean;\n};\n\nconst defaults: Config = {\n origin: '*',\n maxAge: 31536000,\n credentials: true,\n methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],\n headers: ['Content-Type', 'Authorization', 'Origin', 'Accept'],\n keepHeadersOnError: false,\n};\n\n/**\n * Determines if a request origin is allowed based on the configured origin list\n * @param requestOrigin - The origin from the request header\n * @param configuredOrigin - The origin configuration (string, array, or function)\n * @param ctx - The Koa context (for function-based origin)\n * @returns The allowed origin string or empty string if blocked\n */\nexport const matchOrigin = async (\n requestOrigin: string | undefined,\n configuredOrigin:\n string | string[] | ((ctx: any) => string | string[] | Promise<string | string[]>),\n ctx?: any\n): Promise<string> => {\n if (!requestOrigin) {\n return '*';\n }\n\n let originList: string | string[];\n\n if (typeof configuredOrigin === 'function') {\n originList = await configuredOrigin(ctx);\n } else {\n originList = configuredOrigin;\n }\n\n // Normalize originList into an array\n let normalizedOrigins: string[];\n if (Array.isArray(originList)) {\n normalizedOrigins = originList;\n } else if (originList === undefined || originList === null) {\n // Handle undefined/null - treat as wildcard\n normalizedOrigins = ['*'];\n } else {\n // Handle comma-separated string of origins\n normalizedOrigins = originList.split(',').map((origin) => origin.trim());\n }\n\n // Check if wildcard is in the normalized origins\n if (normalizedOrigins.includes('*')) {\n return requestOrigin;\n }\n\n // Check if request origin is in the normalized origins\n return normalizedOrigins.includes(requestOrigin) ? requestOrigin : '';\n};\n\nexport const cors: Core.MiddlewareFactory<Config> = (config) => {\n const { origin, expose, maxAge, credentials, methods, headers, keepHeadersOnError } = {\n ...defaults,\n ...config,\n };\n\n if (config.enabled !== undefined) {\n strapi.log.warn(\n 'The strapi::cors middleware no longer supports the `enabled` option. Using it' +\n ' to conditionally enable CORS might cause an insecure default. To disable strapi::cors, remove it from' +\n ' the exported array in config/middleware.js'\n );\n }\n\n return koaCors({\n async origin(ctx) {\n const requestOrigin = ctx.get('Origin');\n return matchOrigin(requestOrigin, origin, ctx);\n },\n exposeHeaders: expose,\n maxAge,\n credentials,\n allowMethods: methods,\n allowHeaders: headers,\n keepHeadersOnError,\n });\n};\n"],"names":["defaults","origin","maxAge","credentials","methods","headers","keepHeadersOnError","matchOrigin","requestOrigin","configuredOrigin","ctx","originList","normalizedOrigins","Array","isArray","undefined","split","map","trim","includes","cors","config","expose","enabled","strapi","log","warn","koaCors","get","exposeHeaders","allowMethods","allowHeaders"],"mappings":";;;;;;;;AAeA,MAAMA,QAAAA,GAAmB;IACvBC,MAAAA,EAAQ,GAAA;IACRC,MAAAA,EAAQ,QAAA;IACRC,WAAAA,EAAa,IAAA;IACbC,OAAAA,EAAS;AAAC,QAAA,KAAA;AAAO,QAAA,MAAA;AAAQ,QAAA,KAAA;AAAO,QAAA,OAAA;AAAS,QAAA,QAAA;AAAU,QAAA,MAAA;AAAQ,QAAA;AAAU,KAAA;IACrEC,OAAAA,EAAS;AAAC,QAAA,cAAA;AAAgB,QAAA,eAAA;AAAiB,QAAA,QAAA;AAAU,QAAA;AAAS,KAAA;IAC9DC,kBAAAA,EAAoB;AACtB,CAAA;AAEA;;;;;;AAMC,IACM,MAAMC,WAAAA,GAAc,OACzBC,eACAC,gBAAAA,EAEAC,GAAAA,GAAAA;AAEA,IAAA,IAAI,CAACF,aAAAA,EAAe;QAClB,OAAO,GAAA;AACT,IAAA;IAEA,IAAIG,UAAAA;IAEJ,IAAI,OAAOF,qBAAqB,UAAA,EAAY;AAC1CE,QAAAA,UAAAA,GAAa,MAAMF,gBAAAA,CAAiBC,GAAAA,CAAAA;IACtC,CAAA,MAAO;QACLC,UAAAA,GAAaF,gBAAAA;AACf,IAAA;;IAGA,IAAIG,iBAAAA;IACJ,IAAIC,KAAAA,CAAMC,OAAO,CAACH,UAAAA,CAAAA,EAAa;QAC7BC,iBAAAA,GAAoBD,UAAAA;AACtB,IAAA,CAAA,MAAO,IAAIA,UAAAA,KAAeI,SAAAA,IAAaJ,UAAAA,KAAe,IAAA,EAAM;;QAE1DC,iBAAAA,GAAoB;AAAC,YAAA;AAAI,SAAA;IAC3B,CAAA,MAAO;;QAELA,iBAAAA,GAAoBD,UAAAA,CAAWK,KAAK,CAAC,GAAA,CAAA,CAAKC,GAAG,CAAC,CAAChB,MAAAA,GAAWA,MAAAA,CAAOiB,IAAI,EAAA,CAAA;AACvE,IAAA;;IAGA,IAAIN,iBAAAA,CAAkBO,QAAQ,CAAC,GAAA,CAAA,EAAM;QACnC,OAAOX,aAAAA;AACT,IAAA;;AAGA,IAAA,OAAOI,iBAAAA,CAAkBO,QAAQ,CAACX,aAAAA,CAAAA,GAAiBA,aAAAA,GAAgB,EAAA;AACrE;AAEO,MAAMY,OAAuC,CAACC,MAAAA,GAAAA;AACnD,IAAA,MAAM,EAAEpB,MAAM,EAAEqB,MAAM,EAAEpB,MAAM,EAAEC,WAAW,EAAEC,OAAO,EAAEC,OAAO,EAAEC,kBAAkB,EAAE,GAAG;AACpF,QAAA,GAAGN,QAAQ;AACX,QAAA,GAAGqB;AACL,KAAA;IAEA,IAAIA,MAAAA,CAAOE,OAAO,KAAKR,SAAAA,EAAW;AAChCS,QAAAA,MAAAA,CAAOC,GAAG,CAACC,IAAI,CACb,kFACE,wGAAA,GACA,6CAAA,CAAA;AAEN,IAAA;AAEA,IAAA,OAAOC,wBAAAA,CAAQ;AACb,QAAA,MAAM1B,QAAOS,GAAG,EAAA;YACd,MAAMF,aAAAA,GAAgBE,GAAAA,CAAIkB,GAAG,CAAC,QAAA,CAAA;YAC9B,OAAOrB,WAAAA,CAAYC,eAAeP,MAAAA,EAAQS,GAAAA,CAAAA;AAC5C,QAAA,CAAA;QACAmB,aAAAA,EAAeP,MAAAA;AACfpB,QAAAA,MAAAA;AACAC,QAAAA,WAAAA;QACA2B,YAAAA,EAAc1B,OAAAA;QACd2B,YAAAA,EAAc1B,OAAAA;AACdC,QAAAA;AACF,KAAA,CAAA;AACF;;;;;"}
|