@speleodb/api 0.1.0 → 0.2.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/README.md CHANGED
@@ -75,8 +75,11 @@ silently omitting an update. See the
75
75
  `onUploadProgress` or `onUploadComplete` selects the browser XHR transport. The
76
76
  completion callback means request bytes have been uploaded; the server response
77
77
  may still be pending. Without these callbacks, requests use fetch. XHR rejects
78
- cookie omission and redirect-refusal policies it cannot enforce; use fetch for
79
- those operations. Callback failures do not change the HTTP result.
78
+ cookie omission and redirect-refusal policies it cannot enforce. The XHR adapter
79
+ also rejects `responsePolicy: 'status-first-json'` because it waits for the
80
+ complete response body before inspecting status. Use fetch for those operations;
81
+ the adapter never silently discards upload callbacks by switching transports.
82
+ Callback failures do not change the HTTP result.
80
83
 
81
84
  ## Native and custom transports
82
85
 
@@ -133,7 +136,7 @@ schema.
133
136
 
134
137
  `bun run test` uses Vitest with Istanbul runtime coverage. A schema-derived
135
138
  loopback HTTP matrix exercises all 322 canonical operations, 525 generated
136
- request variants and 1,145 declared status/media combinations. It verifies
139
+ request variants and 1,148 declared status/media combinations. It verifies
137
140
  request bytes, complete response metadata, decoding and unexpected responses.
138
141
  Focused tests cover cancellation, streaming, redirects, credentials, forms, XHR
139
142
  adapter events and generation safety. CI verifies generation, strict types,
@@ -46,7 +46,7 @@ runtime calls use generated TypeScript and do not download the schema.
46
46
 
47
47
  Change endpoint behavior, serializer annotations and contract tests in the web
48
48
  repository first. Its
