velocious 1.0.0 → 1.0.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 (120) hide show
  1. package/README.md +26 -0
  2. package/bin/velocious.mjs +8 -0
  3. package/index.mjs +17 -0
  4. package/package.json +13 -6
  5. package/peak_flow.yml +9 -5
  6. package/spec/cli/generate/migration-spec.mjs +9 -0
  7. package/spec/database/connection/drivers/mysql/{query-parser-spec.cjs → query-parser-spec.mjs} +12 -8
  8. package/spec/database/drivers/mysql/connection-spec.mjs +21 -0
  9. package/spec/database/record/create-spec.mjs +14 -0
  10. package/spec/database/record/destroy-spec.mjs +17 -0
  11. package/spec/database/record/find-spec.mjs +29 -0
  12. package/spec/database/record/update-spec.mjs +15 -0
  13. package/spec/dummy/index.mjs +69 -0
  14. package/spec/dummy/src/config/database.example.mjs +15 -0
  15. package/spec/dummy/src/config/database.peakflow.mjs +15 -0
  16. package/spec/dummy/src/{routes.cjs → config/routes.mjs} +3 -2
  17. package/spec/dummy/src/database/migrations/001-create-tasks.mjs +12 -0
  18. package/spec/dummy/src/models/task.mjs +4 -0
  19. package/spec/dummy/src/routes/tasks/controller.mjs +26 -0
  20. package/spec/http-server/{client-spec.cjs → client-spec.mjs} +12 -5
  21. package/spec/http-server/{get-spec.cjs → get-spec.mjs} +2 -2
  22. package/spec/http-server/post-spec.mjs +72 -0
  23. package/spec/support/jasmine.json +4 -3
  24. package/src/application.mjs +56 -0
  25. package/src/cli/commands/db/create.mjs +14 -0
  26. package/src/cli/commands/generate/migration.mjs +12 -0
  27. package/src/cli/index.mjs +39 -0
  28. package/src/configuration.mjs +27 -0
  29. package/src/{controller.cjs → controller.mjs} +21 -4
  30. package/src/database/drivers/base.mjs +9 -0
  31. package/src/database/drivers/index.mjs +5 -0
  32. package/src/database/drivers/mysql/connect-connection.mjs +12 -0
  33. package/src/database/drivers/mysql/index.mjs +77 -0
  34. package/src/database/drivers/mysql/options.mjs +17 -0
  35. package/src/database/drivers/mysql/query-parser.mjs +25 -0
  36. package/src/database/drivers/mysql/query.mjs +26 -0
  37. package/src/database/drivers/mysql/sql/delete.mjs +19 -0
  38. package/src/database/drivers/mysql/sql/insert.mjs +29 -0
  39. package/src/database/drivers/mysql/sql/update.mjs +31 -0
  40. package/src/database/handler.mjs +11 -0
  41. package/src/database/index.mjs +15 -0
  42. package/src/database/migration/index.mjs +5 -0
  43. package/src/database/migrator/index.mjs +15 -0
  44. package/src/database/pool/index.mjs +43 -0
  45. package/src/database/query/delete-base.mjs +15 -0
  46. package/src/database/query/from-base.mjs +9 -0
  47. package/src/database/query/from-plain.mjs +12 -0
  48. package/src/database/query/{from-table.cjs → from-table.mjs} +2 -2
  49. package/src/database/query/index.mjs +144 -0
  50. package/src/database/query/insert-base.mjs +15 -0
  51. package/src/database/query/join-base.mjs +9 -0
  52. package/src/database/query/join-plain.mjs +12 -0
  53. package/src/database/query/order-base.mjs +9 -0
  54. package/src/database/query/order-plain.mjs +21 -0
  55. package/src/database/query/select-base.mjs +9 -0
  56. package/src/database/query/select-plain.mjs +12 -0
  57. package/src/database/query/{select-table-and-column.cjs → select-table-and-column.mjs} +4 -4
  58. package/src/database/query/update-base.mjs +16 -0
  59. package/src/database/query-parser/{from-parser.cjs → from-parser.mjs} +3 -6
  60. package/src/database/query-parser/{joins-parser.cjs → joins-parser.mjs} +3 -6
  61. package/src/database/query-parser/{options.cjs → options.mjs} +13 -2
  62. package/src/database/query-parser/{select-parser.cjs → select-parser.mjs} +7 -6
  63. package/src/database/record/index.mjs +187 -0
  64. package/src/database/record/record-not-found-error.mjs +1 -0
  65. package/src/{error-logger.js → error-logger.mjs} +1 -1
  66. package/src/http-server/client/{index.cjs → index.mjs} +10 -11
  67. package/src/http-server/client/params-to-object.mjs +68 -0
  68. package/src/http-server/client/request-buffer/form-data-part.mjs +42 -0
  69. package/src/http-server/client/request-buffer/header.mjs +7 -0
  70. package/src/http-server/client/request-buffer/index.mjs +229 -0
  71. package/src/http-server/client/request-parser.mjs +47 -0
  72. package/src/http-server/client/{request-runner.cjs → request-runner.mjs} +5 -5
  73. package/src/http-server/client/request.mjs +15 -0
  74. package/src/http-server/client/{response.cjs → response.mjs} +1 -1
  75. package/src/http-server/index.mjs +137 -0
  76. package/src/http-server/server-client.mjs +47 -0
  77. package/src/http-server/worker-handler/index.mjs +79 -0
  78. package/src/http-server/worker-handler/worker-script.mjs +4 -0
  79. package/src/http-server/worker-handler/{worker-thread.cjs → worker-thread.mjs} +18 -11
  80. package/src/{logger.cjs → logger.mjs} +2 -2
  81. package/src/routes/base-route.mjs +34 -0
  82. package/src/routes/{get-route.cjs → get-route.mjs} +5 -3
  83. package/src/routes/index.mjs +9 -0
  84. package/src/routes/{resolver.cjs → resolver.mjs} +15 -9
  85. package/src/routes/{resource-route.cjs → resource-route.mjs} +9 -5
  86. package/src/routes/root-route.mjs +6 -0
  87. package/bin/velocious +0 -14
  88. package/index.cjs +0 -11
  89. package/spec/dummy/config/databases.example.json +0 -10
  90. package/spec/dummy/config/databases.json +0 -0
  91. package/spec/dummy/config/databases.peakflow.json +0 -11
  92. package/spec/dummy/index.cjs +0 -40
  93. package/spec/dummy/src/models/task.cjs +0 -4
  94. package/spec/dummy/src/routes/tasks/controller.cjs +0 -18
  95. package/src/application.cjs +0 -36
  96. package/src/configuration.cjs +0 -14
  97. package/src/database/connection/drivers/mysql/index.cjs +0 -5
  98. package/src/database/connection/drivers/mysql/options.cjs +0 -7
  99. package/src/database/connection/drivers/mysql/query-parser.cjs +0 -26
  100. package/src/database/connection/index.cjs +0 -2
  101. package/src/database/handler.cjs +0 -5
  102. package/src/database/index.cjs +0 -9
  103. package/src/database/pool/index.cjs +0 -2
  104. package/src/database/query/from-base.cjs +0 -15
  105. package/src/database/query/from-plain.cjs +0 -12
  106. package/src/database/query/index.cjs +0 -59
  107. package/src/database/query/join-base.cjs +0 -15
  108. package/src/database/query/join-plain.cjs +0 -12
  109. package/src/database/query/select-base.cjs +0 -15
  110. package/src/database/query/select-plain.cjs +0 -12
  111. package/src/database/record/index.cjs +0 -5
  112. package/src/http-server/client/request-parser.cjs +0 -92
  113. package/src/http-server/client/request.cjs +0 -25
  114. package/src/http-server/index.cjs +0 -78
  115. package/src/http-server/worker-handler/index.cjs +0 -78
  116. package/src/http-server/worker-handler/socket-handler.cjs +0 -35
  117. package/src/http-server/worker-handler/worker-script.cjs +0 -4
  118. package/src/routes/base-route.cjs +0 -25
  119. package/src/routes/index.cjs +0 -9
  120. package/src/routes/root-route.cjs +0 -4
