@platformatic/db 2.72.0 → 3.0.0-alpha.1

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.
Files changed (58) hide show
  1. package/config.d.ts +1 -19
  2. package/eslint.config.js +9 -5
  3. package/index.d.ts +56 -31
  4. package/index.js +67 -128
  5. package/lib/application.js +102 -0
  6. package/lib/commands/index.js +59 -0
  7. package/lib/commands/migrations-apply.js +62 -0
  8. package/lib/commands/migrations-create.js +48 -0
  9. package/lib/commands/print-schema.js +30 -0
  10. package/lib/commands/seed.js +88 -0
  11. package/lib/commands/types.js +21 -0
  12. package/lib/errors.js +15 -11
  13. package/lib/{generator/db-generator.js → generator.js} +57 -52
  14. package/lib/{migrator.mjs → migrator.js} +45 -37
  15. package/lib/{root-endpoint/index.js → root.js} +6 -7
  16. package/lib/schema.js +31 -21
  17. package/lib/stackable.js +14 -26
  18. package/lib/{generator/code-templates.js → templates.js} +47 -17
  19. package/lib/types.js +160 -0
  20. package/lib/upgrade.js +7 -10
  21. package/lib/utils.js +12 -23
  22. package/lib/versions/0.18.0.js +3 -5
  23. package/lib/versions/{from-zero-twenty-height-to-will-see.js → 0.28.0.js} +3 -5
  24. package/lib/versions/2.0.0.js +3 -5
  25. package/package.json +16 -23
  26. package/schema.json +2 -73
  27. package/tsconfig.json +16 -6
  28. package/.snapshots/810d795d512560f3863d8db472c81c27/0.json +0 -1
  29. package/.snapshots/810d795d512560f3863d8db472c81c27/1.json +0 -1
  30. package/db.mjs +0 -86
  31. package/help/compile.txt +0 -17
  32. package/help/create.txt +0 -13
  33. package/help/help.txt +0 -11
  34. package/help/migrations apply.txt +0 -45
  35. package/help/migrations create.txt +0 -27
  36. package/help/migrations.txt +0 -4
  37. package/help/schema.txt +0 -25
  38. package/help/seed.txt +0 -36
  39. package/help/start.txt +0 -47
  40. package/help/types.txt +0 -40
  41. package/index.test-d.ts +0 -43
  42. package/lib/adjust-config.js +0 -42
  43. package/lib/create.mjs +0 -89
  44. package/lib/gen-migration.mjs +0 -53
  45. package/lib/gen-schema.mjs +0 -68
  46. package/lib/gen-types.mjs +0 -202
  47. package/lib/generator/README.md +0 -38
  48. package/lib/generator.d.ts +0 -7
  49. package/lib/migrate.mjs +0 -87
  50. package/lib/seed.mjs +0 -90
  51. /package/{lib/root-endpoint/public → public}/images/dark_mode.svg +0 -0
  52. /package/{lib/root-endpoint/public → public}/images/favicon.ico +0 -0
  53. /package/{lib/root-endpoint/public → public}/images/light_mode.svg +0 -0
  54. /package/{lib/root-endpoint/public → public}/images/platformatic-logo-dark.svg +0 -0
  55. /package/{lib/root-endpoint/public → public}/images/platformatic-logo-light.svg +0 -0
  56. /package/{lib/root-endpoint/public → public}/images/triangle_dark.svg +0 -0
  57. /package/{lib/root-endpoint/public → public}/images/triangle_light.svg +0 -0
  58. /package/{lib/root-endpoint/public → public}/index.html +0 -0
