@onlyworlds/sdk 4.63.0 → 4.65.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/README.md +2 -0
- package/dist/index.d.ts +52 -9
- package/dist/index.js +61 -19
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,25 @@ earlier history lives in git log only.
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [4.65.0] - 2026-10-23
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **`patchWorld` takes a `getWorld()` body back again** (keel #571, live 2026-10-23). keel's `GET /world` now serves `origin`, and a PATCH naming it is a 422 (an unknown key), so a world body read and sent back failed. `patchWorld` now leaves out `origin`, and `id` too: keel answers `id` with the same 422 (it is not a key PATCH takes), so the round trip 4.57.1's entry promised never held for a whole body. `owner_character` is still sent.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- **`OwWorldMeta.origin?: OwWorldOrigin`**, read-only: where the world first came from, `{ source, producer }`, both keys always present, each the folder format's provenance line (spec 4.2) as the tool that made the world from a folder gave it, or `null`. Types `OwWorldOrigin`, `OwWorldSource` (`server`, `world`, `at`) and `OwWorldProducer` (`tool`, `version`, `input`), each open to keys keel keeps as given. The origin is written as the plain keys `source` and `producer`: `patchWorld({ source, producer })` sends them as given (an object, or `null` to clear).
|
|
17
|
+
- **The World's extension keys on `OwWorldMeta`**: `x_*`, `atlas_*` and `shadow_*`, typed `unknown` by template-literal index signatures (the first is `x_names`, the names profile `typeWord` reads). `patchWorld` sends every one as given, `null` included (keel removes the key); over keel's 64 KB cap on the whole store the answer is a 422 with `param: extensions`.
|
|
18
|
+
- Tests: a full `GET /world` body sent back sends neither `origin` nor `id` and keeps `x_names`; `source`, `producer` and a key of each extension prefix pass untouched, `null` included; the published types declare `origin` and its two keys, and the documented calls (`patchWorld(await getWorld())`, `patchWorld({ source, producer, x_names })`, `typeWord(world, …)`) compile against the built `.d.ts`. Watched failing on mutants: `origin` and `id` each out of the strip list, `origin` out of `OwWorldMeta`, and a narrowed `patchWorld` parameter.
|
|
19
|
+
|
|
20
|
+
## [4.64.0] - 2026-10-23
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- **Every options object in the package now refuses an unknown key**, not only the client's typed methods (4.51.0 to 4.53.0): `readWorldFile`, `parseDate`, `resolveCalendarLens`, `lookupWorld`, `renderElement`, `planPhoto`, `preparePhoto`, the client's `request()` escape hatch, `listAll` (with its own keys: a `cursor` it was handed was overwritten unread), the deprecated `tokens.consume` and `new OwSignInError`'s third argument throw a `TypeError` naming the function, the key and the keys it takes, before anything is read, decoded, parsed or sent. A dropped key was never harmless: `readWorldFile(bytes, { maxbytes: 1e6 })` read with the 2 GiB budget, `parseDate(cfg, input, { Now: 12 })` parsed as if the world had no now, and W11's `list('character', { name__icontains })` read every Character and a cleanup script deleted 99 of them (2026-10-22). A plain-JavaScript caller passing a misspelt key will now see a `TypeError` where the call used to run with the default; TypeScript callers were already refused at compile time. `writeWorldFile` and `typeWord` keep their refusals on the same shared check; `typeWord`'s message now reads like the others (`typeWord: unknown option 'plural'. The keys are supertype, many.`).
|
|
25
|
+
- Tests: one test calls every options parameter of the exported surface with `{ __unknown__: 1 }` and asserts a `TypeError` naming the key, nothing sent; a second reads `src/index.ts` with the TypeScript checker and fails on any exported object parameter that is neither in that list nor named as data (a calendar config, a world index, an element), so a new options object cannot ship unfenced. Watched failing on mutants of the `readWorldFile`, `parseDate`, `preparePhoto` and `request()` fences, and on an exported options function added without one.
|
|
26
|
+
|
|
8
27
|
## [4.63.0] - 2026-10-23
|
|
9
28
|
|
|
10
29
|
### Added
|
package/README.md
CHANGED
|
@@ -184,6 +184,8 @@ To poll for news cheaply, `client.changesHead()` returns `{ head, cursor, epoch,
|
|
|
184
184
|
|
|
185
185
|
Edits to the world itself (its name, calendar, `public_read`) don't appear in the change feed. Read `client.getWorld()` and compare `updated_at`.
|
|
186
186
|
|
|
187
|
+
`client.patchWorld(partial)` writes the world's own settings, and takes a `getWorld()` body back: the keys keel does not take (`id`, `origin`, `slug`, `public_page` and the owner's switches) are left out. The world's `origin` is written as the plain keys `source` and `producer` (each an object or `null`), and extension keys (`x_*`, `atlas_*`, `shadow_*`) are sent as given; `null` removes one.
|
|
188
|
+
|
|
187
189
|
### Only if unchanged
|
|
188
190
|
|
|
189
191
|
A client that edits offline, or from a copy it has held a while, can ask for an update to land only if nobody changed the element since it was read: pass the `change_seq` you read as `ifMatch`, on `patch`, `editLinks` or `delete` (since 4.61.0: a delete of an element someone changed since you read it is refused, nothing deleted).
|
package/dist/index.d.ts
CHANGED
|
@@ -1968,9 +1968,47 @@ interface OwWorldMeta {
|
|
|
1968
1968
|
* the owner on the world page; read-only on the wire, and patchWorld strips it.
|
|
1969
1969
|
*/
|
|
1970
1970
|
agent_writes_proposed?: boolean;
|
|
1971
|
+
/**
|
|
1972
|
+
* Where the world first came from (keel #571, #477): the folder format's provenance lines (spec
|
|
1973
|
+
* 4.2) as the tool that made the world from a folder gave them, both keys always present, each
|
|
1974
|
+
* null when not known. Read-only on the wire, and patchWorld strips it: write it as the plain
|
|
1975
|
+
* keys `source` and `producer` (`patchWorld({ source, producer })`, each an object or null).
|
|
1976
|
+
*/
|
|
1977
|
+
origin?: OwWorldOrigin;
|
|
1971
1978
|
created_at?: string | null;
|
|
1972
1979
|
/** Moves when the world's own fields change, not on element writes. */
|
|
1973
1980
|
updated_at?: string | null;
|
|
1981
|
+
/**
|
|
1982
|
+
* Extension keys (keel #571): a tool's own setting on the world, any JSON value, served at the
|
|
1983
|
+
* top level as an element's are (the first is `x_names`, the names profile: see `typeWord`).
|
|
1984
|
+
* patchWorld sends them as given; `null` removes one; 64 KB in all, else a 422 `param: extensions`.
|
|
1985
|
+
*/
|
|
1986
|
+
[extension: `x_${string}`]: unknown;
|
|
1987
|
+
[extension: `atlas_${string}`]: unknown;
|
|
1988
|
+
[extension: `shadow_${string}`]: unknown;
|
|
1989
|
+
[field: string]: unknown;
|
|
1990
|
+
}
|
|
1991
|
+
/**
|
|
1992
|
+
* OwWorldMeta.origin (keel #571, #477), as keel's `World` component types it: both keys always
|
|
1993
|
+
* present, each an object or null. Kept as the writer gave it; keel checks only that `source.world`
|
|
1994
|
+
* and `producer.tool` are strings when present.
|
|
1995
|
+
*/
|
|
1996
|
+
interface OwWorldOrigin {
|
|
1997
|
+
source: OwWorldSource | null;
|
|
1998
|
+
producer: OwWorldProducer | null;
|
|
1999
|
+
}
|
|
2000
|
+
/** The folder format's `source` line (spec 4.2): the server and world a folder was exported from, and when. Kept as given. */
|
|
2001
|
+
interface OwWorldSource {
|
|
2002
|
+
server?: string;
|
|
2003
|
+
world?: string;
|
|
2004
|
+
at?: string;
|
|
2005
|
+
[field: string]: unknown;
|
|
2006
|
+
}
|
|
2007
|
+
/** The folder format's `producer` line (spec 4.2): the tool that made a folder, its version, and what it made it from. Kept as given. */
|
|
2008
|
+
interface OwWorldProducer {
|
|
2009
|
+
tool?: string;
|
|
2010
|
+
version?: string;
|
|
2011
|
+
input?: string;
|
|
1974
2012
|
[field: string]: unknown;
|
|
1975
2013
|
}
|
|
1976
2014
|
/** OwWorldMeta.public_page (keel #471), as keel's `World` component types it: all six keys, always. */
|
|
@@ -3421,7 +3459,10 @@ declare class OwV2Client {
|
|
|
3421
3459
|
/**
|
|
3422
3460
|
* PATCH /world -- partial world-meta update. The element write's server-managed keys are
|
|
3423
3461
|
* stripped, and so are the world's own read-only ones (WORLD_READ_ONLY_FIELDS: `slug` and
|
|
3424
|
-
* `public_page`, keel #471; `agent_writes_proposed`, keel #519; set on the world page, not here
|
|
3462
|
+
* `public_page`, keel #471; `agent_writes_proposed`, keel #519; set on the world page, not here;
|
|
3463
|
+
* `origin`, keel #571; `id`), so a `getWorld()` body can be sent back. The world's origin is
|
|
3464
|
+
* written as `source` and `producer` (keel #571, each an object or null, served under `origin`);
|
|
3465
|
+
* extension keys (`x_*`, `atlas_*`, `shadow_*`) are sent as given, and `null` removes one.
|
|
3425
3466
|
*/
|
|
3426
3467
|
patchWorld(partial: Record<string, unknown>): Promise<OwWorldMeta>;
|
|
3427
3468
|
/**
|
|
@@ -4371,7 +4412,8 @@ interface OwReadWorldFileOptions {
|
|
|
4371
4412
|
declare function simpleCaseFold(text: string): string;
|
|
4372
4413
|
/**
|
|
4373
4414
|
* Read a world file. Throws `OwWorldFileError` saying why, having returned
|
|
4374
|
-
* nothing; the caller writes only what this returns.
|
|
4415
|
+
* nothing; the caller writes only what this returns. An unknown option is a
|
|
4416
|
+
* `TypeError` before the bytes are looked at.
|
|
4375
4417
|
*/
|
|
4376
4418
|
declare function readWorldFile(bytes: Uint8Array, opts?: OwReadWorldFileOptions): OwReadWorldFile;
|
|
4377
4419
|
interface OwWriteWorldFileOptions {
|
|
@@ -4535,13 +4577,13 @@ declare function buildWorldIndex<T extends OwLookupElement>(elements: Iterable<T
|
|
|
4535
4577
|
* elements whose other text holds the question's words. An empty question
|
|
4536
4578
|
* returns no hits.
|
|
4537
4579
|
*/
|
|
4538
|
-
declare function lookupWorld<T extends OwLookupElement>(index: OwWorldIndex<T>, question: string,
|
|
4580
|
+
declare function lookupWorld<T extends OwLookupElement>(index: OwWorldIndex<T>, question: string, opts?: OwLookupOptions): OwLookupHit<T>[];
|
|
4539
4581
|
/**
|
|
4540
4582
|
* A compact text card for one element, for a person or a model: name, type,
|
|
4541
4583
|
* kind, description, its fields, its links by name (or how many point outside
|
|
4542
4584
|
* the data), and what links to it.
|
|
4543
4585
|
*/
|
|
4544
|
-
declare function renderElement<T extends OwLookupElement>(element: T, index: OwWorldIndex<T>,
|
|
4586
|
+
declare function renderElement<T extends OwLookupElement>(element: T, index: OwWorldIndex<T>, opts?: OwRenderOptions): string;
|
|
4545
4587
|
|
|
4546
4588
|
/**
|
|
4547
4589
|
* Context for keel's AI proxy (POST /api/v2/account/ask, Keel #159): the elements a
|
|
@@ -4641,9 +4683,9 @@ declare function planPhoto(source: {
|
|
|
4641
4683
|
type: string;
|
|
4642
4684
|
}, opts?: OwPhotoOptions): OwPhotoPlan;
|
|
4643
4685
|
/**
|
|
4644
|
-
* Shrink and convert a picture for upload. Throws `TypeError`
|
|
4645
|
-
*
|
|
4646
|
-
* over `maxBytes`.
|
|
4686
|
+
* Shrink and convert a picture for upload. Throws `TypeError` for an unknown
|
|
4687
|
+
* option (before anything is decoded), outside a browser, for a file the
|
|
4688
|
+
* browser cannot decode, or when the result is still over `maxBytes`.
|
|
4647
4689
|
*/
|
|
4648
4690
|
declare function preparePhoto(input: Blob, opts?: OwPhotoOptions): Promise<OwPreparedPhoto>;
|
|
4649
4691
|
|
|
@@ -4908,7 +4950,8 @@ declare function worldCalendars(elements: Iterable<OwCalendarElement>): WorldCal
|
|
|
4908
4950
|
*
|
|
4909
4951
|
* `fallbackToOnly`: when no calendar was ever chosen (`activeId` is `undefined`, not
|
|
4910
4952
|
* `null`) and the world holds exactly one, use it. `null` is an explicit "no calendar" and
|
|
4911
|
-
* stays null. With several calendars and no choice, nothing is guessed.
|
|
4953
|
+
* stays null. With several calendars and no choice, nothing is guessed. An unknown option is a
|
|
4954
|
+
* TypeError (the caller's bug, not the world's data).
|
|
4912
4955
|
*/
|
|
4913
4956
|
declare function resolveCalendarLens(elements: Iterable<OwCalendarElement>, activeId: string | null | undefined, opts?: {
|
|
4914
4957
|
fallbackToOnly?: boolean;
|
|
@@ -5218,4 +5261,4 @@ declare class TokenResource {
|
|
|
5218
5261
|
getEncryptionInfo(): Promise<EncryptionInfo>;
|
|
5219
5262
|
}
|
|
5220
5263
|
|
|
5221
|
-
export { AGENT_DOORS, ASK_LIMITS, type AccessKeyResponse, CALENDAR_FIELD, CALENDAR_SUPERTYPE, type CalendarConfig, type CalendarEra, type CalendarIntercalary, type CalendarMonths, type CalendarWeek, ELEMENT_FAMILIES, ELEMENT_ICONS, ELEMENT_LABELS, ELEMENT_SECTIONS, ELEMENT_TYPES, type ElementFamily, type ElementType, type EncryptionInfo, type EraDomain, FAMILY_COLORS, FAMILY_ORDER, FIELD_ACRONYMS, FIELD_SCHEMA, FILE_EXTENSIONS, type FieldInfo, type FieldType, GameTier, type ListParams, ONLYWORLDS_VERSION, type OwAccountWorld, type OwAgentJoined, type OwAllowance, OwApiError, type OwAskAnswer, type OwAskContext, type OwAuthErrorCode, type OwBulkItem, type OwBulkItemResult, type OwBulkResponse, type OwCalendarElement, type OwChange, type OwChangeDelete, type OwChangeUpsert, type OwChangesPage, type OwClientConfig, type OwCreatedWorldLink, type OwDeleteReason, type OwDraught, type OwDraughtComponent, type OwDraughtItem, type OwDraughtPolicy, type OwElement, type OwElementBase, type OwErrorBody, type OwFileAddedBy, type OwFileDownload, type OwFileKind, type OwFileRow, type OwFileTicket, type OwFrontDoor, type OwHiddenRow, type OwJoinPreview, type OwJoined, type OwJoinedMembership, type OwKeyKind, type OwLinkEdit, type OwLookupElement, type OwLookupHit, type OwLookupLink, type OwLookupOptions, type OwLookupReason, type OwMe, type OwMediaTicket, type OwMember, type OwMemberRole, type OwMintedKey, type OwNamesMap, OwNetworkError, type OwPage, type OwPhotoOptions, type OwPhotoPlan, type OwPlayerJoined, OwPreconditionFailedError, type OwPreparedPhoto, type OwProposal, type OwProposalAccepted, type OwProposalConflict, type OwProposalList, type OwProposalQuery, type OwProposalState, type OwProposeInput, type OwProposed, OwProposedError, type OwReadWorldFile, type OwReadWorldFileOptions, type OwRemovalTicket, type OwRemovedImage, type OwRenderOptions, type OwResyncReason, type OwSeat, type OwSeatCreated, type OwSignInBegin, type OwSignInBegun, type OwSignInComplete, OwSignInError, type OwSignInReason, type OwSignInResult, type OwSignInStorage, type OwSignedIn, type OwSortAddToRow, type OwSortAnswer, type OwSortAskRow, type OwSortLinkRow, type OwSortMakeRow, type OwSortNote, type OwSortRef, type OwSortRow, OwStaleProposalError, type OwUploadedFile, type OwUploadedImage, OwV2Client, type OwWordPair, type OwWorldFileEntry, OwWorldFileError, type OwWorldFileReason, type OwWorldFileRow, type OwWorldFiles, type OwWorldIndex, type OwWorldLink, type OwWorldMeta, type OwWorldProposalQuery, type OwWorldPublicPage, type OwWriteDoor, type OwWriteWorldFileOptions, PHOTO_MAX_BYTES, PHOTO_TYPES, PUBLIC_FIELDS, type ParseError, type ParseOptions, type ParseResult, ROOM_PAIRS, type RevokeAllSessionsResponse, type RevokeSessionResponse, SPATIAL_TYPES, type SectionInfo, type StepBreakdown, type TokenConsumeParams, type TokenConsumeResponse, TokenResource, type TokenStatus, type TokenTransport, WORLD_FILE_MAX_BYTES, WORLD_FILE_MAX_ENTRIES, WORLD_FILE_MEDIA_TYPE, type WorldCalendar, absYearForEraYear, absoluteYear, approxYearLength, base64url, breakdownStep, buildAskContext, buildWorldIndex, detectKeyKind, displayYear, elementColor, eraForStep, errorFromResponse, familyOf, fieldLabel, fileKindOf, floorDiv, floorMod, formatDuration, formatMidLabel, formatStep, formatYearLabel, getElementIcon, getElementLabel, isAgentDoor, isDemoKey, isKnownOf, isLeapYear, isParseError, isRoomElement, kindCanWrite, lookupWorld, monthStartSteps, parseDate, parseErrorEnvelope, pinExpectation, pkceChallenge, planPhoto, preparePhoto, readCalendarConfig, readCalendarValue, readWorldFile, renderElement, resolveCalendarLens, resolveEraDomains, simpleCaseFold, typeWord, validateCalendarConfig, weekdayForStep, worldCalendars, writeWorldFile, yearLength, yearStartStep };
|
|
5264
|
+
export { AGENT_DOORS, ASK_LIMITS, type AccessKeyResponse, CALENDAR_FIELD, CALENDAR_SUPERTYPE, type CalendarConfig, type CalendarEra, type CalendarIntercalary, type CalendarMonths, type CalendarWeek, ELEMENT_FAMILIES, ELEMENT_ICONS, ELEMENT_LABELS, ELEMENT_SECTIONS, ELEMENT_TYPES, type ElementFamily, type ElementType, type EncryptionInfo, type EraDomain, FAMILY_COLORS, FAMILY_ORDER, FIELD_ACRONYMS, FIELD_SCHEMA, FILE_EXTENSIONS, type FieldInfo, type FieldType, GameTier, type ListParams, ONLYWORLDS_VERSION, type OwAccountWorld, type OwAgentJoined, type OwAllowance, OwApiError, type OwAskAnswer, type OwAskContext, type OwAuthErrorCode, type OwBulkItem, type OwBulkItemResult, type OwBulkResponse, type OwCalendarElement, type OwChange, type OwChangeDelete, type OwChangeUpsert, type OwChangesPage, type OwClientConfig, type OwCreatedWorldLink, type OwDeleteReason, type OwDraught, type OwDraughtComponent, type OwDraughtItem, type OwDraughtPolicy, type OwElement, type OwElementBase, type OwErrorBody, type OwFileAddedBy, type OwFileDownload, type OwFileKind, type OwFileRow, type OwFileTicket, type OwFrontDoor, type OwHiddenRow, type OwJoinPreview, type OwJoined, type OwJoinedMembership, type OwKeyKind, type OwLinkEdit, type OwLookupElement, type OwLookupHit, type OwLookupLink, type OwLookupOptions, type OwLookupReason, type OwMe, type OwMediaTicket, type OwMember, type OwMemberRole, type OwMintedKey, type OwNamesMap, OwNetworkError, type OwPage, type OwPhotoOptions, type OwPhotoPlan, type OwPlayerJoined, OwPreconditionFailedError, type OwPreparedPhoto, type OwProposal, type OwProposalAccepted, type OwProposalConflict, type OwProposalList, type OwProposalQuery, type OwProposalState, type OwProposeInput, type OwProposed, OwProposedError, type OwReadWorldFile, type OwReadWorldFileOptions, type OwRemovalTicket, type OwRemovedImage, type OwRenderOptions, type OwResyncReason, type OwSeat, type OwSeatCreated, type OwSignInBegin, type OwSignInBegun, type OwSignInComplete, OwSignInError, type OwSignInReason, type OwSignInResult, type OwSignInStorage, type OwSignedIn, type OwSortAddToRow, type OwSortAnswer, type OwSortAskRow, type OwSortLinkRow, type OwSortMakeRow, type OwSortNote, type OwSortRef, type OwSortRow, OwStaleProposalError, type OwUploadedFile, type OwUploadedImage, OwV2Client, type OwWordPair, type OwWorldFileEntry, OwWorldFileError, type OwWorldFileReason, type OwWorldFileRow, type OwWorldFiles, type OwWorldIndex, type OwWorldLink, type OwWorldMeta, type OwWorldOrigin, type OwWorldProducer, type OwWorldProposalQuery, type OwWorldPublicPage, type OwWorldSource, type OwWriteDoor, type OwWriteWorldFileOptions, PHOTO_MAX_BYTES, PHOTO_TYPES, PUBLIC_FIELDS, type ParseError, type ParseOptions, type ParseResult, ROOM_PAIRS, type RevokeAllSessionsResponse, type RevokeSessionResponse, SPATIAL_TYPES, type SectionInfo, type StepBreakdown, type TokenConsumeParams, type TokenConsumeResponse, TokenResource, type TokenStatus, type TokenTransport, WORLD_FILE_MAX_BYTES, WORLD_FILE_MAX_ENTRIES, WORLD_FILE_MEDIA_TYPE, type WorldCalendar, absYearForEraYear, absoluteYear, approxYearLength, base64url, breakdownStep, buildAskContext, buildWorldIndex, detectKeyKind, displayYear, elementColor, eraForStep, errorFromResponse, familyOf, fieldLabel, fileKindOf, floorDiv, floorMod, formatDuration, formatMidLabel, formatStep, formatYearLabel, getElementIcon, getElementLabel, isAgentDoor, isDemoKey, isKnownOf, isLeapYear, isParseError, isRoomElement, kindCanWrite, lookupWorld, monthStartSteps, parseDate, parseErrorEnvelope, pinExpectation, pkceChallenge, planPhoto, preparePhoto, readCalendarConfig, readCalendarValue, readWorldFile, renderElement, resolveCalendarLens, resolveEraDomains, simpleCaseFold, typeWord, validateCalendarConfig, weekdayForStep, worldCalendars, writeWorldFile, yearLength, yearStartStep };
|
package/dist/index.js
CHANGED
|
@@ -56,6 +56,19 @@ function keyedId(idempotencyKey, index) {
|
|
|
56
56
|
${index}`);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
// src/options.ts
|
|
60
|
+
function unknownKey(opts, keys) {
|
|
61
|
+
if (!opts || typeof opts !== "object") return void 0;
|
|
62
|
+
for (const k of Object.keys(opts)) if (!keys.includes(k)) return k;
|
|
63
|
+
return void 0;
|
|
64
|
+
}
|
|
65
|
+
function refuseUnknownOptions(fn, opts, keys, after = "") {
|
|
66
|
+
const k = unknownKey(opts, keys);
|
|
67
|
+
if (k !== void 0) {
|
|
68
|
+
throw new TypeError(`${fn}: unknown option '${k}'. The keys are ${keys.join(", ")}.${after ? ` ${after}` : ""}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
59
72
|
// src/v2/errors.ts
|
|
60
73
|
var OwApiError = class extends Error {
|
|
61
74
|
constructor(status, code, message, docUrl, detail, type = null, param = null, retryAfter = null) {
|
|
@@ -342,6 +355,7 @@ var OwNetworkError = class extends Error {
|
|
|
342
355
|
};
|
|
343
356
|
var OwSignInError = class extends Error {
|
|
344
357
|
constructor(reason, message, opts = {}) {
|
|
358
|
+
refuseUnknownOptions("OwSignInError", opts, ["status", "code", "retryAfter"]);
|
|
345
359
|
super(message);
|
|
346
360
|
this.name = "OwSignInError";
|
|
347
361
|
this.reason = reason;
|
|
@@ -603,7 +617,10 @@ var OwV2Client = class {
|
|
|
603
617
|
/**
|
|
604
618
|
* PATCH /world -- partial world-meta update. The element write's server-managed keys are
|
|
605
619
|
* stripped, and so are the world's own read-only ones (WORLD_READ_ONLY_FIELDS: `slug` and
|
|
606
|
-
* `public_page`, keel #471; `agent_writes_proposed`, keel #519; set on the world page, not here
|
|
620
|
+
* `public_page`, keel #471; `agent_writes_proposed`, keel #519; set on the world page, not here;
|
|
621
|
+
* `origin`, keel #571; `id`), so a `getWorld()` body can be sent back. The world's origin is
|
|
622
|
+
* written as `source` and `producer` (keel #571, each an object or null, served under `origin`);
|
|
623
|
+
* extension keys (`x_*`, `atlas_*`, `shadow_*`) are sent as given, and `null` removes one.
|
|
607
624
|
*/
|
|
608
625
|
async patchWorld(partial) {
|
|
609
626
|
const body = sanitizePayload(partial);
|
|
@@ -652,7 +669,7 @@ var OwV2Client = class {
|
|
|
652
669
|
// -- Element CRUD --------------------------------------------------------
|
|
653
670
|
/** GET /{type}/ -- one cursor page. */
|
|
654
671
|
async list(type, params = {}) {
|
|
655
|
-
only("list", params, LIST_PARAM_KEYS,
|
|
672
|
+
only("list", params, LIST_PARAM_KEYS, LIST_FILTER_HINT);
|
|
656
673
|
const query = buildQuery({
|
|
657
674
|
limit: params.limit ?? this.pageSize,
|
|
658
675
|
cursor: params.cursor,
|
|
@@ -691,6 +708,7 @@ var OwV2Client = class {
|
|
|
691
708
|
}
|
|
692
709
|
/** Cursor-walk every page of a type. Politeness: uses config pageSize. */
|
|
693
710
|
async *listAll(type, params = {}) {
|
|
711
|
+
only("listAll", params, LIST_ALL_PARAM_KEYS, LIST_FILTER_HINT);
|
|
694
712
|
let cursor;
|
|
695
713
|
do {
|
|
696
714
|
const page = await this.list(type, { ...params, cursor });
|
|
@@ -1718,6 +1736,7 @@ var OwV2Client = class {
|
|
|
1718
1736
|
* sanitizePayload — callers own their body shape.
|
|
1719
1737
|
*/
|
|
1720
1738
|
async request(method, path, opts = {}) {
|
|
1739
|
+
only("request", opts, REQUEST_OPTION_KEYS);
|
|
1721
1740
|
if (opts.ifMatch !== void 0 && !(Number.isInteger(opts.ifMatch) && opts.ifMatch >= 0)) {
|
|
1722
1741
|
throw new TypeError(`ifMatch must be a whole number (an element's change_seq), got ${String(opts.ifMatch)}`);
|
|
1723
1742
|
}
|
|
@@ -1784,7 +1803,7 @@ var HeadPollState = class {
|
|
|
1784
1803
|
}
|
|
1785
1804
|
};
|
|
1786
1805
|
var READ_ONLY_FIELDS = ["world", "type", "created_at", "updated_at", "change_seq", "known_of"];
|
|
1787
|
-
var WORLD_READ_ONLY_FIELDS = ["slug", "public_page", "public_read", "agent_narrator_rule", "agent_writes_proposed"];
|
|
1806
|
+
var WORLD_READ_ONLY_FIELDS = ["id", "slug", "public_page", "public_read", "agent_narrator_rule", "agent_writes_proposed", "origin"];
|
|
1788
1807
|
function proposalsPath(type, id) {
|
|
1789
1808
|
return `/${type}/${encodeURIComponent(id)}/proposals`;
|
|
1790
1809
|
}
|
|
@@ -1930,12 +1949,26 @@ function objectKey(keyOrUrl) {
|
|
|
1930
1949
|
return decodeURIComponent(new URL(keyOrUrl).pathname.replace(/^\/+/, ""));
|
|
1931
1950
|
}
|
|
1932
1951
|
var LIST_PARAM_KEYS = ["limit", "cursor", "ids", "createdBy", "expand", "fields", "filter", "viewAs"];
|
|
1952
|
+
var LIST_ALL_PARAM_KEYS = LIST_PARAM_KEYS.filter((k) => k !== "cursor");
|
|
1953
|
+
var LIST_FILTER_HINT = "A wire filter (name, name__icontains, supertype, subtype, characters) goes under filter: { ... }.";
|
|
1954
|
+
var REQUEST_OPTION_KEYS = [
|
|
1955
|
+
"query",
|
|
1956
|
+
"body",
|
|
1957
|
+
"idempotencyKey",
|
|
1958
|
+
"auth",
|
|
1959
|
+
"allowEmpty",
|
|
1960
|
+
"replayAware",
|
|
1961
|
+
"write",
|
|
1962
|
+
"elementWrite",
|
|
1963
|
+
"proposable",
|
|
1964
|
+
"ifMatch",
|
|
1965
|
+
"ifNoneMatch",
|
|
1966
|
+
"onEtag"
|
|
1967
|
+
];
|
|
1933
1968
|
function only(method, obj, keys, hint = "") {
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
throw new TypeError(`${method}: unknown parameter '${k}'. ${hint ? hint + " " : ""}The keys are ${keys.join(", ")}. Nothing was sent.`);
|
|
1938
|
-
}
|
|
1969
|
+
const k = unknownKey(obj, keys);
|
|
1970
|
+
if (k !== void 0) {
|
|
1971
|
+
throw new TypeError(`${method}: unknown parameter '${k}'. ${hint ? hint + " " : ""}The keys are ${keys.join(", ")}. Nothing was sent.`);
|
|
1939
1972
|
}
|
|
1940
1973
|
}
|
|
1941
1974
|
var CLIENT_CONFIG_KEYS = ["apiKey", "apiPin", "baseUrl", "pageSize", "changesPageSize", "fetch", "agent", "client"];
|
|
@@ -2884,6 +2917,7 @@ var OwWorldFileError = class extends Error {
|
|
|
2884
2917
|
this.reason = reason;
|
|
2885
2918
|
}
|
|
2886
2919
|
};
|
|
2920
|
+
var READ_OPTION_KEYS = ["maxBytes", "maxEntries", "skip"];
|
|
2887
2921
|
var refuse = (reason, message) => {
|
|
2888
2922
|
throw new OwWorldFileError(reason, message);
|
|
2889
2923
|
};
|
|
@@ -3163,6 +3197,7 @@ function checkFileAndFolder(files) {
|
|
|
3163
3197
|
}
|
|
3164
3198
|
}
|
|
3165
3199
|
function readWorldFile(bytes, opts = {}) {
|
|
3200
|
+
refuseUnknownOptions("readWorldFile", opts, READ_OPTION_KEYS, "Nothing was read.");
|
|
3166
3201
|
const maxBytes = opts.maxBytes ?? WORLD_FILE_MAX_BYTES;
|
|
3167
3202
|
const maxEntries = opts.maxEntries ?? WORLD_FILE_MAX_ENTRIES;
|
|
3168
3203
|
const entries = centralDirectory(bytes);
|
|
@@ -3254,11 +3289,7 @@ var RECORDS_MANIFEST = "records/RECORDS.json";
|
|
|
3254
3289
|
function asksPrivate(opts) {
|
|
3255
3290
|
if (opts === void 0 || opts === null) return false;
|
|
3256
3291
|
if (typeof opts !== "object") throw new TypeError(`writeWorldFile: options must be an object, such as { includePrivateRecords: true }. Nothing was written.`);
|
|
3257
|
-
|
|
3258
|
-
if (!WRITE_OPTION_KEYS.includes(k)) {
|
|
3259
|
-
throw new TypeError(`writeWorldFile: unknown option '${k}'. The keys are ${WRITE_OPTION_KEYS.join(", ")}. Nothing was written.`);
|
|
3260
|
-
}
|
|
3261
|
-
}
|
|
3292
|
+
refuseUnknownOptions("writeWorldFile", opts, WRITE_OPTION_KEYS, "Nothing was written.");
|
|
3262
3293
|
const asked = opts.includePrivateRecords;
|
|
3263
3294
|
if (asked !== void 0 && typeof asked !== "boolean") {
|
|
3264
3295
|
throw new TypeError(`writeWorldFile: includePrivateRecords must be true or false; got ${JSON.stringify(asked) ?? String(asked)}. Nothing was written.`);
|
|
@@ -3369,7 +3400,7 @@ function isRoomElement(el) {
|
|
|
3369
3400
|
|
|
3370
3401
|
// src/names.ts
|
|
3371
3402
|
var SLUGS = new Set(ELEMENT_TYPES);
|
|
3372
|
-
var OPTION_KEYS =
|
|
3403
|
+
var OPTION_KEYS = ["supertype", "many"];
|
|
3373
3404
|
var isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
3374
3405
|
function word(pair, many) {
|
|
3375
3406
|
if (!isObject(pair) || typeof pair.one !== "string") return null;
|
|
@@ -3380,9 +3411,7 @@ function word(pair, many) {
|
|
|
3380
3411
|
return plural === "" ? one : plural;
|
|
3381
3412
|
}
|
|
3382
3413
|
function typeWord(world, type, opts = {}) {
|
|
3383
|
-
|
|
3384
|
-
if (!OPTION_KEYS.has(key)) throw new TypeError(`typeWord: unknown option "${key}" (known: supertype, many)`);
|
|
3385
|
-
}
|
|
3414
|
+
refuseUnknownOptions("typeWord", opts, OPTION_KEYS);
|
|
3386
3415
|
const map = world?.x_names;
|
|
3387
3416
|
if (!isObject(map) || map.version !== 1) return null;
|
|
3388
3417
|
const { types, supertypes } = map;
|
|
@@ -3405,6 +3434,8 @@ function typeWord(world, type, opts = {}) {
|
|
|
3405
3434
|
}
|
|
3406
3435
|
|
|
3407
3436
|
// src/lookup.ts
|
|
3437
|
+
var LOOKUP_OPTION_KEYS = ["limit"];
|
|
3438
|
+
var RENDER_OPTION_KEYS = ["descMax", "linkMax", "incomingMax"];
|
|
3408
3439
|
var STOP = /* @__PURE__ */ new Set([
|
|
3409
3440
|
"a",
|
|
3410
3441
|
"an",
|
|
@@ -3708,7 +3739,9 @@ function similarWords(w, vocab) {
|
|
|
3708
3739
|
}
|
|
3709
3740
|
return res;
|
|
3710
3741
|
}
|
|
3711
|
-
function lookupWorld(index, question,
|
|
3742
|
+
function lookupWorld(index, question, opts = {}) {
|
|
3743
|
+
refuseUnknownOptions("lookupWorld", opts, LOOKUP_OPTION_KEYS);
|
|
3744
|
+
const { limit = 8 } = opts;
|
|
3712
3745
|
const seeds = 12;
|
|
3713
3746
|
const q = words(normalize(question));
|
|
3714
3747
|
const qSet = new Set(q);
|
|
@@ -3825,7 +3858,9 @@ function lookupWorld(index, question, { limit = 8 } = {}) {
|
|
|
3825
3858
|
for (const [id, c] of cand) if (SPATIAL.has(index.byId.get(id).type)) c.score *= 0.85;
|
|
3826
3859
|
return [...cand.entries()].map(([id, c]) => ({ element: index.byId.get(id), score: Math.round(c.score * 10) / 10, reasons: c.reasons })).sort((a, b) => b.score - a.score || String(a.element.name).length - String(b.element.name).length || (a.element.id < b.element.id ? -1 : 1)).slice(0, limit);
|
|
3827
3860
|
}
|
|
3828
|
-
function renderElement(element, index,
|
|
3861
|
+
function renderElement(element, index, opts = {}) {
|
|
3862
|
+
refuseUnknownOptions("renderElement", opts, RENDER_OPTION_KEYS);
|
|
3863
|
+
const { descMax = 500, linkMax = 12, incomingMax = 10 } = opts;
|
|
3829
3864
|
const el = element;
|
|
3830
3865
|
const name = (id) => index.byId.get(id)?.name ?? "?";
|
|
3831
3866
|
const kind = [el.supertype, el.subtype].filter((x) => x && x !== "undefined").join(" / ");
|
|
@@ -3909,7 +3944,9 @@ function buildAskContext(items, index) {
|
|
|
3909
3944
|
// src/photo.ts
|
|
3910
3945
|
var PHOTO_TYPES = ["image/webp", "image/png", "image/jpeg", "image/avif"];
|
|
3911
3946
|
var PHOTO_MAX_BYTES = 15 * 1024 * 1024;
|
|
3947
|
+
var PHOTO_OPTION_KEYS = ["maxSide", "quality", "maxBytes"];
|
|
3912
3948
|
function planPhoto(source, opts = {}) {
|
|
3949
|
+
refuseUnknownOptions("planPhoto", opts, PHOTO_OPTION_KEYS);
|
|
3913
3950
|
const maxSide = opts.maxSide ?? 2048;
|
|
3914
3951
|
if (!(maxSide > 0)) throw new TypeError("preparePhoto: maxSide must be a positive number");
|
|
3915
3952
|
if (!(source.width > 0 && source.height > 0)) throw new TypeError("preparePhoto: the picture has no size");
|
|
@@ -3934,6 +3971,7 @@ function makeCanvas(width, height) {
|
|
|
3934
3971
|
throw new TypeError("preparePhoto needs a browser: no canvas here");
|
|
3935
3972
|
}
|
|
3936
3973
|
async function preparePhoto(input, opts = {}) {
|
|
3974
|
+
refuseUnknownOptions("preparePhoto", opts, PHOTO_OPTION_KEYS);
|
|
3937
3975
|
const quality = opts.quality ?? 0.82;
|
|
3938
3976
|
const maxBytes = opts.maxBytes ?? PHOTO_MAX_BYTES;
|
|
3939
3977
|
const decode = globalThis.createImageBitmap;
|
|
@@ -4272,6 +4310,7 @@ function formatMidLabel(cfg, step) {
|
|
|
4272
4310
|
if (b.monthName != null && b.day != null) return `${b.day} ${b.monthName} ${b.year}`;
|
|
4273
4311
|
return formatYearLabel(cfg, step);
|
|
4274
4312
|
}
|
|
4313
|
+
var PARSE_OPTION_KEYS = ["now"];
|
|
4275
4314
|
function absYearForEraYear(cfg, era, Y) {
|
|
4276
4315
|
if (era.restart === false) return Y;
|
|
4277
4316
|
const base = era.year_base ?? 1;
|
|
@@ -4290,6 +4329,7 @@ function defaultEra(cfg, now) {
|
|
|
4290
4329
|
return [...pool].sort((a, b) => b.start - a.start)[0];
|
|
4291
4330
|
}
|
|
4292
4331
|
function parseDate(cfg, input, opts = {}) {
|
|
4332
|
+
refuseUnknownOptions("parseDate", opts, PARSE_OPTION_KEYS);
|
|
4293
4333
|
const raw = input.trim();
|
|
4294
4334
|
if (raw === "") return { error: "empty date" };
|
|
4295
4335
|
if (/^-?\d+$/.test(raw)) return { step: parseInt(raw, 10) };
|
|
@@ -4420,6 +4460,7 @@ function worldCalendars(elements) {
|
|
|
4420
4460
|
return out;
|
|
4421
4461
|
}
|
|
4422
4462
|
function resolveCalendarLens(elements, activeId, opts) {
|
|
4463
|
+
refuseUnknownOptions("resolveCalendarLens", opts, ["fallbackToOnly"]);
|
|
4423
4464
|
if (activeId === void 0 && opts?.fallbackToOnly) {
|
|
4424
4465
|
const all = worldCalendars(elements);
|
|
4425
4466
|
return all.length === 1 ? all[0] : null;
|
|
@@ -4499,6 +4540,7 @@ var TokenResource = class {
|
|
|
4499
4540
|
* ```
|
|
4500
4541
|
*/
|
|
4501
4542
|
async consume(params) {
|
|
4543
|
+
refuseUnknownOptions("consume", params, ["amount", "service", "sessionId", "metadata"], "Nothing was sent.");
|
|
4502
4544
|
return this.req("POST", "/tokens/consume/", {
|
|
4503
4545
|
body: {
|
|
4504
4546
|
amount: params.amount,
|