@onlyworlds/sdk 4.7.3 → 4.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -33,7 +33,7 @@ type ElementType = 'ability' | 'character' | 'collective' | 'construct' | 'creat
33
33
  declare const ELEMENT_TYPES: ElementType[];
34
34
  /** Canonical OnlyWorlds schema version. Source: the `canonical:` value of the pinned
35
35
  * distribution's VERSION file (see the provenance block at the top of this file). */
36
- declare const ONLYWORLDS_VERSION: "00.31.00";
36
+ declare const ONLYWORLDS_VERSION: "00.32.00";
37
37
  /** The four semantic families (colour carries the family; ELEMENT_ICONS carries the type). */
38
38
  type ElementFamily = 'agents' | 'world' | 'abstract' | 'temporal';
39
39
  /** Per-type semantic family. Source: the distribution's `presentation.json` sidecar
@@ -1970,6 +1970,37 @@ interface OwMediaTicket {
1970
1970
  membership: string | null;
1971
1971
  };
1972
1972
  }
1973
+ /**
1974
+ * POST /media/remove-ticket's 200: a short-lived, single-use permission to remove one
1975
+ * image. keel issues it to the image's uploader or the world's owner key; the edge at
1976
+ * `remove_url` does the removal.
1977
+ */
1978
+ interface OwRemovalTicket {
1979
+ /** Opaque: send it to `remove_url` as `Authorization: Bearer <ticket>`, as is. */
1980
+ ticket: string;
1981
+ /** Where the removal goes: the upload host's /v1/remove (https://upload.onlyworlds.com/v1/remove on production). */
1982
+ remove_url: string;
1983
+ /** Unix seconds after which the edge refuses the ticket (10 minutes after issue). */
1984
+ exp: number;
1985
+ /** The object key the ticket removes. */
1986
+ key: string;
1987
+ /** How many of the world's elements show the image. Removal does not change them: clear their `image_url` yourself. */
1988
+ referenced: number;
1989
+ }
1990
+ /** The edge's 200 for one removal. */
1991
+ interface OwRemovedImage {
1992
+ /** The object key that was removed. */
1993
+ removed: string;
1994
+ /** The bytes given back to the uploading account's storage. */
1995
+ bytes: number;
1996
+ /**
1997
+ * `may_linger`: copies the network or a browser already holds can keep answering for days
1998
+ * or longer (images are cached as unchanging for a year). `purging`: the edge cache is
1999
+ * being cleared too.
2000
+ */
2001
+ cache: 'may_linger' | 'purging' | (string & {});
2002
+ [k: string]: unknown;
2003
+ }
1973
2004
  /** The edge's 201 for one upload. Put `url` in an element's `image_url`. */
1974
2005
  interface OwUploadedImage {
1975
2006
  /** The permanent public URL (https://media.onlyworlds.com/<key>). */
@@ -2280,6 +2311,34 @@ declare class OwV2Client {
2280
2311
  key?: string;
2281
2312
  ticket?: OwMediaTicket;
2282
2313
  }): Promise<OwUploadedImage>;
