@fedify/testing 2.4.0-pr.936.41 → 2.5.0-dev.2271
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 +27 -0
- package/dist/mod.cjs +586 -173
- package/dist/mod.d.cts +72 -6
- package/dist/mod.d.ts +72 -6
- package/dist/mod.js +476 -71
- package/package.json +5 -3
package/dist/mod.cjs
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
let _fedify_fedify_sig = require("@fedify/fedify/sig");
|
|
4
4
|
let _fedify_vocab = require("@fedify/vocab");
|
|
5
|
+
let _fedify_vocab_runtime = require("@fedify/vocab-runtime");
|
|
5
6
|
let _fedify_fedify_federation = require("@fedify/fedify/federation");
|
|
6
7
|
let es_toolkit = require("es-toolkit");
|
|
7
8
|
let node_assert_strict = require("node:assert/strict");
|
|
@@ -38,7 +39,7 @@ const noopMeterProvider$1 = { getMeter: () => ({
|
|
|
38
39
|
removeBatchObservableCallback: () => void 0
|
|
39
40
|
}) };
|
|
40
41
|
function createContext(values) {
|
|
41
|
-
const { federation, url = new URL("http://example.com/"), canonicalOrigin, data, documentLoader, contextLoader, meterProvider, tracerProvider, clone, getNodeInfoUri, getActorUri, getObjectUri, getCollectionUri, getOutboxUri, getMediaUploaderUri, getInboxUri, getFollowingUri, getFollowersUri, getLikedUri, getFeaturedUri, getFeaturedTagsUri, parseUri, getActorKeyPairs, getDocumentLoader, lookupObject, traverseCollection, lookupNodeInfo, lookupWebFinger, sendActivity, routeActivity, enqueueTask, enqueueTaskMany } = values;
|
|
42
|
+
const { federation, url = new URL("http://example.com/"), canonicalOrigin, data, documentLoader, contextLoader, verifyPortableObject, meterProvider, tracerProvider, clone, getNodeInfoUri, getActorUri, getPortableActorUri, getObjectUri, getPortableObjectUri, getPortableInboxUri, getPortableOutboxUri, getPortableFollowingUri, getPortableFollowersUri, getPortableLikedUri, getPortableFeaturedUri, getPortableFeaturedTagsUri, getPortableCollectionUri, getCollectionUri, getOutboxUri, getMediaUploaderUri, getInboxUri, getFollowingUri, getFollowersUri, getLikedUri, getFeaturedUri, getFeaturedTagsUri, parseUri, getActorKeyPairs, getDocumentLoader, lookupObject, traverseCollection, lookupNodeInfo, lookupWebFinger, sendActivity, routeActivity, enqueueTask, enqueueTaskMany } = values;
|
|
42
43
|
function throwRouterError() {
|
|
43
44
|
throw new _fedify_fedify_federation.RouterError("Not implemented");
|
|
44
45
|
}
|
|
@@ -51,6 +52,7 @@ function createContext(values) {
|
|
|
51
52
|
hostname: url.hostname,
|
|
52
53
|
documentLoader: documentLoader ?? mockDocumentLoader,
|
|
53
54
|
contextLoader: contextLoader ?? mockDocumentLoader,
|
|
55
|
+
...verifyPortableObject == null ? {} : { verifyPortableObject },
|
|
54
56
|
meterProvider: meterProvider ?? noopMeterProvider$1,
|
|
55
57
|
tracerProvider: tracerProvider ?? noopTracerProvider$1,
|
|
56
58
|
clone: clone ?? ((data) => createContext({
|
|
@@ -59,7 +61,17 @@ function createContext(values) {
|
|
|
59
61
|
})),
|
|
60
62
|
getNodeInfoUri: getNodeInfoUri ?? throwRouterError,
|
|
61
63
|
getActorUri: getActorUri ?? throwRouterError,
|
|
64
|
+
getPortableActorUri: getPortableActorUri ?? throwRouterError,
|
|
62
65
|
getObjectUri: getObjectUri ?? throwRouterError,
|
|
66
|
+
getPortableObjectUri: getPortableObjectUri ?? throwRouterError,
|
|
67
|
+
getPortableInboxUri: getPortableInboxUri ?? throwRouterError,
|
|
68
|
+
getPortableOutboxUri: getPortableOutboxUri ?? throwRouterError,
|
|
69
|
+
getPortableFollowingUri: getPortableFollowingUri ?? throwRouterError,
|
|
70
|
+
getPortableFollowersUri: getPortableFollowersUri ?? throwRouterError,
|
|
71
|
+
getPortableLikedUri: getPortableLikedUri ?? throwRouterError,
|
|
72
|
+
getPortableFeaturedUri: getPortableFeaturedUri ?? throwRouterError,
|
|
73
|
+
getPortableFeaturedTagsUri: getPortableFeaturedTagsUri ?? throwRouterError,
|
|
74
|
+
getPortableCollectionUri: getPortableCollectionUri ?? throwRouterError,
|
|
63
75
|
getCollectionUri: getCollectionUri ?? throwRouterError,
|
|
64
76
|
getOutboxUri: getOutboxUri ?? throwRouterError,
|
|
65
77
|
getMediaUploaderUri: getMediaUploaderUri ?? throwRouterError,
|
|
@@ -79,13 +91,15 @@ function createContext(values) {
|
|
|
79
91
|
lookupObject: lookupObject ?? ((uri, options = {}) => {
|
|
80
92
|
return (0, _fedify_vocab.lookupObject)(uri, {
|
|
81
93
|
documentLoader: options.documentLoader ?? documentLoader ?? mockDocumentLoader,
|
|
82
|
-
contextLoader: options.contextLoader ?? contextLoader ?? mockDocumentLoader
|
|
94
|
+
contextLoader: options.contextLoader ?? contextLoader ?? mockDocumentLoader,
|
|
95
|
+
verifyPortableObject: options.verifyPortableObject ?? verifyPortableObject
|
|
83
96
|
});
|
|
84
97
|
}),
|
|
85
98
|
traverseCollection: traverseCollection ?? ((collection, options = {}) => {
|
|
86
99
|
return (0, _fedify_vocab.traverseCollection)(collection, {
|
|
87
100
|
documentLoader: options.documentLoader ?? documentLoader ?? mockDocumentLoader,
|
|
88
|
-
contextLoader: options.contextLoader ?? contextLoader ?? mockDocumentLoader
|
|
101
|
+
contextLoader: options.contextLoader ?? contextLoader ?? mockDocumentLoader,
|
|
102
|
+
verifyPortableObject: options.verifyPortableObject ?? verifyPortableObject
|
|
89
103
|
});
|
|
90
104
|
}),
|
|
91
105
|
lookupNodeInfo: lookupNodeInfo ?? ((_params) => {
|
|
@@ -124,15 +138,59 @@ function createRequestContext(args) {
|
|
|
124
138
|
})),
|
|
125
139
|
request: args.request ?? new Request(args.url),
|
|
126
140
|
url: args.url,
|
|
141
|
+
portableRequest: args.portableRequest,
|
|
127
142
|
getActor: args.getActor ?? (() => Promise.resolve(null)),
|
|
128
143
|
getObject: args.getObject ?? (() => Promise.resolve(null)),
|
|
129
144
|
getSignedKey: args.getSignedKey ?? (() => Promise.resolve(null)),
|
|
130
145
|
getSignedKeyOwner: args.getSignedKeyOwner ?? (() => Promise.resolve(null)),
|
|
146
|
+
isSignedByAudience: args.isSignedByAudience ?? ((object, options) => isSignedByAudience(() => args.getSignedKeyOwner == null ? Promise.resolve(null) : args.getSignedKeyOwner(options ?? {}), object, options?.isMember)),
|
|
131
147
|
sendActivity: args.sendActivity ?? ((_params) => {
|
|
132
148
|
throw new Error("Not implemented");
|
|
133
149
|
})
|
|
134
150
|
};
|
|
135
151
|
}
|
|
152
|
+
const PUBLIC_IDS = /* @__PURE__ */ new Set([
|
|
153
|
+
_fedify_vocab.PUBLIC_COLLECTION.href,
|
|
154
|
+
"as:Public",
|
|
155
|
+
"Public"
|
|
156
|
+
]);
|
|
157
|
+
function getPortableIri(id) {
|
|
158
|
+
try {
|
|
159
|
+
if (id.protocol === "ap:" || id.protocol === "ap+ef61:") return (0, _fedify_vocab_runtime.formatIri)(id);
|
|
160
|
+
const portable = (0, _fedify_vocab_runtime.fromCompatibleEf61Id)(id);
|
|
161
|
+
return portable == null ? null : (0, _fedify_vocab_runtime.formatIri)(portable);
|
|
162
|
+
} catch (error) {
|
|
163
|
+
if (error instanceof TypeError) return null;
|
|
164
|
+
throw error;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function isSameActorId(a, b) {
|
|
168
|
+
const portableA = getPortableIri(a);
|
|
169
|
+
const portableB = getPortableIri(b);
|
|
170
|
+
if (portableA != null || portableB != null) return portableA != null && portableB != null && (0, _fedify_vocab_runtime.arePortableUrisEqual)(portableA, portableB);
|
|
171
|
+
return a.href === b.href;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* The default implementation of `RequestContext.isSignedByAudience()` for
|
|
175
|
+
* testing, which checks the audience against `getSignedKeyOwner()`.
|
|
176
|
+
*/
|
|
177
|
+
async function isSignedByAudience(getSignedKeyOwner, object, isMember) {
|
|
178
|
+
const addressees = [
|
|
179
|
+
...object.toIds,
|
|
180
|
+
...object.ccIds,
|
|
181
|
+
...object.btoIds,
|
|
182
|
+
...object.bccIds,
|
|
183
|
+
...object.audienceIds
|
|
184
|
+
];
|
|
185
|
+
if (addressees.some((id) => PUBLIC_IDS.has(id.href))) return true;
|
|
186
|
+
const actor = await getSignedKeyOwner();
|
|
187
|
+
const actorId = actor?.id;
|
|
188
|
+
if (actor == null || actorId == null) return false;
|
|
189
|
+
if (addressees.some((id) => isSameActorId(id, actorId))) return true;
|
|
190
|
+
if (isMember == null) return false;
|
|
191
|
+
for (const addressee of addressees) if (await isMember(addressee, actor)) return true;
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
136
194
|
/**
|
|
137
195
|
* Creates an InboxContext for testing purposes.
|
|
138
196
|
* Not exported - used internally only. Public API is in mock.ts
|
|
@@ -226,6 +284,63 @@ function expandUriTemplate(template, values) {
|
|
|
226
284
|
}
|
|
227
285
|
});
|
|
228
286
|
}
|
|
287
|
+
/**
|
|
288
|
+
* Builds an FEP-ef61 portable ID from a DID authority and a path, validating
|
|
289
|
+
* the authority the same way as `@fedify/fedify` does.
|
|
290
|
+
*/
|
|
291
|
+
function buildPortableUri(authority, path) {
|
|
292
|
+
if (typeof authority !== "string" || !/^did:[a-z0-9]+:[^/?#]+$/i.test(authority)) throw new TypeError("The authority of a portable ID must be a DID without a path, query, or fragment.");
|
|
293
|
+
const did = (0, _fedify_vocab_runtime.getFe34Origin)(authority);
|
|
294
|
+
if (!isBase58BtcDidKey(did)) throw new TypeError("The did:key authority of a portable ID must be encoded in base58-btc, i.e., start with z.");
|
|
295
|
+
return (0, _fedify_vocab_runtime.parseIri)(`ap+ef61://${did}${path}`);
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Checks that a normalized DID, if it is a `did:key` DID, is encoded in
|
|
299
|
+
* base58-btc, as `@fedify/fedify` requires of portable IDs.
|
|
300
|
+
*/
|
|
301
|
+
function isBase58BtcDidKey(did) {
|
|
302
|
+
return !did.startsWith("did:key:") || /^z[1-9A-HJ-NP-Za-km-z]+$/.test(did.slice(8));
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Recognizes an FEP-ef61 portable ID, i.e., an `ap:` or `ap+ef61:` URI, or
|
|
306
|
+
* a compatible identifier on any gateway, validating it the same way as
|
|
307
|
+
* `Context.parseUri()` of `@fedify/fedify` does.
|
|
308
|
+
* @returns The DID and the path of the portable ID, `null` if it is
|
|
309
|
+
* malformed, or `undefined` if the URI is not a portable ID.
|
|
310
|
+
*/
|
|
311
|
+
function parseMockPortableId(uri) {
|
|
312
|
+
const portable = uri.protocol === "ap:" || uri.protocol === "ap+ef61:";
|
|
313
|
+
if (!portable && !((uri.protocol === "http:" || uri.protocol === "https:") && /^\/\.well-known\/apgateway\/did(?::|%3A)/i.test(uri.pathname))) return;
|
|
314
|
+
if (uri.username !== "" || uri.password !== "") return null;
|
|
315
|
+
try {
|
|
316
|
+
const id = portable ? (0, _fedify_vocab_runtime.parseIri)(uri) : (0, _fedify_vocab_runtime.fromCompatibleEf61Id)(uri.origin + uri.pathname);
|
|
317
|
+
if (id == null) return null;
|
|
318
|
+
(0, _fedify_vocab_runtime.canonicalizePortableUri)((0, _fedify_vocab_runtime.formatIri)(id));
|
|
319
|
+
const authority = (0, _fedify_vocab_runtime.getFe34Origin)(id);
|
|
320
|
+
if (!isBase58BtcDidKey(authority)) return null;
|
|
321
|
+
return {
|
|
322
|
+
authority,
|
|
323
|
+
path: id.pathname
|
|
324
|
+
};
|
|
325
|
+
} catch (error) {
|
|
326
|
+
if (error instanceof TypeError) return null;
|
|
327
|
+
throw error;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Parses a path in the way {@link MockContext.parseUri} does, i.e., only
|
|
332
|
+
* `/users/{identifier}` and its subpaths are recognized, as actors.
|
|
333
|
+
*/
|
|
334
|
+
function parseMockPath(path) {
|
|
335
|
+
if (path.startsWith("/users/")) {
|
|
336
|
+
const parts = path.split("/");
|
|
337
|
+
if (parts.length >= 3) return {
|
|
338
|
+
type: "actor",
|
|
339
|
+
identifier: parts[2]
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
return null;
|
|
343
|
+
}
|
|
229
344
|
function validateOutboxListenerPath(path, dispatcherPath) {
|
|
230
345
|
if (!path.startsWith("/")) throw new TypeError("Path must start with a slash.");
|
|
231
346
|
if (dispatcherPath != null && dispatcherPath !== path) throw new TypeError("Outbox listener path and outbox dispatcher path must match.");
|
|
@@ -302,6 +417,7 @@ var MockFederation = class {
|
|
|
302
417
|
outboxListenerErrorHandler;
|
|
303
418
|
mediaUploaderCallback;
|
|
304
419
|
mediaUploaderAuthorizePredicate;
|
|
420
|
+
hashlinkMediaDispatcher;
|
|
305
421
|
followingDispatcher;
|
|
306
422
|
followersDispatcher;
|
|
307
423
|
likedDispatcher;
|
|
@@ -339,93 +455,103 @@ var MockFederation = class {
|
|
|
339
455
|
setActorDispatcher(path, dispatcher) {
|
|
340
456
|
this.actorDispatchers.set(path, dispatcher);
|
|
341
457
|
this.actorPath = path;
|
|
342
|
-
|
|
458
|
+
const setters = {
|
|
343
459
|
setKeyPairsDispatcher: (keyPairsDispatcher) => {
|
|
344
460
|
this.actorKeyPairsDispatcher = keyPairsDispatcher;
|
|
345
|
-
return
|
|
461
|
+
return setters;
|
|
346
462
|
},
|
|
347
|
-
mapHandle: () =>
|
|
348
|
-
mapAlias: () =>
|
|
349
|
-
|
|
463
|
+
mapHandle: () => setters,
|
|
464
|
+
mapAlias: () => setters,
|
|
465
|
+
mapPortableActorId: () => setters,
|
|
466
|
+
authorize: () => setters
|
|
350
467
|
};
|
|
468
|
+
return setters;
|
|
351
469
|
}
|
|
352
470
|
setObjectDispatcher(cls, path, dispatcher) {
|
|
353
471
|
this.objectDispatchers.set(path, dispatcher);
|
|
354
472
|
this.objectPaths.set(cls.typeId.href, path);
|
|
355
|
-
|
|
473
|
+
const setters = { authorize: () => setters };
|
|
474
|
+
return setters;
|
|
356
475
|
}
|
|
357
476
|
setInboxDispatcher(_path, dispatcher) {
|
|
358
477
|
this.inboxDispatcher = dispatcher;
|
|
359
|
-
|
|
360
|
-
setCounter: () =>
|
|
361
|
-
setFirstCursor: () =>
|
|
362
|
-
setLastCursor: () =>
|
|
363
|
-
authorize: () =>
|
|
478
|
+
const setters = {
|
|
479
|
+
setCounter: () => setters,
|
|
480
|
+
setFirstCursor: () => setters,
|
|
481
|
+
setLastCursor: () => setters,
|
|
482
|
+
authorize: () => setters
|
|
364
483
|
};
|
|
484
|
+
return setters;
|
|
365
485
|
}
|
|
366
486
|
setOutboxDispatcher(path, dispatcher) {
|
|
367
487
|
validateOutboxListenerPath(path, this.outboxListenersInitialized ? this.outboxPath : void 0);
|
|
368
488
|
this.outboxDispatcher = dispatcher;
|
|
369
489
|
this.outboxPath = path;
|
|
370
|
-
|
|
371
|
-
setCounter: () =>
|
|
372
|
-
setFirstCursor: () =>
|
|
373
|
-
setLastCursor: () =>
|
|
490
|
+
const setters = {
|
|
491
|
+
setCounter: () => setters,
|
|
492
|
+
setFirstCursor: () => setters,
|
|
493
|
+
setLastCursor: () => setters,
|
|
374
494
|
authorize: (predicate) => {
|
|
375
495
|
this.outboxDispatcherAuthorizePredicate = predicate;
|
|
376
|
-
return
|
|
496
|
+
return setters;
|
|
377
497
|
}
|
|
378
498
|
};
|
|
499
|
+
return setters;
|
|
379
500
|
}
|
|
380
501
|
setFollowingDispatcher(path, dispatcher) {
|
|
381
502
|
this.followingDispatcher = dispatcher;
|
|
382
503
|
this.followingPath = path;
|
|
383
|
-
|
|
384
|
-
setCounter: () =>
|
|
385
|
-
setFirstCursor: () =>
|
|
386
|
-
setLastCursor: () =>
|
|
387
|
-
authorize: () =>
|
|
504
|
+
const setters = {
|
|
505
|
+
setCounter: () => setters,
|
|
506
|
+
setFirstCursor: () => setters,
|
|
507
|
+
setLastCursor: () => setters,
|
|
508
|
+
authorize: () => setters
|
|
388
509
|
};
|
|
510
|
+
return setters;
|
|
389
511
|
}
|
|
390
512
|
setFollowersDispatcher(path, dispatcher) {
|
|
391
513
|
this.followersDispatcher = dispatcher;
|
|
392
514
|
this.followersPath = path;
|
|
393
|
-
|
|
394
|
-
setCounter: () =>
|
|
395
|
-
setFirstCursor: () =>
|
|
396
|
-
setLastCursor: () =>
|
|
397
|
-
authorize: () =>
|
|
515
|
+
const setters = {
|
|
516
|
+
setCounter: () => setters,
|
|
517
|
+
setFirstCursor: () => setters,
|
|
518
|
+
setLastCursor: () => setters,
|
|
519
|
+
authorize: () => setters
|
|
398
520
|
};
|
|
521
|
+
return setters;
|
|
399
522
|
}
|
|
400
523
|
setLikedDispatcher(path, dispatcher) {
|
|
401
524
|
this.likedDispatcher = dispatcher;
|
|
402
525
|
this.likedPath = path;
|
|
403
|
-
|
|
404
|
-
setCounter: () =>
|
|
405
|
-
setFirstCursor: () =>
|
|
406
|
-
setLastCursor: () =>
|
|
407
|
-
authorize: () =>
|
|
526
|
+
const setters = {
|
|
527
|
+
setCounter: () => setters,
|
|
528
|
+
setFirstCursor: () => setters,
|
|
529
|
+
setLastCursor: () => setters,
|
|
530
|
+
authorize: () => setters
|
|
408
531
|
};
|
|
532
|
+
return setters;
|
|
409
533
|
}
|
|
410
534
|
setFeaturedDispatcher(path, dispatcher) {
|
|
411
535
|
this.featuredDispatcher = dispatcher;
|
|
412
536
|
this.featuredPath = path;
|
|
413
|
-
|
|
414
|
-
setCounter: () =>
|
|
415
|
-
setFirstCursor: () =>
|
|
416
|
-
setLastCursor: () =>
|
|
417
|
-
authorize: () =>
|
|
537
|
+
const setters = {
|
|
538
|
+
setCounter: () => setters,
|
|
539
|
+
setFirstCursor: () => setters,
|
|
540
|
+
setLastCursor: () => setters,
|
|
541
|
+
authorize: () => setters
|
|
418
542
|
};
|
|
543
|
+
return setters;
|
|
419
544
|
}
|
|
420
545
|
setFeaturedTagsDispatcher(path, dispatcher) {
|
|
421
546
|
this.featuredTagsDispatcher = dispatcher;
|
|
422
547
|
this.featuredTagsPath = path;
|
|
423
|
-
|
|
424
|
-
setCounter: () =>
|
|
425
|
-
setFirstCursor: () =>
|
|
426
|
-
setLastCursor: () =>
|
|
427
|
-
authorize: () =>
|
|
548
|
+
const setters = {
|
|
549
|
+
setCounter: () => setters,
|
|
550
|
+
setFirstCursor: () => setters,
|
|
551
|
+
setLastCursor: () => setters,
|
|
552
|
+
authorize: () => setters
|
|
428
553
|
};
|
|
554
|
+
return setters;
|
|
429
555
|
}
|
|
430
556
|
setInboxListeners(inboxPath, sharedInboxPath) {
|
|
431
557
|
this.inboxPath = inboxPath;
|
|
@@ -444,6 +570,9 @@ var MockFederation = class {
|
|
|
444
570
|
onUnverifiedActivity() {
|
|
445
571
|
return this;
|
|
446
572
|
},
|
|
573
|
+
onRequestFinished() {
|
|
574
|
+
return this;
|
|
575
|
+
},
|
|
447
576
|
setSharedKeyDispatcher() {
|
|
448
577
|
return this;
|
|
449
578
|
},
|
|
@@ -484,6 +613,10 @@ var MockFederation = class {
|
|
|
484
613
|
return this;
|
|
485
614
|
} };
|
|
486
615
|
}
|
|
616
|
+
setHashlinkMediaDispatcher(dispatcher) {
|
|
617
|
+
if (this.hashlinkMediaDispatcher != null) throw new TypeError("Hashlink media dispatcher already set.");
|
|
618
|
+
this.hashlinkMediaDispatcher = dispatcher;
|
|
619
|
+
}
|
|
487
620
|
setOutboxPermanentFailureHandler(_handler) {}
|
|
488
621
|
async startQueue(contextData, options) {
|
|
489
622
|
this.contextData = contextData;
|
|
@@ -499,7 +632,7 @@ var MockFederation = class {
|
|
|
499
632
|
async processQueuedTask(contextData, _message) {
|
|
500
633
|
this.contextData = contextData;
|
|
501
634
|
}
|
|
502
|
-
createContext(baseUrlOrRequest, contextData) {
|
|
635
|
+
createContext(baseUrlOrRequest, contextData, options = {}) {
|
|
503
636
|
const mockFederation = this;
|
|
504
637
|
const request = baseUrlOrRequest instanceof Request ? baseUrlOrRequest : null;
|
|
505
638
|
return new MockContext({
|
|
@@ -508,10 +641,63 @@ var MockFederation = class {
|
|
|
508
641
|
data: contextData,
|
|
509
642
|
federation: mockFederation,
|
|
510
643
|
meterProvider: this.options.meterProvider,
|
|
511
|
-
tracerProvider: this.options.tracerProvider
|
|
644
|
+
tracerProvider: this.options.tracerProvider,
|
|
645
|
+
documentLoader: this.options.documentLoader,
|
|
646
|
+
contextLoader: this.options.contextLoader,
|
|
647
|
+
verifyPortableObject: this.options.verifyPortableObject,
|
|
648
|
+
portableRequest: options.portableRequest
|
|
512
649
|
});
|
|
513
650
|
}
|
|
514
651
|
async fetch(request, options) {
|
|
652
|
+
if (this.hashlinkMediaDispatcher != null) {
|
|
653
|
+
const url = new URL(request.url);
|
|
654
|
+
if ((url.protocol === "http:" || url.protocol === "https:") && url.pathname.startsWith("/.well-known/apgateway/")) {
|
|
655
|
+
const encoded = url.pathname.slice(23);
|
|
656
|
+
if (/^hl(?::|%3A)/i.test(encoded)) {
|
|
657
|
+
if (request.method !== "GET" && request.method !== "HEAD") return new Response("Method not allowed.", {
|
|
658
|
+
status: 405,
|
|
659
|
+
headers: {
|
|
660
|
+
Allow: "GET, HEAD",
|
|
661
|
+
"Content-Type": "text/plain; charset=utf-8"
|
|
662
|
+
}
|
|
663
|
+
});
|
|
664
|
+
let media;
|
|
665
|
+
try {
|
|
666
|
+
let hashlink;
|
|
667
|
+
try {
|
|
668
|
+
hashlink = decodeURIComponent(encoded);
|
|
669
|
+
} catch (error) {
|
|
670
|
+
throw new TypeError("Invalid percent-encoding in the hashlink.", { cause: error });
|
|
671
|
+
}
|
|
672
|
+
const { digestMultibase } = (0, _fedify_vocab_runtime.parseHashlink)(hashlink);
|
|
673
|
+
const { digest } = (0, _fedify_vocab_runtime.parseDigestMultibase)(digestMultibase);
|
|
674
|
+
media = globalThis.Object.freeze({
|
|
675
|
+
hashlink: `hl:${digestMultibase}`,
|
|
676
|
+
digestMultibase,
|
|
677
|
+
algorithm: "sha2-256",
|
|
678
|
+
digest,
|
|
679
|
+
multihash: (0, _fedify_vocab_runtime.decodeMultibase)(digestMultibase)
|
|
680
|
+
});
|
|
681
|
+
} catch (error) {
|
|
682
|
+
if (!(error instanceof TypeError)) throw error;
|
|
683
|
+
return new Response(request.method === "HEAD" ? null : "Malformed hashlink.", {
|
|
684
|
+
status: 400,
|
|
685
|
+
headers: { "Content-Type": "text/plain; charset=utf-8" }
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
const context = this.createContext(request, options.contextData);
|
|
689
|
+
const response = await this.hashlinkMediaDispatcher(context, media);
|
|
690
|
+
if (response == null) return options.onNotFound == null ? new Response("Not Found", { status: 404 }) : await options.onNotFound(request);
|
|
691
|
+
if (request.method !== "HEAD" || response.body == null) return response;
|
|
692
|
+
response.body.cancel().catch(() => {});
|
|
693
|
+
return new Response(null, {
|
|
694
|
+
status: response.status,
|
|
695
|
+
statusText: response.statusText,
|
|
696
|
+
headers: response.headers
|
|
697
|
+
});
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
}
|
|
515
701
|
if (options.onNotFound) return options.onNotFound(request);
|
|
516
702
|
return new Response("Not Found", { status: 404 });
|
|
517
703
|
}
|
|
@@ -619,20 +805,24 @@ var MockFederation = class {
|
|
|
619
805
|
this.sentActivities = [];
|
|
620
806
|
}
|
|
621
807
|
setCollectionDispatcher(_name, _itemType, _path, _dispatcher) {
|
|
622
|
-
|
|
623
|
-
setCounter: () =>
|
|
624
|
-
setFirstCursor: () =>
|
|
625
|
-
setLastCursor: () =>
|
|
626
|
-
authorize: () =>
|
|
808
|
+
const setters = {
|
|
809
|
+
setCounter: () => setters,
|
|
810
|
+
setFirstCursor: () => setters,
|
|
811
|
+
setLastCursor: () => setters,
|
|
812
|
+
authorize: () => setters,
|
|
813
|
+
mapPortableOwner: () => setters
|
|
627
814
|
};
|
|
815
|
+
return setters;
|
|
628
816
|
}
|
|
629
817
|
setOrderedCollectionDispatcher(_name, _itemType, _path, _dispatcher) {
|
|
630
|
-
|
|
631
|
-
setCounter: () =>
|
|
632
|
-
setFirstCursor: () =>
|
|
633
|
-
setLastCursor: () =>
|
|
634
|
-
authorize: () =>
|
|
818
|
+
const setters = {
|
|
819
|
+
setCounter: () => setters,
|
|
820
|
+
setFirstCursor: () => setters,
|
|
821
|
+
setLastCursor: () => setters,
|
|
822
|
+
authorize: () => setters,
|
|
823
|
+
mapPortableOwner: () => setters
|
|
635
824
|
};
|
|
825
|
+
return setters;
|
|
636
826
|
}
|
|
637
827
|
};
|
|
638
828
|
/**
|
|
@@ -730,6 +920,10 @@ var MockContext = class MockContext {
|
|
|
730
920
|
tracerProvider;
|
|
731
921
|
request;
|
|
732
922
|
url;
|
|
923
|
+
portableRequest;
|
|
924
|
+
verifyPortableObject;
|
|
925
|
+
hasDocumentLoader;
|
|
926
|
+
hasContextLoader;
|
|
733
927
|
sentActivities = [];
|
|
734
928
|
constructor(options) {
|
|
735
929
|
const url = options.url ?? new URL("https://example.com");
|
|
@@ -739,6 +933,10 @@ var MockContext = class MockContext {
|
|
|
739
933
|
this.hostname = url.hostname;
|
|
740
934
|
this.url = url;
|
|
741
935
|
this.request = options.request ?? new Request(url);
|
|
936
|
+
this.portableRequest = options.portableRequest;
|
|
937
|
+
this.verifyPortableObject = options.verifyPortableObject;
|
|
938
|
+
this.hasDocumentLoader = options.hasDocumentLoader ?? options.documentLoader != null;
|
|
939
|
+
this.hasContextLoader = options.hasContextLoader ?? options.contextLoader != null;
|
|
742
940
|
this.data = options.data;
|
|
743
941
|
this.federation = options.federation;
|
|
744
942
|
this.documentLoader = options.documentLoader ?? (async (url) => ({
|
|
@@ -757,12 +955,16 @@ var MockContext = class MockContext {
|
|
|
757
955
|
}
|
|
758
956
|
return null;
|
|
759
957
|
}
|
|
760
|
-
async getObject(cls, values) {
|
|
958
|
+
async getObject(cls, values, options) {
|
|
761
959
|
if (this.federation instanceof MockFederation) {
|
|
762
960
|
const path = this.federation.objectPaths.get(cls.typeId.href);
|
|
763
961
|
if (path) {
|
|
764
962
|
const dispatcher = this.federation.objectDispatchers.get(path);
|
|
765
|
-
if (dispatcher)
|
|
963
|
+
if (dispatcher) {
|
|
964
|
+
const object = await dispatcher(this, values);
|
|
965
|
+
if (object instanceof _fedify_vocab.Tombstone && !(object instanceof cls) && options?.tombstone !== "passthrough") return null;
|
|
966
|
+
return object;
|
|
967
|
+
}
|
|
766
968
|
}
|
|
767
969
|
}
|
|
768
970
|
return null;
|
|
@@ -773,6 +975,9 @@ var MockContext = class MockContext {
|
|
|
773
975
|
getSignedKeyOwner() {
|
|
774
976
|
return Promise.resolve(null);
|
|
775
977
|
}
|
|
978
|
+
isSignedByAudience(object, options) {
|
|
979
|
+
return isSignedByAudience(() => this.getSignedKeyOwner(), object, options?.isMember);
|
|
980
|
+
}
|
|
776
981
|
#resolveTaskDefinition(task) {
|
|
777
982
|
if (!(this.federation instanceof MockFederation)) throw new TypeError("No task definitions are available.");
|
|
778
983
|
const def = this.federation.taskDefinitions.get(task.name);
|
|
@@ -796,10 +1001,15 @@ var MockContext = class MockContext {
|
|
|
796
1001
|
clone(data) {
|
|
797
1002
|
return new MockContext({
|
|
798
1003
|
url: this.url,
|
|
1004
|
+
request: this.request,
|
|
799
1005
|
data,
|
|
800
1006
|
federation: this.federation,
|
|
801
1007
|
documentLoader: this.documentLoader,
|
|
802
1008
|
contextLoader: this.contextLoader,
|
|
1009
|
+
verifyPortableObject: this.verifyPortableObject,
|
|
1010
|
+
portableRequest: this.portableRequest,
|
|
1011
|
+
hasDocumentLoader: this.hasDocumentLoader,
|
|
1012
|
+
hasContextLoader: this.hasContextLoader,
|
|
803
1013
|
meterProvider: this.meterProvider,
|
|
804
1014
|
tracerProvider: this.tracerProvider
|
|
805
1015
|
});
|
|
@@ -826,6 +1036,46 @@ var MockContext = class MockContext {
|
|
|
826
1036
|
const path = globalThis.Object.entries(values).map(([key, value]) => `${key}/${value}`).join("/");
|
|
827
1037
|
return new URL(`/objects/${cls.name.toLowerCase()}/${path}`, this.origin);
|
|
828
1038
|
}
|
|
1039
|
+
getPortableActorUri(identifier, authority) {
|
|
1040
|
+
const { pathname } = this.getActorUri(identifier);
|
|
1041
|
+
return buildPortableUri(authority, pathname);
|
|
1042
|
+
}
|
|
1043
|
+
getPortableObjectUri(cls, values, authority) {
|
|
1044
|
+
const { pathname } = this.getObjectUri(cls, values);
|
|
1045
|
+
return buildPortableUri(authority, pathname);
|
|
1046
|
+
}
|
|
1047
|
+
getPortableInboxUri(identifier, authority) {
|
|
1048
|
+
const { pathname } = this.getInboxUri(identifier);
|
|
1049
|
+
return buildPortableUri(authority, pathname);
|
|
1050
|
+
}
|
|
1051
|
+
getPortableOutboxUri(identifier, authority) {
|
|
1052
|
+
const { pathname } = this.getOutboxUri(identifier);
|
|
1053
|
+
return buildPortableUri(authority, pathname);
|
|
1054
|
+
}
|
|
1055
|
+
getPortableFollowingUri(identifier, authority) {
|
|
1056
|
+
const { pathname } = this.getFollowingUri(identifier);
|
|
1057
|
+
return buildPortableUri(authority, pathname);
|
|
1058
|
+
}
|
|
1059
|
+
getPortableFollowersUri(identifier, authority) {
|
|
1060
|
+
const { pathname } = this.getFollowersUri(identifier);
|
|
1061
|
+
return buildPortableUri(authority, pathname);
|
|
1062
|
+
}
|
|
1063
|
+
getPortableLikedUri(identifier, authority) {
|
|
1064
|
+
const { pathname } = this.getLikedUri(identifier);
|
|
1065
|
+
return buildPortableUri(authority, pathname);
|
|
1066
|
+
}
|
|
1067
|
+
getPortableFeaturedUri(identifier, authority) {
|
|
1068
|
+
const { pathname } = this.getFeaturedUri(identifier);
|
|
1069
|
+
return buildPortableUri(authority, pathname);
|
|
1070
|
+
}
|
|
1071
|
+
getPortableFeaturedTagsUri(identifier, authority) {
|
|
1072
|
+
const { pathname } = this.getFeaturedTagsUri(identifier);
|
|
1073
|
+
return buildPortableUri(authority, pathname);
|
|
1074
|
+
}
|
|
1075
|
+
getPortableCollectionUri(name, values, authority) {
|
|
1076
|
+
const { pathname } = this.getCollectionUri(name, values);
|
|
1077
|
+
return buildPortableUri(authority, pathname);
|
|
1078
|
+
}
|
|
829
1079
|
getOutboxUri(identifier) {
|
|
830
1080
|
if (this.federation instanceof MockFederation && this.federation.outboxPath) {
|
|
831
1081
|
const path = expandUriTemplate(this.federation.outboxPath, { identifier });
|
|
@@ -890,15 +1140,16 @@ var MockContext = class MockContext {
|
|
|
890
1140
|
const path = globalThis.Object.entries(values).map(([key, value]) => `${key}/${value}`).join("/");
|
|
891
1141
|
return new URL(`/collections/${String(_name)}/${path}`, this.origin);
|
|
892
1142
|
}
|
|
893
|
-
parseUri(uri) {
|
|
894
|
-
if (uri
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
1143
|
+
parseUri(uri, options = {}) {
|
|
1144
|
+
if (uri == null) return null;
|
|
1145
|
+
const portable = parseMockPortableId(uri);
|
|
1146
|
+
if (portable === void 0) return parseMockPath(uri.pathname);
|
|
1147
|
+
if (portable === null || !options.portable) return null;
|
|
1148
|
+
const result = parseMockPath(portable.path);
|
|
1149
|
+
return result == null ? null : {
|
|
1150
|
+
...result,
|
|
1151
|
+
authority: portable.authority
|
|
1152
|
+
};
|
|
902
1153
|
}
|
|
903
1154
|
async getActorKeyPairs(identifier) {
|
|
904
1155
|
if (this.federation instanceof MockFederation && this.federation.actorKeyPairsDispatcher) {
|
|
@@ -924,8 +1175,21 @@ var MockContext = class MockContext {
|
|
|
924
1175
|
if ("keyId" in params) return this.documentLoader;
|
|
925
1176
|
return Promise.resolve(this.documentLoader);
|
|
926
1177
|
}
|
|
927
|
-
lookupObject(
|
|
928
|
-
return Promise.resolve(null);
|
|
1178
|
+
lookupObject(uri, options = {}) {
|
|
1179
|
+
if (!this.hasDocumentLoader && options.documentLoader == null || (options.verifyPortableObject ?? this.verifyPortableObject) == null) return Promise.resolve(null);
|
|
1180
|
+
const value = typeof uri === "string" ? uri : (0, _fedify_vocab_runtime.formatIri)(uri);
|
|
1181
|
+
if (!/^ap(?:\+ef61)?:\/\//i.test(value)) try {
|
|
1182
|
+
if ((0, _fedify_vocab_runtime.fromCompatibleEf61Id)(value) == null) return Promise.resolve(null);
|
|
1183
|
+
} catch (error) {
|
|
1184
|
+
if (error instanceof TypeError) return Promise.resolve(null);
|
|
1185
|
+
throw error;
|
|
1186
|
+
}
|
|
1187
|
+
return (0, _fedify_vocab.lookupObject)(uri, {
|
|
1188
|
+
...options,
|
|
1189
|
+
documentLoader: options.documentLoader ?? this.documentLoader,
|
|
1190
|
+
contextLoader: options.contextLoader ?? (this.hasContextLoader ? this.contextLoader : options.documentLoader ?? this.contextLoader),
|
|
1191
|
+
verifyPortableObject: options.verifyPortableObject ?? this.verifyPortableObject
|
|
1192
|
+
});
|
|
929
1193
|
}
|
|
930
1194
|
traverseCollection(_collection, _options) {
|
|
931
1195
|
return { async *[Symbol.asyncIterator]() {} };
|
|
@@ -1129,7 +1393,7 @@ function parseInt0(s) {
|
|
|
1129
1393
|
function padNumber(digits, num) {
|
|
1130
1394
|
return String(num).padStart(digits, "0");
|
|
1131
1395
|
}
|
|
1132
|
-
const padNumber2 =
|
|
1396
|
+
const padNumber2 = /*@__PURE__*/ bindArgs(padNumber, 2);
|
|
1133
1397
|
function compareNumbers(a, b) {
|
|
1134
1398
|
return Math.sign(a - b);
|
|
1135
1399
|
}
|
|
@@ -1197,7 +1461,7 @@ const unitNameMap = {
|
|
|
1197
1461
|
month: 8,
|
|
1198
1462
|
year: 9
|
|
1199
1463
|
};
|
|
1200
|
-
const unitNamesAsc =
|
|
1464
|
+
const unitNamesAsc = /*@__PURE__*/ Object.keys(unitNameMap);
|
|
1201
1465
|
const nanoInMicro = nanoInMicro$1;
|
|
1202
1466
|
const nanoInMilli = nanoInMilli$1;
|
|
1203
1467
|
const nanoInSec = nanoInSec$1;
|
|
@@ -1213,19 +1477,19 @@ const unitNanoMap = [
|
|
|
1213
1477
|
nanoInHour,
|
|
1214
1478
|
nanoInUtcDay
|
|
1215
1479
|
];
|
|
1216
|
-
const bigNanoInMicro =
|
|
1217
|
-
const bigNanoInMilli =
|
|
1218
|
-
const bigNanoInSec =
|
|
1219
|
-
const bigNanoInMinute =
|
|
1220
|
-
const bigNanoInHour =
|
|
1221
|
-
const bigNanoInUtcDay =
|
|
1480
|
+
const bigNanoInMicro = /*@__PURE__*/ BigInt(nanoInMicro);
|
|
1481
|
+
const bigNanoInMilli = /*@__PURE__*/ BigInt(nanoInMilli);
|
|
1482
|
+
const bigNanoInSec = /*@__PURE__*/ BigInt(nanoInSec);
|
|
1483
|
+
const bigNanoInMinute = /*@__PURE__*/ BigInt(nanoInMinute);
|
|
1484
|
+
const bigNanoInHour = /*@__PURE__*/ BigInt(nanoInHour);
|
|
1485
|
+
const bigNanoInUtcDay = /*@__PURE__*/ BigInt(nanoInUtcDay);
|
|
1222
1486
|
function divideBigNanoToExactNumber(bigNano, divisorNano) {
|
|
1223
1487
|
const days = Number(bigNano / bigNanoInUtcDay);
|
|
1224
1488
|
const timeNano = Number(bigNano % bigNanoInUtcDay);
|
|
1225
1489
|
return days * (nanoInUtcDay / divisorNano) + (Math.trunc(timeNano / divisorNano) + timeNano % divisorNano / divisorNano);
|
|
1226
1490
|
}
|
|
1227
|
-
const timeFieldNamesAsc =
|
|
1228
|
-
const timeGetters =
|
|
1491
|
+
const timeFieldNamesAsc = /*@__PURE__*/ unitNamesAsc.slice(0, 6);
|
|
1492
|
+
const timeGetters = /*@__PURE__*/ createPropGetters(timeFieldNamesAsc);
|
|
1229
1493
|
const yearFieldNamesAsc = ["year"];
|
|
1230
1494
|
const dayFieldNamesAsc = ["day"];
|
|
1231
1495
|
const calendarDateFieldNamesAsc = [
|
|
@@ -1247,24 +1511,24 @@ const monthDayFieldNames = [
|
|
|
1247
1511
|
"month",
|
|
1248
1512
|
"monthCode"
|
|
1249
1513
|
];
|
|
1250
|
-
const timeFieldNamesAlpha =
|
|
1251
|
-
const yearFieldNamesWithEraAlpha =
|
|
1252
|
-
const yearMonthFieldNamesAlpha =
|
|
1253
|
-
const yearMonthFieldNamesWithEraAlpha =
|
|
1254
|
-
const yearMonthCodeFieldNamesAlpha =
|
|
1255
|
-
const yearMonthCodeFieldNamesWithEraAlpha =
|
|
1256
|
-
const monthCodeDayFieldNamesAlpha =
|
|
1257
|
-
const dateFieldNamesAlpha =
|
|
1258
|
-
const dateFieldNamesWithEraAlpha =
|
|
1259
|
-
const dateTimeFieldNamesAlpha =
|
|
1260
|
-
const dateTimeFieldNamesWithEraAlpha =
|
|
1261
|
-
const dateTimeAndOffsetFieldNamesAlpha =
|
|
1262
|
-
const dateTimeAndOffsetFieldNamesWithEraAlpha =
|
|
1263
|
-
const dateTimeAndZoneFieldNamesAlpha =
|
|
1264
|
-
const dateTimeAndZoneFieldNamesWithEraAlpha =
|
|
1265
|
-
const yearMonthCodeDayFieldNamesAlpha =
|
|
1266
|
-
const yearMonthCodeDayFieldNamesWithEraAlpha =
|
|
1267
|
-
const timeFieldDefaults =
|
|
1514
|
+
const timeFieldNamesAlpha = /*@__PURE__*/ sortStrings(timeFieldNamesAsc);
|
|
1515
|
+
const yearFieldNamesWithEraAlpha = /*@__PURE__*/ sortStrings(eraYearFieldNames, yearFieldNamesAsc);
|
|
1516
|
+
const yearMonthFieldNamesAlpha = /*@__PURE__*/ sortStrings(monthFieldNames, yearFieldNamesAsc);
|
|
1517
|
+
const yearMonthFieldNamesWithEraAlpha = /*@__PURE__*/ sortStrings(eraYearFieldNames, yearMonthFieldNamesAlpha);
|
|
1518
|
+
const yearMonthCodeFieldNamesAlpha = /*@__PURE__*/ sortStrings(["monthCode"], yearFieldNamesAsc);
|
|
1519
|
+
const yearMonthCodeFieldNamesWithEraAlpha = /*@__PURE__*/ sortStrings(eraYearFieldNames, yearMonthCodeFieldNamesAlpha);
|
|
1520
|
+
const monthCodeDayFieldNamesAlpha = /*@__PURE__*/ sortStrings(dayFieldNamesAsc, ["monthCode"]);
|
|
1521
|
+
const dateFieldNamesAlpha = /*@__PURE__*/ sortStrings(dayFieldNamesAsc, yearMonthFieldNamesAlpha);
|
|
1522
|
+
const dateFieldNamesWithEraAlpha = /*@__PURE__*/ sortStrings(dayFieldNamesAsc, eraYearFieldNames, yearMonthFieldNamesAlpha);
|
|
1523
|
+
const dateTimeFieldNamesAlpha = /*@__PURE__*/ sortStrings(dateFieldNamesAlpha, timeFieldNamesAsc);
|
|
1524
|
+
const dateTimeFieldNamesWithEraAlpha = /*@__PURE__*/ sortStrings(dateFieldNamesWithEraAlpha, timeFieldNamesAsc);
|
|
1525
|
+
const dateTimeAndOffsetFieldNamesAlpha = /*@__PURE__*/ sortStrings(dateFieldNamesAlpha, timeFieldNamesAsc, offsetFieldNames);
|
|
1526
|
+
const dateTimeAndOffsetFieldNamesWithEraAlpha = /*@__PURE__*/ sortStrings(dateFieldNamesWithEraAlpha, timeFieldNamesAsc, offsetFieldNames);
|
|
1527
|
+
const dateTimeAndZoneFieldNamesAlpha = /*@__PURE__*/ sortStrings(dateFieldNamesAlpha, timeFieldNamesAsc, offsetFieldNames, timeZoneFieldNames);
|
|
1528
|
+
const dateTimeAndZoneFieldNamesWithEraAlpha = /*@__PURE__*/ sortStrings(dateFieldNamesWithEraAlpha, timeFieldNamesAsc, offsetFieldNames, timeZoneFieldNames);
|
|
1529
|
+
const yearMonthCodeDayFieldNamesAlpha = /*@__PURE__*/ sortStrings(dayFieldNamesAsc, yearMonthCodeFieldNamesAlpha);
|
|
1530
|
+
const yearMonthCodeDayFieldNamesWithEraAlpha = /*@__PURE__*/ sortStrings(dayFieldNamesAsc, eraYearFieldNames, yearMonthCodeFieldNamesAlpha);
|
|
1531
|
+
const timeFieldDefaults = /*@__PURE__*/ zipPropsConst(timeFieldNamesAsc, 0);
|
|
1268
1532
|
function validateTimeFields(timeFields) {
|
|
1269
1533
|
return constrainTimeFields(timeFields, 1), timeFields;
|
|
1270
1534
|
}
|
|
@@ -1493,20 +1757,20 @@ function computeCalendarWeekOfYear(calendar, isoDate) {
|
|
|
1493
1757
|
function computeCalendarYearOfWeek(calendar, isoDate) {
|
|
1494
1758
|
return calendar === void 0 ? computeIsoWeekFields(isoDate).yearOfWeek : void 0;
|
|
1495
1759
|
}
|
|
1496
|
-
const durationFieldNamesAsc =
|
|
1497
|
-
const durationGetters =
|
|
1498
|
-
const durationFieldNamesAlpha =
|
|
1499
|
-
const durationTimeFieldNamesAsc =
|
|
1500
|
-
const durationDateFieldNamesAsc =
|
|
1501
|
-
const durationCalendarFieldNamesAsc =
|
|
1502
|
-
const durationFieldIndexes =
|
|
1503
|
-
const durationFieldDefaults =
|
|
1504
|
-
const durationTimeFieldDefaults =
|
|
1505
|
-
const clearDurationFields =
|
|
1760
|
+
const durationFieldNamesAsc = /*@__PURE__*/ unitNamesAsc.map((unitName) => unitName + "s");
|
|
1761
|
+
const durationGetters = /*@__PURE__*/ createPropGetters(durationFieldNamesAsc);
|
|
1762
|
+
const durationFieldNamesAlpha = /*@__PURE__*/ sortStrings(durationFieldNamesAsc);
|
|
1763
|
+
const durationTimeFieldNamesAsc = /*@__PURE__*/ durationFieldNamesAsc.slice(0, 6);
|
|
1764
|
+
const durationDateFieldNamesAsc = /*@__PURE__*/ durationFieldNamesAsc.slice(6);
|
|
1765
|
+
const durationCalendarFieldNamesAsc = /*@__PURE__*/ durationDateFieldNamesAsc.slice(1);
|
|
1766
|
+
const durationFieldIndexes = /*@__PURE__*/ durationFieldNamesAsc.reduce((indexes, fieldName, i) => (indexes[fieldName] = i, indexes), {});
|
|
1767
|
+
const durationFieldDefaults = /*@__PURE__*/ zipPropsConst(durationFieldNamesAsc, 0);
|
|
1768
|
+
const durationTimeFieldDefaults = /*@__PURE__*/ zipPropsConst(durationTimeFieldNamesAsc, 0);
|
|
1769
|
+
const clearDurationFields = /*@__PURE__*/ bindArgs(zeroOutProps, durationFieldNamesAsc);
|
|
1506
1770
|
function requirePropDefined(optionName, optionVal) {
|
|
1507
1771
|
return optionVal ?? throwRangeError(missingField(optionName)), optionVal;
|
|
1508
1772
|
}
|
|
1509
|
-
const requireString =
|
|
1773
|
+
const requireString = /*@__PURE__*/ bindArgs(requireType, "string");
|
|
1510
1774
|
function requireType(typeName, arg, entityName = typeName) {
|
|
1511
1775
|
return typeof arg !== typeName && throwTypeError(invalidEntity(entityName, arg)), arg;
|
|
1512
1776
|
}
|
|
@@ -1618,17 +1882,17 @@ function coerceChoiceOption(optionName, enumNameMap, options, defaultChoice = 0)
|
|
|
1618
1882
|
const enumNum = enumNameMap[enumStr];
|
|
1619
1883
|
return void 0 === enumNum && throwRangeError(invalidChoice(optionName, enumStr, enumNameMap)), enumNum;
|
|
1620
1884
|
}
|
|
1621
|
-
const coerceSmallestUnit =
|
|
1622
|
-
const coerceLargestUnit =
|
|
1623
|
-
const coerceTotalUnit =
|
|
1624
|
-
const coerceOverflow =
|
|
1625
|
-
const coerceEpochDisambig =
|
|
1626
|
-
const coerceOffsetDisambig =
|
|
1627
|
-
const coerceCalendarDisplay =
|
|
1628
|
-
const coerceTimeZoneDisplay =
|
|
1629
|
-
const coerceOffsetDisplay =
|
|
1630
|
-
const coerceRoundingMode =
|
|
1631
|
-
const coerceDirection =
|
|
1885
|
+
const coerceSmallestUnit = /*@__PURE__*/ bindArgs(coerceUnitOption, smallestUnitStr);
|
|
1886
|
+
const coerceLargestUnit = /*@__PURE__*/ bindArgs(coerceUnitOption, "largestUnit");
|
|
1887
|
+
const coerceTotalUnit = /*@__PURE__*/ bindArgs(coerceUnitOption, "unit");
|
|
1888
|
+
const coerceOverflow = /*@__PURE__*/ bindArgs(coerceChoiceOption, "overflow", overflowMap);
|
|
1889
|
+
const coerceEpochDisambig = /*@__PURE__*/ bindArgs(coerceChoiceOption, "disambiguation", epochDisambigMap);
|
|
1890
|
+
const coerceOffsetDisambig = /*@__PURE__*/ bindArgs(coerceChoiceOption, "offset", offsetDisambigMap);
|
|
1891
|
+
const coerceCalendarDisplay = /*@__PURE__*/ bindArgs(coerceChoiceOption, "calendarName", calendarDisplayMap);
|
|
1892
|
+
const coerceTimeZoneDisplay = /*@__PURE__*/ bindArgs(coerceChoiceOption, "timeZoneName", timeZoneDisplayMap);
|
|
1893
|
+
const coerceOffsetDisplay = /*@__PURE__*/ bindArgs(coerceChoiceOption, "offset", offsetDisplayMap);
|
|
1894
|
+
const coerceRoundingMode = /*@__PURE__*/ bindArgs(coerceChoiceOption, "roundingMode", roundingModeMap);
|
|
1895
|
+
const coerceDirection = /*@__PURE__*/ bindArgs(coerceChoiceOption, "direction", directionMap);
|
|
1632
1896
|
function validateRoundingInc(roundingInc, smallestUnit, allowManyLargeUnits, solarMode) {
|
|
1633
1897
|
const upUnitNano = solarMode ? nanoInUtcDay : unitNanoMap[smallestUnit + 1];
|
|
1634
1898
|
if (upUnitNano) {
|
|
@@ -1682,8 +1946,8 @@ function refineZonedFieldOptions(options, defaultOffsetDisambig = 0) {
|
|
|
1682
1946
|
epochDisambig
|
|
1683
1947
|
];
|
|
1684
1948
|
}
|
|
1685
|
-
const epochNanoMax =
|
|
1686
|
-
const epochNanoMin =
|
|
1949
|
+
const epochNanoMax = /*@__PURE__*/ BigInt(1e8) * bigNanoInUtcDay;
|
|
1950
|
+
const epochNanoMin = /*@__PURE__*/ BigInt(-1e8) * bigNanoInUtcDay;
|
|
1687
1951
|
const plainDateEpochNanoMin = epochNanoMin - bigNanoInUtcDay;
|
|
1688
1952
|
const isoYearMonthIndexMin = -3261848;
|
|
1689
1953
|
function checkIsoYearMonthInBounds(isoDate) {
|
|
@@ -1954,11 +2218,12 @@ function nudgeRelativeDuration(sign, durationFields, endEpochNano, _largestUnit,
|
|
|
1954
2218
|
}
|
|
1955
2219
|
function getTimeZoneTransitionEpochNanoseconds(slots, options) {
|
|
1956
2220
|
return slots.timeZone.U(slots.epochNanoseconds, ((options) => {
|
|
1957
|
-
const
|
|
2221
|
+
const normalizedOptions = normalizeOptionsOrString(options, "direction");
|
|
2222
|
+
const res = coerceDirection(normalizedOptions, 0);
|
|
1958
2223
|
return res || throwRangeError(invalidEntity("direction", res)), res;
|
|
1959
2224
|
})(options));
|
|
1960
2225
|
}
|
|
1961
|
-
const zonedEpochSlotsToIso =
|
|
2226
|
+
const zonedEpochSlotsToIso = /*@__PURE__*/ memoize(_zonedEpochSlotsToIso, WeakMap);
|
|
1962
2227
|
function _zonedEpochSlotsToIso(slots) {
|
|
1963
2228
|
const { epochNanoseconds, timeZone } = slots;
|
|
1964
2229
|
const offsetNanoseconds = timeZone.C(epochNanoseconds);
|
|
@@ -2524,7 +2789,7 @@ function resolveTimeFields(fields, overflow) {
|
|
|
2524
2789
|
...fields
|
|
2525
2790
|
}), overflow);
|
|
2526
2791
|
}
|
|
2527
|
-
const offsetRegExp =
|
|
2792
|
+
const offsetRegExp = /*@__PURE__*/ createRegExp("([+-])(\\d{2})(?::?(\\d{2})(?::?(\\d{2})(?:[.,](\\d{1,9}))?)?)?");
|
|
2528
2793
|
function parseOffsetNano(s) {
|
|
2529
2794
|
const offsetNano = parseOffsetNanoMaybe(s);
|
|
2530
2795
|
return void 0 === offsetNano && throwRangeError(failedParse(s)), offsetNano;
|
|
@@ -2559,13 +2824,13 @@ const dateFieldRefiners = {
|
|
|
2559
2824
|
},
|
|
2560
2825
|
day: toPositiveIntegerWithTruncation
|
|
2561
2826
|
};
|
|
2562
|
-
const timeFieldRefiners =
|
|
2563
|
-
const durationFieldRefiners =
|
|
2827
|
+
const timeFieldRefiners = /*@__PURE__*/ zipPropsConst(timeFieldNamesAsc, toIntegerWithTrunc);
|
|
2828
|
+
const durationFieldRefiners = /*@__PURE__*/ zipPropsConst(durationFieldNamesAsc, toStrictInteger);
|
|
2564
2829
|
const offsetFieldRefiners = { offset(offsetString) {
|
|
2565
2830
|
return parseOffsetNano(toStringViaPrimitive(offsetString));
|
|
2566
2831
|
} };
|
|
2567
|
-
const dateTimeFieldRefiners =
|
|
2568
|
-
const zonedDateTimeFieldRefiners =
|
|
2832
|
+
const dateTimeFieldRefiners = /*@__PURE__*/ Object.assign({}, dateFieldRefiners, timeFieldRefiners);
|
|
2833
|
+
const zonedDateTimeFieldRefiners = /*@__PURE__*/ Object.assign({}, dateTimeFieldRefiners, offsetFieldRefiners);
|
|
2569
2834
|
function readAndRefineBagFields(bag, validFieldNames, fieldRefiners, requiredFieldNames, disallowEmpty = !requiredFieldNames) {
|
|
2570
2835
|
const res = {};
|
|
2571
2836
|
let anyMatching = 0;
|
|
@@ -2668,7 +2933,9 @@ const timeZonePeriodDaysByName = {
|
|
|
2668
2933
|
const minPossibleTransitionSec = -388152e4;
|
|
2669
2934
|
function refineTimeDisplayTuple(options, maxSmallestUnit = 4) {
|
|
2670
2935
|
const subsecDigits = coerceFractionalSecondDigits(options);
|
|
2671
|
-
|
|
2936
|
+
const roundingMode = coerceRoundingMode(options, 4);
|
|
2937
|
+
const smallestUnit = coerceSmallestUnit(options);
|
|
2938
|
+
return [roundingMode, ...resolveSmallestUnitAndSubsecDigits(validateUnitRange(smallestUnitStr, smallestUnit, 0, maxSmallestUnit), subsecDigits)];
|
|
2672
2939
|
}
|
|
2673
2940
|
function refineDateDisplayOptions(options) {
|
|
2674
2941
|
return coerceCalendarDisplay(normalizeOptions(options));
|
|
@@ -2843,15 +3110,17 @@ function resolveTimeZoneRecord(rawId) {
|
|
|
2843
3110
|
kind: "fixed",
|
|
2844
3111
|
...offsetRecord
|
|
2845
3112
|
};
|
|
2846
|
-
|
|
3113
|
+
const normId = "UTC" === upperRawId ? "UTC" : ((rawId) => (badCharactersRegExp.test(rawId) && throwRangeError(invalidTimeZone(rawId)), icuRegExp.test(rawId) && throwRangeError("Forbidden ICU TimeZone"), rawId.toLowerCase().split("/").map((part, partI) => (part.length <= 3 || /\d/.test(part)) && !/etc|yap/.test(part) ? part.toUpperCase() : part.replace(/baja|dumont|[a-z]+/g, (a, i) => a.length <= 2 && !partI || "in" === a || "chat" === a ? a.toUpperCase() : a.length > 2 || !i ? capitalize(a).replace(/island|noronha|murdo|rivadavia|urville/, capitalize) : a)).join("/")))(rawId);
|
|
3114
|
+
return queryNamedTimeZoneRecord(normId);
|
|
2847
3115
|
}
|
|
2848
|
-
const queryNamedTimeZoneRecord =
|
|
3116
|
+
const queryNamedTimeZoneRecord = /*@__PURE__*/ memoize((normId) => {
|
|
2849
3117
|
if ("UTC" === normId) return {
|
|
2850
3118
|
kind: "utc",
|
|
2851
3119
|
id: normId,
|
|
2852
3120
|
o: normId
|
|
2853
3121
|
};
|
|
2854
|
-
const
|
|
3122
|
+
const upperNormId = normId.toUpperCase();
|
|
3123
|
+
const format = queryTimeZoneIntlFormat(upperNormId);
|
|
2855
3124
|
return {
|
|
2856
3125
|
kind: "named",
|
|
2857
3126
|
id: normId,
|
|
@@ -2859,7 +3128,7 @@ const queryNamedTimeZoneRecord = /* @__PURE__ */ memoize((normId) => {
|
|
|
2859
3128
|
o: format.resolvedOptions().timeZone
|
|
2860
3129
|
};
|
|
2861
3130
|
});
|
|
2862
|
-
const queryTimeZoneIntlFormat =
|
|
3131
|
+
const queryTimeZoneIntlFormat = /*@__PURE__*/ memoize((upperNormId) => new RawDateTimeFormat("en-u-hc-h23", {
|
|
2863
3132
|
calendar: "iso8601",
|
|
2864
3133
|
timeZone: upperNormId,
|
|
2865
3134
|
era: "short",
|
|
@@ -2874,7 +3143,7 @@ function queryTimeZone(rawTimeZoneId) {
|
|
|
2874
3143
|
const record = resolveTimeZoneRecord(rawTimeZoneId);
|
|
2875
3144
|
return queryTimeZoneRecord(record.id, record);
|
|
2876
3145
|
}
|
|
2877
|
-
const queryTimeZoneRecord =
|
|
3146
|
+
const queryTimeZoneRecord = /*@__PURE__*/ memoize((normTimeZoneId, record) => "named" === record.kind ? new IntlTimeZone(normTimeZoneId, record.o, record.format) : new FixedTimeZone(normTimeZoneId, record.o, "fixed" === record.kind ? record._ : 0));
|
|
2878
3147
|
var FixedTimeZone = class {
|
|
2879
3148
|
constructor(id, compareKey, offsetNano) {
|
|
2880
3149
|
this.id = id, this.o = compareKey, this._ = offsetNano;
|
|
@@ -2956,7 +3225,8 @@ var IntlTimeZone = class {
|
|
|
2956
3225
|
return void 0 !== intlParts.era && "bce" === normalizeEraName(intlParts.era) ? 1 - year : year;
|
|
2957
3226
|
})(intlParts), parseInt(intlParts.month), parseInt(intlParts.day)) + 3600 * parseInt(intlParts.hour) + 60 * parseInt(intlParts.minute) + parseInt(intlParts.second) - epochSec;
|
|
2958
3227
|
})(format), ((timeZoneId) => {
|
|
2959
|
-
|
|
3228
|
+
const timeZoneName = timeZoneId.split("/").pop();
|
|
3229
|
+
return timeZonePeriodDaysByName[timeZoneName] || 60;
|
|
2960
3230
|
})(id));
|
|
2961
3231
|
}
|
|
2962
3232
|
C(epochNano) {
|
|
@@ -3180,12 +3450,12 @@ function offsetRegExpStr(separatorIndex) {
|
|
|
3180
3450
|
return "([+-])" + timeRegExpStr(separatorIndex);
|
|
3181
3451
|
}
|
|
3182
3452
|
const dateTimeRegExpStr = "(?:(?:([+-])(\\d{6}))|(\\d{4}))(-?)(\\d{2})\\4(\\d{2})(?:[T ]" + timeRegExpStr(8) + "(Z|" + offsetRegExpStr(15) + ")?)?";
|
|
3183
|
-
const yearMonthRegExp =
|
|
3184
|
-
const monthDayRegExp =
|
|
3185
|
-
const dateTimeRegExp =
|
|
3186
|
-
const timeRegExp =
|
|
3187
|
-
const annotationRegExp =
|
|
3188
|
-
const durationRegExp =
|
|
3453
|
+
const yearMonthRegExp = /*@__PURE__*/ createRegExp("(?:(?:([+-])(\\d{6}))|(\\d{4}))-?(\\d{2})((?:\\[(!?)([^\\]]*)\\]){0,9})");
|
|
3454
|
+
const monthDayRegExp = /*@__PURE__*/ createRegExp("(?:--)?(\\d{2})-?(\\d{2})((?:\\[(!?)([^\\]]*)\\]){0,9})");
|
|
3455
|
+
const dateTimeRegExp = /*@__PURE__*/ createRegExp(dateTimeRegExpStr + "((?:\\[(!?)([^\\]]*)\\]){0,9})");
|
|
3456
|
+
const timeRegExp = /*@__PURE__*/ createRegExp("T?" + timeRegExpStr(2) + `(${offsetRegExpStr(9)})?((?:\\[(!?)([^\\]]*)\\]){0,9})`);
|
|
3457
|
+
const annotationRegExp = /*@__PURE__*/ new RegExp("\\[(!?)([^\\]]*)\\]", "g");
|
|
3458
|
+
const durationRegExp = /*@__PURE__*/ createRegExp("([+-])?P(\\d+Y)?(\\d+M)?(\\d+W)?(\\d+D)?(?:T(?:(\\d+)(?:[.,](\\d{1,9}))?H)?(?:(\\d+)(?:[.,](\\d{1,9}))?M)?(?:(\\d+)(?:[.,](\\d{1,9}))?S)?)?");
|
|
3189
3459
|
function parseDateTimeLike(s) {
|
|
3190
3460
|
const parts = dateTimeRegExp.exec(s);
|
|
3191
3461
|
return parts ? ((parts) => {
|
|
@@ -3463,8 +3733,8 @@ const timeDefaultShapeFields = {
|
|
|
3463
3733
|
minute: "numeric",
|
|
3464
3734
|
second: "numeric"
|
|
3465
3735
|
};
|
|
3466
|
-
const dateTimeDefaultShapeFields =
|
|
3467
|
-
const zonedDateTimeDefaultShapeFields =
|
|
3736
|
+
const dateTimeDefaultShapeFields = /*@__PURE__*/ Object.assign({}, dateDefaultShapeFields, timeDefaultShapeFields);
|
|
3737
|
+
const zonedDateTimeDefaultShapeFields = /*@__PURE__*/ Object.assign({}, dateTimeDefaultShapeFields, { timeZoneName: "short" });
|
|
3468
3738
|
const yearMonthDefaultShapeFields = {
|
|
3469
3739
|
year: "numeric",
|
|
3470
3740
|
month: "numeric"
|
|
@@ -3488,15 +3758,15 @@ const timeShapeFieldNames = [
|
|
|
3488
3758
|
"fractionalSecondDigits",
|
|
3489
3759
|
"timeStyle"
|
|
3490
3760
|
];
|
|
3491
|
-
const dateTimeShapeFieldNames =
|
|
3492
|
-
const yearMonthIgnoredFieldNames =
|
|
3493
|
-
const monthDayIgnoredFieldNames =
|
|
3494
|
-
const transformInstantOptions =
|
|
3495
|
-
const transformZonedOptions =
|
|
3496
|
-
const transformDateTimeOptions =
|
|
3497
|
-
const transformDateOptions =
|
|
3498
|
-
const transformTimeOptions =
|
|
3499
|
-
const transformYearMonthOptions =
|
|
3761
|
+
const dateTimeShapeFieldNames = /*@__PURE__*/ dateShapeFieldNames.concat(timeShapeFieldNames);
|
|
3762
|
+
const yearMonthIgnoredFieldNames = /*@__PURE__*/ ["weekday", "day"].concat(timeShapeFieldNames);
|
|
3763
|
+
const monthDayIgnoredFieldNames = /*@__PURE__*/ ["weekday", "year"].concat(timeShapeFieldNames);
|
|
3764
|
+
const transformInstantOptions = /*@__PURE__*/ createOptionsTransformer(dateTimeShapeFieldNames, [], [], dateTimeDefaultShapeFields);
|
|
3765
|
+
const transformZonedOptions = /*@__PURE__*/ createOptionsTransformer(dateTimeShapeFieldNames, [], [], zonedDateTimeDefaultShapeFields);
|
|
3766
|
+
const transformDateTimeOptions = /*@__PURE__*/ createOptionsTransformer(dateTimeShapeFieldNames, [], ["timeZoneName"], dateTimeDefaultShapeFields);
|
|
3767
|
+
const transformDateOptions = /*@__PURE__*/ createOptionsTransformer(dateShapeFieldNames, timeShapeFieldNames, ["timeZoneName"], dateDefaultShapeFields);
|
|
3768
|
+
const transformTimeOptions = /*@__PURE__*/ createOptionsTransformer(timeShapeFieldNames, dateShapeFieldNames, ["timeZoneName", "era"], timeDefaultShapeFields);
|
|
3769
|
+
const transformYearMonthOptions = /*@__PURE__*/ createOptionsTransformer([
|
|
3500
3770
|
"year",
|
|
3501
3771
|
"month",
|
|
3502
3772
|
"dateStyle"
|
|
@@ -3518,7 +3788,7 @@ const transformYearMonthOptions = /* @__PURE__ */ createOptionsTransformer([
|
|
|
3518
3788
|
month: "numeric"
|
|
3519
3789
|
}
|
|
3520
3790
|
});
|
|
3521
|
-
const transformMonthDayOptions =
|
|
3791
|
+
const transformMonthDayOptions = /*@__PURE__*/ createOptionsTransformer([
|
|
3522
3792
|
"month",
|
|
3523
3793
|
"day",
|
|
3524
3794
|
"dateStyle"
|
|
@@ -3692,8 +3962,8 @@ function resolveBasicCalendarId(rawCalendarId) {
|
|
|
3692
3962
|
function resolveBasicCalendarArg(rawCalendarId = isoCalendarId) {
|
|
3693
3963
|
return resolveBasicCalendarId(rawCalendarId);
|
|
3694
3964
|
}
|
|
3695
|
-
const zonedDateTimeSlotsMap =
|
|
3696
|
-
const ZonedDateTime =
|
|
3965
|
+
const zonedDateTimeSlotsMap = /*@__PURE__*/ new WeakMap();
|
|
3966
|
+
const ZonedDateTime = /*@__PURE__*/ defineTemporalClass(ZonedDateTimeBranding, class {
|
|
3697
3967
|
constructor(epochNanoseconds, timeZoneId, calendar = void 0) {
|
|
3698
3968
|
const epochNano = checkEpochNanoInBounds(toBigInt(epochNanoseconds));
|
|
3699
3969
|
const timeZone = queryTimeZone(refineTimeZoneId(timeZoneId));
|
|
@@ -3841,8 +4111,8 @@ function refineTimeZoneArg(arg) {
|
|
|
3841
4111
|
}
|
|
3842
4112
|
return ((arg) => resolveTimeZoneId(parseTimeZoneId(requireString(arg))))(arg);
|
|
3843
4113
|
}
|
|
3844
|
-
const instantSlotsMap =
|
|
3845
|
-
const Instant =
|
|
4114
|
+
const instantSlotsMap = /*@__PURE__*/ new WeakMap();
|
|
4115
|
+
const Instant = /*@__PURE__*/ defineTemporalClass(InstantBranding, class {
|
|
3846
4116
|
constructor(epochNanoseconds) {
|
|
3847
4117
|
const epochNano = checkEpochNanoInBounds(toBigInt(epochNanoseconds));
|
|
3848
4118
|
initInstant(this, createEpochNanoSlots(epochNano));
|
|
@@ -3927,8 +4197,8 @@ const { toTemporalInstant: toTemporalInstant$1 } = { toTemporalInstant() {
|
|
|
3927
4197
|
function initInstant(instance, slots) {
|
|
3928
4198
|
return instantSlotsMap.set(instance, slots), attachDebugString(instance), instance;
|
|
3929
4199
|
}
|
|
3930
|
-
const plainMonthDaySlotsMap =
|
|
3931
|
-
const PlainMonthDay =
|
|
4200
|
+
const plainMonthDaySlotsMap = /*@__PURE__*/ new WeakMap();
|
|
4201
|
+
const PlainMonthDay = /*@__PURE__*/ defineTemporalClass(PlainMonthDayBranding, class {
|
|
3932
4202
|
constructor(isoMonth, isoDay, calendar = void 0, referenceIsoYear) {
|
|
3933
4203
|
const isoMonthInt = toIntegerWithTrunc(isoMonth);
|
|
3934
4204
|
const isoDayInt = toIntegerWithTrunc(isoDay);
|
|
@@ -3992,8 +4262,8 @@ function toPlainMonthDaySlots(arg, options) {
|
|
|
3992
4262
|
function initPlainMonthDay(instance, slots) {
|
|
3993
4263
|
return plainMonthDaySlotsMap.set(instance, slots), attachDebugString(instance), instance;
|
|
3994
4264
|
}
|
|
3995
|
-
const plainYearMonthSlotsMap =
|
|
3996
|
-
const PlainYearMonth =
|
|
4265
|
+
const plainYearMonthSlotsMap = /*@__PURE__*/ new WeakMap();
|
|
4266
|
+
const PlainYearMonth = /*@__PURE__*/ defineTemporalClass(PlainYearMonthBranding, class {
|
|
3997
4267
|
constructor(isoYear, isoMonth, calendar = void 0, referenceIsoDay) {
|
|
3998
4268
|
const isoYearInt = toIntegerWithTrunc(isoYear);
|
|
3999
4269
|
const isoMonthInt = toIntegerWithTrunc(isoMonth);
|
|
@@ -4085,8 +4355,8 @@ function getTemporalBrandingAndSlots(obj) {
|
|
|
4085
4355
|
function validateBag(bag) {
|
|
4086
4356
|
return (getTemporalBrandingAndSlots(bag) || void 0 !== bag.calendar || void 0 !== bag.timeZone) && throwTypeError("Invalid bag"), bag;
|
|
4087
4357
|
}
|
|
4088
|
-
const plainTimeSlotsMap =
|
|
4089
|
-
const PlainTime =
|
|
4358
|
+
const plainTimeSlotsMap = /*@__PURE__*/ new WeakMap();
|
|
4359
|
+
const PlainTime = /*@__PURE__*/ defineTemporalClass(PlainTimeBranding, class {
|
|
4090
4360
|
constructor(hour = 0, minute = 0, second = 0, millisecond = 0, microsecond = 0, nanosecond = 0) {
|
|
4091
4361
|
const fields = validateTimeFields(mapProps(toIntegerWithTrunc, {
|
|
4092
4362
|
hour,
|
|
@@ -4168,8 +4438,8 @@ function optionalToPlainTimeFields(timeArg) {
|
|
|
4168
4438
|
function initPlainTime(instance, slots) {
|
|
4169
4439
|
return plainTimeSlotsMap.set(instance, slots), attachDebugString(instance), instance;
|
|
4170
4440
|
}
|
|
4171
|
-
const plainDateTimeSlotsMap =
|
|
4172
|
-
const PlainDateTime =
|
|
4441
|
+
const plainDateTimeSlotsMap = /*@__PURE__*/ new WeakMap();
|
|
4442
|
+
const PlainDateTime = /*@__PURE__*/ defineTemporalClass(PlainDateTimeBranding, class {
|
|
4173
4443
|
constructor(isoYear, isoMonth, isoDay, hour = 0, minute = 0, second = 0, millisecond = 0, microsecond = 0, nanosecond = 0, calendar = void 0) {
|
|
4174
4444
|
const fields = checkIsoDateTimeInBounds(validateIsoDateTimeFields(mapProps(toIntegerWithTrunc, {
|
|
4175
4445
|
year: isoYear,
|
|
@@ -4280,8 +4550,8 @@ function toPlainDateTimeSlots(arg, options) {
|
|
|
4280
4550
|
function initPlainDateTime(instance, slots) {
|
|
4281
4551
|
return plainDateTimeSlotsMap.set(instance, slots), attachDebugString(instance), instance;
|
|
4282
4552
|
}
|
|
4283
|
-
const plainDateSlotsMap =
|
|
4284
|
-
const PlainDate =
|
|
4553
|
+
const plainDateSlotsMap = /*@__PURE__*/ new WeakMap();
|
|
4554
|
+
const PlainDate = /*@__PURE__*/ defineTemporalClass(PlainDateBranding, class {
|
|
4285
4555
|
constructor(isoYear, isoMonth, isoDay, calendar = void 0) {
|
|
4286
4556
|
const fields = checkIsoDateInBounds(validateIsoDateFields(mapProps(toIntegerWithTrunc, {
|
|
4287
4557
|
year: isoYear,
|
|
@@ -4399,8 +4669,8 @@ function refineCalendarArg(arg) {
|
|
|
4399
4669
|
}
|
|
4400
4670
|
return ((arg) => resolveBasicCalendarId(parseCalendarId(requireString(arg))))(arg);
|
|
4401
4671
|
}
|
|
4402
|
-
const durationSlotsMap =
|
|
4403
|
-
const Duration =
|
|
4672
|
+
const durationSlotsMap = /*@__PURE__*/ new WeakMap();
|
|
4673
|
+
const Duration = /*@__PURE__*/ defineTemporalClass(DurationBranding, class {
|
|
4404
4674
|
constructor(years = 0, months = 0, weeks = 0, days = 0, hours = 0, minutes = 0, seconds = 0, milliseconds = 0, microseconds = 0, nanoseconds = 0) {
|
|
4405
4675
|
const fields = validateDurationFields(mapProps(toStrictInteger, {
|
|
4406
4676
|
years,
|
|
@@ -4493,7 +4763,7 @@ function refinePublicRelativeTo(relativeTo) {
|
|
|
4493
4763
|
function initDuration(instance, slots) {
|
|
4494
4764
|
return durationSlotsMap.set(instance, slots), attachDebugString(instance), instance;
|
|
4495
4765
|
}
|
|
4496
|
-
const Now =
|
|
4766
|
+
const Now = /*@__PURE__*/ Object.defineProperties({}, {
|
|
4497
4767
|
...createStringTagDescriptors("Temporal.Now"),
|
|
4498
4768
|
...createPropDescriptors({
|
|
4499
4769
|
timeZoneId() {
|
|
@@ -4517,7 +4787,7 @@ const Now = /* @__PURE__ */ Object.defineProperties({}, {
|
|
|
4517
4787
|
}
|
|
4518
4788
|
})
|
|
4519
4789
|
});
|
|
4520
|
-
const Temporal$
|
|
4790
|
+
const Temporal$3 = /*@__PURE__*/ Object.defineProperties({}, {
|
|
4521
4791
|
...createStringTagDescriptors("Temporal"),
|
|
4522
4792
|
...createPropDescriptors({
|
|
4523
4793
|
PlainYearMonth,
|
|
@@ -4533,11 +4803,153 @@ const Temporal$2 = /* @__PURE__ */ Object.defineProperties({}, {
|
|
|
4533
4803
|
});
|
|
4534
4804
|
//#endregion
|
|
4535
4805
|
//#region ../../node_modules/.pnpm/temporal-polyfill@1.0.1/node_modules/temporal-polyfill/index.js
|
|
4536
|
-
const Temporal$
|
|
4806
|
+
const Temporal$2 = NativeTemporal || Temporal$3;
|
|
4537
4807
|
NativeTemporal && Date.prototype.toTemporalInstant;
|
|
4538
4808
|
//#endregion
|
|
4809
|
+
//#region src/kv-tester.ts
|
|
4810
|
+
const Temporal$1 = Temporal$2;
|
|
4811
|
+
/**
|
|
4812
|
+
* Tests a {@link KvStore} implementation with a standard set of tests.
|
|
4813
|
+
*
|
|
4814
|
+
* The suite covers reads and writes, deletion, structured keys and values,
|
|
4815
|
+
* prefix listing, TTL expiration, and optional compare-and-swap behavior.
|
|
4816
|
+
* Every key is isolated below a random prefix and is deleted after the suite.
|
|
4817
|
+
*
|
|
4818
|
+
* @example
|
|
4819
|
+
* ```typescript ignore
|
|
4820
|
+
* import { test } from "@fedify/fixture";
|
|
4821
|
+
* import { testKvStore } from "@fedify/testing";
|
|
4822
|
+
* import { MyKvStore } from "./my-kv.ts";
|
|
4823
|
+
*
|
|
4824
|
+
* test("MyKvStore", () =>
|
|
4825
|
+
* testKvStore(
|
|
4826
|
+
* () => new MyKvStore(),
|
|
4827
|
+
* async ({ store }) => await store.close(),
|
|
4828
|
+
* )
|
|
4829
|
+
* );
|
|
4830
|
+
* ```
|
|
4831
|
+
*
|
|
4832
|
+
* @param getKvStore A factory that creates the store to test.
|
|
4833
|
+
* @param onFinally A cleanup function called after the suite completes.
|
|
4834
|
+
* @param options Optional configuration for the suite.
|
|
4835
|
+
*/
|
|
4836
|
+
async function testKvStore(getKvStore, onFinally, options = {}) {
|
|
4837
|
+
const store = await getKvStore();
|
|
4838
|
+
const prefix = [`fedify_test_${crypto.randomUUID()}`];
|
|
4839
|
+
const key = (...segments) => [...prefix, ...segments];
|
|
4840
|
+
try {
|
|
4841
|
+
(0, node_assert_strict.strictEqual)(await store.get(key("missing")), void 0);
|
|
4842
|
+
for (const [index, value] of [
|
|
4843
|
+
"text",
|
|
4844
|
+
42,
|
|
4845
|
+
true,
|
|
4846
|
+
null,
|
|
4847
|
+
[
|
|
4848
|
+
1,
|
|
4849
|
+
"two",
|
|
4850
|
+
false
|
|
4851
|
+
],
|
|
4852
|
+
{ nested: { value: "test" } }
|
|
4853
|
+
].entries()) {
|
|
4854
|
+
const valueKey = key("values", index.toString());
|
|
4855
|
+
await store.set(valueKey, value);
|
|
4856
|
+
(0, node_assert_strict.deepStrictEqual)(await store.get(valueKey), value);
|
|
4857
|
+
}
|
|
4858
|
+
const overwriteKey = key("overwrite");
|
|
4859
|
+
await store.set(overwriteKey, "before");
|
|
4860
|
+
await store.set(overwriteKey, "after");
|
|
4861
|
+
(0, node_assert_strict.strictEqual)(await store.get(overwriteKey), "after");
|
|
4862
|
+
const deleteKey = key("delete");
|
|
4863
|
+
await store.set(deleteKey, "value");
|
|
4864
|
+
await store.delete(deleteKey);
|
|
4865
|
+
(0, node_assert_strict.strictEqual)(await store.get(deleteKey), void 0);
|
|
4866
|
+
await store.delete(deleteKey);
|
|
4867
|
+
const isolatedKeys = [
|
|
4868
|
+
key("a", "b"),
|
|
4869
|
+
key("a,b"),
|
|
4870
|
+
key("a:b")
|
|
4871
|
+
];
|
|
4872
|
+
for (const [index, isolatedKey] of isolatedKeys.entries()) await store.set(isolatedKey, index);
|
|
4873
|
+
for (const [index, isolatedKey] of isolatedKeys.entries()) (0, node_assert_strict.strictEqual)(await store.get(isolatedKey), index);
|
|
4874
|
+
if (options.testTtl ?? true) {
|
|
4875
|
+
const expiringKey = key("ttl", "expiring");
|
|
4876
|
+
await store.set(expiringKey, "expired", { ttl: Temporal$1.Duration.from({ milliseconds: 50 }) });
|
|
4877
|
+
await (0, es_toolkit.delay)(100);
|
|
4878
|
+
(0, node_assert_strict.strictEqual)(await store.get(expiringKey), void 0);
|
|
4879
|
+
(0, node_assert_strict.deepStrictEqual)(await collect(store.list(key("ttl"))), []);
|
|
4880
|
+
const refreshedKey = key("ttl", "refreshed");
|
|
4881
|
+
await store.set(refreshedKey, "temporary", { ttl: Temporal$1.Duration.from({ milliseconds: 50 }) });
|
|
4882
|
+
await store.set(refreshedKey, "persistent");
|
|
4883
|
+
await (0, es_toolkit.delay)(100);
|
|
4884
|
+
(0, node_assert_strict.strictEqual)(await store.get(refreshedKey), "persistent");
|
|
4885
|
+
}
|
|
4886
|
+
const listPrefix = key("list");
|
|
4887
|
+
const listEntries = [
|
|
4888
|
+
{
|
|
4889
|
+
key: listPrefix,
|
|
4890
|
+
value: "exact"
|
|
4891
|
+
},
|
|
4892
|
+
{
|
|
4893
|
+
key: key("list", "child"),
|
|
4894
|
+
value: "child"
|
|
4895
|
+
},
|
|
4896
|
+
{
|
|
4897
|
+
key: key("list", "child", "nested"),
|
|
4898
|
+
value: "nested"
|
|
4899
|
+
},
|
|
4900
|
+
{
|
|
4901
|
+
key: key("list-other"),
|
|
4902
|
+
value: "other"
|
|
4903
|
+
}
|
|
4904
|
+
];
|
|
4905
|
+
for (const entry of listEntries) await store.set(entry.key, entry.value);
|
|
4906
|
+
(0, node_assert_strict.deepStrictEqual)(normalize(await collect(store.list(listPrefix))), normalize(listEntries.slice(0, 3)));
|
|
4907
|
+
const prefixedEntries = await collect(store.list(prefix));
|
|
4908
|
+
(0, node_assert_strict.deepStrictEqual)(normalize(filterByPrefix(await collect(store.list()), prefix)), normalize(prefixedEntries));
|
|
4909
|
+
(0, node_assert_strict.deepStrictEqual)(normalize(filterByPrefix(await collect(store.list([])), prefix)), normalize(prefixedEntries));
|
|
4910
|
+
if (options.testCas ?? store.cas != null) {
|
|
4911
|
+
if (store.cas == null) throw new TypeError("KvStore.cas is not implemented");
|
|
4912
|
+
const cas = store.cas.bind(store);
|
|
4913
|
+
const casKey = key("cas", "value");
|
|
4914
|
+
(0, node_assert_strict.strictEqual)(await cas(casKey, "wrong", "value"), false);
|
|
4915
|
+
(0, node_assert_strict.strictEqual)(await cas(casKey, void 0, "created"), true);
|
|
4916
|
+
(0, node_assert_strict.strictEqual)(await cas(casKey, "wrong", "updated"), false);
|
|
4917
|
+
(0, node_assert_strict.strictEqual)(await cas(casKey, "created", "updated"), true);
|
|
4918
|
+
(0, node_assert_strict.strictEqual)(await store.get(casKey), "updated");
|
|
4919
|
+
(0, node_assert_strict.strictEqual)(await cas(casKey, "updated", void 0), true);
|
|
4920
|
+
(0, node_assert_strict.strictEqual)(await store.get(casKey), void 0);
|
|
4921
|
+
if (options.testTtl ?? true) {
|
|
4922
|
+
const expiredCasKey = key("cas", "expired");
|
|
4923
|
+
await store.set(expiredCasKey, "old", { ttl: Temporal$1.Duration.from({ milliseconds: 50 }) });
|
|
4924
|
+
await (0, es_toolkit.delay)(100);
|
|
4925
|
+
(0, node_assert_strict.strictEqual)(await cas(expiredCasKey, void 0, "replaced"), true);
|
|
4926
|
+
const ttlCasKey = key("cas", "ttl");
|
|
4927
|
+
(0, node_assert_strict.strictEqual)(await cas(ttlCasKey, void 0, "temporary", { ttl: Temporal$1.Duration.from({ milliseconds: 50 }) }), true);
|
|
4928
|
+
await (0, es_toolkit.delay)(100);
|
|
4929
|
+
(0, node_assert_strict.strictEqual)(await store.get(ttlCasKey), void 0);
|
|
4930
|
+
}
|
|
4931
|
+
const concurrentKey = key("cas", "concurrent");
|
|
4932
|
+
(0, node_assert_strict.strictEqual)((await Promise.all(Array.from({ length: 8 }, (_, index) => cas(concurrentKey, void 0, index)))).filter(Boolean).length, 1);
|
|
4933
|
+
}
|
|
4934
|
+
} finally {
|
|
4935
|
+
for await (const entry of store.list(prefix)) await store.delete(entry.key);
|
|
4936
|
+
await onFinally({ store });
|
|
4937
|
+
}
|
|
4938
|
+
}
|
|
4939
|
+
async function collect(entries) {
|
|
4940
|
+
const results = [];
|
|
4941
|
+
for await (const entry of entries) results.push(entry);
|
|
4942
|
+
return results;
|
|
4943
|
+
}
|
|
4944
|
+
function normalize(entries) {
|
|
4945
|
+
return entries.map((entry) => JSON.stringify(entry)).sort();
|
|
4946
|
+
}
|
|
4947
|
+
function filterByPrefix(entries, prefix) {
|
|
4948
|
+
return entries.filter((entry) => prefix.every((segment, index) => entry.key[index] === segment));
|
|
4949
|
+
}
|
|
4950
|
+
//#endregion
|
|
4539
4951
|
//#region src/mq-tester.ts
|
|
4540
|
-
const Temporal = Temporal$
|
|
4952
|
+
const Temporal = Temporal$2;
|
|
4541
4953
|
/**
|
|
4542
4954
|
* Tests a {@link MessageQueue} implementation with a standard set of tests.
|
|
4543
4955
|
*
|
|
@@ -4723,5 +5135,6 @@ exports.createInboxContext = createInboxContext;
|
|
|
4723
5135
|
exports.createOutboxContext = createOutboxContext;
|
|
4724
5136
|
exports.createRequestContext = createRequestContext;
|
|
4725
5137
|
exports.getRandomKey = getRandomKey;
|
|
5138
|
+
exports.testKvStore = testKvStore;
|
|
4726
5139
|
exports.testMessageQueue = testMessageQueue;
|
|
4727
5140
|
exports.waitFor = waitFor;
|