gdc-sdk-node-ts 2.9.16 → 2.9.17
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.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type FamilyOrganizationSummary } from 'gdc-common-utils-ts/utils/family-organization-summary';
|
|
1
|
+
import { type FamilyOrganizationSummary, type FamilyRegistrationStatus } from 'gdc-common-utils-ts/utils/family-organization-summary';
|
|
2
2
|
import type { PollOptions, SubmitAndPollResult } from './orchestration/client-port.js';
|
|
3
3
|
import type { RouteContext } from './individual-onboarding.js';
|
|
4
4
|
export type FamilyOrganizationSearchInput = Readonly<{
|
|
@@ -19,7 +19,11 @@ export type OwnedFamilyOrganizationDirectoryInput = Readonly<{
|
|
|
19
19
|
}>;
|
|
20
20
|
export type OwnedFamilyOrganizationDirectoryEntry = Readonly<{
|
|
21
21
|
resourceId: string;
|
|
22
|
-
|
|
22
|
+
/** Missing only for an owner-private registration draft. */
|
|
23
|
+
alternateName?: string;
|
|
24
|
+
status?: FamilyRegistrationStatus;
|
|
25
|
+
birthDate?: string;
|
|
26
|
+
missingFields?: string[];
|
|
23
27
|
claims: Readonly<Record<string, unknown>>;
|
|
24
28
|
}>;
|
|
25
29
|
type SearchFamilyOrganizationWithDeps = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
2
|
import { readFamilyOrganizationSummaryFromResponseBody, } from 'gdc-common-utils-ts/utils/family-organization-summary';
|
|
3
|
-
import { ClaimsOrganizationSchemaorg, ClaimsServiceSchemaorg } from 'gdc-common-utils-ts/constants';
|
|
3
|
+
import { ClaimsOrganizationSchemaorg, ClaimsPersonSchemaorg, ClaimsServiceSchemaorg } from 'gdc-common-utils-ts/constants';
|
|
4
4
|
import { resolvePollOptionsFromSeconds } from './poll-options.js';
|
|
5
5
|
/**
|
|
6
6
|
* Searches one existing family/individual organization registration by the
|
|
@@ -100,11 +100,35 @@ export async function listOwnedFamilyOrganizationsWithDeps(routeCtx, input, deps
|
|
|
100
100
|
if (!((email && ownerEmail === email) || (telephone && ownerTelephone === telephone)))
|
|
101
101
|
return [];
|
|
102
102
|
const alternateName = String(resourceClaims[ClaimsOrganizationSchemaorg.alternateName] || '').trim();
|
|
103
|
-
|
|
103
|
+
const rawStatus = String(resourceClaims['org.schema.FamilyRegistration.status'] || '').trim();
|
|
104
|
+
const status = isFamilyRegistrationStatus(rawStatus) ? rawStatus : undefined;
|
|
105
|
+
if (!alternateName && status !== 'draft_saved' && status !== 'resume_required')
|
|
104
106
|
return [];
|
|
105
|
-
|
|
107
|
+
const birthDate = String(resourceClaims[ClaimsPersonSchemaorg.birthDate]
|
|
108
|
+
|| resourceClaims['org.schema.Organization.foundingDate']
|
|
109
|
+
|| '').trim();
|
|
110
|
+
const missingFields = Array.isArray(resourceClaims['org.schema.FamilyRegistration.missingFields'])
|
|
111
|
+
? resourceClaims['org.schema.FamilyRegistration.missingFields']
|
|
112
|
+
.map((value) => String(value || '').trim())
|
|
113
|
+
.filter(Boolean)
|
|
114
|
+
: [];
|
|
115
|
+
return [{
|
|
116
|
+
resourceId: String(resource.id),
|
|
117
|
+
...(alternateName ? { alternateName } : {}),
|
|
118
|
+
...(status ? { status } : {}),
|
|
119
|
+
...(birthDate ? { birthDate } : {}),
|
|
120
|
+
...(missingFields.length ? { missingFields } : {}),
|
|
121
|
+
claims: resourceClaims,
|
|
122
|
+
}];
|
|
106
123
|
});
|
|
107
124
|
}
|
|
125
|
+
function isFamilyRegistrationStatus(value) {
|
|
126
|
+
return value === 'new_created'
|
|
127
|
+
|| value === 'draft_saved'
|
|
128
|
+
|| value === 'resume_required'
|
|
129
|
+
|| value === 'already_exists'
|
|
130
|
+
|| value === 'not_found';
|
|
131
|
+
}
|
|
108
132
|
function createRuntimeUuid() {
|
|
109
133
|
const fromCrypto = globalThis.crypto?.randomUUID?.();
|
|
110
134
|
if (fromCrypto) {
|
|
@@ -6,6 +6,14 @@ import type { PollOptions, SubmitAndPollResult } from './orchestration/client-po
|
|
|
6
6
|
import type { RouteContext } from './individual-onboarding.js';
|
|
7
7
|
import type { OfferPreview } from './order-offer-summary.js';
|
|
8
8
|
export type IndividualOrganizationRegistrationInput = {
|
|
9
|
+
/**
|
|
10
|
+
* Explicitly saves an owner-private, cardless registration draft.
|
|
11
|
+
*
|
|
12
|
+
* This is intended for accessible channels that captured a birth year/date
|
|
13
|
+
* but could not reliably capture the subject's name. It never authorizes an
|
|
14
|
+
* Order or public card by itself.
|
|
15
|
+
*/
|
|
16
|
+
registrationIntent?: 'activate' | 'save-private-draft';
|
|
9
17
|
/**
|
|
10
18
|
* Preferred high-level input produced by `createIndividualOnboardingEditor()`.
|
|
11
19
|
*
|
|
@@ -77,8 +85,17 @@ export type IndividualOrganizationRegistrationInput = {
|
|
|
77
85
|
export type IndividualOrganizationBootstrapInput = IndividualOrganizationRegistrationInput;
|
|
78
86
|
export type IndividualOrganizationRegistrationResult = {
|
|
79
87
|
registration: SubmitAndPollResult;
|
|
80
|
-
|
|
81
|
-
|
|
88
|
+
/**
|
|
89
|
+
* Owner-private Organization UUID returned by GW for a saved draft.
|
|
90
|
+
*
|
|
91
|
+
* It is not a public card identifier or DID and is present only when
|
|
92
|
+
* `registrationIntent` was `save-private-draft`.
|
|
93
|
+
*/
|
|
94
|
+
draftId?: string;
|
|
95
|
+
/** Absent only for an explicitly requested owner-private draft. */
|
|
96
|
+
offerId?: string;
|
|
97
|
+
/** Absent only for an explicitly requested owner-private draft. */
|
|
98
|
+
offerPreview?: OfferPreview;
|
|
82
99
|
/** Lifecycle state returned by GW for this registration receipt. */
|
|
83
100
|
registrationStatus?: FamilyRegistrationStatus;
|
|
84
101
|
/** False when the same family registration is already active. */
|
package/dist/individual-start.js
CHANGED
|
@@ -26,7 +26,8 @@ export async function registerIndividualOrganizationWithDeps(deps) {
|
|
|
26
26
|
* routing/indexing contract for this flow.
|
|
27
27
|
*/
|
|
28
28
|
const onboardingDraft = deps.input.onboardingDraft;
|
|
29
|
-
|
|
29
|
+
const savesPrivateDraft = deps.input.registrationIntent === 'save-private-draft';
|
|
30
|
+
if (onboardingDraft && !hasSignedPdfEvidence(onboardingDraft) && !savesPrivateDraft) {
|
|
30
31
|
const subjectAlternateName = String(onboardingDraft.formFields.subjectAlternateName
|
|
31
32
|
|| onboardingDraft.claims?.[ClaimsOrganizationSchemaorg.alternateName]
|
|
32
33
|
|| '').trim();
|
|
@@ -35,9 +36,16 @@ export async function registerIndividualOrganizationWithDeps(deps) {
|
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
const alternateName = String(deps.input.alternateName || '').trim();
|
|
38
|
-
if (!onboardingDraft && !alternateName) {
|
|
39
|
+
if (!onboardingDraft && !alternateName && !savesPrivateDraft) {
|
|
39
40
|
throw new Error('registerIndividualOrganization requires alternateName.');
|
|
40
41
|
}
|
|
42
|
+
const draftClaims = {
|
|
43
|
+
...(onboardingDraft?.claims || {}),
|
|
44
|
+
...(deps.input.additionalClaims || {}),
|
|
45
|
+
};
|
|
46
|
+
if (!alternateName && savesPrivateDraft && !hasValidHumanBirthDate(draftClaims)) {
|
|
47
|
+
throw new Error('registerIndividualOrganization private draft requires a valid birth year or date.');
|
|
48
|
+
}
|
|
41
49
|
const controllerEmail = String(deps.input.controllerEmail
|
|
42
50
|
|| onboardingDraft?.formFields.controllerEmail
|
|
43
51
|
|| onboardingDraft?.claims?.[ClaimsOrganizationSchemaorg.ownerEmail]
|
|
@@ -99,6 +107,23 @@ export async function registerIndividualOrganizationWithDeps(deps) {
|
|
|
99
107
|
});
|
|
100
108
|
const registration = await deps.submitAndPoll(deps.individualFamilyOrganizationBatchPath(deps.routeCtx), deps.individualFamilyOrganizationPollPath(deps.routeCtx), registrationPayload, pollOptions);
|
|
101
109
|
deps.assertFirstDidcommEntrySuccess?.(registration, 'registerIndividualOrganization.registration');
|
|
110
|
+
const registrationSummary = readFamilyOrganizationSummaryFromResponseBody(registration.poll.body);
|
|
111
|
+
const registrationStatus = registrationSummary?.status;
|
|
112
|
+
if (savesPrivateDraft) {
|
|
113
|
+
if (registrationStatus !== 'draft_saved') {
|
|
114
|
+
throw new Error('registerIndividualOrganization failed: GW did not preserve the requested private draft.');
|
|
115
|
+
}
|
|
116
|
+
const draftId = String(registrationSummary?.organizationId || '').trim();
|
|
117
|
+
if (!draftId) {
|
|
118
|
+
throw new Error('registerIndividualOrganization failed: GW did not return the private draft id.');
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
registration,
|
|
122
|
+
registrationStatus,
|
|
123
|
+
draftId,
|
|
124
|
+
orderConfirmationRequired: false,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
102
127
|
/**
|
|
103
128
|
* Commercial contract for this SDK path:
|
|
104
129
|
* - this helper targets the family/individual commercial bootstrap flow
|
|
@@ -112,12 +137,11 @@ export async function registerIndividualOrganizationWithDeps(deps) {
|
|
|
112
137
|
if (!offerId) {
|
|
113
138
|
throw new Error('registerIndividualOrganization failed: missing offerId in registration response.');
|
|
114
139
|
}
|
|
115
|
-
const registrationSummary = readFamilyOrganizationSummaryFromResponseBody(registration.poll.body);
|
|
116
140
|
return {
|
|
117
141
|
registration,
|
|
118
142
|
offerId,
|
|
119
143
|
offerPreview: deps.getOfferPreviewFromResponse(registration),
|
|
120
|
-
registrationStatus
|
|
144
|
+
registrationStatus,
|
|
121
145
|
orderConfirmationRequired: registrationSummary?.status !== 'already_exists',
|
|
122
146
|
identity: readIndividualOrganizationBootstrapIdentity(registration.poll.body, {
|
|
123
147
|
controllerEmail,
|
|
@@ -125,6 +149,10 @@ export async function registerIndividualOrganizationWithDeps(deps) {
|
|
|
125
149
|
}),
|
|
126
150
|
};
|
|
127
151
|
}
|
|
152
|
+
function hasValidHumanBirthDate(claims) {
|
|
153
|
+
const birthDate = String(claims?.[ClaimsPersonSchemaorg.birthDate] || '').trim();
|
|
154
|
+
return /^(?:19|20)\d{2}(?:-(?:0[1-9]|1[0-2])(?:-(?:0[1-9]|[12]\d|3[01]))?)?$/.test(birthDate);
|
|
155
|
+
}
|
|
128
156
|
function canonicalControllerUuid(value) {
|
|
129
157
|
const hexadecimal = normalizeUuid(String(value || '').trim());
|
|
130
158
|
if (!hexadecimal) {
|
|
@@ -389,7 +389,10 @@ export declare class HttpRuntimeClient implements NodeRuntimeClient {
|
|
|
389
389
|
/** Lists all individual Organizations owned by one verified account contact. */
|
|
390
390
|
listOwnedFamilyOrganizations(ctx: RouteContext, input: OwnedFamilyOrganizationDirectoryInput): Promise<Readonly<{
|
|
391
391
|
resourceId: string;
|
|
392
|
-
alternateName
|
|
392
|
+
alternateName?: string;
|
|
393
|
+
status?: import("gdc-common-utils-ts").FamilyRegistrationStatus;
|
|
394
|
+
birthDate?: string;
|
|
395
|
+
missingFields?: string[];
|
|
393
396
|
claims: Readonly<Record<string, unknown>>;
|
|
394
397
|
}>[]>;
|
|
395
398
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gdc-sdk-node-ts",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.17",
|
|
4
4
|
"description": "Next-generation Node runtime package for the GDC SDK family",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Antifraud Services Inc.",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"test:e2e:live-gw:clean": "bash ./scripts/run-live-gw-clean.sh"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"gdc-common-utils-ts": "2.9.
|
|
41
|
+
"gdc-common-utils-ts": "2.9.16",
|
|
42
42
|
"gdc-sdk-core-ts": "2.9.10"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|