velocious 1.0.1 → 1.0.3

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 (157) hide show
  1. package/README.md +36 -0
  2. package/bin/velocious.mjs +8 -0
  3. package/index.mjs +21 -0
  4. package/package.json +15 -7
  5. package/peak_flow.yml +12 -5
  6. package/spec/cli/commands/db/create-spec.mjs +25 -0
  7. package/spec/cli/commands/db/migrate-spec.mjs +37 -0
  8. package/spec/cli/commands/destroy/migration-spec.mjs +15 -0
  9. package/spec/cli/commands/generate/migration-spec.mjs +18 -0
  10. package/spec/cli/commands/init-spec.mjs +19 -0
  11. package/spec/cli/commands/test/test-files-finder-spec.mjs +12 -0
  12. package/spec/database/connection/drivers/mysql/{query-parser-spec.cjs → query-parser-spec.mjs} +12 -8
  13. package/spec/database/drivers/mysql/connection-spec.mjs +21 -0
  14. package/spec/database/record/create-spec.mjs +14 -0
  15. package/spec/database/record/destroy-spec.mjs +17 -0
  16. package/spec/database/record/find-spec.mjs +29 -0
  17. package/spec/database/record/update-spec.mjs +15 -0
  18. package/spec/dummy/dummy-directory.mjs +11 -0
  19. package/spec/dummy/index.mjs +63 -0
  20. package/spec/dummy/src/config/configuration.example.mjs +19 -0
  21. package/spec/dummy/src/config/configuration.peakflow.mjs +20 -0
  22. package/spec/dummy/src/{routes.cjs → config/routes.mjs} +3 -2
  23. package/spec/dummy/src/database/migrations/20230728075328-create-projects.mjs +11 -0
  24. package/spec/dummy/src/database/migrations/20230728075329-create-tasks.mjs +13 -0
  25. package/spec/dummy/src/models/task.mjs +4 -0
  26. package/spec/dummy/src/routes/tasks/controller.mjs +26 -0
  27. package/spec/http-server/{client-spec.cjs → client-spec.mjs} +7 -10
  28. package/spec/http-server/{get-spec.cjs → get-spec.mjs} +2 -2
  29. package/spec/http-server/post-spec.mjs +72 -0
  30. package/spec/support/jasmine.json +4 -3
  31. package/src/application.mjs +50 -0
  32. package/src/cli/base-command.mjs +11 -0
  33. package/src/cli/commands/db/create.mjs +50 -0
  34. package/src/cli/commands/db/migrate.mjs +58 -0
  35. package/src/cli/commands/destroy/migration.mjs +35 -0
  36. package/src/cli/commands/generate/migration.mjs +36 -0
  37. package/src/cli/commands/init.mjs +60 -0
  38. package/src/cli/commands/test/index.mjs +14 -0
  39. package/src/cli/commands/test/test-files-finder.mjs +99 -0
  40. package/src/cli/commands/test/test-runner.mjs +19 -0
  41. package/src/cli/index.mjs +59 -0
  42. package/src/configuration-resolver.mjs +26 -0
  43. package/src/configuration.mjs +49 -0
  44. package/src/{controller.cjs → controller.mjs} +21 -4
  45. package/src/database/drivers/base.mjs +17 -0
  46. package/src/database/drivers/index.mjs +5 -0
  47. package/src/database/drivers/mysql/connect-connection.mjs +12 -0
  48. package/src/database/drivers/mysql/index.mjs +102 -0
  49. package/src/database/drivers/mysql/options.mjs +17 -0
  50. package/src/database/drivers/mysql/query-parser.mjs +25 -0
  51. package/src/database/drivers/mysql/query.mjs +26 -0
  52. package/src/database/drivers/mysql/sql/create-database.mjs +4 -0
  53. package/src/database/drivers/mysql/sql/create-table.mjs +4 -0
  54. package/src/database/drivers/mysql/sql/delete.mjs +19 -0
  55. package/src/database/drivers/mysql/sql/insert.mjs +29 -0
  56. package/src/database/drivers/mysql/sql/update.mjs +31 -0
  57. package/src/database/drivers/sqlite/options.mjs +17 -0
  58. package/src/database/drivers/sqlite/query-parser.mjs +25 -0
  59. package/src/database/drivers/sqlite/sql/create-database.mjs +4 -0
  60. package/src/database/drivers/sqlite/sql/create-table.mjs +4 -0
  61. package/src/database/drivers/sqlite/sql/delete.mjs +19 -0
  62. package/src/database/drivers/sqlite/sql/insert.mjs +29 -0
  63. package/src/database/drivers/sqlite/sql/update.mjs +31 -0
  64. package/src/database/drivers/sqlite-expo/index.mjs +100 -0
  65. package/src/database/drivers/sqlite-expo/query.mjs +9 -0
  66. package/src/database/handler.mjs +7 -0
  67. package/src/database/index.mjs +15 -0
  68. package/src/database/migration/index.mjs +18 -0
  69. package/src/database/migrator/index.mjs +15 -0
  70. package/src/database/pool/index.mjs +112 -0
  71. package/src/database/query/base.mjs +11 -0
  72. package/src/database/query/create-database-base.mjs +20 -0
  73. package/src/database/query/create-table-base.mjs +69 -0
  74. package/src/database/query/delete-base.mjs +9 -0
  75. package/src/database/query/from-base.mjs +9 -0
  76. package/src/database/query/from-plain.mjs +10 -0
  77. package/src/database/query/from-table.mjs +12 -0
  78. package/src/database/query/index.mjs +144 -0
  79. package/src/database/query/insert-base.mjs +15 -0
  80. package/src/database/query/join-base.mjs +9 -0
  81. package/src/database/query/join-plain.mjs +12 -0
  82. package/src/database/query/order-base.mjs +9 -0
  83. package/src/database/query/order-plain.mjs +21 -0
  84. package/src/database/query/select-base.mjs +9 -0
  85. package/src/database/query/select-plain.mjs +12 -0
  86. package/src/database/query/{select-table-and-column.cjs → select-table-and-column.mjs} +4 -4
  87. package/src/database/query/update-base.mjs +16 -0
  88. package/src/database/query-parser/{from-parser.cjs → from-parser.mjs} +3 -6
  89. package/src/database/query-parser/{joins-parser.cjs → joins-parser.mjs} +3 -6
  90. package/src/database/query-parser/{options.cjs → options.mjs} +13 -2
  91. package/src/database/query-parser/{select-parser.cjs → select-parser.mjs} +7 -6
  92. package/src/database/record/index.mjs +187 -0
  93. package/src/database/record/record-not-found-error.mjs +1 -0
  94. package/src/database/table-data/index.mjs +83 -0
  95. package/src/{error-logger.js → error-logger.mjs} +1 -1
  96. package/src/http-server/client/{index.cjs → index.mjs} +10 -11
  97. package/src/http-server/client/params-to-object.mjs +68 -0
  98. package/src/http-server/client/request-buffer/form-data-part.mjs +42 -0
  99. package/src/http-server/client/request-buffer/header.mjs +7 -0
  100. package/src/http-server/client/request-buffer/index.mjs +229 -0
  101. package/src/http-server/client/request-parser.mjs +47 -0
  102. package/src/http-server/client/{request-runner.cjs → request-runner.mjs} +5 -5
  103. package/src/http-server/client/request.mjs +15 -0
  104. package/src/http-server/client/{response.cjs → response.mjs} +1 -1
  105. package/src/http-server/index.mjs +137 -0
  106. package/src/http-server/server-client.mjs +47 -0
  107. package/src/http-server/worker-handler/index.mjs +79 -0
  108. package/src/http-server/worker-handler/worker-script.mjs +4 -0
  109. package/src/http-server/worker-handler/worker-thread.mjs +65 -0
  110. package/src/{logger.cjs → logger.mjs} +2 -2
  111. package/src/routes/base-route.mjs +34 -0
  112. package/src/routes/{get-route.cjs → get-route.mjs} +5 -3
  113. package/src/routes/index.mjs +9 -0
  114. package/src/routes/{resolver.cjs → resolver.mjs} +17 -9
  115. package/src/routes/{resource-route.cjs → resource-route.mjs} +9 -5
  116. package/src/routes/root-route.mjs +6 -0
  117. package/src/spec/index.mjs +5 -0
  118. package/src/templates/configuration.mjs +17 -0
  119. package/src/templates/generate-migration.mjs +11 -0
  120. package/src/templates/routes.mjs +11 -0
  121. package/src/utils/file-exists.mjs +13 -0
  122. package/bin/velocious +0 -14
  123. package/index.cjs +0 -13
  124. package/spec/dummy/config/databases.example.json +0 -10
  125. package/spec/dummy/config/databases.json +0 -0
  126. package/spec/dummy/config/databases.peakflow.json +0 -11
  127. package/spec/dummy/index.cjs +0 -40
  128. package/spec/dummy/src/models/task.cjs +0 -4
  129. package/spec/dummy/src/routes/tasks/controller.cjs +0 -18
  130. package/src/application.cjs +0 -36
  131. package/src/configuration.cjs +0 -14
  132. package/src/database/connection/drivers/mysql/index.cjs +0 -5
  133. package/src/database/connection/drivers/mysql/options.cjs +0 -7
  134. package/src/database/connection/drivers/mysql/query-parser.cjs +0 -26
  135. package/src/database/connection/index.cjs +0 -2
  136. package/src/database/handler.cjs +0 -5
  137. package/src/database/index.cjs +0 -9
  138. package/src/database/pool/index.cjs +0 -2
  139. package/src/database/query/from-base.cjs +0 -15
  140. package/src/database/query/from-plain.cjs +0 -12
  141. package/src/database/query/from-table.cjs +0 -12
  142. package/src/database/query/index.cjs +0 -59
  143. package/src/database/query/join-base.cjs +0 -15
  144. package/src/database/query/join-plain.cjs +0 -12
  145. package/src/database/query/select-base.cjs +0 -15
  146. package/src/database/query/select-plain.cjs +0 -12
  147. package/src/database/record/index.cjs +0 -5
  148. package/src/http-server/client/request-parser.cjs +0 -92
  149. package/src/http-server/client/request.cjs +0 -25
  150. package/src/http-server/index.cjs +0 -78
  151. package/src/http-server/worker-handler/index.cjs +0 -78
  152. package/src/http-server/worker-handler/socket-handler.cjs +0 -35
  153. package/src/http-server/worker-handler/worker-script.cjs +0 -4
  154. package/src/http-server/worker-handler/worker-thread.cjs +0 -49
  155. package/src/routes/base-route.cjs +0 -25
  156. package/src/routes/index.cjs +0 -9
  157. package/src/routes/root-route.cjs +0 -4
