@platformatic/db 2.74.3 → 3.0.0-alpha.2

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 (60) hide show
  1. package/config.d.ts +2 -30
  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 +72 -0
  11. package/lib/commands/types.js +21 -0
  12. package/lib/errors.js +15 -11
  13. package/lib/generator.js +229 -0
  14. package/lib/{migrator.mjs → migrator.js} +44 -37
  15. package/lib/{root-endpoint/index.js → root.js} +6 -7
  16. package/lib/schema.js +38 -22
  17. package/lib/stackable.js +14 -26
  18. package/lib/{generator/code-templates.js → templates.js} +57 -16
  19. package/lib/types.js +160 -0
  20. package/lib/upgrade.js +8 -12
  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/lib/versions/3.0.0.js +14 -0
  26. package/package.json +20 -28
  27. package/schema.json +9 -154
  28. package/tsconfig.json +16 -6
  29. package/.snapshots/810d795d512560f3863d8db472c81c27/0.json +0 -1
  30. package/.snapshots/810d795d512560f3863d8db472c81c27/1.json +0 -1
  31. package/db.mjs +0 -86
  32. package/help/compile.txt +0 -17
  33. package/help/create.txt +0 -13
  34. package/help/help.txt +0 -11
  35. package/help/migrations apply.txt +0 -45
  36. package/help/migrations create.txt +0 -27
  37. package/help/migrations.txt +0 -4
  38. package/help/schema.txt +0 -25
  39. package/help/seed.txt +0 -36
  40. package/help/start.txt +0 -47
  41. package/help/types.txt +0 -40
  42. package/index.test-d.ts +0 -43
  43. package/lib/adjust-config.js +0 -42
  44. package/lib/create.mjs +0 -89
  45. package/lib/gen-migration.mjs +0 -53
  46. package/lib/gen-schema.mjs +0 -68
  47. package/lib/gen-types.mjs +0 -202
  48. package/lib/generator/README.md +0 -38
  49. package/lib/generator/db-generator.js +0 -262
  50. package/lib/generator.d.ts +0 -7
  51. package/lib/migrate.mjs +0 -87
  52. package/lib/seed.mjs +0 -90
  53. /package/{lib/root-endpoint/public → public}/images/dark_mode.svg +0 -0
  54. /package/{lib/root-endpoint/public → public}/images/favicon.ico +0 -0
  55. /package/{lib/root-endpoint/public → public}/images/light_mode.svg +0 -0
  56. /package/{lib/root-endpoint/public → public}/images/platformatic-logo-dark.svg +0 -0
  57. /package/{lib/root-endpoint/public → public}/images/platformatic-logo-light.svg +0 -0
  58. /package/{lib/root-endpoint/public → public}/images/triangle_dark.svg +0 -0
  59. /package/{lib/root-endpoint/public → public}/images/triangle_light.svg +0 -0
  60. /package/{lib/root-endpoint/public → public}/index.html +0 -0