@@ -0,0 +1,88 @@
1
+ import tsCompiler from '@platformatic/ts-compiler'
2
+ import { loadConfiguration, loadModule } from '@platformatic/utils'
3
+ import { access, readFile } from 'fs/promises'
4
+ import { createRequire } from 'node:module'
5
+ import { join, resolve } from 'node:path'
6
+ import { MissingSeedFileError } from '../errors.js'
7
+ import { Migrator } from '../migrator.js'
8
+ import { schema } from '../schema.js'
9
+ import { setupDB } from '../utils.js'
10
+
11
+ export async function seed (logger, configFile, args, { colorette: { bold }, logFatalError }) {
12
+ const config = await loadConfiguration(configFile, schema)
13
+
14
+ if (config.migrations !== undefined) {
15
+ const migrator = new Migrator(config.migrations, config.db, logger)
16
+
17
+ try {
18
+ const hasMigrationsToApply = await migrator.hasMigrationsToApply()
19
+ if (hasMigrationsToApply) {
20
+ logFatalError(logger, 'You must apply migrations before seeding the database.')
21
+ return
22
+ }
23
+ } finally {
24
+ await migrator.close()
25
+ }
26
+ }
27
+
28
+ if (!args.length) {
29
+ throw new MissingSeedFileError()
30
+ }
31
+
32
+ let seedFile = resolve(process.cwd(), args[0])
33
+
34
+ // check if we are in Typescript and, in case, compile it
35
+ if (seedFile.endsWith('.ts')) {
36
+ await tsCompiler.compile({
37
+ cwd: process.cwd(),
38
+ logger,
39
+ tsConfig: config.plugins?.typescript?.tsConfig,
40
+ flags: config.plugins?.typescript?.flags
41
+ })
42
+ const tsConfigPath = config?.plugins?.typescript?.tsConfig || resolve(process.cwd(), 'tsconfig.json')
43
+ const tsConfig = JSON.parse(await readFile(tsConfigPath, 'utf8'))
44
+ const outDir = tsConfig.compilerOptions.outDir
45
+ seedFile = join(outDir, seedFile.replace('.ts', '.js'))
46
+ }
47
+
48
+ await access(seedFile)
49
+
50
+ logger.info(`Seeding from ${bold(seedFile)}`)
51
+
52
+ const importedModule = await loadModule(createRequire(resolve(process.cwd(), 'noop.js')), seedFile)
53
+
54
+ const seedFunction = typeof importedModule?.seed !== 'function' ? importedModule : importedModule
55
+
56
+ if (typeof seedFunction !== 'function') {
57
+ logFatalError(logger, 'Cannot find seed function.')
58
+ logFatalError(logger, "If you use an ESM module use the signature 'export async function seed (opts)'.")
59
+ logFatalError(logger, "If you use a CJS module use the signature 'module.exports = async function seed (opts)'.")
60
+ logFatalError(logger, "If you use Typescript use the signature 'export async function seed(opts)'")
61
+ return
62
+ }
63
+
64
+ const { db, sql, entities } = await setupDB(logger, config.db)
65
+ await seedFunction({ db, sql, entities, logger })
66
+ logger.info('Seeding complete.')
67
+
68
+ // Once done seeding, close your connection.
69
+ await db.dispose()
70
+ }
71
+
72
+ export const helpFooter = `
73
+ This is a convenience method that loads a JavaScript file and configure @platformatic/sql-mapper to connect to the database specified in the configuration file.
74
+
75
+ Here is an example of a seed file:
76
+
77
+ \`\`\`
78
+ 'use strict'
79
+
80
+ module.exports = async function ({ entities, db, sql }) {
81
+ await entities.graph.save({ input: { name: 'Hello' } })
82
+ await db.query(sql\`INSERT INTO graphs (name) VALUES ('Hello 2');\`)
83
+ }
84
+ \`\`\`
85
+
86
+ You can find more details about the configuration format here:
87
+ * [Platformatic DB Configuration](https://docs.platformatic.dev/docs/db/configuration)
88
+ `
@@ -0,0 +1,21 @@
1
+ import { loadConfiguration } from '@platformatic/utils'
2
+ import { schema } from '../schema.js'
3
+ import { execute } from '../types.js'
4
+
5
+ export async function generateTypes (logger, configFile, _args) {
6
+ const config = await loadConfiguration(configFile, schema)
7
+
8
+ const count = await execute({ logger, config })
9
+
10
+ if (count === 0) {
11
+ logger.warn('No entities found in your schema. Types were NOT generated.')
12
+ logger.warn('Make sure you have applied all the migrations and try again.')
13
+ }
14
+ }
15
+
16
+ export const helpFooter = `
17
+ As a result of executing this command, the Platformatic DB will generate a \`types\` folder with a typescript file for each database entity. It will also generate a \`plt-env.d.ts\` file that injects the types into the Application instance.
18
+
19
+ You can find more details about the configuration format here:
20
+ * [Platformatic DB Configuration](https://docs.platformatic.dev/docs/db/configuration)
21
+ `
package/lib/errors.js CHANGED
@@ -1,14 +1,18 @@
1
- 'use strict'
2
-
3
- const createError = require('@fastify/error')
1
+ import createError from '@fastify/error'
4
2
 
