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 CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { checkNodeVersionForServices } from '@platformatic/foundation'
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
- checkNodeVersionForServices()
9
+ checkNodeVersionForApplications()
10
10
 
11
11
  const _args = process.argv.slice(2)
12
12
  const args = parseArgs(_args, {
package/eslint.config.js CHANGED
@@ -1,3 +1,3 @@
1
1
  import neostandard from 'neostandard'
2
2
 
3
- export default neostandard({})
3
+ export default neostandard()
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 { findComposerConfigFile, getUsername, getVersion, say } from './utils.js'
28
- const MARKETPLACE_HOST = 'https://marketplace.platformatic.dev'
29
- const defaultStackables = ['@platformatic/service', '@platformatic/composer', '@platformatic/db']
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 (defaultStackables.includes(pkg) || pkg === '@platformatic/runtime') {
86
- // Let's find if we are using one of the default stackables
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 fetchStackables (marketplaceHost, modules = []) {
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 service do you want to create?',
155
- default: stackables[0],
156
- choices: stackables
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', 'marketplace-host', 'module']
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['marketplace-host'], args['install'])
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 services folder
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 existingService = await findComposerConfigFile(projectDir)
262
+ const existingApplication = await findGatewayConfigFile(projectDir)
275
263
 
276
- if (existingService) {
277
- const serviceConfig = await loadConfigurationFile(existingService)
264
+ if (existingApplication) {
265
+ const applicationConfig = await loadConfigurationFile(existingApplication)
278
266
 
279
- if (serviceConfig.runtime) {
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 stackables = await fetchStackables(marketplaceHost, modules)
368
+ const capabilities = Array.from(new Set([...modules, ...defaultCapabilities]))
381
369
 
382
- const names = generator.existingServices ?? []
370
+ const names = generator.existingApplications ?? []
383
371
 
384
372
  while (true) {
385
- const stackableName = await chooseStackable(inquirer, stackables)
386
- // await say(`Creating a ${stackable} project in ${projectDir}...`)
373
+ const capabilityName = await chooseCapability(inquirer, capabilities)
374
+ // await say(`Creating a ${capability} project in ${projectDir}...`)
387
375
 
388
- const stackable = await importOrLocal({
376
+ const capability = await importOrLocal({
389
377
  pkgManager: packageManager,
390
378
  name: projectName,
391
379
  projectDir,
392
- pkg: stackableName
380
+ pkg: capabilityName
393
381
  })
394
382
 
395
- const { serviceName } = await inquirer.prompt({
383
+ const { applicationName } = await inquirer.prompt({
396
384
  type: 'input',
397
- name: 'serviceName',
398
- message: 'What is the name of the service?',
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(serviceName)
405
+ names.push(applicationName)
418
406
 
419
- const stackableGenerator = stackable.Generator
420
- ? new stackable.Generator({
407
+ const capabilityGenerator = capability.Generator
408
+ ? new capability.Generator({
421
409
  logger,
422
410
  inquirer,
423
- serviceName,
411
+ applicationName,
424
412
  parent: generator,
425
413
  ...additionalGeneratorOptions
426
414
  })
427
415
  : new ImportGenerator({
428
416
  logger,
429
417
  inquirer,
430
- serviceName,
431
- module: stackableName,
432
- version: await getPackageVersion(stackableName, projectDir),
418
+ applicationName,
419
+ module: capabilityName,
420
+ version: await getPackageVersion(capabilityName, projectDir),
433
421
  parent: generator,
434
422
  ...additionalGeneratorOptions
435
423
  })
436
424
 
437
- stackableGenerator.setConfig({
438
- ...stackableGenerator.config,
425
+ capabilityGenerator.setConfig({
426
+ ...capabilityGenerator.config,
439
427
  ...additionalGeneratorConfig,
440
- serviceName
428
+ applicationName
441
429
  })
442
430
 
443
- generator.addService(stackableGenerator, serviceName)
431
+ generator.addApplication(capabilityGenerator, applicationName)
444
432
 
445
- await stackableGenerator.ask()
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 service?',
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 service should be exposed?',
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 findComposerConfigFile = async directory => findConfigurationFile(directory, 'composer')
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(__dirname, '..', 'package.json')
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 convertServiceNameToPrefix (serviceName) {
125
- return serviceName.replace(/-/g, '_').toUpperCase()
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.4",
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/generators": "3.0.0-alpha.4",
28
- "@platformatic/foundation": "3.0.0-alpha.4"
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/composer": "3.0.0-alpha.4",
43
- "@platformatic/service": "3.0.0-alpha.4",
44
- "@platformatic/runtime": "3.0.0-alpha.4",
45
- "@platformatic/db": "3.0.0-alpha.4"
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
  }