gdc-common-utils-ts 2.0.2 → 2.0.5

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.
Files changed (40) hide show
  1. package/README.md +45 -0
  2. package/dist/constants/verifiable-credentials.d.ts +6 -0
  3. package/dist/constants/verifiable-credentials.js +6 -0
  4. package/dist/examples/employee.d.ts +15 -0
  5. package/dist/examples/employee.js +15 -0
  6. package/dist/examples/ica-verify-response.d.ts +5 -0
  7. package/dist/examples/ica-verify-response.js +6 -0
  8. package/dist/examples/index.d.ts +2 -0
  9. package/dist/examples/index.js +2 -0
  10. package/dist/examples/individual-controller.d.ts +25 -0
  11. package/dist/examples/individual-controller.js +23 -0
  12. package/dist/examples/legal-organization-verification-transaction.d.ts +1 -0
  13. package/dist/examples/legal-organization-verification-transaction.js +76 -0
  14. package/dist/examples/organization-did-binding.d.ts +1 -0
  15. package/dist/examples/organization-did-binding.js +14 -0
  16. package/dist/examples/shared.d.ts +10 -0
  17. package/dist/examples/shared.js +11 -1
  18. package/dist/utils/bundle-reader.d.ts +2 -0
  19. package/dist/utils/bundle-reader.js +14 -0
  20. package/dist/utils/clinical-bundle-summary.d.ts +20 -0
  21. package/dist/utils/clinical-bundle-summary.js +34 -0
  22. package/dist/utils/didcomm-submit-policy.d.ts +20 -3
  23. package/dist/utils/didcomm-submit-policy.js +37 -6
  24. package/dist/utils/didcomm-submit.d.ts +10 -3
  25. package/dist/utils/didcomm-submit.js +12 -5
  26. package/dist/utils/family-organization-summary.d.ts +24 -0
  27. package/dist/utils/family-organization-summary.js +59 -0
  28. package/dist/utils/index.d.ts +6 -0
  29. package/dist/utils/index.js +6 -0
  30. package/dist/utils/legal-organization-onboarding-editor.d.ts +156 -0
  31. package/dist/utils/legal-organization-onboarding-editor.js +350 -0
  32. package/dist/utils/legal-organization-verification-transaction.d.ts +130 -0
  33. package/dist/utils/legal-organization-verification-transaction.js +118 -0
  34. package/dist/utils/organization-did-binding.d.ts +60 -0
  35. package/dist/utils/organization-did-binding.js +103 -0
  36. package/dist/utils/professional-smart.d.ts +21 -0
  37. package/dist/utils/professional-smart.js +37 -0
  38. package/dist/utils/related-person-list.d.ts +14 -0
  39. package/dist/utils/related-person-list.js +31 -0
  40. package/package.json +1 -1
@@ -0,0 +1,24 @@
1
+ export type FamilyRegistrationStatus = 'new_created' | 'resume_required' | 'already_exists' | 'not_found';
2
+ export type FamilyOrganizationSubjectInfo = Readonly<{
3
+ identifierType?: string;
4
+ identifierValue?: string;
5
+ alternateName?: string;
6
+ birthDate?: string;
7
+ ownerTelephone?: string;
8
+ }>;
9
+ export type FamilyOrganizationSummary = Readonly<{
10
+ status: FamilyRegistrationStatus;
11
+ offerId?: string;
12
+ organizationId?: string;
13
+ subjectInfo?: FamilyOrganizationSubjectInfo;
14
+ missingFields?: string[];
15
+ updatedAt?: string;
16
+ }>;
17
+ /**
18
+ * Reads the first family-organization summary returned by current GW-style
19
+ * search or batch responses.
20
+ *
21
+ * Returns `null` when the response does not contain one usable summary or when
22
+ * the registration status is explicitly `not_found`.
23
+ */
24
+ export declare function readFamilyOrganizationSummaryFromResponseBody(body: unknown): FamilyOrganizationSummary | null;
@@ -0,0 +1,59 @@
1
+ // Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
2
+ function asRecord(value) {
3
+ return value && typeof value === 'object' ? value : {};
4
+ }
5
+ function normalizeText(value) {
6
+ const normalized = String(value ?? '').trim();
7
+ return normalized || undefined;
8
+ }
9
+ function normalizeStringList(value) {
10
+ if (!Array.isArray(value)) {
11
+ return undefined;
12
+ }
13
+ const items = value.map((item) => normalizeText(item)).filter(Boolean);
14
+ return items.length ? items : undefined;
15
+ }
16
+ /**
17
+ * Reads the first family-organization summary returned by current GW-style
18
+ * search or batch responses.
19
+ *
20
+ * Returns `null` when the response does not contain one usable summary or when
21
+ * the registration status is explicitly `not_found`.
22
+ */
23
+ export function readFamilyOrganizationSummaryFromResponseBody(body) {
24
+ const root = asRecord(body);
25
+ const bodyNode = asRecord(root.body);
26
+ const rawEntries = Array.isArray(bodyNode.data)
27
+ ? bodyNode.data
28
+ : (Array.isArray(root.data) ? root.data : []);
29
+ const firstEntry = rawEntries[0];
30
+ if (!firstEntry || typeof firstEntry !== 'object') {
31
+ return null;
32
+ }
33
+ const entry = asRecord(firstEntry);
34
+ const entryMeta = asRecord(entry.meta);
35
+ const entryResource = asRecord(entry.resource);
36
+ const entryResourceMeta = asRecord(entryResource.meta);
37
+ const claims = {
38
+ ...asRecord(entryMeta.claims),
39
+ ...asRecord(entryResourceMeta.claims),
40
+ };
41
+ const status = normalizeText(claims['org.schema.FamilyRegistration.status'] ?? claims.status);
42
+ if (!status || status === 'not_found') {
43
+ return null;
44
+ }
45
+ return {
46
+ status,
47
+ offerId: normalizeText(claims['org.schema.Offer.identifier']),
48
+ organizationId: normalizeText(claims['org.schema.Organization.identifier.value'] ?? entryResource.id),
49
+ subjectInfo: {
50
+ identifierType: normalizeText(claims['org.schema.Organization.identifier.additionalType']),
51
+ identifierValue: normalizeText(claims['org.schema.Organization.identifier.value']),
52
+ alternateName: normalizeText(claims['org.schema.Organization.alternateName']),
53
+ birthDate: normalizeText(claims['org.schema.Organization.foundingDate']),
54
+ ownerTelephone: normalizeText(claims['org.schema.Organization.owner.telephone']),
55
+ },
56
+ missingFields: normalizeStringList(claims['org.schema.FamilyRegistration.missingFields'] ?? claims.missingFields),
57
+ updatedAt: normalizeText(claims['org.schema.FamilyRegistration.updatedAt'] ?? claims.updatedAt),
58
+ };
59
+ }
@@ -28,6 +28,7 @@ export * from './discovery-normalization';
28
28
  export * from './format-converter';
