velocious 1.0.2 → 1.0.4

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 (79) hide show
  1. package/.github/dependabot.yml +1 -1
  2. package/README.md +19 -3
  3. package/bin/velocious.mjs +4 -4
  4. package/index.mjs +5 -3
  5. package/package.json +5 -3
  6. package/peak_flow.yml +5 -2
  7. package/spec/cli/commands/db/create-spec.mjs +25 -0
  8. package/spec/cli/commands/db/migrate-spec.mjs +37 -0
  9. package/spec/cli/commands/destroy/migration-spec.mjs +15 -0
  10. package/spec/cli/commands/generate/migration-spec.mjs +18 -0
  11. package/spec/cli/commands/init-spec.mjs +19 -0
  12. package/spec/cli/commands/test/test-files-finder-spec.mjs +12 -0
  13. package/spec/database/drivers/mysql/connection-spec.mjs +2 -2
  14. package/spec/dummy/dummy-directory.mjs +11 -0
  15. package/spec/dummy/index.mjs +22 -26
  16. package/spec/dummy/src/config/configuration.example.mjs +21 -0
  17. package/spec/dummy/src/config/configuration.peakflow.mjs +22 -0
  18. package/spec/dummy/src/database/migrations/20230728075328-create-projects.mjs +11 -0
  19. package/spec/dummy/src/database/migrations/20230728075329-create-tasks.mjs +13 -0
  20. package/spec/http-server/client-spec.mjs +7 -12
  21. package/src/application.mjs +10 -11
  22. package/src/cli/base-command.mjs +11 -0
  23. package/src/cli/commands/db/create.mjs +44 -8
  24. package/src/cli/commands/db/migrate.mjs +105 -0
  25. package/src/cli/commands/destroy/migration.mjs +35 -0
  26. package/src/cli/commands/generate/migration.mjs +31 -7
  27. package/src/cli/commands/generate/model.mjs +36 -0
  28. package/src/cli/commands/init.mjs +60 -0
  29. package/src/cli/commands/server.mjs +15 -0
  30. package/src/cli/commands/test/index.mjs +14 -0
  31. package/src/cli/commands/test/test-files-finder.mjs +99 -0
  32. package/src/cli/commands/test/test-runner.mjs +19 -0
  33. package/src/cli/index.mjs +37 -16
  34. package/src/configuration-resolver.mjs +26 -0
  35. package/src/configuration.mjs +51 -13
  36. package/src/controller.mjs +1 -1
  37. package/src/database/drivers/base.mjs +8 -0
  38. package/src/database/drivers/mysql/index.mjs +25 -0
  39. package/src/database/drivers/mysql/sql/create-database.mjs +4 -0
  40. package/src/database/drivers/mysql/sql/create-table.mjs +4 -0
  41. package/src/database/drivers/sqlite/index.native.mjs +92 -0
  42. package/src/database/drivers/sqlite/index.web.mjs +64 -0
  43. package/src/database/drivers/sqlite/options.mjs +17 -0
  44. package/src/database/drivers/sqlite/query-parser.mjs +25 -0
  45. package/src/database/drivers/sqlite/query.native.mjs +9 -0
  46. package/src/database/drivers/sqlite/query.web.mjs +9 -0
  47. package/src/database/drivers/sqlite/sql/create-table.mjs +4 -0
  48. package/src/database/drivers/sqlite/sql/delete.mjs +19 -0
  49. package/src/database/drivers/sqlite/sql/insert.mjs +29 -0
  50. package/src/database/drivers/sqlite/sql/update.mjs +31 -0
  51. package/src/database/handler.mjs +0 -4
  52. package/src/database/migrate-from-require-context.mjs +53 -0
  53. package/src/database/migration/index.mjs +15 -2
  54. package/src/database/pool/async-tracked-multi-connection.mjs +81 -0
  55. package/src/database/pool/base.mjs +47 -0
  56. package/src/database/pool/single-multi-use.mjs +40 -0
  57. package/src/database/query/base.mjs +11 -0
  58. package/src/database/query/create-database-base.mjs +22 -0
  59. package/src/database/query/create-table-base.mjs +69 -0
  60. package/src/database/query/delete-base.mjs +4 -10
  61. package/src/database/query/from-plain.mjs +3 -5
  62. package/src/database/query/from-table.mjs +2 -2
  63. package/src/database/record/index.mjs +2 -2
  64. package/src/database/table-data/index.mjs +83 -0
  65. package/src/http-server/worker-handler/index.mjs +2 -1
  66. package/src/http-server/worker-handler/worker-thread.mjs +17 -9
  67. package/src/routes/app-routes.mjs +10 -0
  68. package/src/routes/resolver.mjs +4 -2
  69. package/src/spec/index.mjs +5 -0
  70. package/src/templates/configuration.mjs +19 -0
  71. package/src/templates/generate-migration.mjs +11 -0
  72. package/src/templates/generate-model.mjs +4 -0
  73. package/src/templates/routes.mjs +11 -0
  74. package/src/utils/file-exists.mjs +13 -0
  75. package/spec/cli/generate/migration-spec.mjs +0 -9
  76. package/spec/dummy/src/config/database.example.mjs +0 -15
  77. package/spec/dummy/src/config/database.peakflow.mjs +0 -15
  78. package/spec/dummy/src/database/migrations/001-create-tasks.mjs +0 -12
  79. package/src/database/pool/index.mjs +0 -43