2314
+ /**
2315
+ * POST /media/remove-ticket -- permission to remove ONE image (a write key and its
2316
+ * PIN). The image's uploader may remove it, and so may the world's owner key; an
2317
+ * agent seat answers as its sponsor. Only images uploaded with a ticket qualify.
2318
+ * `key` is the object key, or the whole image_url (the part after the host is taken).
2319
+ * The reply's `referenced` counts the world's elements still showing the image.
2320
+ * Refusals: 403 `permission_error` (neither uploader nor owner), 404 `not_found`
2321
+ * (no removable image under this key), 409 `removal_in_flight` (a ticket for this
2322
+ * image is already out) and 409 `upload_pending` (an upload is not yet recorded), both
2323
+ * with Retry-After.
2324
+ */
2325
+ createRemovalTicket(key: string): Promise<OwRemovalTicket>;
2326
+ /**
2327
+ * Remove one uploaded image: a removal ticket from the API, then the removal at the
2328
+ * edge (the API key never leaves for the edge). Pass the object key or the whole
2329
+ * image_url, or a ticket from createRemovalTicket() to use it instead of fetching one.
2330
+ * The bytes go back to the uploading account's storage.
2331
+ *
2332
+ * Removal does not touch elements: clear or replace their `image_url` yourself (the
2333
+ * ticket's `referenced` says how many there are). A copy already cached by the network
2334
+ * or a browser can keep answering for a while (`cache: 'may_linger'`). The edge's
2335
+ * refusals arrive as OwApiError with its code: 401 `ticket_expired` / `ticket_used` /
2336
+ * `ticket_invalid`, 403 `not_removable`, 502 `remove_failed` (nothing removed; the
2337
+ * ticket is still unspent).
2338
+ */
2339
+ removeImage(keyOrUrl: string, opts?: {
2340
+ ticket?: OwRemovalTicket;
2341
+ }): Promise<OwRemovedImage>;
2283
2342
  /**
2284
2343
  * Raw authenticated request against this client's baseUrl. Public since 4.0
2285
2344
  * so auxiliary resources can ride the same transport — it structurally
@@ -2653,4 +2712,4 @@ declare class TokenResource {
2653
2712
  getEncryptionInfo(): Promise<EncryptionInfo>;
2654
2713
  }
2655
2714
 
2656
- export { type AccessKeyResponse, ELEMENT_FAMILIES, ELEMENT_ICONS, ELEMENT_LABELS, ELEMENT_SECTIONS, ELEMENT_TYPES, type ElementFamily, type ElementType, type EncryptionInfo, FAMILY_COLORS, FAMILY_ORDER, FIELD_SCHEMA, type FieldInfo, type FieldType, GameTier, type ListParams, ONLYWORLDS_VERSION, OwApiError, type OwAuthErrorCode, type OwBulkItem, type OwBulkItemResult, type OwBulkResponse, type OwChange, type OwChangesPage, type OwClientConfig, type OwElement, type OwElementBase, type OwErrorBody, type OwKeyKind, type OwLinkEdit, type OwMediaTicket, OwNetworkError, type OwPage, type OwUploadedImage, OwV2Client, type OwWorldMeta, type RevokeAllSessionsResponse, type RevokeSessionResponse, SPATIAL_TYPES, type SectionInfo, type TokenConsumeParams, type TokenConsumeResponse, TokenResource, type TokenStatus, type TokenTransport, detectKeyKind, elementColor, errorFromResponse, familyOf, getElementIcon, getElementLabel, isDemoKey, kindCanWrite, parseErrorEnvelope, pinExpectation };
2715
+ export { type AccessKeyResponse, ELEMENT_FAMILIES, ELEMENT_ICONS, ELEMENT_LABELS, ELEMENT_SECTIONS, ELEMENT_TYPES, type ElementFamily, type ElementType, type EncryptionInfo, FAMILY_COLORS, FAMILY_ORDER, FIELD_SCHEMA, type FieldInfo, type FieldType, GameTier, type ListParams, ONLYWORLDS_VERSION, OwApiError, type OwAuthErrorCode, type OwBulkItem, type OwBulkItemResult, type OwBulkResponse, type OwChange, type OwChangesPage, type OwClientConfig, type OwElement, type OwElementBase, type OwErrorBody, type OwKeyKind, type OwLinkEdit, type OwMediaTicket, OwNetworkError, type OwPage, type OwRemovalTicket, type OwRemovedImage, type OwUploadedImage, OwV2Client, type OwWorldMeta, type RevokeAllSessionsResponse, type RevokeSessionResponse, SPATIAL_TYPES, type SectionInfo, type TokenConsumeParams, type TokenConsumeResponse, TokenResource, type TokenStatus, type TokenTransport, detectKeyKind, elementColor, errorFromResponse, familyOf, getElementIcon, getElementLabel, isDemoKey, kindCanWrite, parseErrorEnvelope, pinExpectation };
package/dist/index.js CHANGED
@@ -348,6 +348,44 @@ var OwV2Client = class {
348
348
  if (!res.ok) throw await errorFromResponse(res);
349
349
  return await res.json();
350
350
  }
351
+ /**
352
+ * POST /media/remove-ticket -- permission to remove ONE image (a write key and its
353
+ * PIN). The image's uploader may remove it, and so may the world's owner key; an
354
+ * agent seat answers as its sponsor. Only images uploaded with a ticket qualify.
355
+ * `key` is the object key, or the whole image_url (the part after the host is taken).
356
+ * The reply's `referenced` counts the world's elements still showing the image.
357
+ * Refusals: 403 `permission_error` (neither uploader nor owner), 404 `not_found`
358
+ * (no removable image under this key), 409 `removal_in_flight` (a ticket for this
359
+ * image is already out) and 409 `upload_pending` (an upload is not yet recorded), both
360
+ * with Retry-After.
361
+ */
362
+ async createRemovalTicket(key) {
363
+ return this.request("POST", "/media/remove-ticket", { body: { key: objectKey(key) } });
364
+ }
365
+ /**
366
+ * Remove one uploaded image: a removal ticket from the API, then the removal at the
367
+ * edge (the API key never leaves for the edge). Pass the object key or the whole
368
+ * image_url, or a ticket from createRemovalTicket() to use it instead of fetching one.
369
+ * The bytes go back to the uploading account's storage.
370
+ *
371
+ * Removal does not touch elements: clear or replace their `image_url` yourself (the
372
+ * ticket's `referenced` says how many there are). A copy already cached by the network
373
+ * or a browser can keep answering for a while (`cache: 'may_linger'`). The edge's
374
+ * refusals arrive as OwApiError with its code: 401 `ticket_expired` / `ticket_used` /
375
+ * `ticket_invalid`, 403 `not_removable`, 502 `remove_failed` (nothing removed; the
376
+ * ticket is still unspent).
377
+ */
378
+ async removeImage(keyOrUrl, opts = {}) {
379
+ const ticket = opts.ticket ?? await this.createRemovalTicket(keyOrUrl);
380
+ let res;
381
+ try {
382
+ res = await this.fetchImpl(ticket.remove_url, { method: "POST", headers: { Authorization: `Bearer ${ticket.ticket}` } });
383
+ } catch (cause) {
384
+ throw new OwNetworkError(`OnlyWorlds image removal failed: POST ${ticket.remove_url}`, cause);
385
+ }
386
+ if (!res.ok) throw await errorFromResponse(res);
387
+ return await res.json();
388
+ }
351
389
  // -- Core request machinery ----------------------------------------------