@@ -0,0 +1,12 @@
1
+ import JoinBase from "./join-base.mjs"
2
+
3
+ export default class VelociousDatabaseQueryJoinPlain extends JoinBase {
4
+ constructor({plain}) {
5
+ super()
6
+ this.plain = plain
7
+ }
8
+
9
+ toSql() {
10
+ return this.plain
11
+ }
12
+ }
@@ -0,0 +1,9 @@
1
+ export default class VelociousDatabaseQueryOrderBase {
2
+ getOptions() {
3
+ return this.query.driver.options()
4
+ }
5
+
6
+ toSql() {
7
+ throw new Error("'toSql' wasn't implemented")
8
+ }
9
+ }
@@ -0,0 +1,21 @@
1
+ import OrderBase from "./order-base.mjs"
2
+
3
+ export default class VelociousDatabaseQueryOrderPlain extends OrderBase {
4
+ constructor({plain}) {
5
+ super()
6
+ this.plain = plain
7
+ this.reverseOrder = false
8
+ }
9
+
10
+ setReverseOrder() {
11
+ this.reverseOrder = true
12
+ }
13
+
14
+ toSql() {
15
+ if (this.reverseOrder) {
16
+ return `${this.plain} DESC`
17
+ }
18
+
19
+ return this.plain
20
+ }
21
+ }
@@ -0,0 +1,9 @@
1
+ export default class VelociousDatabaseQuerySelectBase {
2
+ getOptions() {
3
+ return this.query.driver.options()
4
+ }
5
+
6
+ toSql() {
7
+ throw new Error("'toSql' wasn't implemented")
8
+ }
9
+ }
@@ -0,0 +1,12 @@
1
+ import SelectBase from "./select-base.mjs"
2
+
3
+ export default class VelociousDatabaseQuerySelectPlain extends SelectBase {
4
+ constructor({plain}) {
5
+ super()
6
+ this.plain = plain
7
+ }
8
+
9
+ toSql() {
10
+ return this.plain
11
+ }
12
+ }
@@ -1,8 +1,8 @@
1
- const SelectBase = require("./select-base.cjs")
1
+ import SelectBase from "./select-base.mjs"
2
2
 
