@c9up/ream 0.2.28 → 0.2.30

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 (293) hide show
  1. package/README.md +5 -6
  2. package/dist/Codemods.d.ts +24 -0
  3. package/dist/Codemods.d.ts.map +1 -1
  4. package/dist/Codemods.js +211 -1
  5. package/dist/Codemods.js.map +1 -1
  6. package/dist/HttpKernel.d.ts.map +1 -1
  7. package/dist/HttpKernel.js +17 -5
  8. package/dist/HttpKernel.js.map +1 -1
  9. package/dist/Ignitor.d.ts +15 -2
  10. package/dist/Ignitor.d.ts.map +1 -1
  11. package/dist/Ignitor.js +33 -23
  12. package/dist/Ignitor.js.map +1 -1
  13. package/dist/bodyparser/BodyParserMiddleware.d.ts +4 -4
  14. package/dist/bodyparser/BodyParserMiddleware.d.ts.map +1 -1
  15. package/dist/bodyparser/BodyParserMiddleware.js +41 -11
  16. package/dist/bodyparser/BodyParserMiddleware.js.map +1 -1
  17. package/dist/bodyparser/MultipartFile.d.ts +21 -15
  18. package/dist/bodyparser/MultipartFile.d.ts.map +1 -1
  19. package/dist/bodyparser/MultipartFile.js +40 -58
  20. package/dist/bodyparser/MultipartFile.js.map +1 -1
  21. package/dist/bodyparser/parseSize.d.ts +7 -4
  22. package/dist/bodyparser/parseSize.d.ts.map +1 -1
  23. package/dist/bodyparser/parseSize.js +12 -17
  24. package/dist/bodyparser/parseSize.js.map +1 -1
  25. package/dist/bodyparser/qsParse.d.ts +20 -1
  26. package/dist/bodyparser/qsParse.d.ts.map +1 -1
  27. package/dist/bodyparser/qsParse.js +78 -25
  28. package/dist/bodyparser/qsParse.js.map +1 -1
  29. package/dist/codemods/source.d.ts +57 -0
  30. package/dist/codemods/source.d.ts.map +1 -0
  31. package/dist/codemods/source.js +282 -0
  32. package/dist/codemods/source.js.map +1 -0
  33. package/dist/console/prompts.d.ts.map +1 -1
  34. package/dist/console/prompts.js +3 -1
  35. package/dist/console/prompts.js.map +1 -1
  36. package/dist/container/Container.d.ts.map +1 -1
  37. package/dist/container/Container.js +61 -71
  38. package/dist/container/Container.js.map +1 -1
  39. package/dist/events/Emitter.d.ts +12 -0
  40. package/dist/events/Emitter.d.ts.map +1 -1
  41. package/dist/events/Emitter.js +36 -9
  42. package/dist/events/Emitter.js.map +1 -1
  43. package/dist/events/helix/helpers.d.ts.map +1 -1
  44. package/dist/events/helix/helpers.js +19 -9
  45. package/dist/events/helix/helpers.js.map +1 -1
  46. package/dist/graphql/GraphQLEngine.d.ts +8 -0
  47. package/dist/graphql/GraphQLEngine.d.ts.map +1 -1
  48. package/dist/graphql/GraphQLEngine.js +79 -12
  49. package/dist/graphql/GraphQLEngine.js.map +1 -1
  50. package/dist/helpers/MessageBuilder.d.ts +4 -2
  51. package/dist/helpers/MessageBuilder.d.ts.map +1 -1
  52. package/dist/helpers/MessageBuilder.js +4 -2
  53. package/dist/helpers/MessageBuilder.js.map +1 -1
  54. package/dist/helpers/errors.d.ts +11 -0
  55. package/dist/helpers/errors.d.ts.map +1 -0
  56. package/dist/helpers/errors.js +17 -0
  57. package/dist/helpers/errors.js.map +1 -0
  58. package/dist/helpers/napi-loader.d.ts.map +1 -1
  59. package/dist/helpers/napi-loader.js +3 -2
  60. package/dist/helpers/napi-loader.js.map +1 -1
  61. package/dist/http/Exception.d.ts +14 -1
  62. package/dist/http/Exception.d.ts.map +1 -1
  63. package/dist/http/Exception.js +10 -2
  64. package/dist/http/Exception.js.map +1 -1
  65. package/dist/http/HttpContext.d.ts +31 -2
  66. package/dist/http/HttpContext.d.ts.map +1 -1
  67. package/dist/http/HttpContext.js +12 -5
  68. package/dist/http/HttpContext.js.map +1 -1
  69. package/dist/http/RedirectBuilder.d.ts +9 -3
  70. package/dist/http/RedirectBuilder.d.ts.map +1 -1
  71. package/dist/http/RedirectBuilder.js +43 -37
  72. package/dist/http/RedirectBuilder.js.map +1 -1
  73. package/dist/http/Request.d.ts +42 -17
  74. package/dist/http/Request.d.ts.map +1 -1
  75. package/dist/http/Request.js +80 -58
  76. package/dist/http/Request.js.map +1 -1
  77. package/dist/http/Response.d.ts +7 -4
  78. package/dist/http/Response.d.ts.map +1 -1
  79. package/dist/http/Response.js +14 -6
  80. package/dist/http/Response.js.map +1 -1
  81. package/dist/http/SseStream.js +6 -7
  82. package/dist/http/SseStream.js.map +1 -1
  83. package/dist/http/permissions.d.ts +25 -0
  84. package/dist/http/permissions.d.ts.map +1 -0
  85. package/dist/http/permissions.js +38 -0
  86. package/dist/http/permissions.js.map +1 -0
  87. package/dist/http-client/HttpClient.d.ts +111 -0
  88. package/dist/http-client/HttpClient.d.ts.map +1 -0
  89. package/dist/http-client/HttpClient.js +386 -0
  90. package/dist/http-client/HttpClient.js.map +1 -0
  91. package/dist/http-client/addresses.d.ts +14 -0
  92. package/dist/http-client/addresses.d.ts.map +1 -0
  93. package/dist/http-client/addresses.js +57 -0
  94. package/dist/http-client/addresses.js.map +1 -0
  95. package/dist/http-client/fake.d.ts +50 -0
  96. package/dist/http-client/fake.d.ts.map +1 -0
  97. package/dist/http-client/fake.js +95 -0
  98. package/dist/http-client/fake.js.map +1 -0
  99. package/dist/http-client/index.d.ts +7 -0
  100. package/dist/http-client/index.d.ts.map +1 -0
  101. package/dist/http-client/index.js +7 -0
  102. package/dist/http-client/index.js.map +1 -0
  103. package/dist/index.d.ts +4 -3
  104. package/dist/index.d.ts.map +1 -1
  105. package/dist/index.js +1 -1
  106. package/dist/index.js.map +1 -1
  107. package/dist/middleware/Pipeline.d.ts.map +1 -1
  108. package/dist/middleware/Pipeline.js +6 -3
  109. package/dist/middleware/Pipeline.js.map +1 -1
  110. package/dist/native/generated.d.ts +93 -36
  111. package/dist/native/generated.d.ts.map +1 -1
  112. package/dist/profiler/Profiler.d.ts.map +1 -1
  113. package/dist/profiler/Profiler.js +4 -1
  114. package/dist/profiler/Profiler.js.map +1 -1
  115. package/dist/profiler/client.generated.d.ts +5 -0
  116. package/dist/profiler/client.generated.d.ts.map +1 -0
  117. package/dist/profiler/client.generated.js +6 -0
  118. package/dist/profiler/client.generated.js.map +1 -0
  119. package/dist/profiler/collectors.d.ts +92 -13
  120. package/dist/profiler/collectors.d.ts.map +1 -1
  121. package/dist/profiler/collectors.js +106 -19
  122. package/dist/profiler/collectors.js.map +1 -1
  123. package/dist/profiler/endpoint.d.ts +2 -1
  124. package/dist/profiler/endpoint.d.ts.map +1 -1
  125. package/dist/profiler/endpoint.js +25 -1
  126. package/dist/profiler/endpoint.js.map +1 -1
  127. package/dist/profiler/index.d.ts +8 -4
  128. package/dist/profiler/index.d.ts.map +1 -1
  129. package/dist/profiler/index.js +11 -4
  130. package/dist/profiler/index.js.map +1 -1
  131. package/dist/profiler/middleware.d.ts.map +1 -1
  132. package/dist/profiler/middleware.js +76 -10
  133. package/dist/profiler/middleware.js.map +1 -1
  134. package/dist/profiler/preview.d.ts +17 -0
  135. package/dist/profiler/preview.d.ts.map +1 -0
  136. package/dist/profiler/preview.js +100 -0
  137. package/dist/profiler/preview.js.map +1 -0
  138. package/dist/profiler/toolbar.d.ts +15 -23
  139. package/dist/profiler/toolbar.d.ts.map +1 -1
  140. package/dist/profiler/toolbar.js +25 -91
  141. package/dist/profiler/toolbar.js.map +1 -1
  142. package/dist/profiler/types.d.ts +6 -1
  143. package/dist/profiler/types.d.ts.map +1 -1
  144. package/dist/router/Router.d.ts +6 -0
  145. package/dist/router/Router.d.ts.map +1 -1
  146. package/dist/router/Router.js +115 -12
  147. package/dist/router/Router.js.map +1 -1
  148. package/dist/rpc/RpcProvider.d.ts +6 -0
  149. package/dist/rpc/RpcProvider.d.ts.map +1 -1
  150. package/dist/rpc/RpcProvider.js +4 -1
  151. package/dist/rpc/RpcProvider.js.map +1 -1
  152. package/dist/rpc/RpcRouter.d.ts +27 -14
  153. package/dist/rpc/RpcRouter.d.ts.map +1 -1
  154. package/dist/rpc/RpcRouter.js +97 -40
  155. package/dist/rpc/RpcRouter.js.map +1 -1
  156. package/dist/scheduler/Scheduler.js +1 -1
  157. package/dist/scheduler/Scheduler.js.map +1 -1
  158. package/dist/scheduler/locks/RedisLockBackend.d.ts.map +1 -1
  159. package/dist/scheduler/locks/RedisLockBackend.js +13 -2
  160. package/dist/scheduler/locks/RedisLockBackend.js.map +1 -1
  161. package/dist/security/CookieSigner.d.ts.map +1 -1
  162. package/dist/security/CookieSigner.js +32 -8
  163. package/dist/security/CookieSigner.js.map +1 -1
  164. package/dist/security/SignedUrl.d.ts.map +1 -1
  165. package/dist/security/SignedUrl.js +16 -19
  166. package/dist/security/SignedUrl.js.map +1 -1
  167. package/dist/server/Server.d.ts +44 -12
  168. package/dist/server/Server.d.ts.map +1 -1
  169. package/dist/server/Server.js +31 -10
  170. package/dist/server/Server.js.map +1 -1
  171. package/dist/server/nativeGrpc.d.ts +27 -0
  172. package/dist/server/nativeGrpc.d.ts.map +1 -0
  173. package/dist/server/nativeGrpc.js +47 -0
  174. package/dist/server/nativeGrpc.js.map +1 -0
  175. package/dist/server/nativeLimits.d.ts +57 -0
  176. package/dist/server/nativeLimits.d.ts.map +1 -0
  177. package/dist/server/nativeLimits.js +75 -0
  178. package/dist/server/nativeLimits.js.map +1 -0
  179. package/dist/session/Session.d.ts +12 -0
  180. package/dist/session/Session.d.ts.map +1 -1
  181. package/dist/session/Session.js +13 -4
  182. package/dist/session/Session.js.map +1 -1
  183. package/dist/session/SessionMiddleware.d.ts.map +1 -1
  184. package/dist/session/SessionMiddleware.js +28 -9
  185. package/dist/session/SessionMiddleware.js.map +1 -1
  186. package/dist/session/config.d.ts +5 -0
  187. package/dist/session/config.d.ts.map +1 -1
  188. package/dist/session/config.js +8 -0
  189. package/dist/session/config.js.map +1 -1
  190. package/dist/session/drivers/MemoryDriver.d.ts.map +1 -1
  191. package/dist/session/drivers/MemoryDriver.js +26 -7
  192. package/dist/session/drivers/MemoryDriver.js.map +1 -1
  193. package/dist/session/errors.d.ts +17 -0
  194. package/dist/session/errors.d.ts.map +1 -1
  195. package/dist/session/errors.js +21 -0
  196. package/dist/session/errors.js.map +1 -1
  197. package/dist/session/templateTags.d.ts +14 -0
  198. package/dist/session/templateTags.d.ts.map +1 -1
  199. package/dist/session/templateTags.js +45 -17
  200. package/dist/session/templateTags.js.map +1 -1
  201. package/dist/storage/StaticMiddleware.d.ts.map +1 -1
  202. package/dist/storage/StaticMiddleware.js +49 -27
  203. package/dist/storage/StaticMiddleware.js.map +1 -1
  204. package/dist/testing/ApiResponse.d.ts.map +1 -1
  205. package/dist/testing/ApiResponse.js +7 -1
  206. package/dist/testing/ApiResponse.js.map +1 -1
  207. package/dist/testing/TestClient.d.ts.map +1 -1
  208. package/dist/testing/TestClient.js +16 -4
  209. package/dist/testing/TestClient.js.map +1 -1
  210. package/dist/utils/Macroable.d.ts +1 -1
  211. package/dist/utils/Macroable.js +2 -2
  212. package/dist/utils/Macroable.js.map +1 -1
  213. package/events.darwin-arm64.node +0 -0
  214. package/events.darwin-x64.node +0 -0
  215. package/events.linux-arm64-gnu.node +0 -0
  216. package/events.linux-x64-gnu.node +0 -0
  217. package/events.win32-x64-msvc.node +0 -0
  218. package/index.darwin-arm64.node +0 -0
  219. package/index.darwin-x64.node +0 -0
  220. package/index.linux-arm64-gnu.node +0 -0
  221. package/index.linux-x64-gnu.node +0 -0
  222. package/index.win32-x64-msvc.node +0 -0
  223. package/package.json +11 -3
  224. package/scheduler.darwin-arm64.node +0 -0
  225. package/scheduler.darwin-x64.node +0 -0
  226. package/scheduler.linux-arm64-gnu.node +0 -0
  227. package/scheduler.linux-x64-gnu.node +0 -0
  228. package/scheduler.win32-x64-msvc.node +0 -0
  229. package/src/Codemods.ts +314 -3
  230. package/src/HttpKernel.ts +18 -7
  231. package/src/Ignitor.ts +58 -26
  232. package/src/bodyparser/BodyParserMiddleware.ts +45 -16
  233. package/src/bodyparser/MultipartFile.ts +46 -67
  234. package/src/bodyparser/parseSize.ts +17 -17
  235. package/src/bodyparser/qsParse.ts +96 -26
  236. package/src/codemods/source.ts +303 -0
  237. package/src/console/prompts.ts +3 -1
  238. package/src/container/Container.ts +97 -81
  239. package/src/events/Emitter.ts +37 -10
  240. package/src/events/helix/helpers.ts +24 -19
  241. package/src/graphql/GraphQLEngine.ts +91 -14
  242. package/src/helpers/MessageBuilder.ts +4 -2
  243. package/src/helpers/errors.ts +16 -0
  244. package/src/helpers/napi-loader.ts +3 -2
  245. package/src/http/Exception.ts +17 -2
  246. package/src/http/HttpContext.ts +34 -5
  247. package/src/http/RedirectBuilder.ts +51 -37
  248. package/src/http/Request.ts +102 -58
  249. package/src/http/Response.ts +15 -7
  250. package/src/http/SseStream.ts +6 -7
  251. package/src/http/permissions.ts +47 -0
  252. package/src/http-client/HttpClient.ts +505 -0
  253. package/src/http-client/addresses.ts +58 -0
  254. package/src/http-client/fake.ts +141 -0
  255. package/src/http-client/index.ts +21 -0
  256. package/src/index.ts +6 -1
  257. package/src/middleware/Pipeline.ts +7 -3
  258. package/src/native/generated.ts +106 -48
  259. package/src/profiler/Profiler.ts +4 -1
  260. package/src/profiler/client/toolbar.css +595 -0
  261. package/src/profiler/client/toolbar.js +1299 -0
  262. package/src/profiler/client.generated.ts +7 -0
  263. package/src/profiler/collectors.ts +156 -19
  264. package/src/profiler/endpoint.ts +27 -1
  265. package/src/profiler/index.ts +17 -3
  266. package/src/profiler/middleware.ts +74 -9
  267. package/src/profiler/preview.ts +104 -0
  268. package/src/profiler/toolbar.ts +28 -91
  269. package/src/profiler/types.ts +6 -1
  270. package/src/router/Router.ts +136 -13
  271. package/src/rpc/RpcProvider.ts +10 -1
  272. package/src/rpc/RpcRouter.ts +129 -45
  273. package/src/scheduler/Scheduler.ts +1 -1
  274. package/src/scheduler/locks/RedisLockBackend.ts +12 -4
  275. package/src/security/CookieSigner.ts +30 -8
  276. package/src/security/SignedUrl.ts +18 -17
  277. package/src/server/Server.ts +60 -12
  278. package/src/server/nativeGrpc.ts +59 -0
  279. package/src/server/nativeLimits.ts +111 -0
  280. package/src/session/Session.ts +29 -4
  281. package/src/session/SessionMiddleware.ts +30 -10
  282. package/src/session/config.ts +7 -0
  283. package/src/session/drivers/MemoryDriver.ts +26 -7
  284. package/src/session/errors.ts +31 -0
  285. package/src/session/templateTags.ts +57 -0
  286. package/src/storage/StaticMiddleware.ts +46 -27
  287. package/src/testing/ApiResponse.ts +7 -1
  288. package/src/testing/TestClient.ts +14 -5
  289. package/src/utils/Macroable.ts +2 -2
  290. package/scripts/build-napi-types.mjs +0 -69
  291. package/scripts/copy-napi.mjs +0 -121
  292. package/scripts/generate-mime.mjs +0 -119
  293. package/scripts/generate-napi-types.mjs +0 -187