5
3
  const ERROR_PREFIX = 'PLT_DB'
6
4
 
7
- module.exports = {
8
- MigrateMissingMigrationsError: createError(`${ERROR_PREFIX}_MIGRATE_ERROR`, 'Missing "migrations" section in config file'),
9
- UnknownDatabaseError: createError(`${ERROR_PREFIX}_UNKNOWN_DATABASE_ERROR`, 'Unknown database'),
10
- MigrateMissingMigrationsDirError: createError(`${ERROR_PREFIX}_MIGRATE_ERROR`, 'Migrations directory %s does not exist'),
11
- MissingSeedFileError: createError(`${ERROR_PREFIX}_MISSING_SEED_FILE_ERROR`, 'Missing seed file'),
12
- MigrationsToApplyError: createError(`${ERROR_PREFIX}_MIGRATIONS_TO_APPLY_ERROR`, 'You have migrations to apply. Please run `platformatic db migrations apply` first.'),
13
-
14
- }
5
+ export const MigrateMissingMigrationsError = createError(
6
+ `${ERROR_PREFIX}_MIGRATE_ERROR`,
7
+ 'Missing "migrations" section in config file'
8
+ )
9
+ export const UnknownDatabaseError = createError(`${ERROR_PREFIX}_UNKNOWN_DATABASE_ERROR`, 'Unknown database')
10
+ export const MigrateMissingMigrationsDirError = createError(
11
+ `${ERROR_PREFIX}_MIGRATE_ERROR`,
12
+ 'Migrations directory %s does not exist'
13
+ )
14
+ export const MissingSeedFileError = createError(`${ERROR_PREFIX}_MISSING_SEED_FILE_ERROR`, 'Missing seed file')
15
+ export const MigrationsToApplyError = createError(
16
+ `${ERROR_PREFIX}_MIGRATIONS_TO_APPLY_ERROR`,
17
+ 'You have migrations to apply.'
18
+ )
@@ -1,21 +1,18 @@
1
- 'use strict'
1
+ import { BaseGenerator, generateTests } from '@platformatic/generators'
2
+ import { join } from 'node:path'
3
+ import { jsHelperMySQL, jsHelperPostgres, jsHelperSqlite, moviesTestJS, moviesTestTS, README } from './templates.js'
2
4
 
3
- const { BaseGenerator, generateTests } = require('@platformatic/generators')
4
- const { jsHelperSqlite, jsHelperMySQL, jsHelperPostgres, moviesTestTS, moviesTestJS } = require('./code-templates')
5
- const { join } = require('node:path')
6
- const { readFile } = require('node:fs/promises')
7
-
8
- class DBGenerator extends BaseGenerator {
5
+ export class Generator extends BaseGenerator {
9
6
  constructor (opts = {}) {
10
7
  super({
11
8
  ...opts,
12
- module: '@platformatic/db',
9
+ module: '@platformatic/db'
13
10
  })
14
11
  this.connectionStrings = {
15
12
  postgres: 'postgres://postgres:postgres@127.0.0.1:5432/postgres',
16
13
  sqlite: 'sqlite://./db.sqlite',
17
14
  mysql: 'mysql://root@127.0.0.1:3306/platformatic',
18
- mariadb: 'mysql://root@127.0.0.1:3306/platformatic',
15
+ mariadb: 'mysql://root@127.0.0.1:3306/platformatic'
19
16
  }
20
17
  }
21
18
 
@@ -29,7 +26,7 @@ class DBGenerator extends BaseGenerator {
29
26
  tests: true,
30
27
  types: true,
31
28
  migrations: 'migrations',
32
- createMigrations: true,
29
+ createMigrations: true
33
30
  }
34
31
  }
35
32
 
@@ -43,11 +40,11 @@ class DBGenerator extends BaseGenerator {
43
40
  connectionString: `{${this.getEnvVarName('DATABASE_URL')}}`,
44
41
  graphql: true,
45
42
  openapi: true,
46
- schemalock: true,
43
+ schemalock: true
47
44
  },
48
45
  watch: {
49
- ignore: ['*.sqlite', '*.sqlite-journal'],
50
- },
46
+ ignore: ['*.sqlite', '*.sqlite-journal']
47
+ }
51
48
  }