352
390
  /**
353
391
  * Raw authenticated request against this client's baseUrl. Public since 4.0
@@ -423,6 +461,10 @@ function mintUuid(now = Date.now()) {
423
461
  for (let i = 0; i < 256; i++) hex.push((i + 256).toString(16).slice(1));
424
462
  return hex[bytes[0]] + hex[bytes[1]] + hex[bytes[2]] + hex[bytes[3]] + "-" + hex[bytes[4]] + hex[bytes[5]] + "-" + hex[bytes[6]] + hex[bytes[7]] + "-" + hex[bytes[8]] + hex[bytes[9]] + "-" + hex[bytes[10]] + hex[bytes[11]] + hex[bytes[12]] + hex[bytes[13]] + hex[bytes[14]] + hex[bytes[15]];
425
463
  }
464
+ function objectKey(keyOrUrl) {
465
+ if (!/^https?:\/\//i.test(keyOrUrl)) return keyOrUrl;
466
+ return decodeURIComponent(new URL(keyOrUrl).pathname.replace(/^\/+/, ""));
467
+ }
426
468
  function buildQuery(params) {
427
469
  const q = new URLSearchParams();
428
470
  for (const [k, v] of Object.entries(params)) {
@@ -433,7 +475,7 @@ function buildQuery(params) {
433
475
 
434
476
  // src/v2/types.generated.ts
435
477
  var ELEMENT_TYPES = ["ability", "character", "collective", "construct", "creature", "event", "family", "institution", "language", "law", "location", "map", "marker", "narrative", "object", "phenomenon", "pin", "relation", "species", "title", "trait", "zone"];
436
- var ONLYWORLDS_VERSION = "00.31.00";
478
+ var ONLYWORLDS_VERSION = "00.32.00";
437
479
  var ELEMENT_FAMILIES = {
438
480
  ability: "abstract",
439
481
  character: "agents",
package/package.json CHANGED
@@ -1,64 +1,64 @@
1
- {
2
- "name": "@onlyworlds/sdk",
3
- "version": "4.7.3",
4
- "description": "TypeScript SDK for the OnlyWorlds API - build world-building applications with type safety",
5
- "type": "module",
6
- "exports": {
7
- ".": {
8
- "types": "./dist/index.d.ts",
9
- "import": "./dist/index.js"
10
- },
11
- "./package.json": "./package.json"
12
- },
13
- "types": "dist/index.d.ts",
14
- "sideEffects": false,
15
- "files": [
16
- "dist",
17
- "README.md",
18
- "AGENTS.md",
19
- "CHANGELOG.md",
20
- "SCHEMA.md"
21
- ],
22
- "scripts": {
23
- "build": "tsup src/index.ts --format esm --dts --clean",
24
- "dev": "tsup src/index.ts --format esm --dts --watch",
25
- "pretest": "npm run build",
26
- "test": "node --test",
27
- "codegen": "python codegen/generate_types.py",
28
- "codegen:check": "python codegen/generate_types.py --check",
29
- "schema:verify": "python codegen/verify_dist.py",
30
- "schema:check": "npm run schema:verify && npm run codegen:check",
31
- "prepublishOnly": "npm run build",
32
- "release:verify": "node codegen/verify_release.mjs"
33
- },
34
- "keywords": [
35
- "onlyworlds",
36
- "worldbuilding",
37
- "api",
38
- "sdk",
39
- "typescript",
40
- "rpg",
41
- "ttrpg",
42
- "game-development"
43
- ],
44
- "author": "OnlyWorlds",
45
- "license": "MIT",
46
- "repository": {
47
- "type": "git",
48
- "url": "git+https://github.com/OnlyWorlds/sdk.git"
49
- },
50
- "homepage": "https://onlyworlds.github.io/",
51
- "bugs": {
52
- "url": "https://github.com/OnlyWorlds/sdk/issues"
53
- },
54
- "devDependencies": {
55
- "tsup": "^8.0.1",
56
- "typescript": "^5.3.3"
57
- },
58
- "peerDependencies": {
59
- "typescript": ">=4.5.0"
60
- },
61
- "engines": {
62
- "node": ">=18.0.0"
63
- }
64
- }
1
+ {
2
+ "name": "@onlyworlds/sdk",
3
+ "version": "4.8.1",
4
+ "description": "TypeScript SDK for the OnlyWorlds API - build world-building applications with type safety",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/index.d.ts",
9
+ "import": "./dist/index.js"
10
+ },
11
+ "./package.json": "./package.json"
12
+ },
13
+ "types": "dist/index.d.ts",
14
+ "sideEffects": false,
15
+ "files": [
16
+ "dist",
17
+ "README.md",
18
+ "AGENTS.md",
19
+ "CHANGELOG.md",
20
+ "SCHEMA.md"
21
+ ],
22
+ "scripts": {
23
+ "build": "tsup src/index.ts --format esm --dts --clean",
24
+ "dev": "tsup src/index.ts --format esm --dts --watch",
25
+ "pretest": "npm run build",
26
+ "test": "node --test",
27
+ "codegen": "python codegen/generate_types.py",
28
+ "codegen:check": "python codegen/generate_types.py --check",
29
+ "schema:verify": "python codegen/verify_dist.py",
30
+ "schema:check": "npm run schema:verify && npm run codegen:check",
31
+ "prepublishOnly": "npm run build",
32
+ "release:verify": "node codegen/verify_release.mjs"
33
+ },
34
+ "keywords": [
35
+ "onlyworlds",
36
+ "worldbuilding",
37
+ "api",
38
+ "sdk",
39
+ "typescript",
40
+ "rpg",
41
+ "ttrpg",
42
+ "game-development"
43
+ ],
44
+ "author": "OnlyWorlds",
45
+ "license": "MIT",
46
+ "repository": {
47
+ "type": "git",
48
+ "url": "git+https://github.com/OnlyWorlds/sdk.git"
49
+ },
50
+ "homepage": "https://onlyworlds.github.io/",
51
+ "bugs": {
52
+ "url": "https://github.com/OnlyWorlds/sdk/issues"
53
+ },
54
+ "devDependencies": {
55
+ "tsup": "^8.0.1",
56
+ "typescript": "^5.3.3"
57
+ },
58
+ "peerDependencies": {
59
+ "typescript": ">=4.5.0"
60
+ },
61
+ "engines": {
62
+ "node": ">=18.0.0"
63
+ }
64
+ }