49
- [API contract documentation](https://github.com/OpenSpeleo/SpeleoDB/blob/9b55e7c706947c2a4443110400375730e761bd26/docs/api-contract.md)
49
+ [API contract documentation](https://github.com/OpenSpeleo/SpeleoDB/blob/93b445c7c5c7d69823a849806ea05b78058edec1/docs/api-contract.md)
50
50
  describes route inventory, allauth and OGC composition, error/media auditing and
51
51
  backend verification. Legacy v1 is intentionally excluded from this SDK.
52
52
 
@@ -233,7 +233,7 @@ hash-verifying source loader used by generation. It independently derives the
233
233
  operation, parameter, request-media and response-status/media inventory.
234
234
  `tests/generated-contract.test.ts` sends every generated callable through the
235
235
  public SDK and real fetch to an owned loopback HTTP server. Currently this means
236
- 322 canonical operations, 525 request-media callables and 1,145 declared
236
+ 322 canonical operations, 525 request-media callables and 1,148 declared
237
237
  status/media cases. Each callable is checked against the entire canonical
238
238
  response metadata, not only the response selected for its request test.
239
239
  Undeclared statuses and media are tested for every operation as well.
@@ -322,11 +322,16 @@ generator upgrades.
322
322
 
323
323
  Browser upload tests distinguish progress, upload completion and response
324
324
  completion. XHR cannot enforce cookie omission or redirect refusal and must
325
- reject those policy combinations. Native adapters retain their own transport and
326
- device verification: ordinary TypeScript tests cannot prove cookie isolation
327
- inside an iOS/Android HTTP stack or cancellation on physical devices. In mobile,
328
- retain GIS status-before-body behavior and existing session/offline persistence
329
- regressions.
325
+ reject those policy combinations. Our XHR adapter waits for the complete
326
+ response before inspecting its status, so it also rejects
327
+ `responsePolicy: 'status-first-json'` before constructing or sending a request.
328
+ Keep regressions for explicit XHR selection and both upload callbacks with an
329
+ untimed client: denial bodies must never silently become an indefinite wait. Do
330
+ not fall back to fetch while silently dropping upload observers. Native adapters
331
+ retain their own transport and device verification: ordinary TypeScript tests
332
+ cannot prove cookie isolation inside an iOS/Android HTTP stack or cancellation
333
+ on physical devices. In mobile, retain GIS status-before-body behavior and
334
+ existing session/offline persistence regressions.
330
335
 
331
336
  The public generated options argument remains optional due to the fetch
332
337
  generator's signature, but an ApiClient is required at runtime. Do not introduce
@@ -363,6 +368,24 @@ operations or optional fields can be a minor release; behavior-preserving fixes
363
368
  can be patches. While the package is `0.x`, communicate breaking changes clearly
364
369
  and use a new minor version rather than quietly shipping them as a patch.
365
370
 
371
+ ### Migrating from 0.1.x to 0.2.0
372
+
373
+ Cylinder installation creation now requires `project` in JSON, multipart and
374
+ URL-encoded inputs, matching the backend's non-null project association. Include
375
+ the existing project identifier when creating an installation; PUT/PATCH
376
+ continue to allow omission to preserve the current association. Downloads at a
377
+ specified revision now recognize JSON 400, 422 and 500 responses as documented
378
+ results. Narrow the response by `kind` and `status` as usual. The XHR adapter
379
+ now rejects `status-first-json` before sending; use fetch without upload
380
+ observers when that response policy is required.
381
+
382
+ These corrections require the 0.2.0 minor release because creation inputs are
383
+ stricter. Update the exact package pin and standalone lock in each consumer,
384
+ then run its own types, tests and build against the published package. The web
385
+ backend remains the sole schema owner.
386
+
387
+ ### Release coordination
388
+
366
389
  The SDK version in `package.json` is independent of the backend version in
367
390
  OpenAPI's `info.version`. Never edit the backend YAML to bump the SDK version;
368
391
  the source record must continue identifying the reviewed producer bytes.
@@ -406,7 +429,7 @@ bun pm pack --destination "$archive_dir" --ignore-scripts
406
429
  mkdir "$archive_dir/consumer"
407
430
  cd "$archive_dir/consumer"
408
431
  printf '{"name":"sdk-smoke","private":true,"type":"module"}\n' > package.json
409
- bun add "$archive_dir/speleodb-api-0.1.0.tgz"
432
+ bun add "$archive_dir/speleodb-api-0.2.0.tgz"
410
433
  bun add --dev typescript@6.0.3
411
434
  cat > smoke.ts <<'TS'
412
435
  import { createApiClient, v2ProjectsList } from '@speleodb/api';
@@ -485,8 +508,8 @@ export or hash mismatch before the publish job can run.
485
508
  After the required tests and repository-local prek checks pass, inspect the
486
509
  reviewed archive and commit the same source and documentation. When publication
487
510
  and Git actions are authorized, push the reviewed SDK commit and its
488
- `v<package.json version>` tag to its own upstream. For version `0.1.0`, the tag
489
- must be `v0.1.0`; the workflow rejects a mismatch. The publish job waits for
511
+ `v<package.json version>` tag to its own upstream. For version `0.2.0`, the tag
512
+ must be `v0.2.0`; the workflow rejects a mismatch. The publish job waits for
490
513
  `verify`, performs its own frozen install and build, and runs
491
514
  `npm publish --access public` from that tagged checkout. It packages the tagged
492
515
  files itself; the local archive is the reviewed candidate, not a separate
@@ -496,7 +519,7 @@ Wait for the tag workflow's successful publish job, then query the actual
496
519
  registry version:
497
520
 
498
521
  ```sh
499
- bun pm view @speleodb/api@0.1.0 name version dist.integrity
522
+ bun pm view @speleodb/api@0.2.0 name version dist.integrity
500
523
  ```
501
524
 
502
525
  Use the actual release version. Inspect the published archive's file list,
@@ -1,4 +1,4 @@
1
1
  {
2
- "revision": "9b55e7c706947c2a4443110400375730e761bd26",
3
- "sha256": "c5b25a601e9ffcc18fcc165e695a5390cd6bdf496bbe4ee05ffcd190d2e7ee58"
2
+ "revision": "93b445c7c5c7d69823a849806ea05b78058edec1",
3
+ "sha256": "0074e12e23591cf0cbcdd6208c8d5df1989d09014e50ee22a38602c3d99f5a51"
4
4
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@speleodb/api",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "registry": "https://registry.npmjs.org/"
@@ -9,7 +9,7 @@ import type { CylinderInstallCreateRequestRequestUnitSystem } from "./cylinderIn
9
9
  */
10
10
  export interface CylinderInstallCreateRequestRequest {
11
11
  cylinder: string;
12
- project?: string;
12
+ project: string;
13
13
  /** Station latitude coordinate */
14
14
  latitude: string | number;
15
15
  /** Station longitude coordinate */
@@ -1292,8 +1292,11 @@ export * from "./v2ProjectsDownloadRetrieveByFormat403";
1292
1292
  export * from "./v2ProjectsDownloadRetrieveByFormat404";
1293
1293
  export * from "./v2ProjectsDownloadRetrieveByFormat422";
1294
1294
  export * from "./v2ProjectsDownloadRetrieveByFormat500";
1295
+ export * from "./v2ProjectsDownloadRetrieveByFormatAtHash400";
1295
1296
  export * from "./v2ProjectsDownloadRetrieveByFormatAtHash403";
1296
1297
  export * from "./v2ProjectsDownloadRetrieveByFormatAtHash404";
1298
+ export * from "./v2ProjectsDownloadRetrieveByFormatAtHash422";
1299
+ export * from "./v2ProjectsDownloadRetrieveByFormatAtHash500";
1297
1300
  export * from "./v2ProjectsExplorationLeadsCreateWithFormData400";
1298
1301
  export * from "./v2ProjectsExplorationLeadsCreateWithFormData403";
1299
1302
  export * from "./v2ProjectsExplorationLeadsCreateWithFormData404";
@@ -9,7 +9,7 @@ import type { V2CylinderInstallsCreateBodyOneUnitSystem } from "./v2CylinderInst
9
9
  */
10
10
  export type V2CylinderInstallsCreateBodyOne = {
11
11
  cylinder: string;
12
- project?: string;
12
+ project: string;
13
13
  /** Station latitude coordinate */
14
14
  latitude: string | number;
15
15
  /** Station longitude coordinate */
@@ -9,7 +9,7 @@ import type { V2CylinderInstallsCreateBodyThreeUnitSystem } from "./v2CylinderIn
9
9
  */
10
10
  export type V2CylinderInstallsCreateBodyThree = {
11
11
  cylinder: string;
12
- project?: string;
12
+ project: string;
13
13
  /** Station latitude coordinate */
14
14
  latitude: string | number;
15
15
  /** Station longitude coordinate */
@@ -9,7 +9,7 @@ import type { V2CylinderInstallsCreateBodyTwoUnitSystem } from "./v2CylinderInst
9
9
  */
10
10
  export type V2CylinderInstallsCreateBodyTwo = {
11
11
  cylinder: string;
12
- project?: string;
12
+ project: string;
13
13
  /** Station latitude coordinate */
14
14
  latitude: string | number;
15
15
  /** Station longitude coordinate */
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Generated by Orval 8.43.0 from OpenAPI.yaml. Do not edit.
3
+ */
4
+
5
+ export type V2ProjectsDownloadRetrieveByFormatAtHash400 =
6
+ | { [key: string]: string | string[] }
7
+ | {
8
+ error: string;
9
+ }
10
+ | {
11
+ detail: string;
12
+ }
13
+ | {
14
+ errors: { [key: string]: unknown } | string[];
15
+ };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Generated by Orval 8.43.0 from OpenAPI.yaml. Do not edit.
3
+ */
4
+
5
+ export type V2ProjectsDownloadRetrieveByFormatAtHash422 =
6
+ | { [key: string]: string | string[] }
7
+ | {
8
+ error: string;
9
+ }
10
+ | {
11
+ detail: string;
12
+ }
13
+ | {
14
+ errors: { [key: string]: unknown } | string[];
15
+ };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Generated by Orval 8.43.0 from OpenAPI.yaml. Do not edit.
3
+ */
4
+
5
+ export type V2ProjectsDownloadRetrieveByFormatAtHash500 =
6
+ | { [key: string]: string | string[] }
7
+ | {
8
+ error: string;
9
+ }
10
+ | {
11
+ detail: string;
12
+ }
13
+ | {
14
+ errors: { [key: string]: unknown } | string[];
15
+ };
@@ -896,8 +896,11 @@ import type {
896
896
  V2ProjectsDownloadRetrieveByFormat404,
897
897
  V2ProjectsDownloadRetrieveByFormat422,
898
898
  V2ProjectsDownloadRetrieveByFormat500,
899
+ V2ProjectsDownloadRetrieveByFormatAtHash400,
899
900
  V2ProjectsDownloadRetrieveByFormatAtHash403,
900
901
  V2ProjectsDownloadRetrieveByFormatAtHash404,
902
+ V2ProjectsDownloadRetrieveByFormatAtHash422,
903
+ V2ProjectsDownloadRetrieveByFormatAtHash500,
901
904
  V2ProjectsExplorationLeadsCreateWithFormData400,
902
905
  V2ProjectsExplorationLeadsCreateWithFormData403,
903
906
  V2ProjectsExplorationLeadsCreateWithFormData404,
@@ -19308,6 +19311,11 @@ export type v2ProjectsDownloadRetrieveByFormatAtHashResponse200 = {
19308
19311
  status: 200;
19309
19312
  };
19310
19313
 
19314
+ export type v2ProjectsDownloadRetrieveByFormatAtHashResponse400 = {
19315
+ data: V2ProjectsDownloadRetrieveByFormatAtHash400;
19316
+ status: 400;
19317
+ };
19318
+
19311
19319
  export type v2ProjectsDownloadRetrieveByFormatAtHashResponse403 = {
19312
19320
  data: V2ProjectsDownloadRetrieveByFormatAtHash403;
19313
19321
  status: 403;
@@ -19318,13 +19326,26 @@ export type v2ProjectsDownloadRetrieveByFormatAtHashResponse404 = {
19318
19326
  status: 404;
19319
19327
  };
19320
19328
 
19329
+ export type v2ProjectsDownloadRetrieveByFormatAtHashResponse422 = {
19330
+ data: V2ProjectsDownloadRetrieveByFormatAtHash422;
19331
+ status: 422;
19332
+ };
19333
+
19334
+ export type v2ProjectsDownloadRetrieveByFormatAtHashResponse500 = {
19335
+ data: V2ProjectsDownloadRetrieveByFormatAtHash500;
19336
+ status: 500;
19337
+ };
19338
+
19321
19339
  export type v2ProjectsDownloadRetrieveByFormatAtHashResponseSuccess =
19322
19340
  v2ProjectsDownloadRetrieveByFormatAtHashResponse200 & {
19323
19341
  headers: Headers;
19324
19342
  };
19325
19343
  export type v2ProjectsDownloadRetrieveByFormatAtHashResponseError = (
19344
+ | v2ProjectsDownloadRetrieveByFormatAtHashResponse400
19326
19345
  | v2ProjectsDownloadRetrieveByFormatAtHashResponse403
19327
19346
  | v2ProjectsDownloadRetrieveByFormatAtHashResponse404
19347
+ | v2ProjectsDownloadRetrieveByFormatAtHashResponse422
19348
+ | v2ProjectsDownloadRetrieveByFormatAtHashResponse500
19328
19349
  ) & {
19329
19350
  headers: Headers;
19330
19351
  };
@@ -19357,8 +19378,11 @@ export const v2ProjectsDownloadRetrieveByFormatAtHash = (
19357
19378
  operationId: "v2_projects_download_retrieve_by_format_at_hash",
19358
19379
  responses: {
19359
19380
  "200": { content: { "application/octet-stream": "blob" } },
19381
+ "400": { content: { "application/json": "json" } },
19360
19382
  "403": { content: { "application/json": "json" } },
19361
19383
  "404": { content: { "application/json": "json" } },
19384
+ "422": { content: { "application/json": "json" } },
19385
+ "500": { content: { "application/json": "json" } },
19362
19386
  },
19363
19387
  },
19364
19388
  ...options,
@@ -46,6 +46,13 @@ export function xhrTransport(
46
46
  ),
47
47
  );
48
48
  }
49
+ if (request.responsePolicy === "status-first-json") {
50
+ return Promise.reject(
51
+ new TypeError(
52
+ "The XHR adapter does not support status-first responses. Use the fetch transport.",
53
+ ),
54
+ );
55
+ }
49
56
  return new Promise((resolve, reject) => {
50
57
  request.signal.throwIfAborted();
51
58
  const xhr = new XMLHttpRequest();