@@ -1,15 +1,9 @@
1
- export default class VelociousDatabaseQueryDeleteBase {
1
+ import QueryBase from "./base.mjs"
2
+
3
+ export default class VelociousDatabaseQueryDeleteBase extends QueryBase {
2
4
  constructor({conditions, driver, tableName}) {
5
+ super({driver})
3
6
  this.conditions = conditions
4
- this.driver = driver
5
7
  this.tableName = tableName
6
8
  }
7
-
8
- getOptions() {
9
- return this.driver.options()
10
- }
11
-
12
- toSql() {
13
- throw new Error("'toSql' wasn't implemented")
14
- }
15
9
  }
@@ -1,12 +1,10 @@
1
1
  import FromBase from "./from-base.mjs"
2
2
 
3
3
  export default class VelociousDatabaseQueryFromPlain extends FromBase {
4
- constructor({plain}) {
5
- super()
4
+ constructor({driver, plain}) {
5
+ super({driver})
6
6
  this.plain = plain
7
7
  }
8
8
 
9
- toSql() {
10
- return this.plain
11
- }
9
+ toSql = () => this.plain
12
10
  }
@@ -1,8 +1,8 @@
1
1
  import FromBase from "./from-base.mjs"
2
2
 
3
3
  export default class VelociousDatabaseQueryFromTable extends FromBase {
4
- constructor({tableName}) {
5
- super()
4
+ constructor({driver, tableName}) {
5
+ super({driver})
6
6
  this.tableName = tableName
7
7
  }
8
8
 
@@ -1,4 +1,4 @@
1
- import DatabasePool from "../pool/index.mjs"
1
+ import Configuration from "../../configuration.mjs"
2
2
  import Handler from "../handler.mjs"
3
3
  import inflection from "inflection"
4
4
  import Query from "../query/index.mjs"
@@ -6,7 +6,7 @@ import RecordNotFoundError from "./record-not-found-error.mjs"
6
6
 
7
7
  export default class VelociousDatabaseRecord {
8
8
  static connection() {
9
- const connection = DatabasePool.current().singleConnection()
9
+ const connection = Configuration.current().getDatabasePoolType().current().getCurrentConnection()
10
10
 
11
11
  if (!connection) throw new Error("No connection?")
12
12
 
@@ -0,0 +1,83 @@
1
+ class TableColumn {
2
+ constructor(name, args) {
3
+ this.args = args
4
+ this.name = name
5
+ }
6
+ }
7
+
8
+ class TableIndex {
9
+ constructor(columns, args) {
10
+ this.args = args
11
+ this.columns = columns
12
+ }
13
+
14
+ getColumns = () => this.columns
15
+ getName = () => this.args.name
16
+ getUnique = () => Boolean(this.args.unique)
17
+ }
18
+
19
+ class TableReference {
20
+ constructor(name, args) {
21
+ this.args = args
22
+ this.name = name
23
+ }
24
+ }
25
+
26
+ export default class TableData {
27
+ _columns = []
28
+ _indexes = []
29
+ _references = []
30
+
31
+ constructor(name, args = {}) {
32
+ this.args = args
33
+ this._name = name
34
+ }
35
+
36
+ getColumns = () => this._columns
37
+ getName = () => this._name
38
+ getIfNotExists = () => this.args.ifNotExists
39
+ getIndexes = () => this._indexes
40
+ getReferences = () => this._references
41
+
42
+ bigint(name, args = {}) {
43
+ const columnArgs = Object.assign({type: "bigint"}, args)
44
+ const column = new TableColumn(name, columnArgs)
45
+
46
+ this._columns.push(column)
47
+ }
48
+
49
+ references(name, args = {}) {
50
+ const columnName = `${name}_id`
51
+ const indexName = `index_on_${columnName}`
52
+ const reference = new TableReference(name, args)
53
+ const columnArgs = Object.assign({type: "bigint"}, args)
54
+ const column = new TableColumn(columnName, columnArgs)
55
+ const index = new TableIndex([column], {name: indexName})
56
+
57
+ this._columns.push(column)
58
+ this._indexes.push(index)
59
+ this._references.push(reference)
60
+ }
61
+
62
+ string(name, args) {
63
+ const columnArgs = Object.assign({type: "string"}, args)
64
+ const column = new TableColumn(name, columnArgs)
65
+
66
+ this._columns.push(column)
67
+ }
68
+
69
+ text(name, args) {
70
+ const columnArgs = Object.assign({type: "text"}, args)
71
+ const column = new TableColumn(name, columnArgs)
72
+
73
+ this._columns.push(column)
74
+ }
75
+
76
+ timestamps() {
77
+ const createdAtColumn = new TableColumn("created_at", {type: "datetime"})
78
+ const updatedAtColumn = new TableColumn("updated_at", {type: "datetime"})
79
+
80
+ this._columns.push(createdAtColumn)
81
+ this._columns.push(updatedAtColumn)
82
+ }
83
+ }
@@ -13,7 +13,8 @@ export default class VelociousHttpServerWorker {
13
13
 
14
14
  async start() {
15
15
  return new Promise((resolve) => {
16
- const {debug, directory} = digs(this.configuration, "debug", "directory")
16
+ const {debug} = digs(this.configuration, "debug")
17
+ const directory = this.configuration.getDirectory()
17
18
  const __filename = fileURLToPath(import.meta.url)
18
19
  const __dirname = dirname(__filename)
19
20
 
@@ -1,32 +1,40 @@
1
1
  import Application from "../../application.mjs"
2
2
  import Client from "../client/index.mjs"
3
- import DatabasePool from "../../database/pool/index.mjs"
4
3
  import {digg, digs} from "diggerize"
5
4
  import errorLogger from "../../error-logger.mjs"
6
5
  import logger from "../../logger.mjs"
7
6
 
8
7
  export default class VelociousHttpServerWorkerHandlerWorkerThread {
9
8
  constructor({parentPort, workerData}) {
10
- const {debug, directory, workerCount} = digs(workerData, "debug", "directory", "workerCount")
9
+ const {workerCount} = digs(workerData, "workerCount")
11
10
 
12
- this.application = new Application({debug, directory})
13
- this.databasePool = DatabasePool.current()
14
11
  this.clients = {}
15
- this.configuration = this.application.configuration
16
12
  this.parentPort = parentPort
13
+ this.workerData = workerData
17
14
  this.workerCount = workerCount
18
15
 
19
16
  parentPort.on("message", errorLogger(this.onCommand))
20
17
 
21
- logger(this, `Worker ${workerCount} started`)
22
-
23
- this.application.initialize().then(() => {
24
- this.databasePool.connect().then(() => {
18
+ this.initialize().then(() => {
19
+ this.application.initialize().then(() => {
20
+ logger(this, `Worker ${workerCount} started`)
25
21
  parentPort.postMessage({command: "started"})
26
22
  })
27
23
  })
28
24
  }
29
25
 
26
+ async initialize() {
27
+ const {debug, directory} = digs(this.workerData, "debug", "directory")
28
+ const configurationPath = `${this.workerData.directory}/src/config/configuration.mjs`
29
+ const configurationImport = await import(configurationPath)
30
+ const configuration = configurationImport.default
31
+
32
+ this.application = new Application({configuration, debug, directory})
33
+
34
+ this.configuration = configuration
35
+ this.configuration.setCurrent()
36
+ }
37
+
30
38
  onCommand = (data) => {
31
39
  logger(this, `Worker ${this.workerCount} received command`, data)
32
40
 
@@ -0,0 +1,10 @@
1
+ import {digg} from "diggerize"
2
+
3
+ export default class VelociousRoutesAppRoutes {
4
+ static async getRoutes(configuration) {
5
+ // Every client need to make their own routes because they probably can't be shared across different worker threads
6
+ const routesImport = await import(`${configuration.getDirectory()}/src/config/routes.mjs`)
7
+
8
+ return digg(routesImport, "default", "routes")
9
+ }
10
+ }
@@ -21,7 +21,7 @@ export default class VelociousRoutesResolver {
21
21
  if (!matchResult) throw new Error(`Couldn't match a route with the given path: ${currentPath}`)
22
22
 
23
23
  if (this.params.action && this.params.controller) {
24
- const controllerPath = `${digg(this, "configuration", "directory")}/src/routes/${digg(this, "params", "controller")}/controller.mjs`
24
+ const controllerPath = `${this.configuration.getDirectory()}/src/routes/${digg(this, "params", "controller")}/controller.mjs`
25
25
  const controllerClassImport = await import(controllerPath)
26
26
  const controllerClass = controllerClassImport.default
27
27
  const controllerInstance = new controllerClass({
@@ -35,7 +35,9 @@ export default class VelociousRoutesResolver {
35
35
  throw new Error(`Missing action on controller: ${this.params.controller}#${this.params.action}`)
36
36
  }
37
37
 
38
- await controllerInstance[this.params.action]()
38
+ await this.configuration.getDatabasePool().withConnection(async () => {
39
+ await controllerInstance[this.params.action]()
40
+ })
39
41
 
40
42
  return
41
43
  }
@@ -0,0 +1,5 @@
1
+ export default class VelocuiousSpec {
2
+ static describe(description) {
3
+ throw new Error("stub", description)
4
+ }
5
+ }
@@ -0,0 +1,19 @@
1
+ import AsyncTrackedMultiConnection from "velocious/src/database/pool/async-tracked-multi-connection.mjs"
2
+ import Configuration from "velocious/src/configuration.mjs"
3
+ import MysqlDriver from "velocious/src/database/drivers/mysql/index.mjs"
4
+
5
+ export default new Configuration({
6
+ database: {
7
+ default: {
8
+ master: {
9
+ driver: MysqlDriver,
10
+ poolType: AsyncTrackedMultiConnection,
11
+ type: "mysql",
12
+ host: "mariadb",
13
+ username: "username",
14
+ password: "password",
15
+ database: "database"
16
+ }
17
+ }
18
+ }
19
+ })
@@ -0,0 +1,11 @@
1
+ import Migration from "velocious/src/database/migration/index.mjs"
2
+
3
+ export default class __MIGRATION_NAME__ extends Migration {
4
+ async up() {
5
+ await this.connection().execute("...")
6
+ }
7
+
8
+ async down() {
9
+ await this.connection().execute("...")
10
+ }
11
+ }
@@ -0,0 +1,4 @@
1
+ import Record from "velocious/src/database/record/index.mjs"
2
+
3
+ export default class __MODEL_NAME__ extends Record {
4
+ }
@@ -0,0 +1,11 @@
1
+ import Routes from "velocious/src/routes/index.mjs"
2
+
3
+ const routes = new Routes()
4
+
5
+ routes.draw((route) => {
6
+ route.resources("tasks", (route) => {
7
+ route.get("users")
8
+ })
9
+ })
10
+
11
+ export default {routes}
@@ -0,0 +1,13 @@
1
+ import fs from "node:fs/promises"
2
+
3
+ const fileExists = async (path) => {
4
+ try {
5
+ await fs.access(path)
6
+
7
+ return true
8
+ } catch (error) {
9
+ return false
10
+ }
11
+ }
12
+
13
+ export default fileExists
@@ -1,9 +0,0 @@
1
- import Cli from "../../../src/cli/index.mjs"
2
-
3
- describe("Cli - generate - migration", () => {
4
- it("generates a new migration", async () => {
5
- const cli = new Cli()
6
-
7
- await cli.execute({args: ["g:migration", "create_tasks"]})
8
- })
9
- })
@@ -1,15 +0,0 @@
1
- const databaseConfiguration = () => {
2
- return {
3
- "default": {
4
- "master": {
5
- "type": "mysql",
6
- "host": "mariadb",
7
- "username": "username",
8
- "password": "password",
9
- "database": "velocious_test"
10
- }
11
- }
12
- }
13
- }
14
-
15
- export {databaseConfiguration}
@@ -1,15 +0,0 @@
1
- const databaseConfiguration = () => {
2
- return {
3
- "default": {
4
- "master": {
5
- "type": "mysql",
6
- "host": "mariadb",
7
- "username": "peakflow",
8
- "password": "password",
9
- "database": "velocious_test"
10
- }
11
- }
12
- }
13
- }
14
-
15
- export {databaseConfiguration}
@@ -1,12 +0,0 @@
1
- import {Database} from "../../../../index.mjs"
2
-
3
- export default class CreateTasks extends Database.Migration {
4
- change() {
5
- this.createTable("tasks", (table) => {
6
- table.bigint("id", {autoIncrement: true, primaryKey: true})
7
- table.string("name")
8
- table.text("description")
9
- table.timestamps()
10
- })
11
- }
12
- }
@@ -1,43 +0,0 @@
1
- import Configuration from "../../configuration.mjs"
2
- import {digg} from "diggerize"
3
-
4
- export default class VelociousDatabasePool {
5
- static current() {
6
- if (!global.velociousDatabasePool) global.velociousDatabasePool = new VelociousDatabasePool()
7
-
8
- return global.velociousDatabasePool
9
- }
10
-
11
- async connect() {
12
- if (this.connection) {
13
- console.warn("DatabasePoool#connect: Already connected")
14
- } else {
15
- this.connection = await this.spawnConnection()
16
-
17
- if (!this.connection) throw new Error("spawnConnection didn't set a connection")
18
-
19
- await this.connection.connect()
20
- }
21
- }
22
-
23
- isConnected = () => Boolean(this.connection)
24
-
25
- singleConnection() {
26
- if (!this.connection) throw new Error("Not connected")
27
-
28
- return this.connection
29
- }
30
-
31
- async spawnConnection() {
32
- const databaseConfigPath = `${Configuration.current().directory}/src/config/database.mjs`
33
- const {databaseConfiguration} = await import(databaseConfigPath)
34
- const config = databaseConfiguration()
35
- const defaultConfig = digg(config, "default", "master")
36
- const driverPath = `../drivers/${digg(defaultConfig, "type")}/index.mjs`
37
- const DriverClassImport = await import(driverPath)
38
- const DriverClass = DriverClassImport.default
39
- const connection = new DriverClass(defaultConfig)
40
-
41
- return connection
42
- }
43
- }