temba 0.43.0 → 0.45.0

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 (86) hide show
  1. package/README.md +55 -32
  2. package/config/index.d.ts +0 -1
  3. package/config/index.d.ts.map +1 -1
  4. package/config/index.js +1 -1
  5. package/config/index.js.map +1 -1
  6. package/index.d.ts +2 -2
  7. package/index.d.ts.map +1 -1
  8. package/index.js +20 -32
  9. package/index.js.map +1 -1
  10. package/openapi/html.d.ts +2 -0
  11. package/openapi/html.d.ts.map +1 -0
  12. package/openapi/html.js +14 -0
  13. package/openapi/html.js.map +1 -0
  14. package/openapi/index.d.ts +5 -0
  15. package/openapi/index.d.ts.map +1 -0
  16. package/openapi/index.js +37 -0
  17. package/openapi/index.js.map +1 -0
  18. package/openapi/spec.d.ts +8 -0
  19. package/openapi/spec.d.ts.map +1 -0
  20. package/openapi/spec.js +518 -0
  21. package/openapi/spec.js.map +1 -0
  22. package/package.json +11 -11
  23. package/requestHandlers/delete.d.ts +2 -2
  24. package/requestHandlers/delete.js +8 -8
  25. package/requestHandlers/delete.js.map +1 -1
  26. package/requestHandlers/get.d.ts +13 -7
  27. package/requestHandlers/get.d.ts.map +1 -1
  28. package/requestHandlers/get.js +7 -7
  29. package/requestHandlers/get.js.map +1 -1
  30. package/requestHandlers/index.d.ts +40 -18
  31. package/requestHandlers/index.d.ts.map +1 -1
  32. package/requestHandlers/index.js +2 -2
  33. package/requestHandlers/index.js.map +1 -1
  34. package/requestHandlers/patch.d.ts +9 -2
  35. package/requestHandlers/patch.d.ts.map +1 -1
  36. package/requestHandlers/patch.js +10 -7
  37. package/requestHandlers/patch.js.map +1 -1
  38. package/requestHandlers/post.d.ts +5 -3
  39. package/requestHandlers/post.d.ts.map +1 -1
  40. package/requestHandlers/post.js +6 -6
  41. package/requestHandlers/post.js.map +1 -1
  42. package/requestHandlers/put.d.ts +9 -2
  43. package/requestHandlers/put.d.ts.map +1 -1
  44. package/requestHandlers/put.js +10 -7
  45. package/requestHandlers/put.js.map +1 -1
  46. package/requestHandlers/types.d.ts +4 -12
  47. package/requestHandlers/types.d.ts.map +1 -1
  48. package/requestHandlers/utils.d.ts +4 -1
  49. package/requestHandlers/utils.d.ts.map +1 -1
  50. package/requestHandlers/utils.js.map +1 -1
  51. package/requestInterceptor/interceptRequest.d.ts +6 -5
  52. package/requestInterceptor/interceptRequest.d.ts.map +1 -1
  53. package/requestInterceptor/interceptRequest.js +8 -8
  54. package/requestInterceptor/interceptRequest.js.map +1 -1
  55. package/requestInterceptor/types.d.ts +9 -7
  56. package/requestInterceptor/types.d.ts.map +1 -1
  57. package/resourceHandler.d.ts +2 -7
  58. package/resourceHandler.d.ts.map +1 -1
  59. package/resourceHandler.js +17 -48
  60. package/resourceHandler.js.map +1 -1
  61. package/responseHandler.d.ts +13 -0
  62. package/responseHandler.d.ts.map +1 -0
  63. package/responseHandler.js +39 -0
  64. package/responseHandler.js.map +1 -0
  65. package/root/html.d.ts +8 -0
  66. package/root/html.d.ts.map +1 -0
  67. package/root/html.js +48 -0
  68. package/root/html.js.map +1 -0
  69. package/root/root.d.ts +4 -0
  70. package/root/root.d.ts.map +1 -0
  71. package/root/root.js +37 -0
  72. package/root/root.js.map +1 -0
  73. package/schema/compile.js +10 -11
  74. package/schema/compile.js.map +1 -1
  75. package/schema/validate.d.ts +2 -1
  76. package/schema/validate.d.ts.map +1 -1
  77. package/schema/validate.js.map +1 -1
  78. package/staticFolder/staticFolder.d.ts +3 -5
  79. package/staticFolder/staticFolder.d.ts.map +1 -1
  80. package/staticFolder/staticFolder.js +15 -18
  81. package/staticFolder/staticFolder.js.map +1 -1
  82. package/version.js +1 -1
  83. package/openapi/openapi.d.ts +0 -6
  84. package/openapi/openapi.d.ts.map +0 -1
  85. package/openapi/openapi.js +0 -476
  86. package/openapi/openapi.js.map +0 -1
