create-wattpm 3.0.0-alpha.4 → 3.0.0-alpha.6
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/bin/cli.js +2 -2
- package/eslint.config.js +1 -1
- package/lib/index.js +55 -66
- package/lib/utils.js +4 -6
- package/package.json +10 -10
package/bin/cli.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { checkNodeVersionForApplications } from '@platformatic/foundation'
|
|
4
4
|
import { readFile } from 'fs/promises'
|
|
5
5
|
import parseArgs from 'minimist'
|
|
6
6
|
import { join } from 'node:path'
|
|
7
7
|
import { createPlatformatic } from '../lib/index.js'
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
checkNodeVersionForApplications()
|
|
10
10
|
|
|
11
11
|
const _args = process.argv.slice(2)
|
|
12
12
|
const args = parseArgs(_args, {
|
package/eslint.config.js
CHANGED
package/lib/index.js
CHANGED
|
@@ -2,7 +2,6 @@ import {
|
|
|
2
2
|
createDirectory,
|
|
3
3
|
defaultPackageManager,
|
|
4
4
|
detectApplicationType,
|
|
5
|
-
executeWithTimeout,
|
|
6
5
|
findConfigurationFileRecursive,
|
|
7
6
|
generateDashedName,
|
|
8
7
|
getPackageManager,
|
|
@@ -22,11 +21,25 @@ import ora from 'ora'
|
|
|
22
21
|
import pino from 'pino'
|
|
23
22
|
import pretty from 'pino-pretty'
|
|
24
23
|
import resolveModule from 'resolve'
|
|
25
|
-
import { request } from 'undici'
|
|
26
24
|
import { createGitRepository } from './git.js'
|
|
27
|
-
import {
|
|
28
|
-
|
|
29
|
-
const
|
|
25
|
+
import { findGatewayConfigFile, getUsername, getVersion, say } from './utils.js'
|
|
26
|
+
|
|
27
|
+
const defaultCapabilities = [
|
|
28
|
+
'@platformatic/node',
|
|
29
|
+
'@platformatic/gateway',
|
|
30
|
+
'@platformatic/next',
|
|
31
|
+
'@platformatic/vite',
|
|
32
|
+
'@platformatic/astro',
|
|
33
|
+
'@platformatic/remix',
|
|
34
|
+
'@platformatic/nest',
|
|
35
|
+
'@platformatic/service',
|
|
36
|
+
'@platformatic/db',
|
|
37
|
+
'@platformatic/php',
|
|
38
|
+
'@platformatic/ai-warp',
|
|
39
|
+
'@platformatic/pg-hooks',
|
|
40
|
+
'@platformatic/rabbitmq-hooks',
|
|
41
|
+
'@platformatic/kafka-hooks'
|
|
42
|
+
]
|
|
30
43
|
|
|
31
44
|
export * from './git.js'
|
|
32
45
|
export * from './utils.js'
|
|
@@ -82,8 +95,8 @@ async function importOrLocal ({ pkgManager, projectDir, pkg }) {
|
|
|
82
95
|
|
|
83
96
|
let version = ''
|
|
84
97
|
|
|
85
|
-
if (
|
|
86
|
-
// Let's find if we are using one of the default
|
|
98
|
+
if (defaultCapabilities.includes(pkg) || pkg === '@platformatic/runtime') {
|
|
99
|
+
// Let's find if we are using one of the default capabilities
|
|
87
100
|
// If we are, we have to use the "local" version of the package
|
|
88
101
|
|
|
89
102
|
const meta = await JSON.parse(await readFile(join(import.meta.dirname, '..', 'package.json'), 'utf-8'))
|
|
@@ -123,37 +136,13 @@ async function findApplicationRoot (projectDir) {
|
|
|
123
136
|
return null
|
|
124
137
|
}
|
|
125
138
|
|
|
126
|
-
export async function
|
|
127
|
-
const stackables = new Set([...modules, ...defaultStackables])
|
|
128
|
-
|
|
129
|
-
// Skip the remote network request if we are running tests
|
|
130
|
-
if (process.env.PLT_MARKETPLACE_TEST) {
|
|
131
|
-
return Array.from(stackables)
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
let response
|
|
135
|
-
try {
|
|
136
|
-
response = await executeWithTimeout(request(new URL('/templates', marketplaceHost || MARKETPLACE_HOST)), 5000)
|
|
137
|
-
} catch (err) {
|
|
138
|
-
// No-op: we just use the default stackables
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
if (response && response.statusCode === 200) {
|
|
142
|
-
for (const stackable of await response.body.json()) {
|
|
143
|
-
stackables.add(stackable.name)
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return Array.from(stackables)
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
export async function chooseStackable (inquirer, stackables) {
|
|
139
|
+
export async function chooseCapability (inquirer, capabilities) {
|
|
151
140
|
const options = await inquirer.prompt({
|
|
152
141
|
type: 'list',
|
|
153
142
|
name: 'type',
|
|
154
|
-
message: 'Which kind of
|
|
155
|
-
default:
|
|
156
|
-
choices:
|
|
143
|
+
message: 'Which kind of application do you want to create?',
|
|
144
|
+
default: capabilities[0],
|
|
145
|
+
choices: capabilities
|
|
157
146
|
})
|
|
158
147
|
|
|
159
148
|
return options.type
|
|
@@ -215,7 +204,7 @@ export async function createPlatformatic (argv) {
|
|
|
215
204
|
module: []
|
|
216
205
|
},
|
|
217
206
|
boolean: ['install'],
|
|
218
|
-
string: ['global-config', '
|
|
207
|
+
string: ['global-config', 'module']
|
|
219
208
|
})
|
|
220
209
|
|
|
221
210
|
const username = await getUsername()
|
|
@@ -232,14 +221,13 @@ export async function createPlatformatic (argv) {
|
|
|
232
221
|
|
|
233
222
|
const pkgManager = getPkgManager()
|
|
234
223
|
const modules = Array.isArray(args.module) ? args.module : [args.module]
|
|
235
|
-
await createApplication(logger, pkgManager, modules, args['
|
|
224
|
+
await createApplication(logger, pkgManager, modules, args['install'])
|
|
236
225
|
}
|
|
237
226
|
|
|
238
227
|
export async function createApplication (
|
|
239
228
|
logger,
|
|
240
229
|
packageManager,
|
|
241
230
|
modules,
|
|
242
|
-
marketplaceHost,
|
|
243
231
|
install,
|
|
244
232
|
additionalGeneratorOptions = {},
|
|
245
233
|
additionalGeneratorConfig = {}
|
|
@@ -266,17 +254,17 @@ export async function createApplication (
|
|
|
266
254
|
const { name: module, label } = await detectApplicationType(projectDir)
|
|
267
255
|
|
|
268
256
|
// Check if the file belongs to a Watt application, this can happen for instance if we executed watt create
|
|
269
|
-
// in the
|
|
257
|
+
// in the applications folder
|
|
270
258
|
const existingRuntime = await findConfigurationFileRecursive(applicationRoot, null, '@platformatic/runtime')
|
|
271
259
|
|
|
272
260
|
if (!existingRuntime) {
|
|
273
261
|
// If there is a watt.json file with a runtime property, we assume we already executed watt create and we exit.
|
|
274
|
-
const
|
|
262
|
+
const existingApplication = await findGatewayConfigFile(projectDir)
|
|
275
263
|
|
|
276
|
-
if (
|
|
277
|
-
const
|
|
264
|
+
if (existingApplication) {
|
|
265
|
+
const applicationConfig = await loadConfigurationFile(existingApplication)
|
|
278
266
|
|
|
279
|
-
if (
|
|
267
|
+
if (applicationConfig.runtime) {
|
|
280
268
|
await say(`The ${label} application has already been wrapped into Watt.`)
|
|
281
269
|
return
|
|
282
270
|
}
|
|
@@ -377,25 +365,25 @@ export async function createApplication (
|
|
|
377
365
|
await say('Using existing configuration ...')
|
|
378
366
|
}
|
|
379
367
|
|
|
380
|
-
const
|
|
368
|
+
const capabilities = Array.from(new Set([...modules, ...defaultCapabilities]))
|
|
381
369
|
|
|
382
|
-
const names = generator.
|
|
370
|
+
const names = generator.existingApplications ?? []
|
|
383
371
|
|
|
384
372
|
while (true) {
|
|
385
|
-
const
|
|
386
|
-
// await say(`Creating a ${
|
|
373
|
+
const capabilityName = await chooseCapability(inquirer, capabilities)
|
|
374
|
+
// await say(`Creating a ${capability} project in ${projectDir}...`)
|
|
387
375
|
|
|
388
|
-
const
|
|
376
|
+
const capability = await importOrLocal({
|
|
389
377
|
pkgManager: packageManager,
|
|
390
378
|
name: projectName,
|
|
391
379
|
projectDir,
|
|
392
|
-
pkg:
|
|
380
|
+
pkg: capabilityName
|
|
393
381
|
})
|
|
394
382
|
|
|
395
|
-
const {
|
|
383
|
+
const { applicationName } = await inquirer.prompt({
|
|
396
384
|
type: 'input',
|
|
397
|
-
name: '
|
|
398
|
-
message: 'What is the name of the
|
|
385
|
+
name: 'applicationName',
|
|
386
|
+
message: 'What is the name of the application?',
|
|
399
387
|
default: generateDashedName(),
|
|
400
388
|
validate: value => {
|
|
401
389
|
if (value.length === 0) {
|
|
@@ -414,41 +402,41 @@ export async function createApplication (
|
|
|
414
402
|
}
|
|
415
403
|
})
|
|
416
404
|
|
|
417
|
-
names.push(
|
|
405
|
+
names.push(applicationName)
|
|
418
406
|
|
|
419
|
-
const
|
|
420
|
-
? new
|
|
407
|
+
const capabilityGenerator = capability.Generator
|
|
408
|
+
? new capability.Generator({
|
|
421
409
|
logger,
|
|
422
410
|
inquirer,
|
|
423
|
-
|
|
411
|
+
applicationName,
|
|
424
412
|
parent: generator,
|
|
425
413
|
...additionalGeneratorOptions
|
|
426
414
|
})
|
|
427
415
|
: new ImportGenerator({
|
|
428
416
|
logger,
|
|
429
417
|
inquirer,
|
|
430
|
-
|
|
431
|
-
module:
|
|
432
|
-
version: await getPackageVersion(
|
|
418
|
+
applicationName,
|
|
419
|
+
module: capabilityName,
|
|
420
|
+
version: await getPackageVersion(capabilityName, projectDir),
|
|
433
421
|
parent: generator,
|
|
434
422
|
...additionalGeneratorOptions
|
|
435
423
|
})
|
|
436
424
|
|
|
437
|
-
|
|
438
|
-
...
|
|
425
|
+
capabilityGenerator.setConfig({
|
|
426
|
+
...capabilityGenerator.config,
|
|
439
427
|
...additionalGeneratorConfig,
|
|
440
|
-
|
|
428
|
+
applicationName
|
|
441
429
|
})
|
|
442
430
|
|
|
443
|
-
generator.
|
|
431
|
+
generator.addApplication(capabilityGenerator, applicationName)
|
|
444
432
|
|
|
445
|
-
await
|
|
433
|
+
await capabilityGenerator.ask()
|
|
446
434
|
|
|
447
435
|
const { shouldBreak } = await inquirer.prompt([
|
|
448
436
|
{
|
|
449
437
|
type: 'list',
|
|
450
438
|
name: 'shouldBreak',
|
|
451
|
-
message: 'Do you want to create another
|
|
439
|
+
message: 'Do you want to create another application?',
|
|
452
440
|
default: false,
|
|
453
441
|
choices: [
|
|
454
442
|
{ name: 'yes', value: false },
|
|
@@ -470,7 +458,7 @@ export async function createApplication (
|
|
|
470
458
|
{
|
|
471
459
|
type: 'list',
|
|
472
460
|
name: 'entrypoint',
|
|
473
|
-
message: 'Which
|
|
461
|
+
message: 'Which application should be exposed?',
|
|
474
462
|
choices: names.map(name => ({ name, value: name }))
|
|
475
463
|
}
|
|
476
464
|
])
|
|
@@ -513,6 +501,7 @@ export async function createApplication (
|
|
|
513
501
|
const content = `packages:
|
|
514
502
|
# all packages in direct subdirs of packages/
|
|
515
503
|
- 'services/*'
|
|
504
|
+
- 'services/*'
|
|
516
505
|
- 'web/*'`
|
|
517
506
|
await writeFile(join(projectDir, 'pnpm-workspace.yaml'), content)
|
|
518
507
|
}
|
package/lib/utils.js
CHANGED
|
@@ -3,11 +3,9 @@ import { execa } from 'execa'
|
|
|
3
3
|
import { access, constants, readFile } from 'node:fs/promises'
|
|
4
4
|
import { createRequire } from 'node:module'
|
|
5
5
|
import { dirname, join, resolve } from 'node:path'
|
|
6
|
-
import * as url from 'node:url'
|
|
7
6
|
|
|
8
7
|
export const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
|
|
9
8
|
export const randomBetween = (min, max) => Math.floor(Math.random() * (max - min + 1) + min)
|
|
10
|
-
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
|
|
11
9
|
|
|
12
10
|
const ansiCodes = {
|
|
13
11
|
// Platformatic Green: #21FA90
|
|
@@ -72,7 +70,7 @@ export async function isDirectoryWriteable (directory) {
|
|
|
72
70
|
export const findConfigFile = async directory => findConfigurationFile(directory)
|
|
73
71
|
export const findDBConfigFile = async directory => findConfigurationFile(directory, 'db')
|
|
74
72
|
export const findServiceConfigFile = async directory => findConfigurationFile(directory, 'service')
|
|
75
|
-
export const
|
|
73
|
+
export const findGatewayConfigFile = async directory => findConfigurationFile(directory, 'gateway')
|
|
76
74
|
export const findRuntimeConfigFile = async directory => findConfigurationFile(directory, 'runtime')
|
|
77
75
|
|
|
78
76
|
/**
|
|
@@ -81,7 +79,7 @@ export const findRuntimeConfigFile = async directory => findConfigurationFile(di
|
|
|
81
79
|
* @returns string
|
|
82
80
|
*/
|
|
83
81
|
export async function getDependencyVersion (dependencyName) {
|
|
84
|
-
const rootPackageJson = join(
|
|
82
|
+
const rootPackageJson = join(import.meta.dirname, '..', 'package.json')
|
|
85
83
|
const packageJsonContents = JSON.parse(await readFile(rootPackageJson, 'utf8'))
|
|
86
84
|
const dependencies = packageJsonContents.dependencies
|
|
87
85
|
const devDependencies = packageJsonContents.devDependencies
|
|
@@ -121,8 +119,8 @@ export async function getDependencyVersion (dependencyName) {
|
|
|
121
119
|
}
|
|
122
120
|
}
|
|
123
121
|
|
|
124
|
-
export function
|
|
125
|
-
return
|
|
122
|
+
export function convertApplicationNameToPrefix (applicationName) {
|
|
123
|
+
return applicationName.replace(/-/g, '_').toUpperCase()
|
|
126
124
|
}
|
|
127
125
|
|
|
128
126
|
export function addPrefixToEnv (env, prefix) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-wattpm",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.6",
|
|
4
4
|
"description": "Create platformatic application interactive tool",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -24,13 +24,13 @@
|
|
|
24
24
|
"resolve": "^1.22.8",
|
|
25
25
|
"undici": "^7.0.0",
|
|
26
26
|
"which": "^3.0.1",
|
|
27
|
-
"@platformatic/
|
|
28
|
-
"@platformatic/
|
|
27
|
+
"@platformatic/foundation": "3.0.0-alpha.6",
|
|
28
|
+
"@platformatic/generators": "3.0.0-alpha.6"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/node": "^22.5.0",
|
|
32
|
-
"borp": "^0.20.0",
|
|
33
32
|
"c8": "^10.0.0",
|
|
33
|
+
"cleaner-spec-reporter": "^0.5.0",
|
|
34
34
|
"cross-env": "^7.0.3",
|
|
35
35
|
"eslint": "9",
|
|
36
36
|
"esmock": "^2.6.4",
|
|
@@ -39,18 +39,18 @@
|
|
|
39
39
|
"semver": "^7.6.0",
|
|
40
40
|
"typescript": "~5.8.0",
|
|
41
41
|
"yaml": "^2.4.1",
|
|
42
|
-
"@platformatic/
|
|
43
|
-
"@platformatic/
|
|
44
|
-
"@platformatic/runtime": "3.0.0-alpha.
|
|
45
|
-
"@platformatic/
|
|
42
|
+
"@platformatic/gateway": "3.0.0-alpha.6",
|
|
43
|
+
"@platformatic/db": "3.0.0-alpha.6",
|
|
44
|
+
"@platformatic/runtime": "3.0.0-alpha.6",
|
|
45
|
+
"@platformatic/service": "3.0.0-alpha.6"
|
|
46
46
|
},
|
|
47
47
|
"engines": {
|
|
48
48
|
"node": ">=22.18.0"
|
|
49
49
|
},
|
|
50
50
|
"scripts": {
|
|
51
|
-
"test:cli": "borp --pattern \"test/cli/*test.js\" --timeout=1200000 --concurrency=1",
|
|
52
|
-
"test:unit": "pnpm run lint && cross-env NODE_OPTIONS=\"--loader=esmock --no-warnings\" borp --pattern \"test/unit/*test.js\" --timeout=1200000 --concurrency=1",
|
|
53
51
|
"test": "npm run test:unit && npm run test:cli",
|
|
52
|
+
"test:cli": "node --test --test-reporter=cleaner-spec-reporter --test-concurrency=1 --test-timeout=2000000 test/cli/*.test.js",
|
|
53
|
+
"test:unit": "node --test --test-reporter=cleaner-spec-reporter --test-concurrency=1 --test-timeout=2000000 test/unit/*.test.js",
|
|
54
54
|
"lint": "eslint"
|
|
55
55
|
}
|
|
56
56
|
}
|