@@ -19,11 +19,19 @@ function isMimeType(value) {
19
19
  *
20
20
  * Like AdonisJS MultipartFile:
21
21
  * const avatar = request.file('avatar', { size: '2mb', extnames: ['jpg', 'png'] })
22
- * await avatar.moveToDisk('uploads')
22
+ * await avatar.move(app.makePath('uploads'))
23
+ *
24
+ * Macroable: a package extends every upload at boot, the way a storage
25
+ * package adds `moveToDisk(key, disk?, options?)` to write it to a configured
26
+ * disk. `moveToDisk` is deliberately not defined here, so that macro owns it.
23
27
  */
24
28
  import { randomBytes } from 'node:crypto';
25
29
  import { Readable } from 'node:stream';
26
- export class MultipartFile {
30
+ import { errorCode } from '../helpers/errors.js';
31
+ import { Macroable } from '../utils/Macroable.js';
32
+ import { parseSize } from './parseSize.js';
33
+ import { parseFormFields } from './qsParse.js';
34
+ export class MultipartFile extends Macroable {
27
35
  /** Original filename from the client. */
28
36
  clientName;
29
37
  /**
@@ -105,6 +113,11 @@ export class MultipartFile {
105
113
  filePath;
106
114
  /** The name it was written under, once it has been moved. */
107
115
  fileName;
116
+ /**
117
+ * Free-form data about the file, for whoever moves it: a storage macro
118
+ * records the URL of the stored object here.
119
+ */
120
+ meta = {};
108
121
  /** File size in bytes. */
109
122
  size;
110
123
  /** Raw file content as Buffer. */
@@ -126,6 +139,7 @@ export class MultipartFile {
126
139
  /** Whether the magic-byte pass has run, however it turned out. */
127
140
  #detectionRan = false;
128
141
  constructor(options) {
142
+ super();
129
143
  this.fieldName = options.fieldName;
130
144
  this.clientName = options.clientName;
131
145
  this.headers = { 'content-type': options.type };
@@ -201,8 +215,8 @@ export class MultipartFile {
201
215
  * spells it.
202
216
  */
203
217
  validate(options = this.#validationOptions) {
204
- if (options.size) {
205
- const maxBytes = parseFileSize(options.size);
218
+ if (options.size !== undefined) {
219
+ const maxBytes = parseSize(options.size);
206
220
  if (this.size > maxBytes) {
207
221
  this.errors.push(`File size ${this.size} exceeds limit ${options.size}`);
208
222
  }
@@ -243,33 +257,6 @@ export class MultipartFile {
243
257
  get isValid() {
244
258
  return this.errors.length === 0;
245
259
  }
246
- /**
247
- * Move file to a directory on disk. When `name` is supplied it must be
248
- * a plain filename — no path separators, no `.`/`..` segments. The
249
- * common footgun is passing the client-supplied `clientName` directly
250
- * (`await file.moveToDisk('uploads', file.clientName)`); a malicious
251
- * upload could otherwise traverse out of `directory` via `../../etc/...`.
252
- */
253
- async moveToDisk(directory, name) {
254
- const { mkdirSync, writeFileSync } = await import('node:fs');
255
- const { join } = await import('node:path');
256
- if (name !== undefined && !isSafeFilename(name)) {
257
- throw new Error(`MultipartFile.moveToDisk: 'name' must be a plain filename (no path separators, '.', or '..'). Got: ${JSON.stringify(name)}`);
258
- }
259
- mkdirSync(directory, { recursive: true });
260
- const fileName = name ?? `${randomBytes(16).toString('hex')}.${this.extname}`;
261
- // Defense-in-depth: the default branch interpolates `extname` (derived
262
- // from attacker-controlled `clientName`) into the filename, bypassing
263
- // the `name` guard above. Re-validate the synthesized fileName before
264
- // join to reject a hostile extname (separators, NUL).
265
- if (!isSafeFilename(fileName)) {
266
- throw new Error(`MultipartFile.moveToDisk: derived filename '${fileName}' is unsafe (separator or invalid char in clientName-derived extname).`);
267
- }
268
- const filePath = join(directory, fileName);
269
- writeFileSync(filePath, this.content);
270
- this.markAsMoved(fileName, filePath);
271
- return filePath;
272
- }
273
260
  /**
274
261
  * Write the file into `location` (AdonisJS `move`).
275
262
  *
@@ -278,17 +265,27 @@ export class MultipartFile {
278
265
  * construction), so this writes the buffer. There is therefore no
279
266
  * `E_MISSING_FILE_TMP_PATH`: there is no temporary file to be missing.
280
267
  *
281
- * `overwrite` defaults to true, as upstream. The generated name carries the
282
- * detected extension, and both it and a caller-supplied `name` go through the
283
- * same plain-filename guard {@link moveToDisk} uses — the common footgun is
284
- * passing `file.clientName` straight through.
268
+ * `overwrite` defaults to true, as upstream.
269
+ *
270
+ * NAMED DEVIATION — without `name`, upstream writes under `clientName`, a
271
+ * value the client chose; Ream generates a random name carrying the
272
+ * detected extension, so an upload neither picks its own path nor
273
+ * overwrites another one by sharing its name.
274
+ *
275
+ * A caller-supplied `name` must be a plain filename (no separator, no `.`
276
+ * or `..`): the common footgun is passing `file.clientName` straight
277
+ * through. The generated name is checked too, since its extension comes
278
+ * from the client's filename when the bytes are not recognised.
285
279
  */
286
280
  async move(location, options) {
287
281
  const { mkdir, writeFile } = await import('node:fs/promises');
288
282
  const { join } = await import('node:path');
283
+ if (options?.name !== undefined && !isSafeFilename(options.name)) {
284
+ throw new Error(`MultipartFile.move: 'name' must be a plain filename (no path separators, '.', or '..'). Got: ${JSON.stringify(options.name)}`);
285
+ }
289
286
  const name = options?.name ?? `${randomBytes(16).toString('hex')}.${this.extname || 'unknown'}`;
290
287
  if (!isSafeFilename(name)) {
291
- throw new Error(`MultipartFile.move: 'name' must be a plain filename (no path separators, '.', or '..'). Got: ${JSON.stringify(name)}`);
288
+ throw new Error(`MultipartFile.move: the derived file name ${JSON.stringify(name)} is unsafe (a separator or NUL in the extension of the client's filename).`);
292
289
  }
293
290
  const filePath = join(location, name);
294
291
  await mkdir(location, { recursive: true });
@@ -306,7 +303,7 @@ export class MultipartFile {
306
303
  await writeFile(filePath, this.content, options?.overwrite === false ? { flag: 'wx' } : {});
307
304
  }
308
305
  catch (error) {
309
- if (error.code === 'EEXIST') {
306
+ if (errorCode(error) === 'EEXIST') {
310
307
  throw new Error(`"${name}" already exists at "${location}". Set "overwrite = true" to overwrite it`);
311
308
  }
312
309
  throw error;
@@ -342,23 +339,6 @@ function isSafeFilename(name) {
342
339
  return false;
343
340
  return true;
344
341
  }
345
- function parseFileSize(size) {
346
- const match = size.match(/^(\d+)(kb|mb|gb)?$/i);
347
- if (!match)
348
- return 1024 * 1024;
349
- const [, digits, unit] = match;
350
- const num = parseInt(digits ?? '0', 10);
351
- switch (unit?.toLowerCase()) {
352
- case 'kb':
353
- return num * 1024;
354
- case 'mb':
355
- return num * 1024 * 1024;
356
- case 'gb':
357
- return num * 1024 * 1024 * 1024;
358
- default:
359
- return num;
360
- }
361
- }
362
342
  /**
363
343
  * Hydrate `MultipartFile` instances from the typed payload the Rust
364
344
  * HyperServer attaches to the request. The wire-level parser (multer crate,
@@ -366,10 +346,12 @@ function parseFileSize(size) {
366
346
  * parsing — JS just decodes the base64 envelope and wraps the result.
367
347
  */
368
348
  export function hydrateMultipartPayload(payload) {
369
- const fields = {};
370
- for (const field of payload.fields) {
371
- fields[field.name] = field.value;
372
- }
349
+ // Nested and collected exactly like a urlencoded body: `tags[]` repeated is
350
+ // an array, `user[name]` an object. Flat, a repeated name kept only its
351
+ // last value once a file input was added to the form.
352
+ // The multipart part count is already bounded natively (`maxFields`), so
353
+ // no parameter cap applies on top of it here.
354
+ const fields = parseFormFields(payload.fields, { parameterLimit: Number.POSITIVE_INFINITY });
373
355
  const files = payload.files.map((f) => new MultipartFile({
374
356
  fieldName: f.fieldName,
375
357
  clientName: f.clientName,
@@ -1 +1 @@
1
- {"version":3,"file":"MultipartFile.js","sourceRoot":"","sources":["../../src/bodyparser/MultipartFile.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MultipartFile.js","sourceRoot":"","sources":["../../src/bodyparser/MultipartFile.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,10 @@
1
1
  /**
2
- * Parse a human-readable size string (e.g. '1mb', '512kb', '2gb') to bytes.
3
- * Single source of truth, imported by BodyParserMiddleware (which previously
4
- * carried an identical inline copy — consolidated 2026-06-15).
2
+ * Read a size limit (`'1mb'`, `'50 mb'`, `'1.5kb'`, `1024`) into bytes, with
3
+ * the `bytes` grammar every size option of the body parser accepts.
4
+ *
5
+ * Throws on anything it cannot read, or on a negative size. A silent fallback
6
+ * is what turned `limit: '50 mb'` into a 1 MB cap with no word: a limit the
7
+ * application did not set is worse than a boot that refuses to start.
5
8
  */
6
- export declare function parseSize(size: string): number;
9
+ export declare function parseSize(size: string | number): number;
7
10
  //# sourceMappingURL=parseSize.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parseSize.d.ts","sourceRoot":"","sources":["../../src/bodyparser/parseSize.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAe9C"}
1
+ {"version":3,"file":"parseSize.d.ts","sourceRoot":"","sources":["../../src/bodyparser/parseSize.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CASvD"}
@@ -1,23 +1,18 @@
1
+ import { ReamError } from '../errors/ReamError.js';
2
+ import { parse } from '../helpers/bytes.js';
1
3
  /**
2
- * Parse a human-readable size string (e.g. '1mb', '512kb', '2gb') to bytes.
3
- * Single source of truth, imported by BodyParserMiddleware (which previously
4
- * carried an identical inline copy — consolidated 2026-06-15).
4
+ * Read a size limit (`'1mb'`, `'50 mb'`, `'1.5kb'`, `1024`) into bytes, with
5
+ * the `bytes` grammar every size option of the body parser accepts.
6
+ *
7
+ * Throws on anything it cannot read, or on a negative size. A silent fallback
8
+ * is what turned `limit: '50 mb'` into a 1 MB cap with no word: a limit the
9
+ * application did not set is worse than a boot that refuses to start.
5
10
  */
6
11
  export function parseSize(size) {
7
- const match = size.match(/^(\d+)(kb|mb|gb)?$/i);
8
- if (!match)
9
- return 1024 * 1024; // default 1mb
10
- const [, digits, unit] = match;
11
- const num = parseInt(digits ?? '0', 10);
12
- switch (unit?.toLowerCase()) {
13
- case 'kb':
14
- return num * 1024;
15
- case 'mb':
16
- return num * 1024 * 1024;
17
- case 'gb':
18
- return num * 1024 * 1024 * 1024;
19
- default:
20
- return num;
12
+ const bytes = parse(size);
13
+ if (bytes === null || !Number.isFinite(bytes) || bytes < 0) {
14
+ throw new ReamError('E_BODYPARSER_INVALID_SIZE', `Cannot read the size ${JSON.stringify(size)}: expected a number of bytes or a value such as '512kb', '1.5mb' or '2 gb'.`);
21
15
  }
16
+ return bytes;
22
17
  }
23
18
  //# sourceMappingURL=parseSize.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"parseSize.js","sourceRoot":"","sources":["../../src/bodyparser/parseSize.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAA;IAC/C,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,GAAG,IAAI,CAAA,CAAC,cAAc;IAC7C,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,KAAK,CAAA;IAC9B,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,IAAI,GAAG,EAAE,EAAE,CAAC,CAAA;IACvC,QAAQ,IAAI,EAAE,WAAW,EAAE,EAAE,CAAC;QAC5B,KAAK,IAAI;YACP,OAAO,GAAG,GAAG,IAAI,CAAA;QACnB,KAAK,IAAI;YACP,OAAO,GAAG,GAAG,IAAI,GAAG,IAAI,CAAA;QAC1B,KAAK,IAAI;YACP,OAAO,GAAG,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;QACjC;YACE,OAAO,GAAG,CAAA;IACd,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"parseSize.js","sourceRoot":"","sources":["../../src/bodyparser/parseSize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAE3C;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CAAC,IAAqB;IAC7C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAA;IACzB,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,SAAS,CACjB,2BAA2B,EAC3B,wBAAwB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,6EAA6E,CAC1H,CAAA;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC"}
@@ -11,7 +11,7 @@
11
11
  * dependency it can write in a screenful, and the limits below are easier to
12
12
  * defend when they are visible.
13
13
  *
14
- * Three guards, all of which `qs` also applies:
14
+ * Four guards, all of which `qs` also applies:
15
15
  *
16
16
  * - **Prototype keys are dropped.** `__proto__[x]=1` in a form body is the
17
17
  * classic prototype-pollution vector; the key never reaches an object.
@@ -19,10 +19,13 @@
19
19
  * as a literal key rather than allocating unbounded nesting.
20
20
  * - **Parameter count is capped** (`qs` defaults to 1000), so a body of a
21
21
  * million `a[0]`, `a[1]`… cannot be turned into a million-entry object.
22
+ * - **Explicit array indices are capped** (`qs` `arrayLimit`, default 20).
23
+ * A larger index is an object key, so `ids[4294967294]=1` stays one entry.
22
24
  */
23
25
  /** `qs` defaults, reproduced so the behaviour is the same out of the box. */
24
26
  export declare const DEFAULT_DEPTH = 5;
25
27
  export declare const DEFAULT_PARAMETER_LIMIT = 1000;
28
+ export declare const DEFAULT_ARRAY_LIMIT = 20;
26
29
  export interface QsParseOptions {
27
30
  /**
28
31
  * Treat `user.name` as `user[name]`. AdonisJS forces this ON for form
@@ -32,6 +35,12 @@ export interface QsParseOptions {
32
35
  allowDots?: boolean;
33
36
  depth?: number;
34
37
  parameterLimit?: number;
38
+ /**
39
+ * Highest explicit index + 1 that still builds an array (`qs` defaults to
40
+ * 20). `ids[25]=x` becomes `{ ids: { '25': 'x' } }`, so a 16-byte request
41
+ * cannot allocate a 100-million-slot array.
42
+ */
43
+ arrayLimit?: number;
35
44
  /** Turn `''` into `null`, as AdonisJS' `convertEmptyStringsToNull` does. */
36
45
  convertEmptyStringsToNull?: boolean;
37
46
  /** Trim surrounding whitespace, as AdonisJS' `trimWhitespaces` does. */
@@ -49,4 +58,14 @@ export interface QsParseOptions {
49
58
  export declare function decodeFormComponent(value: string): string;
50
59
  /** Parse a urlencoded body into a nested object. */
51
60
  export declare function parseQueryString(body: string, options?: QsParseOptions): Record<string, unknown>;
61
+ /**
62
+ * Nest form fields that arrive as decoded name/value pairs — a multipart
63
+ * body's text parts — with the key grammar and the guards of a urlencoded
64
+ * body. A `<select multiple name="tags[]">` keeps every value, and
65
+ * `user[name]` nests, whether or not the form also carries a file input.
66
+ */
67
+ export declare function parseFormFields(fields: Iterable<{
68
+ name: string;
69
+ value: string;
70
+ }>, options?: QsParseOptions): Record<string, unknown>;
52
71
  //# sourceMappingURL=qsParse.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"qsParse.d.ts","sourceRoot":"","sources":["../../src/bodyparser/qsParse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,6EAA6E;AAC7E,eAAO,MAAM,aAAa,IAAI,CAAA;AAC9B,eAAO,MAAM,uBAAuB,OAAO,CAAA;AAE3C,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,4EAA4E;IAC5E,yBAAyB,CAAC,EAAE,OAAO,CAAA;IACnC,wEAAwE;IACxE,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B;AA4FD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOzD;AAED,oDAAoD;AACpD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,cAAmB,GAC3B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAwBzB"}
1
+ {"version":3,"file":"qsParse.d.ts","sourceRoot":"","sources":["../../src/bodyparser/qsParse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,6EAA6E;AAC7E,eAAO,MAAM,aAAa,IAAI,CAAA;AAC9B,eAAO,MAAM,uBAAuB,OAAO,CAAA;AAC3C,eAAO,MAAM,mBAAmB,KAAK,CAAA;AAErC,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,4EAA4E;IAC5E,yBAAyB,CAAC,EAAE,OAAO,CAAA;IACnC,wEAAwE;IACxE,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B;AAyID;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOzD;AAED,oDAAoD;AACpD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,cAAmB,GAC3B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAczB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,EACjD,OAAO,GAAE,cAAmB,GAC3B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAezB"}
@@ -11,7 +11,7 @@
11
11
  * dependency it can write in a screenful, and the limits below are easier to
12
12
  * defend when they are visible.
13
13
  *
14
- * Three guards, all of which `qs` also applies:
14
+ * Four guards, all of which `qs` also applies:
15
15
  *
16
16
  * - **Prototype keys are dropped.** `__proto__[x]=1` in a form body is the
17
17
  * classic prototype-pollution vector; the key never reaches an object.
@@ -19,10 +19,13 @@
19
19
  * as a literal key rather than allocating unbounded nesting.
20
20
  * - **Parameter count is capped** (`qs` defaults to 1000), so a body of a
21
21
  * million `a[0]`, `a[1]`… cannot be turned into a million-entry object.
22
+ * - **Explicit array indices are capped** (`qs` `arrayLimit`, default 20).
23
+ * A larger index is an object key, so `ids[4294967294]=1` stays one entry.
22
24
  */
23
25
  /** `qs` defaults, reproduced so the behaviour is the same out of the box. */
24
26
  export const DEFAULT_DEPTH = 5;
25
27
  export const DEFAULT_PARAMETER_LIMIT = 1000;
28
+ export const DEFAULT_ARRAY_LIMIT = 20;
26
29
  /** Keys that must never be written onto an object. */
27
30
  const FORBIDDEN_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
28
31
  /**
@@ -60,14 +63,42 @@ function splitKey(key, depth, allowDots) {
60
63
  function isIndex(segment) {
61
64
  return /^\d+$/.test(segment);
62
65
  }
63
- /** Assign `value` at `segments` inside `target`, creating containers as needed. */
64
- function assign(target, segments, value) {
66
+ function isContainer(value) {
67
+ return typeof value === 'object' && value !== null;
68
+ }
69
+ /** `{ '0': a, '1': b }` from `[a, b]`, holes left out — what `qs` produces on overflow. */
70
+ function arrayToObject(array) {
71
+ const object = {};
72
+ array.forEach((item, index) => {
73
+ object[String(index)] = item;
74
+ });
75
+ return object;
76
+ }
77
+ /**
78
+ * Assign `value` at `segments` inside `target`, creating containers as needed.
79
+ *
80
+ * An explicit index at or above `arrayLimit` never addresses an array: the
81
+ * container becomes (or is converted into) an object keyed by that index,
82
+ * as `qs` does. Without it, `ids[100000000]=1` allocates a sparse array whose
83
+ * iteration or serialisation blocks the event loop for seconds. Appends
84
+ * (`tags[]`, a repeated key) stay arrays — each one costs a parameter, so
85
+ * `parameterLimit` already bounds them, and a long checkbox group keeps the
86
+ * shape its handler expects (`qs` turns those into objects past the limit).
87
+ */
88
+ function assign(target, segments, value, arrayLimit) {
65
89
  let cursor = target;
90
+ // Swaps `cursor` inside its parent when an array has to become an object.
91
+ let replace = () => { };
66
92
  for (let i = 0; i < segments.length; i++) {
67
93
  const segment = segments[i] ?? '';
68
94
  const last = i === segments.length - 1;
69
95
  if (FORBIDDEN_KEYS.has(segment))
70
96
  return;
97
+ if (Array.isArray(cursor) && isIndex(segment) && Number(segment) >= arrayLimit) {
98
+ const converted = arrayToObject(cursor);
99
+ replace(converted);
100
+ cursor = converted;
101
+ }
71
102
  if (last) {
72
103
  if (segment === '') {
73
104
  // `tags[]` — append.
@@ -94,23 +125,29 @@ function assign(target, segments, value) {
94
125
  return;
95
126
  }
96
127
  const nextSegment = segments[i + 1] ?? '';
97
- const wantsArray = nextSegment === '' || isIndex(nextSegment);
128
+ const wantsArray = nextSegment === '' || (isIndex(nextSegment) && Number(nextSegment) < arrayLimit);
98
129
  if (Array.isArray(cursor)) {
99
130
  if (!isIndex(segment))
100
131
  return;
132
+ const array = cursor;
101
133
  const index = Number(segment);
102
- const existing = cursor[index];
103
- if (existing === undefined || typeof existing !== 'object' || existing === null) {
104
- cursor[index] = wantsArray ? [] : {};
105
- }
106
- cursor = cursor[index];
134
+ const existing = array[index];
135
+ const child = isContainer(existing) ? existing : wantsArray ? [] : {};
136
+ array[index] = child;
137
+ replace = (next) => {
138
+ array[index] = next;
139
+ };
140
+ cursor = child;
107
141
  continue;
108
142
  }
109
- const existing = cursor[segment];
110
- if (existing === undefined || typeof existing !== 'object' || existing === null) {
111
- cursor[segment] = wantsArray ? [] : {};
112
- }
113
- cursor = cursor[segment];
143
+ const object = cursor;
144
+ const existing = object[segment];
145
+ const child = isContainer(existing) ? existing : wantsArray ? [] : {};
146
+ object[segment] = child;
147
+ replace = (next) => {
148
+ object[segment] = next;
149
+ };
150
+ cursor = child;
114
151
  }
115
152
  }
116
153
  /**
@@ -133,28 +170,44 @@ export function decodeFormComponent(value) {
133
170
  }
134
171
  /** Parse a urlencoded body into a nested object. */
135
172
  export function parseQueryString(body, options = {}) {
136
- const depth = options.depth ?? DEFAULT_DEPTH;
137
- const parameterLimit = options.parameterLimit ?? DEFAULT_PARAMETER_LIMIT;
138
- const result = {};
139
173
  if (!body)
140
- return result;
141
- const pairs = body.split('&');
142
- let seen = 0;
143
- for (const pair of pairs) {
174
+ return {};
175
+ const parameterLimit = options.parameterLimit ?? DEFAULT_PARAMETER_LIMIT;
176
+ const fields = [];
177
+ for (const pair of body.split('&')) {
144
178
  if (!pair)
145
179
  continue;
146
- if (++seen > parameterLimit)
180
+ // Nothing past the limit is even decoded.
181
+ if (fields.length >= parameterLimit)
147
182
  break;
148
183
  const eqIdx = pair.indexOf('=');
149
184
  const rawKey = eqIdx === -1 ? pair : pair.slice(0, eqIdx);
150
185
  const rawValue = eqIdx === -1 ? '' : pair.slice(eqIdx + 1);
151
- const key = decodeFormComponent(rawKey);
152
- let value = decodeFormComponent(rawValue);
186
+ fields.push({ name: decodeFormComponent(rawKey), value: decodeFormComponent(rawValue) });
187
+ }
188
+ return parseFormFields(fields, options);
189
+ }
190
+ /**
191
+ * Nest form fields that arrive as decoded name/value pairs — a multipart
192
+ * body's text parts — with the key grammar and the guards of a urlencoded
193
+ * body. A `<select multiple name="tags[]">` keeps every value, and
194
+ * `user[name]` nests, whether or not the form also carries a file input.
195
+ */
196
+ export function parseFormFields(fields, options = {}) {
197
+ const depth = options.depth ?? DEFAULT_DEPTH;
198
+ const parameterLimit = options.parameterLimit ?? DEFAULT_PARAMETER_LIMIT;
199
+ const arrayLimit = options.arrayLimit ?? DEFAULT_ARRAY_LIMIT;
200
+ const result = {};
201
+ let seen = 0;
202
+ for (const field of fields) {
203
+ if (++seen > parameterLimit)
204
+ break;
205
+ let value = field.value;
153
206
  if (options.trimWhitespaces && typeof value === 'string')
154
207
  value = value.trim();
155
208
  if (options.convertEmptyStringsToNull && value === '')
156
209
  value = null;
157
- assign(result, splitKey(key, depth, options.allowDots ?? true), value);
210
+ assign(result, splitKey(field.name, depth, options.allowDots ?? true), value, arrayLimit);
158
211
  }
159
212
  return result;
160
213
  }
@@ -1 +1 @@
1
- {"version":3,"file":"qsParse.js","sourceRoot":"","sources":["../../src/bodyparser/qsParse.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"qsParse.js","sourceRoot":"","sources":["../../src/bodyparser/qsParse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Just enough of a TypeScript scanner for the configure codemods: find a
3
+ * call or an object/array literal in CODE (never inside a string, a template
4
+ * or a comment), split a literal into its top-level entries, and append to
5
+ * one. Upstream does this with a full AST; ream ships no compiler, and the
6
+ * files these codemods edit (`start/env.ts`, `reamrc.ts`) are object and
7
+ * array literals.
8
+ *
9
+ * Not handled: regular-expression literals (a quote inside one reads as the
10
+ * start of a string). Neither file has a reason to contain one.
11
+ */
12
+ /** Index of the bracket closing the one at `open`, or -1. */
13
+ export declare function matchClose(src: string, open: number): number;
14
+ /** One top-level entry of a literal: the text between two commas. */
15
+ export interface Segment {
16
+ start: number;
17
+ end: number;
18
+ /** First code character, or `end` when the entry is only trivia. */
19
+ codeStart: number;
20
+ /** Just past the last code character (comments and whitespace excluded). */
21
+ codeEnd: number;
22
+ }
23
+ /** Split `src[start, end)` on its top-level commas. */
24
+ export declare function segments(src: string, start: number, end: number): Segment[];
25
+ /**
26
+ * Whether `code` is one complete expression that cannot reach outside the
27
+ * slot it is written into: brackets balanced and never closing past where
28
+ * they opened, strings and comments terminated, no top-level comma.
29
+ */
30
+ export declare function isSingleExpression(code: string): boolean;
31
+ /**
32
+ * Index of the `(` of the first call to `callee` in code, or -1. A mention
33
+ * inside a string or a comment, or as the tail of a longer name
34
+ * (`MyEnv.create`), does not count.
35
+ */
36
+ export declare function findCall(src: string, callee: string): number;
37
+ /** Index of the `{` after the first `export default` in code, or -1. */
38
+ export declare function findExportDefaultObject(src: string): number;
39
+ /** A `key: value` entry of an object literal. */
40
+ export interface Property {
41
+ key: string;
42
+ valueStart: number;
43
+ valueEnd: number;
44
+ }
45
+ /** The `key: value` entries of the object literal opening at `open`. */
46
+ export declare function properties(src: string, open: number, close: number): Property[];
47
+ /**
48
+ * Append entries to the literal `src[open..close]` and return the new text.
49
+ *
50
+ * `build` receives the indentation of the existing entries (or one level
51
+ * deeper than the closing bracket when there are none) and returns the lines
52
+ * to add, each already ending with its comma. `blankLine` separates the new
53
+ * entries from existing ones. A missing comma after the last existing entry
54
+ * is added.
55
+ */
56
+ export declare function appendToLiteral(src: string, open: number, close: number, eol: string, build: (indent: string) => string[], blankLine?: boolean): string;
57
+ //# sourceMappingURL=source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../src/codemods/source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAuDH,6DAA6D;AAC7D,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAwB5D;AAoBD,qEAAqE;AACrE,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,oEAAoE;IACpE,SAAS,EAAE,MAAM,CAAA;IACjB,4EAA4E;IAC5E,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,uDAAuD;AACvD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,EAAE,CAoC3E;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAsBxD;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAgB5D;AAED,wEAAwE;AACxE,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAkB3D;AAED,iDAAiD;AACjD,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAA;IACX,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,wEAAwE;AACxE,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ,EAAE,CAY/E;AAQD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,EAAE,EACnC,SAAS,UAAQ,GAChB,MAAM,CA0BR"}