@@ -1,262 +0,0 @@
1
- 'use strict'
2
-
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 {
9
- constructor (opts = {}) {
10
- super({
11
- ...opts,
12
- module: '@platformatic/db',
13
- })
14
- this.connectionStrings = {
15
- postgres: 'postgres://postgres:postgres@127.0.0.1:5432/postgres',
16
- sqlite: 'sqlite://./db.sqlite',
17
- mysql: 'mysql://root@127.0.0.1:3306/platformatic',
18
- mariadb: 'mysql://root@127.0.0.1:3306/platformatic',
19
- }
20
- }
21
-
22
- getDefaultConfig () {
23
- const defaultBaseConfig = super.getDefaultConfig()
24
- return {
25
- ...defaultBaseConfig,
26
- database: 'sqlite',
27
- connectionString: null,
28
- plugin: true,
29
- tests: true,
30
- types: true,
31
- migrations: 'migrations',
32
- createMigrations: true,
33
- }
34
- }
35
-
36
- async _getConfigFileContents () {
37
- const { isRuntimeContext, migrations, plugin, types } = this.config
38
- const version = this.platformaticVersion
39
-
40
- const config = {
41
- $schema: `https://schemas.platformatic.dev/@platformatic/db/${version}.json`,
42
- db: {
43
- connectionString: `{${this.getEnvVarName('DATABASE_URL')}}`,
44
- graphql: true,
45
- openapi: true,
46
- schemalock: true,
47
- },
48
- watch: {
49
- ignore: ['*.sqlite', '*.sqlite-journal'],
50
- },
51
- }
52
-
53
- if (!isRuntimeContext) {
54
- config.server = {
55
- hostname: '{PLT_SERVER_HOSTNAME}',
56
- port: '{PORT}',
57
- logger: {
58
- level: '{PLT_SERVER_LOGGER_LEVEL}',
59
- },
60
- }
61
- }
62
-
63
- if (migrations) {
64
- config.migrations = {
65
- dir: migrations,
66
- autoApply: `{${this.getEnvVarName('PLT_APPLY_MIGRATIONS')}}`,
67
- }
68
-
69
- this.addFile({ path: 'migrations', file: '.gitkeep', contents: '' })
70
- }
71
-
72
- if (plugin === true) {
73
- config.plugins = {
74
- paths: [{
75
- path: './plugins',
76
- encapsulate: false,
77
- }, {
78
- path: './routes',
79
- }],
80
- typescript: `{${this.getEnvVarName('PLT_TYPESCRIPT')}}`,
81
- }
82
- }
83
-
84
- if (types === true) {
85
- config.types = {
86
- autogenerate: true,
87
- }
88
- }
89
-
90
- return config
91
- }
92
-
93
- async _beforePrepare () {
94
- if (!this.config.isUpdating) {
95
- this.config.connectionString = this.config.connectionString || this.connectionStrings[this.config.database]
96
- this.config.dependencies = {
97
- '@platformatic/db': `^${this.platformaticVersion}`,
98
- }
99
-
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 })
106
- }
107
-
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 })
113
- }
114
- }
115
-
116
- async _afterPrepare () {
117
- if (!this.config.isUpdating) {
118
- if (this.config.createMigrations) {
119
- this.createMigrationFiles()
120
- }
121
-
122
- this.addFile({ path: '', file: 'README.md', contents: await readFile(join(__dirname, 'README.md'), 'utf-8') })
123
-
124
- if (this.config.plugin) {
125
- let jsHelper = { pre: '', config: '', post: '' }
126
- switch (this.config.database) {
127
- case 'sqlite':
128
- jsHelper = jsHelperSqlite
129
- break
130
- case 'mysql':
131
- jsHelper = jsHelperMySQL(this.config.connectionString)
132
- break
133
- case 'postgres':
134
- jsHelper = jsHelperPostgres(this.config.connectionString)
135
- break
136
- case 'mariadb':
137
- jsHelper = jsHelperMySQL(this.config.connectionString)
138
- break
139
- }
140
-
141
- if (this.config.createMigrations) {
142
- if (this.config.typescript) {
143
- this.addFile({ path: join('test', 'routes'), file: 'movies.test.ts', contents: moviesTestTS })
144
- } else {
145
- this.addFile({ path: join('test', 'routes'), file: 'movies.test.js', contents: moviesTestJS })
146
- }
147
- }
148
-
149
- // TODO(leorossi): this is unfortunate. We have already generated tests in BaseGenerator
150
- // next line will override the test files
151
- generateTests(this.config.typescript, '@platformatic/db', jsHelper).forEach((fileObject) => {
152
- this.addFile(fileObject)
153
- })
154
-
155
- if (this.config.isRuntimeContext) {
156
- // remove .env file and env variables since they are all for the config.server property
157
- const envFile = this.getFileObject('.env')
158
- if (envFile) {
159
- envFile.contents = ''
160
- }
161
- }
162
- }
163
-
164
- const GLOBAL_TYPES_TEMPLATE = `
165
- import { FastifyInstance } from 'fastify'
166
- import { PlatformaticApp, PlatformaticDBConfig, PlatformaticDBMixin, Entities } from '@platformatic/db'
167
-
168
- declare module 'fastify' {
169
- interface FastifyInstance {
170
- platformatic: PlatformaticApp<PlatformaticDBConfig> & PlatformaticDBMixin<Entities>
171
- }
172
- }
173
- `
174
- this.addFile({ path: '', file: 'global.d.ts', contents: GLOBAL_TYPES_TEMPLATE })
175
- }
176
- }
177
-
178
- createMigrationFiles () {
179
- this.addFile({ path: 'migrations', file: '001.do.sql', contents: this.getMoviesMigrationDo() })
180
- this.addFile({ path: 'migrations', file: '001.undo.sql', contents: this.getMoviesMigrationUndo() })
181
- }
182
-
183
- getMoviesMigrationDo () {
184
- const key = {
185
- postgres: 'SERIAL',
186
- sqlite: 'INTEGER',
187
- mysql: 'INTEGER UNSIGNED AUTO_INCREMENT',
188
- mariadb: 'INTEGER UNSIGNED AUTO_INCREMENT',
189
- }
190
-
191
- return `
192
- -- Add SQL in this file to create the database tables for your API
193
- CREATE TABLE IF NOT EXISTS movies (
194
- id ${key[this.config.database]} PRIMARY KEY,
195
- title TEXT NOT NULL
196
- );
197
- `
198
- }
199
-
200
- getMoviesMigrationUndo () {
201
- return '-- Add SQL in this file to drop the database tables\nDROP TABLE movies;'
202
- }
203
-
204
- setConfigFields (fields) {
205
- super.setConfigFields(fields)
206
- this.config.database = this.getDatabaseFromConnectionString()
207
- }
208
-
209
- getDatabaseFromConnectionString () {
210
- if (this.config.connectionString) {
211
- if (this.config.connectionString.indexOf('://') !== -1) {
212
- const splitted = this.config.connectionString.split('://')
213
- return splitted[0]
214
- }
215
- return null
216
- }
217
- return null
218
- }
219
-
220
- getConfigFieldsDefinitions () {
221
- return [
222
- {
223
- var: 'DATABASE_URL',
224
- label: 'What is the connection string?',
225
- default: this.connectionStrings.sqlite,
226
- type: 'string',
227
- configValue: 'connectionString',
228
- },
229
- {
230
- var: 'PLT_APPLY_MIGRATIONS',
231
- label: 'Should migrations be applied automatically on startup?',
232
- default: true,
233
- type: 'boolean',
234
- },
235
- ]
236
- }
237
-
238
- async prepareQuestions () {
239
- await super.prepareQuestions()
240
- if (!this.config.connectionString) {
241
- const def = this.getConfigFieldsDefinitions().find((q) => q.var === 'DATABASE_URL')
242
- this.questions.push({
243
- type: 'input',
244
- name: def.configValue,
245
- message: def.label,
246
- default: def.default,
247
- })
248
- }
249
-
250
- this.questions.push({
251
- type: 'list',
252
- name: 'createMigrations',
253
- message: 'Do you want to create default migrations?',
254
- default: true,
255
- choices: [{ name: 'yes', value: true }, { name: 'no', value: false }],
256
- })
257
- }
258
- }
259
-
260
- module.exports = DBGenerator
261
- module.exports.DBGenerator = DBGenerator
262
- module.exports.Generator = DBGenerator
@@ -1,7 +0,0 @@
1
- import { BaseGenerator } from '@platformatic/generators'
2
-
3
- type DBGeneratorOptions = BaseGenerator.BaseGeneratorOptions
4
- export class DBGenerator extends BaseGenerator.BaseGenerator {
5
- connectionStrings: string[]
6
- constructor (opts?: DBGeneratorOptions)
7
- }
package/lib/migrate.mjs DELETED
@@ -1,87 +0,0 @@
1
- #! /usr/bin/env node
2
-
3
- import { loadConfig } from '@platformatic/config'
4
- import { checkForDependencies } from '@platformatic/utils'
5
- import { utimesSync } from 'fs'
6
- import { createRequire } from 'node:module'
7
- import pino from 'pino'
8
- import pretty from 'pino-pretty'
9
- import { platformaticDB } from '../index.js'
10
- import errors from './errors.js'
11
- import { execute as generateTypes } from './gen-types.mjs'
12
- import { Migrator } from './migrator.mjs'
13
- import { updateSchemaLock } from './utils.js'
14
-
15
- async function execute ({ logger, rollback, to, config }) {
16
- const migrationsConfig = config.migrations
17
- if (migrationsConfig === undefined) {
18
- throw new errors.MigrateMissingMigrationsError()
19
- }
20
- const migrator = new Migrator(migrationsConfig, config.db, logger)
21
-
22
- try {
23
- if (rollback) {
24
- await migrator.rollbackMigration()
25
- } else {
26
- await migrator.applyMigrations(to)
27
- }
28
- return migrator.appliedMigrationsCount > 0
29
- } finally {
30
- await migrator.close()
31
- }
32
- }
33
-
34
- async function applyMigrations (_args) {
35
- const logger = pino(
36
- pretty({
37
- translateTime: 'SYS:HH:MM:ss',
38
- ignore: 'hostname,pid'
39
- })
40
- )
41
-
42
- try {
43
- const { configManager, args } = await loadConfig(
44
- {
45
- string: ['to'],
46
- boolean: ['rollback'],
47
- alias: {
48
- t: 'to',
49
- r: 'rollback'
50
- }
51
- },
52
- _args,
53
- platformaticDB
54
- )
55
-
56
- const config = configManager.current
57
- const appliedMigrations = await execute({ logger, ...args, config })
58
-
59
- if (config.types && config.types.autogenerate) {
60
- await generateTypes({ logger, config, configManager })
61
- const modules = ['@platformatic/db']
62
- if (config.plugins?.typescript) {
63
- modules.push('typescript')
64
- }
65
- await checkForDependencies(logger, args, createRequire(import.meta.url), config, modules)
66
- }
67
-
68
- if (appliedMigrations) {
69
- await updateSchemaLock(logger, configManager)
70
- }
71
-
72
- // touch the platformatic db config to trigger a restart
73
- const now = new Date()
74
-
75
- const configPath = configManager.fullPath
76
- utimesSync(configPath, now, now)
77
- } catch (err) {
78
- if (err.code === 'PTL_DB_MIGRATE_ERROR') {
79
- logger.error(err.message)
80
- process.exit(1)
81
- }
82
- /* c8 ignore next 2 */
83
- throw err
84
- }
85
- }
86
-
87
- export { applyMigrations, execute }
package/lib/seed.mjs DELETED
@@ -1,90 +0,0 @@
1
- import pino from 'pino'
2
- import pretty from 'pino-pretty'
3
- import { access, readFile } from 'fs/promises'
4
- import { setupDB } from './utils.js'
5
- import { Migrator } from './migrator.mjs'
6
- import { pathToFileURL } from 'url'
7
- import { loadConfig } from '@platformatic/config'
8
- import { platformaticDB } from '../index.js'
9
- import errors from './errors.js'
10
- import tsCompiler from '@platformatic/ts-compiler'
11
- import { join, resolve } from 'node:path'
12
-
13
- async function execute (logger, seedFile, config) {
14
- const { db, sql, entities } = await setupDB(logger, config.db)
15
-
16
- await access(seedFile)
17
-
18
- logger.info(`seeding from ${seedFile}`)
19
- let seedFunction
20
- const importedFunction = await import(pathToFileURL(seedFile))
21
-
22
- if (typeof importedFunction === 'function') {
23
- seedFunction = importedFunction
24
- } else if (typeof importedFunction.seed === 'function') {
25
- seedFunction = importedFunction.seed
26
- } else if (typeof importedFunction.default === 'function') {
27
- seedFunction = importedFunction.default
28
- }
29
-
30
- if (!seedFunction) {
31
- logger.error('Cannot find seed function.')
32
- logger.error('If you use an ESM module use the signature \'export async function seed (opts)\'.')
33
- logger.error('If you use a CJS module use the signature \'module.exports = async function seed (opts)\'.')
34
- logger.error('If you use Typescript use the signature \'export async function seed(opts)\'')
35
- return
36
- }
37
- await seedFunction({ db, sql, entities, logger })
38
- logger.info('seeding complete')
39
-
40
- // Once done seeding, close your connection.
41
- await db.dispose()
42
- }
43
-
44
- async function seed (_args) {
45
- const logger = pino(pretty({
46
- translateTime: 'SYS:HH:MM:ss',
47
- ignore: 'hostname,pid',
48
- }))
49
-
50
- const { configManager, args } = await loadConfig({
51
- alias: {
52
- c: 'config',
53
- },
54
- }, _args, platformaticDB)
55
- await configManager.parseAndValidate()
56
- const config = configManager.current
57
-
58
- if (config.migrations !== undefined) {
59
- const migrator = new Migrator(config.migrations, config.db, logger)
60
-
61
- try {
62
- const hasMigrationsToApply = await migrator.hasMigrationsToApply()
63
- if (hasMigrationsToApply) {
64
- throw new errors.MigrationsToApplyError()
65
- }
66
- } finally {
67
- await migrator.close()
68
- }
69
- }
70
- let seedFile = args._[0]
71
- if (!seedFile) {
72
- throw new errors.MissingSeedFileError()
73
- }
74
- // check if we are in Typescript and, in case, compile it
75
- if (seedFile.endsWith('.ts')) {
76
- await tsCompiler.compile({
77
- cwd: process.cwd(),
78
- logger,
79
- tsConfig: configManager.current.plugins?.typescript?.tsConfig,
80
- flags: configManager.current.plugins?.typescript?.flags,
81
- })
82
- const tsConfigPath = config?.plugins?.typescript?.tsConfig || resolve(process.cwd(), 'tsconfig.json')
83
- const tsConfig = JSON.parse(await readFile(tsConfigPath, 'utf8'))
84
- const outDir = tsConfig.compilerOptions.outDir
85
- seedFile = join(outDir, seedFile.replace('.ts', '.js'))
86
- }
87
- await execute(logger, seedFile, config)
88
- }
89
-
90
- export { seed, execute }
File without changes