create-platformatic 0.47.6 → 1.1.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.
@@ -24,7 +24,7 @@ if (isMain(import.meta)) {
24
24
  })
25
25
 
26
26
  if (args.version) {
27
- console.log('v' + JSON.parse(await readFile(join(import.meta.url, 'package.json'))).version)
27
+ console.log('v' + JSON.parse(await readFile(join(import.meta.url, 'package.json'), 'utf8')).version)
28
28
  process.exit(0)
29
29
  }
30
30
  await createPlatformatic(_args)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-platformatic",
3
- "version": "0.47.6",
3
+ "version": "1.1.0",
4
4
  "description": "Create platformatic-db interactive tool",
5
5
  "repository": {
6
6
  "type": "git",
@@ -16,39 +16,39 @@
16
16
  "author": "Marco Piraccini <marco.piraccini@gmail.com>",
17
17
  "dependencies": {
18
18
  "boring-name-generator": "^1.0.3",
19
- "chalk": "^5.2.0",
19
+ "chalk": "^5.3.0",
20
20
  "columnify": "^1.6.0",
21
21
  "commist": "^3.2.0",
22
22
  "desm": "^1.3.0",
23
- "es-main": "^1.2.0",
24
- "execa": "^8.0.0",
25
- "fastify": "^4.18.0",
23
+ "es-main": "^1.3.0",
24
+ "execa": "^8.0.1",
25
+ "fastify": "^4.23.2",
26
26
  "help-me": "^4.2.0",
27
- "inquirer": "^9.2.7",
27
+ "inquirer": "^9.2.11",
28
28
  "log-update": "^5.0.1",
29
29
  "minimist": "^1.2.8",
30
30
  "ora": "^6.3.1",
31
- "pino": "^8.14.1",
32
- "pino-pretty": "^10.0.0",
31
+ "pino": "^8.15.3",
32
+ "pino-pretty": "^10.2.0",
33
33
  "pupa": "^3.1.0",
34
- "semver": "^7.5.1",
35
- "undici": "^5.22.1",
34
+ "semver": "^7.5.4",
35
+ "undici": "^5.25.3",
36
36
  "which": "^3.0.1",
37
- "@platformatic/config": "0.47.6"
37
+ "@platformatic/config": "1.1.0"
38
38
  },
39
39
  "devDependencies": {
40
40
  "ajv": "^8.12.0",
41
- "c8": "^8.0.0",
41
+ "c8": "^8.0.1",
42
42
  "cross-env": "^7.0.3",
43
- "dotenv": "^16.1.4",
44
- "esmock": "^2.3.1",
43
+ "dotenv": "^16.3.1",
44
+ "esmock": "^2.5.1",
45
45
  "snazzy": "^9.0.0",
46
46
  "standard": "^17.1.0",
47
- "tap": "^16.3.6",
48
- "typescript": "~5.2.0",
49
- "yaml": "^2.3.1",
50
- "@platformatic/db": "0.47.6",
51
- "@platformatic/service": "0.47.6"
47
+ "tap": "^16.3.9",
48
+ "typescript": "~5.2.2",
49
+ "yaml": "^2.3.2",
50
+ "@platformatic/service": "1.1.0",
51
+ "@platformatic/db": "1.1.0"
52
52
  },
53
53
  "scripts": {
54
54
  "test": "standard | snazzy && cross-env NODE_OPTIONS=\"--loader=esmock --no-warnings\" c8 tap --no-coverage test/*test.mjs test/*/*test.mjs",
package/src/ask-dir.mjs CHANGED
@@ -1,3 +1,5 @@
1
+ 'use strict'
2
+
1
3
  import inquirer from 'inquirer'
2
4
  import { resolve } from 'path'
3
5
 
@@ -19,16 +19,6 @@ export const getUseTypescript = typescript => {
19
19
  }
20
20
  }
21
21
 
22
- export const getOverwriteReadme = () => {
23
- return {
24
- type: 'list',
25
- name: 'shouldReplace',
26
- message: 'Do you want to overwrite the existing README.md?',
27
- default: true,
28
- choices: [{ name: 'yes', value: true }, { name: 'no', value: false }]
29
- }
30
- }
31
-
32
22
  let port = 3042
33
23
  export const getPort = (nextPort) => {
34
24
  if (nextPort === undefined) {
@@ -1,39 +1,20 @@
1
- import { getVersion, getDependencyVersion, isFileAccessible } from '../utils.mjs'
1
+ import { getVersion, getDependencyVersion } from '../utils.mjs'
2
2
  import { createPackageJson } from '../create-package-json.mjs'
3
3
  import { createGitignore } from '../create-gitignore.mjs'
4
4
  import { getPkgManager } from '../get-pkg-manager.mjs'
5
5
  import parseArgs from 'minimist'
6
- import { join } from 'path'
7
6
  import inquirer from 'inquirer'
8
- import { readFile, writeFile, mkdir } from 'fs/promises'
7
+ import { mkdir } from 'fs/promises'
9
8
  import pino from 'pino'
10
9
  import pretty from 'pino-pretty'
11
10
  import { execa } from 'execa'
12
11
  import ora from 'ora'
13
12
  import createComposer from './create-composer.mjs'
14
13
  import askDir from '../ask-dir.mjs'
15
- import { askDynamicWorkspaceCreateGHAction, askStaticWorkspaceGHAction } from '../ghaction.mjs'
16
- import { getRunPackageManagerInstall, getPort, getOverwriteReadme } from '../cli-options.mjs'
17
-
18
- export const createReadme = async (logger, dir = '.') => {
19
- const readmeFileName = join(dir, 'README.md')
20
- let isReadmeExists = await isFileAccessible(readmeFileName)
21
- if (isReadmeExists) {
22
- logger.debug(`${readmeFileName} found, asking to overwrite it.`)
23
- const { shouldReplace } = await inquirer.prompt([getOverwriteReadme()])
24
- isReadmeExists = !shouldReplace
25
- }
26
-
27
- if (isReadmeExists) {
28
- logger.debug(`${readmeFileName} found, skipping creation of README.md file.`)
29
- return
30
- }
31
-
32
- const readmeFile = new URL('README.md', import.meta.url)
33
- const readme = await readFile(readmeFile, 'utf-8')
34
- await writeFile(readmeFileName, readme)
35
- logger.debug(`${readmeFileName} successfully created.`)
36
- }
14
+ import { getRunPackageManagerInstall, getPort } from '../cli-options.mjs'
15
+ import { createReadme } from '../create-readme.mjs'
16
+ import { stat } from 'node:fs/promises'
17
+ import { join } from 'path'
37
18
 
38
19
  export const getServicesToCompose = (servicesNames) => {
39
20
  return {
@@ -64,44 +45,77 @@ const createPlatformaticComposer = async (_args, opts) => {
64
45
  const version = await getVersion()
65
46
  const pkgManager = getPkgManager()
66
47
 
67
- const projectDir = opts.dir || await askDir(logger, '.')
48
+ const projectDir = opts.dir || await askDir(logger, join('.', 'platformatic-composer'))
49
+ // checks directory
50
+ try {
51
+ await stat(projectDir)
52
+ logger.error(`Directory ${projectDir} already exists. Please choose another path.`)
53
+ process.exit(1)
54
+ } catch (err) {}
55
+
68
56
  const isRuntimeContext = opts.isRuntimeContext || false
69
57
 
70
- const toAsk = [getPort(args.port)]
58
+ const toAsk = []
59
+
60
+ // Ask for port if not in runtime context
61
+ const portQuestion = getPort(args.port)
62
+ portQuestion.when = !isRuntimeContext
63
+ toAsk.push(portQuestion)
71
64
 
72
65
  if (isRuntimeContext) {
73
66
  const servicesNames = opts.runtimeContext.servicesNames.filter(
74
67
  (serviceName) => serviceName !== opts.serviceName
75
68
  )
76
- toAsk.push(getServicesToCompose(servicesNames))
69
+ if (servicesNames.length > 0) {
70
+ toAsk.push(getServicesToCompose(servicesNames))
71
+ }
77
72
  }
78
73
 
79
74
  if (!opts.skipPackageJson) {
80
75
  toAsk.push(getRunPackageManagerInstall(pkgManager))
81
76
  }
82
-
77
+ if (!opts.skipGitHubActions) {
78
+ toAsk.push({
79
+ type: 'list',
80
+ name: 'staticWorkspaceGitHubAction',
81
+ message: 'Do you want to create the github action to deploy this application to Platformatic Cloud?',
82
+ default: true,
83
+ choices: [{ name: 'yes', value: true }, { name: 'no', value: false }]
84
+ },
85
+ {
86
+ type: 'list',
87
+ name: 'dynamicWorkspaceGitHubAction',
88
+ message: 'Do you want to enable PR Previews in your application?',
89
+ default: true,
90
+ choices: [{ name: 'yes', value: true }, { name: 'no', value: false }]
91
+ })
92
+ }
83
93
  const {
84
94
  runPackageManagerInstall,
85
95
  servicesToCompose,
86
- port
96
+ port,
97
+ staticWorkspaceGitHubAction,
98
+ dynamicWorkspaceGitHubAction
87
99
  } = await inquirer.prompt(toAsk)
88
100
 
89
101
  // Create the project directory
90
102
  await mkdir(projectDir, { recursive: true })
91
103
 
92
104
  const params = {
105
+ isRuntimeContext,
93
106
  hostname: args.hostname,
94
107
  port,
95
- isRuntime: opts.isRuntime
108
+ servicesToCompose,
109
+ staticWorkspaceGitHubAction,
110
+ dynamicWorkspaceGitHubAction,
111
+ runtimeContext: opts.runtimeContext
96
112
  }
97
113
 
98
- const env = await createComposer(
114
+ await createComposer(
99
115
  params,
100
116
  logger,
101
117
  projectDir,
102
- version,
103
- isRuntimeContext,
104
- servicesToCompose
118
+ version
105
119
  )
106
120
 
107
121
  const fastifyVersion = await getDependencyVersion('fastify')
@@ -114,17 +128,12 @@ const createPlatformaticComposer = async (_args, opts) => {
114
128
  if (!opts.skipGitignore) {
115
129
  await createGitignore(logger, projectDir)
116
130
  }
117
- await createReadme(logger, projectDir)
131
+ await createReadme(logger, projectDir, 'composer')
118
132
 
119
133
  if (runPackageManagerInstall) {
120
134
  const spinner = ora('Installing dependencies...').start()
121
135
  await execa(pkgManager, ['install'], { cwd: projectDir })
122
- spinner.succeed('...done!')
123
- }
124
-
125
- if (!opts.skipGitHubActions) {
126
- await askStaticWorkspaceGHAction(logger, env, 'composer', false, projectDir)
127
- await askDynamicWorkspaceCreateGHAction(logger, env, 'composer', false, projectDir)
136
+ spinner.succeed()
128
137
  }
129
138
  }
130
139
 
@@ -2,28 +2,39 @@ import { readFile, writeFile, appendFile } from 'fs/promises'
2
2
  import { findComposerConfigFile, isFileAccessible } from '../utils.mjs'
3
3
  import { join } from 'path'
4
4
  import * as desm from 'desm'
5
+ import { generatePlugins, generateRouteWithTypesSupport } from '../create-plugins.mjs'
6
+ import { createDynamicWorkspaceGHAction, createStaticWorkspaceGHAction } from '../ghaction.mjs'
5
7
 
6
- function generateConfig (version, isRuntimeContext, servicesToCompose) {
8
+ function generateConfig (isRuntimeContext, version, servicesToCompose, envPrefix) {
7
9
  const config = {
8
10
  $schema: `https://platformatic.dev/schemas/v${version}/composer`,
9
- server: {
10
- hostname: '{PLT_SERVER_HOSTNAME}',
11
- port: '{PORT}',
12
- logger: {
13
- level: '{PLT_SERVER_LOGGER_LEVEL}'
14
- }
15
- },
16
11
  composer: {
17
12
  services: [{
18
13
  id: 'example',
19
- origin: '{PLT_EXAMPLE_ORIGIN}',
14
+ origin: `{PLT_${envPrefix}EXAMPLE_ORIGIN}`,
20
15
  openapi: {
21
16
  url: '/documentation/json'
22
17
  }
23
18
  }],
24
19
  refreshTimeout: 1000
25
20
  },
26
- watch: true
21
+ watch: true,
22
+ plugins: {
23
+ paths: [
24
+ { path: './plugins', encapsulate: false },
25
+ './routes'
26
+ ]
27
+ }
28
+ }
29
+
30
+ if (!isRuntimeContext) {
31
+ config.server = {
32
+ hostname: '{PLT_SERVER_HOSTNAME}',
33
+ port: '{PORT}',
34
+ logger: {
35
+ level: '{PLT_SERVER_LOGGER_LEVEL}'
36
+ }
37
+ }
27
38
  }
28
39
 
29
40
  if (isRuntimeContext) {
@@ -41,30 +52,36 @@ function generateConfig (version, isRuntimeContext, servicesToCompose) {
41
52
  return config
42
53
  }
43
54
 
44
- function generateEnv (isRuntimeContext, hostname, port) {
45
- let env = `\
46
- PLT_SERVER_HOSTNAME=${hostname}
47
- PORT=${port}
48
- PLT_SERVER_LOGGER_LEVEL=info
49
- `
55
+ function generateEnv (isRuntimeContext, hostname, port, envPrefix) {
56
+ let env = ''
50
57
 
51
58
  if (!isRuntimeContext) {
52
59
  env += `\
53
- PLT_EXAMPLE_ORIGIN=
54
- `
60
+ PLT_SERVER_HOSTNAME=${hostname}
61
+ PORT=${port}
62
+ PLT_SERVER_LOGGER_LEVEL=info`
55
63
  }
56
-
64
+ env += `
65
+ PLT_${envPrefix}EXAMPLE_ORIGIN=
66
+ `
57
67
  return env
58
68
  }
59
69
 
60
70
  async function createComposer (
61
- { hostname, port },
71
+ params,
62
72
  logger,
63
73
  currentDir = process.cwd(),
64
74
  version,
65
- isRuntimeContext = false,
66
- servicesToCompose = []
75
+ staticWorkspaceGitHubAction,
76
+ dynamicWorkspaceGitHubAction
67
77
  ) {
78
+ const { isRuntimeContext, hostname, port, servicesToCompose = [], runtimeContext } = params
79
+
80
+ const composerEnv = {
81
+ PLT_SERVER_LOGGER_LEVEL: 'info',
82
+ PORT: port,
83
+ PLT_SERVER_HOSTNAME: hostname
84
+ }
68
85
  if (!version) {
69
86
  const pkg = await readFile(desm.join(import.meta.url, '..', '..', 'package.json'))
70
87
  version = JSON.parse(pkg).version
@@ -72,11 +89,13 @@ async function createComposer (
72
89
  const accessibleConfigFilename = await findComposerConfigFile(currentDir)
73
90
 
74
91
  if (accessibleConfigFilename === undefined) {
75
- const config = generateConfig(version, isRuntimeContext, servicesToCompose)
92
+ const envPrefix = runtimeContext !== undefined ? `${runtimeContext.envPrefix}_` : ''
93
+
94
+ const config = generateConfig(isRuntimeContext, version, servicesToCompose, envPrefix)
76
95
  await writeFile(join(currentDir, 'platformatic.composer.json'), JSON.stringify(config, null, 2))
77
96
  logger.info('Configuration file platformatic.composer.json successfully created.')
78
97
 
79
- const env = generateEnv(isRuntimeContext, hostname, port)
98
+ const env = generateEnv(isRuntimeContext, hostname, port, envPrefix)
80
99
  const envFileExists = await isFileAccessible('.env', currentDir)
81
100
  await appendFile(join(currentDir, '.env'), env)
82
101
  await writeFile(join(currentDir, '.env.sample'), env)
@@ -89,12 +108,17 @@ async function createComposer (
89
108
  } else {
90
109
  logger.info(`Configuration file ${accessibleConfigFilename} found, skipping creation of configuration file.`)
91
110
  }
111
+ await generatePlugins(logger, currentDir, false, 'composer')
112
+ await generateRouteWithTypesSupport(logger, currentDir, false)
92
113
 
93
- return {
94
- PLT_SERVER_LOGGER_LEVEL: 'info',
95
- PORT: port,
96
- PLT_SERVER_HOSTNAME: hostname
114
+ if (staticWorkspaceGitHubAction) {
115
+ await createStaticWorkspaceGHAction(logger, composerEnv, './platformatic.service.json', currentDir, false)
97
116
  }
117
+ if (dynamicWorkspaceGitHubAction) {
118
+ await createDynamicWorkspaceGHAction(logger, composerEnv, './platformatic.service.json', currentDir, false)
119
+ }
120
+
121
+ return composerEnv
98
122
  }
99
123
 
100
124
  export default createComposer
@@ -14,7 +14,8 @@ const packageJsonTemplate = async (addTSBuild, fastifyVersion, platVersion) => {
14
14
 
15
15
  const pkg = {
16
16
  scripts: {
17
- start: 'platformatic start'
17
+ start: 'platformatic start',
18
+ test: 'node --test test/**'
18
19
  },
19
20
  devDependencies: {
20
21
  fastify: `^${fastifyVersion}`
@@ -0,0 +1,12 @@
1
+ 'use strict'
2
+ import { readFile, writeFile } from 'fs/promises'
3
+ import { join as desmJoin } from 'desm'
4
+ import { join } from 'path'
5
+
6
+ export const createReadme = async (logger, dir = '.', type) => {
7
+ const readmeFileTarget = join(dir, 'README.md')
8
+ const readmeFileSource = desmJoin(import.meta.url, type, 'README.md')
9
+ const readme = await readFile(readmeFileSource, 'utf-8')
10
+ await writeFile(readmeFileTarget, readme)
11
+ logger.debug(`${readmeFileTarget} successfully created.`)
12
+ }