@comms-id/company 0.4.0 → 0.5.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/README.md CHANGED
@@ -27,7 +27,7 @@ Every operation is a read, safe to repeat, and is retried after a retryable fail
27
27
 
28
28
  Entries: `.` (types and errors, safe in a browser), `./server` (signs each call), `./browser` (your relay route; never signs), `./fixtures` (LOCAL FIXTURES, no network), `./descriptor` (what `@comms-id/relay` may forward).
29
29
 
30
- The package is private until the publishing path exists (#515). `LICENSE` is the consumer client licence.
30
+ `LICENSE` is the consumer client licence.
31
31
 
32
32
  ## The field
33
33
 
@@ -2,7 +2,7 @@ import { type CallOptions, type TransportConfig } from "../runtime/http.js";
2
2
  import type { LookupRequest, LookupResponse, SearchRequest, SearchResponse } from "./types.js";
3
3
  /** The client of Comms.ID Company: one method for each operation. */
4
4
  export interface CompanyClient {
5
- /** Look up one nine-digit ACN in the company snapshot. ABN lookup is not offered in v1. At most ten rows; no uniqueness or complete history claim. */
5
+ /** Look up one nine-digit ACN in the company snapshot. ABN lookup is not offered in v1. At most ten rows; no uniqueness or complete history claim. Only the nine-digit normal form is accepted. identifierState is current or retired when ASIC establishes it, with a source deregistration date as YYYY-MM-DD when available; unknown statuses omit it. No successor ACN is invented. */
6
6
  readonly lookup: (input: LookupRequest, options?: CallOptions) => Promise<LookupResponse>;
7
7
  /** Search the company snapshot by case-insensitive name prefix and optional exact status. Default eight rows, maximum ten, no paging. A snapshot miss does not prove absence from the live register. */
8
8
  readonly search: (input: SearchRequest, options?: CallOptions) => Promise<SearchResponse>;
@@ -40,6 +40,10 @@ export const fixtures = {
40
40
  "format": "CSV",
41
41
  "observedAt": "2026-10-01T00:00:00Z",
42
42
  "license": "http://creativecommons.org/licenses/by/3.0/au/"
43
+ },
44
+ "identifierState": {
45
+ "value": "001234567",
46
+ "state": "current"
43
47
  }
44
48
  },
45
49
  "/company/v1/search": {
@@ -311,6 +311,95 @@ export const operations = {
311
311
  "license"
312
312
  ],
313
313
  "extra": false
314
+ },
315
+ "identifierState": {
316
+ "t": "any_of",
317
+ "of": [
318
+ {
319
+ "t": "obj",
320
+ "props": {
321
+ "value": {
322
+ "t": "str"
323
+ },
324
+ "state": {
325
+ "t": "str",
326
+ "values": [
327
+ "current"
328
+ ]
329
+ }
330
+ },
331
+ "req": [
332
+ "value",
333
+ "state"
334
+ ],
335
+ "extra": false
336
+ },
337
+ {
338
+ "t": "obj",
339
+ "props": {
340
+ "value": {
341
+ "t": "str"
342
+ },
343
+ "state": {
344
+ "t": "str",
345
+ "values": [
346
+ "superseded"
347
+ ]
348
+ },
349
+ "since": {
350
+ "t": "str"
351
+ },
352
+ "successors": {
353
+ "t": "arr",
354
+ "of": {
355
+ "t": "obj",
356
+ "props": {
357
+ "value": {
358
+ "t": "str"
359
+ },
360
+ "kind": {
361
+ "t": "str"
362
+ }
363
+ },
364
+ "req": [
365
+ "value",
366
+ "kind"
367
+ ],
368
+ "extra": false
369
+ },
370
+ "min": 1
371
+ }
372
+ },
373
+ "req": [
374
+ "value",
375
+ "state",
376
+ "successors"
377
+ ],
378
+ "extra": false
379
+ },
380
+ {
381
+ "t": "obj",
382
+ "props": {
383
+ "value": {
384
+ "t": "str"
385
+ },
386
+ "state": {
387
+ "t": "str",
388
+ "values": [
389
+ "retired"
390
+ ]
391
+ },
392
+ "since": {
393
+ "t": "str"
394
+ }
395
+ },
396
+ "req": [
397
+ "value",
398
+ "state"
399
+ ],
400
+ "extra": false
401
+ }
402
+ ]
314
403
  }
315
404
  },
316
405
  "req": [
@@ -649,6 +738,95 @@ export const operations = {
649
738
  "license"
650
739
  ],
651
740
  "extra": false
741
+ },
742
+ "identifierState": {
743
+ "t": "any_of",
744
+ "of": [
745
+ {
746
+ "t": "obj",
747
+ "props": {
748
+ "value": {
749
+ "t": "str"
750
+ },
751
+ "state": {
752
+ "t": "str",
753
+ "values": [
754
+ "current"
755
+ ]
756
+ }
757
+ },
758
+ "req": [
759
+ "value",
760
+ "state"
761
+ ],
762
+ "extra": false
763
+ },
764
+ {
765
+ "t": "obj",
766
+ "props": {
767
+ "value": {
768
+ "t": "str"
769
+ },
770
+ "state": {
771
+ "t": "str",
772
+ "values": [
773
+ "superseded"
774
+ ]
775
+ },
776
+ "since": {
777
+ "t": "str"
778
+ },
779
+ "successors": {
780
+ "t": "arr",
781
+ "of": {
782
+ "t": "obj",
783
+ "props": {
784
+ "value": {
785
+ "t": "str"
786
+ },
787
+ "kind": {
788
+ "t": "str"
789
+ }
790
+ },
791
+ "req": [
792
+ "value",
793
+ "kind"
794
+ ],
795
+ "extra": false
796
+ },
797
+ "min": 1
798
+ }
799
+ },
800
+ "req": [
801
+ "value",
802
+ "state",
803
+ "successors"
804
+ ],
805
+ "extra": false
806
+ },
807
+ {
808
+ "t": "obj",
809
+ "props": {
810
+ "value": {
811
+ "t": "str"
812
+ },
813
+ "state": {
814
+ "t": "str",
815
+ "values": [
816
+ "retired"
817
+ ]
818
+ },
819
+ "since": {
820
+ "t": "str"
821
+ }
822
+ },
823
+ "req": [
824
+ "value",
825
+ "state"
826
+ ],
827
+ "extra": false
828
+ }
829
+ ]
652
830
  }
