@platformatic/generators 2.67.0-alpha.1 → 2.67.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/index.js +4 -1
- package/lib/base-generator.js +72 -57
- package/lib/file-generator.js +18 -11
- package/lib/import-generator.js +230 -0
- package/package.json +4 -2
package/index.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { BaseGenerator } = require('./lib/base-generator')
|
|
4
|
+
const { ImportGenerator } = require('./lib/import-generator')
|
|
4
5
|
const { generateTests } = require('./lib/create-plugin')
|
|
5
6
|
const utils = require('./lib/utils')
|
|
7
|
+
|
|
6
8
|
module.exports = {
|
|
7
9
|
BaseGenerator,
|
|
10
|
+
ImportGenerator,
|
|
8
11
|
generateTests,
|
|
9
|
-
...utils
|
|
12
|
+
...utils
|
|
10
13
|
}
|
package/lib/base-generator.js
CHANGED
|
@@ -8,7 +8,7 @@ const {
|
|
|
8
8
|
getPackageConfigurationObject,
|
|
9
9
|
PLT_ROOT,
|
|
10
10
|
getLatestNpmVersion,
|
|
11
|
-
stripVersion
|
|
11
|
+
stripVersion
|
|
12
12
|
} = require('./utils')
|
|
13
13
|
const { join } = require('node:path')
|
|
14
14
|
const { FileGenerator } = require('./file-generator')
|
|
@@ -20,11 +20,11 @@ const { flattenObject } = require('./utils')
|
|
|
20
20
|
const { envStringToObject } = require('./utils')
|
|
21
21
|
/* c8 ignore start */
|
|
22
22
|
const fakeLogger = {
|
|
23
|
-
info: () => {
|
|
24
|
-
warn: () => {
|
|
25
|
-
debug: () => {
|
|
26
|
-
trace: () => {
|
|
27
|
-
error: () => {
|
|
23
|
+
info: () => {},
|
|
24
|
+
warn: () => {},
|
|
25
|
+
debug: () => {},
|
|
26
|
+
trace: () => {},
|
|
27
|
+
error: () => {}
|
|
28
28
|
}
|
|
29
29
|
/* c8 ignore start */
|
|
30
30
|
|
|
@@ -61,7 +61,7 @@ class BaseGenerator extends FileGenerator {
|
|
|
61
61
|
envPrefix: '',
|
|
62
62
|
env: {},
|
|
63
63
|
defaultEnv: {},
|
|
64
|
-
isUpdating: false
|
|
64
|
+
isUpdating: false
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
|
|
@@ -72,9 +72,11 @@ class BaseGenerator extends FileGenerator {
|
|
|
72
72
|
setConfigFields (fields) {
|
|
73
73
|
const availableConfigFields = this.getConfigFieldsDefinitions()
|
|
74
74
|
function shouldHandleConfigField (field) {
|
|
75
|
-
return
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
return (
|
|
76
|
+
availableConfigFields.filter(f => {
|
|
77
|
+
return f.configValue === field.configValue && f.var === field.var
|
|
78
|
+
}).length > 0
|
|
79
|
+
)
|
|
78
80
|
}
|
|
79
81
|
for (const field of fields) {
|
|
80
82
|
if (shouldHandleConfigField(field)) {
|
|
@@ -138,7 +140,7 @@ class BaseGenerator extends FileGenerator {
|
|
|
138
140
|
this.config = {
|
|
139
141
|
...this.getDefaultConfig(),
|
|
140
142
|
...oldConfig,
|
|
141
|
-
...config
|
|
143
|
+
...config
|
|
142
144
|
}
|
|
143
145
|
|
|
144
146
|
if (this.config.isRuntimeContext) {
|
|
@@ -164,7 +166,7 @@ class BaseGenerator extends FileGenerator {
|
|
|
164
166
|
const newConfig = await this.inquirer.prompt(this.questions)
|
|
165
167
|
this.setConfig({
|
|
166
168
|
...this.config,
|
|
167
|
-
...newConfig
|
|
169
|
+
...newConfig
|
|
168
170
|
})
|
|
169
171
|
}
|
|
170
172
|
}
|
|
@@ -191,7 +193,7 @@ class BaseGenerator extends FileGenerator {
|
|
|
191
193
|
this.addFile({
|
|
192
194
|
path: '',
|
|
193
195
|
file: this.runtimeConfig,
|
|
194
|
-
contents: JSON.stringify(currentConfigFile, null, 2)
|
|
196
|
+
contents: JSON.stringify(currentConfigFile, null, 2)
|
|
195
197
|
})
|
|
196
198
|
} else {
|
|
197
199
|
await this.getFastifyVersion()
|
|
@@ -204,7 +206,7 @@ class BaseGenerator extends FileGenerator {
|
|
|
204
206
|
this.addFile({
|
|
205
207
|
path: '',
|
|
206
208
|
file: 'package.json',
|
|
207
|
-
contents: JSON.stringify(template, null, 2)
|
|
209
|
+
contents: JSON.stringify(template, null, 2)
|
|
208
210
|
})
|
|
209
211
|
|
|
210
212
|
await this.generateConfigFile()
|
|
@@ -216,7 +218,7 @@ class BaseGenerator extends FileGenerator {
|
|
|
216
218
|
this.addFile({
|
|
217
219
|
path: '',
|
|
218
220
|
file: 'tsconfig.json',
|
|
219
|
-
contents: JSON.stringify(this.getTsConfig(), null, 2)
|
|
221
|
+
contents: JSON.stringify(this.getTsConfig(), null, 2)
|
|
220
222
|
})
|
|
221
223
|
}
|
|
222
224
|
|
|
@@ -237,7 +239,7 @@ class BaseGenerator extends FileGenerator {
|
|
|
237
239
|
}
|
|
238
240
|
return {
|
|
239
241
|
targetDirectory: this.targetDirectory,
|
|
240
|
-
env: this.config.env
|
|
242
|
+
env: this.config.env
|
|
241
243
|
}
|
|
242
244
|
} catch (err) {
|
|
243
245
|
if (err.code?.startsWith('PLT_GEN')) {
|
|
@@ -282,15 +284,15 @@ class BaseGenerator extends FileGenerator {
|
|
|
282
284
|
incremental: true,
|
|
283
285
|
strict: true,
|
|
284
286
|
outDir: 'dist',
|
|
285
|
-
skipLibCheck: true
|
|
287
|
+
skipLibCheck: true
|
|
286
288
|
},
|
|
287
289
|
watchOptions: {
|
|
288
290
|
watchFile: 'fixedPollingInterval',
|
|
289
291
|
watchDirectory: 'fixedPollingInterval',
|
|
290
292
|
fallbackPolling: 'dynamicPriority',
|
|
291
293
|
synchronousWatchDirectory: true,
|
|
292
|
-
excludeDirectories: ['**/node_modules', 'dist']
|
|
293
|
-
}
|
|
294
|
+
excludeDirectories: ['**/node_modules', 'dist']
|
|
295
|
+
}
|
|
294
296
|
}
|
|
295
297
|
}
|
|
296
298
|
|
|
@@ -301,7 +303,7 @@ class BaseGenerator extends FileGenerator {
|
|
|
301
303
|
this.questions.push({
|
|
302
304
|
type: 'input',
|
|
303
305
|
name: 'targetDirectory',
|
|
304
|
-
message: 'Where would you like to create your project?'
|
|
306
|
+
message: 'Where would you like to create your project?'
|
|
305
307
|
})
|
|
306
308
|
}
|
|
307
309
|
|
|
@@ -337,18 +339,18 @@ class BaseGenerator extends FileGenerator {
|
|
|
337
339
|
if (!contents.plugins) {
|
|
338
340
|
contents.plugins = {}
|
|
339
341
|
}
|
|
340
|
-
contents.plugins.packages = this.packages.map(
|
|
342
|
+
contents.plugins.packages = this.packages.map(packageDefinition => {
|
|
341
343
|
const packageConfigOutput = getPackageConfigurationObject(packageDefinition.options, this.config.serviceName)
|
|
342
344
|
if (Object.keys(packageConfigOutput.env).length > 0) {
|
|
343
345
|
const envForPackages = {}
|
|
344
|
-
Object.entries(packageConfigOutput.env).forEach(
|
|
346
|
+
Object.entries(packageConfigOutput.env).forEach(kv => {
|
|
345
347
|
envForPackages[kv[0]] = kv[1]
|
|
346
348
|
})
|
|
347
349
|
this.addEnvVars(envForPackages)
|
|
348
350
|
}
|
|
349
351
|
return {
|
|
350
352
|
name: packageDefinition.name,
|
|
351
|
-
options: packageConfigOutput.config
|
|
353
|
+
options: packageConfigOutput.config
|
|
352
354
|
}
|
|
353
355
|
})
|
|
354
356
|
}
|
|
@@ -356,8 +358,10 @@ class BaseGenerator extends FileGenerator {
|
|
|
356
358
|
this.addFile({
|
|
357
359
|
path: '',
|
|
358
360
|
file: configFileName,
|
|
359
|
-
contents: JSON.stringify(contents, null, 2)
|
|
361
|
+
contents: JSON.stringify(contents, null, 2)
|
|
360
362
|
})
|
|
363
|
+
|
|
364
|
+
return contents
|
|
361
365
|
}
|
|
362
366
|
|
|
363
367
|
/**
|
|
@@ -388,23 +392,24 @@ class BaseGenerator extends FileGenerator {
|
|
|
388
392
|
name: `${this.config.serviceName}`,
|
|
389
393
|
scripts: {
|
|
390
394
|
start: 'platformatic start',
|
|
391
|
-
test: 'borp'
|
|
395
|
+
test: 'borp'
|
|
392
396
|
},
|
|
393
397
|
devDependencies: {
|
|
394
398
|
fastify: `^${this.fastifyVersion}`,
|
|
395
399
|
borp: `${this.pkgData.devDependencies.borp}`,
|
|
396
|
-
...this.config.devDependencies
|
|
400
|
+
...this.config.devDependencies
|
|
397
401
|
},
|
|
398
402
|
dependencies: {
|
|
399
|
-
...this.config.dependencies
|
|
403
|
+
...this.config.dependencies
|
|
400
404
|
},
|
|
401
405
|
engines: {
|
|
402
|
-
node: '^22.14.0 || ^20.6.0'
|
|
403
|
-
}
|
|
406
|
+
node: '^22.14.0 || ^20.6.0'
|
|
407
|
+
}
|
|
404
408
|
}
|
|
405
409
|
|
|
406
410
|
if (this.config.typescript) {
|
|
407
|
-
const typescriptVersion = JSON.parse(await readFile(join(__dirname, '..', 'package.json'), 'utf-8'))
|
|
411
|
+
const typescriptVersion = JSON.parse(await readFile(join(__dirname, '..', 'package.json'), 'utf-8'))
|
|
412
|
+
.devDependencies.typescript
|
|
408
413
|
template.scripts.clean = 'rm -fr ./dist'
|
|
409
414
|
template.scripts.build = 'platformatic compile'
|
|
410
415
|
template.devDependencies.typescript = typescriptVersion
|
|
@@ -413,29 +418,35 @@ class BaseGenerator extends FileGenerator {
|
|
|
413
418
|
}
|
|
414
419
|
|
|
415
420
|
async generateEnv () {
|
|
416
|
-
if (
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
file: '.env',
|
|
420
|
-
contents: serializeEnvVars(this.config.env),
|
|
421
|
-
})
|
|
421
|
+
if (this.config.isRuntimeContext) {
|
|
422
|
+
return
|
|
423
|
+
}
|
|
422
424
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
425
|
+
const serializedEnv = serializeEnvVars(this.config.env)
|
|
426
|
+
|
|
427
|
+
this.addFile({
|
|
428
|
+
path: '',
|
|
429
|
+
file: '.env',
|
|
430
|
+
contents: serializedEnv
|
|
431
|
+
})
|
|
432
|
+
|
|
433
|
+
const emptyEnvVars = {}
|
|
434
|
+
for (const envVarName of Object.keys(this.config.env)) {
|
|
435
|
+
if (!this.config.defaultEnv[envVarName]) {
|
|
436
|
+
emptyEnvVars[envVarName] = ''
|
|
428
437
|
}
|
|
438
|
+
}
|
|
429
439
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
}),
|
|
440
|
+
this.addFile({
|
|
441
|
+
path: '',
|
|
442
|
+
file: '.env.sample',
|
|
443
|
+
contents: serializeEnvVars({
|
|
444
|
+
...this.config.defaultEnv,
|
|
445
|
+
...emptyEnvVars
|
|
437
446
|
})
|
|
438
|
-
}
|
|
447
|
+
})
|
|
448
|
+
|
|
449
|
+
return serializedEnv
|
|
439
450
|
}
|
|
440
451
|
|
|
441
452
|
async run () {
|
|
@@ -460,7 +471,9 @@ class BaseGenerator extends FileGenerator {
|
|
|
460
471
|
async loadFromDir (serviceName, runtimeRootPath) {
|
|
461
472
|
const runtimePkgConfigFileData = JSON.parse(await readFile(join(runtimeRootPath, this.runtimeConfig), 'utf-8'))
|
|
462
473
|
const servicesPath = runtimePkgConfigFileData.autoload.path
|
|
463
|
-
const servicePkgJsonFileData = JSON.parse(
|
|
474
|
+
const servicePkgJsonFileData = JSON.parse(
|
|
475
|
+
await readFile(join(runtimeRootPath, servicesPath, serviceName, 'platformatic.json'), 'utf-8')
|
|
476
|
+
)
|
|
464
477
|
const runtimeEnv = envStringToObject(await readFile(join(runtimeRootPath, '.env'), 'utf-8'))
|
|
465
478
|
const serviceNamePrefix = convertServiceNameToPrefix(serviceName)
|
|
466
479
|
const plugins = []
|
|
@@ -469,7 +482,7 @@ class BaseGenerator extends FileGenerator {
|
|
|
469
482
|
const flattened = flattenObject(pkg)
|
|
470
483
|
const output = {
|
|
471
484
|
name: flattened.name,
|
|
472
|
-
options: []
|
|
485
|
+
options: []
|
|
473
486
|
}
|
|
474
487
|
if (pkg.options) {
|
|
475
488
|
Object.entries(flattened)
|
|
@@ -481,7 +494,7 @@ class BaseGenerator extends FileGenerator {
|
|
|
481
494
|
name: serviceEnvVarKey,
|
|
482
495
|
path: key.replace('options.', ''),
|
|
483
496
|
type: 'string',
|
|
484
|
-
value: runtimeEnv[runtimeEnvVarKey]
|
|
497
|
+
value: runtimeEnv[runtimeEnvVarKey]
|
|
485
498
|
}
|
|
486
499
|
output.options.push(option)
|
|
487
500
|
})
|
|
@@ -495,16 +508,18 @@ class BaseGenerator extends FileGenerator {
|
|
|
495
508
|
name: serviceName,
|
|
496
509
|
template: getServiceTemplateFromSchemaUrl(servicePkgJsonFileData.$schema),
|
|
497
510
|
fields: [],
|
|
498
|
-
plugins
|
|
511
|
+
plugins
|
|
499
512
|
}
|
|
500
513
|
}
|
|
501
514
|
|
|
502
515
|
// implement in the subclass
|
|
503
516
|
/* c8 ignore next 1 */
|
|
504
|
-
async postInstallActions () {
|
|
505
|
-
async _beforePrepare () {
|
|
506
|
-
async _afterPrepare () {
|
|
507
|
-
async _getConfigFileContents () {
|
|
517
|
+
async postInstallActions () {}
|
|
518
|
+
async _beforePrepare () {}
|
|
519
|
+
async _afterPrepare () {}
|
|
520
|
+
async _getConfigFileContents () {
|
|
521
|
+
return {}
|
|
522
|
+
}
|
|
508
523
|
}
|
|
509
524
|
|
|
510
525
|
function serializeEnvVars (envVars) {
|
package/lib/file-generator.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
const { createDirectory } = require('@platformatic/utils')
|
|
3
|
-
const { join } = require('node:path')
|
|
3
|
+
const { dirname, join, isAbsolute } = require('node:path')
|
|
4
4
|
const { writeFile, readFile } = require('node:fs/promises')
|
|
5
5
|
|
|
6
6
|
/* c8 ignore start */
|
|
@@ -9,7 +9,7 @@ const fakeLogger = {
|
|
|
9
9
|
warn: () => {},
|
|
10
10
|
debug: () => {},
|
|
11
11
|
trace: () => {},
|
|
12
|
-
error: () => {}
|
|
12
|
+
error: () => {}
|
|
13
13
|
}
|
|
14
14
|
/* c8 ignore start */
|
|
15
15
|
|
|
@@ -31,15 +31,16 @@ class FileGenerator {
|
|
|
31
31
|
return this.getFileObject(file, path)
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
addFile ({ path, file, contents, options = {} }) {
|
|
34
|
+
addFile ({ path, file, contents, options = {}, tags }) {
|
|
35
35
|
const fileObject = this.getFileObject(file, path)
|
|
36
36
|
if (path.startsWith('/')) {
|
|
37
37
|
path = path.substring(1)
|
|
38
38
|
}
|
|
39
39
|
if (fileObject) {
|
|
40
40
|
fileObject.contents = contents
|
|
41
|
+
fileObject.tags = tags ?? []
|
|
41
42
|
} else {
|
|
42
|
-
this.files.push({ path, file, contents, options })
|
|
43
|
+
this.files.push({ path, file, contents, options, tags: tags ?? [] })
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
46
|
|
|
@@ -64,26 +65,32 @@ class FileGenerator {
|
|
|
64
65
|
if (fileToWrite.contents.length === 0 && !fileToWrite.file.match(/^\..+keep$/)) {
|
|
65
66
|
continue
|
|
66
67
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
|
|
69
|
+
let fullFilePath = join(fileToWrite.path, fileToWrite.file)
|
|
70
|
+
|
|
71
|
+
if (!isAbsolute(fullFilePath)) {
|
|
72
|
+
fullFilePath = join(this.targetDirectory, fullFilePath)
|
|
70
73
|
}
|
|
71
|
-
|
|
74
|
+
|
|
75
|
+
await createDirectory(dirname(fullFilePath))
|
|
72
76
|
await writeFile(fullFilePath, fileToWrite.contents, fileToWrite.options)
|
|
77
|
+
|
|
73
78
|
this.logger.info(`${fullFilePath} written!`)
|
|
74
79
|
}
|
|
75
80
|
}
|
|
76
81
|
|
|
77
82
|
getFileObject (name, path = '') {
|
|
78
|
-
const output = this.files.find(
|
|
83
|
+
const output = this.files.find(file => {
|
|
79
84
|
return file.path === path && file.file === name
|
|
80
85
|
})
|
|
81
|
-
if (!output) {
|
|
86
|
+
if (!output) {
|
|
87
|
+
return null
|
|
88
|
+
}
|
|
82
89
|
return output
|
|
83
90
|
}
|
|
84
91
|
|
|
85
92
|
listFiles () {
|
|
86
|
-
return this.files.map(
|
|
93
|
+
return this.files.map(fileObject => {
|
|
87
94
|
return join(fileObject.path, fileObject.file)
|
|
88
95
|
})
|
|
89
96
|
}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { findConfigurationFile } = require('@platformatic/config')
|
|
4
|
+
const { safeRemove } = require('@platformatic/utils')
|
|
5
|
+
const { glob } = require('glob')
|
|
6
|
+
const { BaseGenerator } = require('./base-generator')
|
|
7
|
+
const { spawnSync } = require('node:child_process')
|
|
8
|
+
const { stat, readFile } = require('node:fs/promises')
|
|
9
|
+
const { join, dirname } = require('node:path')
|
|
10
|
+
|
|
11
|
+
class ImportGenerator extends BaseGenerator {
|
|
12
|
+
constructor (options = {}) {
|
|
13
|
+
const { serviceName, module, version, parent: runtime, ...opts } = options
|
|
14
|
+
super({ ...opts, module })
|
|
15
|
+
|
|
16
|
+
this.runtime = runtime
|
|
17
|
+
this.setConfig({
|
|
18
|
+
serviceName,
|
|
19
|
+
servicePathEnvName: `PLT_SERVICE_${serviceName.toUpperCase().replaceAll(/[^A-Z0-9_]/g, '_')}_PATH`,
|
|
20
|
+
module,
|
|
21
|
+
version
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async prepareQuestions () {
|
|
26
|
+
await super.prepareQuestions()
|
|
27
|
+
|
|
28
|
+
this.questions.push({
|
|
29
|
+
type: 'input',
|
|
30
|
+
name: 'applicationPath',
|
|
31
|
+
message: 'Where is your application located?',
|
|
32
|
+
async validate (value) {
|
|
33
|
+
if (value.length === 0) {
|
|
34
|
+
return 'Please enter a path'
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
const pathStat = await stat(value)
|
|
39
|
+
|
|
40
|
+
if (!pathStat?.isDirectory()) {
|
|
41
|
+
return 'Please enter a valid path'
|
|
42
|
+
}
|
|
43
|
+
} catch {
|
|
44
|
+
return 'Please enter a valid path'
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return true
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
this.questions.push({
|
|
52
|
+
type: 'list',
|
|
53
|
+
name: 'operation',
|
|
54
|
+
message: 'Do you want to import or copy your application?',
|
|
55
|
+
default: 'import',
|
|
56
|
+
choices: [
|
|
57
|
+
{ name: 'import', value: 'import' },
|
|
58
|
+
{ name: 'copy', value: 'copy' }
|
|
59
|
+
]
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// We can't use prepare as it is not invoked from the runtime when dealing with existing applications
|
|
64
|
+
/* c8 ignore next 3 - Invoked from base-generator */
|
|
65
|
+
async prepare () {
|
|
66
|
+
return { targetDirectory: this.targetDirectory, env: this.config.env }
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async _beforeWriteFiles (runtime) {
|
|
70
|
+
const { module: pkg, version, applicationPath: path } = this.config
|
|
71
|
+
|
|
72
|
+
const packageJsonPath = join(path, 'package.json')
|
|
73
|
+
|
|
74
|
+
if (this.config.operation === 'copy') {
|
|
75
|
+
await this.#copy(path)
|
|
76
|
+
await this.#generateConfigFile(path, '')
|
|
77
|
+
await this.#updatePackageJson(packageJsonPath, 'package.json', pkg, version)
|
|
78
|
+
} else {
|
|
79
|
+
await this.#detectGitUrl(path)
|
|
80
|
+
await this.#generateConfigFile(path, path)
|
|
81
|
+
|
|
82
|
+
await this.#updatePackageJson(packageJsonPath, packageJsonPath, pkg, version)
|
|
83
|
+
await this.#updateRuntime(runtime)
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async _afterWriteFiles (runtime) {
|
|
88
|
+
// No need for an empty folder in the services folder
|
|
89
|
+
if (this.config.operation === 'import') {
|
|
90
|
+
await safeRemove(join(runtime.servicesBasePath, this.config.serviceName))
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async #detectGitUrl (path) {
|
|
95
|
+
let url
|
|
96
|
+
|
|
97
|
+
// First of all, determine if there is a git repository in the application path
|
|
98
|
+
// Detect if there is a git folder and eventually get the remote
|
|
99
|
+
for (const candidate of ['origin', 'upstream']) {
|
|
100
|
+
try {
|
|
101
|
+
const result = spawnSync('git', ['remote', 'get-url', candidate], { cwd: path })
|
|
102
|
+
|
|
103
|
+
/* c8 ignore next 3 - Hard to test */
|
|
104
|
+
if (result.error || result.status !== 0) {
|
|
105
|
+
continue
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
url = result.stdout.toString().trim()
|
|
109
|
+
break
|
|
110
|
+
/* c8 ignore next 3 - Hard to test */
|
|
111
|
+
} catch (e) {
|
|
112
|
+
// No-op
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
this.setConfig({ gitUrl: url })
|
|
117
|
+
return url
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async #generateConfigFile (originalPath, updatedPath) {
|
|
121
|
+
// Determine if there is a watt.json file in the application path - If it's missing, insert one
|
|
122
|
+
// For import it means we don't update the file, for copy it means it was already copied in #copy.
|
|
123
|
+
const existingConfig = await findConfigurationFile(originalPath)
|
|
124
|
+
|
|
125
|
+
if (existingConfig) {
|
|
126
|
+
return
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const { module: pkg, version } = this.config
|
|
130
|
+
|
|
131
|
+
if (pkg.startsWith('@platformatic/')) {
|
|
132
|
+
this.addFile({
|
|
133
|
+
path: '',
|
|
134
|
+
file: join(updatedPath, this.runtimeConfig),
|
|
135
|
+
contents: JSON.stringify({ $schema: `https://schemas.platformatic.dev/${pkg}/${version}.json` }, null, 2)
|
|
136
|
+
})
|
|
137
|
+
} else {
|
|
138
|
+
this.addFile({
|
|
139
|
+
path: '',
|
|
140
|
+
file: join(updatedPath, this.runtimeConfig),
|
|
141
|
+
contents: JSON.stringify({ module: pkg }, null, 2)
|
|
142
|
+
})
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async #updatePackageJson (originalPath, updatedPath, pkg, version) {
|
|
147
|
+
// Add the module to the package.json dependencies
|
|
148
|
+
let packageJson = {}
|
|
149
|
+
|
|
150
|
+
try {
|
|
151
|
+
packageJson = JSON.parse(await readFile(originalPath, 'utf-8'))
|
|
152
|
+
} catch (e) {
|
|
153
|
+
// No-op, we will create a new package.json
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
packageJson.dependencies ??= {}
|
|
157
|
+
packageJson.dependencies[pkg] = `^${version}`
|
|
158
|
+
if (packageJson.devDependencies?.[pkg]) {
|
|
159
|
+
packageJson.devDependencies[pkg] = undefined
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
this.addFile({ path: '', file: updatedPath, contents: JSON.stringify(packageJson, null, 2) })
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
async #updateRuntime (runtime) {
|
|
166
|
+
const configObject = runtime.getRuntimeConfigFileObject()
|
|
167
|
+
/* c8 ignore next - else */
|
|
168
|
+
const config = JSON.parse(configObject?.contents ?? '{}')
|
|
169
|
+
const envObject = runtime.getRuntimeEnvFileObject()
|
|
170
|
+
/* c8 ignore next - else */
|
|
171
|
+
let env = envObject?.contents ?? ''
|
|
172
|
+
|
|
173
|
+
// Find which key is being used for the manual services
|
|
174
|
+
let key
|
|
175
|
+
for (const candidate of new Set([runtime.servicesFolder, 'web', 'services'])) {
|
|
176
|
+
if (Array.isArray(config[candidate])) {
|
|
177
|
+
key = candidate
|
|
178
|
+
break
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/* c8 ignore next - else */
|
|
183
|
+
key ??= runtime.servicesFolder ?? 'services'
|
|
184
|
+
const services = config[key] ?? []
|
|
185
|
+
|
|
186
|
+
if (!services.some(service => service.id === this.config.serviceName)) {
|
|
187
|
+
services.push({
|
|
188
|
+
id: this.config.serviceName,
|
|
189
|
+
path: `{${this.config.servicePathEnvName}}`,
|
|
190
|
+
url: this.config.gitUrl
|
|
191
|
+
})
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
config[key] = services
|
|
195
|
+
|
|
196
|
+
if (env.length > 0) {
|
|
197
|
+
env += '\n'
|
|
198
|
+
}
|
|
199
|
+
env += `${this.config.servicePathEnvName}=${this.config.applicationPath}`
|
|
200
|
+
|
|
201
|
+
runtime.updateRuntimeConfig(config)
|
|
202
|
+
runtime.updateRuntimeEnv(env)
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
async #copy (root) {
|
|
206
|
+
const files = await glob('**/*', { cwd: root, dot: true, ignore: ['node_modules/**'], withFileTypes: true })
|
|
207
|
+
|
|
208
|
+
for (const file of files) {
|
|
209
|
+
if (file.isDirectory()) {
|
|
210
|
+
continue
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/* c8 ignore next 6 */
|
|
214
|
+
let path = dirname(file.relative())
|
|
215
|
+
if (path === '.') {
|
|
216
|
+
path = ''
|
|
217
|
+
} else if (path.startsWith('./')) {
|
|
218
|
+
path = path.substring(2)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
this.addFile({
|
|
222
|
+
path,
|
|
223
|
+
file: file.name,
|
|
224
|
+
contents: await readFile(file.fullpath())
|
|
225
|
+
})
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
module.exports = { ImportGenerator }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/generators",
|
|
3
|
-
"version": "2.67.0
|
|
3
|
+
"version": "2.67.0",
|
|
4
4
|
"description": "Main classes and utils for generators.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"keywords": [],
|
|
@@ -9,10 +9,12 @@
|
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"@fastify/error": "^4.0.0",
|
|
11
11
|
"change-case-all": "^2.1.0",
|
|
12
|
+
"execa": "^9.6.0",
|
|
12
13
|
"fastify": "^5.0.0",
|
|
13
14
|
"pino": "^9.0.0",
|
|
14
15
|
"undici": "^7.0.0",
|
|
15
|
-
"@platformatic/
|
|
16
|
+
"@platformatic/config": "2.67.0",
|
|
17
|
+
"@platformatic/utils": "2.67.0"
|
|
16
18
|
},
|
|
17
19
|
"devDependencies": {
|
|
18
20
|
"@types/inquirer": "^9.0.7",
|