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.
- package/create-platformatic.mjs +1 -1
- package/package.json +19 -19
- package/src/ask-dir.mjs +2 -0
- package/src/cli-options.mjs +0 -10
- package/src/composer/create-composer-cli.mjs +51 -42
- package/src/composer/create-composer.mjs +52 -28
- package/src/create-package-json.mjs +2 -1
- package/src/create-readme.mjs +12 -0
- package/src/db/create-db-cli.mjs +91 -80
- package/src/db/create-db.mjs +71 -29
- package/src/ghaction.mjs +8 -41
- package/src/runtime/create-runtime-cli.mjs +64 -40
- package/src/runtime/create-runtime.mjs +78 -62
- package/src/service/create-service-cli.mjs +51 -39
- package/src/service/create-service.mjs +56 -24
- package/src/utils.mjs +12 -0
package/create-platformatic.mjs
CHANGED
|
@@ -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": "
|
|
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.
|
|
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.
|
|
24
|
-
"execa": "^8.0.
|
|
25
|
-
"fastify": "^4.
|
|
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.
|
|
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.
|
|
32
|
-
"pino-pretty": "^10.
|
|
31
|
+
"pino": "^8.15.3",
|
|
32
|
+
"pino-pretty": "^10.2.0",
|
|
33
33
|
"pupa": "^3.1.0",
|
|
34
|
-
"semver": "^7.5.
|
|
35
|
-
"undici": "^5.
|
|
34
|
+
"semver": "^7.5.4",
|
|
35
|
+
"undici": "^5.25.3",
|
|
36
36
|
"which": "^3.0.1",
|
|
37
|
-
"@platformatic/config": "
|
|
37
|
+
"@platformatic/config": "1.1.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"ajv": "^8.12.0",
|
|
41
|
-
"c8": "^8.0.
|
|
41
|
+
"c8": "^8.0.1",
|
|
42
42
|
"cross-env": "^7.0.3",
|
|
43
|
-
"dotenv": "^16.1
|
|
44
|
-
"esmock": "^2.
|
|
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.
|
|
48
|
-
"typescript": "~5.2.
|
|
49
|
-
"yaml": "^2.3.
|
|
50
|
-
"@platformatic/
|
|
51
|
-
"@platformatic/
|
|
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
package/src/cli-options.mjs
CHANGED
|
@@ -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
|
|
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 {
|
|
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 {
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
|
|
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 = [
|
|
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
|
-
|
|
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
|
-
|
|
108
|
+
servicesToCompose,
|
|
109
|
+
staticWorkspaceGitHubAction,
|
|
110
|
+
dynamicWorkspaceGitHubAction,
|
|
111
|
+
runtimeContext: opts.runtimeContext
|
|
96
112
|
}
|
|
97
113
|
|
|
98
|
-
|
|
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(
|
|
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,
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
71
|
+
params,
|
|
62
72
|
logger,
|
|
63
73
|
currentDir = process.cwd(),
|
|
64
74
|
version,
|
|
65
|
-
|
|
66
|
-
|
|
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
|
|
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
|
-
|
|
94
|
-
|
|
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
|
+
}
|