@comms-id/company 0.5.0 → 1.0.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 +5 -5
- package/dist/descriptor.d.ts +2 -2
- package/dist/descriptor.js +2 -2
- package/dist/generated/client.d.ts +1 -1
- package/dist/generated/fixtures.js +9 -7
- package/dist/generated/operations.js +35 -27
- package/dist/generated/types.d.ts +7 -3
- package/dist/local/profile.d.ts +8 -3
- package/dist/local/profile.js +31 -15
- package/dist/runtime/http.js +8 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# @comms-id/company
|
|
2
2
|
|
|
3
|
-
Typed client for the Comms.ID Company API (`https://api.comms.id/company/
|
|
3
|
+
Typed client for the Comms.ID Company API (`https://api.comms.id/company/v2`): Australian companies from ASIC's public registers: search by name, look up one by ACN or ARBN. Each record names its number `asicNumber` and its kind `asicNumberType` (`ACN`, or `ARBN` for a registered foreign company or registered Australian body). Company v1 and its `acn` field are retired (ADR-0050, #714); earlier versions of this package call v1 and get `VERSION_RETIRED`.
|
|
4
4
|
|
|
5
|
-
`src/` is generated from the Company contract (`packages/asic-public-registers/openapi/company.
|
|
5
|
+
`src/` is generated from the Company contract (`packages/asic-public-registers/openapi/company.v2.json`) by `@comms-id/forge-transformers`. Do not edit it: change the contract and run `pnpm --filter @comms-id/forge-transformers generate`.
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
import { createCompanyClient } from "@comms-id/company/server";
|
|
@@ -11,12 +11,12 @@ const client = createCompanyClient({
|
|
|
11
11
|
clientId: process.env.COMMS_ID_CLIENT_ID!,
|
|
12
12
|
privateJwk: JSON.parse(process.env.COMMS_ID_PRIVATE_JWK!),
|
|
13
13
|
});
|
|
14
|
-
const reply = await client.lookup({"
|
|
14
|
+
const reply = await client.lookup({"asicNumber": "001234564"});
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
## Operations
|
|
18
18
|
|
|
19
|
-
- `lookup`: Look up one nine-digit ACN in the company snapshot. ABN lookup is not offered
|
|
19
|
+
- `lookup`: Look up one nine-digit ASIC number (ACN or ARBN) with a valid ASIC check digit in the company snapshot. ABN lookup is not offered. At most ten rows; no uniqueness or complete history claim.
|
|
20
20
|
- `search`: 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.
|
|
21
21
|
|
|
22
22
|
Every operation is a read, safe to repeat, and is retried after a retryable failure. A reply that is not a match is one of the outcomes of the reply convention: an error with `outcomeOf(error)` of `no-match`, `source-unavailable` or `failed`; an outage is never a "no match".
|
|
@@ -31,7 +31,7 @@ Entries: `.` (types and errors, safe in a browser), `./server` (signs each call)
|
|
|
31
31
|
|
|
32
32
|
## The field
|
|
33
33
|
|
|
34
|
-
`@comms-id/company/controller` is the headless controller of a company name or
|
|
34
|
+
`@comms-id/company/controller` is the headless controller of a company name, ACN or ARBN field: input, debounce, suggestions, identifier checks, choice and errors, with the WAI-ARIA combobox attributes and key handler. It has no framework and no DOM. `@comms-id/company-react` (a hook and a component) and `<comms-id-company>` (a web element) run on it, and so can your own UI.
|
|
35
35
|
|
|
36
36
|
```ts
|
|
37
37
|
import { createCompanyController } from "@comms-id/company/controller";
|
package/dist/descriptor.d.ts
CHANGED
|
@@ -6,10 +6,10 @@ export declare const companyProduct: {
|
|
|
6
6
|
readonly operations: readonly [{
|
|
7
7
|
readonly name: "lookup";
|
|
8
8
|
readonly method: "POST";
|
|
9
|
-
readonly path: "/company/
|
|
9
|
+
readonly path: "/company/v2/lookup";
|
|
10
10
|
}, {
|
|
11
11
|
readonly name: "search";
|
|
12
12
|
readonly method: "POST";
|
|
13
|
-
readonly path: "/company/
|
|
13
|
+
readonly path: "/company/v2/search";
|
|
14
14
|
}];
|
|
15
15
|
};
|
package/dist/descriptor.js
CHANGED
|
@@ -9,12 +9,12 @@ export const companyProduct = {
|
|
|
9
9
|
{
|
|
10
10
|
"name": "lookup",
|
|
11
11
|
"method": "POST",
|
|
12
|
-
"path": "/company/
|
|
12
|
+
"path": "/company/v2/lookup"
|
|
13
13
|
},
|
|
14
14
|
{
|
|
15
15
|
"name": "search",
|
|
16
16
|
"method": "POST",
|
|
17
|
-
"path": "/company/
|
|
17
|
+
"path": "/company/v2/search"
|
|
18
18
|
}
|
|
19
19
|
],
|
|
20
20
|
};
|
|
@@ -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
|
|
5
|
+
/** Look up one nine-digit ASIC number in the company snapshot. Only the nine-digit normal form with a valid ASIC check digit is accepted. Each record names its asicNumber and asicNumberType: ACN for an Australian company (APTY, APUB, CCIV), ARBN for a registered foreign company or registered Australian body (FNOS, RACN). ABN lookup is not offered. At most ten rows; no uniqueness or complete history claim. 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 number 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>;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Every reply is the example in the contract.
|
|
3
3
|
/** LOCAL FIXTURES: one canned reply for each operation path. Fake data. */
|
|
4
4
|
export const fixtures = {
|
|
5
|
-
"/company/
|
|
5
|
+
"/company/v2/lookup": {
|
|
6
6
|
"activatedAt": "2026-10-01T00:01:00Z",
|
|
7
7
|
"attribution": "Australian Securities and Investments Commission via data.gov.au; Creative Commons Attribution 3.0 Australia",
|
|
8
8
|
"generation": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
|
@@ -13,11 +13,12 @@ export const fixtures = {
|
|
|
13
13
|
"records": [
|
|
14
14
|
{
|
|
15
15
|
"register": "companies",
|
|
16
|
-
"
|
|
16
|
+
"asicNumber": "001234564",
|
|
17
|
+
"asicNumberType": "ACN",
|
|
17
18
|
"name": "EXAMPLE COMPANY PTY LTD",
|
|
18
19
|
"status": "Registered",
|
|
19
20
|
"abn": "99001234567",
|
|
20
|
-
"type":
|
|
21
|
+
"type": "APTY",
|
|
21
22
|
"companyClass": null,
|
|
22
23
|
"subClass": null,
|
|
23
24
|
"registeredAt": null,
|
|
@@ -42,11 +43,11 @@ export const fixtures = {
|
|
|
42
43
|
"license": "http://creativecommons.org/licenses/by/3.0/au/"
|
|
43
44
|
},
|
|
44
45
|
"identifierState": {
|
|
45
|
-
"value": "
|
|
46
|
+
"value": "001234564",
|
|
46
47
|
"state": "current"
|
|
47
48
|
}
|
|
48
49
|
},
|
|
49
|
-
"/company/
|
|
50
|
+
"/company/v2/search": {
|
|
50
51
|
"activatedAt": "2026-10-01T00:01:00Z",
|
|
51
52
|
"attribution": "Australian Securities and Investments Commission via data.gov.au; Creative Commons Attribution 3.0 Australia",
|
|
52
53
|
"generation": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
|
@@ -57,11 +58,12 @@ export const fixtures = {
|
|
|
57
58
|
"records": [
|
|
58
59
|
{
|
|
59
60
|
"register": "companies",
|
|
60
|
-
"
|
|
61
|
+
"asicNumber": "001234564",
|
|
62
|
+
"asicNumberType": "ACN",
|
|
61
63
|
"name": "EXAMPLE COMPANY PTY LTD",
|
|
62
64
|
"status": "Registered",
|
|
63
65
|
"abn": "99001234567",
|
|
64
|
-
"type":
|
|
66
|
+
"type": "APTY",
|
|
65
67
|
"companyClass": null,
|
|
66
68
|
"subClass": null,
|
|
67
69
|
"registeredAt": null,
|
|
@@ -4,18 +4,18 @@ export const operations = {
|
|
|
4
4
|
lookup: {
|
|
5
5
|
name: "lookup",
|
|
6
6
|
method: "POST",
|
|
7
|
-
path: "/company/
|
|
7
|
+
path: "/company/v2/lookup",
|
|
8
8
|
safeToRetry: true,
|
|
9
9
|
request: {
|
|
10
10
|
"t": "obj",
|
|
11
11
|
"props": {
|
|
12
|
-
"
|
|
12
|
+
"asicNumber": {
|
|
13
13
|
"t": "str",
|
|
14
|
-
"pattern": "
|
|
14
|
+
"pattern": "^\\d{9}$"
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
"req": [
|
|
18
|
-
"
|
|
18
|
+
"asicNumber"
|
|
19
19
|
],
|
|
20
20
|
"extra": false
|
|
21
21
|
},
|
|
@@ -70,15 +70,18 @@ export const operations = {
|
|
|
70
70
|
"companies"
|
|
71
71
|
]
|
|
72
72
|
},
|
|
73
|
-
"
|
|
74
|
-
"t": "
|
|
75
|
-
"
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
73
|
+
"asicNumber": {
|
|
74
|
+
"t": "str",
|
|
75
|
+
"pattern": "^\\d{9}$"
|
|
76
|
+
},
|
|
77
|
+
"asicNumberType": {
|
|
78
|
+
"t": "str",
|
|
79
|
+
"values": [
|
|
80
|
+
"ACN",
|
|
81
|
+
"ARBN",
|
|
82
|
+
"ARSN",
|
|
83
|
+
"ARFN",
|
|
84
|
+
"undetermined"
|
|
82
85
|
]
|
|
83
86
|
},
|
|
84
87
|
"name": {
|
|
@@ -227,7 +230,8 @@ export const operations = {
|
|
|
227
230
|
},
|
|
228
231
|
"req": [
|
|
229
232
|
"register",
|
|
230
|
-
"
|
|
233
|
+
"asicNumber",
|
|
234
|
+
"asicNumberType",
|
|
231
235
|
"name",
|
|
232
236
|
"status",
|
|
233
237
|
"abn",
|
|
@@ -420,7 +424,7 @@ export const operations = {
|
|
|
420
424
|
search: {
|
|
421
425
|
name: "search",
|
|
422
426
|
method: "POST",
|
|
423
|
-
path: "/company/
|
|
427
|
+
path: "/company/v2/search",
|
|
424
428
|
safeToRetry: true,
|
|
425
429
|
request: {
|
|
426
430
|
"t": "obj",
|
|
@@ -497,15 +501,18 @@ export const operations = {
|
|
|
497
501
|
"companies"
|
|
498
502
|
]
|
|
499
503
|
},
|
|
500
|
-
"
|
|
501
|
-
"t": "
|
|
502
|
-
"
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
504
|
+
"asicNumber": {
|
|
505
|
+
"t": "str",
|
|
506
|
+
"pattern": "^\\d{9}$"
|
|
507
|
+
},
|
|
508
|
+
"asicNumberType": {
|
|
509
|
+
"t": "str",
|
|
510
|
+
"values": [
|
|
511
|
+
"ACN",
|
|
512
|
+
"ARBN",
|
|
513
|
+
"ARSN",
|
|
514
|
+
"ARFN",
|
|
515
|
+
"undetermined"
|
|
509
516
|
]
|
|
510
517
|
},
|
|
511
518
|
"name": {
|
|
@@ -654,7 +661,8 @@ export const operations = {
|
|
|
654
661
|
},
|
|
655
662
|
"req": [
|
|
656
663
|
"register",
|
|
657
|
-
"
|
|
664
|
+
"asicNumber",
|
|
665
|
+
"asicNumberType",
|
|
658
666
|
"name",
|
|
659
667
|
"status",
|
|
660
668
|
"abn",
|
|
@@ -847,6 +855,6 @@ export const operations = {
|
|
|
847
855
|
};
|
|
848
856
|
/** The error codes the contract documents for each operation. */
|
|
849
857
|
export const errorCodes = {
|
|
850
|
-
lookup: ["INVALID_INPUT", "UNAUTHORIZED", "RESIDENCY_INGRESS", "NOT_FOUND", "METHOD_NOT_ALLOWED", "LIMIT_REACHED", "FAIR_USE_CEILING", "CANCELLED", "INTERNAL_ERROR", "UNAVAILABLE", "RESIDENCY_UNAVAILABLE"],
|
|
851
|
-
search: ["INVALID_INPUT", "UNAUTHORIZED", "RESIDENCY_INGRESS", "NOT_FOUND", "METHOD_NOT_ALLOWED", "LIMIT_REACHED", "FAIR_USE_CEILING", "CANCELLED", "INTERNAL_ERROR", "UNAVAILABLE", "RESIDENCY_UNAVAILABLE"],
|
|
858
|
+
lookup: ["INVALID_INPUT", "UNAUTHORIZED", "RESIDENCY_INGRESS", "NOT_FOUND", "METHOD_NOT_ALLOWED", "VERSION_RETIRED", "LIMIT_REACHED", "FAIR_USE_CEILING", "CANCELLED", "INTERNAL_ERROR", "UNAVAILABLE", "RESIDENCY_UNAVAILABLE"],
|
|
859
|
+
search: ["INVALID_INPUT", "UNAUTHORIZED", "RESIDENCY_INGRESS", "NOT_FOUND", "METHOD_NOT_ALLOWED", "VERSION_RETIRED", "LIMIT_REACHED", "FAIR_USE_CEILING", "CANCELLED", "INTERNAL_ERROR", "UNAVAILABLE", "RESIDENCY_UNAVAILABLE"],
|
|
852
860
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** The body of lookup. */
|
|
2
2
|
export type LookupRequest = {
|
|
3
|
-
readonly
|
|
3
|
+
readonly asicNumber: string;
|
|
4
4
|
};
|
|
5
5
|
/** The reply of lookup. */
|
|
6
6
|
export type LookupResponse = {
|
|
@@ -13,7 +13,9 @@ export type LookupResponse = {
|
|
|
13
13
|
readonly offset: 0;
|
|
14
14
|
readonly records: ReadonlyArray<{
|
|
15
15
|
readonly register: "companies";
|
|
16
|
-
|
|
16
|
+
/** The ASIC number the register lists for this row (ACN or ARBN; see asicNumberType). */
|
|
17
|
+
readonly asicNumber: string;
|
|
18
|
+
readonly asicNumberType: "ACN" | "ARBN" | "ARSN" | "ARFN" | "undetermined";
|
|
17
19
|
readonly name: string | null;
|
|
18
20
|
readonly status: string | null;
|
|
19
21
|
readonly abn: string | null;
|
|
@@ -80,7 +82,9 @@ export type SearchResponse = {
|
|
|
80
82
|
readonly offset: 0;
|
|
81
83
|
readonly records: ReadonlyArray<{
|
|
82
84
|
readonly register: "companies";
|
|
83
|
-
|
|
85
|
+
/** The ASIC number the register lists for this row (ACN or ARBN; see asicNumberType). */
|
|
86
|
+
readonly asicNumber: string;
|
|
87
|
+
readonly asicNumberType: "ACN" | "ARBN" | "ARSN" | "ARFN" | "undetermined";
|
|
84
88
|
readonly name: string | null;
|
|
85
89
|
readonly status: string | null;
|
|
86
90
|
readonly abn: string | null;
|
package/dist/local/profile.d.ts
CHANGED
|
@@ -4,8 +4,13 @@ import type { FieldProfile } from "../runtime/field-types.js";
|
|
|
4
4
|
/** One company record of the ASIC register snapshot. */
|
|
5
5
|
export type ProductRecord = LookupResponse["records"][number];
|
|
6
6
|
export declare const ATTRIBUTION = "Company data: Australian Securities and Investments Commission, via data.gov.au (CC BY 3.0 AU).";
|
|
7
|
-
/** "
|
|
8
|
-
export declare const
|
|
9
|
-
/**
|
|
7
|
+
/** "001234564" as "001 234 564"; anything else is shown as it is. */
|
|
8
|
+
export declare const formatAsicNumber: (value: string) => string;
|
|
9
|
+
/**
|
|
10
|
+
* "ACN 001 234 564", "ARBN 001 234 591": the number named by the kind the register gives it
|
|
11
|
+
* (#714, #719). A number of unknown kind is an "ASIC number", never assumed to be an ACN.
|
|
12
|
+
*/
|
|
13
|
+
export declare const describeAsicNumber: (record: ProductRecord) => string;
|
|
14
|
+
/** One line for a found company: name, the ASIC number with its kind, and status. The full record is in `onSelect`. */
|
|
10
15
|
export declare const describeCompany: (record: ProductRecord) => string;
|
|
11
16
|
export declare const profile: FieldProfile<CompanyClient, ProductRecord>;
|
package/dist/local/profile.js
CHANGED
|
@@ -1,27 +1,36 @@
|
|
|
1
1
|
// The Company field's profile: the only company-specific code of the field. It reads the typed
|
|
2
|
-
// text (a nine-digit
|
|
2
|
+
// text (a nine-digit ASIC number is looked up, anything else is searched by name), calls the client, and
|
|
3
3
|
// reduces every reply to the text the UIs show and the record the consumer receives. The
|
|
4
4
|
// controller, the React package and the web element are generated and know nothing else.
|
|
5
5
|
import { isCommsIdError } from "../runtime/errors.js";
|
|
6
6
|
export const ATTRIBUTION = "Company data: Australian Securities and Investments Commission, via data.gov.au (CC BY 3.0 AU).";
|
|
7
|
-
const
|
|
7
|
+
const NUMBER_DIGITS = 9;
|
|
8
|
+
const WEIGHTS = [8, 7, 6, 5, 4, 3, 2, 1];
|
|
8
9
|
/** The contract allows ten rows at most. */
|
|
9
10
|
const MAX_LIMIT = 10;
|
|
10
11
|
const NUMBER_TEXT = /^[\d\s-]+$/;
|
|
11
12
|
const SEPARATORS = /[\s-]/g;
|
|
12
|
-
/** "
|
|
13
|
-
export const
|
|
13
|
+
/** "001234564" as "001 234 564"; anything else is shown as it is. */
|
|
14
|
+
export const formatAsicNumber = (value) => value.length === NUMBER_DIGITS ? `${value.slice(0, 3)} ${value.slice(3, 6)} ${value.slice(6)}` : value;
|
|
15
|
+
/** ASIC's check digit, shared by every kind of ASIC number (#721): it validates, it never types. */
|
|
16
|
+
const checkDigitIsValid = (digits) => (10 - (WEIGHTS.reduce((sum, weight, index) => sum + weight * Number(digits[index]), 0) % 10)) % 10 ===
|
|
17
|
+
Number(digits[NUMBER_DIGITS - 1]);
|
|
18
|
+
/**
|
|
19
|
+
* "ACN 001 234 564", "ARBN 001 234 591": the number named by the kind the register gives it
|
|
20
|
+
* (#714, #719). A number of unknown kind is an "ASIC number", never assumed to be an ACN.
|
|
21
|
+
*/
|
|
22
|
+
export const describeAsicNumber = (record) => `${record.asicNumberType === "undetermined" ? "ASIC number" : record.asicNumberType} ${formatAsicNumber(record.asicNumber)}`;
|
|
14
23
|
const nameOf = (record) => record.name ?? record.currentName ?? "Unnamed company";
|
|
15
24
|
const compact = (parts) => parts.filter((part) => part !== null && part !== undefined && part !== "");
|
|
16
|
-
/** One line for a found company: name,
|
|
17
|
-
export const describeCompany = (record) => compact([nameOf(record),
|
|
25
|
+
/** One line for a found company: name, the ASIC number with its kind, and status. The full record is in `onSelect`. */
|
|
26
|
+
export const describeCompany = (record) => compact([nameOf(record), describeAsicNumber(record), record.status]).join(" · ");
|
|
18
27
|
const foundOf = (reply, record) => ({
|
|
19
28
|
record,
|
|
20
29
|
summary: describeCompany(record),
|
|
21
30
|
asAt: reply.activatedAt ?? reply.source.observedAt,
|
|
22
31
|
attribution: reply.attribution,
|
|
23
32
|
});
|
|
24
|
-
/** The service answers an unknown name or
|
|
33
|
+
/** The service answers an unknown name or ASIC number with NOT_FOUND: that is "no match", not a failure. */
|
|
25
34
|
const orNothing = async (call) => {
|
|
26
35
|
try {
|
|
27
36
|
return await call;
|
|
@@ -35,7 +44,7 @@ const orNothing = async (call) => {
|
|
|
35
44
|
};
|
|
36
45
|
export const profile = {
|
|
37
46
|
attribution: ATTRIBUTION,
|
|
38
|
-
label: "Company name or
|
|
47
|
+
label: "Company name, ACN or ARBN",
|
|
39
48
|
listLabel: "Company suggestions",
|
|
40
49
|
noun: "company",
|
|
41
50
|
notFound: "No company found.",
|
|
@@ -45,17 +54,24 @@ export const profile = {
|
|
|
45
54
|
read: (text, context) => {
|
|
46
55
|
const trimmed = text.trim();
|
|
47
56
|
if (NUMBER_TEXT.test(trimmed)) {
|
|
48
|
-
const
|
|
49
|
-
if (
|
|
57
|
+
const asicNumber = trimmed.replace(SEPARATORS, "");
|
|
58
|
+
if (asicNumber.length < NUMBER_DIGITS) {
|
|
50
59
|
return { kind: "incomplete" };
|
|
51
60
|
}
|
|
52
|
-
if (
|
|
53
|
-
return { kind: "invalid", reason: "LENGTH", message: "An ACN has 9 digits." };
|
|
61
|
+
if (asicNumber.length > NUMBER_DIGITS) {
|
|
62
|
+
return { kind: "invalid", reason: "LENGTH", message: "An ACN or ARBN has 9 digits." };
|
|
63
|
+
}
|
|
64
|
+
if (!checkDigitIsValid(asicNumber)) {
|
|
65
|
+
return {
|
|
66
|
+
kind: "invalid",
|
|
67
|
+
reason: "CHECK_DIGIT",
|
|
68
|
+
message: "This is not a valid ACN or ARBN: check the digits.",
|
|
69
|
+
};
|
|
54
70
|
}
|
|
55
71
|
return {
|
|
56
72
|
kind: "lookup",
|
|
57
73
|
run: async (client, options) => {
|
|
58
|
-
const reply = await orNothing(client.lookup({
|
|
74
|
+
const reply = await orNothing(client.lookup({ asicNumber }, options));
|
|
59
75
|
const record = reply?.records[0];
|
|
60
76
|
return {
|
|
61
77
|
found: reply === undefined || record === undefined ? undefined : foundOf(reply, record),
|
|
@@ -81,9 +97,9 @@ export const profile = {
|
|
|
81
97
|
return { suggestions: [], attribution: undefined };
|
|
82
98
|
}
|
|
83
99
|
const suggestions = reply.records.map((record, index) => ({
|
|
84
|
-
key: `${record.
|
|
100
|
+
key: `${record.asicNumber}-${index}`,
|
|
85
101
|
primary: nameOf(record),
|
|
86
|
-
secondary: compact([
|
|
102
|
+
secondary: compact([describeAsicNumber(record), record.status]).join(" · "),
|
|
87
103
|
// The search already returned the whole record: choosing it needs no second call.
|
|
88
104
|
choose: { kind: "found", found: foundOf(reply, record) },
|
|
89
105
|
}));
|
package/dist/runtime/http.js
CHANGED
|
@@ -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
|
|
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.
|
|
3
|
+
"version": "1.0.0",
|
|
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,
|