@@ -0,0 +1,47 @@
1
+ import {digg} from "diggerize"
2
+ import {EventEmitter} from "events"
3
+ import Incorporator from "incorporator"
4
+ import ParamsToObject from "./params-to-object.mjs"
5
+ import RequestBuffer from "./request-buffer/index.mjs"
6
+
7
+ export default class VelociousHttpServerClientRequestParser {
8
+ constructor({configuration}) {
9
+ if (!configuration) throw new Error("No configuration given")
10
+
11
+ this.configuration = configuration
12
+ this.data = []
13
+ this.events = new EventEmitter()
14
+ this.params = {}
15
+
16
+ this.requestBuffer = new RequestBuffer({configuration})
17
+ this.requestBuffer.events.on("completed", this.requestDone)
18
+ this.requestBuffer.events.on("form-data-part", this.onFormDataPart)
19
+ this.requestBuffer.events.on("request-done", this.requestDone)
20
+ }
21
+
22
+ onFormDataPart = (formDataPart) => {
23
+ const unorderedParams = {}
24
+
25
+ unorderedParams[formDataPart.getName()] = formDataPart.getValue()
26
+
27
+ const paramsToObject = new ParamsToObject(unorderedParams)
28
+ const newParams = paramsToObject.toObject()
29
+ const incorporator = new Incorporator({objects: [this.params, newParams]})
30
+
31
+ incorporator.merge()
32
+ }
33
+
34
+ feed = (data) => this.requestBuffer.feed(data)
35
+ getHeader = (name) => this.requestBuffer.getHeader(name)?.value
36
+ getHttpMethod = () => digg(this, "requestBuffer", "httpMethod")
37
+ getHost = () => this.requestBuffer.getHeader("host")?.value
38
+ getPath = () => digg(this, "requestBuffer", "path")
39
+
40
+ requestDone = () => {
41
+ const incorporator = new Incorporator({objects: [this.params, this.requestBuffer.params]})
42
+
43
+ incorporator.merge()
44
+ this.state = "done"
45
+ this.events.emit("done")
46
+ }
47
+ }
@@ -1,9 +1,9 @@
1
- const EventEmitter = require("events")
2
- const logger = require("../../logger.cjs")
3
- const Response = require("./response.cjs")
4
- const RoutesResolver = require("../../routes/resolver.cjs")
1
+ import EventEmitter from "events"
2
+ import logger from "../../logger.mjs"
3
+ import Response from "./response.mjs"
4
+ import RoutesResolver from "../../routes/resolver.mjs"
5
5
 