653
831
  },
654
832
  "req": [
@@ -40,6 +40,28 @@ export type LookupResponse = {
40
40
  readonly observedAt: string;
41
41
  readonly license: string;
42
42
  };
43
+ readonly identifierState?: {
44
+ /** The identifier in its normal form (digits only). */
45
+ readonly value: string;
46
+ readonly state: "current";
47
+ } | {
48
+ /** The identifier in its normal form (digits only). */
49
+ readonly value: string;
50
+ readonly state: "superseded";
51
+ /** When the identifier entered this state (YYYY-MM-DD), when the source dates it. */
52
+ readonly since?: string;
53
+ readonly successors: ReadonlyArray<{
54
+ readonly value: string;
55
+ /** The kind of the successor identifier, for example abn. */
56
+ readonly kind: string;
57
+ }>;
58
+ } | {
59
+ /** The identifier in its normal form (digits only). */
60
+ readonly value: string;
61
+ readonly state: "retired";
62
+ /** When the identifier entered this state (YYYY-MM-DD), when the source dates it. */
63
+ readonly since?: string;
64
+ };
43
65
  };
44
66
  /** The body of search. */
45
67
  export type SearchRequest = {
@@ -85,4 +107,26 @@ export type SearchResponse = {
85
107
  readonly observedAt: string;
86
108
  readonly license: string;
87
109
  };
110
+ readonly identifierState?: {
111
+ /** The identifier in its normal form (digits only). */
112
+ readonly value: string;
113
+ readonly state: "current";
114
+ } | {
115
+ /** The identifier in its normal form (digits only). */
116
+ readonly value: string;
117
+ readonly state: "superseded";
118
+ /** When the identifier entered this state (YYYY-MM-DD), when the source dates it. */
119
+ readonly since?: string;
120
+ readonly successors: ReadonlyArray<{
121
+ readonly value: string;
122
+ /** The kind of the successor identifier, for example abn. */
123
+ readonly kind: string;
124
+ }>;
125
+ } | {
126
+ /** The identifier in its normal form (digits only). */
127
+ readonly value: string;
128
+ readonly state: "retired";
129
+ /** When the identifier entered this state (YYYY-MM-DD), when the source dates it. */
130
+ readonly since?: string;
131
+ };
88
132
  };
@@ -142,7 +142,9 @@ const prepare = (operation, input) => {
142
142
  /** Sends one operation and returns its decoded reply, or throws a CommsIdError. */
143
143
  export const call = async (transport, operation, input, options = {}) => {
144
144
  const body = prepare(operation, input);
145
- const deadline = AbortSignal.timeout(options.deadlineMs ?? transport.deadlineMs ?? DEFAULT_DEADLINE_MS);
145
+ const deadlineMs = options.deadlineMs ?? transport.deadlineMs ?? DEFAULT_DEADLINE_MS;
146
+ const startedAt = performance.now();
147
+ const deadline = AbortSignal.timeout(deadlineMs);
146
148
  const signal = options.signal === undefined ? deadline : AbortSignal.any([options.signal, deadline]);
147
149
  const maxRetries = operation.safeToRetry ? (transport.maxRetries ?? DEFAULT_MAX_RETRIES) : 0;
148
150
  const sleep = transport.sleep ?? defaultSleep;
@@ -155,6 +157,11 @@ export const call = async (transport, operation, input, options = {}) => {
155
157
  throw result.error;
156
158
  }
157
159
  const delay = result.retryAfterMs ?? Math.min(BASE_DELAY_MS * 2 ** attempt, MAX_DELAY_MS);
160
+ // A retry that cannot start within this call's budget must not replace a real
161
+ // service failure (notably 429) with a later timeout or violate Retry-After.
162
+ if (delay >= deadlineMs - (performance.now() - startedAt)) {
163
+ throw result.error;
164
+ }
158
165
  try {
159
166
  await sleep(delay, signal);
160
167
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@comms-id/company",
3
- "version": "0.4.0",
3
+ "version": "0.5.1",
4
4
  "description": "Typed client for the Comms.ID Company API: Australian companies from ASIC's public registers: search by name, look up one by ACN",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -49,9 +49,9 @@
49
49
  "README.md"
50
50
  ],
51
51
  "devDependencies": {
52
- "@types/node": "24.19.0",
52
+ "@types/node": "24.19.1",
53
53
  "typescript": "7.0.2",
54
- "vitest": "5.0.2"
54
+ "vitest": "5.0.3"
55
55
  },
56
56
  "publishConfig": {
57
57
  "access": "public",