@popina/cli 5.0.0-20260203082304Z → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/package.json +3 -3
- package/turbo/generators/config.ts +11 -0
- package/turbo/generators/package.json +3 -0
- package/turbo/generators/plopGenerator/api.ts +456 -0
- package/turbo/generators/plopGenerator/component.ts +63 -0
- package/turbo/generators/plopGenerator/icon.ts +201 -0
- package/turbo/generators/templates/api/api-controller.hbs +46 -0
- package/turbo/generators/templates/api/api-param-schema.hbs +22 -0
- package/turbo/generators/templates/api/api-router.hbs +28 -0
- package/turbo/generators/templates/api/api-schema.hbs +90 -0
- package/turbo/generators/templates/api/api-service.hbs +42 -0
- package/turbo/generators/templates/component/component-index.hbs +1 -0
- package/turbo/generators/templates/component/component-react.hbs +14 -0
- package/turbo/generators/templates/component/component-story.hbs +21 -0
- package/turbo/generators/templates/component/component-test.hbs +14 -0
- package/turbo/generators/templates/icon/icon-react.hbs +32 -0
- package/build/index.d.ts +0 -1
- package/build/index.js +0 -12861
- package/build/index.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @popina/cli
|
|
2
2
|
|
|
3
|
+
## 5.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- Rename @fveauvy/cli to @popina/cli.
|
|
8
|
+
|
|
9
|
+
We now manage entirely publishing of our CLI.
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- Migrate from @pragma/cli to @popina/cli package.
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Popina CLI generate command now uses turbo generators from packages/cli/turbo/ instead of turbo/.
|
|
18
|
+
- Bump vitest config from 0.x.x to 4.0.17
|
|
19
|
+
- Add metadata to Popina CLI package
|
|
20
|
+
- Change package name to Popina CLI
|
|
21
|
+
|
|
3
22
|
## 4.5.0
|
|
4
23
|
|
|
5
24
|
### Minor Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@popina/cli",
|
|
3
|
-
"version": "5.0.0
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"description": "Popina CLI",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"author": "François Veauvy",
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"eslint": "^9.19.0",
|
|
23
|
-
"@pragma/
|
|
24
|
-
"@pragma/
|
|
23
|
+
"@pragma/config": "3.0.0",
|
|
24
|
+
"@pragma/eslint": "1.3.5",
|
|
25
25
|
"@pragma/tsconfig": "1.0.2"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PlopTypes } from '@turbo/gen'
|
|
2
|
+
|
|
3
|
+
import { generatorApi } from './plopGenerator/api'
|
|
4
|
+
import { generatorComponent } from './plopGenerator/component'
|
|
5
|
+
import { generatorIcon } from './plopGenerator/icon'
|
|
6
|
+
|
|
7
|
+
export default function generator(plop: PlopTypes.NodePlopAPI): void {
|
|
8
|
+
generatorComponent(plop)
|
|
9
|
+
generatorIcon(plop)
|
|
10
|
+
generatorApi(plop)
|
|
11
|
+
}
|
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import type { PlopTypes } from '@turbo/gen'
|
|
4
|
+
import pluralize from 'pluralize'
|
|
5
|
+
|
|
6
|
+
type EndpointActionValues = {
|
|
7
|
+
actionName: string
|
|
8
|
+
entityName: string
|
|
9
|
+
zodElementarySchemaDefinition: string
|
|
10
|
+
zodSchemaDefinitionName: string
|
|
11
|
+
typeName: string
|
|
12
|
+
fastifySchemaName: string
|
|
13
|
+
fastifyDescription: string
|
|
14
|
+
fastifySummary: string
|
|
15
|
+
fastifyOperationId: string
|
|
16
|
+
verb: string
|
|
17
|
+
responseCode: number
|
|
18
|
+
route: string
|
|
19
|
+
isAParamRoute?: boolean
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const generatorApi = (plop: PlopTypes.NodePlopAPI) => {
|
|
23
|
+
plop.setGenerator('api', {
|
|
24
|
+
description: 'Create a new API endpoint',
|
|
25
|
+
prompts: [
|
|
26
|
+
{
|
|
27
|
+
type: 'list',
|
|
28
|
+
name: 'apiDirectory',
|
|
29
|
+
message:
|
|
30
|
+
'What is the new API directory in which you want to create the endpoint(s) ?',
|
|
31
|
+
choices: () => {
|
|
32
|
+
return fs
|
|
33
|
+
.readdirSync(path.join(plop.getDestBasePath(), '/apps/'))
|
|
34
|
+
.filter(
|
|
35
|
+
(f) =>
|
|
36
|
+
fs
|
|
37
|
+
.statSync(path.join(plop.getDestBasePath() + '/apps/', f))
|
|
38
|
+
.isDirectory() && f.startsWith('api'),
|
|
39
|
+
)
|
|
40
|
+
.map((f) => ({
|
|
41
|
+
name: f,
|
|
42
|
+
value: f,
|
|
43
|
+
}))
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
type: 'input',
|
|
48
|
+
name: 'modulePath',
|
|
49
|
+
message:
|
|
50
|
+
"What is the name of the new module to create the endpoints in ? (e.g: 'auth', 'v1/auth')",
|
|
51
|
+
validate: (input: string) => {
|
|
52
|
+
if (!input) {
|
|
53
|
+
return 'module name is required'
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (input.match(/^([a-zA-Z0-9]+)(\/[a-zA-Z0-9]+)*$/)) {
|
|
57
|
+
return true
|
|
58
|
+
} else {
|
|
59
|
+
return 'Malformed module name must only contain alphanumeric characters [a-zA-Z0-9] and slashes (no slashes at the beginning or end & at least one character between slashes)'
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
type: 'checkbox',
|
|
65
|
+
name: 'endpointActions',
|
|
66
|
+
message: 'What is the action(s) of the module ?',
|
|
67
|
+
choices: (inputs) => {
|
|
68
|
+
const entity = pluralize.singular(inputs.modulePath.split('/').pop())
|
|
69
|
+
const pluralEntity = pluralize.plural(entity)
|
|
70
|
+
const capitalizedEntity = entity[0].toUpperCase() + entity.slice(1)
|
|
71
|
+
const capitalizedPluralEntity =
|
|
72
|
+
pluralEntity[0].toUpperCase() + pluralEntity.slice(1)
|
|
73
|
+
|
|
74
|
+
return [
|
|
75
|
+
{
|
|
76
|
+
name: `getOne${capitalizedEntity}`,
|
|
77
|
+
value: {
|
|
78
|
+
actionName: `getOne${capitalizedEntity}`,
|
|
79
|
+
entityName: entity,
|
|
80
|
+
zodElementarySchemaDefinition: `fetch${capitalizedEntity}Output`,
|
|
81
|
+
zodSchemaDefinitionName: `fetch${capitalizedEntity}ReplySchema`,
|
|
82
|
+
typeName: `${capitalizedEntity}OutputType`,
|
|
83
|
+
fastifySchemaName: `fetch${capitalizedEntity}Schema`,
|
|
84
|
+
fastifyDescription: `Fetch one ${entity} based on the ${entity} id`,
|
|
85
|
+
fastifySummary: `fetch a ${entity}`,
|
|
86
|
+
fastifyOperationId: `fetch-${entity}`,
|
|
87
|
+
verb: 'get',
|
|
88
|
+
responseCode: 200,
|
|
89
|
+
route: '/:id',
|
|
90
|
+
isAParamRoute: true,
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: `getMany${capitalizedPluralEntity}`,
|
|
95
|
+
value: {
|
|
96
|
+
actionName: `getMany${capitalizedPluralEntity}`,
|
|
97
|
+
entityName: entity,
|
|
98
|
+
zodElementarySchemaDefinition: `fetch${capitalizedPluralEntity}ListOutput`,
|
|
99
|
+
zodSchemaDefinitionName: `fetch${capitalizedPluralEntity}ListReplySchema`,
|
|
100
|
+
typeName: `${capitalizedPluralEntity}ListOutputType`,
|
|
101
|
+
fastifySchemaName: `fetch${capitalizedPluralEntity}ListSchema`,
|
|
102
|
+
fastifyDescription: `Fetch many ${pluralEntity}`,
|
|
103
|
+
fastifySummary: `fetch a list of ${pluralEntity}`,
|
|
104
|
+
fastifyOperationId: `fetch-many-${pluralEntity}`,
|
|
105
|
+
verb: 'get',
|
|
106
|
+
responseCode: 200,
|
|
107
|
+
route: '/',
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
name: 'custom',
|
|
112
|
+
value: {
|
|
113
|
+
entityName: 'custom',
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
]
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
when: (inputs) => {
|
|
121
|
+
return inputs.endpointActions.some(
|
|
122
|
+
(action: EndpointActionValues) => action.entityName === 'custom',
|
|
123
|
+
)
|
|
124
|
+
},
|
|
125
|
+
type: 'input',
|
|
126
|
+
name: 'customName',
|
|
127
|
+
message: 'What is the name of the custom endpoint ?',
|
|
128
|
+
validate(input, answers) {
|
|
129
|
+
if (!input) {
|
|
130
|
+
return 'custom endpoint name is required'
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (input.match(/^([a-zA-Z0-9]+)(\/[a-zA-Z0-9]+)*$/) && answers) {
|
|
134
|
+
answers.endpointActions.find((action: EndpointActionValues) => {
|
|
135
|
+
if (action.entityName === 'custom') {
|
|
136
|
+
action.actionName = input
|
|
137
|
+
action.entityName = answers.modulePath.split('/').pop()
|
|
138
|
+
action.zodElementarySchemaDefinition = input
|
|
139
|
+
action.zodSchemaDefinitionName = input + 'Schema'
|
|
140
|
+
action.typeName =
|
|
141
|
+
input[0].toUpperCase() + input.slice(1) + 'Type'
|
|
142
|
+
action.fastifySchemaName = input + 'FastifySchema'
|
|
143
|
+
action.fastifyDescription =
|
|
144
|
+
'Please set the description of the custom endpoint'
|
|
145
|
+
action.fastifySummary =
|
|
146
|
+
'Please set the summary of the custom endpoint'
|
|
147
|
+
action.fastifyOperationId = input
|
|
148
|
+
action.verb = 'get'
|
|
149
|
+
action.responseCode = 200
|
|
150
|
+
action.route = '/'
|
|
151
|
+
}
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
console.log(answers.endpointActions)
|
|
155
|
+
|
|
156
|
+
return true
|
|
157
|
+
} else {
|
|
158
|
+
return 'Malformed custom endpoint name must only contain alphanumeric characters [a-zA-Z0-9] and slashes (no slashes at the beginning or end & at least one character between slashes)'
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
actions: function (data) {
|
|
164
|
+
const entity = data?.modulePath.split('/').pop()
|
|
165
|
+
const actions: PlopTypes.Actions = [
|
|
166
|
+
{
|
|
167
|
+
type: 'add',
|
|
168
|
+
path: `{{ turbo.paths.root }}/apps/{{apiDirectory}}/src/modules/{{modulePath}}/${entity}.schema.ts`,
|
|
169
|
+
templateFile: 'templates/api/api-schema.hbs',
|
|
170
|
+
abortOnFail: true,
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
type: 'add',
|
|
174
|
+
path: `{{ turbo.paths.root }}/apps/{{apiDirectory}}/src/modules/{{modulePath}}/${entity}.router.ts`,
|
|
175
|
+
templateFile: 'templates/api/api-router.hbs',
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
type: 'add',
|
|
179
|
+
path: `{{ turbo.paths.root }}/apps/{{apiDirectory}}/src/modules/{{modulePath}}/${entity}.controller.ts`,
|
|
180
|
+
templateFile: 'templates/api/api-controller.hbs',
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
type: 'add',
|
|
184
|
+
path: `{{ turbo.paths.root }}/apps/{{apiDirectory}}/src/modules/{{modulePath}}/${entity}.service.ts`,
|
|
185
|
+
templateFile: 'templates/api/api-service.hbs',
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
type: 'modify',
|
|
189
|
+
path: `{{ turbo.paths.root }}/apps/{{apiDirectory}}/src/schemas.ts`,
|
|
190
|
+
pattern: /(?<=(import.*'\.\/modules.*schema')).*(?=(\n\n))/gm,
|
|
191
|
+
template: `\nimport { ${entity}Schemas } from './modules/{{modulePath}}/${entity}.schema'`,
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
type: 'modify',
|
|
195
|
+
path: `{{ turbo.paths.root }}/apps/{{apiDirectory}}/src/schemas.ts`,
|
|
196
|
+
pattern: /(?<=(for .* \[\n?))(((\s+)?\.{3}\w+(,?( |\r|)))+)/gm,
|
|
197
|
+
template: `\n ...${entity}Schemas,\r$2`,
|
|
198
|
+
},
|
|
199
|
+
]
|
|
200
|
+
|
|
201
|
+
data?.endpointActions.forEach((action: EndpointActionValues) => {
|
|
202
|
+
if (action.isAParamRoute) {
|
|
203
|
+
actions.push(
|
|
204
|
+
{
|
|
205
|
+
type: 'add',
|
|
206
|
+
path: `{{ turbo.paths.root }}/packages/common/server/schemas/params/${entity}.schema.ts`,
|
|
207
|
+
templateFile: 'templates/api/api-param-schema.hbs',
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
type: 'append',
|
|
211
|
+
path: `{{ turbo.paths.root }}/packages/common/server/schemas/params/index.ts`,
|
|
212
|
+
template: `export * from './${entity}.schema'`,
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
type: 'modify',
|
|
216
|
+
path: `{{ turbo.paths.root }}/apps/{{apiDirectory}}/src/schemas.ts`,
|
|
217
|
+
// ----- Append entityParamId schema to the common/server import block ----- //
|
|
218
|
+
pattern:
|
|
219
|
+
/(?<=(import {\n?))(.*)(?=((.*\n?( |,\n))*} from '@pragma\/common\/server'))/gm,
|
|
220
|
+
template: `\n ${entity}IdParamSchema,\n$2`,
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
type: 'modify',
|
|
224
|
+
path: `{{ turbo.paths.root }}/apps/{{apiDirectory}}/src/schemas.ts`,
|
|
225
|
+
// ----- Export entityParamId schema to the common/server export block ----- //
|
|
226
|
+
pattern: /(?<=(for .* \[\n?))(((\s+)?\.{3}\w+(,?( |\r|)))+)/gm,
|
|
227
|
+
template: `\n ...${entity}IdParamSchema,\r$2`,
|
|
228
|
+
},
|
|
229
|
+
)
|
|
230
|
+
}
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
return actions
|
|
234
|
+
},
|
|
235
|
+
})
|
|
236
|
+
|
|
237
|
+
plop.addHelper('getEntityFromPath', (path: string) => {
|
|
238
|
+
if (path.includes('/')) {
|
|
239
|
+
return path.split('/').pop()
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return path
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
plop.setGenerator('api', {
|
|
246
|
+
description: 'Create a new API endpoint',
|
|
247
|
+
prompts: [
|
|
248
|
+
{
|
|
249
|
+
type: 'list',
|
|
250
|
+
name: 'apiDirectory',
|
|
251
|
+
message:
|
|
252
|
+
'What is the new API directory in which you want to create the endpoint(s) ?',
|
|
253
|
+
choices: () => {
|
|
254
|
+
return fs
|
|
255
|
+
.readdirSync(path.join(plop.getDestBasePath(), '/apps/'))
|
|
256
|
+
.filter(
|
|
257
|
+
(f) =>
|
|
258
|
+
fs
|
|
259
|
+
.statSync(path.join(plop.getDestBasePath() + '/apps/', f))
|
|
260
|
+
.isDirectory() && f.startsWith('api'),
|
|
261
|
+
)
|
|
262
|
+
.map((f) => ({
|
|
263
|
+
name: f,
|
|
264
|
+
value: f,
|
|
265
|
+
}))
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
type: 'input',
|
|
270
|
+
name: 'modulePath',
|
|
271
|
+
message:
|
|
272
|
+
"What is the name of the new module to create the endpoints in ? (e.g: 'auth', 'v1/auth')",
|
|
273
|
+
validate: (input: string) => {
|
|
274
|
+
if (!input) {
|
|
275
|
+
return 'module name is required'
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (input.match(/^([a-zA-Z0-9]+)(\/[a-zA-Z0-9]+)*$/)) {
|
|
279
|
+
return true
|
|
280
|
+
} else {
|
|
281
|
+
return 'Malformed module name must only contain alphanumeric characters [a-zA-Z0-9] and slashes (no slashes at the beginning or end & at least one character between slashes)'
|
|
282
|
+
}
|
|
283
|
+
},
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
type: 'checkbox',
|
|
287
|
+
name: 'endpointActions',
|
|
288
|
+
message: 'What is the action(s) of the module ?',
|
|
289
|
+
choices: (inputs) => {
|
|
290
|
+
const entity = pluralize.singular(inputs.modulePath.split('/').pop())
|
|
291
|
+
const pluralEntity = pluralize.plural(entity)
|
|
292
|
+
const capitalizedEntity = entity[0].toUpperCase() + entity.slice(1)
|
|
293
|
+
const capitalizedPluralEntity =
|
|
294
|
+
pluralEntity[0].toUpperCase() + pluralEntity.slice(1)
|
|
295
|
+
|
|
296
|
+
return [
|
|
297
|
+
{
|
|
298
|
+
name: `getOne${capitalizedEntity}`,
|
|
299
|
+
value: {
|
|
300
|
+
actionName: `getOne${capitalizedEntity}`,
|
|
301
|
+
entityName: entity,
|
|
302
|
+
zodElementarySchemaDefinition: `fetch${capitalizedEntity}Output`,
|
|
303
|
+
zodSchemaDefinitionName: `fetch${capitalizedEntity}ReplySchema`,
|
|
304
|
+
typeName: `${capitalizedEntity}OutputType`,
|
|
305
|
+
fastifySchemaName: `fetch${capitalizedEntity}Schema`,
|
|
306
|
+
fastifyDescription: `Fetch one ${entity} based on the ${entity} id`,
|
|
307
|
+
fastifySummary: `fetch a ${entity}`,
|
|
308
|
+
fastifyOperationId: `fetch-${entity}`,
|
|
309
|
+
verb: 'get',
|
|
310
|
+
responseCode: 200,
|
|
311
|
+
route: '/:id',
|
|
312
|
+
isAParamRoute: true,
|
|
313
|
+
},
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
name: `getMany${capitalizedPluralEntity}`,
|
|
317
|
+
value: {
|
|
318
|
+
actionName: `getMany${capitalizedPluralEntity}`,
|
|
319
|
+
entityName: entity,
|
|
320
|
+
zodElementarySchemaDefinition: `fetch${capitalizedPluralEntity}ListOutput`,
|
|
321
|
+
zodSchemaDefinitionName: `fetch${capitalizedPluralEntity}ListReplySchema`,
|
|
322
|
+
typeName: `${capitalizedPluralEntity}ListOutputType`,
|
|
323
|
+
fastifySchemaName: `fetch${capitalizedPluralEntity}ListSchema`,
|
|
324
|
+
fastifyDescription: `Fetch many ${pluralEntity}`,
|
|
325
|
+
fastifySummary: `fetch a list of ${pluralEntity}`,
|
|
326
|
+
fastifyOperationId: `fetch-many-${pluralEntity}`,
|
|
327
|
+
verb: 'get',
|
|
328
|
+
responseCode: 200,
|
|
329
|
+
route: '/',
|
|
330
|
+
},
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
name: 'custom',
|
|
334
|
+
value: {
|
|
335
|
+
entityName: 'custom',
|
|
336
|
+
},
|
|
337
|
+
},
|
|
338
|
+
]
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
when: (inputs) => {
|
|
343
|
+
return inputs.endpointActions.some(
|
|
344
|
+
(action: EndpointActionValues) => action.entityName === 'custom',
|
|
345
|
+
)
|
|
346
|
+
},
|
|
347
|
+
type: 'input',
|
|
348
|
+
name: 'customName',
|
|
349
|
+
message: 'What is the name of the custom endpoint ?',
|
|
350
|
+
validate(input, answers) {
|
|
351
|
+
if (!input) {
|
|
352
|
+
return 'custom endpoint name is required'
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
if (input.match(/^([a-zA-Z0-9]+)(\/[a-zA-Z0-9]+)*$/) && answers) {
|
|
356
|
+
answers.endpointActions.find((action: EndpointActionValues) => {
|
|
357
|
+
if (action.entityName === 'custom') {
|
|
358
|
+
action.actionName = input
|
|
359
|
+
action.entityName = answers.modulePath.split('/').pop()
|
|
360
|
+
action.zodElementarySchemaDefinition = input
|
|
361
|
+
action.zodSchemaDefinitionName = input + 'Schema'
|
|
362
|
+
action.typeName =
|
|
363
|
+
input[0].toUpperCase() + input.slice(1) + 'Type'
|
|
364
|
+
action.fastifySchemaName = input + 'FastifySchema'
|
|
365
|
+
action.fastifyDescription =
|
|
366
|
+
'Please set the description of the custom endpoint'
|
|
367
|
+
action.fastifySummary =
|
|
368
|
+
'Please set the summary of the custom endpoint'
|
|
369
|
+
action.fastifyOperationId = input
|
|
370
|
+
action.verb = 'get'
|
|
371
|
+
action.responseCode = 200
|
|
372
|
+
action.route = `/${input}`
|
|
373
|
+
}
|
|
374
|
+
})
|
|
375
|
+
|
|
376
|
+
return true
|
|
377
|
+
} else {
|
|
378
|
+
return 'Malformed custom endpoint name must only contain alphanumeric characters [a-zA-Z0-9] and slashes (no slashes at the beginning or end & at least one character between slashes)'
|
|
379
|
+
}
|
|
380
|
+
},
|
|
381
|
+
},
|
|
382
|
+
],
|
|
383
|
+
actions: function (data) {
|
|
384
|
+
const entity = data?.modulePath.split('/').pop()
|
|
385
|
+
const actions: PlopTypes.Actions = [
|
|
386
|
+
{
|
|
387
|
+
type: 'add',
|
|
388
|
+
path: `{{ turbo.paths.root }}/apps/{{apiDirectory}}/src/modules/{{modulePath}}/${entity}.schema.ts`,
|
|
389
|
+
templateFile: 'templates/api/api-schema.hbs',
|
|
390
|
+
abortOnFail: true,
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
type: 'add',
|
|
394
|
+
path: `{{ turbo.paths.root }}/apps/{{apiDirectory}}/src/modules/{{modulePath}}/${entity}.router.ts`,
|
|
395
|
+
templateFile: 'templates/api/api-router.hbs',
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
type: 'add',
|
|
399
|
+
path: `{{ turbo.paths.root }}/apps/{{apiDirectory}}/src/modules/{{modulePath}}/${entity}.controller.ts`,
|
|
400
|
+
templateFile: 'templates/api/api-controller.hbs',
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
type: 'add',
|
|
404
|
+
path: `{{ turbo.paths.root }}/apps/{{apiDirectory}}/src/modules/{{modulePath}}/${entity}.service.ts`,
|
|
405
|
+
templateFile: 'templates/api/api-service.hbs',
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
type: 'modify',
|
|
409
|
+
path: `{{ turbo.paths.root }}/apps/{{apiDirectory}}/src/schemas.ts`,
|
|
410
|
+
pattern: /(?<=(import.*'\.\/modules.*schema')).*(?=(\n\n))/gm,
|
|
411
|
+
template: `\nimport { ${entity}Schemas } from './modules/{{modulePath}}/${entity}.schema'`,
|
|
412
|
+
},
|
|
413
|
+
{
|
|
414
|
+
type: 'modify',
|
|
415
|
+
path: `{{ turbo.paths.root }}/apps/{{apiDirectory}}/src/schemas.ts`,
|
|
416
|
+
pattern: /(?<=(for .* \[\n?))(((\s+)?\.{3}\w+(,?( |\r|)))+)/gm,
|
|
417
|
+
template: `\n ...${entity}Schemas,\r$2`,
|
|
418
|
+
},
|
|
419
|
+
]
|
|
420
|
+
|
|
421
|
+
data?.endpointActions.forEach((action: EndpointActionValues) => {
|
|
422
|
+
if (action.isAParamRoute) {
|
|
423
|
+
actions.push(
|
|
424
|
+
{
|
|
425
|
+
type: 'add',
|
|
426
|
+
path: `{{ turbo.paths.root }}/packages/common/server/schemas/params/${entity}.schema.ts`,
|
|
427
|
+
templateFile: 'templates/api/api-param-schema.hbs',
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
type: 'append',
|
|
431
|
+
path: `{{ turbo.paths.root }}/packages/common/server/schemas/params/index.ts`,
|
|
432
|
+
template: `export * from './${entity}.schema'`,
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
type: 'modify',
|
|
436
|
+
path: `{{ turbo.paths.root }}/apps/{{apiDirectory}}/src/schemas.ts`,
|
|
437
|
+
// ----- Append entityParamId schema to the common/server import block ----- //
|
|
438
|
+
pattern:
|
|
439
|
+
/(?<=(import {))(\n?.*)(?=((.*\n?( |,\n))*} from '@pragma\/common\/server'))/gm,
|
|
440
|
+
template: `\n ${entity}IdParamSchema,\n$2`,
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
type: 'modify',
|
|
444
|
+
path: `{{ turbo.paths.root }}/apps/{{apiDirectory}}/src/schemas.ts`,
|
|
445
|
+
// ----- Export entityParamId schema to the common/server export block ----- //
|
|
446
|
+
pattern: /(?<=(for .* \[\n?))(((\s+)?\.{3}\w+(,?( |\r|)))+)/gm,
|
|
447
|
+
template: `\n ...${entity}IdParamSchema,\r$2`,
|
|
448
|
+
},
|
|
449
|
+
)
|
|
450
|
+
}
|
|
451
|
+
})
|
|
452
|
+
|
|
453
|
+
return actions
|
|
454
|
+
},
|
|
455
|
+
})
|
|
456
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { PlopTypes } from '@turbo/gen'
|
|
2
|
+
|
|
3
|
+
export const generatorComponent = (plop: PlopTypes.NodePlopAPI) => {
|
|
4
|
+
plop.setGenerator('component', {
|
|
5
|
+
description: 'Create a new component in @pragma/ui',
|
|
6
|
+
prompts: [
|
|
7
|
+
{
|
|
8
|
+
type: 'input',
|
|
9
|
+
name: 'componentName',
|
|
10
|
+
message: 'What is the name of the new component to create?',
|
|
11
|
+
validate: (input) => {
|
|
12
|
+
if (input.includes('.')) {
|
|
13
|
+
return 'File name cannot include an extension.'
|
|
14
|
+
}
|
|
15
|
+
if (!input) {
|
|
16
|
+
return 'File name is required.'
|
|
17
|
+
}
|
|
18
|
+
return true
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
actions: (data) => {
|
|
23
|
+
const componentName = data?.componentName
|
|
24
|
+
const camelCaseComponentName = plop.getHelper('camelCase')(componentName)
|
|
25
|
+
|
|
26
|
+
const pascalCaseComponentName =
|
|
27
|
+
plop.getHelper('pascalCase')(componentName)
|
|
28
|
+
|
|
29
|
+
const actions: PlopTypes.Actions = []
|
|
30
|
+
|
|
31
|
+
actions.push(
|
|
32
|
+
{
|
|
33
|
+
type: 'add',
|
|
34
|
+
path: `{{ turbo.paths.root }}/packages/ui/src/components/${camelCaseComponentName}/index.ts`,
|
|
35
|
+
templateFile: 'templates/component/component-index.hbs',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
type: 'add',
|
|
39
|
+
path: `{{ turbo.paths.root }}/packages/ui/src/components/${camelCaseComponentName}/${pascalCaseComponentName}.tsx`,
|
|
40
|
+
templateFile: 'templates/component/component-react.hbs',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
type: 'add',
|
|
44
|
+
path: `{{ turbo.paths.root }}/packages/ui/src/components/${camelCaseComponentName}/${camelCaseComponentName}.stories.tsx`,
|
|
45
|
+
templateFile: 'templates/component/component-story.hbs',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
type: 'add',
|
|
49
|
+
path: `{{ turbo.paths.root }}/packages/ui/src/components/${camelCaseComponentName}/${camelCaseComponentName}.test.tsx`,
|
|
50
|
+
templateFile: 'templates/component/component-test.hbs',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
type: 'modify',
|
|
54
|
+
path: '{{ turbo.paths.root }}/packages/ui/index.ts',
|
|
55
|
+
pattern: /export \{/,
|
|
56
|
+
template: `import { ${pascalCaseComponentName} } from './src/components/${camelCaseComponentName}/index';\n\nexport {\n ${pascalCaseComponentName},`,
|
|
57
|
+
},
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
return actions
|
|
61
|
+
},
|
|
62
|
+
})
|
|
63
|
+
}
|