6
- module.exports = class VelociousHttpServerClientRequestRunner {
6
+ export default class VelociousHttpServerClientRequestRunner {
7
7
  events = new EventEmitter()
8
8
 
9
9
  constructor({configuration, request}) {
@@ -0,0 +1,15 @@
1
+ import {digg} from "diggerize"
2
+ import RequestParser from "./request-parser.mjs"
3
+
4
+ export default class VelociousHttpServerClientRequest {
5
+ constructor({configuration}) {
6
+ this.configuration = configuration
7
+ this.requestParser = new RequestParser({configuration})
8
+ }
9
+
10
+ feed = (data) => this.requestParser.feed(data)
11
+ httpMethod = () => this.requestParser.getHttpMethod()
12
+ host = () => this.requestParser.getHost()
13
+ path = () => this.requestParser.getPath()
14
+ params = () => digg(this, "requestParser", "params")
15
+ }
@@ -1,4 +1,4 @@
1
- module.exports = class VelociousHttpServerClientResponse {
1
+ export default class VelociousHttpServerClientResponse {
2
2
  body = undefined
3
3
  headers = {}
4
4
 
@@ -0,0 +1,137 @@
1
+ import {digg} from "diggerize"
2
+ import logger from "../logger.mjs"
3
+ import Net from "net"
4
+ import ServerClient from "./server-client.mjs"
5
+ import WorkerHandler from "./worker-handler/index.mjs"
6
+
7
+ export default class VelociousHttpServer {
8
+ clientCount = 0
9
+ clients = {}
10
+ workerCount = 0
11
+ workerHandlers = []
12
+
13
+ constructor({configuration, host, maxWorkers, port}) {
14
+ this.configuration = configuration
15
+ this.host = host || "0.0.0.0"
16
+ this.port = port || 3006
17
+ this.maxWorkers = maxWorkers || 16
18
+ }
19
+
20
+ async start() {
21
+ await this._ensureAtLeastOneWorker()
22
+ this.netServer = new Net.Server()
23
+ this.netServer.on("connection", this.onConnection)
24
+ await this._netServerListen()
25
+ }
26
+
27
+ _netServerListen() {
28
+ return new Promise((resolve, reject) => {
29
+ try {
30
+ this.netServer.listen(this.port, this.host, () => {
31
+ logger(this, `Velocious listening on ${this.host}:${this.port}`)
32
+ resolve()
33
+ })
34
+ } catch (error) {
35
+ reject(error)
36
+ }
37
+ })
38
+ }
39
+
40
+ async _ensureAtLeastOneWorker() {
41
+ if (this.workerHandlers.length == 0) {
42
+ await this.spawnWorker()
43
+ }
44
+ }
45
+
46
+ isActive() {
47
+ return this.netServer.listening
48
+ }
49
+
50
+ async stopClients() {
51
+ for (const clientCount in this.clients) {
52
+ const client = this.clients[clientCount]
53
+
54
+ await client.close()
55
+ }
56
+ }
57
+
58
+ stopServer() {
59
+ return new Promise((resolve, reject) => {
60
+ this.netServer.close((error) => {
61
+ if (error) {
62
+ reject(error)
63
+ } else {
64
+ resolve()
65
+ }
66
+ })
67
+ })
68
+ }
69
+
70
+ async stop() {
71
+ await this.stopClients()
72
+ await this.stopServer()
73
+ }
74
+
75
+ onConnection = (socket) => {
76
+ const clientCount = this.clientCount
77
+
78
+ logger(this, `New client ${clientCount}`)
79
+
80
+ this.clientCount++
81
+
82
+ const workerHandler = this.workerHandlerToUse()
83
+ const client = new ServerClient({
84
+ clientCount,
85
+ configuration: this.configuration,
86
+ socket
87
+ })
88
+
89
+ client.events.on("close", this.onClientClose)
90
+
91
+ logger(this, `Gave client ${clientCount} to worker ${workerHandler.workerCount}`)
92
+
93
+ workerHandler.addSocketConnection(client)
94
+
95
+ this.clients[clientCount] = client
96
+ }
97
+
98
+ onClientClose = (client) => {
99
+ const clientCount = digg(client, "clientCount")
100
+ const oldClientsLength = Object.keys(this.clients).length
101
+
102
+ delete this.clients[clientCount]
103
+
104
+ const newClientsLength = Object.keys(this.clients).length
105
+
106
+ if (newClientsLength != (oldClientsLength - 1)) {
107
+ console.error(`Expected client to have been removed but length didn't change from ${oldClientsLength} to ${oldClientsLength - 1}`)
108
+ }
109
+ }
110
+
111
+ async spawnWorker() {
112
+ const workerCount = this.workerCount
113
+
114
+ this.workerCount++
115
+
116
+ const workerHandler = new WorkerHandler({
117
+ configuration: this.configuration,
118
+ workerCount
119
+ })
120
+
121
+ await workerHandler.start()
122
+ this.workerHandlers.push(workerHandler)
123
+ }
124
+
125
+ workerHandlerToUse() {
126
+ logger(this, `Worker handlers length: ${this.workerHandlers.length}`)
127
+
128
+ const randomWorkerNumber = parseInt(Math.random() * this.workerHandlers.length)
129
+ const workerHandler = this.workerHandlers[randomWorkerNumber]
130
+
131
+ if (!workerHandler) {
132
+ throw new Error(`No workerHandler by that number: ${randomWorkerNumber}`)
133
+ }
134
+
135
+ return workerHandler
136
+ }
137
+ }
@@ -0,0 +1,47 @@
1
+ import EventEmitter from "events"
2
+ import logger from "../logger.mjs"
3
+
4
+ export default class ServerClient {
5
+ events = new EventEmitter()
6
+
7
+ constructor({configuration, socket, clientCount}) {
8
+ if (!configuration) throw new Error("No configuration given")
9
+
10
+ this.configuration = configuration
11
+ this.socket = socket
12
+ this.clientCount = clientCount
13
+
14
+ socket.on("end", this.onSocketEnd)
15
+ }
16
+
17
+ listen = () => this.socket.on("data", this.onSocketData)
18
+
19
+ close() {
20
+ return new Promise((resolve, reject) => {
21
+ this.socket.destroy()
22
+ this.events.emit("close", this)
23
+ resolve()
24
+ })
25
+ }
26
+
27
+ onSocketData = (chunk) => {
28
+ logger(this, `Socket ${this.clientCount}: ${chunk}`)
29
+
30
+ this.worker.postMessage({
31
+ command: "clientWrite",
32
+ chunk,
33
+ clientCount: this.clientCount
34
+ })
35
+ }
36
+
37
+ onSocketEnd = () => {
38
+ logger(this, `Socket ${this.clientCount} end`)
39
+ this.events.emit("close", this)
40
+ }
41
+
42
+ send(data) {
43
+ logger(this, "Send", data)
44
+
45
+ this.socket.write(data)
46
+ }
47
+ }
@@ -0,0 +1,79 @@
1
+ import {digg, digs} from "diggerize"
2
+ import {dirname} from "path"
3
+ import {fileURLToPath} from "url"
4
+ import logger from "../../logger.mjs"
5
+ import {Worker} from "worker_threads"
6
+
7
+ export default class VelociousHttpServerWorker {
8
+ constructor({configuration, workerCount}) {
9
+ this.configuration = configuration
10
+ this.clients = {}
11
+ this.workerCount = workerCount
12
+ }
13
+
14
+ async start() {
15
+ return new Promise((resolve) => {
16
+ const {debug, directory} = digs(this.configuration, "debug", "directory")
17
+ const __filename = fileURLToPath(import.meta.url)
18
+ const __dirname = dirname(__filename)
19
+
20
+ this.onStartCallback = resolve
21
+ this.worker = new Worker(`${__dirname}/worker-script.mjs`, {
22
+ workerData: {
23
+ debug,
24
+ directory,
25
+ workerCount: this.workerCount
26
+ }
27
+ })
28
+ this.worker.on("error", this.onWorkerError)
29
+ this.worker.on("exit", this.onWorkerExit)
30
+ this.worker.on("message", this.onWorkerMessage)
31
+ })
32
+ }
33
+
34
+ addSocketConnection(client) {
35
+ const clientCount = digg(client, "clientCount")
36
+
37
+ client.socket.on("end", () => {
38
+ logger(this, `Removing ${clientCount} from clients`)
39
+ delete this.clients[clientCount]
40
+ })
41
+
42
+ client.worker = this.worker
43
+ client.listen()
44
+
45
+ this.clients[clientCount] = client
46
+ this.worker.postMessage({command: "newClient", clientCount})
47
+ }
48
+
49
+ onWorkerError = (error) => {
50
+ throw error // Throws original error with backtrace and everything into the console
51
+ }
52
+
53
+ onWorkerExit = (code) => {
54
+ if (code !== 0) {
55
+ throw new Error(`Client worker stopped with exit code ${code}`)
56
+ }
57
+ }
58
+
59
+ onWorkerMessage = (data) => {
60
+ logger(this, `Worker message`, data)
61
+
62
+ const {command} = digs(data, "command")
63
+
64
+ if (command == "started") {
65
+ this.onStartCallback()
66
+ this.onStartCallback = null
67
+ } else if (command == "clientOutput") {
68
+ logger(this, "CLIENT OUTPUT", data)
69
+
70
+ const {clientCount, output} = digs(data, "clientCount", "output")
71
+
72
+ logger(this, "CLIENT OUTPUT", data)
73
+
74
+ this.clients[clientCount].send(output)
75
+ } else {
76
+ throw new Error(`Unknown command: ${command}`)
77
+ }
78
+ }
79
+ }
@@ -0,0 +1,4 @@
1
+ import {workerData, parentPort} from "worker_threads"
2
+ import WorkerThread from "./worker-thread.mjs"
3
+
4
+ new WorkerThread({parentPort, workerData})
@@ -0,0 +1,65 @@
1
+ import Application from "../../application.mjs"
2
+ import Client from "../client/index.mjs"
3
+ import DatabasePool from "../../database/pool/index.mjs"
4
+ import {digg, digs} from "diggerize"
5
+ import errorLogger from "../../error-logger.mjs"
6
+ import logger from "../../logger.mjs"
7
+
8
+ export default class VelociousHttpServerWorkerHandlerWorkerThread {
9
+ constructor({parentPort, workerData}) {
10
+ const {workerCount} = digs(workerData, "workerCount")
11
+
12
+ this.clients = {}
13
+ this.parentPort = parentPort
14
+ this.workerData = workerData
15
+ this.workerCount = workerCount
16
+
17
+ parentPort.on("message", errorLogger(this.onCommand))
18
+
19
+ this.initialize().then(() => {
20
+ this.application.initialize().then(() => {
21
+ logger(this, `Worker ${workerCount} started`)
22
+ parentPort.postMessage({command: "started"})
23
+ })
24
+ })
25
+ }
26
+
27
+ async initialize() {
28
+ const {debug, directory} = digs(this.workerData, "debug", "directory")
29
+ const configurationPath = `${this.workerData.directory}/src/config/configuration.mjs`
30
+ const configurationImport = await import(configurationPath)
31
+ const configuration = configurationImport.default
32
+
33
+ this.application = new Application({configuration, debug, directory})
34
+
35
+ this.configuration = configuration
36
+ this.configuration.setCurrent()
37
+ }
38
+
39
+ onCommand = (data) => {
40
+ logger(this, `Worker ${this.workerCount} received command`, data)
41
+
42
+ const {command} = data
43
+
44
+ if (command == "newClient") {
45
+ const {clientCount} = digs(data, "clientCount")
46
+ const client = new Client({
47
+ clientCount,
48
+ configuration: this.configuration
49
+ })
50
+
51
+ client.events.on("output", (output) => {
52
+ this.parentPort.postMessage({command: "clientOutput", clientCount, output})
53
+ })
54
+
55
+ this.clients[clientCount] = client
56
+ } else if (command == "clientWrite") {
57
+ const {chunk, clientCount} = digs(data, "chunk", "clientCount")
58
+ const client = digg(this.clients, clientCount)
59
+
60
+ client.onWrite(chunk)
61
+ } else {
62
+ throw new Error(`Unknown command: ${command}`)
63
+ }
64
+ }
65
+ }
@@ -1,6 +1,6 @@
1
- const {digg} = require("diggerize")
1
+ import {digg} from "diggerize"
2
2
 
3
- module.exports = function log(object, ...messages) {
3
+ export default function log(object, ...messages) {
4
4
  if (!object.configuration) console.error(`No configuration on ${object.constructor.name}`)
5
5
 
6
6
  if (object.configuration?.debug) {
@@ -0,0 +1,34 @@
1
+ import GetRoute from "./get-route.mjs"
2
+ import ResourceRoute from "./resource-route.mjs"
3
+
4
+ var VelociousBaseRoute
5
+
6
+ export function initBaseRoute() {
7
+ if (VelociousBaseRoute) return
8
+
9
+ VelociousBaseRoute = class VelociousBaseRoute {
10
+ routes = []
11
+
12
+ get(name, args) {
13
+ const route = new GetRoute({name, args})
14
+
15
+ this.routes.push(route)
16
+ }
17
+
18
+ matchWithPath(_path) {
19
+ throw new Error(`No 'matchWithPath' implemented on ${this.constructor.name}`)
20
+ }
21
+
22
+ resources(name, callback) {
23
+ const route = new ResourceRoute({name})
24
+
25
+ this.routes.push(route)
26
+
27
+ if (callback) {
28
+ callback(route)
29
+ }
30
+ }
31
+ }
32
+ }
33
+
34
+ export {VelociousBaseRoute as default}
@@ -1,7 +1,9 @@
1
- const BaseRoute = require("./base-route.cjs")
2
- const escapeStringRegexp = require("escape-string-regexp")
1
+ import BaseRoute, {initBaseRoute} from "./base-route.mjs"
2
+ import escapeStringRegexp from "escape-string-regexp"
3
3
 
4
- module.exports = class VelociousRouteGetRoute extends BaseRoute {
4
+ initBaseRoute()
5
+
6
+ export default class VelociousRouteGetRoute extends BaseRoute {
5
7
  constructor({name}) {
6
8
  super()
7
9
  this.name = name
@@ -0,0 +1,9 @@
1
+ import RootRoute from "./root-route.mjs"
2
+
3
+ export default class VelociousRoutes {
4
+ rootRoute = new RootRoute()
5
+
6
+ draw(callback) {
7
+ callback(this.rootRoute)
8
+ }
9
+ }
@@ -1,18 +1,18 @@
1
- const {digg, digs} = require("diggerize")
1
+ import {digg, digs} from "diggerize"
2
2
 
3
- module.exports = class VelociousRoutesResolver {
4
- constructor({configuration, request, response, routes}) {
3
+ export default class VelociousRoutesResolver {
4
+ constructor({configuration, request, response}) {
5
5
  if (!configuration) throw new Error("No configuration given")
6
6
  if (!request) throw new Error("No request given")
7
7
  if (!response) throw new Error("No response given")
8
8
 
9
9
  this.configuration = configuration
10
- this.params = {}
10
+ this.params = request.params()
11
11
  this.request = request
12
12
  this.response = response
13
13
  }
14
14
 
15
- resolve() {
15
+ async resolve() {
16
16
  let currentRoute = digg(this, "configuration", "routes", "rootRoute")
17
17
  let currentPath = this.request.path()
18
18
 
@@ -21,8 +21,9 @@ module.exports = 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.cjs`
25
- const controllerClass = require(controllerPath)
24
+ const controllerPath = `${digg(this, "configuration", "directory")}/src/routes/${digg(this, "params", "controller")}/controller.mjs`
25
+ const controllerClassImport = await import(controllerPath)
26
+ const controllerClass = controllerClassImport.default
26
27
  const controllerInstance = new controllerClass({
27
28
  configuration: this.configuration,
28
29
  params: this.params,
@@ -30,7 +31,13 @@ module.exports = class VelociousRoutesResolver {
30
31
  response: this.response
31
32
  })
32
33
 
33
- controllerInstance[this.params.action]()
34
+ if (!(this.params.action in controllerInstance)) {
35
+ throw new Error(`Missing action on controller: ${this.params.controller}#${this.params.action}`)
36
+ }
37
+
38
+ await this.configuration.getDatabasePool().withConnection(async () => {
39
+ await controllerInstance[this.params.action]()
40
+ })
34
41
 
35
42
  return
36
43
  }
@@ -44,7 +51,8 @@ module.exports = class VelociousRoutesResolver {
44
51
  for (const subRoute of route.routes) {
45
52
  const matchResult = subRoute.matchWithPath({
46
53
  params: this.params,
47
- path: pathWithoutSlash
54
+ path: pathWithoutSlash,
55
+ request: this.request
48
56
  })
49
57
 
50
58
  if (!matchResult) continue
@@ -1,14 +1,16 @@
1
- const BaseRoute = require("./base-route.cjs")
2
- const escapeStringRegexp = require("escape-string-regexp")
1
+ import BaseRoute, {initBaseRoute} from "./base-route.mjs"
2
+ import escapeStringRegexp from "escape-string-regexp"
3
3
 
4
- module.exports = class VelociousRouteResourceRoute extends BaseRoute {
4
+ initBaseRoute()
5
+
6
+ export default class VelociousRouteResourceRoute extends BaseRoute {
5
7
  constructor({name}) {
6
8
  super()
7
9
  this.name = name
8
10
  this.regExp = new RegExp(`^(${escapeStringRegexp(name)})(.*)$`)
9
11
  }
10
12
 
11
- matchWithPath({params, path}) {
13
+ matchWithPath({params, path, request}) {
12
14
  const match = path.match(this.regExp)
13
15
 
14
16
  if (match) {
@@ -24,7 +26,9 @@ module.exports = class VelociousRouteResourceRoute extends BaseRoute {
24
26
  }
25
27
 
26
28
  if (!subRoutesMatchesRestPath) {
27
- if (restPath.match(/\/(.+)/)) {
29
+ if (request.httpMethod() == "POST") {
30
+ action = "create"
31
+ } else if (restPath.match(/\/(.+)/)) {
28
32
  // TODO: This should change the action to "show" and set the "resource_name_id" in params.
29
33
  action = "show"
30
34
  }
@@ -0,0 +1,6 @@
1
+ import BaseRoute, {initBaseRoute} from "./base-route.mjs"
2
+
3
+ initBaseRoute()
4
+
5
+ export default class VelociousRootRoute extends BaseRoute {
6
+ }
@@ -0,0 +1,5 @@
1
+ export default class VelocuiousSpec {
2
+ static describe(description) {
3
+ throw new Error("stub", description)
4
+ }
5
+ }
@@ -0,0 +1,17 @@
1
+ import {Configuration} from "velocious"
2
+
3
+ const configuration = new Configuration({
4
+ database: {
5
+ default: {
6
+ master: {
7
+ type: "mysql",
8
+ host: "mariadb",
9
+ username: "username",
10
+ password: "password",
11
+ database: "database"
12
+ }
13
+ }
14
+ }
15
+ })
16
+
17
+ export default configuration
@@ -0,0 +1,11 @@
1
+ import {Database} from "velocious"
2
+
3
+ export default class __MIGRATION_NAME__ extends Database.Migration {
4
+ async up() {
5
+ await this.connection().execute("...")
6
+ }
7
+
8
+ async down() {
9
+ await this.connection().execute("...")
10
+ }
11
+ }
@@ -0,0 +1,11 @@
1
+ import {Routes} from "velocious"
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
package/bin/velocious DELETED
@@ -1,14 +0,0 @@
1
- #!/usr/bin/node
2
-
3
- console.log("Hello", process.argv)
4
-
5
- const args = process.argv.slice(2)
6
-
7
- console.log(args)
8
-
9
- if (args[0] == "g" && args[1] == "migration") {
10
- const migrationName = args[2]
11
- const date = new Date()
12
-
13
- console.log({ migrationName, date })
14
- }