@strapi/generators 0.0.0-next.f0a0bc26f5ef0693aaea2a616bc6b816cfee54b6 → 0.0.0-next.f0f36e3df4b18f167036dcbca529dcb933bf4e1d
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/index.d.ts +8 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +89 -50
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +89 -29
- package/dist/index.mjs.map +1 -1
- package/dist/plopfile.js +25 -584
- package/dist/plopfile.js.map +1 -1
- package/dist/plopfile.mjs +24 -581
- package/dist/plopfile.mjs.map +1 -1
- package/dist/plops/api.d.ts.map +1 -1
- package/dist/plops/api.js +149 -0
- package/dist/plops/api.js.map +1 -0
- package/dist/plops/api.mjs +147 -0
- package/dist/plops/api.mjs.map +1 -0
- package/dist/plops/content-type.d.ts.map +1 -1
- package/dist/plops/content-type.js +245 -0
- package/dist/plops/content-type.js.map +1 -0
- package/dist/plops/content-type.mjs +243 -0
- package/dist/plops/content-type.mjs.map +1 -0
- package/dist/plops/controller.d.ts.map +1 -1
- package/dist/plops/controller.js +73 -0
- package/dist/plops/controller.js.map +1 -0
- package/dist/plops/controller.mjs +71 -0
- package/dist/plops/controller.mjs.map +1 -0
- package/dist/plops/middleware.d.ts.map +1 -1
- package/dist/plops/middleware.js +75 -0
- package/dist/plops/middleware.js.map +1 -0
- package/dist/plops/middleware.mjs +73 -0
- package/dist/plops/middleware.mjs.map +1 -0
- package/dist/plops/migration.js +35 -0
- package/dist/plops/migration.js.map +1 -0
- package/dist/plops/migration.mjs +33 -0
- package/dist/plops/migration.mjs.map +1 -0
- package/dist/plops/policy.d.ts.map +1 -1
- package/dist/plops/policy.js +75 -0
- package/dist/plops/policy.js.map +1 -0
- package/dist/plops/policy.mjs +73 -0
- package/dist/plops/policy.mjs.map +1 -0
- package/dist/plops/prompts/bootstrap-api-prompts.d.ts +6 -2
- package/dist/plops/prompts/bootstrap-api-prompts.d.ts.map +1 -1
- package/dist/plops/prompts/bootstrap-api-prompts.js +13 -0
- package/dist/plops/prompts/bootstrap-api-prompts.js.map +1 -0
- package/dist/plops/prompts/bootstrap-api-prompts.mjs +11 -0
- package/dist/plops/prompts/bootstrap-api-prompts.mjs.map +1 -0
- package/dist/plops/prompts/ct-names-prompts.d.ts +18 -2
- package/dist/plops/prompts/ct-names-prompts.d.ts.map +1 -1
- package/dist/plops/prompts/ct-names-prompts.js +44 -0
- package/dist/plops/prompts/ct-names-prompts.js.map +1 -0
- package/dist/plops/prompts/ct-names-prompts.mjs +42 -0
- package/dist/plops/prompts/ct-names-prompts.mjs.map +1 -0
- package/dist/plops/prompts/get-attributes-prompts.d.ts +8 -2
- package/dist/plops/prompts/get-attributes-prompts.d.ts.map +1 -1
- package/dist/plops/prompts/get-attributes-prompts.js +101 -0
- package/dist/plops/prompts/get-attributes-prompts.js.map +1 -0
- package/dist/plops/prompts/get-attributes-prompts.mjs +99 -0
- package/dist/plops/prompts/get-attributes-prompts.mjs.map +1 -0
- package/dist/plops/prompts/get-destination-prompts.d.ts +24 -2
- package/dist/plops/prompts/get-destination-prompts.d.ts.map +1 -1
- package/dist/plops/prompts/get-destination-prompts.js +78 -0
- package/dist/plops/prompts/get-destination-prompts.js.map +1 -0
- package/dist/plops/prompts/get-destination-prompts.mjs +76 -0
- package/dist/plops/prompts/get-destination-prompts.mjs.map +1 -0
- package/dist/plops/prompts/kind-prompts.d.ts +11 -2
- package/dist/plops/prompts/kind-prompts.d.ts.map +1 -1
- package/dist/plops/prompts/kind-prompts.js +26 -0
- package/dist/plops/prompts/kind-prompts.js.map +1 -0
- package/dist/plops/prompts/kind-prompts.mjs +24 -0
- package/dist/plops/prompts/kind-prompts.mjs.map +1 -0
- package/dist/plops/service.d.ts.map +1 -1
- package/dist/plops/service.js +71 -0
- package/dist/plops/service.js.map +1 -0
- package/dist/plops/service.mjs +69 -0
- package/dist/plops/service.mjs.map +1 -0
- package/dist/plops/utils/extend-plugin-index-files.d.ts +8 -0
- package/dist/plops/utils/extend-plugin-index-files.d.ts.map +1 -0
- package/dist/plops/utils/extend-plugin-index-files.js +356 -0
- package/dist/plops/utils/extend-plugin-index-files.js.map +1 -0
- package/dist/plops/utils/extend-plugin-index-files.mjs +335 -0
- package/dist/plops/utils/extend-plugin-index-files.mjs.map +1 -0
- package/dist/plops/utils/get-file-path.d.ts +1 -1
- package/dist/plops/utils/get-file-path.js +17 -0
- package/dist/plops/utils/get-file-path.js.map +1 -0
- package/dist/plops/utils/get-file-path.mjs +15 -0
- package/dist/plops/utils/get-file-path.mjs.map +1 -0
- package/dist/plops/utils/get-formatted-date.js +8 -0
- package/dist/plops/utils/get-formatted-date.js.map +1 -0
- package/dist/plops/utils/get-formatted-date.mjs +6 -0
- package/dist/plops/utils/get-formatted-date.mjs.map +1 -0
- package/dist/plops/utils/validate-attribute-input.js +12 -0
- package/dist/plops/utils/validate-attribute-input.js.map +1 -0
- package/dist/plops/utils/validate-attribute-input.mjs +10 -0
- package/dist/plops/utils/validate-attribute-input.mjs.map +1 -0
- package/dist/plops/utils/validate-file-name-input.js +12 -0
- package/dist/plops/utils/validate-file-name-input.js.map +1 -0
- package/dist/plops/utils/validate-file-name-input.mjs +10 -0
- package/dist/plops/utils/validate-file-name-input.mjs.map +1 -0
- package/dist/plops/utils/validate-input.js +12 -0
- package/dist/plops/utils/validate-input.js.map +1 -0
- package/dist/plops/utils/validate-input.mjs +10 -0
- package/dist/plops/utils/validate-input.mjs.map +1 -0
- package/dist/templates/js/plugin/plugin.index.js.hbs +3 -0
- package/dist/templates/js/plugin/plugin.routes.index.js.hbs +12 -0
- package/dist/templates/js/plugin/plugin.routes.type.index.js.hbs +6 -0
- package/dist/templates/ts/core-controller.ts.hbs +1 -1
- package/dist/templates/ts/plugin/plugin.index.ts.hbs +1 -0
- package/dist/templates/ts/plugin/plugin.routes.index.ts.hbs +9 -0
- package/dist/templates/ts/plugin/plugin.routes.type.index.ts.hbs +4 -0
- package/package.json +17 -12
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-destination-prompts.mjs","sources":["../../../src/plops/prompts/get-destination-prompts.ts"],"sourcesContent":["import { join } from 'path';\nimport fs from 'fs-extra';\n\nexport default (action: string, basePath: string, { rootFolder = false } = {}) => {\n return [\n {\n type: 'list',\n name: 'destination',\n message: `Where do you want to add this ${action}?`,\n choices: [\n ...(rootFolder\n ? [\n {\n name: `Add ${action} to root of project`,\n value: 'root',\n },\n ]\n : [\n {\n name: `Add ${action} to new API`,\n value: 'new',\n },\n ]),\n { name: `Add ${action} to an existing API`, value: 'api' },\n { name: `Add ${action} to an existing plugin`, value: 'plugin' },\n ],\n },\n {\n when: (answers: any) => answers.destination === 'api',\n type: 'list',\n message: 'Which API is this for?',\n name: 'api',\n async choices() {\n const apiPath = join(basePath, 'api');\n const exists = await fs.pathExists(apiPath);\n\n if (!exists) {\n throw Error('Couldn\\'t find an \"api\" directory');\n }\n\n const apiDir = await fs.readdir(apiPath, { withFileTypes: true });\n const apiDirContent = apiDir.filter((fd) => fd.isDirectory());\n\n if (apiDirContent.length === 0) {\n throw Error('The \"api\" directory is empty');\n }\n\n return apiDirContent;\n },\n },\n {\n when: (answers: any) => answers.destination === 'plugin',\n type: 'list',\n message: 'Which plugin is this for?',\n name: 'plugin',\n async choices() {\n const pluginsPath = join(basePath, 'plugins');\n const exists = await fs.pathExists(pluginsPath);\n\n if (!exists) {\n throw Error('Couldn\\'t find a \"plugins\" directory');\n }\n\n const pluginsDir = await fs.readdir(pluginsPath);\n const pluginsDirContent = pluginsDir.filter((api) =>\n fs.lstatSync(join(pluginsPath, api)).isDirectory()\n );\n\n if (pluginsDirContent.length === 0) {\n throw Error('The \"plugins\" directory is empty');\n }\n\n return pluginsDirContent;\n },\n },\n ];\n};\n"],"names":["action","basePath","rootFolder","type","name","message","choices","value","when","answers","destination","apiPath","join","exists","fs","pathExists","Error","apiDir","readdir","withFileTypes","apiDirContent","filter","fd","isDirectory","length","pluginsPath","pluginsDir","pluginsDirContent","api","lstatSync"],"mappings":"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"}
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
declare const questions: {
|
|
2
|
+
type: string;
|
|
3
|
+
name: string;
|
|
4
|
+
message: string;
|
|
5
|
+
default: string;
|
|
6
|
+
choices: {
|
|
7
|
+
name: string;
|
|
8
|
+
value: string;
|
|
9
|
+
}[];
|
|
10
|
+
validate: (input: string) => true | "You must provide an input" | "Please use only letters, '-' and no spaces";
|
|
11
|
+
}[];
|
|
3
12
|
export default questions;
|
|
4
13
|
//# sourceMappingURL=kind-prompts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kind-prompts.d.ts","sourceRoot":"","sources":["../../../src/plops/prompts/kind-prompts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"kind-prompts.d.ts","sourceRoot":"","sources":["../../../src/plops/prompts/kind-prompts.ts"],"names":[],"mappings":"AAEA,QAAA,MAAM,SAAS;;;;;;;;;sBAUO,MAAM;GAE3B,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var validateInput = require('../utils/validate-input.js');
|
|
4
|
+
|
|
5
|
+
const questions = [
|
|
6
|
+
{
|
|
7
|
+
type: 'list',
|
|
8
|
+
name: 'kind',
|
|
9
|
+
message: 'Please choose the model type',
|
|
10
|
+
default: 'collectionType',
|
|
11
|
+
choices: [
|
|
12
|
+
{
|
|
13
|
+
name: 'Collection Type',
|
|
14
|
+
value: 'collectionType'
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: 'Single Type',
|
|
18
|
+
value: 'singleType'
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
validate: (input)=>validateInput(input)
|
|
22
|
+
}
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
module.exports = questions;
|
|
26
|
+
//# sourceMappingURL=kind-prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kind-prompts.js","sources":["../../../src/plops/prompts/kind-prompts.ts"],"sourcesContent":["import validateInput from '../utils/validate-input';\n\nconst questions = [\n {\n type: 'list',\n name: 'kind',\n message: 'Please choose the model type',\n default: 'collectionType',\n choices: [\n { name: 'Collection Type', value: 'collectionType' },\n { name: 'Single Type', value: 'singleType' },\n ],\n validate: (input: string) => validateInput(input),\n },\n];\n\nexport default questions;\n"],"names":["questions","type","name","message","default","choices","value","validate","input","validateInput"],"mappings":";;;;AAEA,MAAMA,SAAY,GAAA;AAChB,IAAA;QACEC,IAAM,EAAA,MAAA;QACNC,IAAM,EAAA,MAAA;QACNC,OAAS,EAAA,8BAAA;QACTC,OAAS,EAAA,gBAAA;QACTC,OAAS,EAAA;AACP,YAAA;gBAAEH,IAAM,EAAA,iBAAA;gBAAmBI,KAAO,EAAA;AAAiB,aAAA;AACnD,YAAA;gBAAEJ,IAAM,EAAA,aAAA;gBAAeI,KAAO,EAAA;AAAa;AAC5C,SAAA;QACDC,QAAU,EAAA,CAACC,QAAkBC,aAAcD,CAAAA,KAAAA;AAC7C;AACD;;;;"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import validateInput from '../utils/validate-input.mjs';
|
|
2
|
+
|
|
3
|
+
const questions = [
|
|
4
|
+
{
|
|
5
|
+
type: 'list',
|
|
6
|
+
name: 'kind',
|
|
7
|
+
message: 'Please choose the model type',
|
|
8
|
+
default: 'collectionType',
|
|
9
|
+
choices: [
|
|
10
|
+
{
|
|
11
|
+
name: 'Collection Type',
|
|
12
|
+
value: 'collectionType'
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
name: 'Single Type',
|
|
16
|
+
value: 'singleType'
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
validate: (input)=>validateInput(input)
|
|
20
|
+
}
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
export { questions as default };
|
|
24
|
+
//# sourceMappingURL=kind-prompts.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kind-prompts.mjs","sources":["../../../src/plops/prompts/kind-prompts.ts"],"sourcesContent":["import validateInput from '../utils/validate-input';\n\nconst questions = [\n {\n type: 'list',\n name: 'kind',\n message: 'Please choose the model type',\n default: 'collectionType',\n choices: [\n { name: 'Collection Type', value: 'collectionType' },\n { name: 'Single Type', value: 'singleType' },\n ],\n validate: (input: string) => validateInput(input),\n },\n];\n\nexport default questions;\n"],"names":["questions","type","name","message","default","choices","value","validate","input","validateInput"],"mappings":";;AAEA,MAAMA,SAAY,GAAA;AAChB,IAAA;QACEC,IAAM,EAAA,MAAA;QACNC,IAAM,EAAA,MAAA;QACNC,OAAS,EAAA,8BAAA;QACTC,OAAS,EAAA,gBAAA;QACTC,OAAS,EAAA;AACP,YAAA;gBAAEH,IAAM,EAAA,iBAAA;gBAAmBI,KAAO,EAAA;AAAiB,aAAA;AACnD,YAAA;gBAAEJ,IAAM,EAAA,aAAA;gBAAeI,KAAO,EAAA;AAAa;AAC5C,SAAA;QACDC,QAAU,EAAA,CAACC,QAAkBC,aAAcD,CAAAA,KAAAA;AAC7C;AACD;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/plops/service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/plops/service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,WAAW,EAAE,MAAM,MAAM,CAAC;+BAS9B,WAAW;AAAjC,wBAmEE"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var tsUtils = require('@strapi/typescript-utils');
|
|
4
|
+
var path = require('path');
|
|
5
|
+
var fs = require('fs');
|
|
6
|
+
var getDestinationPrompts = require('./prompts/get-destination-prompts.js');
|
|
7
|
+
var getFilePath = require('./utils/get-file-path.js');
|
|
8
|
+
var extendPluginIndexFiles = require('./utils/extend-plugin-index-files.js');
|
|
9
|
+
|
|
10
|
+
var generateService = ((plop)=>{
|
|
11
|
+
// Service generator
|
|
12
|
+
plop.setGenerator('service', {
|
|
13
|
+
description: 'Generate a service for an API',
|
|
14
|
+
prompts: [
|
|
15
|
+
{
|
|
16
|
+
type: 'input',
|
|
17
|
+
name: 'id',
|
|
18
|
+
message: 'Service name'
|
|
19
|
+
},
|
|
20
|
+
...getDestinationPrompts('service', plop.getDestBasePath())
|
|
21
|
+
],
|
|
22
|
+
actions (answers) {
|
|
23
|
+
if (!answers) {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
const filePath = getFilePath(answers?.destination);
|
|
27
|
+
const currentDir = process.cwd();
|
|
28
|
+
let language = tsUtils.isUsingTypeScriptSync(currentDir) ? 'ts' : 'js';
|
|
29
|
+
if (answers.plugin) {
|
|
30
|
+
// The tsconfig in plugins is located just outside the server src, not in the root of the plugin.
|
|
31
|
+
const pluginServerDir = path.join(currentDir, 'src', filePath.replace('{{ plugin }}', answers.plugin), '../');
|
|
32
|
+
language = tsUtils.isUsingTypeScriptSync(pluginServerDir) ? 'ts' : 'js';
|
|
33
|
+
}
|
|
34
|
+
const baseActions = [
|
|
35
|
+
{
|
|
36
|
+
type: 'add',
|
|
37
|
+
path: `${filePath}/services/{{ id }}.${language}`,
|
|
38
|
+
templateFile: `templates/${language}/service.${language}.hbs`
|
|
39
|
+
}
|
|
40
|
+
];
|
|
41
|
+
if (answers.plugin) {
|
|
42
|
+
const indexPath = path.join(plop.getDestBasePath(), `${filePath}/services/index.${language}`);
|
|
43
|
+
const exists = fs.existsSync(indexPath);
|
|
44
|
+
if (!exists) {
|
|
45
|
+
// Create index file if it doesn't exist
|
|
46
|
+
baseActions.push({
|
|
47
|
+
type: 'add',
|
|
48
|
+
path: `${filePath}/services/index.${language}`,
|
|
49
|
+
templateFile: `templates/${language}/plugin/plugin.index.${language}.hbs`,
|
|
50
|
+
skipIfExists: true
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
// Append the new service to the index.ts file
|
|
54
|
+
baseActions.push({
|
|
55
|
+
type: 'modify',
|
|
56
|
+
path: `${filePath}/services/index.${language}`,
|
|
57
|
+
transform (template) {
|
|
58
|
+
return extendPluginIndexFiles.appendToFile(template, {
|
|
59
|
+
type: 'index',
|
|
60
|
+
singularName: answers.id
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return baseActions;
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
module.exports = generateService;
|
|
71
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sources":["../../src/plops/service.ts"],"sourcesContent":["import type { ActionType, NodePlopAPI } from 'plop';\nimport tsUtils from '@strapi/typescript-utils';\nimport { join } from 'path';\nimport fs from 'fs';\n\nimport getDestinationPrompts from './prompts/get-destination-prompts';\nimport getFilePath from './utils/get-file-path';\nimport { appendToFile } from './utils/extend-plugin-index-files';\n\nexport default (plop: NodePlopAPI) => {\n // Service generator\n plop.setGenerator('service', {\n description: 'Generate a service for an API',\n prompts: [\n {\n type: 'input',\n name: 'id',\n message: 'Service name',\n },\n ...getDestinationPrompts('service', plop.getDestBasePath()),\n ],\n actions(answers) {\n if (!answers) {\n return [];\n }\n\n const filePath = getFilePath(answers?.destination);\n const currentDir = process.cwd();\n let language = tsUtils.isUsingTypeScriptSync(currentDir) ? 'ts' : 'js';\n\n if (answers.plugin) {\n // The tsconfig in plugins is located just outside the server src, not in the root of the plugin.\n const pluginServerDir = join(\n currentDir,\n 'src',\n filePath.replace('{{ plugin }}', answers.plugin),\n '../'\n );\n language = tsUtils.isUsingTypeScriptSync(pluginServerDir) ? 'ts' : 'js';\n }\n\n const baseActions: Array<ActionType> = [\n {\n type: 'add',\n path: `${filePath}/services/{{ id }}.${language}`,\n templateFile: `templates/${language}/service.${language}.hbs`,\n },\n ];\n\n if (answers.plugin) {\n const indexPath = join(plop.getDestBasePath(), `${filePath}/services/index.${language}`);\n const exists = fs.existsSync(indexPath);\n\n if (!exists) {\n // Create index file if it doesn't exist\n baseActions.push({\n type: 'add',\n path: `${filePath}/services/index.${language}`,\n templateFile: `templates/${language}/plugin/plugin.index.${language}.hbs`,\n skipIfExists: true,\n });\n }\n\n // Append the new service to the index.ts file\n baseActions.push({\n type: 'modify',\n path: `${filePath}/services/index.${language}`,\n transform(template: string) {\n return appendToFile(template, { type: 'index', singularName: answers.id });\n },\n });\n }\n\n return baseActions;\n },\n });\n};\n"],"names":["plop","setGenerator","description","prompts","type","name","message","getDestinationPrompts","getDestBasePath","actions","answers","filePath","getFilePath","destination","currentDir","process","cwd","language","tsUtils","isUsingTypeScriptSync","plugin","pluginServerDir","join","replace","baseActions","path","templateFile","indexPath","exists","fs","existsSync","push","skipIfExists","transform","template","appendToFile","singularName","id"],"mappings":";;;;;;;;;AASA,sBAAe,CAAA,CAACA,IAAAA,GAAAA;;IAEdA,IAAKC,CAAAA,YAAY,CAAC,SAAW,EAAA;QAC3BC,WAAa,EAAA,+BAAA;QACbC,OAAS,EAAA;AACP,YAAA;gBACEC,IAAM,EAAA,OAAA;gBACNC,IAAM,EAAA,IAAA;gBACNC,OAAS,EAAA;AACX,aAAA;eACGC,qBAAsB,CAAA,SAAA,EAAWP,KAAKQ,eAAe,EAAA;AACzD,SAAA;AACDC,QAAAA,OAAAA,CAAAA,CAAQC,OAAO,EAAA;AACb,YAAA,IAAI,CAACA,OAAS,EAAA;AACZ,gBAAA,OAAO,EAAE;AACX;YAEA,MAAMC,QAAAA,GAAWC,YAAYF,OAASG,EAAAA,WAAAA,CAAAA;YACtC,MAAMC,UAAAA,GAAaC,QAAQC,GAAG,EAAA;AAC9B,YAAA,IAAIC,QAAWC,GAAAA,OAAAA,CAAQC,qBAAqB,CAACL,cAAc,IAAO,GAAA,IAAA;YAElE,IAAIJ,OAAAA,CAAQU,MAAM,EAAE;;gBAElB,MAAMC,eAAAA,GAAkBC,SACtBR,CAAAA,UAAAA,EACA,KACAH,EAAAA,QAAAA,CAASY,OAAO,CAAC,cAAA,EAAgBb,OAAQU,CAAAA,MAAM,CAC/C,EAAA,KAAA,CAAA;AAEFH,gBAAAA,QAAAA,GAAWC,OAAQC,CAAAA,qBAAqB,CAACE,eAAAA,CAAAA,GAAmB,IAAO,GAAA,IAAA;AACrE;AAEA,YAAA,MAAMG,WAAiC,GAAA;AACrC,gBAAA;oBACEpB,IAAM,EAAA,KAAA;AACNqB,oBAAAA,IAAAA,EAAM,CAAGd,EAAAA,QAAAA,CAAS,mBAAmB,EAAEM,QAAU,CAAA,CAAA;oBACjDS,YAAc,EAAA,CAAC,UAAU,EAAET,QAAAA,CAAS,SAAS,EAAEA,QAAAA,CAAS,IAAI;AAC9D;AACD,aAAA;YAED,IAAIP,OAAAA,CAAQU,MAAM,EAAE;gBAClB,MAAMO,SAAAA,GAAYL,UAAKtB,IAAKQ,CAAAA,eAAe,IAAI,CAAGG,EAAAA,QAAAA,CAAS,gBAAgB,EAAEM,QAAU,CAAA,CAAA,CAAA;gBACvF,MAAMW,MAAAA,GAASC,EAAGC,CAAAA,UAAU,CAACH,SAAAA,CAAAA;AAE7B,gBAAA,IAAI,CAACC,MAAQ,EAAA;;AAEXJ,oBAAAA,WAAAA,CAAYO,IAAI,CAAC;wBACf3B,IAAM,EAAA,KAAA;AACNqB,wBAAAA,IAAAA,EAAM,CAAGd,EAAAA,QAAAA,CAAS,gBAAgB,EAAEM,QAAU,CAAA,CAAA;wBAC9CS,YAAc,EAAA,CAAC,UAAU,EAAET,QAAAA,CAAS,qBAAqB,EAAEA,QAAAA,CAAS,IAAI,CAAC;wBACzEe,YAAc,EAAA;AAChB,qBAAA,CAAA;AACF;;AAGAR,gBAAAA,WAAAA,CAAYO,IAAI,CAAC;oBACf3B,IAAM,EAAA,QAAA;AACNqB,oBAAAA,IAAAA,EAAM,CAAGd,EAAAA,QAAAA,CAAS,gBAAgB,EAAEM,QAAU,CAAA,CAAA;AAC9CgB,oBAAAA,SAAAA,CAAAA,CAAUC,QAAgB,EAAA;AACxB,wBAAA,OAAOC,oCAAaD,QAAU,EAAA;4BAAE9B,IAAM,EAAA,OAAA;AAASgC,4BAAAA,YAAAA,EAAc1B,QAAQ2B;AAAG,yBAAA,CAAA;AAC1E;AACF,iBAAA,CAAA;AACF;YAEA,OAAOb,WAAAA;AACT;AACF,KAAA,CAAA;AACF,CAAA;;;;"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import tsUtils from '@strapi/typescript-utils';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import getDestinationPrompts from './prompts/get-destination-prompts.mjs';
|
|
5
|
+
import getFilePath from './utils/get-file-path.mjs';
|
|
6
|
+
import { appendToFile } from './utils/extend-plugin-index-files.mjs';
|
|
7
|
+
|
|
8
|
+
var generateService = ((plop)=>{
|
|
9
|
+
// Service generator
|
|
10
|
+
plop.setGenerator('service', {
|
|
11
|
+
description: 'Generate a service for an API',
|
|
12
|
+
prompts: [
|
|
13
|
+
{
|
|
14
|
+
type: 'input',
|
|
15
|
+
name: 'id',
|
|
16
|
+
message: 'Service name'
|
|
17
|
+
},
|
|
18
|
+
...getDestinationPrompts('service', plop.getDestBasePath())
|
|
19
|
+
],
|
|
20
|
+
actions (answers) {
|
|
21
|
+
if (!answers) {
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
24
|
+
const filePath = getFilePath(answers?.destination);
|
|
25
|
+
const currentDir = process.cwd();
|
|
26
|
+
let language = tsUtils.isUsingTypeScriptSync(currentDir) ? 'ts' : 'js';
|
|
27
|
+
if (answers.plugin) {
|
|
28
|
+
// The tsconfig in plugins is located just outside the server src, not in the root of the plugin.
|
|
29
|
+
const pluginServerDir = join(currentDir, 'src', filePath.replace('{{ plugin }}', answers.plugin), '../');
|
|
30
|
+
language = tsUtils.isUsingTypeScriptSync(pluginServerDir) ? 'ts' : 'js';
|
|
31
|
+
}
|
|
32
|
+
const baseActions = [
|
|
33
|
+
{
|
|
34
|
+
type: 'add',
|
|
35
|
+
path: `${filePath}/services/{{ id }}.${language}`,
|
|
36
|
+
templateFile: `templates/${language}/service.${language}.hbs`
|
|
37
|
+
}
|
|
38
|
+
];
|
|
39
|
+
if (answers.plugin) {
|
|
40
|
+
const indexPath = join(plop.getDestBasePath(), `${filePath}/services/index.${language}`);
|
|
41
|
+
const exists = fs.existsSync(indexPath);
|
|
42
|
+
if (!exists) {
|
|
43
|
+
// Create index file if it doesn't exist
|
|
44
|
+
baseActions.push({
|
|
45
|
+
type: 'add',
|
|
46
|
+
path: `${filePath}/services/index.${language}`,
|
|
47
|
+
templateFile: `templates/${language}/plugin/plugin.index.${language}.hbs`,
|
|
48
|
+
skipIfExists: true
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
// Append the new service to the index.ts file
|
|
52
|
+
baseActions.push({
|
|
53
|
+
type: 'modify',
|
|
54
|
+
path: `${filePath}/services/index.${language}`,
|
|
55
|
+
transform (template) {
|
|
56
|
+
return appendToFile(template, {
|
|
57
|
+
type: 'index',
|
|
58
|
+
singularName: answers.id
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return baseActions;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
export { generateService as default };
|
|
69
|
+
//# sourceMappingURL=service.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.mjs","sources":["../../src/plops/service.ts"],"sourcesContent":["import type { ActionType, NodePlopAPI } from 'plop';\nimport tsUtils from '@strapi/typescript-utils';\nimport { join } from 'path';\nimport fs from 'fs';\n\nimport getDestinationPrompts from './prompts/get-destination-prompts';\nimport getFilePath from './utils/get-file-path';\nimport { appendToFile } from './utils/extend-plugin-index-files';\n\nexport default (plop: NodePlopAPI) => {\n // Service generator\n plop.setGenerator('service', {\n description: 'Generate a service for an API',\n prompts: [\n {\n type: 'input',\n name: 'id',\n message: 'Service name',\n },\n ...getDestinationPrompts('service', plop.getDestBasePath()),\n ],\n actions(answers) {\n if (!answers) {\n return [];\n }\n\n const filePath = getFilePath(answers?.destination);\n const currentDir = process.cwd();\n let language = tsUtils.isUsingTypeScriptSync(currentDir) ? 'ts' : 'js';\n\n if (answers.plugin) {\n // The tsconfig in plugins is located just outside the server src, not in the root of the plugin.\n const pluginServerDir = join(\n currentDir,\n 'src',\n filePath.replace('{{ plugin }}', answers.plugin),\n '../'\n );\n language = tsUtils.isUsingTypeScriptSync(pluginServerDir) ? 'ts' : 'js';\n }\n\n const baseActions: Array<ActionType> = [\n {\n type: 'add',\n path: `${filePath}/services/{{ id }}.${language}`,\n templateFile: `templates/${language}/service.${language}.hbs`,\n },\n ];\n\n if (answers.plugin) {\n const indexPath = join(plop.getDestBasePath(), `${filePath}/services/index.${language}`);\n const exists = fs.existsSync(indexPath);\n\n if (!exists) {\n // Create index file if it doesn't exist\n baseActions.push({\n type: 'add',\n path: `${filePath}/services/index.${language}`,\n templateFile: `templates/${language}/plugin/plugin.index.${language}.hbs`,\n skipIfExists: true,\n });\n }\n\n // Append the new service to the index.ts file\n baseActions.push({\n type: 'modify',\n path: `${filePath}/services/index.${language}`,\n transform(template: string) {\n return appendToFile(template, { type: 'index', singularName: answers.id });\n },\n });\n }\n\n return baseActions;\n },\n });\n};\n"],"names":["plop","setGenerator","description","prompts","type","name","message","getDestinationPrompts","getDestBasePath","actions","answers","filePath","getFilePath","destination","currentDir","process","cwd","language","tsUtils","isUsingTypeScriptSync","plugin","pluginServerDir","join","replace","baseActions","path","templateFile","indexPath","exists","fs","existsSync","push","skipIfExists","transform","template","appendToFile","singularName","id"],"mappings":";;;;;;;AASA,sBAAe,CAAA,CAACA,IAAAA,GAAAA;;IAEdA,IAAKC,CAAAA,YAAY,CAAC,SAAW,EAAA;QAC3BC,WAAa,EAAA,+BAAA;QACbC,OAAS,EAAA;AACP,YAAA;gBACEC,IAAM,EAAA,OAAA;gBACNC,IAAM,EAAA,IAAA;gBACNC,OAAS,EAAA;AACX,aAAA;eACGC,qBAAsB,CAAA,SAAA,EAAWP,KAAKQ,eAAe,EAAA;AACzD,SAAA;AACDC,QAAAA,OAAAA,CAAAA,CAAQC,OAAO,EAAA;AACb,YAAA,IAAI,CAACA,OAAS,EAAA;AACZ,gBAAA,OAAO,EAAE;AACX;YAEA,MAAMC,QAAAA,GAAWC,YAAYF,OAASG,EAAAA,WAAAA,CAAAA;YACtC,MAAMC,UAAAA,GAAaC,QAAQC,GAAG,EAAA;AAC9B,YAAA,IAAIC,QAAWC,GAAAA,OAAAA,CAAQC,qBAAqB,CAACL,cAAc,IAAO,GAAA,IAAA;YAElE,IAAIJ,OAAAA,CAAQU,MAAM,EAAE;;gBAElB,MAAMC,eAAAA,GAAkBC,IACtBR,CAAAA,UAAAA,EACA,KACAH,EAAAA,QAAAA,CAASY,OAAO,CAAC,cAAA,EAAgBb,OAAQU,CAAAA,MAAM,CAC/C,EAAA,KAAA,CAAA;AAEFH,gBAAAA,QAAAA,GAAWC,OAAQC,CAAAA,qBAAqB,CAACE,eAAAA,CAAAA,GAAmB,IAAO,GAAA,IAAA;AACrE;AAEA,YAAA,MAAMG,WAAiC,GAAA;AACrC,gBAAA;oBACEpB,IAAM,EAAA,KAAA;AACNqB,oBAAAA,IAAAA,EAAM,CAAGd,EAAAA,QAAAA,CAAS,mBAAmB,EAAEM,QAAU,CAAA,CAAA;oBACjDS,YAAc,EAAA,CAAC,UAAU,EAAET,QAAAA,CAAS,SAAS,EAAEA,QAAAA,CAAS,IAAI;AAC9D;AACD,aAAA;YAED,IAAIP,OAAAA,CAAQU,MAAM,EAAE;gBAClB,MAAMO,SAAAA,GAAYL,KAAKtB,IAAKQ,CAAAA,eAAe,IAAI,CAAGG,EAAAA,QAAAA,CAAS,gBAAgB,EAAEM,QAAU,CAAA,CAAA,CAAA;gBACvF,MAAMW,MAAAA,GAASC,EAAGC,CAAAA,UAAU,CAACH,SAAAA,CAAAA;AAE7B,gBAAA,IAAI,CAACC,MAAQ,EAAA;;AAEXJ,oBAAAA,WAAAA,CAAYO,IAAI,CAAC;wBACf3B,IAAM,EAAA,KAAA;AACNqB,wBAAAA,IAAAA,EAAM,CAAGd,EAAAA,QAAAA,CAAS,gBAAgB,EAAEM,QAAU,CAAA,CAAA;wBAC9CS,YAAc,EAAA,CAAC,UAAU,EAAET,QAAAA,CAAS,qBAAqB,EAAEA,QAAAA,CAAS,IAAI,CAAC;wBACzEe,YAAc,EAAA;AAChB,qBAAA,CAAA;AACF;;AAGAR,gBAAAA,WAAAA,CAAYO,IAAI,CAAC;oBACf3B,IAAM,EAAA,QAAA;AACNqB,oBAAAA,IAAAA,EAAM,CAAGd,EAAAA,QAAAA,CAAS,gBAAgB,EAAEM,QAAU,CAAA,CAAA;AAC9CgB,oBAAAA,SAAAA,CAAAA,CAAUC,QAAgB,EAAA;AACxB,wBAAA,OAAOC,aAAaD,QAAU,EAAA;4BAAE9B,IAAM,EAAA,OAAA;AAASgC,4BAAAA,YAAAA,EAAc1B,QAAQ2B;AAAG,yBAAA,CAAA;AAC1E;AACF,iBAAA,CAAA;AACF;YAEA,OAAOb,WAAAA;AACT;AACF,KAAA,CAAA;AACF,CAAA;;;;"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type AppendType = 'content-type' | 'index' | 'routes';
|
|
2
|
+
interface AppendConfig {
|
|
3
|
+
type: AppendType;
|
|
4
|
+
singularName: string;
|
|
5
|
+
}
|
|
6
|
+
export declare const appendToFile: (template: string, config: AppendConfig) => string;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=extend-plugin-index-files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extend-plugin-index-files.d.ts","sourceRoot":"","sources":["../../../src/plops/utils/extend-plugin-index-files.ts"],"names":[],"mappings":"AAKA,KAAK,UAAU,GAAG,cAAc,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEtD,UAAU,YAAY;IACpB,IAAI,EAAE,UAAU,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAsHD,eAAO,MAAM,YAAY,aAAc,MAAM,UAAU,YAAY,KAAG,MAuBrE,CAAC"}
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jscodeshift = require('jscodeshift');
|
|
4
|
+
var camelCase = require('lodash/camelCase');
|
|
5
|
+
|
|
6
|
+
function _interopNamespaceDefault(e) {
|
|
7
|
+
var n = Object.create(null);
|
|
8
|
+
if (e) {
|
|
9
|
+
Object.keys(e).forEach(function (k) {
|
|
10
|
+
if (k !== 'default') {
|
|
11
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
12
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () { return e[k]; }
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
n.default = e;
|
|
20
|
+
return Object.freeze(n);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
var jscodeshift__namespace = /*#__PURE__*/_interopNamespaceDefault(jscodeshift);
|
|
24
|
+
|
|
25
|
+
const j = jscodeshift__namespace.withParser('tsx');
|
|
26
|
+
// Helper to check if a string is a valid JavaScript identifier
|
|
27
|
+
const isValidIdentifier = (str)=>{
|
|
28
|
+
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(str);
|
|
29
|
+
};
|
|
30
|
+
// Helper to create the appropriate property based on type
|
|
31
|
+
const createProperty = (config)=>{
|
|
32
|
+
const { type, singularName } = config;
|
|
33
|
+
const camelCaseName = camelCase(singularName);
|
|
34
|
+
const varName = type === 'content-type' ? `${camelCaseName}Schema` : camelCaseName;
|
|
35
|
+
// Use string literal for key only if singularName is not a valid identifier
|
|
36
|
+
const keyNode = isValidIdentifier(singularName) ? j.identifier(singularName) : j.literal(singularName);
|
|
37
|
+
switch(type){
|
|
38
|
+
case 'content-type':
|
|
39
|
+
return j.objectProperty(keyNode, j.objectExpression([
|
|
40
|
+
j.objectProperty(j.identifier('schema'), j.identifier(varName))
|
|
41
|
+
]));
|
|
42
|
+
case 'index':
|
|
43
|
+
return j.objectProperty(keyNode, j.identifier(varName));
|
|
44
|
+
case 'routes':
|
|
45
|
+
return j.spreadElement(j.memberExpression(j.identifier(varName), j.identifier('routes')));
|
|
46
|
+
default:
|
|
47
|
+
throw new Error(`Unknown append type: ${type}`);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
// Helper to check if property already exists
|
|
51
|
+
const hasExistingProperty = (obj, config)=>{
|
|
52
|
+
const { type, singularName } = config;
|
|
53
|
+
if (!obj?.properties && !j.ArrayExpression.check(obj)) return false;
|
|
54
|
+
const elements = j.ArrayExpression.check(obj) ? obj.elements : obj.properties;
|
|
55
|
+
if (!elements) return false;
|
|
56
|
+
if (type === 'routes') {
|
|
57
|
+
// Check for spread elements ...camelCaseName.routes
|
|
58
|
+
const camelCaseName = camelCase(singularName);
|
|
59
|
+
return elements.some((element)=>j.SpreadElement.check(element) && j.MemberExpression.check(element.argument) && j.Identifier.check(element.argument.object) && element.argument.object.name === camelCaseName && j.Identifier.check(element.argument.property) && element.argument.property.name === 'routes');
|
|
60
|
+
}
|
|
61
|
+
// For content-type and index, check for object property (both identifier and literal keys)
|
|
62
|
+
return elements.some((prop)=>j.ObjectProperty.check(prop) && (j.Identifier.check(prop.key) && prop.key.name === singularName || j.Literal.check(prop.key) && prop.key.value === singularName));
|
|
63
|
+
};
|
|
64
|
+
// Helper to add property to object if it doesn't exist
|
|
65
|
+
const addPropertyToObject = (obj, config)=>{
|
|
66
|
+
if (!obj || hasExistingProperty(obj, config)) return;
|
|
67
|
+
if (config.type === 'routes' && j.ArrayExpression.check(obj)) {
|
|
68
|
+
obj.elements.push(createRoutesElement(config));
|
|
69
|
+
} else if (obj.properties?.length >= 0) {
|
|
70
|
+
obj.properties.push(createProperty(config));
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
// Helper to find and add to routes array
|
|
74
|
+
const handleRoutesArray = (obj, config)=>{
|
|
75
|
+
if (!obj?.properties) return false;
|
|
76
|
+
const routesProp = obj.properties.find((prop)=>j.ObjectProperty.check(prop) && (j.Identifier.check(prop.key) && prop.key.name === 'routes' || j.Literal.check(prop.key) && prop.key.value === 'routes') && j.ArrayExpression.check(prop.value));
|
|
77
|
+
if (routesProp?.value) {
|
|
78
|
+
const routesArray = routesProp.value;
|
|
79
|
+
if (!hasExistingProperty(routesArray, config)) {
|
|
80
|
+
routesArray.elements = routesArray.elements || [];
|
|
81
|
+
routesArray.elements.push(createRoutesElement(config));
|
|
82
|
+
}
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
return false;
|
|
86
|
+
};
|
|
87
|
+
// Helper to create routes array element (always returns SpreadElement for routes)
|
|
88
|
+
const createRoutesElement = (config)=>{
|
|
89
|
+
const { singularName } = config;
|
|
90
|
+
const camelCaseName = camelCase(singularName);
|
|
91
|
+
return j.spreadElement(j.memberExpression(j.identifier(camelCaseName), j.identifier('routes')));
|
|
92
|
+
};
|
|
93
|
+
// Helper to create new export for routes
|
|
94
|
+
const createRoutesExport = (config)=>{
|
|
95
|
+
return j.arrowFunctionExpression([], j.objectExpression([
|
|
96
|
+
j.objectProperty(j.identifier('type'), j.literal('content-api')),
|
|
97
|
+
j.objectProperty(j.identifier('routes'), j.arrayExpression([
|
|
98
|
+
createRoutesElement(config)
|
|
99
|
+
]))
|
|
100
|
+
]));
|
|
101
|
+
};
|
|
102
|
+
// Unified append function for all types
|
|
103
|
+
const appendToFile = (template, config)=>{
|
|
104
|
+
if (!config?.singularName || !config?.type) {
|
|
105
|
+
throw new Error('Invalid config: singularName and type are required');
|
|
106
|
+
}
|
|
107
|
+
const normalizedTemplate = template?.trim() || '';
|
|
108
|
+
const root = normalizedTemplate ? j(normalizedTemplate) : j(j.program([]));
|
|
109
|
+
const { type, singularName } = config;
|
|
110
|
+
const isEsm = detectModuleFormat(normalizedTemplate) === 'esm';
|
|
111
|
+
const camelCaseName = camelCase(singularName);
|
|
112
|
+
const varName = type === 'content-type' ? `${camelCaseName}Schema` : camelCaseName;
|
|
113
|
+
const source = type === 'content-type' ? `./${singularName}/schema.json` : `./${singularName}`;
|
|
114
|
+
addImportIfMissing(root, varName, source, isEsm);
|
|
115
|
+
if (isEsm) {
|
|
116
|
+
handleEsmExport(root, config, type);
|
|
117
|
+
} else {
|
|
118
|
+
handleCjsExport(root, config, type);
|
|
119
|
+
}
|
|
120
|
+
return root.toSource({
|
|
121
|
+
quote: 'single'
|
|
122
|
+
});
|
|
123
|
+
};
|
|
124
|
+
// Helper to detect module format
|
|
125
|
+
const detectModuleFormat = (template)=>{
|
|
126
|
+
const hasImport = /^import\s/.test(template) || template.includes('import ');
|
|
127
|
+
const hasExportDefault = template.includes('export default');
|
|
128
|
+
const hasRequire = template.includes('require(');
|
|
129
|
+
const hasModuleExports = template.includes('module.exports');
|
|
130
|
+
if (hasImport || hasExportDefault) return 'esm';
|
|
131
|
+
if (hasRequire || hasModuleExports) return 'cjs';
|
|
132
|
+
return 'esm'; // Default to ESM
|
|
133
|
+
};
|
|
134
|
+
// Helper to insert statement at appropriate location
|
|
135
|
+
const insertStatement = (root, statement, preferredLocation)=>{
|
|
136
|
+
if (preferredLocation && preferredLocation.length > 0) {
|
|
137
|
+
preferredLocation.at(-1).insertAfter(statement);
|
|
138
|
+
} else {
|
|
139
|
+
const firstStatement = root.find(j.Statement).at(0);
|
|
140
|
+
if (firstStatement.length > 0) {
|
|
141
|
+
firstStatement.insertBefore(statement);
|
|
142
|
+
} else {
|
|
143
|
+
handleEmptyFile(root, statement);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
// Helper to add import/require if missing
|
|
148
|
+
const addImportIfMissing = (root, varName, source, isEsm)=>{
|
|
149
|
+
if (isEsm) {
|
|
150
|
+
if (root.find(j.ImportDeclaration, {
|
|
151
|
+
source: {
|
|
152
|
+
value: source
|
|
153
|
+
}
|
|
154
|
+
}).length === 0) {
|
|
155
|
+
const importDecl = j.importDeclaration([
|
|
156
|
+
j.importDefaultSpecifier(j.identifier(varName))
|
|
157
|
+
], j.literal(source));
|
|
158
|
+
insertStatement(root, importDecl, root.find(j.ImportDeclaration));
|
|
159
|
+
}
|
|
160
|
+
} else if (root.find(j.VariableDeclarator, {
|
|
161
|
+
id: {
|
|
162
|
+
name: varName
|
|
163
|
+
},
|
|
164
|
+
init: {
|
|
165
|
+
type: 'CallExpression',
|
|
166
|
+
callee: {
|
|
167
|
+
name: 'require'
|
|
168
|
+
},
|
|
169
|
+
arguments: [
|
|
170
|
+
{
|
|
171
|
+
value: source
|
|
172
|
+
}
|
|
173
|
+
]
|
|
174
|
+
}
|
|
175
|
+
}).length === 0) {
|
|
176
|
+
const requireStmt = j.variableDeclaration('const', [
|
|
177
|
+
j.variableDeclarator(j.identifier(varName), j.callExpression(j.identifier('require'), [
|
|
178
|
+
j.literal(source)
|
|
179
|
+
]))
|
|
180
|
+
]);
|
|
181
|
+
const requires = root.find(j.VariableDeclaration).filter((path)=>path.value.declarations.some((decl)=>j.CallExpression.check(decl.init) && decl.init.callee?.name === 'require'));
|
|
182
|
+
const useStrict = root.find(j.ExpressionStatement).filter((path)=>j.Literal.check(path.value.expression) && /use strict/.test(String(path.value.expression.value)));
|
|
183
|
+
insertStatement(root, requireStmt, requires.length > 0 ? requires : useStrict);
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
// Helper to safely handle empty files
|
|
187
|
+
const handleEmptyFile = (root, firstStatement)=>{
|
|
188
|
+
try {
|
|
189
|
+
// Check if we have any paths in the collection
|
|
190
|
+
const paths = root.paths();
|
|
191
|
+
if (paths.length === 0) {
|
|
192
|
+
// Completely empty collection - create new program
|
|
193
|
+
const newProgram = j.program([
|
|
194
|
+
firstStatement
|
|
195
|
+
]);
|
|
196
|
+
// Replace the entire root with new program
|
|
197
|
+
return root.replaceWith(newProgram);
|
|
198
|
+
}
|
|
199
|
+
// Get the first path (should be the program)
|
|
200
|
+
const rootPath = paths[0];
|
|
201
|
+
if (!rootPath || !rootPath.value) {
|
|
202
|
+
// Invalid root path - create new program
|
|
203
|
+
const newProgram = j.program([
|
|
204
|
+
firstStatement
|
|
205
|
+
]);
|
|
206
|
+
return root.replaceWith(newProgram);
|
|
207
|
+
}
|
|
208
|
+
// Check if it's a valid program node
|
|
209
|
+
if (j.Program.check(rootPath.value)) {
|
|
210
|
+
// Ensure body exists and add statement
|
|
211
|
+
if (!rootPath.value.body) {
|
|
212
|
+
rootPath.value.body = [];
|
|
213
|
+
}
|
|
214
|
+
rootPath.value.body.push(firstStatement);
|
|
215
|
+
} else {
|
|
216
|
+
// Not a program node - replace with new program
|
|
217
|
+
const newProgram = j.program([
|
|
218
|
+
firstStatement
|
|
219
|
+
]);
|
|
220
|
+
rootPath.replace(newProgram);
|
|
221
|
+
}
|
|
222
|
+
} catch (error) {
|
|
223
|
+
// Ultimate fallback - create a minimal working file
|
|
224
|
+
console.warn('Failed to handle empty file, creating new program:', error.message);
|
|
225
|
+
const newProgram = j.program([
|
|
226
|
+
firstStatement
|
|
227
|
+
]);
|
|
228
|
+
try {
|
|
229
|
+
root.replaceWith(newProgram);
|
|
230
|
+
} catch (replaceError) {
|
|
231
|
+
// Last resort - throw descriptive error
|
|
232
|
+
throw new Error(`Unable to add statement to empty file: ${error.message}. Root collection may be invalid.`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
// Helper to find the exported object regardless of export pattern
|
|
237
|
+
const findExportedObject = (root, exportedValue)=>{
|
|
238
|
+
// Case 1: Direct object export
|
|
239
|
+
if (j.ObjectExpression.check(exportedValue)) {
|
|
240
|
+
return exportedValue;
|
|
241
|
+
}
|
|
242
|
+
// Case 2: Function that returns an object
|
|
243
|
+
if (j.FunctionExpression.check(exportedValue) || j.ArrowFunctionExpression.check(exportedValue) || j.FunctionDeclaration.check(exportedValue)) {
|
|
244
|
+
const body = exportedValue.body;
|
|
245
|
+
// Arrow function with object expression body: () => ({...})
|
|
246
|
+
if (j.ObjectExpression.check(body)) {
|
|
247
|
+
return body;
|
|
248
|
+
}
|
|
249
|
+
// Function with return statement in block
|
|
250
|
+
if (j.BlockStatement.check(body)) {
|
|
251
|
+
for (const stmt of body.body){
|
|
252
|
+
if (j.ReturnStatement.check(stmt) && j.ObjectExpression.check(stmt.argument)) {
|
|
253
|
+
return stmt.argument;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
// Case 3: Identifier reference to a variable
|
|
259
|
+
if (j.Identifier.check(exportedValue)) {
|
|
260
|
+
const varName = exportedValue.name;
|
|
261
|
+
// Find the variable declaration
|
|
262
|
+
const varDeclaration = root.find(j.VariableDeclarator, {
|
|
263
|
+
id: {
|
|
264
|
+
name: varName
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
if (varDeclaration.length > 0) {
|
|
268
|
+
const init = varDeclaration.get().value.init;
|
|
269
|
+
// If it's an object, return it
|
|
270
|
+
if (j.ObjectExpression.check(init)) {
|
|
271
|
+
return init;
|
|
272
|
+
}
|
|
273
|
+
// If it's a function, recursively check its return value
|
|
274
|
+
if (j.FunctionExpression.check(init) || j.ArrowFunctionExpression.check(init)) {
|
|
275
|
+
return findExportedObject(root, init);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return null;
|
|
280
|
+
};
|
|
281
|
+
// Helper to handle object export (common logic for ESM and CJS)
|
|
282
|
+
const handleObjectExport = (obj, config, type, setExport)=>{
|
|
283
|
+
if (type === 'routes') {
|
|
284
|
+
if (!handleRoutesArray(obj, config)) {
|
|
285
|
+
setExport(createRoutesExport(config));
|
|
286
|
+
}
|
|
287
|
+
} else {
|
|
288
|
+
addPropertyToObject(obj, config);
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
// Handle ESM export default
|
|
292
|
+
const handleEsmExport = (root, config, type)=>{
|
|
293
|
+
const exports = root.find(j.ExportDefaultDeclaration);
|
|
294
|
+
if (exports.length === 0) {
|
|
295
|
+
const newExport = type === 'routes' ? createRoutesExport(config) : j.objectExpression([
|
|
296
|
+
createProperty(config)
|
|
297
|
+
]);
|
|
298
|
+
insertStatement(root, j.exportDefaultDeclaration(newExport), root.find(j.Statement));
|
|
299
|
+
} else {
|
|
300
|
+
exports.forEach((path)=>{
|
|
301
|
+
const decl = path.value.declaration;
|
|
302
|
+
// Find the actual object being exported
|
|
303
|
+
const exportedObject = findExportedObject(root, decl);
|
|
304
|
+
if (exportedObject) {
|
|
305
|
+
handleObjectExport(exportedObject, config, type, (newExport)=>{
|
|
306
|
+
path.value.declaration = newExport;
|
|
307
|
+
});
|
|
308
|
+
} else {
|
|
309
|
+
// Fallback: replace the entire export
|
|
310
|
+
path.value.declaration = type === 'routes' ? createRoutesExport(config) : j.objectExpression([
|
|
311
|
+
createProperty(config)
|
|
312
|
+
]);
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
// Handle CJS module.exports
|
|
318
|
+
const handleCjsExport = (root, config, type)=>{
|
|
319
|
+
const exports = root.find(j.AssignmentExpression, {
|
|
320
|
+
left: {
|
|
321
|
+
type: 'MemberExpression',
|
|
322
|
+
object: {
|
|
323
|
+
name: 'module'
|
|
324
|
+
},
|
|
325
|
+
property: {
|
|
326
|
+
name: 'exports'
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
if (exports.length === 0) {
|
|
331
|
+
const newExport = type === 'routes' ? createRoutesExport(config) : j.objectExpression([
|
|
332
|
+
createProperty(config)
|
|
333
|
+
]);
|
|
334
|
+
const moduleExportStmt = j.expressionStatement(j.assignmentExpression('=', j.memberExpression(j.identifier('module'), j.identifier('exports')), newExport));
|
|
335
|
+
insertStatement(root, moduleExportStmt, root.find(j.Statement));
|
|
336
|
+
} else {
|
|
337
|
+
exports.forEach((path)=>{
|
|
338
|
+
const right = path.value.right;
|
|
339
|
+
// Find the actual object being exported
|
|
340
|
+
const exportedObject = findExportedObject(root, right);
|
|
341
|
+
if (exportedObject) {
|
|
342
|
+
handleObjectExport(exportedObject, config, type, (newExport)=>{
|
|
343
|
+
path.value.right = newExport;
|
|
344
|
+
});
|
|
345
|
+
} else {
|
|
346
|
+
// Fallback: replace the entire export
|
|
347
|
+
path.value.right = type === 'routes' ? createRoutesExport(config) : j.objectExpression([
|
|
348
|
+
createProperty(config)
|
|
349
|
+
]);
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
exports.appendToFile = appendToFile;
|
|
356
|
+
//# sourceMappingURL=extend-plugin-index-files.js.map
|