29
29
  export * from './fhir-cid';
30
30
  export * from './fhir-search';
31
+ export * from './family-organization-summary';
31
32
  export * from './gw-core-path';
32
33
  export * from './communication-fhir-r4';
33
34
  export * from './communication-document-reference';
@@ -41,14 +42,18 @@ export * from './communication-attached-bundle-session';
41
42
  export * from './confidential-storage-persistence';
42
43
  export * from './confidential-storage-test-data';
43
44
  export * from './permission-templates';
45
+ export * from './professional-smart';
44
46
  export * from './related-person-list';
45
47
  export * from './clinical-resource-converters';
48
+ export * from './clinical-bundle-summary';
46
49
  export * from './clinical-resource-view';
47
50
  export * from './fhir-validator';
48
51
  export * from './family-registration-test-data';
49
52
  export * from './individual-form-pdf';
50
53
  export * from './individual-organization-claims';
54
+ export * from './legal-organization-onboarding-editor';
51
55
  export * from './organization-lifecycle';
56
+ export * from './organization-did-binding';
52
57
  export * from './individual-organization-lifecycle';
53
58
  export * from './individual-onboarding-editor';
54
59
  export * from './individual-onboarding-document-reference';
@@ -60,6 +65,7 @@ export * from './interoperable-resource-operation';
60
65
  export * from './jwt';
61
66
  export * from './jwk-thumbprint';
62
67
  export * from './legal-organization-onboarding';
68
+ export * from './legal-organization-verification-transaction';
63
69
  export * from './license';
64
70
  export * from './license-commercial-search';
65
71
  export * from './license-list-search';
@@ -28,6 +28,7 @@ export * from './discovery-normalization.js';
28
28
  export * from './format-converter.js';
29
29
  export * from './fhir-cid.js';
30
30
  export * from './fhir-search.js';
31
+ export * from './family-organization-summary.js';
31
32
  export * from './gw-core-path.js';
32
33
  export * from './communication-fhir-r4.js';
33
34
  export * from './communication-document-reference.js';
@@ -41,14 +42,18 @@ export * from './communication-attached-bundle-session.js';
41
42
  export * from './confidential-storage-persistence.js';
42
43
  export * from './confidential-storage-test-data.js';
43
44
  export * from './permission-templates.js';
45
+ export * from './professional-smart.js';
44
46
  export * from './related-person-list.js';
45
47
  export * from './clinical-resource-converters.js';
48
+ export * from './clinical-bundle-summary.js';
46
49
  export * from './clinical-resource-view.js';
47
50
  export * from './fhir-validator.js';
48
51
  export * from './family-registration-test-data.js';
49
52
  export * from './individual-form-pdf.js';
50
53
  export * from './individual-organization-claims.js';
54
+ export * from './legal-organization-onboarding-editor.js';
51
55
  export * from './organization-lifecycle.js';
56
+ export * from './organization-did-binding.js';
52
57
  export * from './individual-organization-lifecycle.js';