52
49
 
53
50
  if (!isRuntimeContext) {
@@ -55,15 +52,15 @@ class DBGenerator extends BaseGenerator {
55
52
  hostname: '{PLT_SERVER_HOSTNAME}',
56
53
  port: '{PORT}',
57
54
  logger: {
58
- level: '{PLT_SERVER_LOGGER_LEVEL}',
59
- },
55
+ level: '{PLT_SERVER_LOGGER_LEVEL}'
56
+ }
60
57
  }
61
58
  }
62
59
 
63
60
  if (migrations) {
64
61
  config.migrations = {
65
62
  dir: migrations,
66
- autoApply: `{${this.getEnvVarName('PLT_APPLY_MIGRATIONS')}}`,
63
+ autoApply: `{${this.getEnvVarName('PLT_APPLY_MIGRATIONS')}}`
67
64
  }
68
65
 
69
66
  this.addFile({ path: 'migrations', file: '.gitkeep', contents: '' })
@@ -71,19 +68,22 @@ class DBGenerator extends BaseGenerator {
71
68
 
72
69
  if (plugin === true) {
73
70
  config.plugins = {
74
- paths: [{
75
- path: './plugins',
76
- encapsulate: false,
77
- }, {
78
- path: './routes',
79
- }],
80
- typescript: `{${this.getEnvVarName('PLT_TYPESCRIPT')}}`,
71
+ paths: [
72
+ {
73
+ path: './plugins',
74
+ encapsulate: false
75
+ },
76
+ {
77
+ path: './routes'
78
+ }
79
+ ],
80
+ typescript: `{${this.getEnvVarName('PLT_TYPESCRIPT')}}`
81
81
  }
82
82
  }
83
83
 
84
84
  if (types === true) {
85
85
  config.types = {
86
- autogenerate: true,
86
+ autogenerate: true
87
87
  }
88
88
  }
89
89
 
@@ -94,22 +94,28 @@ class DBGenerator extends BaseGenerator {
94
94
  if (!this.config.isUpdating) {
95
95
  this.config.connectionString = this.config.connectionString || this.connectionStrings[this.config.database]
96
96
  this.config.dependencies = {
97
- '@platformatic/db': `^${this.platformaticVersion}`,
97
+ '@platformatic/db': `^${this.platformaticVersion}`
98
98
  }
99
99
 
100
100
  if (!this.config.isRuntimeContext) {
101
- this.addEnvVars({
102
- PLT_SERVER_HOSTNAME: this.config.hostname,
103
- PLT_SERVER_LOGGER_LEVEL: 'info',
104
- PORT: 3042,
105
- }, { overwrite: false, default: true })
101
+ this.addEnvVars(
102
+ {
103
+ PLT_SERVER_HOSTNAME: this.config.hostname,
104
+ PLT_SERVER_LOGGER_LEVEL: 'info',
105
+ PORT: 3042
106
+ },
107
+ { overwrite: false, default: true }
108
+ )
106
109
  }
107
110
 
108
- this.addEnvVars({
109
- PLT_TYPESCRIPT: this.config.typescript,
110
- DATABASE_URL: this.connectionStrings[this.config.database],
111
- PLT_APPLY_MIGRATIONS: 'true',
112
- }, { overwrite: false, default: true })
111
+ this.addEnvVars(
112
+ {
113
+ PLT_TYPESCRIPT: this.config.typescript,
114
+ DATABASE_URL: this.connectionStrings[this.config.database],
115
+ PLT_APPLY_MIGRATIONS: 'true'
116
+ },
117
+ { overwrite: false, default: true }
118
+ )
113
119
  }
114
120
  }
115
121
 
@@ -119,7 +125,7 @@ class DBGenerator extends BaseGenerator {
119
125
  this.createMigrationFiles()
120
126
  }
121
127
 
122
- this.addFile({ path: '', file: 'README.md', contents: await readFile(join(__dirname, 'README.md'), 'utf-8') })
128
+ this.addFile({ path: '', file: 'README.md', contents: README })
123
129
 
124
130
  if (this.config.plugin) {
125
131
  let jsHelper = { pre: '', config: '', post: '' }
@@ -148,7 +154,7 @@ class DBGenerator extends BaseGenerator {
148
154
 
149
155
  // TODO(leorossi): this is unfortunate. We have already generated tests in BaseGenerator
150
156
  // next line will override the test files
151
- generateTests(this.config.typescript, '@platformatic/db', jsHelper).forEach((fileObject) => {
157
+ generateTests(this.config.typescript, '@platformatic/db', jsHelper).forEach(fileObject => {
152
158
  this.addFile(fileObject)
153
159
  })
154
160
 
@@ -161,17 +167,17 @@ class DBGenerator extends BaseGenerator {
161
167
  }
162
168
  }
163
169
 
164
- const GLOBAL_TYPES_TEMPLATE = `
170
+ const ENVIRONMENT_TEMPLATE = `
165
171
  import { FastifyInstance } from 'fastify'
166
- import { PlatformaticApp, PlatformaticDBConfig, PlatformaticDBMixin, Entities } from '@platformatic/db'
172
+ import { PlatformaticApplication, PlatformaticDatabaseConfig, PlatformaticDatabaseMixin, Entities } from '@platformatic/db'
167
173
 
168
174
  declare module 'fastify' {
169
175
  interface FastifyInstance {
170
- platformatic: PlatformaticApp<PlatformaticDBConfig> & PlatformaticDBMixin<Entities>
176
+ platformatic: PlatformaticApplication<PlatformaticDatabaseConfig> & PlatformaticDatabaseMixin<Entities>
171
177
  }
172
178
  }
173
179
  `
174
- this.addFile({ path: '', file: 'global.d.ts', contents: GLOBAL_TYPES_TEMPLATE })
180
+ this.addFile({ path: '', file: 'plt-env.d.ts', contents: ENVIRONMENT_TEMPLATE })
175
181
  }
176
182
  }
177
183
 
@@ -185,7 +191,7 @@ declare module 'fastify' {
185
191
  postgres: 'SERIAL',
186
192
  sqlite: 'INTEGER',
187
193
  mysql: 'INTEGER UNSIGNED AUTO_INCREMENT',
188
- mariadb: 'INTEGER UNSIGNED AUTO_INCREMENT',
194
+ mariadb: 'INTEGER UNSIGNED AUTO_INCREMENT'
189
195
  }
190
196
 
191
197
  return `
@@ -224,26 +230,26 @@ declare module 'fastify' {
224
230
  label: 'What is the connection string?',
225
231
  default: this.connectionStrings.sqlite,
226
232
  type: 'string',
227
- configValue: 'connectionString',
233
+ configValue: 'connectionString'
228
234
  },
229
235
  {
230
236
  var: 'PLT_APPLY_MIGRATIONS',
231
237
  label: 'Should migrations be applied automatically on startup?',
232
238
  default: true,
233
- type: 'boolean',
234
- },
239
+ type: 'boolean'
240
+ }
235
241
  ]
236
242
  }
237
243
 
238
244
  async prepareQuestions () {
239
245
  await super.prepareQuestions()
240
246
  if (!this.config.connectionString) {
241
- const def = this.getConfigFieldsDefinitions().find((q) => q.var === 'DATABASE_URL')
247
+ const def = this.getConfigFieldsDefinitions().find(q => q.var === 'DATABASE_URL')
242
248
  this.questions.push({
243
249
  type: 'input',
244
250
  name: def.configValue,
245
251
  message: def.label,
246
- default: def.default,
252
+ default: def.default
247
253
  })
248
254
  }
249
255
 
@@ -252,11 +258,10 @@ declare module 'fastify' {
252
258
  name: 'createMigrations',
253
259
  message: 'Do you want to create default migrations?',
254
260
  default: true,
255
- choices: [{ name: 'yes', value: true }, { name: 'no', value: false }],
261
+ choices: [
262
+ { name: 'yes', value: true },
263
+ { name: 'no', value: false }
264
+ ]
256
265
  })
257
266
  }
258
267
  }