3
- module.exports = class VelociousDatabaseQuerySelectTableAndColumn extends SelectBase {
4
- constructor({tableName, columnName}) {
5
- super()
3
+ export default class VelociousDatabaseQuerySelectTableAndColumn extends SelectBase {
4
+ constructor({query, tableName, columnName}) {
5
+ super({query})
6
6
  this.columnName = columnName
7
7
  this.tableName = tableName
8
8
  }
@@ -0,0 +1,16 @@
1
+ export default class VelociousDatabaseQueryUpdateBase {
2
+ constructor({conditions, data, driver, tableName}) {
3
+ this.conditions = conditions
4
+ this.data = data
5
+ this.driver = driver
6
+ this.tableName = tableName
7
+ }
8
+
9
+ getOptions() {
10
+ return this.driver.options()
11
+ }
12
+
13
+ toSql() {
14
+ throw new Error("'toSql' wasn't implemented")
15
+ }
16
+ }
@@ -1,10 +1,9 @@
1
- const {digs} = require("diggerize")
1
+ import {digs} from "diggerize"
2
2
 
3
- module.exports = class VelociousDatabaseQueryParserFromParser {
4
- constructor({pretty, query, queryParserOptions}) {
3
+ export default class VelociousDatabaseQueryParserFromParser {
4
+ constructor({pretty, query}) {
5
5
  this.pretty = pretty
6
6
  this.query = query
7
- this.queryParserOptions = queryParserOptions
8
7
  }
9
8
 
10
9
  toSql() {
@@ -15,8 +14,6 @@ module.exports = class VelociousDatabaseQueryParserFromParser {
15
14
  for (const fromKey in query._froms) {
16
15
  const from = query._froms[fromKey]
17
16
 
18
- from.setOptions(this.queryParserOptions)
19
-
20
17
  if (fromKey > 0) {
21
18
  sql += ","
22
19
  }
@@ -1,10 +1,9 @@
1
- const {digs} = require("diggerize")
1
+ import {digs} from "diggerize"
2
2
 
3
- module.exports = class VelocuiousDatabaseQueryParserJoinsParser {
4
- constructor({pretty, query, queryParserOptions}) {
3
+ export default class VelocuiousDatabaseQueryParserJoinsParser {
4
+ constructor({pretty, query}) {
5
5
  this.pretty = pretty
6
6
  this.query = query
7
- this.queryParserOptions = queryParserOptions
8
7
  }
9
8
 
10
9
  toSql() {
@@ -15,8 +14,6 @@ module.exports = class VelocuiousDatabaseQueryParserJoinsParser {
15
14
  for (const joinKey in query._joins) {
16
15
  const join = query._joins[joinKey]
17
16
 
18
- join.setOptions(this.queryParserOptions)
19
-
20
17
  if (joinKey == 0) {
21
18
  if (pretty) {
22
19
  sql += "\n\n"
@@ -1,9 +1,13 @@
1
- const {digg} = require("diggerize")
1
+ import {digg} from "diggerize"
2
2
 
3
- module.exports = class VelociousDatabaseQueryParserOptions {
3
+ export default class VelociousDatabaseQueryParserOptions {
4
4
  constructor(options) {
5
5
  this.columnQuote = digg(options, "columnQuote")
6
+ this.driver = digg(options, "driver")
6
7
  this.tableQuote = digg(options, "tableQuote")
8
+ this.stringQuote = digg(options, "stringQuote")
9
+
10
+ if (!this.driver) throw new Error("No driver given")
7
11
  }
8
12
 
9
13
  quoteColumnName(columnName) {
@@ -17,4 +21,11 @@ module.exports = class VelociousDatabaseQueryParserOptions {
17
21
 
18
22
  return `${this.tableQuote}${tableName}${this.tableQuote}`
19
23
  }
24
+
25
+ quote(value) {
26
+ if (typeof value == "number")
27
+ return value
28
+
29
+ return this.quoteString(value)
30
+ }
20
31
  }
@@ -1,10 +1,9 @@
1
- const {digs} = require("diggerize")
1
+ import {digs} from "diggerize"
2
2
 
3
- module.exports = class VelociousDatabaseQueryParserSelectParser {
4
- constructor({pretty, query, queryParserOptions}) {
3
+ export default class VelociousDatabaseQueryParserSelectParser {
4
+ constructor({pretty, query}) {
5
5
  this.pretty = pretty
6
6
  this.query = query
7
- this.queryParserOptions = queryParserOptions
8
7
  }
9
8
 
10
9
  toSql() {
@@ -23,8 +22,6 @@ module.exports = class VelociousDatabaseQueryParserSelectParser {
23
22
  for (const selectKey in query._selects) {
24
23
  const selectValue = query._selects[selectKey]
25
24
 
26
- selectValue.setOptions(this.queryParserOptions)
27
-
28
25
  sql += selectValue.toSql()
29
26
 
30
27
  if (selectKey + 1 < query._selects.length) {
@@ -37,6 +34,10 @@ module.exports = class VelociousDatabaseQueryParserSelectParser {
37
34
  }
38
35
  }
39
36
 
37
+ if (query._selects.length == 0) {
38
+ sql += "*"
39
+ }
40
+
40
41
  return sql
41
42
  }
42
43
  }
@@ -0,0 +1,187 @@
1
+ import DatabasePool from "../pool/index.mjs"
2
+ import Handler from "../handler.mjs"
3
+ import inflection from "inflection"
4
+ import Query from "../query/index.mjs"
5
+ import RecordNotFoundError from "./record-not-found-error.mjs"
6
+
7
+ export default class VelociousDatabaseRecord {
8
+ static connection() {
9
+ const connection = DatabasePool.current().singleConnection()
10
+
11
+ if (!connection) throw new Error("No connection?")
12
+
13
+ return connection
14
+ }
15
+
16
+ static async find(recordId) {
17
+ const conditions = {}
18
+
19
+ conditions[this.primaryKey()] = recordId
20
+
21
+ const record = await this.where(conditions).first()
22
+
23
+ if (!record) {
24
+ throw new RecordNotFoundError(`Couldn't find ${this.name} with '${this.primaryKey()}'=${recordId}`)
25
+ }
26
+
27
+ return record
28
+ }
29
+
30
+ static async last() {
31
+ const query = this._newQuery().order(this.primaryKey()).limit(1)
32
+ const record = await query.last()
33
+
34
+ return record
35
+ }
36
+
37
+ static primaryKey() {
38
+ return "id"
39
+ }
40
+
41
+ async save() {
42
+ if (this.isPersisted()) {
43
+ return await this._updateRecordWithChanges()
44
+ } else {
45
+ return await this._createNewRecord()
46
+ }
47
+ }
48
+
49
+ static tableName() {
50
+ return inflection.underscore(inflection.pluralize(this.name))
51
+ }
52
+
53
+ static _newQuery() {
54
+ const handler = new Handler()
55
+ const query = new Query({
56
+ driver: this.connection(),
57
+ handler,
58
+ modelClass: this
59
+ })
60
+
61
+ return query.from(this.tableName())
62
+ }
63
+
64
+ static orderableColumn() {
65
+ // Allow to change to 'created_at' if using UUID?
66
+
67
+ return this.primaryKey()
68
+ }
69
+
70
+ static where(object) {
71
+ const query = this._newQuery().where(object)
72
+
73
+ return query
74
+ }
75
+
76
+ constructor(attributes = {}) {
77
+ this._attributes = attributes
78
+ this._changes = {}
79
+ }
80
+
81
+ assign(attributesToAssign) {
82
+ for (const attributeToAssign in attributesToAssign) {
83
+ this._changes[attributeToAssign] = attributesToAssign[attributeToAssign]
84
+ }
85
+ }
86
+
87
+ attributes() {
88
+ return Object.assign({}, this._attributes, this._changes)
89
+ }
90
+
91
+ _connection() {
92
+ if (this.__connection) return this.__connection
93
+
94
+ return this.constructor.connection()
95
+ }
96
+
97
+ async destroy() {
98
+ const conditions = {}
99
+
100
+ conditions[this.constructor.primaryKey()] = this.id()
101
+
102
+ const sql = this._connection().deleteSql({
103
+ conditions,
104
+ tableName: this._tableName()
105
+ })
106
+
107
+ await this._connection().query(sql)
108
+ }
109
+
110
+ _tableName() {
111
+ if (this.__tableName) return this.__tableName
112
+
113
+ return this.constructor.tableName()
114
+ }
115
+
116
+ readAttribute(attributeName) {
117
+ if (attributeName in this._changes) return this._changes[attributeName]
118
+
119
+ return this._attributes[attributeName]
120
+ }
121
+
122
+ async _createNewRecord() {
123
+ if (!this.constructor.connection()["insertSql"]) {
124
+ throw new Error(`No insertSql on ${this.constructor.connection().constructor.name}`)
125
+ }
126
+
127
+ const sql = this._connection().insertSql({
128
+ tableName: this._tableName(),
129
+ data: this.attributes()
130
+ })
131
+ const result = await this._connection().query(sql)
132
+ const id = result.insertId
133
+
134
+ await this._reloadWithId(id)
135
+ }
136
+
137
+ async _updateRecordWithChanges() {
138
+ const conditions = {}
139
+
140
+ conditions[this.constructor.primaryKey()] = this.id()
141
+
142
+ const sql = this._connection().updateSql({
143
+ tableName: this._tableName(),
144
+ data: this._changes,
145
+ conditions
146
+ })
147
+ await this._connection().query(sql)
148
+ await this._reloadWithId(this.id())
149
+ }
150
+
151
+ id() {
152
+ return this.readAttribute(this.constructor.primaryKey())
153
+ }
154
+
155
+ isPersisted() {
156
+ if (this.id()) return true
157
+
158
+ return false
159
+ }
160
+
161
+ isNewRecord() {
162
+ return !this.isPersisted()
163
+ }
164
+
165
+ async _reloadWithId(id) {
166
+ const primaryKey = this.constructor.primaryKey()
167
+ const whereObject = {}
168
+
169
+ whereObject[primaryKey] = id
170
+
171
+ const query = this.constructor.where(whereObject)
172
+ const reloadedModel = await query.first()
173
+
174
+ this._attributes = reloadedModel.attributes()
175
+ this._changes = {}
176
+ }
177
+
178
+ async reload() {
179
+ this._reloadWithId(this.readAttribute("id"))
180
+ }
181
+
182
+ async update(attributesToAssign) {
183
+ if (attributesToAssign) this.assign(attributesToAssign)
184
+
185
+ await this.save()
186
+ }
187
+ }
@@ -0,0 +1 @@
1
+ export default class RecordNotFoundError extends Error {}
@@ -1,4 +1,4 @@
1
- module.exports = function errorLogger(callback) {
1
+ export default function errorLogger(callback) {
2
2
  return async function(...args) {
3
3
  try {
4
4
  await callback(...args)
@@ -1,11 +1,10 @@
1
- const Configuration = require("../../configuration.cjs")
2
- const {digg} = require("diggerize")
3
- const {EventEmitter} = require("events")
4
- const logger = require("../../logger.cjs")
5
- const Request = require("./request.cjs")
6
- const RequestRunner = require("./request-runner.cjs")
1
+ import {digg} from "diggerize"
2
+ import {EventEmitter} from "events"
3
+ import logger from "../../logger.mjs"
4
+ import Request from "./request.mjs"
5
+ import RequestRunner from "./request-runner.mjs"
7
6
 
8
- module.exports = class VeoliciousHttpServerClient {
7
+ export default class VeoliciousHttpServerClient {
9
8
  events = new EventEmitter()
10
9
  state = "initial"
11
10
 
@@ -17,7 +16,7 @@ module.exports = class VeoliciousHttpServerClient {
17
16
  this.onExecuteRequest = onExecuteRequest
18
17
  }
19
18
 
20
- executeCurrentRequest() {
19
+ executeCurrentRequest = () => {
21
20
  logger(this, "executeCurrentRequest")
22
21
 
23
22
  this.state = "response"
@@ -28,7 +27,7 @@ module.exports = class VeoliciousHttpServerClient {
28
27
  routes: this.routes
29
28
  })
30
29
 
31
- requestRunner.events.on("done", (requestRunner) => this.sendResponse(requestRunner))
30
+ requestRunner.events.on("done", this.sendResponse)
32
31
  requestRunner.run()
33
32
  }
34
33
 
@@ -37,7 +36,7 @@ module.exports = class VeoliciousHttpServerClient {
37
36
  this.currentRequest = new Request({
38
37
  configuration: this.configuration
39
38
  })
40
- this.currentRequest.requestParser.events.on("done", () => this.executeCurrentRequest())
39
+ this.currentRequest.requestParser.events.on("done", this.executeCurrentRequest)
41
40
  this.currentRequest.feed(data)
42
41
  this.state = "requestStarted"
43
42
  } else if (this.state == "requestStarted") {
@@ -47,7 +46,7 @@ module.exports = class VeoliciousHttpServerClient {
47
46
  }
48
47
  }
49
48
 
50
- sendResponse(requestRunner) {
49
+ sendResponse = (requestRunner) => {
51
50
  const response = digg(requestRunner, "response")
52
51
  const body = response.getBody()
53
52
  const date = new Date()
@@ -0,0 +1,68 @@
1
+ export default class ParamsToObject {
2
+ constructor(object) {
3
+ this.object = object
4
+ }
5
+
6
+ toObject() {
7
+ const result = {}
8
+
9
+ for(const key in this.object) {
10
+ const value = this.object[key]
11
+
12
+ this.treatInitial(key, value, result)
13
+ }
14
+
15
+ return result
16
+ }
17
+
18
+ treatInitial(key, value, result) {
19
+ const firstMatch = key.match(/^(.+?)(\[([\s\S]+$))/)
20
+
21
+ if (firstMatch) {
22
+ const inputName = firstMatch[1]
23
+ const rest = firstMatch[2]
24
+
25
+ let newResult
26
+
27
+ if (inputName in result) {
28
+ newResult = result[inputName]
29
+ } else if (rest == "[]") {
30
+ newResult = []
31
+ result[inputName] = newResult
32
+ } else {
33
+ newResult = {}
34
+ result[inputName] = newResult
35
+ }
36
+
37
+ this.treatSecond(value, rest, newResult)
38
+ } else {
39
+ result[key] = value
40
+ }
41
+ }
42
+
43
+ treatSecond(value, rest, result) {
44
+ const secondMatch = rest.match(/^\[(.*?)\]([\s\S]*)$/)
45
+ const key = secondMatch[1]
46
+ const newRest = secondMatch[2]
47
+
48
+ let newResult
49
+
50
+ if (rest == "[]") {
51
+ result.push(value)
52
+ } else if (newRest == "") {
53
+ result[key] = value
54
+ } else {
55
+ if (typeof result == "object" && key in result) {
56
+ newResult = result[key]
57
+ } else if (newRest == "[]") {
58
+ newResult = []
59
+ result[key] = newResult
60
+ } else {
61
+ newResult = {}
62
+ result[key] = newResult
63
+ }
64
+
65
+ this.treatSecond(value, newRest, newResult)
66
+ }
67
+ }
68
+ }
@@ -0,0 +1,42 @@
1
+ export default class FormDataPart {
2
+ headers = {}
3
+ body = []
4
+
5
+ addHeader(header) {
6
+ const name = header.formattedName
7
+
8
+ this.headers[name] = header
9
+
10
+ if (name == "content-disposition") {
11
+ const match = header.value.match(/^form-data; name="(.+)"$/)
12
+
13
+ if (match) {
14
+ this.name = match[1]
15
+ } else {
16
+ console.error(`Couldn't match name from content-disposition: ${header.value}`)
17
+ }
18
+ } else if (name == "content-length") {
19
+ this.contentLength = parseInt(header.value)
20
+ }
21
+ }
22
+
23
+ finish() {
24
+ this.value = String.fromCharCode.apply(null, this.body)
25
+ }
26
+
27
+ getName() {
28
+ if (!this.name) throw new Error("Name hasn't been set")
29
+
30
+ return this.name
31
+ }
32
+
33
+ getValue() {
34
+ if (!this.value) throw new Error("Value hasn't been set")
35
+
36
+ return this.value
37
+ }
38
+
39
+ removeFromBody(text) {
40
+ this.body = this.body.slice(0, this.body.length - text.length)
41
+ }
42
+ }
@@ -0,0 +1,7 @@
1
+ export default class Header {
2
+ constructor(name, value) {
3
+ this.formattedName = name.toLowerCase().trim()
4
+ this.name = name
5
+ this.value = value
6
+ }
7
+ }