@strapi/core 5.50.1 → 5.50.2
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/compile.d.ts +1 -1
- package/dist/core-api/routes/validation/common.d.ts +3 -3
- package/dist/core-api/routes/validation/common.d.ts.map +1 -1
- package/dist/core-api/service/collection-type.d.ts +2 -2
- package/dist/core-api/service/single-type.d.ts +2 -2
- package/dist/domain/content-type/index.d.ts +1 -1
- package/dist/domain/content-type/index.d.ts.map +1 -1
- package/dist/domain/content-type/index.js +9 -0
- package/dist/domain/content-type/index.js.map +1 -1
- package/dist/domain/content-type/index.mjs +9 -0
- package/dist/domain/content-type/index.mjs.map +1 -1
- package/dist/domain/content-type/validator.d.ts.map +1 -1
- package/dist/domain/content-type/validator.js.map +1 -1
- package/dist/domain/content-type/validator.mjs.map +1 -1
- package/dist/ee/index.js.map +1 -1
- package/dist/ee/index.mjs.map +1 -1
- package/dist/ee/license.d.ts +1 -1
- package/dist/ee/license.d.ts.map +1 -1
- package/dist/ee/license.js +51 -8
- package/dist/ee/license.js.map +1 -1
- package/dist/ee/license.mjs +32 -8
- package/dist/ee/license.mjs.map +1 -1
- package/dist/package.json.js +17 -15
- package/dist/package.json.js.map +1 -1
- package/dist/package.json.mjs +17 -15
- package/dist/package.json.mjs.map +1 -1
- package/dist/services/document-service/attributes/index.d.ts +1 -1
- package/dist/services/document-service/attributes/index.d.ts.map +1 -1
- package/dist/services/document-service/components.d.ts +2 -2
- package/dist/services/document-service/components.d.ts.map +1 -1
- package/dist/services/document-service/repository.d.ts.map +1 -1
- package/dist/services/document-service/repository.js +31 -11
- package/dist/services/document-service/repository.js.map +1 -1
- package/dist/services/document-service/repository.mjs +30 -10
- package/dist/services/document-service/repository.mjs.map +1 -1
- package/dist/services/document-service/utils/clone-relations.d.ts +7 -0
- package/dist/services/document-service/utils/clone-relations.d.ts.map +1 -0
- package/dist/services/document-service/utils/clone-relations.js +124 -0
- package/dist/services/document-service/utils/clone-relations.js.map +1 -0
- package/dist/services/document-service/utils/clone-relations.mjs +121 -0
- package/dist/services/document-service/utils/clone-relations.mjs.map +1 -0
- package/dist/services/mcp/tools/log.d.ts +2 -2
- package/dist/services/mcp/tools/log.d.ts.map +1 -1
- package/dist/utils/fetch.d.ts +1 -1
- package/dist/utils/fetch.d.ts.map +1 -1
- package/dist/utils/fetch.js +2 -2
- package/dist/utils/fetch.js.map +1 -1
- package/dist/utils/fetch.mjs +2 -2
- package/dist/utils/fetch.mjs.map +1 -1
- package/dist/utils/startup-logger.d.ts.map +1 -1
- package/dist/utils/startup-logger.js +8 -2
- package/dist/utils/startup-logger.js.map +1 -1
- package/dist/utils/startup-logger.mjs +8 -2
- package/dist/utils/startup-logger.mjs.map +1 -1
- package/dist/utils/transform-content-types-to-models.d.ts +9 -9
- package/package.json +17 -15
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var fp = require('lodash/fp');
|
|
4
|
+
var mapRelation = require('../transform/relations/utils/map-relation.js');
|
|
5
|
+
|
|
6
|
+
const RELATION_OPERATIONS = [
|
|
7
|
+
'connect',
|
|
8
|
+
'disconnect',
|
|
9
|
+
'set'
|
|
10
|
+
];
|
|
11
|
+
const isRecord = (value)=>{
|
|
12
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
13
|
+
};
|
|
14
|
+
const isRelationAttribute = (attribute)=>{
|
|
15
|
+
return isRecord(attribute) && attribute.type === 'relation' && typeof attribute.relation === 'string';
|
|
16
|
+
};
|
|
17
|
+
const isRelationOperationPayload = (value)=>{
|
|
18
|
+
return isRecord(value) && RELATION_OPERATIONS.some((operation)=>Object.prototype.hasOwnProperty.call(value, operation));
|
|
19
|
+
};
|
|
20
|
+
const hasMeaningfulRelationOperations = (value)=>{
|
|
21
|
+
if (Object.prototype.hasOwnProperty.call(value, 'set')) {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
return [
|
|
25
|
+
'connect',
|
|
26
|
+
'disconnect'
|
|
27
|
+
].some((operation)=>{
|
|
28
|
+
const operationValue = value[operation];
|
|
29
|
+
return Array.isArray(operationValue) ? operationValue.length > 0 : operationValue != null;
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
const canTransformRelationOperationPayload = (attribute)=>{
|
|
33
|
+
return attribute.useJoinTable !== false && attribute.relation !== 'morphToOne';
|
|
34
|
+
};
|
|
35
|
+
const isBidirectionalOneToOne = (attribute)=>{
|
|
36
|
+
return attribute.relation === 'oneToOne' && [
|
|
37
|
+
attribute.inversedBy,
|
|
38
|
+
attribute.mappedBy,
|
|
39
|
+
attribute.targetAttribute
|
|
40
|
+
].some((inverseAttribute)=>inverseAttribute != null);
|
|
41
|
+
};
|
|
42
|
+
const hasPopulatedRelation = (value)=>{
|
|
43
|
+
return isRecord(value) && ('id' in value || 'documentId' in value);
|
|
44
|
+
};
|
|
45
|
+
const collectRelationOperationOverrides = async (submittedData, contentType, getModel)=>{
|
|
46
|
+
const overrides = new Map();
|
|
47
|
+
await mapRelation.traverseEntityRelations(({ path, value })=>{
|
|
48
|
+
if (isRelationOperationPayload(value) && hasMeaningfulRelationOperations(value)) {
|
|
49
|
+
overrides.set(path.rawWithIndices, value);
|
|
50
|
+
}
|
|
51
|
+
}, {
|
|
52
|
+
schema: contentType,
|
|
53
|
+
getModel
|
|
54
|
+
}, submittedData);
|
|
55
|
+
return [
|
|
56
|
+
...overrides.entries()
|
|
57
|
+
].sort(([leftPath], [rightPath])=>leftPath.localeCompare(rightPath));
|
|
58
|
+
};
|
|
59
|
+
const prepareCloneData = async (originalData, submittedData, contentType, getModel)=>{
|
|
60
|
+
const submitted = submittedData ?? {};
|
|
61
|
+
const relationOperationOverrides = await collectRelationOperationOverrides(submitted, contentType, getModel);
|
|
62
|
+
let data = fp.merge(originalData, submitted);
|
|
63
|
+
const relationsToCopy = [];
|
|
64
|
+
for (const [attributeName, attribute] of Object.entries(contentType.attributes)){
|
|
65
|
+
if (!isRelationAttribute(attribute) || !canTransformRelationOperationPayload(attribute)) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const relationWasSubmitted = Object.prototype.hasOwnProperty.call(submitted, attributeName);
|
|
69
|
+
const submittedValue = submitted[attributeName];
|
|
70
|
+
const isOperationPayload = isRelationOperationPayload(submittedValue);
|
|
71
|
+
const hasMeaningfulOperations = isOperationPayload && hasMeaningfulRelationOperations(submittedValue);
|
|
72
|
+
const relationIsUnchanged = !relationWasSubmitted || isOperationPayload && !hasMeaningfulOperations;
|
|
73
|
+
if (relationIsUnchanged && isBidirectionalOneToOne(attribute) && hasPopulatedRelation(originalData[attributeName])) {
|
|
74
|
+
// Normal relation attachment enforces oneToOne ownership by removing the source link.
|
|
75
|
+
// Leave unchanged relations out of create and copy their join row after the clone exists.
|
|
76
|
+
delete data[attributeName];
|
|
77
|
+
relationsToCopy.push(attributeName);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
for (const [path, value] of relationOperationOverrides){
|
|
81
|
+
data = fp.set(path, value, data);
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
data,
|
|
85
|
+
relationsToCopy
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
const copyCloneRelationRows = async (strapi, uid, sourceEntryId, targetEntryId, attributeNames)=>{
|
|
89
|
+
if (attributeNames.length === 0) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const { attributes } = strapi.db.metadata.get(uid);
|
|
93
|
+
const idColumn = strapi.db.metadata.identifiers.ID_COLUMN;
|
|
94
|
+
const batchSize = strapi.db.dialect.getBatchInsertSize();
|
|
95
|
+
await strapi.db.transaction(async ({ trx })=>{
|
|
96
|
+
for (const attributeName of attributeNames){
|
|
97
|
+
const attribute = attributes[attributeName];
|
|
98
|
+
if (attribute?.type !== 'relation' || !('joinTable' in attribute) || !attribute.joinTable) {
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
const { joinTable } = attribute;
|
|
102
|
+
const { joinColumn } = joinTable;
|
|
103
|
+
const rows = await strapi.db.connection(joinTable.name).where({
|
|
104
|
+
[joinColumn.name]: sourceEntryId,
|
|
105
|
+
...'on' in joinTable && joinTable.on || {}
|
|
106
|
+
}).select('*').transacting(trx);
|
|
107
|
+
const rowsToCopy = rows.map((row)=>{
|
|
108
|
+
const copiedRow = {
|
|
109
|
+
...row,
|
|
110
|
+
[joinColumn.name]: targetEntryId
|
|
111
|
+
};
|
|
112
|
+
delete copiedRow[idColumn];
|
|
113
|
+
return copiedRow;
|
|
114
|
+
});
|
|
115
|
+
for(let index = 0; index < rowsToCopy.length; index += batchSize){
|
|
116
|
+
await strapi.db.connection(joinTable.name).insert(rowsToCopy.slice(index, index + batchSize)).transacting(trx);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
exports.copyCloneRelationRows = copyCloneRelationRows;
|
|
123
|
+
exports.prepareCloneData = prepareCloneData;
|
|
124
|
+
//# sourceMappingURL=clone-relations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clone-relations.js","sources":["../../../../src/services/document-service/utils/clone-relations.ts"],"sourcesContent":["import { merge, set } from 'lodash/fp';\n\nimport type { Core, Schema, UID } from '@strapi/types';\nimport type { traverseEntity } from '@strapi/utils';\nimport { traverseEntityRelations } from '../transform/relations/utils/map-relation';\n\nconst RELATION_OPERATIONS = ['connect', 'disconnect', 'set'] as const;\ntype TraversableData = Parameters<typeof traverseEntity>[2];\n\ntype CloneRelationAttribute = Schema.Attribute.Relation & {\n targetAttribute?: string;\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n};\n\nconst isRelationAttribute = (attribute: unknown): attribute is CloneRelationAttribute => {\n return (\n isRecord(attribute) && attribute.type === 'relation' && typeof attribute.relation === 'string'\n );\n};\n\nconst isRelationOperationPayload = (value: unknown): value is Record<string, unknown> => {\n return (\n isRecord(value) &&\n RELATION_OPERATIONS.some((operation) => Object.prototype.hasOwnProperty.call(value, operation))\n );\n};\n\nconst hasMeaningfulRelationOperations = (value: Record<string, unknown>) => {\n if (Object.prototype.hasOwnProperty.call(value, 'set')) {\n return true;\n }\n\n return ['connect', 'disconnect'].some((operation) => {\n const operationValue = value[operation];\n return Array.isArray(operationValue) ? operationValue.length > 0 : operationValue != null;\n });\n};\n\nconst canTransformRelationOperationPayload = (attribute: Schema.Attribute.Relation) => {\n return attribute.useJoinTable !== false && attribute.relation !== 'morphToOne';\n};\n\nconst isBidirectionalOneToOne = (attribute: CloneRelationAttribute) => {\n return (\n attribute.relation === 'oneToOne' &&\n [attribute.inversedBy, attribute.mappedBy, attribute.targetAttribute].some(\n (inverseAttribute) => inverseAttribute != null\n )\n );\n};\n\nconst hasPopulatedRelation = (value: unknown) => {\n return isRecord(value) && ('id' in value || 'documentId' in value);\n};\n\nconst collectRelationOperationOverrides = async (\n submittedData: Record<string, unknown>,\n contentType: Schema.ContentType,\n getModel: (uid: string) => Schema.Schema\n) => {\n const overrides = new Map<string, Record<string, unknown>>();\n\n await traverseEntityRelations(\n ({ path, value }) => {\n if (isRelationOperationPayload(value) && hasMeaningfulRelationOperations(value)) {\n overrides.set(path.rawWithIndices!, value);\n }\n },\n { schema: contentType, getModel },\n submittedData as TraversableData\n );\n\n return [...overrides.entries()].sort(([leftPath], [rightPath]) =>\n leftPath.localeCompare(rightPath)\n );\n};\n\nexport const prepareCloneData = async (\n originalData: Record<string, unknown>,\n submittedData: Record<string, unknown> | undefined,\n contentType: Schema.ContentType,\n getModel: (uid: string) => Schema.Schema\n) => {\n const submitted = submittedData ?? {};\n const relationOperationOverrides = await collectRelationOperationOverrides(\n submitted,\n contentType,\n getModel\n );\n let data = merge(originalData, submitted) as Record<string, unknown>;\n const relationsToCopy: string[] = [];\n\n for (const [attributeName, attribute] of Object.entries(contentType.attributes)) {\n if (!isRelationAttribute(attribute) || !canTransformRelationOperationPayload(attribute)) {\n continue;\n }\n\n const relationWasSubmitted = Object.prototype.hasOwnProperty.call(submitted, attributeName);\n const submittedValue = submitted[attributeName];\n const isOperationPayload = isRelationOperationPayload(submittedValue);\n const hasMeaningfulOperations =\n isOperationPayload && hasMeaningfulRelationOperations(submittedValue);\n\n const relationIsUnchanged =\n !relationWasSubmitted || (isOperationPayload && !hasMeaningfulOperations);\n\n if (\n relationIsUnchanged &&\n isBidirectionalOneToOne(attribute) &&\n hasPopulatedRelation(originalData[attributeName])\n ) {\n // Normal relation attachment enforces oneToOne ownership by removing the source link.\n // Leave unchanged relations out of create and copy their join row after the clone exists.\n delete data[attributeName];\n relationsToCopy.push(attributeName);\n }\n }\n\n for (const [path, value] of relationOperationOverrides) {\n data = set(path, value, data) as Record<string, unknown>;\n }\n\n return { data, relationsToCopy };\n};\n\nexport const copyCloneRelationRows = async (\n strapi: Core.Strapi,\n uid: UID.ContentType,\n sourceEntryId: number,\n targetEntryId: number,\n attributeNames: string[]\n) => {\n if (attributeNames.length === 0) {\n return;\n }\n\n const { attributes } = strapi.db.metadata.get(uid);\n const idColumn = strapi.db.metadata.identifiers.ID_COLUMN;\n const batchSize = strapi.db.dialect.getBatchInsertSize();\n\n await strapi.db.transaction(async ({ trx }) => {\n for (const attributeName of attributeNames) {\n const attribute = attributes[attributeName];\n\n if (attribute?.type !== 'relation' || !('joinTable' in attribute) || !attribute.joinTable) {\n continue;\n }\n\n const { joinTable } = attribute;\n const { joinColumn } = joinTable;\n const rows = (await strapi.db\n .connection(joinTable.name)\n .where({\n [joinColumn.name]: sourceEntryId,\n ...(('on' in joinTable && joinTable.on) || {}),\n })\n .select('*')\n .transacting(trx)) as Record<string, unknown>[];\n\n const rowsToCopy = rows.map((row) => {\n const copiedRow = { ...row, [joinColumn.name]: targetEntryId };\n delete copiedRow[idColumn];\n return copiedRow;\n });\n\n for (let index = 0; index < rowsToCopy.length; index += batchSize) {\n await strapi.db\n .connection(joinTable.name)\n .insert(rowsToCopy.slice(index, index + batchSize))\n .transacting(trx);\n }\n }\n });\n};\n"],"names":["RELATION_OPERATIONS","isRecord","value","Array","isArray","isRelationAttribute","attribute","type","relation","isRelationOperationPayload","some","operation","Object","prototype","hasOwnProperty","call","hasMeaningfulRelationOperations","operationValue","length","canTransformRelationOperationPayload","useJoinTable","isBidirectionalOneToOne","inversedBy","mappedBy","targetAttribute","inverseAttribute","hasPopulatedRelation","collectRelationOperationOverrides","submittedData","contentType","getModel","overrides","Map","traverseEntityRelations","path","set","rawWithIndices","schema","entries","sort","leftPath","rightPath","localeCompare","prepareCloneData","originalData","submitted","relationOperationOverrides","data","merge","relationsToCopy","attributeName","attributes","relationWasSubmitted","submittedValue","isOperationPayload","hasMeaningfulOperations","relationIsUnchanged","push","copyCloneRelationRows","strapi","uid","sourceEntryId","targetEntryId","attributeNames","db","metadata","get","idColumn","identifiers","ID_COLUMN","batchSize","dialect","getBatchInsertSize","transaction","trx","joinTable","joinColumn","rows","connection","name","where","on","select","transacting","rowsToCopy","map","row","copiedRow","index","insert","slice"],"mappings":"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"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { merge, set } from 'lodash/fp';
|
|
2
|
+
import { traverseEntityRelations as traverseEntityRelationsCurried } from '../transform/relations/utils/map-relation.mjs';
|
|
3
|
+
|
|
4
|
+
const RELATION_OPERATIONS = [
|
|
5
|
+
'connect',
|
|
6
|
+
'disconnect',
|
|
7
|
+
'set'
|
|
8
|
+
];
|
|
9
|
+
const isRecord = (value)=>{
|
|
10
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
11
|
+
};
|
|
12
|
+
const isRelationAttribute = (attribute)=>{
|
|
13
|
+
return isRecord(attribute) && attribute.type === 'relation' && typeof attribute.relation === 'string';
|
|
14
|
+
};
|
|
15
|
+
const isRelationOperationPayload = (value)=>{
|
|
16
|
+
return isRecord(value) && RELATION_OPERATIONS.some((operation)=>Object.prototype.hasOwnProperty.call(value, operation));
|
|
17
|
+
};
|
|
18
|
+
const hasMeaningfulRelationOperations = (value)=>{
|
|
19
|
+
if (Object.prototype.hasOwnProperty.call(value, 'set')) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
return [
|
|
23
|
+
'connect',
|
|
24
|
+
'disconnect'
|
|
25
|
+
].some((operation)=>{
|
|
26
|
+
const operationValue = value[operation];
|
|
27
|
+
return Array.isArray(operationValue) ? operationValue.length > 0 : operationValue != null;
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
const canTransformRelationOperationPayload = (attribute)=>{
|
|
31
|
+
return attribute.useJoinTable !== false && attribute.relation !== 'morphToOne';
|
|
32
|
+
};
|
|
33
|
+
const isBidirectionalOneToOne = (attribute)=>{
|
|
34
|
+
return attribute.relation === 'oneToOne' && [
|
|
35
|
+
attribute.inversedBy,
|
|
36
|
+
attribute.mappedBy,
|
|
37
|
+
attribute.targetAttribute
|
|
38
|
+
].some((inverseAttribute)=>inverseAttribute != null);
|
|
39
|
+
};
|
|
40
|
+
const hasPopulatedRelation = (value)=>{
|
|
41
|
+
return isRecord(value) && ('id' in value || 'documentId' in value);
|
|
42
|
+
};
|
|
43
|
+
const collectRelationOperationOverrides = async (submittedData, contentType, getModel)=>{
|
|
44
|
+
const overrides = new Map();
|
|
45
|
+
await traverseEntityRelationsCurried(({ path, value })=>{
|
|
46
|
+
if (isRelationOperationPayload(value) && hasMeaningfulRelationOperations(value)) {
|
|
47
|
+
overrides.set(path.rawWithIndices, value);
|
|
48
|
+
}
|
|
49
|
+
}, {
|
|
50
|
+
schema: contentType,
|
|
51
|
+
getModel
|
|
52
|
+
}, submittedData);
|
|
53
|
+
return [
|
|
54
|
+
...overrides.entries()
|
|
55
|
+
].sort(([leftPath], [rightPath])=>leftPath.localeCompare(rightPath));
|
|
56
|
+
};
|
|
57
|
+
const prepareCloneData = async (originalData, submittedData, contentType, getModel)=>{
|
|
58
|
+
const submitted = submittedData ?? {};
|
|
59
|
+
const relationOperationOverrides = await collectRelationOperationOverrides(submitted, contentType, getModel);
|
|
60
|
+
let data = merge(originalData, submitted);
|
|
61
|
+
const relationsToCopy = [];
|
|
62
|
+
for (const [attributeName, attribute] of Object.entries(contentType.attributes)){
|
|
63
|
+
if (!isRelationAttribute(attribute) || !canTransformRelationOperationPayload(attribute)) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const relationWasSubmitted = Object.prototype.hasOwnProperty.call(submitted, attributeName);
|
|
67
|
+
const submittedValue = submitted[attributeName];
|
|
68
|
+
const isOperationPayload = isRelationOperationPayload(submittedValue);
|
|
69
|
+
const hasMeaningfulOperations = isOperationPayload && hasMeaningfulRelationOperations(submittedValue);
|
|
70
|
+
const relationIsUnchanged = !relationWasSubmitted || isOperationPayload && !hasMeaningfulOperations;
|
|
71
|
+
if (relationIsUnchanged && isBidirectionalOneToOne(attribute) && hasPopulatedRelation(originalData[attributeName])) {
|
|
72
|
+
// Normal relation attachment enforces oneToOne ownership by removing the source link.
|
|
73
|
+
// Leave unchanged relations out of create and copy their join row after the clone exists.
|
|
74
|
+
delete data[attributeName];
|
|
75
|
+
relationsToCopy.push(attributeName);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
for (const [path, value] of relationOperationOverrides){
|
|
79
|
+
data = set(path, value, data);
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
data,
|
|
83
|
+
relationsToCopy
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
const copyCloneRelationRows = async (strapi, uid, sourceEntryId, targetEntryId, attributeNames)=>{
|
|
87
|
+
if (attributeNames.length === 0) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const { attributes } = strapi.db.metadata.get(uid);
|
|
91
|
+
const idColumn = strapi.db.metadata.identifiers.ID_COLUMN;
|
|
92
|
+
const batchSize = strapi.db.dialect.getBatchInsertSize();
|
|
93
|
+
await strapi.db.transaction(async ({ trx })=>{
|
|
94
|
+
for (const attributeName of attributeNames){
|
|
95
|
+
const attribute = attributes[attributeName];
|
|
96
|
+
if (attribute?.type !== 'relation' || !('joinTable' in attribute) || !attribute.joinTable) {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
const { joinTable } = attribute;
|
|
100
|
+
const { joinColumn } = joinTable;
|
|
101
|
+
const rows = await strapi.db.connection(joinTable.name).where({
|
|
102
|
+
[joinColumn.name]: sourceEntryId,
|
|
103
|
+
...'on' in joinTable && joinTable.on || {}
|
|
104
|
+
}).select('*').transacting(trx);
|
|
105
|
+
const rowsToCopy = rows.map((row)=>{
|
|
106
|
+
const copiedRow = {
|
|
107
|
+
...row,
|
|
108
|
+
[joinColumn.name]: targetEntryId
|
|
109
|
+
};
|
|
110
|
+
delete copiedRow[idColumn];
|
|
111
|
+
return copiedRow;
|
|
112
|
+
});
|
|
113
|
+
for(let index = 0; index < rowsToCopy.length; index += batchSize){
|
|
114
|
+
await strapi.db.connection(joinTable.name).insert(rowsToCopy.slice(index, index + batchSize)).transacting(trx);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
export { copyCloneRelationRows, prepareCloneData };
|
|
121
|
+
//# sourceMappingURL=clone-relations.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clone-relations.mjs","sources":["../../../../src/services/document-service/utils/clone-relations.ts"],"sourcesContent":["import { merge, set } from 'lodash/fp';\n\nimport type { Core, Schema, UID } from '@strapi/types';\nimport type { traverseEntity } from '@strapi/utils';\nimport { traverseEntityRelations } from '../transform/relations/utils/map-relation';\n\nconst RELATION_OPERATIONS = ['connect', 'disconnect', 'set'] as const;\ntype TraversableData = Parameters<typeof traverseEntity>[2];\n\ntype CloneRelationAttribute = Schema.Attribute.Relation & {\n targetAttribute?: string;\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n};\n\nconst isRelationAttribute = (attribute: unknown): attribute is CloneRelationAttribute => {\n return (\n isRecord(attribute) && attribute.type === 'relation' && typeof attribute.relation === 'string'\n );\n};\n\nconst isRelationOperationPayload = (value: unknown): value is Record<string, unknown> => {\n return (\n isRecord(value) &&\n RELATION_OPERATIONS.some((operation) => Object.prototype.hasOwnProperty.call(value, operation))\n );\n};\n\nconst hasMeaningfulRelationOperations = (value: Record<string, unknown>) => {\n if (Object.prototype.hasOwnProperty.call(value, 'set')) {\n return true;\n }\n\n return ['connect', 'disconnect'].some((operation) => {\n const operationValue = value[operation];\n return Array.isArray(operationValue) ? operationValue.length > 0 : operationValue != null;\n });\n};\n\nconst canTransformRelationOperationPayload = (attribute: Schema.Attribute.Relation) => {\n return attribute.useJoinTable !== false && attribute.relation !== 'morphToOne';\n};\n\nconst isBidirectionalOneToOne = (attribute: CloneRelationAttribute) => {\n return (\n attribute.relation === 'oneToOne' &&\n [attribute.inversedBy, attribute.mappedBy, attribute.targetAttribute].some(\n (inverseAttribute) => inverseAttribute != null\n )\n );\n};\n\nconst hasPopulatedRelation = (value: unknown) => {\n return isRecord(value) && ('id' in value || 'documentId' in value);\n};\n\nconst collectRelationOperationOverrides = async (\n submittedData: Record<string, unknown>,\n contentType: Schema.ContentType,\n getModel: (uid: string) => Schema.Schema\n) => {\n const overrides = new Map<string, Record<string, unknown>>();\n\n await traverseEntityRelations(\n ({ path, value }) => {\n if (isRelationOperationPayload(value) && hasMeaningfulRelationOperations(value)) {\n overrides.set(path.rawWithIndices!, value);\n }\n },\n { schema: contentType, getModel },\n submittedData as TraversableData\n );\n\n return [...overrides.entries()].sort(([leftPath], [rightPath]) =>\n leftPath.localeCompare(rightPath)\n );\n};\n\nexport const prepareCloneData = async (\n originalData: Record<string, unknown>,\n submittedData: Record<string, unknown> | undefined,\n contentType: Schema.ContentType,\n getModel: (uid: string) => Schema.Schema\n) => {\n const submitted = submittedData ?? {};\n const relationOperationOverrides = await collectRelationOperationOverrides(\n submitted,\n contentType,\n getModel\n );\n let data = merge(originalData, submitted) as Record<string, unknown>;\n const relationsToCopy: string[] = [];\n\n for (const [attributeName, attribute] of Object.entries(contentType.attributes)) {\n if (!isRelationAttribute(attribute) || !canTransformRelationOperationPayload(attribute)) {\n continue;\n }\n\n const relationWasSubmitted = Object.prototype.hasOwnProperty.call(submitted, attributeName);\n const submittedValue = submitted[attributeName];\n const isOperationPayload = isRelationOperationPayload(submittedValue);\n const hasMeaningfulOperations =\n isOperationPayload && hasMeaningfulRelationOperations(submittedValue);\n\n const relationIsUnchanged =\n !relationWasSubmitted || (isOperationPayload && !hasMeaningfulOperations);\n\n if (\n relationIsUnchanged &&\n isBidirectionalOneToOne(attribute) &&\n hasPopulatedRelation(originalData[attributeName])\n ) {\n // Normal relation attachment enforces oneToOne ownership by removing the source link.\n // Leave unchanged relations out of create and copy their join row after the clone exists.\n delete data[attributeName];\n relationsToCopy.push(attributeName);\n }\n }\n\n for (const [path, value] of relationOperationOverrides) {\n data = set(path, value, data) as Record<string, unknown>;\n }\n\n return { data, relationsToCopy };\n};\n\nexport const copyCloneRelationRows = async (\n strapi: Core.Strapi,\n uid: UID.ContentType,\n sourceEntryId: number,\n targetEntryId: number,\n attributeNames: string[]\n) => {\n if (attributeNames.length === 0) {\n return;\n }\n\n const { attributes } = strapi.db.metadata.get(uid);\n const idColumn = strapi.db.metadata.identifiers.ID_COLUMN;\n const batchSize = strapi.db.dialect.getBatchInsertSize();\n\n await strapi.db.transaction(async ({ trx }) => {\n for (const attributeName of attributeNames) {\n const attribute = attributes[attributeName];\n\n if (attribute?.type !== 'relation' || !('joinTable' in attribute) || !attribute.joinTable) {\n continue;\n }\n\n const { joinTable } = attribute;\n const { joinColumn } = joinTable;\n const rows = (await strapi.db\n .connection(joinTable.name)\n .where({\n [joinColumn.name]: sourceEntryId,\n ...(('on' in joinTable && joinTable.on) || {}),\n })\n .select('*')\n .transacting(trx)) as Record<string, unknown>[];\n\n const rowsToCopy = rows.map((row) => {\n const copiedRow = { ...row, [joinColumn.name]: targetEntryId };\n delete copiedRow[idColumn];\n return copiedRow;\n });\n\n for (let index = 0; index < rowsToCopy.length; index += batchSize) {\n await strapi.db\n .connection(joinTable.name)\n .insert(rowsToCopy.slice(index, index + batchSize))\n .transacting(trx);\n }\n }\n });\n};\n"],"names":["RELATION_OPERATIONS","isRecord","value","Array","isArray","isRelationAttribute","attribute","type","relation","isRelationOperationPayload","some","operation","Object","prototype","hasOwnProperty","call","hasMeaningfulRelationOperations","operationValue","length","canTransformRelationOperationPayload","useJoinTable","isBidirectionalOneToOne","inversedBy","mappedBy","targetAttribute","inverseAttribute","hasPopulatedRelation","collectRelationOperationOverrides","submittedData","contentType","getModel","overrides","Map","traverseEntityRelations","path","set","rawWithIndices","schema","entries","sort","leftPath","rightPath","localeCompare","prepareCloneData","originalData","submitted","relationOperationOverrides","data","merge","relationsToCopy","attributeName","attributes","relationWasSubmitted","submittedValue","isOperationPayload","hasMeaningfulOperations","relationIsUnchanged","push","copyCloneRelationRows","strapi","uid","sourceEntryId","targetEntryId","attributeNames","db","metadata","get","idColumn","identifiers","ID_COLUMN","batchSize","dialect","getBatchInsertSize","transaction","trx","joinTable","joinColumn","rows","connection","name","where","on","select","transacting","rowsToCopy","map","row","copiedRow","index","insert","slice"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from '@strapi/utils';
|
|
2
|
-
export declare const logToolDefinition: import("@strapi/types/dist/modules/mcp").McpToolDefinitionFields<"log", z.ZodObject<{
|
|
2
|
+
export declare const logToolDefinition: import("@strapi/types/dist/modules/mcp.js").McpToolDefinitionFields<"log", z.ZodObject<{
|
|
3
3
|
message: z.ZodString;
|
|
4
4
|
level: z.ZodDefault<z.ZodEnum<{
|
|
5
5
|
http: "http";
|
|
@@ -13,5 +13,5 @@ export declare const logToolDefinition: import("@strapi/types/dist/modules/mcp")
|
|
|
13
13
|
message: z.ZodString;
|
|
14
14
|
level: z.ZodString;
|
|
15
15
|
timestamp: z.ZodString;
|
|
16
|
-
}, z.core.$strip>, "Strapi Log", "Logs a message to the Strapi logger with specified level"> & import("@strapi/types/dist/modules/mcp").McpDevModeAccess;
|
|
16
|
+
}, z.core.$strip>, "Strapi Log", "Logs a message to the Strapi logger with specified level"> & import("@strapi/types/dist/modules/mcp.js").McpDevModeAccess;
|
|
17
17
|
//# sourceMappingURL=log.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../../../src/services/mcp/tools/log.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,eAAe,CAAC;AAmBlC,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../../../src/services/mcp/tools/log.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,eAAe,CAAC;AAmBlC,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;2JAwE5B,CAAC"}
|
package/dist/utils/fetch.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { Core, Modules } from '@strapi/types';
|
|
|
2
2
|
interface StrapiFetchOptions {
|
|
3
3
|
logs?: boolean;
|
|
4
4
|
}
|
|
5
|
-
export declare const createStrapiFetch: (strapi: Core.Strapi, options?: StrapiFetchOptions) =>
|
|
5
|
+
export declare const createStrapiFetch: (strapi: Core.Strapi, options?: StrapiFetchOptions) => Fetch;
|
|
6
6
|
export type Fetch = Modules.Fetch.Fetch;
|
|
7
7
|
export {};
|
|
8
8
|
//# sourceMappingURL=fetch.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/utils/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAKnD,UAAU,kBAAkB;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAGD,eAAO,MAAM,iBAAiB,
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/utils/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAKnD,UAAU,kBAAkB;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAGD,eAAO,MAAM,iBAAiB,GAAI,QAAQ,IAAI,CAAC,MAAM,EAAE,UAAU,kBAAkB,KAAG,KA4BrF,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC"}
|
package/dist/utils/fetch.js
CHANGED
|
@@ -5,7 +5,7 @@ var undici = require('undici');
|
|
|
5
5
|
// Create a wrapper for Node's Fetch API that applies a global proxy
|
|
6
6
|
const createStrapiFetch = (strapi, options)=>{
|
|
7
7
|
const { logs = true } = options ?? {};
|
|
8
|
-
|
|
8
|
+
const strapiFetch = (url, options)=>{
|
|
9
9
|
const fetchOptions = {
|
|
10
10
|
...strapiFetch.dispatcher ? {
|
|
11
11
|
dispatcher: strapiFetch.dispatcher
|
|
@@ -16,7 +16,7 @@ const createStrapiFetch = (strapi, options)=>{
|
|
|
16
16
|
strapi.log.debug(`Making request for ${url}`);
|
|
17
17
|
}
|
|
18
18
|
return fetch(url, fetchOptions);
|
|
19
|
-
}
|
|
19
|
+
};
|
|
20
20
|
const proxy = strapi.config.get('server.proxy.fetch') || strapi.config.get('server.proxy.global');
|
|
21
21
|
if (proxy) {
|
|
22
22
|
if (logs) {
|
package/dist/utils/fetch.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.js","sources":["../../src/utils/fetch.ts"],"sourcesContent":["import type { Core, Modules } from '@strapi/types';\nimport { ProxyAgent } from 'undici';\n\n// TODO: once core Node exposes a stable way to create a ProxyAgent we will use that instead of undici\n\ninterface StrapiFetchOptions {\n logs?: boolean;\n}\n\n// Create a wrapper for Node's Fetch API that applies a global proxy\nexport const createStrapiFetch = (
|
|
1
|
+
{"version":3,"file":"fetch.js","sources":["../../src/utils/fetch.ts"],"sourcesContent":["import type { Core, Modules } from '@strapi/types';\nimport { ProxyAgent } from 'undici';\n\n// TODO: once core Node exposes a stable way to create a ProxyAgent we will use that instead of undici\n\ninterface StrapiFetchOptions {\n logs?: boolean;\n}\n\n// Create a wrapper for Node's Fetch API that applies a global proxy\nexport const createStrapiFetch = (strapi: Core.Strapi, options?: StrapiFetchOptions): Fetch => {\n const { logs = true } = options ?? {};\n\n const strapiFetch: Fetch = (url, options) => {\n const fetchOptions: RequestInit = {\n ...(strapiFetch.dispatcher ? { dispatcher: strapiFetch.dispatcher } : {}),\n ...options,\n };\n\n if (logs) {\n strapi.log.debug(`Making request for ${url}`);\n }\n\n return fetch(url, fetchOptions);\n };\n\n const proxy =\n strapi.config.get<ConstructorParameters<typeof ProxyAgent>[0]>('server.proxy.fetch') ||\n strapi.config.get<string>('server.proxy.global');\n\n if (proxy) {\n if (logs) {\n strapi.log.info(`Using proxy for Fetch requests: ${proxy}`);\n }\n strapiFetch.dispatcher = new ProxyAgent(proxy);\n }\n\n return strapiFetch;\n};\n\nexport type Fetch = Modules.Fetch.Fetch;\n"],"names":["createStrapiFetch","strapi","options","logs","strapiFetch","url","fetchOptions","dispatcher","log","debug","fetch","proxy","config","get","info","ProxyAgent"],"mappings":";;;;AASA;AACO,MAAMA,iBAAAA,GAAoB,CAACC,MAAAA,EAAqBC,OAAAA,GAAAA;AACrD,IAAA,MAAM,EAAEC,IAAAA,GAAO,IAAI,EAAE,GAAGD,WAAW,EAAC;IAEpC,MAAME,WAAAA,GAAqB,CAACC,GAAAA,EAAKH,OAAAA,GAAAA;AAC/B,QAAA,MAAMI,YAAAA,GAA4B;YAChC,GAAIF,WAAAA,CAAYG,UAAU,GAAG;AAAEA,gBAAAA,UAAAA,EAAYH,YAAYG;AAAW,aAAA,GAAI,EAAE;AACxE,YAAA,GAAGL;AACL,SAAA;AAEA,QAAA,IAAIC,IAAAA,EAAM;AACRF,YAAAA,MAAAA,CAAOO,GAAG,CAACC,KAAK,CAAC,CAAC,mBAAmB,EAAEJ,GAAAA,CAAAA,CAAK,CAAA;AAC9C,QAAA;AAEA,QAAA,OAAOK,MAAML,GAAAA,EAAKC,YAAAA,CAAAA;AACpB,IAAA,CAAA;IAEA,MAAMK,KAAAA,GACJV,MAAAA,CAAOW,MAAM,CAACC,GAAG,CAA8C,oBAAA,CAAA,IAC/DZ,MAAAA,CAAOW,MAAM,CAACC,GAAG,CAAS,qBAAA,CAAA;AAE5B,IAAA,IAAIF,KAAAA,EAAO;AACT,QAAA,IAAIR,IAAAA,EAAM;AACRF,YAAAA,MAAAA,CAAOO,GAAG,CAACM,IAAI,CAAC,CAAC,gCAAgC,EAAEH,KAAAA,CAAAA,CAAO,CAAA;AAC5D,QAAA;QACAP,WAAAA,CAAYG,UAAU,GAAG,IAAIQ,iBAAAA,CAAWJ,KAAAA,CAAAA;AAC1C,IAAA;IAEA,OAAOP,WAAAA;AACT;;;;"}
|
package/dist/utils/fetch.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import { ProxyAgent } from 'undici';
|
|
|
3
3
|
// Create a wrapper for Node's Fetch API that applies a global proxy
|
|
4
4
|
const createStrapiFetch = (strapi, options)=>{
|
|
5
5
|
const { logs = true } = options ?? {};
|
|
6
|
-
|
|
6
|
+
const strapiFetch = (url, options)=>{
|
|
7
7
|
const fetchOptions = {
|
|
8
8
|
...strapiFetch.dispatcher ? {
|
|
9
9
|
dispatcher: strapiFetch.dispatcher
|
|
@@ -14,7 +14,7 @@ const createStrapiFetch = (strapi, options)=>{
|
|
|
14
14
|
strapi.log.debug(`Making request for ${url}`);
|
|
15
15
|
}
|
|
16
16
|
return fetch(url, fetchOptions);
|
|
17
|
-
}
|
|
17
|
+
};
|
|
18
18
|
const proxy = strapi.config.get('server.proxy.fetch') || strapi.config.get('server.proxy.global');
|
|
19
19
|
if (proxy) {
|
|
20
20
|
if (logs) {
|
package/dist/utils/fetch.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.mjs","sources":["../../src/utils/fetch.ts"],"sourcesContent":["import type { Core, Modules } from '@strapi/types';\nimport { ProxyAgent } from 'undici';\n\n// TODO: once core Node exposes a stable way to create a ProxyAgent we will use that instead of undici\n\ninterface StrapiFetchOptions {\n logs?: boolean;\n}\n\n// Create a wrapper for Node's Fetch API that applies a global proxy\nexport const createStrapiFetch = (
|
|
1
|
+
{"version":3,"file":"fetch.mjs","sources":["../../src/utils/fetch.ts"],"sourcesContent":["import type { Core, Modules } from '@strapi/types';\nimport { ProxyAgent } from 'undici';\n\n// TODO: once core Node exposes a stable way to create a ProxyAgent we will use that instead of undici\n\ninterface StrapiFetchOptions {\n logs?: boolean;\n}\n\n// Create a wrapper for Node's Fetch API that applies a global proxy\nexport const createStrapiFetch = (strapi: Core.Strapi, options?: StrapiFetchOptions): Fetch => {\n const { logs = true } = options ?? {};\n\n const strapiFetch: Fetch = (url, options) => {\n const fetchOptions: RequestInit = {\n ...(strapiFetch.dispatcher ? { dispatcher: strapiFetch.dispatcher } : {}),\n ...options,\n };\n\n if (logs) {\n strapi.log.debug(`Making request for ${url}`);\n }\n\n return fetch(url, fetchOptions);\n };\n\n const proxy =\n strapi.config.get<ConstructorParameters<typeof ProxyAgent>[0]>('server.proxy.fetch') ||\n strapi.config.get<string>('server.proxy.global');\n\n if (proxy) {\n if (logs) {\n strapi.log.info(`Using proxy for Fetch requests: ${proxy}`);\n }\n strapiFetch.dispatcher = new ProxyAgent(proxy);\n }\n\n return strapiFetch;\n};\n\nexport type Fetch = Modules.Fetch.Fetch;\n"],"names":["createStrapiFetch","strapi","options","logs","strapiFetch","url","fetchOptions","dispatcher","log","debug","fetch","proxy","config","get","info","ProxyAgent"],"mappings":";;AASA;AACO,MAAMA,iBAAAA,GAAoB,CAACC,MAAAA,EAAqBC,OAAAA,GAAAA;AACrD,IAAA,MAAM,EAAEC,IAAAA,GAAO,IAAI,EAAE,GAAGD,WAAW,EAAC;IAEpC,MAAME,WAAAA,GAAqB,CAACC,GAAAA,EAAKH,OAAAA,GAAAA;AAC/B,QAAA,MAAMI,YAAAA,GAA4B;YAChC,GAAIF,WAAAA,CAAYG,UAAU,GAAG;AAAEA,gBAAAA,UAAAA,EAAYH,YAAYG;AAAW,aAAA,GAAI,EAAE;AACxE,YAAA,GAAGL;AACL,SAAA;AAEA,QAAA,IAAIC,IAAAA,EAAM;AACRF,YAAAA,MAAAA,CAAOO,GAAG,CAACC,KAAK,CAAC,CAAC,mBAAmB,EAAEJ,GAAAA,CAAAA,CAAK,CAAA;AAC9C,QAAA;AAEA,QAAA,OAAOK,MAAML,GAAAA,EAAKC,YAAAA,CAAAA;AACpB,IAAA,CAAA;IAEA,MAAMK,KAAAA,GACJV,MAAAA,CAAOW,MAAM,CAACC,GAAG,CAA8C,oBAAA,CAAA,IAC/DZ,MAAAA,CAAOW,MAAM,CAACC,GAAG,CAAS,qBAAA,CAAA;AAE5B,IAAA,IAAIF,KAAAA,EAAO;AACT,QAAA,IAAIR,IAAAA,EAAM;AACRF,YAAAA,MAAAA,CAAOO,GAAG,CAACM,IAAI,CAAC,CAAC,gCAAgC,EAAEH,KAAAA,CAAAA,CAAO,CAAA;AAC5D,QAAA;QACAP,WAAAA,CAAYG,UAAU,GAAG,IAAIQ,UAAAA,CAAWJ,KAAAA,CAAAA;AAC1C,IAAA;IAEA,OAAOP,WAAAA;AACT;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startup-logger.d.ts","sourceRoot":"","sources":["../../src/utils/startup-logger.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAoB1C,eAAO,MAAM,mBAAmB,GAAI,KAAK,IAAI,CAAC,MAAM;;;;
|
|
1
|
+
{"version":3,"file":"startup-logger.d.ts","sourceRoot":"","sources":["../../src/utils/startup-logger.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAoB1C,eAAO,MAAM,mBAAmB,GAAI,KAAK,IAAI,CAAC,MAAM;;;;yCAuFX;QAAE,aAAa,EAAE,OAAO,CAAA;KAAE;CAWlE,CAAC"}
|
|
@@ -42,6 +42,12 @@ const createStartupLogger = (app)=>{
|
|
|
42
42
|
chars: ROUNDED_CHARS
|
|
43
43
|
});
|
|
44
44
|
const dbInfo = app.db?.getInfo();
|
|
45
|
+
const getPlan = ()=>{
|
|
46
|
+
if (!app.EE) {
|
|
47
|
+
return 'Community';
|
|
48
|
+
}
|
|
49
|
+
return app.ee.planPriceId?.toLowerCase().includes('growth') ? 'Growth' : 'Enterprise';
|
|
50
|
+
};
|
|
45
51
|
infoTable.push([
|
|
46
52
|
chalk__default.default.blue('Time'),
|
|
47
53
|
`${new Date()}`
|
|
@@ -58,8 +64,8 @@ const createStartupLogger = (app)=>{
|
|
|
58
64
|
chalk__default.default.blue('Version'),
|
|
59
65
|
`${app.config.info.strapi} (node ${process.version})`
|
|
60
66
|
], [
|
|
61
|
-
chalk__default.default.blue('
|
|
62
|
-
|
|
67
|
+
chalk__default.default.blue('Plan'),
|
|
68
|
+
getPlan()
|
|
63
69
|
], [
|
|
64
70
|
chalk__default.default.blue('Database'),
|
|
65
71
|
dbInfo?.client
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startup-logger.js","sources":["../../src/utils/startup-logger.ts"],"sourcesContent":["import chalk from 'chalk';\nimport CLITable from 'cli-table3';\nimport _ from 'lodash/fp';\n\nimport type { Core } from '@strapi/types';\n\nconst ROUNDED_CHARS = {\n top: '─',\n 'top-mid': '┬',\n 'top-left': '╭',\n 'top-right': '╮',\n bottom: '─',\n 'bottom-mid': '┴',\n 'bottom-left': '╰',\n 'bottom-right': '╯',\n left: '│',\n right: '│',\n middle: '│',\n mid: '',\n 'left-mid': '',\n 'mid-mid': '',\n 'right-mid': '',\n};\n\nexport const createStartupLogger = (app: Core.Strapi) => {\n return {\n logStats() {\n const columns = Math.min(process.stderr.columns, 80) - 2;\n console.log();\n console.log(chalk.black.bgWhite(_.padEnd(columns, ' Project information')));\n console.log();\n\n const infoTable = new CLITable({\n colWidths: [20, 50],\n chars: ROUNDED_CHARS,\n });\n\n const dbInfo = app.db?.getInfo();\n\n infoTable.push(\n [chalk.blue('Time'), `${new Date()}`],\n [chalk.blue('Launched in'), `${Date.now() - app.config.launchedAt} ms`],\n [chalk.blue('Environment'), app.config.environment],\n [chalk.blue('Process PID'), process.pid],\n [chalk.blue('Version'), `${app.config.info.strapi} (node ${process.version})`],\n [chalk.blue('
|
|
1
|
+
{"version":3,"file":"startup-logger.js","sources":["../../src/utils/startup-logger.ts"],"sourcesContent":["import chalk from 'chalk';\nimport CLITable from 'cli-table3';\nimport _ from 'lodash/fp';\n\nimport type { Core } from '@strapi/types';\n\nconst ROUNDED_CHARS = {\n top: '─',\n 'top-mid': '┬',\n 'top-left': '╭',\n 'top-right': '╮',\n bottom: '─',\n 'bottom-mid': '┴',\n 'bottom-left': '╰',\n 'bottom-right': '╯',\n left: '│',\n right: '│',\n middle: '│',\n mid: '',\n 'left-mid': '',\n 'mid-mid': '',\n 'right-mid': '',\n};\n\nexport const createStartupLogger = (app: Core.Strapi) => {\n return {\n logStats() {\n const columns = Math.min(process.stderr.columns, 80) - 2;\n console.log();\n console.log(chalk.black.bgWhite(_.padEnd(columns, ' Project information')));\n console.log();\n\n const infoTable = new CLITable({\n colWidths: [20, 50],\n chars: ROUNDED_CHARS,\n });\n\n const dbInfo = app.db?.getInfo();\n\n const getPlan = () => {\n if (!app.EE) {\n return 'Community';\n }\n\n return app.ee.planPriceId?.toLowerCase().includes('growth') ? 'Growth' : 'Enterprise';\n };\n\n infoTable.push(\n [chalk.blue('Time'), `${new Date()}`],\n [chalk.blue('Launched in'), `${Date.now() - app.config.launchedAt} ms`],\n [chalk.blue('Environment'), app.config.environment],\n [chalk.blue('Process PID'), process.pid],\n [chalk.blue('Version'), `${app.config.info.strapi} (node ${process.version})`],\n [chalk.blue('Plan'), getPlan()],\n [chalk.blue('Database'), dbInfo?.client],\n [chalk.blue('Database name'), dbInfo?.displayName]\n );\n\n if (dbInfo?.schema) {\n infoTable.push([chalk.blue('Database schema'), dbInfo.schema]);\n }\n\n console.log(infoTable.toString());\n console.log();\n console.log(chalk.black.bgWhite(_.padEnd(columns, ' Actions available')));\n console.log();\n },\n\n logFirstStartupMessage() {\n if (!strapi.config.get('server.logger.startup.enabled')) {\n return;\n }\n\n this.logStats();\n\n console.log(chalk.bold('One more thing...'));\n console.log(\n chalk.grey('Create your first administrator 💻 by going to the administration panel at:')\n );\n console.log();\n\n const addressTable = new CLITable();\n\n const adminUrl = strapi.config.get('admin.absoluteUrl');\n addressTable.push([chalk.bold(adminUrl)]);\n\n console.log(`${addressTable.toString()}`);\n console.log();\n },\n\n logDefaultStartupMessage() {\n if (!strapi.config.get('server.logger.startup.enabled')) {\n return;\n }\n this.logStats();\n\n console.log(chalk.bold('Welcome back!'));\n\n if (app.config.get('admin.serveAdminPanel') === true) {\n console.log(chalk.grey('To manage your project 🚀, go to the administration panel at:'));\n const adminUrl = strapi.config.get('admin.absoluteUrl');\n console.log(chalk.bold(adminUrl));\n console.log();\n }\n\n console.log(chalk.grey('To access the server ⚡️, go to:'));\n const serverUrl = strapi.config.get('server.absoluteUrl');\n console.log(chalk.bold(serverUrl));\n console.log();\n },\n\n logStartupMessage({ isInitialized }: { isInitialized: boolean }) {\n if (!strapi.config.get('server.logger.startup.enabled')) {\n return;\n }\n if (!isInitialized) {\n this.logFirstStartupMessage();\n } else {\n this.logDefaultStartupMessage();\n }\n },\n };\n};\n"],"names":["ROUNDED_CHARS","top","bottom","left","right","middle","mid","createStartupLogger","app","logStats","columns","Math","min","process","stderr","console","log","chalk","black","bgWhite","_","padEnd","infoTable","CLITable","colWidths","chars","dbInfo","db","getInfo","getPlan","EE","ee","planPriceId","toLowerCase","includes","push","blue","Date","now","config","launchedAt","environment","pid","info","strapi","version","client","displayName","schema","toString","logFirstStartupMessage","get","bold","grey","addressTable","adminUrl","logDefaultStartupMessage","serverUrl","logStartupMessage","isInitialized"],"mappings":"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"}
|
|
@@ -34,6 +34,12 @@ const createStartupLogger = (app)=>{
|
|
|
34
34
|
chars: ROUNDED_CHARS
|
|
35
35
|
});
|
|
36
36
|
const dbInfo = app.db?.getInfo();
|
|
37
|
+
const getPlan = ()=>{
|
|
38
|
+
if (!app.EE) {
|
|
39
|
+
return 'Community';
|
|
40
|
+
}
|
|
41
|
+
return app.ee.planPriceId?.toLowerCase().includes('growth') ? 'Growth' : 'Enterprise';
|
|
42
|
+
};
|
|
37
43
|
infoTable.push([
|
|
38
44
|
chalk.blue('Time'),
|
|
39
45
|
`${new Date()}`
|
|
@@ -50,8 +56,8 @@ const createStartupLogger = (app)=>{
|
|
|
50
56
|
chalk.blue('Version'),
|
|
51
57
|
`${app.config.info.strapi} (node ${process.version})`
|
|
52
58
|
], [
|
|
53
|
-
chalk.blue('
|
|
54
|
-
|
|
59
|
+
chalk.blue('Plan'),
|
|
60
|
+
getPlan()
|
|
55
61
|
], [
|
|
56
62
|
chalk.blue('Database'),
|
|
57
63
|
dbInfo?.client
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startup-logger.mjs","sources":["../../src/utils/startup-logger.ts"],"sourcesContent":["import chalk from 'chalk';\nimport CLITable from 'cli-table3';\nimport _ from 'lodash/fp';\n\nimport type { Core } from '@strapi/types';\n\nconst ROUNDED_CHARS = {\n top: '─',\n 'top-mid': '┬',\n 'top-left': '╭',\n 'top-right': '╮',\n bottom: '─',\n 'bottom-mid': '┴',\n 'bottom-left': '╰',\n 'bottom-right': '╯',\n left: '│',\n right: '│',\n middle: '│',\n mid: '',\n 'left-mid': '',\n 'mid-mid': '',\n 'right-mid': '',\n};\n\nexport const createStartupLogger = (app: Core.Strapi) => {\n return {\n logStats() {\n const columns = Math.min(process.stderr.columns, 80) - 2;\n console.log();\n console.log(chalk.black.bgWhite(_.padEnd(columns, ' Project information')));\n console.log();\n\n const infoTable = new CLITable({\n colWidths: [20, 50],\n chars: ROUNDED_CHARS,\n });\n\n const dbInfo = app.db?.getInfo();\n\n infoTable.push(\n [chalk.blue('Time'), `${new Date()}`],\n [chalk.blue('Launched in'), `${Date.now() - app.config.launchedAt} ms`],\n [chalk.blue('Environment'), app.config.environment],\n [chalk.blue('Process PID'), process.pid],\n [chalk.blue('Version'), `${app.config.info.strapi} (node ${process.version})`],\n [chalk.blue('
|
|
1
|
+
{"version":3,"file":"startup-logger.mjs","sources":["../../src/utils/startup-logger.ts"],"sourcesContent":["import chalk from 'chalk';\nimport CLITable from 'cli-table3';\nimport _ from 'lodash/fp';\n\nimport type { Core } from '@strapi/types';\n\nconst ROUNDED_CHARS = {\n top: '─',\n 'top-mid': '┬',\n 'top-left': '╭',\n 'top-right': '╮',\n bottom: '─',\n 'bottom-mid': '┴',\n 'bottom-left': '╰',\n 'bottom-right': '╯',\n left: '│',\n right: '│',\n middle: '│',\n mid: '',\n 'left-mid': '',\n 'mid-mid': '',\n 'right-mid': '',\n};\n\nexport const createStartupLogger = (app: Core.Strapi) => {\n return {\n logStats() {\n const columns = Math.min(process.stderr.columns, 80) - 2;\n console.log();\n console.log(chalk.black.bgWhite(_.padEnd(columns, ' Project information')));\n console.log();\n\n const infoTable = new CLITable({\n colWidths: [20, 50],\n chars: ROUNDED_CHARS,\n });\n\n const dbInfo = app.db?.getInfo();\n\n const getPlan = () => {\n if (!app.EE) {\n return 'Community';\n }\n\n return app.ee.planPriceId?.toLowerCase().includes('growth') ? 'Growth' : 'Enterprise';\n };\n\n infoTable.push(\n [chalk.blue('Time'), `${new Date()}`],\n [chalk.blue('Launched in'), `${Date.now() - app.config.launchedAt} ms`],\n [chalk.blue('Environment'), app.config.environment],\n [chalk.blue('Process PID'), process.pid],\n [chalk.blue('Version'), `${app.config.info.strapi} (node ${process.version})`],\n [chalk.blue('Plan'), getPlan()],\n [chalk.blue('Database'), dbInfo?.client],\n [chalk.blue('Database name'), dbInfo?.displayName]\n );\n\n if (dbInfo?.schema) {\n infoTable.push([chalk.blue('Database schema'), dbInfo.schema]);\n }\n\n console.log(infoTable.toString());\n console.log();\n console.log(chalk.black.bgWhite(_.padEnd(columns, ' Actions available')));\n console.log();\n },\n\n logFirstStartupMessage() {\n if (!strapi.config.get('server.logger.startup.enabled')) {\n return;\n }\n\n this.logStats();\n\n console.log(chalk.bold('One more thing...'));\n console.log(\n chalk.grey('Create your first administrator 💻 by going to the administration panel at:')\n );\n console.log();\n\n const addressTable = new CLITable();\n\n const adminUrl = strapi.config.get('admin.absoluteUrl');\n addressTable.push([chalk.bold(adminUrl)]);\n\n console.log(`${addressTable.toString()}`);\n console.log();\n },\n\n logDefaultStartupMessage() {\n if (!strapi.config.get('server.logger.startup.enabled')) {\n return;\n }\n this.logStats();\n\n console.log(chalk.bold('Welcome back!'));\n\n if (app.config.get('admin.serveAdminPanel') === true) {\n console.log(chalk.grey('To manage your project 🚀, go to the administration panel at:'));\n const adminUrl = strapi.config.get('admin.absoluteUrl');\n console.log(chalk.bold(adminUrl));\n console.log();\n }\n\n console.log(chalk.grey('To access the server ⚡️, go to:'));\n const serverUrl = strapi.config.get('server.absoluteUrl');\n console.log(chalk.bold(serverUrl));\n console.log();\n },\n\n logStartupMessage({ isInitialized }: { isInitialized: boolean }) {\n if (!strapi.config.get('server.logger.startup.enabled')) {\n return;\n }\n if (!isInitialized) {\n this.logFirstStartupMessage();\n } else {\n this.logDefaultStartupMessage();\n }\n },\n };\n};\n"],"names":["ROUNDED_CHARS","top","bottom","left","right","middle","mid","createStartupLogger","app","logStats","columns","Math","min","process","stderr","console","log","chalk","black","bgWhite","_","padEnd","infoTable","CLITable","colWidths","chars","dbInfo","db","getInfo","getPlan","EE","ee","planPriceId","toLowerCase","includes","push","blue","Date","now","config","launchedAt","environment","pid","info","strapi","version","client","displayName","schema","toString","logFirstStartupMessage","get","bold","grey","addressTable","adminUrl","logDefaultStartupMessage","serverUrl","logStartupMessage","isInitialized"],"mappings":"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"}
|