@owlmeans/route 0.1.18-rc.2 → 0.1.18-rc.20
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 +236 -43
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/route/SKILL.md +72 -14
- package/build/consts.d.ts +7 -1
- package/build/consts.d.ts.map +1 -1
- package/build/consts.js +6 -0
- package/build/consts.js.map +1 -1
- package/build/helper.d.ts +8 -2
- package/build/helper.d.ts.map +1 -1
- package/build/helper.js +10 -0
- package/build/helper.js.map +1 -1
- package/build/model.d.ts +3 -3
- package/build/model.d.ts.map +1 -1
- package/build/model.js +5 -10
- package/build/model.js.map +1 -1
- package/build/types.d.ts +46 -15
- package/build/types.d.ts.map +1 -1
- package/build/utils/route.d.ts +25 -5
- package/build/utils/route.d.ts.map +1 -1
- package/build/utils/route.js +68 -67
- package/build/utils/route.js.map +1 -1
- package/build/utils/service.d.ts +1 -0
- package/build/utils/service.d.ts.map +1 -1
- package/build/utils/service.js +2 -1
- package/build/utils/service.js.map +1 -1
- package/package.json +2 -2
- package/src/consts.ts +7 -1
- package/src/helper.ts +15 -2
- package/src/model.ts +9 -15
- package/src/types.ts +48 -15
- package/src/utils/route.ts +101 -71
- package/src/utils/service.ts +2 -1
- package/build/.gitkeep +0 -0
package/README.md
CHANGED
|
@@ -1,78 +1,271 @@
|
|
|
1
1
|
# @owlmeans/route
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The route declaration vocabulary for OwlMeans entrypoints. An app imports it in its shared contract
|
|
4
|
+
package, next to `@owlmeans/entrypoint`, to state for each entrypoint the URL segment, parent,
|
|
5
|
+
HTTP method, app type (backend or frontend) and transport (HTTP, WebSocket or queue). It is not a
|
|
6
|
+
router and serves nothing: server binding is `@owlmeans/server-route` / `@owlmeans/server-app`,
|
|
7
|
+
client binding is `@owlmeans/client-route` / `@owlmeans/client-entrypoint`, UI routing is
|
|
8
|
+
`@owlmeans/router`. Application code usually reads addresses through the entrypoint accessors
|
|
9
|
+
(`path()`, `mount()`, `address()`) rather than through this package's `./utils`.
|
|
4
10
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- `RouteMethod` enum covers HTTP verbs; `RouteProtocols` covers `http`/`ws`
|
|
10
|
-
- This package is a dependency of `@owlmeans/module` — you rarely use it directly unless defining module-level routes
|
|
11
|
+
A `RouteDeclaration` is plain, immutable data: its `path` is the segment the route contributes under
|
|
12
|
+
its parent, and it is never rewritten. Where the route actually answers — the full path, the mount
|
|
13
|
+
under a service base, the host and scheme — is computed on demand from the declaration plus the
|
|
14
|
+
context that asks, so the same declaration serves a server and a browser alike.
|
|
11
15
|
|
|
12
16
|
## Installation
|
|
13
17
|
|
|
14
18
|
```bash
|
|
15
|
-
bun add @owlmeans/route
|
|
19
|
+
bun add @owlmeans/route@^0.1.18-rc.19
|
|
16
20
|
```
|
|
17
21
|
|
|
22
|
+
## Concepts
|
|
23
|
+
|
|
24
|
+
- **Declaration** — the `RouteDeclaration` a `route()` call produces: `alias`, `path` (the segment
|
|
25
|
+
under `parent`), `type`, `method`, `protocol`, the service coordinates, and the queue fields.
|
|
26
|
+
- **Model** — `RouteModel` is `{ route: RouteDeclaration }` and nothing more. `protocol()` and
|
|
27
|
+
`openProtocol()` from `@owlmeans/entrypoint` take it as their first argument.
|
|
28
|
+
- **Marker** — `backend()`, `frontend()`, `socket()`, `job()` return `Partial<RouteOptions>` that set
|
|
29
|
+
the app type and protocol; `route()` accepts them as its options.
|
|
30
|
+
- **Parent** — a route nests under another entrypoint. Pass the parent protocol object
|
|
31
|
+
(`parent: storyProtocols.base`); the declaration stores only its alias.
|
|
32
|
+
- **Service** — `service` names the configured service (`cfg.services`) that answers the route.
|
|
33
|
+
Without it the route belongs to the asking context's own service or the default one of its type.
|
|
34
|
+
- **Protocol** — `RouteProtocols` picks the transport that carries a call: HTTP request, socket
|
|
35
|
+
frame or queued job. The call site never chooses.
|
|
36
|
+
|
|
18
37
|
## Usage
|
|
19
38
|
|
|
20
|
-
|
|
39
|
+
### A backend protocol tree
|
|
21
40
|
|
|
22
|
-
|
|
23
|
-
import { route, frontend, backend, socket, RouteMethod } from '@owlmeans/route'
|
|
24
|
-
import { module } from '@owlmeans/module'
|
|
41
|
+
Aliases stay private to the declaration module; the exported value is a tree of protocol objects.
|
|
25
42
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
43
|
+
```ts
|
|
44
|
+
import { contract, protocol } from '@owlmeans/entrypoint'
|
|
45
|
+
import { backend, route, RouteMethod } from '@owlmeans/route'
|
|
46
|
+
import { DEFAULT_GUARD } from '@owlmeans/auth-common'
|
|
47
|
+
import { InvoiceSchema, CreateInvoiceBodySchema } from './schemas.js'
|
|
30
48
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
49
|
+
const aliases = {
|
|
50
|
+
base: 'my-app:api:invoice:base',
|
|
51
|
+
list: 'my-app:api:invoice:list',
|
|
52
|
+
create: 'my-app:api:invoice:create',
|
|
53
|
+
} as const
|
|
35
54
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
55
|
+
const base = protocol(route(aliases.base, '/invoice', backend()), contract(), {
|
|
56
|
+
guards: DEFAULT_GUARD,
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
export const invoiceProtocols = {
|
|
60
|
+
base,
|
|
61
|
+
list: protocol(
|
|
62
|
+
route(aliases.list, '/', backend({ parent: base, method: RouteMethod.GET })),
|
|
63
|
+
contract(InvoiceSchema),
|
|
64
|
+
),
|
|
65
|
+
create: protocol(
|
|
66
|
+
route(aliases.create, '/', backend({ parent: base, method: RouteMethod.POST })),
|
|
67
|
+
contract(CreateInvoiceBodySchema, InvoiceSchema),
|
|
68
|
+
),
|
|
69
|
+
} as const
|
|
40
70
|
```
|
|
41
71
|
|
|
42
|
-
|
|
72
|
+
`invoiceProtocols.create` resolves to `/invoice` on the backend service, answering `POST`, and
|
|
73
|
+
inherits the guard declared on `base`.
|
|
43
74
|
|
|
44
|
-
###
|
|
75
|
+
### Path params, screens and default children
|
|
45
76
|
|
|
46
|
-
|
|
77
|
+
Path params use the `:name` form and are typed through `contract.request`. `frontend()` marks a
|
|
78
|
+
screen; `default: true` marks the child screen shown at the parent's path.
|
|
47
79
|
|
|
48
|
-
|
|
80
|
+
```ts
|
|
81
|
+
import { contract, openProtocol, protocol, typed } from '@owlmeans/entrypoint'
|
|
82
|
+
import { backend, frontend, route, RouteMethod } from '@owlmeans/route'
|
|
83
|
+
import type { ProjectParams, Project, RenameProject } from './types.js'
|
|
84
|
+
import { ProjectParamsSchema, RenameProjectSchema } from './schemas.js'
|
|
49
85
|
|
|
50
|
-
|
|
86
|
+
const aliases = {
|
|
87
|
+
base: 'my-app:api:project:base',
|
|
88
|
+
rename: 'my-app:api:project:rename',
|
|
89
|
+
web: 'my-app:web:project:base',
|
|
90
|
+
dashboard: 'my-app:web:project:dashboard',
|
|
91
|
+
overview: 'my-app:web:project:overview',
|
|
92
|
+
} as const
|
|
51
93
|
|
|
52
|
-
|
|
94
|
+
const base = openProtocol(route(aliases.base, '/project', backend()))
|
|
95
|
+
const web = openProtocol(route(aliases.web, '/project/:projectId', frontend()))
|
|
53
96
|
|
|
54
|
-
|
|
97
|
+
export const projectProtocols = {
|
|
98
|
+
base,
|
|
99
|
+
rename: protocol(
|
|
100
|
+
route(aliases.rename, '/:id/rename', backend({ parent: base, method: RouteMethod.PATCH })),
|
|
101
|
+
contract.request(
|
|
102
|
+
{ params: typed<ProjectParams>(ProjectParamsSchema), body: typed<RenameProject>(RenameProjectSchema) },
|
|
103
|
+
typed<Project>(),
|
|
104
|
+
),
|
|
105
|
+
),
|
|
106
|
+
web: {
|
|
107
|
+
base: web,
|
|
108
|
+
dashboard: openProtocol(route(aliases.dashboard, '/dashboard', frontend({ parent: web }))),
|
|
109
|
+
overview: openProtocol(route(aliases.overview, '/', frontend({ parent: web, default: true }))),
|
|
110
|
+
},
|
|
111
|
+
} as const
|
|
112
|
+
```
|
|
55
113
|
|
|
56
|
-
###
|
|
114
|
+
### Sockets, queued jobs and other services
|
|
57
115
|
|
|
58
|
-
|
|
116
|
+
`socket()` and `job()` are `backend()` with a different protocol. A route pointed at another
|
|
117
|
+
service carries `service`; a queue route also names its `queue`, `timeout` and, optionally, `reply`.
|
|
59
118
|
|
|
60
|
-
|
|
119
|
+
```ts
|
|
120
|
+
import { contract, openProtocol, protocol, typed } from '@owlmeans/entrypoint'
|
|
121
|
+
import { job, route, RouteMethod, socket } from '@owlmeans/route'
|
|
122
|
+
import { GUARD_ED25519 } from '@owlmeans/auth-common'
|
|
123
|
+
import type { ProjectParams, StoryUpdate, Story } from './types.js'
|
|
124
|
+
import { ProjectParamsSchema } from './schemas.js'
|
|
61
125
|
|
|
62
|
-
|
|
63
|
-
|
|
126
|
+
const WORKER = 'my-app-worker'
|
|
127
|
+
const aliases = {
|
|
128
|
+
updates: 'my-app:api:update:base',
|
|
129
|
+
story: 'my-app:api:update:story',
|
|
130
|
+
jobs: 'my-app:worker:story:base',
|
|
131
|
+
develop: 'my-app:worker:story:develop',
|
|
132
|
+
cleanup: 'my-app:worker:story:cleanup',
|
|
133
|
+
} as const
|
|
134
|
+
|
|
135
|
+
const updates = openProtocol(route(aliases.updates, '/update'))
|
|
136
|
+
const jobs = openProtocol(route(aliases.jobs, '/story', { service: WORKER }), { guards: GUARD_ED25519 })
|
|
137
|
+
|
|
138
|
+
export const storyProtocols = {
|
|
139
|
+
updates,
|
|
140
|
+
// WebSocket subscription under /update
|
|
141
|
+
story: protocol(
|
|
142
|
+
route(aliases.story, '/story/:id', socket({ parent: updates })),
|
|
143
|
+
contract.request({ params: typed<ProjectParams>(ProjectParamsSchema) }, typed<StoryUpdate>()),
|
|
144
|
+
),
|
|
145
|
+
jobs,
|
|
146
|
+
// Queued job: the caller waits up to timeout ms for the job's result
|
|
147
|
+
develop: protocol(
|
|
148
|
+
route(aliases.develop, '/:id/develop', job({
|
|
149
|
+
parent: jobs, method: RouteMethod.POST, service: WORKER, queue: 'story-work', timeout: 600_000,
|
|
150
|
+
})),
|
|
151
|
+
contract.request({ params: typed<ProjectParams>(ProjectParamsSchema) }, typed<Story>()),
|
|
152
|
+
),
|
|
153
|
+
// reply: false resolves once the broker accepts the job; the outcome is Accepted
|
|
154
|
+
cleanup: protocol(
|
|
155
|
+
route(aliases.cleanup, '/:id/cleanup', job({
|
|
156
|
+
parent: jobs, method: RouteMethod.POST, service: WORKER, queue: 'story-ops', reply: false, timeout: 30_000,
|
|
157
|
+
})),
|
|
158
|
+
contract.request({ params: typed<ProjectParams>(ProjectParamsSchema) }, typed<unknown>()),
|
|
159
|
+
),
|
|
160
|
+
} as const
|
|
64
161
|
```
|
|
65
162
|
|
|
66
|
-
|
|
163
|
+
Which queues a process consumes is configuration of that process (`listenQueues()`), never part of
|
|
164
|
+
the declaration.
|
|
165
|
+
|
|
166
|
+
### Reading where a route answers
|
|
167
|
+
|
|
168
|
+
Once protocols are registered on a context, the entrypoint accessors answer address questions. The
|
|
169
|
+
`./utils` helpers are the same functions over a bare declaration.
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
import { AppType } from '@owlmeans/context'
|
|
173
|
+
import { service } from '@owlmeans/config'
|
|
174
|
+
import { resolveAddress, resolveMount } from '@owlmeans/route/utils'
|
|
175
|
+
import { invoiceProtocols } from 'my-app-common'
|
|
67
176
|
|
|
68
|
-
|
|
69
|
-
|
|
177
|
+
// Config side: the service the backend routes resolve against
|
|
178
|
+
const cfg = service({ service: 'my-app-api', type: AppType.Backend, host: 'localhost', port: 8080, base: 'api' }, baseCfg)
|
|
179
|
+
|
|
180
|
+
// Runtime side, through the registered entrypoint
|
|
181
|
+
const entrypoint = context.entrypoint(invoiceProtocols.create)
|
|
182
|
+
entrypoint.path() // '/invoice'
|
|
183
|
+
entrypoint.mount() // '/api/invoice'
|
|
184
|
+
entrypoint.address() // { host: 'localhost', port: 8080, base: 'api', secure: true, protocol: 'http' }
|
|
185
|
+
entrypoint.isLocal() // true inside the my-app-api process
|
|
186
|
+
|
|
187
|
+
// Same answers from a declaration
|
|
188
|
+
const declaration = invoiceProtocols.create.route.route
|
|
189
|
+
resolveMount(context, declaration)
|
|
190
|
+
resolveAddress(context, declaration)
|
|
70
191
|
```
|
|
71
192
|
|
|
72
|
-
##
|
|
193
|
+
## API
|
|
194
|
+
|
|
195
|
+
### `@owlmeans/route`
|
|
196
|
+
|
|
197
|
+
| Symbol | Kind | Purpose |
|
|
198
|
+
|--------|------|---------|
|
|
199
|
+
| `route(alias, path, opts?)` | function | Build a `RouteModel`; `opts` is `RouteOptions` or a parent alias string |
|
|
200
|
+
| `createRoute(alias, path, opts?)` | function | Build the bare `RouteDeclaration` (parent reference collapsed to its alias) |
|
|
201
|
+
| `makeRouteModel(declaration)` | function | Wrap a declaration as `{ route }` |
|
|
202
|
+
| `backend(opts?, method?)` | function | Mark `AppType.Backend`; `opts` is options, a parent alias or `null`; `method` is a `RouteMethod` or more options |
|
|
203
|
+
| `frontend(opts?, default?)` | function | Mark `AppType.Frontend`; `default` is a boolean flag or more options |
|
|
204
|
+
| `socket(opts?, secondary?)` | function | `backend()` with `protocol: RouteProtocols.SOCKET` |
|
|
205
|
+
| `job(opts?, secondary?)` | function | `backend()` with `protocol: RouteProtocols.QUEUE` |
|
|
206
|
+
| `service(alias, opts?)` | function | Set `service` on `opts` (mutated and returned) |
|
|
207
|
+
| `rtype(type, opts?)` | function | Set an arbitrary `AppType`; the primitive behind `backend()` / `frontend()` |
|
|
208
|
+
| `normalizePath(path)` | function | Trim whitespace and one leading and trailing `/` |
|
|
209
|
+
| `RouteMethod` | enum | `GET = 'get'`, `POST = 'post'`, `PATCH = 'patch'`, `PUT = 'put'`, `DELETE = 'delete'` |
|
|
210
|
+
| `RouteProtocols` | enum | `WEB = 'http'`, `SOCKET = 'ws'`, `QUEUE = 'queue'` |
|
|
211
|
+
| `SEP` | const | Path separator `'/'` |
|
|
212
|
+
| `PARAM` | const | Path param prefix `':'` |
|
|
213
|
+
| `BasicRoute` | interface | `type`, `service?`, `host?`, `port?`, `base?`, `internalHost?`, `internalPort?` |
|
|
214
|
+
| `RouteDeclaration` | interface | `BasicRoute` + `alias`, `path`, `parent?`, `default?`, `method?`, `protocol?`, `secure?`, `queue?`, `reply?`, `timeout?` |
|
|
215
|
+
| `RouteOptions` | interface | `Partial<RouteDeclaration>` whose `parent` is a `RouteParent` |
|
|
216
|
+
| `RouteParent` | type | `string \| EntrypointReference` |
|
|
217
|
+
| `RouteModel` | interface | `{ route: RouteDeclaration }` |
|
|
218
|
+
| `RouteAddress` | interface | `{ host, port?, base?, secure, protocol }` |
|
|
219
|
+
| `CommonServiceRoute` | interface | A service entry: `BasicRoute` + `service`, `home?`, `default?` |
|
|
220
|
+
| `ResolvedServiceRoute` | interface | A service entry that names its `host` |
|
|
221
|
+
|
|
222
|
+
### `@owlmeans/route/utils`
|
|
223
|
+
|
|
224
|
+
The first six take `(context, declaration)`; the other four are pure and take no context.
|
|
225
|
+
|
|
226
|
+
| Symbol | Kind | Purpose |
|
|
227
|
+
|--------|------|---------|
|
|
228
|
+
| `resolvePath(context, route)` | function | Every ancestor's segment, then this one |
|
|
229
|
+
| `resolveMount(context, route)` | function | Service `base` + the full path |
|
|
230
|
+
| `resolveService(context, route)` | function | The named service, else the default of the route's type, else the first of that type |
|
|
231
|
+
| `resolveAddress(context, route)` | function | The `RouteAddress`; a hop over the service's internal host is never TLS |
|
|
232
|
+
| `isLocalRoute(context, route)` | function | Does the route belong to the context's own service |
|
|
233
|
+
| `getParentRoute(context, route)` | function | The parent declaration, with parentship-cycle detection |
|
|
234
|
+
| `overrideParams(route, overrides?, filter?)` | function | Fill only blank fields of `route` from `overrides`; mutates, returns nothing |
|
|
235
|
+
| `prependBase(route, path)` | function | `path` prefixed with `route.base` when set |
|
|
236
|
+
| `isServiceRoute(obj?)` | type guard | Is `obj` a `CommonServiceRoute` with a known `AppType` |
|
|
237
|
+
| `isServiceRouteResolved(route)` | type guard | Does the service entry name a host |
|
|
238
|
+
| `CreateRouteSignature<R>` | interface | Call signature shared by `route()` and `createRoute()` |
|
|
239
|
+
|
|
240
|
+
## Common pitfalls
|
|
241
|
+
|
|
242
|
+
- Pass the parent protocol object in route options, never an exported alias string. Keep aliases
|
|
243
|
+
private to the declaration module and export a `*Protocols` tree.
|
|
244
|
+
- The positional marker forms (`backend(parent, method)`, `frontend(parent, true)`) accept a parent
|
|
245
|
+
only as an alias string: a protocol object in first position is spread into the options and
|
|
246
|
+
overwrites the child's alias. Pass protocols as `{ parent }`.
|
|
247
|
+
- `path` is only this route's segment. Do not repeat the parent's path in it; `resolvePath()` joins
|
|
248
|
+
the chain.
|
|
249
|
+
- `job()` routes must name `service`, `queue` and `timeout`. `reply: false` returns the job identity
|
|
250
|
+
with an `Accepted` outcome, not the job's result.
|
|
251
|
+
- Do not pass a context to the pure `./utils` helpers: `overrideParams(ctx, decl)` writes route
|
|
252
|
+
fields into the context object instead of resolving anything.
|
|
253
|
+
- A mis-wired tree (no `cfg.services`, a service without a host, a parentship cycle) throws
|
|
254
|
+
`SyntaxError` when an address is resolved. Fix the config; do not catch it.
|
|
255
|
+
- `transportAlias` and `EntrypointTransport` live in `@owlmeans/entrypoint`, not here. A route only
|
|
256
|
+
names its protocol.
|
|
257
|
+
|
|
258
|
+
## Related packages
|
|
73
259
|
|
|
74
|
-
- [`@owlmeans/
|
|
75
|
-
|
|
260
|
+
- [`@owlmeans/entrypoint`](../entrypoint) — `protocol()` / `openProtocol()` consume a `RouteModel` and
|
|
261
|
+
expose `path()`, `mount()`, `address()`, `isLocal()`
|
|
262
|
+
- [`@owlmeans/context`](../context) — `AppType`, `EntrypointReference` and the registry the address helpers walk
|
|
263
|
+
- [`@owlmeans/config`](../config) — `service()` declares the service entries routes resolve against
|
|
264
|
+
- [`@owlmeans/server-route`](../server-route) — server-side route model; re-exported by
|
|
265
|
+
[`@owlmeans/server-app`](../server-app) as `broute`
|
|
266
|
+
- [`@owlmeans/client-route`](../client-route) — marks a route as client-side and extracts its params
|
|
267
|
+
- [`@owlmeans/queue`](../queue) — the QUEUE transport a `job()` route is carried by
|
|
268
|
+
- [`@owlmeans/socket`](../socket) — the SOCKET transport contracts
|
|
76
269
|
|
|
77
270
|
<!-- owlmeans:agent-guidance:start -->
|
|
78
271
|
## Agent guidance
|
|
@@ -82,7 +275,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
82
275
|
your project's skill store (`.agents/skills/`):
|
|
83
276
|
|
|
84
277
|
```sh
|
|
85
|
-
npx @owlmeans/agent-skills
|
|
278
|
+
npx @owlmeans/agent-skills@^0.1.18-rc.23
|
|
86
279
|
```
|
|
87
280
|
|
|
88
281
|
The embedded files are version-matched to this package release. Do not edit them
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/route",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-
|
|
4
|
+
"version": "0.1.18-rc.20",
|
|
5
|
+
"generatedAt": "2026-09-15T12:50:32.621Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: route
|
|
3
|
-
description: How to use @owlmeans/route — route()
|
|
3
|
+
description: How to use @owlmeans/route — route() for declaring URL segments, frontend()/backend()/socket()/job() markers, RouteMethod and RouteProtocols enums, and the address helpers under ./utils. Auto-invoked when importing route helpers or defining an entrypoint's URL path.
|
|
4
4
|
user-invocable: false
|
|
5
5
|
---
|
|
6
6
|
<!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
|
|
@@ -8,43 +8,101 @@ user-invocable: false
|
|
|
8
8
|
# @owlmeans/route
|
|
9
9
|
|
|
10
10
|
**Layer:** Core
|
|
11
|
-
**Install:** `"@owlmeans/route": "^0.1.18-rc.
|
|
11
|
+
**Install:** `"@owlmeans/route": "^0.1.18-rc.20"` in `dependencies`
|
|
12
12
|
|
|
13
13
|
## Key Exports
|
|
14
14
|
|
|
15
15
|
| Export | Description |
|
|
16
16
|
|--------|-------------|
|
|
17
|
-
| `route(alias, path, options?)` |
|
|
18
|
-
| `frontend(options?)` | Mark a route as a React page (web only) |
|
|
19
|
-
| `
|
|
20
|
-
| `
|
|
21
|
-
|
|
|
17
|
+
| `route(alias, path, options?)` | Build a route model — `path` is the segment contributed under `parent` |
|
|
18
|
+
| `frontend(options?, default?)` | Mark a route as a React page (web only) |
|
|
19
|
+
| `backend(options?, method?)` | Mark a route as a backend endpoint |
|
|
20
|
+
| `socket(options?, secondary?)` | A backend route answering over `RouteProtocols.SOCKET` |
|
|
21
|
+
| `job(options?, secondary?)` | A backend route carried by the queue (`RouteProtocols.QUEUE`); its declaration names `service`, `queue`, `reply` and `timeout` |
|
|
22
|
+
| `service(alias, options?)` | Point a route at a named service |
|
|
23
|
+
| `RouteMethod` | enum of GET, POST, PUT, PATCH, DELETE |
|
|
24
|
+
| `RouteProtocols` | enum of WEB (`http`), SOCKET (`ws`), QUEUE (`queue`) |
|
|
25
|
+
| `rtype(type, options?)` | The primitive `frontend()` / `backend()` are built from |
|
|
26
|
+
| `createRoute(alias, path, opts?)` / `makeRouteModel(decl)` | The declaration and its wrapper, when you need them apart |
|
|
27
|
+
| `BasicRoute` | `{ type, service?, host?, port?, base?, internalHost?, internalPort? }` |
|
|
28
|
+
| `RouteDeclaration` | The immutable declaration `route()` produces |
|
|
29
|
+
| `RouteOptions` | `Partial<RouteDeclaration>` — what the marker helpers return |
|
|
30
|
+
| `RouteModel` | `{ route }` — the model wrapping a declaration |
|
|
31
|
+
| `RouteAddress` | `{ host, port, base, secure, protocol }` — where a route answers |
|
|
32
|
+
| `CommonServiceRoute` / `ResolvedServiceRoute` | A service entry, and one that knows its host |
|
|
33
|
+
| `normalizePath(path)`, `SEP`, `PARAM` | Path primitives |
|
|
34
|
+
|
|
35
|
+
## Declaration and model
|
|
36
|
+
|
|
37
|
+
`route()` returns a `RouteModel` that does nothing but **wrap an immutable `RouteDeclaration`**. The
|
|
38
|
+
declaration is plain data an application ships in its contract package: `path` stays the segment this
|
|
39
|
+
route contributes under its parent and is never rewritten, and the model carries no state of its own.
|
|
40
|
+
Where the route answers is worked out on demand, against the context that asks — which is what lets
|
|
41
|
+
the same declaration serve a client and a server at once.
|
|
42
|
+
|
|
43
|
+
## Protocol picks the transport
|
|
44
|
+
|
|
45
|
+
A route names the protocol it answers on, and an application binds one by registering a transport
|
|
46
|
+
service under `transportAlias(protocol)`. So the protocol is what decides whether a call travels as
|
|
47
|
+
an HTTP request, a socket frame or a queued job — the call site never says. Both `transportAlias`
|
|
48
|
+
and the `EntrypointTransport` contract a transport implements are exported by `@owlmeans/entrypoint`,
|
|
49
|
+
not by this package; a route only names the protocol.
|
|
50
|
+
|
|
51
|
+
`job()` is `backend()` with `RouteProtocols.QUEUE`. Three declaration fields matter only for that
|
|
52
|
+
protocol: `queue` (which queue carries it), `reply` and `timeout`. `reply: false` resolves once the
|
|
53
|
+
broker has taken the job — the value is the job's identity and the outcome is `Accepted`, not the
|
|
54
|
+
job's result; the default is to wait for the result. Use the parent protocol object in a route
|
|
55
|
+
option (`job({ parent: storyProtocols.base, service, queue, timeout })`), never an exported alias string.
|
|
22
56
|
|
|
23
57
|
## Subpath Exports
|
|
24
58
|
|
|
25
|
-
|
|
59
|
+
`./utils` holds two kinds of helper, and their signatures differ. The six that answer *where* a
|
|
60
|
+
route lives take `(context, declaration)`, because that is a question about the asking context. The
|
|
61
|
+
other four are pure functions over a declaration or a service entry and take **no context**.
|
|
62
|
+
Passing one to them resolves nothing: `overrideParams(ctx, decl)` writes route fields straight into
|
|
63
|
+
the context object instead.
|
|
64
|
+
|
|
65
|
+
| Helper | Signature | Answers |
|
|
66
|
+
|--------|-----------|---------|
|
|
67
|
+
| `resolvePath` | `(context, route)` | Every ancestor's segment, then this one |
|
|
68
|
+
| `resolveMount` | `(context, route)` | `base` + the full path — what a server mounts and a client requests |
|
|
69
|
+
| `resolveService` | `(context, route)` | The service the declaration answers on: the one it names, else the default of its app type, else the first of that type |
|
|
70
|
+
| `resolveAddress` | `(context, route)` | The `RouteAddress`; a hop over a service's INTERNAL host is never TLS |
|
|
71
|
+
| `isLocalRoute` | `(context, route)` | Does the route belong to the service the asking context IS? |
|
|
72
|
+
| `getParentRoute` | `(context, route)` | The parent declaration, with parentship-cycle detection |
|
|
73
|
+
| `overrideParams` | `(route, overrides?, filter?)` | Fill in **only the blank** fields of `route` from `overrides`; `filter` narrows it to the listed keys. Mutates `route` and returns nothing |
|
|
74
|
+
| `prependBase` | `(route, path)` | `path` prefixed with `route.base`, or `path` when there is no base |
|
|
75
|
+
| `isServiceRoute` | `(obj?)` | Type guard: is this a service entry (`type` + `service`, `type` a known `AppType`)? |
|
|
76
|
+
| `isServiceRouteResolved` | `(route)` | Type guard: does that service entry name a host? |
|
|
77
|
+
|
|
78
|
+
Application code rarely calls these directly — `@owlmeans/entrypoint` exposes them as `path()`,
|
|
79
|
+
`mount()`, `service()`, `address()` and `isLocal()` on the entrypoint itself.
|
|
26
80
|
|
|
27
81
|
## Usage
|
|
28
82
|
|
|
29
83
|
```typescript
|
|
30
84
|
import { route, frontend, RouteMethod } from '@owlmeans/route'
|
|
31
|
-
import {
|
|
85
|
+
import { contract, openProtocol, protocol, typed } from '@owlmeans/entrypoint'
|
|
32
86
|
|
|
33
87
|
// Server route
|
|
34
|
-
|
|
88
|
+
protocol(
|
|
35
89
|
route(manager.back.project.create, '/create', {
|
|
36
90
|
parent: manager.back.project.base,
|
|
37
91
|
method: RouteMethod.POST,
|
|
38
|
-
})
|
|
92
|
+
}),
|
|
93
|
+
contract(typed<Project>()),
|
|
39
94
|
)
|
|
40
95
|
|
|
41
96
|
// Web route — frontend() marks it as a React page
|
|
42
|
-
|
|
97
|
+
openProtocol(
|
|
43
98
|
route(HOME, '/', frontend({ default: true, parent: BASE }))
|
|
44
99
|
)
|
|
45
100
|
```
|
|
46
101
|
|
|
47
102
|
## Depends On
|
|
48
103
|
|
|
49
|
-
- `@owlmeans/
|
|
50
|
-
|
|
104
|
+
- `@owlmeans/context` — `AppType`, and the entrypoint registry the address helpers walk
|
|
105
|
+
|
|
106
|
+
That is the only dependency. The address helpers signal a mis-wired route tree by throwing
|
|
107
|
+
`SyntaxError` — an unconfigured service, an unresolved host, a parentship cycle — so the process
|
|
108
|
+
crashes on a wiring mistake instead of serving a wrong URL.
|
package/build/consts.d.ts
CHANGED
|
@@ -7,8 +7,14 @@ export declare enum RouteMethod {
|
|
|
7
7
|
}
|
|
8
8
|
export declare const SEP = "/";
|
|
9
9
|
export declare const PARAM = ":";
|
|
10
|
+
/**
|
|
11
|
+
* How a route is carried. The protocol picks the transport that answers it — an application binds
|
|
12
|
+
* one by registering a service under `transportAlias(protocol)` — so a caller writes `call()` and
|
|
13
|
+
* never learns whether an HTTP request, a socket frame or a queued job did the work.
|
|
14
|
+
*/
|
|
10
15
|
export declare enum RouteProtocols {
|
|
11
16
|
WEB = "http",
|
|
12
|
-
SOCKET = "ws"
|
|
17
|
+
SOCKET = "ws",
|
|
18
|
+
QUEUE = "queue"
|
|
13
19
|
}
|
|
14
20
|
//# sourceMappingURL=consts.d.ts.map
|
package/build/consts.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AACA,oBAAY,WAAW;IACrB,GAAG,QAAQ;IACX,IAAI,SAAS;IACb,KAAK,UAAU;IACf,GAAG,QAAQ;IACX,MAAM,WAAW;CAClB;AAED,eAAO,MAAM,GAAG,MAAM,CAAA;AAEtB,eAAO,MAAM,KAAK,MAAM,CAAA;AAExB,oBAAY,cAAc;IACxB,GAAG,SAAS;IACZ,MAAM,OAAO;
|
|
1
|
+
{"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AACA,oBAAY,WAAW;IACrB,GAAG,QAAQ;IACX,IAAI,SAAS;IACb,KAAK,UAAU;IACf,GAAG,QAAQ;IACX,MAAM,WAAW;CAClB;AAED,eAAO,MAAM,GAAG,MAAM,CAAA;AAEtB,eAAO,MAAM,KAAK,MAAM,CAAA;AAExB;;;;GAIG;AACH,oBAAY,cAAc;IACxB,GAAG,SAAS;IACZ,MAAM,OAAO;IACb,KAAK,UAAU;CAChB"}
|
package/build/consts.js
CHANGED
|
@@ -8,9 +8,15 @@ export var RouteMethod;
|
|
|
8
8
|
})(RouteMethod || (RouteMethod = {}));
|
|
9
9
|
export const SEP = '/';
|
|
10
10
|
export const PARAM = ':';
|
|
11
|
+
/**
|
|
12
|
+
* How a route is carried. The protocol picks the transport that answers it — an application binds
|
|
13
|
+
* one by registering a service under `transportAlias(protocol)` — so a caller writes `call()` and
|
|
14
|
+
* never learns whether an HTTP request, a socket frame or a queued job did the work.
|
|
15
|
+
*/
|
|
11
16
|
export var RouteProtocols;
|
|
12
17
|
(function (RouteProtocols) {
|
|
13
18
|
RouteProtocols["WEB"] = "http";
|
|
14
19
|
RouteProtocols["SOCKET"] = "ws";
|
|
20
|
+
RouteProtocols["QUEUE"] = "queue";
|
|
15
21
|
})(RouteProtocols || (RouteProtocols = {}));
|
|
16
22
|
//# sourceMappingURL=consts.js.map
|
package/build/consts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AACA,MAAM,CAAN,IAAY,WAMX;AAND,WAAY,WAAW;IACrB,0BAAW,CAAA;IACX,4BAAa,CAAA;IACb,8BAAe,CAAA;IACf,0BAAW,CAAA;IACX,gCAAiB,CAAA;AACnB,CAAC,EANW,WAAW,KAAX,WAAW,QAMtB;AAED,MAAM,CAAC,MAAM,GAAG,GAAG,GAAG,CAAA;AAEtB,MAAM,CAAC,MAAM,KAAK,GAAG,GAAG,CAAA;AAExB,MAAM,CAAN,IAAY,
|
|
1
|
+
{"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AACA,MAAM,CAAN,IAAY,WAMX;AAND,WAAY,WAAW;IACrB,0BAAW,CAAA;IACX,4BAAa,CAAA;IACb,8BAAe,CAAA;IACf,0BAAW,CAAA;IACX,gCAAiB,CAAA;AACnB,CAAC,EANW,WAAW,KAAX,WAAW,QAMtB;AAED,MAAM,CAAC,MAAM,GAAG,GAAG,GAAG,CAAA;AAEtB,MAAM,CAAC,MAAM,KAAK,GAAG,GAAG,CAAA;AAExB;;;;GAIG;AACH,MAAM,CAAN,IAAY,cAIX;AAJD,WAAY,cAAc;IACxB,8BAAY,CAAA;IACZ,+BAAa,CAAA;IACb,iCAAe,CAAA;AACjB,CAAC,EAJW,cAAc,KAAd,cAAc,QAIzB"}
|
package/build/helper.d.ts
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { AppType } from '@owlmeans/context';
|
|
2
2
|
import { RouteMethod } from './consts.js';
|
|
3
|
-
import type {
|
|
3
|
+
import type { RouteModel, RouteOptions } from './types.js';
|
|
4
4
|
import type { CreateRouteSignature } from './utils/types.js';
|
|
5
|
-
export declare const route: CreateRouteSignature<
|
|
5
|
+
export declare const route: CreateRouteSignature<RouteModel>;
|
|
6
6
|
export declare const normalizePath: (path: string) => string;
|
|
7
7
|
export declare const rtype: (type: AppType, opts?: RouteOptions | string) => Partial<RouteOptions>;
|
|
8
8
|
export declare const backend: (opts?: RouteOptions | string | null, method?: RouteOptions | RouteMethod) => Partial<RouteOptions>;
|
|
9
9
|
export declare const service: (service: string, opts?: Partial<RouteOptions>) => Partial<RouteOptions>;
|
|
10
10
|
export declare const socket: (opts?: RouteOptions | string | null, secondary?: RouteOptions) => Partial<RouteOptions>;
|
|
11
|
+
/**
|
|
12
|
+
* A backend route carried by the queue rather than by HTTP. Everything else about it is a normal
|
|
13
|
+
* backend route — it has a path, a parent, guards and a filter — so the same declaration is served
|
|
14
|
+
* with `bind(...)` and called with `call()`; only the transport underneath differs.
|
|
15
|
+
*/
|
|
16
|
+
export declare const job: (opts?: RouteOptions | string | null, secondary?: RouteOptions) => Partial<RouteOptions>;
|
|
11
17
|
export declare const frontend: (opts?: RouteOptions | string | null, def?: RouteOptions | boolean) => Partial<RouteOptions>;
|
|
12
18
|
//# sourceMappingURL=helper.d.ts.map
|
package/build/helper.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAuB,MAAM,aAAa,CAAA;AAE9D,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAuB,MAAM,aAAa,CAAA;AAE9D,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAC1D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AAE5D,eAAO,MAAM,KAAK,EAAE,oBAAoB,CAAC,UAAU,CACH,CAAA;AAEhD,eAAO,MAAM,aAAa,SAAU,MAAM,KAAG,MAM5C,CAAA;AAED,eAAO,MAAM,KAAK,SAAU,OAAO,SAAS,YAAY,GAAG,MAAM,KAAG,OAAO,CAAC,YAAY,CAEvF,CAAA;AAED,eAAO,MAAM,OAAO,UAAW,YAAY,GAAG,MAAM,GAAG,IAAI,WAAW,YAAY,GAAG,WAAW,KAAG,OAAO,CAAC,YAAY,CAQtH,CAAA;AAED,eAAO,MAAM,OAAO,YAAa,MAAM,SAAS,OAAO,CAAC,YAAY,CAAC,KAAG,OAAO,CAAC,YAAY,CAI3F,CAAA;AAED,eAAO,MAAM,MAAM,UAAW,YAAY,GAAG,MAAM,GAAG,IAAI,cAAc,YAAY,KAAG,OAAO,CAAC,YAAY,CAM1G,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,GAAG,UAAW,YAAY,GAAG,MAAM,GAAG,IAAI,cAAc,YAAY,KAAG,OAAO,CAAC,YAAY,CAMvG,CAAA;AAED,eAAO,MAAM,QAAQ,UAAW,YAAY,GAAG,MAAM,GAAG,IAAI,QAAQ,YAAY,GAAG,OAAO,KAAG,OAAO,CAAC,YAAY,CAQhH,CAAA"}
|
package/build/helper.js
CHANGED
|
@@ -28,6 +28,16 @@ export const socket = (opts, secondary) => {
|
|
|
28
28
|
route.protocol = RouteProtocols.SOCKET;
|
|
29
29
|
return route;
|
|
30
30
|
};
|
|
31
|
+
/**
|
|
32
|
+
* A backend route carried by the queue rather than by HTTP. Everything else about it is a normal
|
|
33
|
+
* backend route — it has a path, a parent, guards and a filter — so the same declaration is served
|
|
34
|
+
* with `bind(...)` and called with `call()`; only the transport underneath differs.
|
|
35
|
+
*/
|
|
36
|
+
export const job = (opts, secondary) => {
|
|
37
|
+
const route = backend(opts, secondary);
|
|
38
|
+
route.protocol = RouteProtocols.QUEUE;
|
|
39
|
+
return route;
|
|
40
|
+
};
|
|
31
41
|
export const frontend = (opts, def) => {
|
|
32
42
|
if (typeof def === 'boolean') {
|
|
33
43
|
opts = typeof opts === 'string' ? { parent: opts, default: def } : { default: def, ...(opts ?? {}) };
|
package/build/helper.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAC3C,OAAO,EAAe,cAAc,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AAC9D,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAIxD,MAAM,CAAC,MAAM,KAAK,
|
|
1
|
+
{"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"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"}
|
package/build/model.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RouteDeclaration, RouteModel } from './types.js';
|
|
2
2
|
import type { CreateRouteSignature } from './utils/types.js';
|
|
3
|
-
export declare const makeRouteModel: (route:
|
|
4
|
-
export declare const createRoute: CreateRouteSignature<
|
|
3
|
+
export declare const makeRouteModel: (route: RouteDeclaration) => RouteModel;
|
|
4
|
+
export declare const createRoute: CreateRouteSignature<RouteDeclaration>;
|
|
5
5
|
//# sourceMappingURL=model.d.ts.map
|
package/build/model.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAC9D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AAG5D,eAAO,MAAM,cAAc,UAAW,gBAAgB,KAAG,UAAyB,CAAA;AAElF,eAAO,MAAM,WAAW,EAAE,oBAAoB,CAAC,gBAAgB,CAY9D,CAAA"}
|
package/build/model.js
CHANGED
|
@@ -1,19 +1,14 @@
|
|
|
1
|
-
import { resolve } from './utils/route.js';
|
|
2
1
|
import { AppType } from '@owlmeans/context';
|
|
3
|
-
export const makeRouteModel = (route) => {
|
|
4
|
-
const model = {
|
|
5
|
-
route,
|
|
6
|
-
resolve: ctx => resolve(route)(ctx)
|
|
7
|
-
};
|
|
8
|
-
return model;
|
|
9
|
-
};
|
|
2
|
+
export const makeRouteModel = (route) => ({ route });
|
|
10
3
|
export const createRoute = (alias, path, opts) => {
|
|
4
|
+
const options = typeof opts === 'string' ? { parent: opts } : opts;
|
|
5
|
+
const { parent, ...rest } = options ?? {};
|
|
11
6
|
const route = {
|
|
12
7
|
alias,
|
|
13
8
|
type: AppType.Backend,
|
|
14
9
|
path,
|
|
15
|
-
|
|
16
|
-
...(typeof
|
|
10
|
+
...rest,
|
|
11
|
+
...(parent == null ? {} : { parent: typeof parent === 'string' ? parent : parent.alias }),
|
|
17
12
|
};
|
|
18
13
|
return route;
|
|
19
14
|
};
|
package/build/model.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAE3C,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAuB,EAAc,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;AAElF,MAAM,CAAC,MAAM,WAAW,GAA2C,CAAC,KAAK,EAAE,IAAI,EAAE,IAAK,EAAE,EAAE;IACxF,MAAM,OAAO,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;IAClE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,IAAI,EAAE,CAAA;IACzC,MAAM,KAAK,GAAqB;QAC9B,KAAK;QACL,IAAI,EAAE,OAAO,CAAC,OAAO;QACrB,IAAI;QACJ,GAAG,IAAI;QACP,GAAG,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;KAC1F,CAAA;IAED,OAAO,KAAK,CAAA;AACd,CAAC,CAAA"}
|