259
-
260
- module.exports = DBGenerator
261
- module.exports.DBGenerator = DBGenerator
262
- module.exports.Generator = DBGenerator
@@ -1,10 +1,9 @@
1
- import { basename } from 'path'
2
- import Postgrator from 'postgrator'
3
1
  import { createConnectionPool } from '@platformatic/sql-mapper'
4
- import { stat, readdir } from 'fs/promises'
5
- import errors from './errors.js'
2
+ import { readdir, stat } from 'node:fs/promises'
3
+ import { basename } from 'node:path'
4
+ import { MigrateMissingMigrationsDirError, MigrateMissingMigrationsError } from './errors.js'
6
5
 
7
- class Migrator {
6
+ export class Migrator {
8
7
  constructor (migrationConfig, coreConfig, logger) {
9
8
  this.coreConfig = coreConfig
10
9
  this.migrationDir = migrationConfig.dir
@@ -21,6 +20,8 @@ class Migrator {
21
20
  }
22
21
 
23
22
  async setupPostgrator () {
23
+ const { default: Postgrator } = await import('postgrator')
24
+
24
25
  this.appliedMigrationsCount = 0
25
26
  if (this.postgrator instanceof Postgrator) return
26
27
 
@@ -28,7 +29,7 @@ class Migrator {
28
29
 
29
30
  const { db, sql } = await createConnectionPool({
30
31
  ...this.coreConfig,
31
- log: this.logger,
32
+ log: this.logger
32
33
  })
33
34
 
34
35
  let driver
@@ -44,9 +45,7 @@ class Migrator {
44
45
  driver = 'sqlite3'
45
46
  }
46
47
 
47
- const database = driver !== 'sqlite3'
48
- ? new URL(this.coreConfig.connectionString).pathname.replace(/^\//, '')
49
- : ''
48
+ const database = driver !== 'sqlite3' ? new URL(this.coreConfig.connectionString).pathname.replace(/^\//, '') : ''
50
49
 
51
50
  this.db = db
52
51
 
@@ -59,40 +58,31 @@ class Migrator {
59
58
  driver,
60
59
  database,
61
60
  schemaTable: this.migrationsTable || 'versions',
62
- execQuery: async (query) => {
61
+ execQuery: async query => {
63
62
  const res = await db.query(sql`${sql.__dangerous__rawValue(query)}`)
64
63
  return { rows: res }
65
64
  },
66
65
  validateChecksums: this.validateChecksums,
67
66
  newline: this.newline,
68
- currentSchema: ['pg', 'mysql'].includes(driver) ? this.currentSchema : undefined,
67
+ currentSchema: ['pg', 'mysql'].includes(driver) ? this.currentSchema : undefined
69
68
  })
70
69
 
71
70
  if (this.validateChecksums === true) {
72
- this.postgrator.on(
73
- 'validation-started',
74
- (migration) => {
75
- /* c8 ignore next 3 */
76
- const migrationName = basename(migration.filename)
77
- this.logger.info(`verifying checksum of migration ${migrationName}`)
78
- }
79
- )
80
- }
81
- this.postgrator.on(
82
- 'migration-started',
83
- (migration) => {
84
- const migrationName = basename(migration.filename)
85
- this.logger.info(`running ${migrationName}`)
86
- }
87
- )
88
- this.postgrator.on(
89
- 'migration-finished',
90
- (migration) => {
91
- this.appliedMigrationsCount++
71
+ this.postgrator.on('validation-started', migration => {
72
+ /* c8 ignore next 3 */
92
73
  const migrationName = basename(migration.filename)
93
- this.logger.debug(`completed ${migrationName}`)
94
- }
95
- )
74
+ this.logger.info(`verifying checksum of migration ${migrationName}`)
75
+ })
76
+ }
77
+ this.postgrator.on('migration-started', migration => {
78
+ const migrationName = basename(migration.filename)
79
+ this.logger.info(`running ${migrationName}`)
80
+ })
81
+ this.postgrator.on('migration-finished', migration => {
82
+ this.appliedMigrationsCount++
83
+ const migrationName = basename(migration.filename)
84
+ this.logger.debug(`completed ${migrationName}`)
85
+ })
96
86
  }
97
87
 
98
88
  async checkMigrationsDirectoryExists () {
@@ -100,7 +90,7 @@ class Migrator {
100
90
  await stat(this.migrationDir)
101
91
  } catch (err) {
102
92
  if (err.code === 'ENOENT') {
103
- throw new errors.MigrateMissingMigrationsDirError(this.migrationDir)
93
+ throw new MigrateMissingMigrationsDirError(this.migrationDir)
104
94
  }
105
95
  }
106
96
  }
@@ -178,7 +168,7 @@ class Migrator {
178
168
  }
179
169
  } catch (err) {
180
170
  if (err.code === 'ENOENT') {
181
- throw new errors.MigrateMissingMigrationsDirError(this.migrationDir)
171
+ throw new MigrateMissingMigrationsDirError(this.migrationDir)
182
172
  }
183
173
  }
184
174
  }
@@ -192,4 +182,22 @@ class Migrator {
192
182
  }
193
183
  }
194
184
 
195
- export { Migrator }
185
+ export async function execute (logger, config, to, rollback) {
186
+ const migrationsConfig = config.migrations
187
+ if (migrationsConfig === undefined) {
188
+ throw new MigrateMissingMigrationsError()
189
+ }
190
+
191
+ const migrator = new Migrator(migrationsConfig, config.db, logger)
192
+
193
+ try {
194
+ if (rollback) {
195
+ await migrator.rollbackMigration()
196
+ } else {
197
+ await migrator.applyMigrations(to)
198
+ }
199
+ return migrator.appliedMigrationsCount > 0
200
+ } finally {
201
+ await migrator.close()
202
+ }
203
+ }
@@ -1,11 +1,10 @@
1
- 'use strict'
2
- const path = require('path')
3
- const fastifyStatic = require('@fastify/static')
4
- const userAgentParser = require('my-ua-parser')
1
+ import fastifyStatic from '@fastify/static'
2
+ import userAgentParser from 'my-ua-parser'
3
+ import path from 'node:path'
5
4
 
6
- module.exports = async (app, opts) => {
5
+ export async function root (app) {
7
6
  app.register(fastifyStatic, {
8
- root: path.join(__dirname, 'public'),
7
+ root: path.join(import.meta.dirname, '../public')
9
8
  })
10
9
  // root endpoint
11
10
  app.route({
@@ -21,6 +20,6 @@ module.exports = async (app, opts) => {
21
20
  }
22
21
  }
23
22
  return { message: 'Welcome to Platformatic! Please visit https://docs.platformatic.dev' }
24
- },
23
+ }
25
24
  })
26
25
  }
