create-platformatic 0.27.0 → 0.29.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.
@@ -36,3 +36,4 @@ export {
36
36
  createStaticWorkspaceGHAction,
37
37
  createDynamicWorkspaceGHAction
38
38
  } from './src/ghaction.mjs'
39
+ export { createGitignore, createPackageJson, getDependencyVersion, getVersion } from './src/index.mjs'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-platformatic",
3
- "version": "0.27.0",
3
+ "version": "0.29.0",
4
4
  "description": "Create platformatic-db interactive tool",
5
5
  "repository": {
6
6
  "type": "git",
@@ -33,7 +33,7 @@
33
33
  "semver": "^7.5.1",
34
34
  "undici": "^5.22.1",
35
35
  "which": "^3.0.1",
36
- "@platformatic/config": "0.27.0"
36
+ "@platformatic/config": "0.29.0"
37
37
  },
38
38
  "devDependencies": {
39
39
  "ajv": "^8.12.0",
@@ -45,11 +45,11 @@
45
45
  "standard": "^17.1.0",
46
46
  "tap": "^16.3.6",
47
47
  "yaml": "^2.3.1",
48
- "@platformatic/db": "0.27.0",
49
- "@platformatic/service": "0.27.0"
48
+ "@platformatic/db": "0.29.0",
49
+ "@platformatic/service": "0.29.0"
50
50
  },
51
51
  "scripts": {
52
- "test": "standard | snazzy && cross-env NODE_OPTIONS=\"--loader=esmock --no-warnings\" c8 --100 tap --no-coverage test/*test.mjs test/*/*test.mjs",
52
+ "test": "standard | snazzy && cross-env NODE_OPTIONS=\"--loader=esmock --no-warnings\" c8 tap --no-coverage test/*test.mjs test/*/*test.mjs",
53
53
  "lint": "standard | snazzy"
54
54
  }
55
55
  }
