@estiva-app/interop 0.10.0 → 0.10.1
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 +21 -0
- package/dist/objectUrl.d.ts.map +1 -1
- package/dist/objectUrl.js +26 -3
- package/dist/objectUrl.js.map +1 -1
- package/package.json +1 -1
- package/src/objectUrl.ts +27 -4
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,27 @@ how a declaration is read, is a MAJOR — in `0.x`, a MINOR — even when no
|
|
|
6
6
|
TypeScript signature moved. A consumer upgrading must be able to tell whether
|
|
7
7
|
manifests already published still mean what they meant.
|
|
8
8
|
|
|
9
|
+
## 0.10.1 — 2026-09-03
|
|
10
|
+
|
|
11
|
+
**`matchObjectUrl` matched no fragment route at all.** The parser's path capture
|
|
12
|
+
stopped at the `#`, so `https://ship.estiva.app/#/issue/<uuid>` reduced to no
|
|
13
|
+
segments and matched nothing — including patterns declaring exactly that shape.
|
|
14
|
+
|
|
15
|
+
That is not a corner. Ship served fragment routes until SHI-16 and declares them
|
|
16
|
+
still, so that links already sitting in other people's messages resolve rather
|
|
17
|
+
than rendering as plain text for ever. A consumer on 0.10.0 would have silently
|
|
18
|
+
failed every one of them.
|
|
19
|
+
|
|
20
|
+
Found by a production probe before any consumer was built on it, which is the
|
|
21
|
+
argument for probing the mechanism rather than the fixture.
|
|
22
|
+
|
|
23
|
+
- Path and fragment segments are concatenated rather than swapped, because an
|
|
24
|
+
app may be served under a sub-path *and* use a fragment — Ship's own dev URL
|
|
25
|
+
is `localhost:5190/ship/#/…`, where both halves carry meaning.
|
|
26
|
+
- A fragment route and a path route stay distinct shapes. Collapsing them would
|
|
27
|
+
let a pattern for `/issue/<slug>-<d>` claim `/#/issue/<d>`, and an app that
|
|
28
|
+
means different things by the two would resolve the wrong object.
|
|
29
|
+
|
|
9
30
|
## 0.10.0 — 2026-09-03
|
|
10
31
|
|
|
11
32
|
**RFC 0.5 §7's URL grammar, which was accepted with amendments today.** No
|
package/dist/objectUrl.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"objectUrl.d.ts","sourceRoot":"","sources":["../src/objectUrl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAkBH;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAS7C;AAED,qFAAqF;AACrF,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAGpE;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG5D;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,UAAU;IACzB,sDAAsD;IACtD,OAAO,EAAE,MAAM,CAAA;IACf;;;;;;;;;OASG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,mDAAmD;AACnD,wBAAgB,aAAa,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAA;CAAE,GAAG,UAAU,EAAE,CAQvE;AAED,4CAA4C;AAC5C,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAA;IAClB,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,gBAAgB,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"objectUrl.d.ts","sourceRoot":"","sources":["../src/objectUrl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAkBH;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAS7C;AAED,qFAAqF;AACrF,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAGpE;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG5D;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,UAAU;IACzB,sDAAsD;IACtD,OAAO,EAAE,MAAM,CAAA;IACf;;;;;;;;;OASG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,mDAAmD;AACnD,wBAAgB,aAAa,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAA;CAAE,GAAG,UAAU,EAAE,CAQvE;AAED,4CAA4C;AAC5C,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAA;IAClB,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,gBAAgB,GAAG,IAAI,CAyB3F"}
|
package/dist/objectUrl.js
CHANGED
|
@@ -109,6 +109,9 @@ export function matchObjectUrl(url, patterns) {
|
|
|
109
109
|
continue;
|
|
110
110
|
if (shape.scheme !== target.scheme || shape.host !== target.host)
|
|
111
111
|
continue;
|
|
112
|
+
// A fragment route and a path route are different shapes, not one.
|
|
113
|
+
if (shape.fragmented !== target.fragmented)
|
|
114
|
+
continue;
|
|
112
115
|
// The pattern's path up to its final segment: `/issue/` out of
|
|
113
116
|
// `/issue/<slug>-<d>`. Compared literally and at equal depth, so `/issues`
|
|
114
117
|
// never matches `/issue/…` and a nested route never matches a shallower one.
|
|
@@ -145,14 +148,34 @@ export function matchObjectUrl(url, patterns) {
|
|
|
145
148
|
* declare.
|
|
146
149
|
*/
|
|
147
150
|
function splitUrl(raw) {
|
|
148
|
-
const match = /^(https?):\/\/([^/?#]+)([^?#]*)
|
|
151
|
+
const match = /^(https?):\/\/([^/?#]+)([^?#]*)(?:\?[^#]*)?(?:#(.*))?$/i.exec(raw.trim());
|
|
149
152
|
if (!match)
|
|
150
153
|
return null;
|
|
151
|
-
const [, scheme, host, path] = match;
|
|
154
|
+
const [, scheme, host, path, fragment] = match;
|
|
155
|
+
/*
|
|
156
|
+
A fragment route counts as path.
|
|
157
|
+
|
|
158
|
+
Ship served `#/issue/<d>` until SHI-16 and still declares those shapes, so
|
|
159
|
+
that links already sitting in other people's messages resolve rather than
|
|
160
|
+
rendering as plain text for ever. A parser that stopped at the `#` — this
|
|
161
|
+
one did — matched none of them, which a production probe caught before any
|
|
162
|
+
consumer was built on it.
|
|
163
|
+
|
|
164
|
+
Segments from the path and the fragment are concatenated rather than
|
|
165
|
+
swapped, because an app may be served under a sub-path *and* use a
|
|
166
|
+
fragment: Ship's own dev URL is `localhost:5190/ship/#/…`, where both
|
|
167
|
+
halves carry meaning.
|
|
168
|
+
|
|
169
|
+
`fragmented` is kept so the two do not collapse into each other. Without it
|
|
170
|
+
a pattern for `/issue/<slug>-<d>` would also claim `/#/issue/<d>`, and an
|
|
171
|
+
app that means different things by the two would resolve the wrong object.
|
|
172
|
+
*/
|
|
173
|
+
const fragmentPath = fragment && fragment.startsWith('/') ? fragment : '';
|
|
152
174
|
return {
|
|
153
175
|
scheme: scheme.toLowerCase(),
|
|
154
176
|
host: host.toLowerCase(),
|
|
155
|
-
segments: (path ?? '').split('/').filter(Boolean),
|
|
177
|
+
segments: [...(path ?? '').split('/'), ...fragmentPath.split('/')].filter(Boolean),
|
|
178
|
+
fragmented: fragmentPath !== '',
|
|
156
179
|
};
|
|
157
180
|
}
|
|
158
181
|
//# sourceMappingURL=objectUrl.js.map
|
package/dist/objectUrl.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"objectUrl.js","sourceRoot":"","sources":["../src/objectUrl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH;;;;;;GAMG;AACH,MAAM,gBAAgB,GAAG,gEAAgE,CAAA;AAEzF;;;;GAIG;AACH,MAAM,eAAe,GAAG,EAAE,CAAA;AAE1B;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,KAAa;IACnC,OAAO,KAAK;SACT,SAAS,CAAC,MAAM,CAAC;SACjB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC;SACzB,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;AACxB,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,SAAS,CAAC,UAAkB,EAAE,KAAc;IAC1D,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IACxC,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,UAAU,EAAE,CAAC,CAAC,CAAC,UAAU,CAAA;AACpD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC3C,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACxC,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;AAC9C,CAAC;AA2BD,mDAAmD;AACnD,MAAM,UAAU,aAAa,CAAC,KAA2B;IACvD,MAAM,GAAG,GAAiB,EAAE,CAAA;IAC5B,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,SAAQ;QAC1C,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QAChD,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;IAC5E,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AASD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW,EAAE,QAAsB;IAChE,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAA;IAC5B,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IAExB,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,QAAQ,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAA;QAC/B,IAAI,CAAC,KAAK;YAAE,SAAQ;QACpB,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI;YAAE,SAAQ;
|
|
1
|
+
{"version":3,"file":"objectUrl.js","sourceRoot":"","sources":["../src/objectUrl.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@estiva-app/interop",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"description": "Render and act on another app's objects from its published NIP-89 manifest. The owner defines the projection; the consumer decides how it looks.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
package/src/objectUrl.ts
CHANGED
|
@@ -145,6 +145,8 @@ export function matchObjectUrl(url: string, patterns: UrlPattern[]): MatchedObje
|
|
|
145
145
|
const shape = splitUrl(pattern)
|
|
146
146
|
if (!shape) continue
|
|
147
147
|
if (shape.scheme !== target.scheme || shape.host !== target.host) continue
|
|
148
|
+
// A fragment route and a path route are different shapes, not one.
|
|
149
|
+
if (shape.fragmented !== target.fragmented) continue
|
|
148
150
|
|
|
149
151
|
// The pattern's path up to its final segment: `/issue/` out of
|
|
150
152
|
// `/issue/<slug>-<d>`. Compared literally and at equal depth, so `/issues`
|
|
@@ -180,13 +182,34 @@ export function matchObjectUrl(url: string, patterns: UrlPattern[]): MatchedObje
|
|
|
180
182
|
* refusal local to the parser rather than a consequence of what apps happen to
|
|
181
183
|
* declare.
|
|
182
184
|
*/
|
|
183
|
-
function splitUrl(raw: string): { scheme: string; host: string; segments: string[] } | null {
|
|
184
|
-
const match = /^(https?):\/\/([^/?#]+)([^?#]*)
|
|
185
|
+
function splitUrl(raw: string): { scheme: string; host: string; segments: string[]; fragmented: boolean } | null {
|
|
186
|
+
const match = /^(https?):\/\/([^/?#]+)([^?#]*)(?:\?[^#]*)?(?:#(.*))?$/i.exec(raw.trim())
|
|
185
187
|
if (!match) return null
|
|
186
|
-
const [, scheme, host, path] = match
|
|
188
|
+
const [, scheme, host, path, fragment] = match
|
|
189
|
+
|
|
190
|
+
/*
|
|
191
|
+
A fragment route counts as path.
|
|
192
|
+
|
|
193
|
+
Ship served `#/issue/<d>` until SHI-16 and still declares those shapes, so
|
|
194
|
+
that links already sitting in other people's messages resolve rather than
|
|
195
|
+
rendering as plain text for ever. A parser that stopped at the `#` — this
|
|
196
|
+
one did — matched none of them, which a production probe caught before any
|
|
197
|
+
consumer was built on it.
|
|
198
|
+
|
|
199
|
+
Segments from the path and the fragment are concatenated rather than
|
|
200
|
+
swapped, because an app may be served under a sub-path *and* use a
|
|
201
|
+
fragment: Ship's own dev URL is `localhost:5190/ship/#/…`, where both
|
|
202
|
+
halves carry meaning.
|
|
203
|
+
|
|
204
|
+
`fragmented` is kept so the two do not collapse into each other. Without it
|
|
205
|
+
a pattern for `/issue/<slug>-<d>` would also claim `/#/issue/<d>`, and an
|
|
206
|
+
app that means different things by the two would resolve the wrong object.
|
|
207
|
+
*/
|
|
208
|
+
const fragmentPath = fragment && fragment.startsWith('/') ? fragment : ''
|
|
187
209
|
return {
|
|
188
210
|
scheme: scheme.toLowerCase(),
|
|
189
211
|
host: host.toLowerCase(),
|
|
190
|
-
segments: (path ?? '').split('/').filter(Boolean),
|
|
212
|
+
segments: [...(path ?? '').split('/'), ...fragmentPath.split('/')].filter(Boolean),
|
|
213
|
+
fragmented: fragmentPath !== '',
|
|
191
214
|
}
|
|
192
215
|
}
|