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.
- package/README.md +55 -32
- package/config/index.d.ts +0 -1
- package/config/index.d.ts.map +1 -1
- package/config/index.js +1 -1
- package/config/index.js.map +1 -1
- package/index.d.ts +2 -2
- package/index.d.ts.map +1 -1
- package/index.js +20 -32
- package/index.js.map +1 -1
- package/openapi/html.d.ts +2 -0
- package/openapi/html.d.ts.map +1 -0
- package/openapi/html.js +14 -0
- package/openapi/html.js.map +1 -0
- package/openapi/index.d.ts +5 -0
- package/openapi/index.d.ts.map +1 -0
- package/openapi/index.js +37 -0
- package/openapi/index.js.map +1 -0
- package/openapi/spec.d.ts +8 -0
- package/openapi/spec.d.ts.map +1 -0
- package/openapi/spec.js +518 -0
- package/openapi/spec.js.map +1 -0
- package/package.json +11 -11
- package/requestHandlers/delete.d.ts +2 -2
- package/requestHandlers/delete.js +8 -8
- package/requestHandlers/delete.js.map +1 -1
- package/requestHandlers/get.d.ts +13 -7
- package/requestHandlers/get.d.ts.map +1 -1
- package/requestHandlers/get.js +7 -7
- package/requestHandlers/get.js.map +1 -1
- package/requestHandlers/index.d.ts +40 -18
- package/requestHandlers/index.d.ts.map +1 -1
- package/requestHandlers/index.js +2 -2
- package/requestHandlers/index.js.map +1 -1
- package/requestHandlers/patch.d.ts +9 -2
- package/requestHandlers/patch.d.ts.map +1 -1
- package/requestHandlers/patch.js +10 -7
- package/requestHandlers/patch.js.map +1 -1
- package/requestHandlers/post.d.ts +5 -3
- package/requestHandlers/post.d.ts.map +1 -1
- package/requestHandlers/post.js +6 -6
- package/requestHandlers/post.js.map +1 -1
- package/requestHandlers/put.d.ts +9 -2
- package/requestHandlers/put.d.ts.map +1 -1
- package/requestHandlers/put.js +10 -7
- package/requestHandlers/put.js.map +1 -1
- package/requestHandlers/types.d.ts +4 -12
- package/requestHandlers/types.d.ts.map +1 -1
- package/requestHandlers/utils.d.ts +4 -1
- package/requestHandlers/utils.d.ts.map +1 -1
- package/requestHandlers/utils.js.map +1 -1
- package/requestInterceptor/interceptRequest.d.ts +6 -5
- package/requestInterceptor/interceptRequest.d.ts.map +1 -1
- package/requestInterceptor/interceptRequest.js +8 -8
- package/requestInterceptor/interceptRequest.js.map +1 -1
- package/requestInterceptor/types.d.ts +9 -7
- package/requestInterceptor/types.d.ts.map +1 -1
- package/resourceHandler.d.ts +2 -7
- package/resourceHandler.d.ts.map +1 -1
- package/resourceHandler.js +17 -48
- package/resourceHandler.js.map +1 -1
- package/responseHandler.d.ts +13 -0
- package/responseHandler.d.ts.map +1 -0
- package/responseHandler.js +39 -0
- package/responseHandler.js.map +1 -0
- package/root/html.d.ts +8 -0
- package/root/html.d.ts.map +1 -0
- package/root/html.js +48 -0
- package/root/html.js.map +1 -0
- package/root/root.d.ts +4 -0
- package/root/root.d.ts.map +1 -0
- package/root/root.js +37 -0
- package/root/root.js.map +1 -0
- package/schema/compile.js +10 -11
- package/schema/compile.js.map +1 -1
- package/schema/validate.d.ts +2 -1
- package/schema/validate.d.ts.map +1 -1
- package/schema/validate.js.map +1 -1
- package/staticFolder/staticFolder.d.ts +3 -5
- package/staticFolder/staticFolder.d.ts.map +1 -1
- package/staticFolder/staticFolder.js +15 -18
- package/staticFolder/staticFolder.js.map +1 -1
- package/version.js +1 -1
- package/openapi/openapi.d.ts +0 -6
- package/openapi/openapi.d.ts.map +0 -1
- package/openapi/openapi.js +0 -476
- 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
|
|
15
|
+
**No need for any coding**, unless you want to opt-out of the defaults, or want to do more customization.
|
|
16
16
|
|
|
17
|
-
|
|
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
|
-
|
|
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
|
|
435
|
-
| :------------------------ |
|
|
436
|
-
| `allowDeleteCollection` | Whether a `DELETE` request on a collection is allowed to delete all items.
|
|
437
|
-
| `apiPrefix` | See [API prefix](#api-prefix)
|
|
438
|
-
| `connectionString` | See [Data persistency](#data-persistency)
|
|
439
|
-
| `delay` | The delay, in milliseconds, after processing the request before sending the response.
|
|
440
|
-
| `etags` | See [Caching and consistency with Etags](#caching-and-consistency-with-etags)
|
|
441
|
-
| `
|
|
442
|
-
| `
|
|
443
|
-
| `
|
|
444
|
-
| `
|
|
445
|
-
| `
|
|
446
|
-
| `
|
|
447
|
-
| `
|
|
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;
|
package/config/index.d.ts.map
CHANGED
|
@@ -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,
|
|
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
package/config/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/config/index.ts"],"names":[],"mappings":"
|
|
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;
|
|
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 {
|
|
4
|
-
import {
|
|
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/
|
|
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 {
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
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 = (
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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(
|
|
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
|
-
|
|
41
|
+
createRootUrlHandler(config)(req, res);
|
|
54
42
|
}
|
|
55
43
|
else if (openapiPaths.includes(requestUrl)) {
|
|
56
|
-
createOpenApiHandler(requestUrl.
|
|
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(
|
|
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":"AAAA,OAAO,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAC5D,OAAO,EAAE,UAAU,EAAmB,MAAM,UAAU,CAAA;AAEtD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAC5D,OAAO,EAAE,UAAU,EAAmB,MAAM,UAAU,CAAA;AAEtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AACzD,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACrE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AACjE,OAAO,EAAE,UAAU,IAAI,kBAAkB,EAAE,MAAM,iCAAiC,CAAA;AAClF,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AAChE,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAA;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEjD,MAAM,+BAA+B,GAAG,CAAC,GAAY,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;AAEpG,MAAM,oBAAoB,GAAG,CAAC,GAAoC,EAAE,EAAE,CACpE,YAAY,CAAC,GAAG,CAAC,CAAC;IAChB,UAAU,EAAE,GAAG;CAChB,CAAC,CAAA;AAEJ,MAAM,YAAY,GAAG,KAAK,EAAE,UAAuB,EAAE,EAAE;IACrD,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,CAAA;IAErC,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,+BAA+B,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAC1F,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAA;IAC9C,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IAC3D,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAA;IAC3D,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAC9C,MAAM,cAAc,GAAG,MAAM,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;IAC5E,MAAM,UAAU,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAA;IAE1C,MAAM,MAAM,GAAG,gBAAgB,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC3C,MAAM,eAAe,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAA;QAEzD,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE;YAC3B,IAAI,GAAG;gBAAE,OAAO,iBAAiB,CAAC,GAAG,CAAC,CAAA;YAEtC,MAAM,UAAU,GAAG,+BAA+B,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAE3D,MAAM,aAAa,GAAG,KAAK,IAAI,EAAE;gBAC/B,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;oBAC7B,OAAO,oBAAoB,CAAC,GAAG,CAAC,CAAA;gBAClC,CAAC;gBAED,IAAI,MAAM,CAAC,YAAY,IAAI,CAAC,GAAG,UAAU,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,GAAG,GAAG,CAAC,EAAE,CAAC;oBAChF,kBAAkB,CAChB,GAAG,EACH,GAAG,EACH,KAAK,IAAI,EAAE,CACT,MAAM,eAAe,CAAC,qBAAqB,CACzC,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,YAAY,CACzD,CACJ,CAAA;gBACH,CAAC;qBAAM,IAAI,UAAU,KAAK,QAAQ,EAAE,CAAC;oBACnC,oBAAoB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;gBACxC,CAAC;qBAAM,IAAI,YAAY,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC7C,oBAAoB,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAA;gBACvE,CAAC;qBAAM,IAAI,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC3C,MAAM,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;gBAChC,CAAC;qBAAM,CAAC;oBACN,cAAc,CAAC,GAAG,CAAC,CAAA;gBACrB,CAAC;YACH,CAAC,CAAA;YAED,IAAI,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;gBACrB,UAAU,CAAC,aAAa,EAAE,MAAM,CAAC,KAAK,CAAC,CAAA;YACzC,CAAC;iBAAM,CAAC;gBACN,aAAa,EAAE,CAAA;YACjB,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,OAAO;QACL,KAAK,EAAE,GAAG,EAAE;YACV,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;gBACrB,GAAG,CAAC,KAAK,CAAC,sEAAsE,CAAC,CAAA;gBACjF,OAAM;YACR,CAAC;YAED,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;gBAC9B,GAAG,CAAC,KAAK,CAAC,8BAA8B,MAAM,CAAC,IAAI,EAAE,CAAC,CAAA;YACxD,CAAC,CAAC,CAAA;YACF,OAAO,MAAM,CAAA;QACf,CAAC;QACD,kFAAkF;QAClF,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;KAC9C,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,UAAuB,EAAE,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,CAAA;AAE3E,MAAM,CAAC,MAAM,UAAU,GAAG,kBAAkB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../../src/openapi/html.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,cAY1B,CAAA"}
|
package/openapi/html.js
ADDED
|
@@ -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"}
|
package/openapi/index.js
ADDED
|
@@ -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 @@
|
|
|
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"}
|