@@ -79,7 +79,7 @@ const createPlatformaticComposer = async (_args, opts) => {
79
79
  // Create the package.json, notes that we don't have the option for TS (yet) so we don't generate
80
80
  // the package.json with the TS build
81
81
  if (!opts.skipPackageJson) {
82
- await createPackageJson('composer', version, fastifyVersion, logger, projectDir, false)
82
+ await createPackageJson(version, fastifyVersion, logger, projectDir, false)
83
83
  }
84
84
  if (!opts.skipGitignore) {
85
85
  await createGitignore(logger, projectDir)
@@ -31,7 +31,11 @@ tags
31
31
  # clinicjs
32
32
  .clinic/
33
33
  `
34
-
34
+ /**
35
+ * Creates a standard Platformatic app .gitignore file
36
+ * @param {import('pino').BaseLogger} logger Logger Interface
37
+ * @param {string} dir Target directory
38
+ */
35
39
  export const createGitignore = async (logger, dir = '.') => {
36
40
  const gitignoreFileName = join(dir, '.gitignore')
37
41
  const isGitignoreExists = await isFileAccessible(gitignoreFileName)
@@ -7,10 +7,10 @@ const packageJsonTemplate = (addTSBuild = false) => (`\
7
7
  {
8
8
  "scripts": {
9
9
  ${addTSBuild
10
- ? `"start": "npm run clean && platformatic {type} start",
10
+ ? `"start": "npm run clean && platformatic start",
11
11
  "clean": "rm -fr ./dist",
12
12
  "build": "npx tsc"`
13
- : '"start": "platformatic {type} start"'}
13
+ : '"start": "platformatic start"'}
14
14
  },
15
15
  "devDependencies": {
16
16
  "fastify": "^{fastifyVersion}"
@@ -23,12 +23,23 @@ const packageJsonTemplate = (addTSBuild = false) => (`\
23
23
  }
24
24
  }`)
25
25
 
26
- export const createPackageJson = async (type, platVersion, fastifyVersion, logger, dir, addTSBuild = false) => {
26
+ /**
27
+ * Creates a Platformatic app package.json file
28
+ * @param {string} platVersion Platformatic Version
29
+ * @param {string} fastifyVersion Fastify Version
30
+ * @param {import('pino').BaseLogger} logger Logger Interface
31
+ * @param {string} dir Target directory where to create the file
32
+ * @param {boolean} addTSBuild Whether to add TS Build or not
33
+ * @param {object} scripts Package.json scripts list
34
+ */
35
+ export const createPackageJson = async (platVersion, fastifyVersion, logger, dir, addTSBuild = false, scripts = {}) => {
27
36
  const packageJsonFileName = join(dir, 'package.json')
28
37
  const isPackageJsonExists = await isFileAccessible(packageJsonFileName)
29
38
  if (!isPackageJsonExists) {
30
- const packageJson = pupa(packageJsonTemplate(addTSBuild), { platVersion, fastifyVersion, type })
31
- await writeFile(packageJsonFileName, packageJson)
39
+ const packageJson = pupa(packageJsonTemplate(addTSBuild), { platVersion, fastifyVersion })
40
+ const parsed = JSON.parse(packageJson)
41
+ Object.assign(parsed.scripts, scripts)
42
+ await writeFile(packageJsonFileName, JSON.stringify(parsed, null, 2))
32
43
  logger.debug(`${packageJsonFileName} successfully created.`)
33
44
  } else {
34
45
  logger.debug(`${packageJsonFileName} found, skipping creation of package.json file.`)
package/src/db/README.md CHANGED
@@ -18,7 +18,7 @@ npm install
18
18
  2. Apply migrations:
19
19
 
20
20
  ```bash
21
- npx platformatic db migrations apply
21
+ npm run migrate
22
22
  ```
23
23
 
24
24
 
@@ -11,11 +11,25 @@ import pino from 'pino'
11
11
  import pretty from 'pino-pretty'
12
12
  import { execa } from 'execa'
13
13
  import ora from 'ora'
14
- import createDB from './create-db.mjs'
14
+ import { getConnectionString, createDB } from './create-db.mjs'
15
15
  import askDir from '../ask-dir.mjs'
16
16
  import { askDynamicWorkspaceCreateGHAction, askStaticWorkspaceGHAction } from '../ghaction.mjs'
17
17
  import { getRunPackageManagerInstall, getUseTypescript, getPort, getOverwriteReadme } from '../cli-options.mjs'
18
18
 
19
+ const databases = [{
20
+ value: 'sqlite',
21
+ name: 'SQLite'
22
+ }, {
23
+ value: 'postgres',
24
+ name: 'PostgreSQL'
25
+ }, {
26
+ value: 'mysql',
27
+ name: 'MySQL'
28
+ }, {
29
+ value: 'mariadb',
30
+ name: 'MariaDB'
31
+ }]
32
+
19
33
  export const createReadme = async (logger, dir = '.') => {
20
34
  const readmeFileName = join(dir, 'README.md')
21
35
  let isReadmeExists = await isFileAccessible(readmeFileName)
@@ -70,6 +84,48 @@ const createPlatformaticDB = async (_args, opts) => {
70
84
  const pkgManager = getPkgManager()
71
85
  const projectDir = opts.dir || await askDir(logger, '.')
72
86
 
87
+ const { database } = await inquirer.prompt({
88
+ type: 'list',
89
+ name: 'database',
90
+ message: 'What database do you want to use?',
91
+ default: args.database,
92
+ choices: databases
93
+ })
94
+
95
+ let connectionString = getConnectionString(database)
96
+
97
+ while (true) {
98
+ const pickConnectionString = await inquirer.prompt({
99
+ type: 'expand',
100
+ name: 'edit',
101
+ message: `Do you want to use the connection string "${connectionString}"?`,
102
+ choices: [
103
+ {
104
+ key: 'y',
105
+ name: 'Confirm',
106
+ value: false
107
+ },
108
+ {
109
+ key: 'e',
110
+ name: 'Edit',
111
+ value: true
112
+ }
113
+ ]
114
+ })
115
+
116
+ if (pickConnectionString.edit) {
117
+ const answers = await inquirer.prompt({
118
+ type: 'editor',
119
+ name: 'connectionString',
120
+ message: 'Edit the connection string',
121
+ default: connectionString
122
+ })
123
+ connectionString = answers.connectionString.trim()
124
+ } else {
125
+ break
126
+ }
127
+ }
128
+
73
129
  const wizardOptions = await inquirer.prompt([{
74
130
  type: 'list',
75
131
  name: 'defaultMigrations',
@@ -97,7 +153,8 @@ const createPlatformaticDB = async (_args, opts) => {
97
153
  const params = {
98
154
  hostname: args.hostname,
99
155
  port: wizardOptions.port,
100
- database: args.database,
156
+ database,
157
+ connectionString,
101
158
  migrations: wizardOptions.defaultMigrations ? args.migrations : '',
102
159
  plugin: generatePlugin,
103
160
  types: useTypes,
@@ -108,8 +165,12 @@ const createPlatformaticDB = async (_args, opts) => {
108
165
 
109
166
  const fastifyVersion = await getDependencyVersion('fastify')
110
167
 
168
+ const scripts = {
169
+ migrate: 'platformatic db migrations apply'
170
+ }
171
+
111
172
  // Create the package.json, .gitignore, readme
112
- await createPackageJson('db', version, fastifyVersion, logger, projectDir, useTypescript)
173
+ await createPackageJson(version, fastifyVersion, logger, projectDir, useTypescript, scripts)
113
174
  await createGitignore(logger, projectDir)
114
175
  await createReadme(logger, projectDir)
115
176
 
@@ -158,8 +219,13 @@ const createPlatformaticDB = async (_args, opts) => {
158
219
  if (applyMigrations) {
159
220
  const spinner = ora('Applying migrations...').start()
160
221
  // We need to apply migrations using the platformatic installed in the project
161
- await execa(pkgManager, ['exec', 'platformatic', 'db', 'migrations', 'apply'], { cwd: projectDir })
162
- spinner.succeed('...done!')
222
+ try {
223
+ await execa(pkgManager, ['exec', 'platformatic', 'db', 'migrations', 'apply'], { cwd: projectDir })
224
+ spinner.succeed('...done!')
225
+ } catch (err) {
226
+ logger.trace({ err })
227
+ spinner.fail('...failed! Try again by running "platformatic db migrations apply"')
228
+ }
163
229
  }
164
230
  }
165
231
  if (generatePlugin) {
@@ -173,8 +239,13 @@ const createPlatformaticDB = async (_args, opts) => {
173
239
 
174
240
  if (generateTypes) {
175
241
  const spinner = ora('Generating types...').start()
176
- await execa(pkgManager, ['exec', 'platformatic', 'db', 'types'], { cwd: projectDir })
177
- spinner.succeed('...done!')
242
+ try {
243
+ await execa(pkgManager, ['exec', 'platformatic', 'db', 'types'], { cwd: projectDir })
244
+ spinner.succeed('...done!')
245
+ } catch (err) {
246
+ logger.trace({ err })
247
+ spinner.fail('...failed! Try again by running "platformatic db types"')
248
+ }
178
249
  }
179
250
  }
180
251
  }
@@ -1,49 +1,37 @@
1
1
  import { writeFile, mkdir, appendFile } from 'fs/promises'
2
2
  import { join, relative, resolve } from 'path'
3
3
  import { findDBConfigFile, isFileAccessible } from '../utils.mjs'
4
+ import { getTsConfig } from '../get-tsconfig.mjs'
4
5
 
5
6
  const connectionStrings = {
6
- postgres: 'postgres://postgres:postgres@localhost:5432/postgres',
7
+ postgres: 'postgres://postgres:postgres@127.0.0.1:5432/postgres',
7
8
  sqlite: 'sqlite://./db.sqlite',
8
- mysql: 'mysql://root@localhost:3306/graph',
9
- mysql8: 'mysql://root@localhost:3308/graph',
10
- mariadb: 'mysql://root@localhost:3307/graph'
9
+ mysql: 'mysql://root@127.0.0.1:3306/platformatic',
10
+ mariadb: 'mysql://root@127.0.0.1:3306/platformatic'
11
11
  }
12
12
 
13
- const moviesMigrationDo = `
13
+ const moviesMigrationDo = (database) => {
14
+ const key = {
15
+ postgres: 'SERIAL',
16
+ sqlite: 'INTEGER',
17
+ mysql: 'INTEGER UNSIGNED AUTO_INCREMENT',
18
+ mariadb: 'INTEGER UNSIGNED AUTO_INCREMENT'
19
+ }
20
+
21
+ return `
14
22
  -- Add SQL in this file to create the database tables for your API
15
23
  CREATE TABLE IF NOT EXISTS movies (
16
- id INTEGER PRIMARY KEY,
24
+ id ${key[database]} PRIMARY KEY,
17
25
  title TEXT NOT NULL
18
26
  );
19
27
  `
28
+ }
20
29
 
21
30
  const moviesMigrationUndo = `
22
31
  -- Add SQL in this file to drop the database tables
23
32
  DROP TABLE movies;
24
33
  `
25
34
 
26
- function getTsConfig (outDir) {
27
- return {
28
- compilerOptions: {
29
- module: 'commonjs',
30
- esModuleInterop: true,
31
- target: 'es6',
32
- sourceMap: true,
33
- pretty: true,
34
- noEmitOnError: true,
35
- outDir
36
- },
37
- watchOptions: {
38
- watchFile: 'fixedPollingInterval',
39
- watchDirectory: 'fixedPollingInterval',
40
- fallbackPolling: 'dynamicPriority',
41
- synchronousWatchDirectory: true,
42
- excludeDirectories: ['**/node_modules', outDir]
43
- }
44
- }
45
- }
46
-
47
35
  const getPluginName = (isTypescript) => isTypescript === true ? 'plugin.ts' : 'plugin.js'
48
36
  const TS_OUT_DIR = 'dist'
49
37
 
@@ -61,6 +49,9 @@ function generateConfig (migrations, plugin, types, typescript, version) {
61
49
  connectionString: '{DATABASE_URL}',
62
50
  graphql: true,
63
51
  openapi: true
52
+ },
53
+ watch: {
54
+ ignore: ['*.sqlite', '*.sqlite-journal']
64
55
  }
65
56
  }
66
57
 
@@ -83,20 +74,29 @@ function generateConfig (migrations, plugin, types, typescript, version) {
83
74
  }
84
75
 
85
76
  if (typescript === true) {
86
- config.plugins.typescript = true
77
+ config.plugins.typescript = '{PLT_TYPESCRIPT}'
87
78
  }
88
79
 
89
80
  return config
90
81
  }
91
82
 
92
- function generateEnv (hostname, port, database) {
93
- const connectionString = connectionStrings[database]
94
- const env = `\
83
+ function generateEnv (hostname, port, connectionString, typescript) {
84
+ let env = `\
95
85
  PLT_SERVER_HOSTNAME=${hostname}
96
86
  PORT=${port}
97
87
  PLT_SERVER_LOGGER_LEVEL=info
98
88
  DATABASE_URL=${connectionString}
99
89
  `
90
+
91
+ if (typescript === true) {
92
+ env += `\
93
+
94
+ # Set to false to disable automatic typescript compilation.
95
+ # Changing this setting is needed for production
96
+ PLT_TYPESCRIPT=true
97
+ `
98
+ }
99
+
100
100
  return env
101
101
  }
102
102
 
@@ -132,7 +132,12 @@ async function generatePluginWithTypesSupport (logger, currentDir, isTypescript)
132
132
  logger.info(`Plugin file created at ${relative(currentDir, pluginPath)}`)
133
133
  }
134
134
 
135
- async function createDB ({ hostname, database = 'sqlite', port, migrations = 'migrations', plugin = true, types = true, typescript = false }, logger, currentDir, version) {
135
+ export function getConnectionString (database) {
136
+ return connectionStrings[database]
137
+ }
138
+
139
+ export async function createDB ({ hostname, database = 'sqlite', port, migrations = 'migrations', plugin = true, types = true, typescript = false, connectionString }, logger, currentDir, version) {
140
+ connectionString = connectionString || getConnectionString(database)
136
141
  const createMigrations = !!migrations // If we don't define a migrations folder, we don't create it
137
142
  const accessibleConfigFilename = await findDBConfigFile(currentDir)
138
143
  if (accessibleConfigFilename === undefined) {
@@ -140,7 +145,7 @@ async function createDB ({ hostname, database = 'sqlite', port, migrations = 'mi
140
145
  await writeFile(join(currentDir, 'platformatic.db.json'), JSON.stringify(config, null, 2))
141
146
  logger.info('Configuration file platformatic.db.json successfully created.')
142
147
 
143
- const env = generateEnv(hostname, port, database)
148
+ const env = generateEnv(hostname, port, connectionString, typescript)
144
149
  const envFileExists = await isFileAccessible('.env', currentDir)
145
150
  await appendFile(join(currentDir, '.env'), env)
146
151
  await writeFile(join(currentDir, '.env.sample'), env)
@@ -172,7 +177,7 @@ async function createDB ({ hostname, database = 'sqlite', port, migrations = 'mi
172
177
  const isMigrationFileDoExists = await isFileAccessible(migrationFilePathDo)
173
178
  const isMigrationFileUndoExists = await isFileAccessible(migrationFilePathUndo)
174
179
  if (!isMigrationFileDoExists && createMigrations) {
175
- await writeFile(migrationFilePathDo, moviesMigrationDo)
180
+ await writeFile(migrationFilePathDo, moviesMigrationDo(database))
176
181
  logger.info(`Migration file ${migrationFileNameDo} successfully created.`)
177
182
  if (!isMigrationFileUndoExists) {
178
183
  await writeFile(migrationFilePathUndo, moviesMigrationUndo)
@@ -199,7 +204,7 @@ async function createDB ({ hostname, database = 'sqlite', port, migrations = 'mi
199
204
  }
200
205
 
201
206
  return {
202
- DATABASE_URL: connectionStrings[database],
207
+ DATABASE_URL: connectionString,
203
208
  PLT_SERVER_LOGGER_LEVEL: 'info',
204
209
  PORT: port,
205
210
  PLT_SERVER_HOSTNAME: hostname
@@ -0,0 +1,20 @@
1
+ export function getTsConfig (outDir) {
2
+ return {
3
+ compilerOptions: {
4
+ module: 'commonjs',
5
+ esModuleInterop: true,
6
+ target: 'es2019',
7
+ sourceMap: true,
8
+ pretty: true,
9
+ noEmitOnError: true,
10
+ outDir
11
+ },
12
+ watchOptions: {
13
+ watchFile: 'fixedPollingInterval',
14
+ watchDirectory: 'fixedPollingInterval',
15
+ fallbackPolling: 'dynamicPriority',
16
+ synchronousWatchDirectory: true,
17
+ excludeDirectories: ['**/node_modules', outDir]
18
+ }
19
+ }
20
+ }
package/src/index.mjs CHANGED
@@ -8,7 +8,9 @@ import createPlatformaticService from './service/create-service-cli.mjs'
8
8
  import createPlatformaticComposer from './composer/create-composer-cli.mjs'
9
9
  import { createPlatformaticRuntime, createRuntimeService } from './runtime/create-runtime-cli.mjs'
10
10
  import commist from 'commist'
11
- import { getUsername, getVersion, minimumSupportedNodeVersions, isCurrentVersionSupported, findRuntimeConfigFile } from './utils.mjs'
11
+ import { getUsername, getVersion, minimumSupportedNodeVersions, isCurrentVersionSupported, findRuntimeConfigFile, getDependencyVersion } from './utils.mjs'
12
+ import { createPackageJson } from './create-package-json.mjs'
13
+ import { createGitignore } from './create-gitignore.mjs'
12
14
 
13
15
  export async function chooseKind (argv, opts = {}) {
14
16
  const skip = opts.skip
@@ -101,3 +103,10 @@ const createPlatformatic = async (argv) => {
101
103
  }
102
104
 
103
105
  export default createPlatformatic
106
+
107
+ export {
108
+ createPackageJson,
109
+ createGitignore,
110
+ getVersion,
111
+ getDependencyVersion
112
+ }
@@ -2,7 +2,7 @@ import { getVersion, getDependencyVersion, isFileAccessible } 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
- import { join } from 'path'
5
+ import { join, relative } from 'path'
6
6
  import inquirer from 'inquirer'
7
7
  import { readFile, writeFile, mkdir } from 'fs/promises'
8
8
  import pino from 'pino'
@@ -46,21 +46,24 @@ export async function createPlatformaticRuntime (_args) {
46
46
  const pkgManager = getPkgManager()
47
47
 
48
48
  const projectDir = await askDir(logger, '.')
49
- const servicesDir = await askDir(logger, 'services', 'Where would you like to load your services from?')
49
+
50
+ // Create the project directory
51
+ await mkdir(projectDir, { recursive: true })
52
+
53
+ const baseServicesDir = join(relative(process.cwd(), projectDir), 'services')
54
+ const servicesDir = await askDir(logger, baseServicesDir, 'Where would you like to load your services from?')
50
55
 
51
56
  const { runPackageManagerInstall } = await inquirer.prompt([
52
57
  getRunPackageManagerInstall(pkgManager)
53
58
  ])
54
59
 
55
- // Create the project directory
56
- await mkdir(projectDir, { recursive: true })
57
60
  await mkdir(servicesDir, { recursive: true })
58
61
 
59
62
  const fastifyVersion = await getDependencyVersion('fastify')
60
63
 
61
64
  // Create the package.json, notes that we don't have the option for TS (yet) so we don't generate
62
65
  // the package.json with the TS build
63
- await createPackageJson('runtime', version, fastifyVersion, logger, projectDir, false)
66
+ await createPackageJson(version, fastifyVersion, logger, projectDir, false)
64
67
  await createGitignore(logger, projectDir)
65
68
  await createReadme(logger, projectDir)
66
69
 
@@ -124,13 +127,24 @@ export async function createRuntimeService ({ servicesDir, names, logger }) {
124
127
  type: 'input',
125
128
  name: 'name',
126
129
  message: 'What is the name of the service?',
127
- default: generateName().dashed
130
+ default: generateName().dashed,
131
+ validate: (value) => {
132
+ if (value.length === 0) {
133
+ return 'Please enter a name'
134
+ }
135
+
136
+ if (value.includes(' ')) {
137
+ return 'Please enter a name without spaces'
138
+ }
139
+
140
+ if (names.includes(value)) {
141
+ return 'This name is already used, please choose another one.'
142
+ }
143
+
144
+ return true
145
+ }
128
146
  })
129
147
 
130
- if (names.includes(name)) {
131
- logger.warn('This name is already used, please choose another one.')
132
- return false
133
- }
134
148
  names.push(name)
135
149
 
136
150
  const serviceDir = join(servicesDir, name)
@@ -80,7 +80,7 @@ const createPlatformaticService = async (_args, opts = {}) => {
80
80
  if (!opts.skipPackageJson) {
81
81
  // Create the package.json, notes that we don't have the option for TS (yet) so we don't generate
82
82
  // the package.json with the TS build
83
- await createPackageJson('service', version, fastifyVersion, logger, projectDir, false)
83
+ await createPackageJson(version, fastifyVersion, logger, projectDir, false)
84
84
  }
85
85
  if (!opts.skipGitignore) {
86
86
  await createGitignore(logger, projectDir)
@@ -2,13 +2,14 @@ import { writeFile, mkdir, readFile, appendFile } from 'fs/promises'
2
2
  import { join } from 'path'
3
3
  import * as desm from 'desm'
4
4
  import { findServiceConfigFile, isFileAccessible } from '../utils.mjs'
5
+ import { getTsConfig } from '../get-tsconfig.mjs'
5
6
 
6
7
  const TS_OUT_DIR = 'dist'
7
8
 
8
9
  function generateConfig (version, typescript) {
9
10
  const plugins = {
10
11
  paths: [
11
- './plugins',
12
+ { path: './plugins', encapsulate: false },
12
13
  './routes'
13
14
  ]
14
15
  }
@@ -29,31 +30,42 @@ function generateConfig (version, typescript) {
29
30
  }
30
31
 
31
32
  if (typescript === true) {
32
- config.plugins.typescript = true
33
+ config.plugins.typescript = '{PLT_TYPESCRIPT}'
33
34
  }
34
35
 
35
36
  return config
36
37
  }
37
38
 
38
- function generateEnv (hostname, port) {
39
- const env = `\
39
+ function generateEnv (hostname, port, typescript) {
40
+ let env = `\
40
41
  PLT_SERVER_HOSTNAME=${hostname}
41
42
  PORT=${port}
42
43
  PLT_SERVER_LOGGER_LEVEL=info
43
44
  `
45
+
46
+ if (typescript === true) {
47
+ env += `\
48
+
49
+ # Set to false to disable automatic typescript compilation.
50
+ # Changing this setting is needed for production
51
+ PLT_TYPESCRIPT=true
52
+ `
53
+ }
54
+
44
55
  return env
45
56
  }
46
57
 
47
58
  const JS_PLUGIN_WITH_TYPES_SUPPORT = `\
59
+ /// <reference types="@platformatic/service" />
48
60
  'use strict'
49
61
  /** @param {import('fastify').FastifyInstance} fastify */
50
62
  module.exports = async function (fastify, opts) {
51
63
  fastify.decorate('example', 'foobar')
52
64
  }
53
- module.exports[Symbol.for('skip-override')] = true
54
65
  `
55
66
 
56
67
  const TS_PLUGIN_WITH_TYPES_SUPPORT = `\
68
+ /// <reference types="@platformatic/service" />
57
69
  import { FastifyInstance, FastifyPluginOptions } from 'fastify'
58
70
 
59
71
  export default async function (fastify: FastifyInstance, opts: FastifyPluginOptions) {
@@ -62,6 +74,7 @@ export default async function (fastify: FastifyInstance, opts: FastifyPluginOpti
62
74
  `
63
75
 
64
76
  const JS_ROUTES_WITH_TYPES_SUPPORT = `\
77
+ /// <reference types="@platformatic/service" />
65
78
  'use strict'
66
79
  /** @param {import('fastify').FastifyInstance} fastify */
67
80
  module.exports = async function (fastify, opts) {
@@ -72,6 +85,7 @@ module.exports = async function (fastify, opts) {
72
85
  `
73
86
 
74
87
  const TS_ROUTES_WITH_TYPES_SUPPORT = `\
88
+ /// <reference types="@platformatic/service" />
75
89
  import { FastifyInstance, FastifyPluginOptions } from 'fastify'
76
90
 
77
91
  declare module 'fastify' {
@@ -87,27 +101,6 @@ export default async function (fastify: FastifyInstance, opts: FastifyPluginOpti
87
101
  }
88
102
  `
89
103
 
90
- function getTsConfig (outDir) {
91
- return {
92
- compilerOptions: {
93
- module: 'commonjs',
94
- esModuleInterop: true,
95
- target: 'es6',
96
- sourceMap: true,
97
- pretty: true,
98
- noEmitOnError: true,
99
- outDir
100
- },
101
- watchOptions: {
102
- watchFile: 'fixedPollingInterval',
103
- watchDirectory: 'fixedPollingInterval',
104
- fallbackPolling: 'dynamicPriority',
105
- synchronousWatchDirectory: true,
106
- excludeDirectories: ['**/node_modules', outDir]
107
- }
108
- }
109
- }
110
-
111
104
  async function generatePluginWithTypesSupport (logger, currentDir, isTypescript) {
112
105
  await mkdir(join(currentDir, 'plugins'))
113
106
  const pluginTemplate = isTypescript
@@ -144,7 +137,7 @@ async function createService ({ hostname, port, typescript = false }, logger, cu
144
137
  await writeFile(join(currentDir, 'platformatic.service.json'), JSON.stringify(config, null, 2))
145
138
  logger.info('Configuration file platformatic.service.json successfully created.')
146
139
 
147
- const env = generateEnv(hostname, port)
140
+ const env = generateEnv(hostname, port, typescript)
148
141
  const envFileExists = await isFileAccessible('.env', currentDir)
149
142
  await appendFile(join(currentDir, '.env'), env)
150
143
  await writeFile(join(currentDir, '.env.sample'), env)
package/src/utils.mjs CHANGED
@@ -18,7 +18,10 @@ export async function isFileAccessible (filename, directory) {
18
18
  return false
19
19
  }
20
20
  }
21
-
21
+ /**
22
+ * Gets the username from git config or `whoami` command
23
+ * @returns string | null
24
+ */
22
25
  export const getUsername = async () => {
23
26
  try {
24
27
  const { stdout } = await execa('git', ['config', 'user.name'])
@@ -39,7 +42,10 @@ export const getUsername = async () => {
39
42
 
40
43
  return null
41
44
  }
42
-
45
+ /**
46
+ * Get the platformatic package version from package.json
47
+ * @returns string
48
+ */
43
49
  /* c8 ignore next 4 */
44
50
  export const getVersion = async () => {
45
51
  const data = await readFile(desm.join(import.meta.url, '..', 'package.json'), 'utf8')
@@ -73,6 +79,11 @@ export const findServiceConfigFile = async (directory) => (ConfigManager.findCon
73
79
  export const findComposerConfigFile = async (directory) => (ConfigManager.findConfigFile(directory, 'composer'))
74
80
  export const findRuntimeConfigFile = async (directory) => (ConfigManager.findConfigFile(directory, 'runtime'))
75
81
 
82
+ /**
83
+ * Gets the version of the specified dependency package from package.json
84
+ * @param {string} dependencyName
85
+ * @returns string
86
+ */
76
87
  export const getDependencyVersion = async (dependencyName) => {
77
88
  const require = createRequire(import.meta.url)
78
89
  const pathToPackageJson = join(dirname(require.resolve(dependencyName)), 'package.json')
@@ -23,12 +23,12 @@ afterEach(() => {
23
23
  test('creates package.json file for db project', async ({ equal }) => {
24
24
  const version = '1.2.3'
25
25
  const fastifyVersion = '4.5.6'
26
- await createPackageJson('db', version, fastifyVersion, fakeLogger, tmpDir, false)
26
+ await createPackageJson(version, fastifyVersion, fakeLogger, tmpDir, false)
27
27
  equal(log, `${join(tmpDir, 'package.json')} successfully created.`)
28
28
  const accessible = await isFileAccessible(join(tmpDir, 'package.json'))
29
29
  equal(accessible, true)
30
30
  const packageJson = JSON.parse(readFileSync(join(tmpDir, 'package.json')))
31
- equal(packageJson.scripts.start, 'platformatic db start')
31
+ equal(packageJson.scripts.start, 'platformatic start')
32
32
  equal(packageJson.scripts.build, undefined)
33
33
  equal(packageJson.dependencies.platformatic, `^${version}`)
34
34
  equal(packageJson.devDependencies.fastify, `^${fastifyVersion}`)
@@ -37,12 +37,12 @@ test('creates package.json file for db project', async ({ equal }) => {
37
37
  test('creates package.json file for service project', async ({ equal }) => {
38
38
  const version = '1.2.3'
39
39
  const fastifyVersion = '4.5.6'
40
- await createPackageJson('service', version, fastifyVersion, fakeLogger, tmpDir, false)
40
+ await createPackageJson(version, fastifyVersion, fakeLogger, tmpDir, false)
41
41
  equal(log, `${join(tmpDir, 'package.json')} successfully created.`)
42
42
  const accessible = await isFileAccessible(join(tmpDir, 'package.json'))
43
43
  equal(accessible, true)
44
44
  const packageJson = JSON.parse(readFileSync(join(tmpDir, 'package.json')))
45
- equal(packageJson.scripts.start, 'platformatic service start')
45
+ equal(packageJson.scripts.start, 'platformatic start')
46
46
  equal(packageJson.dependencies.platformatic, `^${version}`)
47
47
  equal(packageJson.devDependencies.fastify, `^${fastifyVersion}`)
48
48
  })
@@ -52,19 +52,19 @@ test('do not create package.json file because already present', async ({ equal }
52
52
  const fastifyVersion = '4.5.6'
53
53
  const packagejson = join(tmpDir, 'package.json')
54
54
  writeFileSync(packagejson, 'TEST')
55
- await createPackageJson('db', version, fastifyVersion, fakeLogger, tmpDir, false)
55
+ await createPackageJson(version, fastifyVersion, fakeLogger, tmpDir, false)
56
56
  equal(log, `${join(tmpDir, 'package.json')} found, skipping creation of package.json file.`)
57
57
  })
58
58
 
59
59
  test('creates package.json file with TS build', async ({ equal }) => {
60
60
  const version = '1.2.3'
61
61
  const fastifyVersion = '4.5.6'
62
- await createPackageJson('db', version, fastifyVersion, fakeLogger, tmpDir, true)
62
+ await createPackageJson(version, fastifyVersion, fakeLogger, tmpDir, true)
63
63
  equal(log, `${join(tmpDir, 'package.json')} successfully created.`)
64
64
  const accessible = await isFileAccessible(join(tmpDir, 'package.json'))
65
65
  equal(accessible, true)
66
66
  const packageJson = JSON.parse(readFileSync(join(tmpDir, 'package.json')))
67
- equal(packageJson.scripts.start, 'npm run clean && platformatic db start')
67
+ equal(packageJson.scripts.start, 'npm run clean && platformatic start')
68
68
  equal(packageJson.scripts.clean, 'rm -fr ./dist')
69
69
  equal(packageJson.scripts.build, 'npx tsc')
70
70
  equal(packageJson.dependencies.platformatic, `^${version}`)
@@ -188,6 +188,7 @@ test('creates project with typescript', async ({ equal, same }) => {
188
188
  equal(process.env.PLT_SERVER_HOSTNAME, 'myhost')
189
189
  equal(process.env.PORT, '6666')
190
190
  equal(process.env.DATABASE_URL, 'sqlite://./db.sqlite')
191
+ equal(process.env.PLT_TYPESCRIPT, 'true')
191
192
 
192
193
  equal(db.graphql, true)
193
194
  equal(db.openapi, true)
@@ -199,7 +200,7 @@ test('creates project with typescript', async ({ equal, same }) => {
199
200
  equal(migrationFileUndo, moviesMigrationUndo)
200
201
 
201
202
  same(plugins.paths, ['plugin.ts'])
202
- equal(plugins.typescript, true)
203
+ equal(plugins.typescript, '{PLT_TYPESCRIPT}')
203
204
  equal(await isFileAccessible(join(tmpDir, 'plugin.ts')), true)
204
205
  equal(await isFileAccessible(join(tmpDir, 'tsconfig.json')), true)
205
206
  })
@@ -0,0 +1,8 @@
1
+ import { test } from 'tap'
2
+ import * as funcs from '../create-platformatic.mjs'
3
+ test('Should export functions', async ({ ok }) => {
4
+ ok(funcs.createPackageJson)
5
+ ok(funcs.createGitignore)
6
+ ok(funcs.getDependencyVersion)
7
+ ok(funcs.getVersion)
8
+ })
@@ -59,8 +59,8 @@ test('creates service with typescript', async ({ equal, same, ok }) => {
59
59
  equal(process.env.PLT_SERVER_HOSTNAME, 'myhost')
60
60
  equal(process.env.PORT, '6666')
61
61
 
62
- same(plugins.paths, ['./plugins', './routes'])
63
- equal(plugins.typescript, true)
62
+ same(plugins.paths, [{ path: './plugins', encapsulate: false }, './routes'])
63
+ equal(plugins.typescript, '{PLT_TYPESCRIPT}')
64
64
 
65
65
  ok(await isFileAccessible(join(tmpDir, 'tsconfig.json')))
66
66
  ok(await isFileAccessible(join(tmpDir, 'plugins', 'example.ts')))
@@ -95,7 +95,7 @@ test('creates service with javascript', async ({ equal, same, ok }) => {
95
95
  equal(process.env.PLT_SERVER_HOSTNAME, 'myhost')
96
96
  equal(process.env.PORT, '6666')
97
97
 
98
- same(plugins, { paths: ['./plugins', './routes'] })
98
+ same(plugins, { paths: [{ path: './plugins', encapsulate: false }, './routes'] })
99
99
  ok(await isFileAccessible(join(tmpDir, 'plugins', 'example.js')))
100
100
  ok(await isFileAccessible(join(tmpDir, 'routes', 'root.js')))
101
101
  })