@abide/abide 0.110.2 → 0.110.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @abide/abide
2
2
 
3
+ ## 0.110.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 2838836: an MCP tool call under a mount is asked under the mount, so a route whose first segment is the mount's name no longer 404s ([`0ceed49`](https://github.com/briancray/abide/commit/0ceed4966d55cd1b56902dc88c7961725319418f))
8
+
9
+ ## 0.110.3
10
+
11
+ ### Patch Changes
12
+
13
+ - 804b901: the root below a mount is the bare mount, url('/') writing /docs and /docs/ redirected to it ([`9c5d3c3`](https://github.com/briancray/abide/commit/9c5d3c360c27f2d9918fb663d7aff83b22078707))
14
+
3
15
  ## 0.110.2
4
16
 
5
17
  ### Patch Changes
package/docs/RULEBOOK.md CHANGED
@@ -1236,8 +1236,9 @@ be refused at construction, naming its `Args` member, and the build MUST refuse
1236
1236
  19.16 `route.url` MUST hold the address a page is served at, the path `APP_URL` names included, on
1237
1237
  the server as in the browser.
1238
1238
 
1239
- 19.17 A request for the path `APP_URL` names, without its trailing `/`, MUST be redirected 308 to
1240
- that path with one, by path alone.
1239
+ 19.17 The root of an app served below the path `APP_URL` names MUST be that path without a trailing
1240
+ `/`, as `url('/')` writes it, and a request for the path with one MUST be redirected 308 to it, by
1241
+ path alone.
1241
1242
 
1242
1243
  19.18 A `Schema` derived per 19.9 MUST refuse a member its type does not declare, wherever the type
1243
1244
  carries no index signature.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abide/abide",
3
- "version": "0.110.2",
3
+ "version": "0.110.4",
4
4
  "type": "module",
5
5
  "description": "Isomorphic type-safe framework for reactive async interfaces for humans and machines",
6
6
  "license": "MIT",
@@ -507,14 +507,14 @@ function stamp(answered: Response): Response {
507
507
 
508
508
  /**
509
509
  * The request with the mount taken off its address, where it is under the mount — or the redirect
510
- * to the mount's root, where it asked for the mount with no `/` after it.
510
+ * to the mount's root, where it asked for the mount with a `/` after it.
511
511
  *
512
512
  * 16.10 — A REQUEST UNDER THE MOUNT IS ANSWERED AS THE ADDRESS BELOW IT; one that is not — a proxy
513
513
  * that already took the prefix off — is answered as it came.
514
514
  *
515
- * THE MOUNT'S ROOT IS `/docs/`, as `url('/')` writes it. A document answered at `/docs` resolves a
516
- * relative address against `/`, which is outside the app, so the bare mount is sent to the root a
517
- * relative address resolves under.
515
+ * 19.17 — THE MOUNT'S ROOT IS `/docs`, as `url('/')` writes it, and `/docs/` is sent there so the
516
+ * root has one address. Every address abide writes is absolute under the mount, so none resolves
517
+ * against the page's.
518
518
  */
519
519
  function belowMount(request: Request): Request | Response {
520
520
  const mount = MOUNT.current()
@@ -522,10 +522,10 @@ function belowMount(request: Request): Request | Response {
522
522
  const url = new URL(request.url)
523
523
  // A PATH RATHER THAN A URL: the origin this request names is the one it reached, which behind
524
524
  // a proxy is not the one the browser asked.
525
- if (url.pathname === mount)
525
+ if (url.pathname === `${mount}/`)
526
526
  return new Response(null, {
527
527
  status: 308,
528
- headers: { location: `${mount}/${url.search}` },
528
+ headers: { location: `${mount}${url.search}` },
529
529
  })
530
530
  const below = unmounted(url.pathname)
531
531
  if (below === undefined || below === url.pathname) return request
@@ -15,6 +15,7 @@
15
15
 
16
16
  import { isFailed } from '#shared/Failed.ts'
17
17
  import { namedLogger } from '#shared/log.ts'
18
+ import { mounted } from '#shared/mount.ts'
18
19
  import { type Reactive, reactive } from '#shared/reactive/index.ts'
19
20
  import { parseRoutePattern } from '#shared/routePattern.ts'
20
21
  import { argsInURL, rpcRequest } from '#shared/rpcRequest.ts'
@@ -510,7 +511,9 @@ function callOf(
510
511
  // 38.68 — the answer is read here rather than sent on, and nothing in process decodes it.
511
512
  headers.delete('accept-encoding')
512
513
  if (call.body !== undefined) headers.set('content-type', 'application/json')
513
- return new Request(new URL(call.url, asked.url), {
514
+ // 16.10 — under the mount, as `rpc.url` is: the app takes the mount off what it is asked, and a
515
+ // route whose first segment is the mount's name would lose that segment instead.
516
+ return new Request(new URL(mounted(call.url), asked.url), {
514
517
  method,
515
518
  headers,
516
519
  body: call.body ?? null,
@@ -25,10 +25,14 @@ function documentMount(): string {
25
25
  return documentMountRead
26
26
  }
27
27
 
28
- /** An address below the app's root, as the address it is served at. */
28
+ /**
29
+ * An address below the app's root, as the address it is served at. 19.17 — the root below a mount
30
+ * is the bare mount, `/docs` rather than `/docs/`.
31
+ */
29
32
  export function mounted(address: string): string {
30
33
  const mount = MOUNT.current()
31
- return mount === '' ? address : `${mount}${address}`
34
+ if (mount === '') return address
35
+ return address === '/' ? mount : `${mount}${address}`
32
36
  }
33
37
 
34
38
  /**