package/README.md CHANGED
@@ -10,11 +10,13 @@
10
10
 
11
11
  **Get a simple REST API with zero coding in less than 30 seconds (seriously).**
12
12
 
13
- For developers that need a quick NodeJS backend for small projects.
13
+ For developers that need a **quick NodeJS backend** for small projects.
14
14
 
15
- No need for any coding, unless you want to opt-out of the defaults, or want to do more customization.
15
+ **No need for any coding**, unless you want to opt-out of the defaults, or want to do more customization.
16
16
 
17
- Data is kept in memory, but you can also store it in a JSON file or MongoDB database.
17
+ An **OpenAPI specification** is generated and enabled by default, providing **interactive documentation** and allowing you to generate client code from it.
18
+
19
+ Data is kept **in memory**, but you can also store it in a **JSON file** or **MongoDB database**.
18
20
 
19
21
  ## Table of contents
20
22
 
@@ -68,6 +70,8 @@ You’ll see:
68
70
 
69
71
  Now you can send any HTTP request to any resource on localhost:3000 — and it just works.
70
72
 
73
+ Or headover to the interactive OpenAPI specification of your API in your browser at `/openapi`.
74
+
71
75
  ### Adding to an existing app
72
76
 
73
77
  Alternatively, add Temba to your app manually:
@@ -78,7 +82,7 @@ Alternatively, add Temba to your app manually:
78
82
 
79
83
  ```js
80
84
  import { create } from "temba"
81
- const server = create()
85
+ const server = await create()
82
86
  server.start()
83
87
  ```
84
88
 
@@ -141,7 +145,7 @@ By default data is stored in memory. This means the data is flushed when the ser
141
145
  const config = {
142
146
  connectionString: 'data.json',
143
147
  }
144
- const server = create(config)
148
+ const server = await create(config)
145
149
  ```
146
150
 
147
151
  All resources are saved in a single JSON file. The file is not created or updated unless you create, update, or delete resources.
@@ -152,11 +156,30 @@ All resources are saved in a single JSON file. The file is not created or update
152
156
  const config = {
153
157
  connectionString: 'mongodb://localhost:27017/myDatabase',
154
158
  }
155
- const server = create(config)
159
+ const server = await create(config)
156
160
  ```
157
161
 
158
162
  For every resource you use in your requests, a collection is created in the database. However, not until you actually create a resource with a `POST`.
159
163
 