53
58
  export * from './individual-onboarding-editor.js';
54
59
  export * from './individual-onboarding-document-reference.js';
@@ -60,6 +65,7 @@ export * from './interoperable-resource-operation.js';
60
65
  export * from './jwt.js';
61
66
  export * from './jwk-thumbprint.js';
62
67
  export * from './legal-organization-onboarding.js';
68
+ export * from './legal-organization-verification-transaction.js';
63
69
  export * from './license.js';
64
70
  export * from './license-commercial-search.js';
65
71
  export * from './license-list-search.js';
@@ -0,0 +1,156 @@
1
+ import type { LegalOrganizationVerificationRouting, LegalOrganizationVerificationTransactionController, LegalOrganizationVerificationTransactionInput, LegalOrganizationVerificationTransactionOrganization, LegalOrganizationVerificationRepresentativePayload } from './legal-organization-verification-transaction';
2
+ import { type ValidateLegalOrganizationOnboardingClaimsOptions } from './legal-organization-onboarding';
3
+ export type LegalOrganizationFormTemplateFields = Readonly<{
4
+ legalName?: string;
5
+ legalIdentifierType?: string;
6
+ legalIdentifierValue?: string;
7
+ taxId?: string;
8
+ addressCountry?: string;
9
+ controllerEmail?: string;
10
+ controllerRole?: string;
11
+ serviceCategory?: string;
12
+ serviceIdentifier?: string;
13
+ serviceUrl?: string;
14
+ tenantAlias?: string;
15
+ }>;
16
+ export type LegalOrganizationOnboardingValidationIssue = Readonly<{
17
+ severity: 'error' | 'warning';
18
+ code: string;
19
+ message: string;
20
+ field?: keyof LegalOrganizationFormTemplateFields | 'claims' | string;
21
+ }>;
22
+ export type LegalOrganizationOnboardingValidationResult = Readonly<{
23
+ ok: boolean;
24
+ errors: LegalOrganizationOnboardingValidationIssue[];
25
+ warnings: LegalOrganizationOnboardingValidationIssue[];
26
+ normalizedClaims: Record<string, unknown>;
27
+ }>;
28
+ export type LegalOrganizationOnboardingDraftResult = Readonly<{
29
+ formFields: LegalOrganizationFormTemplateFields;
30
+ claims: Record<string, unknown>;
31
+ validation: LegalOrganizationOnboardingValidationResult;
32
+ }>;
33
+ export type LegalOrganizationGatewayVerificationSignatureFlow = 'certificate' | 'otp';
34
+ export type LegalOrganizationGatewayVerificationRequestInput = Readonly<{
35
+ controller: LegalOrganizationVerificationTransactionController;
36
+ signatureFlow?: LegalOrganizationGatewayVerificationSignatureFlow;
37
+ representativeSameAs?: string;
38
+ verificationResourceType?: string;
39
+ signedTermsAttachmentId?: string;
40
+ signedTermsPdfUrl?: string;
41
+ validationOptions?: ValidateLegalOrganizationOnboardingClaimsOptions;
42
+ }>;
43
+ export type LegalOrganizationGatewayActivationRequestInput = Readonly<{
44
+ vpToken: string;
45
+ controller?: LegalOrganizationVerificationTransactionController;
46
+ serviceCapabilities?: ReadonlyArray<string>;
47
+ additionalClaims?: Record<string, unknown>;
48
+ validationOptions?: ValidateLegalOrganizationOnboardingClaimsOptions;
49
+ }>;
50
+ export type LegalOrganizationGatewayActivationRequest = Readonly<{
51
+ vpToken: string;
52
+ controller?: LegalOrganizationVerificationTransactionController;
53
+ service?: Readonly<{
54
+ url?: string;
55
+ capabilities?: ReadonlyArray<string>;
56
+ }>;
57
+ additionalClaims?: Record<string, unknown>;
58
+ }>;
59
+ export interface LegalOrganizationOnboardingFacade {
60
+ /** Creates a shallow copy of the legal-organization form draft. */
61
+ createDraft(initial?: LegalOrganizationFormTemplateFields): LegalOrganizationFormTemplateFields;
62
+ setLegalName(fields: LegalOrganizationFormTemplateFields, value: string): LegalOrganizationFormTemplateFields;
63
+ getLegalName(fields: LegalOrganizationFormTemplateFields): string | undefined;
64
+ setLegalIdentifierType(fields: LegalOrganizationFormTemplateFields, value: string): LegalOrganizationFormTemplateFields;
65
+ getLegalIdentifierType(fields: LegalOrganizationFormTemplateFields): string | undefined;
66
+ setLegalIdentifierValue(fields: LegalOrganizationFormTemplateFields, value: string): LegalOrganizationFormTemplateFields;
67
+ getLegalIdentifierValue(fields: LegalOrganizationFormTemplateFields): string | undefined;
68
+ setTaxId(fields: LegalOrganizationFormTemplateFields, value: string): LegalOrganizationFormTemplateFields;
69
+ getTaxId(fields: LegalOrganizationFormTemplateFields): string | undefined;
70
+ setAddressCountry(fields: LegalOrganizationFormTemplateFields, value: string): LegalOrganizationFormTemplateFields;
71
+ getAddressCountry(fields: LegalOrganizationFormTemplateFields): string | undefined;
72
+ setControllerEmail(fields: LegalOrganizationFormTemplateFields, value: string): LegalOrganizationFormTemplateFields;
73
+ getControllerEmail(fields: LegalOrganizationFormTemplateFields): string | undefined;
74
+ setControllerRole(fields: LegalOrganizationFormTemplateFields, value: string): LegalOrganizationFormTemplateFields;
75
+ getControllerRole(fields: LegalOrganizationFormTemplateFields): string | undefined;
76
+ setServiceCategory(fields: LegalOrganizationFormTemplateFields, value: string): LegalOrganizationFormTemplateFields;
77
+ getServiceCategory(fields: LegalOrganizationFormTemplateFields): string | undefined;
78
+ setServiceIdentifier(fields: LegalOrganizationFormTemplateFields, value: string): LegalOrganizationFormTemplateFields;
79
+ getServiceIdentifier(fields: LegalOrganizationFormTemplateFields): string | undefined;
80
+ setServiceUrl(fields: LegalOrganizationFormTemplateFields, value: string): LegalOrganizationFormTemplateFields;
81
+ getServiceUrl(fields: LegalOrganizationFormTemplateFields): string | undefined;
82
+ /**
83
+ * Optional explicit tenant alias.
84
+ *
85
+ * By default validation will only accept a value equal to the canonical
86
+ * legal identifier unless `allowExplicitAlternateNameForTenantId=true`.
87
+ */
88
+ setTenantAlias(fields: LegalOrganizationFormTemplateFields, value: string): LegalOrganizationFormTemplateFields;
89
+ getTenantAlias(fields: LegalOrganizationFormTemplateFields): string | undefined;
90
+ buildClaims(fields: LegalOrganizationFormTemplateFields, options?: ValidateLegalOrganizationOnboardingClaimsOptions): Record<string, unknown>;
91
+ buildDraft(fields: LegalOrganizationFormTemplateFields, options?: ValidateLegalOrganizationOnboardingClaimsOptions): LegalOrganizationOnboardingDraftResult;
92
+ validate(fields: LegalOrganizationFormTemplateFields, options?: ValidateLegalOrganizationOnboardingClaimsOptions): LegalOrganizationOnboardingValidationResult;
93
+ buildVerificationTransactionInput(fields: LegalOrganizationFormTemplateFields, input: Readonly<{
94
+ controller: LegalOrganizationVerificationTransactionController;
95
+ organization?: LegalOrganizationVerificationTransactionOrganization;
96
+ legalRepresentativePayload?: LegalOrganizationVerificationRepresentativePayload;
97
+ verification?: LegalOrganizationVerificationRouting;
98
+ attachments?: unknown[];
99
+ validationOptions?: ValidateLegalOrganizationOnboardingClaimsOptions;
100
+ }>): LegalOrganizationVerificationTransactionInput;
101
+ buildGatewayVerificationRequest(fields: LegalOrganizationFormTemplateFields, input: LegalOrganizationGatewayVerificationRequestInput): LegalOrganizationVerificationTransactionInput;
102
+ buildGatewayActivationRequest(fields: LegalOrganizationFormTemplateFields, input: LegalOrganizationGatewayActivationRequestInput): LegalOrganizationGatewayActivationRequest;
103
+ /** Creates the chainable editor shown in the onboarding 101. */
104
+ createEditor(initial?: LegalOrganizationFormTemplateFields): LegalOrganizationOnboardingEditor;
105
+ }
106
+ export interface LegalOrganizationOnboardingEditor {
107
+ setLegalName(value: string): LegalOrganizationOnboardingEditor;
108
+ getLegalName(): string | undefined;
109
+ setLegalIdentifierType(value: string): LegalOrganizationOnboardingEditor;
110
+ getLegalIdentifierType(): string | undefined;
111
+ setLegalIdentifierValue(value: string): LegalOrganizationOnboardingEditor;
112
+ getLegalIdentifierValue(): string | undefined;
113
+ setTaxId(value: string): LegalOrganizationOnboardingEditor;
114
+ getTaxId(): string | undefined;
115
+ setAddressCountry(value: string): LegalOrganizationOnboardingEditor;
116
+ getAddressCountry(): string | undefined;
117
+ setControllerEmail(value: string): LegalOrganizationOnboardingEditor;
118
+ getControllerEmail(): string | undefined;
119
+ setControllerRole(value: string): LegalOrganizationOnboardingEditor;
120
+ getControllerRole(): string | undefined;
121
+ setServiceCategory(value: string): LegalOrganizationOnboardingEditor;
122
+ getServiceCategory(): string | undefined;
123
+ setServiceIdentifier(value: string): LegalOrganizationOnboardingEditor;
124
+ getServiceIdentifier(): string | undefined;
125
+ setServiceUrl(value: string): LegalOrganizationOnboardingEditor;
126
+ getServiceUrl(): string | undefined;
127
+ setTenantAlias(value: string): LegalOrganizationOnboardingEditor;
128
+ getTenantAlias(): string | undefined;
129
+ getFormFields(): LegalOrganizationFormTemplateFields;
130
+ buildClaims(options?: ValidateLegalOrganizationOnboardingClaimsOptions): Record<string, unknown>;
131
+ validate(options?: ValidateLegalOrganizationOnboardingClaimsOptions): LegalOrganizationOnboardingValidationResult;
132
+ buildDraft(options?: ValidateLegalOrganizationOnboardingClaimsOptions): LegalOrganizationOnboardingDraftResult;
133
+ buildVerificationTransactionInput(input: Readonly<{
134
+ controller: LegalOrganizationVerificationTransactionController;
135
+ organization?: LegalOrganizationVerificationTransactionOrganization;
136
+ legalRepresentativePayload?: LegalOrganizationVerificationRepresentativePayload;
137
+ verification?: LegalOrganizationVerificationRouting;
138
+ attachments?: unknown[];
139
+ validationOptions?: ValidateLegalOrganizationOnboardingClaimsOptions;
140
+ }>): LegalOrganizationVerificationTransactionInput;
141
+ buildGatewayVerificationRequest(input: LegalOrganizationGatewayVerificationRequestInput): LegalOrganizationVerificationTransactionInput;
142
+ buildGatewayActivationRequest(input: LegalOrganizationGatewayActivationRequestInput): LegalOrganizationGatewayActivationRequest;
143
+ }
144
+ /**
145
+ * Stateless helper API for building and validating the current
146
+ * legal-organization onboarding draft.
147
+ *
148
+ * Use this surface when callers prefer immutable functions over the chainable
149
+ * editor wrapper.
150
+ */
151
+ export declare function createLegalOrganizationOnboardingFacade(): LegalOrganizationOnboardingFacade;
152
+ /**
153
+ * Creates the chainable editor used in legal-organization onboarding 101
154
+ * flows.
155
+ */
156
+ export declare function createLegalOrganizationOnboardingEditor(initial?: LegalOrganizationFormTemplateFields): LegalOrganizationOnboardingEditor;
@@ -0,0 +1,350 @@
1
+ import { ClaimsOrganizationSchemaorg, ClaimsPersonSchemaorg, ClaimsServiceSchemaorg, } from '../constants/schemaorg.js';
2
+ import { validateLegalOrganizationOnboardingClaims, } from './legal-organization-onboarding.js';
3
+ function normalizeText(value) {
4
+ return typeof value === 'string' ? value.trim() : '';
5
+ }
6
+ function normalizeOptionalText(value) {
7
+ const normalized = normalizeText(value);
8
+ return normalized || undefined;
9
+ }
10
+ function cloneFields(fields) {
11
+ return { ...(fields || {}) };
12
+ }
13
+ function patchFields(fields, patch) {
14
+ return {
15
+ ...cloneFields(fields),
16
+ ...patch,
17
+ };
18
+ }
19
+ function toValidationResult(normalizedClaims, issues) {
20
+ return {
21
+ ok: !issues.some((issue) => issue.severity === 'error'),
22
+ errors: issues.filter((issue) => issue.severity === 'error'),
23
+ warnings: issues.filter((issue) => issue.severity === 'warning'),
24
+ normalizedClaims,
25
+ };
26
+ }
27
+ function normalizeCapabilityList(values) {
28
+ return [...(values || [])]
29
+ .map((item) => normalizeText(item))
30
+ .filter(Boolean);
31
+ }
32
+ function createEditorFromFacade(facade, initial) {
33
+ let formFields = facade.createDraft(initial);
34
+ const editor = {
35
+ setLegalName(value) { formFields = facade.setLegalName(formFields, value); return editor; },
36
+ getLegalName() { return facade.getLegalName(formFields); },
37
+ setLegalIdentifierType(value) { formFields = facade.setLegalIdentifierType(formFields, value); return editor; },
38
+ getLegalIdentifierType() { return facade.getLegalIdentifierType(formFields); },
39
+ setLegalIdentifierValue(value) { formFields = facade.setLegalIdentifierValue(formFields, value); return editor; },
40
+ getLegalIdentifierValue() { return facade.getLegalIdentifierValue(formFields); },
41
+ setTaxId(value) { formFields = facade.setTaxId(formFields, value); return editor; },
42
+ getTaxId() { return facade.getTaxId(formFields); },
43
+ setAddressCountry(value) { formFields = facade.setAddressCountry(formFields, value); return editor; },
44
+ getAddressCountry() { return facade.getAddressCountry(formFields); },
45
+ setControllerEmail(value) { formFields = facade.setControllerEmail(formFields, value); return editor; },
46
+ getControllerEmail() { return facade.getControllerEmail(formFields); },
47
+ setControllerRole(value) { formFields = facade.setControllerRole(formFields, value); return editor; },
48
+ getControllerRole() { return facade.getControllerRole(formFields); },
49
+ setServiceCategory(value) { formFields = facade.setServiceCategory(formFields, value); return editor; },
50
+ getServiceCategory() { return facade.getServiceCategory(formFields); },
51
+ setServiceIdentifier(value) { formFields = facade.setServiceIdentifier(formFields, value); return editor; },
52
+ getServiceIdentifier() { return facade.getServiceIdentifier(formFields); },
53
+ setServiceUrl(value) { formFields = facade.setServiceUrl(formFields, value); return editor; },
54
+ getServiceUrl() { return facade.getServiceUrl(formFields); },
55
+ setTenantAlias(value) { formFields = facade.setTenantAlias(formFields, value); return editor; },
56
+ getTenantAlias() { return facade.getTenantAlias(formFields); },
57
+ getFormFields() { return cloneFields(formFields); },
58
+ buildClaims(options = {}) { return facade.buildClaims(formFields, options); },
59
+ validate(options = {}) { return facade.validate(formFields, options); },
60
+ buildDraft(options = {}) { return facade.buildDraft(formFields, options); },
61
+ buildVerificationTransactionInput(input) { return facade.buildVerificationTransactionInput(formFields, input); },
62
+ buildGatewayVerificationRequest(input) { return facade.buildGatewayVerificationRequest(formFields, input); },
63
+ buildGatewayActivationRequest(input) { return facade.buildGatewayActivationRequest(formFields, input); },
64
+ };
65
+ return editor;
66
+ }
67
+ /**
68
+ * Stateless helper API for building and validating the current
69
+ * legal-organization onboarding draft.
70
+ *
71
+ * Use this surface when callers prefer immutable functions over the chainable
72
+ * editor wrapper.
73
+ */
74
+ export function createLegalOrganizationOnboardingFacade() {
75
+ const facade = {
76
+ createDraft(initial = {}) {
77
+ return cloneFields(initial);
78
+ },
79
+ setLegalName(fields, value) {
80
+ return patchFields(fields, { legalName: normalizeText(value) });
81
+ },
82
+ getLegalName(fields) {
83
+ return normalizeOptionalText(fields.legalName);
84
+ },
85
+ setLegalIdentifierType(fields, value) {
86
+ return patchFields(fields, { legalIdentifierType: normalizeText(value) });
87
+ },
88
+ getLegalIdentifierType(fields) {
89
+ return normalizeOptionalText(fields.legalIdentifierType);
90
+ },
91
+ setLegalIdentifierValue(fields, value) {
92
+ return patchFields(fields, { legalIdentifierValue: normalizeText(value) });
93
+ },
94
+ getLegalIdentifierValue(fields) {
95
+ return normalizeOptionalText(fields.legalIdentifierValue);
96
+ },
97
+ setTaxId(fields, value) {
98
+ return patchFields(fields, { taxId: normalizeText(value) });
99
+ },
100
+ getTaxId(fields) {
101
+ return normalizeOptionalText(fields.taxId);
102
+ },
103
+ setAddressCountry(fields, value) {
104
+ return patchFields(fields, { addressCountry: normalizeText(value).toUpperCase() });
105
+ },
106
+ getAddressCountry(fields) {
107
+ const value = normalizeOptionalText(fields.addressCountry);
108
+ return value ? value.toUpperCase() : undefined;
109
+ },
110
+ setControllerEmail(fields, value) {
111
+ return patchFields(fields, { controllerEmail: normalizeText(value).toLowerCase() });
112
+ },
113
+ getControllerEmail(fields) {
114
+ const value = normalizeOptionalText(fields.controllerEmail);
115
+ return value ? value.toLowerCase() : undefined;
116
+ },
117
+ setControllerRole(fields, value) {
118
+ return patchFields(fields, { controllerRole: normalizeText(value) });
119
+ },
120
+ getControllerRole(fields) {
121
+ return normalizeOptionalText(fields.controllerRole);
122
+ },
123
+ setServiceCategory(fields, value) {
124
+ return patchFields(fields, { serviceCategory: normalizeText(value) });
125
+ },
126
+ getServiceCategory(fields) {
127
+ return normalizeOptionalText(fields.serviceCategory);
128
+ },
129
+ setServiceIdentifier(fields, value) {
130
+ return patchFields(fields, { serviceIdentifier: normalizeText(value) });
131
+ },
132
+ getServiceIdentifier(fields) {
133
+ return normalizeOptionalText(fields.serviceIdentifier);
134
+ },
135
+ setServiceUrl(fields, value) {
136
+ return patchFields(fields, { serviceUrl: normalizeText(value) });
137
+ },
138
+ getServiceUrl(fields) {
139
+ return normalizeOptionalText(fields.serviceUrl);
140
+ },
141
+ setTenantAlias(fields, value) {
142
+ return patchFields(fields, { tenantAlias: normalizeText(value) });
143
+ },
144
+ getTenantAlias(fields) {
145
+ return normalizeOptionalText(fields.tenantAlias);
146
+ },
147
+ buildClaims(fields, options = {}) {
148
+ const claims = {
149
+ '@context': 'org.schema',
150
+ };
151
+ if (normalizeOptionalText(fields.legalName)) {
152
+ claims[ClaimsOrganizationSchemaorg.legalName] = normalizeText(fields.legalName);
153
+ }
154
+ if (normalizeOptionalText(fields.legalIdentifierType)) {
155
+ claims[ClaimsOrganizationSchemaorg.identifierType] = normalizeText(fields.legalIdentifierType);
156
+ }
157
+ if (normalizeOptionalText(fields.legalIdentifierValue)) {
158
+ claims[ClaimsOrganizationSchemaorg.identifierValue] = normalizeText(fields.legalIdentifierValue);
159
+ }
160
+ if (normalizeOptionalText(fields.taxId)) {
161
+ claims[ClaimsOrganizationSchemaorg.taxId] = normalizeText(fields.taxId);
162
+ }
163
+ if (normalizeOptionalText(fields.addressCountry)) {
164
+ claims[ClaimsOrganizationSchemaorg.addressCountry] = normalizeText(fields.addressCountry).toUpperCase();
165
+ }
166
+ if (normalizeOptionalText(fields.controllerEmail)) {
167
+ claims[ClaimsPersonSchemaorg.email] = normalizeText(fields.controllerEmail).toLowerCase();
168
+ }
169
+ if (normalizeOptionalText(fields.controllerRole)) {
170
+ claims[ClaimsPersonSchemaorg.hasOccupationalRoleValue] = normalizeText(fields.controllerRole);
171
+ }
172
+ if (normalizeOptionalText(fields.serviceCategory)) {
173
+ claims[ClaimsServiceSchemaorg.category] = normalizeText(fields.serviceCategory);
174
+ }
175
+ if (normalizeOptionalText(fields.serviceIdentifier)) {
176
+ claims[ClaimsServiceSchemaorg.identifier] = normalizeText(fields.serviceIdentifier);
177
+ }
178
+ if (normalizeOptionalText(fields.serviceUrl)) {
179
+ claims[ClaimsServiceSchemaorg.url] = normalizeText(fields.serviceUrl);
180
+ }
181
+ if (normalizeOptionalText(fields.tenantAlias)) {
182
+ claims[ClaimsOrganizationSchemaorg.alternateName] = normalizeText(fields.tenantAlias);
183
+ }
184
+ return validateLegalOrganizationOnboardingClaims(claims, options).normalizedClaims;
185
+ },
186
+ buildDraft(fields, options = {}) {
187
+ const validation = facade.validate(fields, options);
188
+ return {
189
+ formFields: cloneFields(fields),
190
+ claims: validation.normalizedClaims,
191
+ validation,
192
+ };
193
+ },
194
+ validate(fields, options = {}) {
195
+ const issues = [];
196
+ const normalizedClaims = facade.buildClaims(fields, options);
197
+ const sharedValidation = validateLegalOrganizationOnboardingClaims(normalizedClaims, options);
198
+ if (!normalizeOptionalText(fields.legalName)) {
199
+ issues.push({
200
+ severity: 'error',
201
+ code: 'missing-legal-name',
202
+ message: 'legalName is required for legal-organization onboarding.',
203
+ field: 'legalName',
204
+ });
205
+ }
206
+ if (!normalizeOptionalText(fields.legalIdentifierType)) {
207
+ issues.push({
208
+ severity: 'error',
209
+ code: 'missing-legal-identifier-type',
210
+ message: 'legalIdentifierType is required for legal-organization onboarding.',
211
+ field: 'legalIdentifierType',
212
+ });
213
+ }
214
+ if (!normalizeOptionalText(fields.addressCountry)) {
215
+ issues.push({
216
+ severity: 'error',
217
+ code: 'missing-address-country',
218
+ message: 'addressCountry is required for legal-organization onboarding.',
219
+ field: 'addressCountry',
220
+ });
221
+ }
222
+ if (!normalizeOptionalText(fields.controllerEmail)) {
223
+ issues.push({
224
+ severity: 'error',
225
+ code: 'missing-controller-email',
226
+ message: 'controllerEmail is required for legal-organization onboarding.',
227
+ field: 'controllerEmail',
228
+ });
229
+ }
230
+ if (!normalizeOptionalText(fields.serviceCategory)) {
231
+ issues.push({
232
+ severity: 'error',
233
+ code: 'missing-service-category',
234
+ message: 'serviceCategory is required for legal-organization onboarding.',
235
+ field: 'serviceCategory',
236
+ });
237
+ }
238
+ if (!normalizeOptionalText(fields.controllerRole)) {
239
+ issues.push({
240
+ severity: 'warning',
241
+ code: 'missing-controller-role',
242
+ message: 'controllerRole is recommended so the onboarding example stays aligned with representative-role flows.',
243
+ field: 'controllerRole',
244
+ });
245
+ }
246
+ if (!normalizeOptionalText(fields.serviceUrl)) {
247
+ issues.push({
248
+ severity: 'warning',
249
+ code: 'missing-service-url',
250
+ message: 'serviceUrl is recommended when the same draft later feeds tenant activation/publication examples.',
251
+ field: 'serviceUrl',
252
+ });
253
+ }
254
+ for (const error of sharedValidation.errors) {
255
+ issues.push({
256
+ severity: 'error',
257
+ code: error.code.toLowerCase(),
258
+ message: error.message,
259
+ field: error.claimPaths[0] || 'claims',
260
+ });
261
+ }
262
+ return toValidationResult(sharedValidation.normalizedClaims, issues);
263
+ },
264
+ buildVerificationTransactionInput(fields, input) {
265
+ return {
266
+ claims: facade.buildClaims(fields, input.validationOptions),
267
+ controller: input.controller,
268
+ ...(input.organization ? { organization: input.organization } : {}),
269
+ ...(input.legalRepresentativePayload
270
+ ? { legalRepresentativePayload: input.legalRepresentativePayload }
271
+ : {}),
272
+ ...(input.verification ? { verification: input.verification } : {}),
273
+ ...(Array.isArray(input.attachments) ? { attachments: input.attachments } : {}),
274
+ };
275
+ },
276
+ buildGatewayVerificationRequest(fields, input) {
277
+ const controllerEmail = facade.getControllerEmail(fields);
278
+ const serviceIdentifier = facade.getServiceIdentifier(fields);
279
+ const serviceUrl = facade.getServiceUrl(fields);
280
+ const signatureFlow = normalizeText(input.signatureFlow || 'certificate').toLowerCase();
281
+ const representativeSameAs = normalizeOptionalText(input.representativeSameAs || controllerEmail);
282
+ const signedTermsPdfUrl = normalizeOptionalText(input.signedTermsPdfUrl);
283
+ return facade.buildVerificationTransactionInput(fields, {
284
+ controller: input.controller,
285
+ organization: serviceIdentifier || serviceUrl
286
+ ? {
287
+ ...(serviceIdentifier ? { did: serviceIdentifier } : {}),
288
+ ...(serviceUrl ? { url: serviceUrl } : {}),
289
+ }
290
+ : undefined,
291
+ legalRepresentativePayload: signatureFlow === 'otp'
292
+ ? {
293
+ ...(controllerEmail ? { email: controllerEmail } : {}),
294
+ ...(representativeSameAs ? { sameAs: representativeSameAs } : {}),
295
+ }
296
+ : controllerEmail
297
+ ? { email: controllerEmail }
298
+ : undefined,
299
+ verification: {
300
+ resourceType: normalizeOptionalText(input.verificationResourceType) || 'contract',
301
+ },
302
+ attachments: signatureFlow === 'otp' || !signedTermsPdfUrl
303
+ ? undefined
304
+ : [{
305
+ id: normalizeOptionalText(input.signedTermsAttachmentId) || 'signed-terms-pdf-001',
306
+ media_type: 'application/pdf',
307
+ data: {
308
+ links: [signedTermsPdfUrl],
309
+ },
310
+ }],
311
+ validationOptions: input.validationOptions,
312
+ });
313
+ },
314
+ buildGatewayActivationRequest(fields, input) {
315
+ const serviceUrl = facade.getServiceUrl(fields);
316
+ const capabilities = normalizeCapabilityList(input.serviceCapabilities);
317
+ const draft = facade.buildDraft(fields, input.validationOptions);
318
+ const additionalClaims = {
319
+ ...draft.claims,
320
+ ...(input.additionalClaims || {}),
321
+ };
322
+ return {
323
+ vpToken: normalizeText(input.vpToken),
324
+ ...(input.controller ? { controller: input.controller } : {}),
325
+ ...((serviceUrl || capabilities.length > 0)
326
+ ? {
327
+ service: {
328
+ ...(serviceUrl ? { url: serviceUrl } : {}),
329
+ ...(capabilities.length > 0 ? { capabilities } : {}),
330
+ },
331
+ }
332
+ : {}),
333
+ ...(Object.keys(additionalClaims).length > 0 ? { additionalClaims } : {}),
334
+ };
335
+ },
336
+ };
337
+ return {
338
+ ...facade,
339
+ createEditor(initial = {}) {
340
+ return createEditorFromFacade(facade, initial);
341
+ },
342
+ };
343
+ }
344
+ /**
345
+ * Creates the chainable editor used in legal-organization onboarding 101
346
+ * flows.
347
+ */
348
+ export function createLegalOrganizationOnboardingEditor(initial = {}) {
349
+ return createLegalOrganizationOnboardingFacade().createEditor(initial);
350
+ }