package/lib/schema.js CHANGED
@@ -1,12 +1,16 @@
1
1
  #! /usr/bin/env node
2
- 'use strict'
3
2
 
4
- const { metrics, server, plugins, watch, openApiDefs, openApiBase, clients } = require('@platformatic/service').schemas
5
- const { schemaComponents } = require('@platformatic/utils')
6
- const telemetry = require('@platformatic/telemetry').schema
7
- const pkg = require('../package.json')
3
+ import { schemaComponents as serviceSchemaComponents } from '@platformatic/service'
4
+ import { fastifyServer as server, schemaComponents as utilsSchemaComponents, watch, wrappedRuntime } from '@platformatic/utils'
5
+ import { readFileSync } from 'node:fs'
6
+ import { resolve } from 'node:path'
8
7
 
9
- const db = {
8
+ export const packageJson = JSON.parse(readFileSync(resolve(import.meta.dirname, '../package.json'), 'utf8'))
9
+ export const version = packageJson.version
10
+
11
+ const { plugins, openApiBase, clients, $defs } = serviceSchemaComponents
12
+
13
+ export const db = {
10
14
  type: 'object',
11
15
  properties: {
12
16
  connectionString: {
@@ -235,7 +239,7 @@ const db = {
235
239
  required: ['connectionString']
236
240
  }
237
241
 
238
- const sharedAuthorizationRule = {
242
+ export const sharedAuthorizationRule = {
239
243
  role: {
240
244
  type: 'string',
241
245
  description: 'the role name to match the rule'
@@ -261,7 +265,7 @@ const sharedAuthorizationRule = {
261
265
  }
262
266
  }
263
267
 
264
- const authorization = {
268
+ export const authorization = {
265
269
  type: 'object',
266
270
  properties: {
267
271
  adminSecret: {
@@ -367,7 +371,7 @@ const authorization = {
367
371
  additionalProperties: false
368
372
  }
369
373
 
370
- const migrations = {
374
+ export const migrations = {
371
375
  type: 'object',
372
376
  properties: {
373
377
  dir: {
@@ -410,7 +414,7 @@ const migrations = {
410
414
  required: ['dir']
411
415
  }
412
416
 
413
- const types = {
417
+ export const types = {
414
418
  type: 'object',
415
419
  properties: {
416
420
  autogenerate: {
@@ -433,10 +437,18 @@ const types = {
433
437
  additionalProperties: false
434
438
  }
435
439
 
436
- const platformaticDBschema = {
437
- $id: `https://schemas.platformatic.dev/@platformatic/db/${pkg.version}.json`,
440
+ export const schemaComponents = {
441
+ db,
442
+ sharedAuthorizationRule,
443
+ authorization,
444
+ migrations,
445
+ types
446
+ }
447
+
448
+ export const schema = {
449
+ $id: `https://schemas.platformatic.dev/@platformatic/db/${packageJson.version}.json`,
438
450
  $schema: 'http://json-schema.org/draft-07/schema#',
439
- title: 'Platformatic DB',
451
+ title: 'Platformatic Database Config',
440
452
  type: 'object',
441
453
  properties: {
442
454
  basePath: {
@@ -455,12 +467,11 @@ const platformaticDBschema = {
455
467
  db,
456
468
  authorization,
457
469
  migrations,
458
- metrics,
459
470
  types,
460
471
  plugins,
461
- telemetry,
472
+ telemetry: utilsSchemaComponents.telemetry,
462
473
  clients,
463
- runtime: schemaComponents.wrappedRuntime,
474
+ runtime: wrappedRuntime,
464
475
  watch: {
465
476
  anyOf: [
466
477
  watch,
@@ -482,7 +493,7 @@ const platformaticDBschema = {
482
493
  additionalProperties: false,
483
494
  required: ['db'],
484
495
  $defs: {
485
- ...openApiDefs,
496
+ ...$defs,
486
497
  'crud-operation-auth': {
487
498
  oneOf: [
488
499
  {
@@ -534,8 +545,7 @@ const platformaticDBschema = {
534
545
  }
535
546
  }
536
547
 
537
- module.exports.schema = platformaticDBschema
538
-
539
- if (require.main === module) {
540
- console.log(JSON.stringify(platformaticDBschema, null, 2))
548
+ /* c8 ignore next 3 */
549
+ if (process.argv[1] === import.meta.filename) {
550
+ console.log(JSON.stringify(schema, null, 2))
541
551
  }