164
+ ### OpenAPI specification
165
+
166
+ OpenAPI support in Temba is enabled by default, automatically generating both JSON and YAML specifications that accurately reflect your configured resources and settings.
167
+
168
+ Alongside these specs, Temba serves interactive HTML documentation (i.e. Swagger UI) out of the box.
169
+
170
+ OpenAPI support is controlled through the `openapi` setting, which accepts two forms:
171
+
172
+ * **Boolean**
173
+
174
+ * `true` (default) enables OpenAPI support.
175
+ * `false` disables it completely.
176
+
177
+ * **Object**
178
+
179
+ * Supplying an object both enables OpenAPI **and** lets you customize the spec.
180
+ * The object must adhere to the `OpenAPIObject` interface (see [openapi3-ts model](https://github.com/metadevpro/openapi3-ts/blob/71b55d772bacc58c127540b6a75d1b17a7ddadbb/src/model/openapi31.ts)).
181
+ * Temba will deep-merge your custom specification into its default spec, preserving all auto-generated endpoints and schemas while applying your overrides.
182
+
160
183
  ### Allowing specific resources only
161
184
 
162
185
  If you only want to allow specific resource names, configure them by providing a `resources` key in the config object when creating the Temba server:
@@ -165,7 +188,7 @@ If you only want to allow specific resource names, configure them by providing a
165
188
  const config = {
166
189
  resources: ['movies', 'actors'],
167
190
  }
168
- const server = create(config)
191
+ const server = await create(config)
169
192
  ```
170
193
 
171
194
  Requests on these resources only give a `404 Not Found` if the ID does not exist. Requests on any other resource will always return a `404 Not Found`.
@@ -178,12 +201,10 @@ With the `apiPrefix` config setting, all resources get an extra path segment in
178
201
  const config = {
179
202
  apiPrefix: 'api',
180
203
  }
181
- const server = create(config)
204
+ const server = await create(config)
182
205
  ```
183
206
 
184
- A request to the `apiPrefix` (e.g. http://localhost:1234/api) will now return the `"It works! ツ"` response message.
185
-
186
- After configuring the `apiPrefix`, requests to the root URL (e.g. http://localhost:1234/), instead of the `"It works! ツ"` response message, will now either return a `404 Not Found` on `GET` requests, or a `405 Method Not Allowed` for any other HTTP method.
207
+ After configuring the `apiPrefix`, requests to the root URL (e.g. http://localhost:1234/), will now either return a `404 Not Found` on `GET` requests, or a `405 Method Not Allowed` for any other HTTP method.
187
208
 
188
209
  ### Static assets
189
210
 
@@ -193,7 +214,7 @@ If you want to host static assets, for example a web app consuming the API, you
193
214
  const config = {
194
215
  staticFolder: 'build',
195
216
  }
196
- const server = create(config)
217
+ const server = await create(config)
197
218
  ```
198
219
 
199
220
  With this setting, sending a `GET` request to the root URL, returns the content that is in the `'./build'` folder in your project, for example an HTML page.
@@ -247,7 +268,7 @@ const config = {
247
268
  },
248
269
  }
249
270
 
250
- const server = create(config)
271
+ const server = await create(config)
251
272
  ```
252
273
 
253
274
  If a request is not valid according to the schema, a `400 Bad Request` response is returned, and a message in the response body indicating the validation error.
@@ -279,7 +300,7 @@ const config = {
279
300
  },
280
301
  }
281
302
 
282
- const server = create(config)
303
+ const server = await create(config)
283
304
  ```
284
305
 
285
306
  The `requestInterceptor` is an object with fields for each of the HTTP methods you might want to intercept, and the callback function you want Temba to call, before processing the request, i.e. going to the database.
@@ -319,7 +340,7 @@ const config = {
319
340
  },
320
341
  }
321
342
 
322
- const server = create(config)
343
+ const server = await create(config)
323
344
  ```
324
345
 
325
346
  ### Response body interception
@@ -349,7 +370,7 @@ const config = {
349
370
  },
350
371
  }
351
372
 
352
- const server = create(config)
373
+ const server = await create(config)
353
374
  ```
354
375
 
355
376
  `responseBodyInterceptor` is a callback function that provides an object containing the `resource`, `body`, and the `id`. Depending on whether it's a collection or item request, the `body` is either an array or object, and the `id` can be `undefined`.
@@ -370,7 +391,7 @@ To optimize `GET` requests, and only send JSON over the wire when it changed, yo
370
391
  const config = {
371
392
  etags: true,
372
393
  }
373
- const server = create(config)
394
+ const server = await create(config)
374
395
  ```
375
396
 
376
397
  After enabling etags, every `GET` request will return an `etag` response header, which clients can (optionally) send as an `If-None-Match` header with every subsequent `GET` request. Only if the resource changed in the meantime the server will return the new JSON, and otherwise it will return a `304 Not Modified` response with an empty response body.
@@ -390,6 +411,7 @@ const config = {
390
411
  connectionString: 'mongodb://localhost:27017/myDatabase',
391
412
  delay: 500,
392
413
  etags: true,
414
+ openapi: true,
393
415
  port: 4321,
394
416
  requestInterceptor: {
395
417
  get: ({ headers, resource, id }) => {
@@ -426,25 +448,26 @@ const config = {
426
448
  },
427
449
  staticFolder: 'build',
428
450
  }
429
- const server = create(config)
451
+ const server = await create(config)
430
452
  ```
431
453
 
432
454
  These are all the possible settings:
433
455
 
434
- | Config setting | Description | Default value |
435
- | :------------------------ | :----------------------------------------------------------------------------------------- | :------------ |
436
- | `allowDeleteCollection` | Whether a `DELETE` request on a collection is allowed to delete all items. | `false` |
437
- | `apiPrefix` | See [API prefix](#api-prefix) | `null` | `'api'` |
438
- | `connectionString` | See [Data persistency](#data-persistency) | `null` |
439
- | `delay` | The delay, in milliseconds, after processing the request before sending the response. | `0` |
440
- | `etags` | See [Caching and consistency with Etags](#caching-and-consistency-with-etags) | `false` |
441
- | `port` | The port your Temba server listens on | `3000` |
442
- | `requestInterceptor` | See [Request validation or mutation](#request-validation-or-mutation) | `noop` |
443
- | `resources` | See [Allowing specific resources only](#allowing-specific-resources-only) | `[]` |
444
- | `responseBodyInterceptor` | See [Response body interception](#response-body-interception) | `noop` |
445
- | `returnNullFields` | Whether fields with a null value should be returned in responses. | `true` |
446
- | `schema` | See [JSON Schema request body validation](#json-schema-request-body-validation) | `null` |
447
- | `staticFolder` | See [Static assets](#static-assets) | `null` |
456
+ | Config setting | Description | Default value |
457
+ | :------------------------ | :------------------------------------------------------------------------------------------- | :--------------- |
458
+ | `allowDeleteCollection` | Whether a `DELETE` request on a collection is allowed to delete all items. | `false` |
459
+ | `apiPrefix` | See [API prefix](#api-prefix) | `null` | `'api'` |
460
+ | `connectionString` | See [Data persistency](#data-persistency) | `null` |
461
+ | `delay` | The delay, in milliseconds, after processing the request before sending the response. | `0` |
462
+ | `etags` | See [Caching and consistency with Etags](#caching-and-consistency-with-etags) | `false` |
463
+ | `openapi` | Enable or disable OpenAPI, or supply your custom spec object to merge into the default spec. | `true` |
464
+ | `port` | The port your Temba server listens on | `3000` |
465
+ | `requestInterceptor` | See [Request validation or mutation](#request-validation-or-mutation) | `noop` |
466
+ | `resources` | See [Allowing specific resources only](#allowing-specific-resources-only) | `[]` |
467
+ | `responseBodyInterceptor` | See [Response body interception](#response-body-interception) | `noop` |
468
+ | `returnNullFields` | Whether fields with a null value should be returned in responses. | `true` |
469
+ | `schema` | See [JSON Schema request body validation](#json-schema-request-body-validation) | `null` |
470
+ | `staticFolder` | See [Static assets](#static-assets) | `null` |
448
471
 
449
472
  ## Under the hood
450
473
 
package/config/index.d.ts CHANGED
@@ -29,7 +29,6 @@ export type Config = {
29
29
  implementations: Implementations | null;
30
30
  };
31
31
  export type ConfigKey = keyof Config;
32
- export type RouterConfig = Pick<Config, 'validateResources' | 'resources' | 'apiPrefix' | 'requestInterceptor' | 'responseBodyInterceptor' | 'returnNullFields' | 'allowDeleteCollection' | 'etagsEnabled'>;
33
32
  export type UserConfig = {
34
33
  resources?: Resources;
35
34
  staticFolder?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AACrE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAA;AAC/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAEzD,KAAK,YAAY,GAAG,MAAM,CAAA;AAE1B,KAAK,gBAAgB,GAAG;IACtB,YAAY,EAAE,YAAY,CAAA;IAC1B,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,KAAK,SAAS,GAAG,CAAC,YAAY,GAAG,gBAAgB,CAAC,EAAE,CAAA;AAEpD,KAAK,aAAa,GAAG,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAEtD,MAAM,MAAM,MAAM,GAAG;IACnB,iBAAiB,EAAE,OAAO,CAAA;IAC1B,SAAS,EAAE,SAAS,CAAA;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,kBAAkB,EAAE,kBAAkB,GAAG,IAAI,CAAA;IAC7C,uBAAuB,EAAE,uBAAuB,GAAG,IAAI,CAAA;IACvD,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,gBAAgB,EAAE,OAAO,CAAA;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAAA;IACjC,qBAAqB,EAAE,OAAO,CAAA;IAC9B,YAAY,EAAE,OAAO,CAAA;IACrB,OAAO,EAAE,aAAa,CAAA;IAEtB,SAAS,EAAE,OAAO,CAAA;IAClB,eAAe,EAAE,eAAe,GAAG,IAAI,CAAA;CACxC,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,MAAM,CAAA;AAEpC,MAAM,MAAM,YAAY,GAAG,IAAI,CAC7B,MAAM,EACJ,mBAAmB,GACnB,WAAW,GACX,WAAW,GACX,oBAAoB,GACpB,yBAAyB,GACzB,kBAAkB,GAClB,uBAAuB,GACvB,cAAc,CACjB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,kBAAkB,CAAC,EAAE,kBAAkB,CAAA;IACvC,uBAAuB,CAAC,EAAE,uBAAuB,CAAA;IACjD,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,iBAAiB,CAAA;IAC3B,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,OAAO,CAAC,EAAE,aAAa,CAAA;IAGvB,SAAS,CAAC,EAAE,OAAO,CAAA;IAEnB,eAAe,CAAC,EAAE,eAAe,CAAA;CAClC,CAAA;AAsBD,eAAO,MAAM,UAAU,GAAI,aAAa,UAAU,KAAG,MA4GpD,CAAA;AAED,eAAO,MAAM,WAAW,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,SAAyC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AACrE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAA;AAC/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAEzD,KAAK,YAAY,GAAG,MAAM,CAAA;AAE1B,KAAK,gBAAgB,GAAG;IACtB,YAAY,EAAE,YAAY,CAAA;IAC1B,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,KAAK,SAAS,GAAG,CAAC,YAAY,GAAG,gBAAgB,CAAC,EAAE,CAAA;AAEpD,KAAK,aAAa,GAAG,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAEtD,MAAM,MAAM,MAAM,GAAG;IACnB,iBAAiB,EAAE,OAAO,CAAA;IAC1B,SAAS,EAAE,SAAS,CAAA;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,kBAAkB,EAAE,kBAAkB,GAAG,IAAI,CAAA;IAC7C,uBAAuB,EAAE,uBAAuB,GAAG,IAAI,CAAA;IACvD,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,gBAAgB,EAAE,OAAO,CAAA;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAAA;IACjC,qBAAqB,EAAE,OAAO,CAAA;IAC9B,YAAY,EAAE,OAAO,CAAA;IACrB,OAAO,EAAE,aAAa,CAAA;IAEtB,SAAS,EAAE,OAAO,CAAA;IAClB,eAAe,EAAE,eAAe,GAAG,IAAI,CAAA;CACxC,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,MAAM,CAAA;AAEpC,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,kBAAkB,CAAC,EAAE,kBAAkB,CAAA;IACvC,uBAAuB,CAAC,EAAE,uBAAuB,CAAA;IACjD,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,iBAAiB,CAAA;IAC3B,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,OAAO,CAAC,EAAE,aAAa,CAAA;IAGvB,SAAS,CAAC,EAAE,OAAO,CAAA;IAEnB,eAAe,CAAC,EAAE,eAAe,CAAA;CAClC,CAAA;AAsBD,eAAO,MAAM,UAAU,GAAI,aAAa,UAAU,KAAG,MA4GpD,CAAA;AAED,eAAO,MAAM,WAAW,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,SAAyC,CAAA"}
package/config/index.js CHANGED
@@ -12,7 +12,7 @@ const defaultConfig = {
12
12
  schemas: null,
13
13
  allowDeleteCollection: false,
14
14
  etagsEnabled: false,
15
- openapi: false,
15
+ openapi: true,
16
16
  isTesting: false,
17
17
  implementations: null,
18
18
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/config/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/config/index.ts"],"names":[],"mappings":"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"}
package/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { type UserConfig } from './config/index.js';
2
2
  import type { IncomingMessage, ServerResponse } from 'http';
3
3
  import { TembaError as TembaErrorInternal } from './requestInterceptor/TembaError.js';
4
- export declare const create: (userConfig?: UserConfig) => {
4
+ export declare const create: (userConfig?: UserConfig) => Promise<{
5
5
  start: () => import("http").Server<typeof IncomingMessage, typeof ServerResponse> | undefined;
6
6
  server: import("http").Server<typeof IncomingMessage, typeof ServerResponse> | undefined;
7
- };
7
+ }>;
8
8
  export declare const TembaError: typeof TembaErrorInternal;
9
9
  //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,UAAU,EAAE,MAAM,UAAU,CAAA;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAA;AAW3D,OAAO,EAAE,UAAU,IAAI,kBAAkB,EAAE,MAAM,iCAAiC,CAAA;AA8FlF,eAAO,MAAM,MAAM,GAAI,aAAa,UAAU;;;CAA6B,CAAA;AAE3E,eAAO,MAAM,UAAU,2BAAqB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,UAAU,EAAE,MAAM,UAAU,CAAA;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAA;AAK3D,OAAO,EAAE,UAAU,IAAI,kBAAkB,EAAE,MAAM,iCAAiC,CAAA;AAoFlF,eAAO,MAAM,MAAM,GAAI,aAAa,UAAU;;;EAA6B,CAAA;AAE3E,eAAO,MAAM,UAAU,2BAAqB,CAAA"}
package/index.js CHANGED
@@ -1,40 +1,28 @@
1
1
  import { createServer as httpCreateServer } from 'node:http';
2
2
  import { initConfig } from './config/index.js';
3
- import { createQueries } from './data/queries.js';
4
- import { compileSchemas } from './schema/compile.js';
5
- import { createResourceHandler, handleMethodNotAllowed, handleNotFound, sendErrorResponse, } from './resourceHandler.js';
3
+ import { createResourceHandler } from './resourceHandler.js';
4
+ import { handleNotFound, sendErrorResponse } from './responseHandler.js';
6
5
  import { getHttpLogger, initLogger } from './log/logger.js';
7
- import { createOpenApiHandler } from './openapi/openapi.js';
6
+ import { createOpenApiHandler, getOpenApiPaths } from './openapi/index.js';
8
7
  import { TembaError as TembaErrorInternal } from './requestInterceptor/TembaError.js';
9
8
  import { handleStaticFolder } from './staticFolder/staticFolder.js';
10
9
  import { getDefaultImplementations } from './implementations.js';
11
- import { setCorsHeaders } from './cors/cors.js';
12
- import { version } from './version.js';
13
- const handleRootUrl = (req, res) => {
14
- if (req.method !== 'GET')
15
- return handleMethodNotAllowed(req, res);
16
- res.statusCode = 200;
17
- res.setHeader('Content-Type', 'text/plain');
18
- setCorsHeaders(res);
19
- res.end(`It works! ツ\n\nTemba ${version}`);
20
- };
10
+ import { createRootUrlHandler } from './root/root.js';
11
+ import { sendResponse } from './responseHandler.js';
12
+ import { createQueries } from './data/queries.js';
13
+ import { compileSchemas } from './schema/compile.js';
21
14
  const removePendingAndTrailingSlashes = (url) => (url ? url.replace(/^\/+|\/+$/g, '') : '');
22
- const handleOptionsRequest = (req, res) => {
23
- res.statusCode = 200;
24
- setCorsHeaders(res);
25
- res.end();
26
- };
27
- const createServer = (userConfig) => {
15
+ const handleOptionsRequest = (res) => sendResponse(res)({
16
+ statusCode: 200,
17
+ });
18
+ const createServer = async (userConfig) => {
28
19
  const config = initConfig(userConfig);
29
20
  const rootPath = config.apiPrefix ? removePendingAndTrailingSlashes(config.apiPrefix) : '';
30
- const openapiPaths = [
31
- `${rootPath ? `${rootPath}/` : ''}openapi.json`,
32
- `${rootPath ? `${rootPath}/` : ''}openapi.yaml`,
33
- ];
21
+ const openapiPaths = getOpenApiPaths(rootPath);
34
22
  const { log, logLevel } = initLogger(process.env.LOG_LEVEL);
35
23
  const queries = createQueries(config.connectionString, log);
36
24
  const schemas = compileSchemas(config.schemas);
37
- const handleResource = createResourceHandler(queries, schemas, config);
25
+ const handleResource = await createResourceHandler(queries, schemas, config);
38
26
  const httpLogger = getHttpLogger(logLevel);
39
27
  const server = httpCreateServer((req, res) => {
40
28
  const implementations = getDefaultImplementations(config);
@@ -42,24 +30,24 @@ const createServer = (userConfig) => {
42
30
  if (err)
43
31
  return sendErrorResponse(res);
44
32
  const requestUrl = removePendingAndTrailingSlashes(req.url);
45
- const handleRequest = () => {
33
+ const handleRequest = async () => {
46
34
  if (req.method === 'OPTIONS') {
47
- return handleOptionsRequest(req, res);
35
+ return handleOptionsRequest(res);
48
36
  }
49
37
  if (config.staticFolder && !`${requestUrl}/`.startsWith(config.apiPrefix + '/')) {
50
- handleStaticFolder(req, res, () => implementations.getStaticFileFromDisk(req.url === '/' ? 'index.html' : req.url || 'index.html'));
38
+ handleStaticFolder(req, res, async () => await implementations.getStaticFileFromDisk(req.url === '/' ? 'index.html' : req.url || 'index.html'));
51
39
  }
52
40
  else if (requestUrl === rootPath) {
53
- handleRootUrl(req, res);
41
+ createRootUrlHandler(config)(req, res);
54
42
  }
55
43
  else if (openapiPaths.includes(requestUrl)) {
56
- createOpenApiHandler(requestUrl.endsWith('.json') ? 'json' : 'yaml', config)(req, res);
44
+ createOpenApiHandler(config, requestUrl, req.headers.host || '')(res);
57
45
  }
58
46
  else if (requestUrl.startsWith(rootPath)) {
59
- handleResource(req, res);
47
+ await handleResource(req, res);
60
48
  }
61
49
  else {
62
- handleNotFound(req, res);
50
+ handleNotFound(res);
63
51
  }
64
52
  };
65
53
  if (config.delay > 0) {
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const getOpenApiHtml: () => string;
2
+ //# sourceMappingURL=html.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../../src/openapi/html.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,cAY1B,CAAA"}
@@ -0,0 +1,14 @@
1
+ export const getOpenApiHtml = () => {
2
+ return `<!doctype html>
3
+ <html>
4
+ <head>
5
+ <meta charset="utf-8" />
6
+ <script type="module" src="https://unpkg.com/rapidoc/dist/rapidoc-min.js"></script>
7
+ </head>
8
+ <body>
9
+ <rapi-doc spec-url="openapi.json"> </rapi-doc>
10
+ </body>
11
+ </html>
12
+ `;
13
+ };
14
+ //# sourceMappingURL=html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../../../src/openapi/html.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,EAAE;IACjC,OAAO;;;;;;;;;;GAUN,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,5 @@
1
+ import type { Config } from '../config/index.js';
2
+ import type { IncomingMessage, ServerResponse } from 'http';
3
+ export declare const getOpenApiPaths: (rootPath: string) => string[];
4
+ export declare const createOpenApiHandler: (config: Config, requestUrl: string, requestHost: string) => (res: ServerResponse<IncomingMessage>) => Promise<void>;
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/openapi/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAA;AAM3D,eAAO,MAAM,eAAe,GAAI,UAAU,MAAM,aAO/C,CAAA;AAED,eAAO,MAAM,oBAAoB,GAAI,QAAQ,MAAM,EAAE,YAAY,MAAM,EAAE,aAAa,MAAM,WACvD,cAAc,CAAC,eAAe,CAAC,kBA6BnE,CAAA"}
@@ -0,0 +1,37 @@
1
+ import { handleNotFound } from '../responseHandler.js';
2
+ import { getSpec } from './spec.js';
3
+ import { getOpenApiHtml } from './html.js';
4
+ import { sendResponse } from '../responseHandler.js';
5
+ export const getOpenApiPaths = (rootPath) => {
6
+ return [
7
+ `${rootPath ? `${rootPath}/` : ''}openapi.json`,
8
+ `${rootPath ? `${rootPath}/` : ''}openapi.yaml`,
9
+ `${rootPath ? `${rootPath}/` : ''}openapi.html`,
10
+ `${rootPath ? `${rootPath}/` : ''}openapi`,
11
+ ];
12
+ };
13
+ export const createOpenApiHandler = (config, requestUrl, requestHost) => {
14
+ const openApiHandler = async (res) => {
15
+ if (!config.openapi) {
16
+ return handleNotFound(res);
17
+ }
18
+ const format = requestUrl.endsWith('.yaml') || requestUrl.endsWith('.yml')
19
+ ? 'yaml'
20
+ : requestUrl.endsWith('.json')
21
+ ? 'json'
22
+ : 'html';
23
+ const contentType = {
24
+ json: 'application/json',
25
+ yaml: 'application/yaml',
26
+ html: 'text/html',
27
+ }[format];
28
+ const body = format === 'html' ? getOpenApiHtml() : getSpec(config, { format, host: requestHost });
29
+ sendResponse(res)({
30
+ statusCode: 200,
31
+ contentType: contentType,
32
+ body,
33
+ });
34
+ };
35
+ return openApiHandler;
36
+ };
37
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/openapi/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEjD,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,QAAgB,EAAE,EAAE;IAClD,OAAO;QACL,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,cAAc;QAC/C,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,cAAc;QAC/C,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,cAAc;QAC/C,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,SAAS;KAC3C,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,MAAc,EAAE,UAAkB,EAAE,WAAmB,EAAE,EAAE;IAC9F,MAAM,cAAc,GAAG,KAAK,EAAE,GAAoC,EAAE,EAAE;QACpE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,cAAc,CAAC,GAAG,CAAC,CAAA;QAC5B,CAAC;QAED,MAAM,MAAM,GACV,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC;YACzD,CAAC,CAAC,MAAM;YACR,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAC5B,CAAC,CAAC,MAAM;gBACR,CAAC,CAAC,MAAM,CAAA;QAEd,MAAM,WAAW,GAAG;YAClB,IAAI,EAAE,kBAAkB;YACxB,IAAI,EAAE,kBAAkB;YACxB,IAAI,EAAE,WAAW;SAClB,CAAC,MAAM,CAAC,CAAA;QAET,MAAM,IAAI,GACR,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAA;QAEvF,YAAY,CAAC,GAAG,CAAC,CAAC;YAChB,UAAU,EAAE,GAAG;YACf,WAAW,EAAE,WAAW;YACxB,IAAI;SACL,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,OAAO,cAAc,CAAA;AACvB,CAAC,CAAA"}
@@ -0,0 +1,8 @@
1
+ import type { Config } from '../config/index.js';
2
+ type OpenApiFormat = 'json' | 'yaml';
3
+ export declare const getSpec: (config: Config, request: {
4
+ host: string;
5
+ format: OpenApiFormat;
6
+ }) => string;
7
+ export {};
8
+ //# sourceMappingURL=spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec.d.ts","sourceRoot":"","sources":["../../../src/openapi/spec.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAEvC,KAAK,aAAa,GAAG,MAAM,GAAG,MAAM,CAAA;AAogBpC,eAAO,MAAM,OAAO,GAClB,QAAQ,MAAM,EACd,SAAS;IACP,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,aAAa,CAAA;CACtB,WAgEF,CAAA"}