gdc-common-utils-ts 2.0.4 → 2.0.6

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 (32) hide show
  1. package/dist/constants/verifiable-credentials.d.ts +6 -0
  2. package/dist/constants/verifiable-credentials.js +6 -0
  3. package/dist/examples/employee.d.ts +15 -0
  4. package/dist/examples/employee.js +15 -0
  5. package/dist/examples/individual-controller.d.ts +25 -0
  6. package/dist/examples/individual-controller.js +23 -0
  7. package/dist/examples/legal-organization-verification-transaction.js +10 -0
  8. package/dist/examples/shared.d.ts +7 -0
  9. package/dist/examples/shared.js +8 -1
  10. package/dist/utils/activation-request.d.ts +3 -3
  11. package/dist/utils/activation-request.js +3 -3
  12. package/dist/utils/bundle-reader.d.ts +2 -0
  13. package/dist/utils/bundle-reader.js +14 -0
  14. package/dist/utils/clinical-bundle-summary.d.ts +20 -0
  15. package/dist/utils/clinical-bundle-summary.js +34 -0
  16. package/dist/utils/didcomm-submit-policy.d.ts +20 -3
  17. package/dist/utils/didcomm-submit-policy.js +37 -6
  18. package/dist/utils/didcomm-submit.d.ts +10 -3
  19. package/dist/utils/didcomm-submit.js +12 -5
  20. package/dist/utils/family-organization-summary.d.ts +24 -0
  21. package/dist/utils/family-organization-summary.js +59 -0
  22. package/dist/utils/index.d.ts +4 -0
  23. package/dist/utils/index.js +4 -0
  24. package/dist/utils/legal-organization-onboarding-editor.d.ts +156 -0
  25. package/dist/utils/legal-organization-onboarding-editor.js +350 -0
  26. package/dist/utils/legal-organization-verification-transaction.d.ts +40 -0
  27. package/dist/utils/legal-organization-verification-transaction.js +53 -0
  28. package/dist/utils/professional-smart.d.ts +21 -0
  29. package/dist/utils/professional-smart.js +37 -0
  30. package/dist/utils/related-person-list.d.ts +14 -0
  31. package/dist/utils/related-person-list.js +31 -0
  32. package/package.json +1 -1
@@ -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
+ }
@@ -75,6 +75,22 @@ export type LegalOrganizationVerificationTransactionInput = Readonly<{
75
75
  verification?: LegalOrganizationVerificationRouting;
76
76
  attachments?: unknown[];
77
77
  }>;
78
+ export type LegalOrganizationVerificationTransactionEntry = Readonly<{
79
+ type?: string;
80
+ meta?: {
81
+ claims?: ClaimsRecord;
82
+ [key: string]: unknown;
83
+ };
84
+ resource?: {
85
+ controller?: LegalOrganizationVerificationTransactionController;
86
+ organization?: LegalOrganizationVerificationTransactionOrganization;
87
+ legalRepresentativePayload?: LegalOrganizationVerificationRepresentativePayload;
88
+ legalRepresentative?: LegalOrganizationVerificationRepresentativePayload;
89
+ verification?: LegalOrganizationVerificationRouting;
90
+ [key: string]: unknown;
91
+ };
92
+ [key: string]: unknown;
93
+ }>;
78
94
  /**
79
95
  * Builds the canonical Bundle payload for host-side legal organization
80
96
  * verification transactions.
@@ -88,3 +104,27 @@ export type LegalOrganizationVerificationTransactionInput = Readonly<{
88
104
  * to target the appropriate ICA verification route
89
105
  */
90
106
  export declare function buildLegalOrganizationVerificationTransactionBundle(input: LegalOrganizationVerificationTransactionInput): BundleJsonApi;
107
+ /**
108
+ * Returns the first bundle entry when the payload matches the canonical
109
+ * legal-organization verification transaction shape.
110
+ *
111
+ * This helper accepts either:
112
+ * - the raw bundle itself
113
+ * - or a DIDComm/API wrapper object whose `body` contains that bundle
114
+ */
115
+ export declare function getFirstLegalOrganizationVerificationTransactionEntry(value: unknown): LegalOrganizationVerificationTransactionEntry | undefined;
116
+ /**
117
+ * Returns the normalized controller binding payload from the first legal
118
+ * organization verification transaction entry when present.
119
+ */
120
+ export declare function getLegalOrganizationVerificationController(value: unknown): LegalOrganizationVerificationTransactionController | undefined;
121
+ /**
122
+ * Returns the normalized legal representative contact payload from the first
123
+ * legal-organization verification transaction entry when present.
124
+ *
125
+ * Compatibility note:
126
+ * - GW/SDK request builders use `resource.legalRepresentativePayload`
127
+ * - the ICA forwarding payload currently uses `resource.legalRepresentative`
128
+ * - this helper intentionally accepts both shapes
129
+ */
130
+ export declare function getLegalOrganizationVerificationRepresentativePayload(value: unknown): LegalOrganizationVerificationRepresentativePayload | undefined;
@@ -21,6 +21,11 @@ export const LegalOrganizationVerificationTransactionEntryTypes = Object.freeze(
21
21
  function normalizeText(value) {
22
22
  return typeof value === 'string' ? value.trim() : '';
23
23
  }
24
+ function asRecord(value) {
25
+ return value && typeof value === 'object' && !Array.isArray(value)
26
+ ? value
27
+ : undefined;
28
+ }
24
29
  /**
25
30
  * Builds the canonical Bundle payload for host-side legal organization
26
31
  * verification transactions.
@@ -63,3 +68,51 @@ export function buildLegalOrganizationVerificationTransactionBundle(input) {
63
68
  : {}),
64
69
  };
65
70
  }
71
+ /**
72
+ * Returns the first bundle entry when the payload matches the canonical
73
+ * legal-organization verification transaction shape.
74
+ *
75
+ * This helper accepts either:
76
+ * - the raw bundle itself
77
+ * - or a DIDComm/API wrapper object whose `body` contains that bundle
78
+ */
79
+ export function getFirstLegalOrganizationVerificationTransactionEntry(value) {
80
+ const root = asRecord(value);
81
+ const bundle = asRecord(root?.body) || root;
82
+ const data = Array.isArray(bundle?.data) ? bundle.data : [];
83
+ const first = data[0];
84
+ return asRecord(first);
85
+ }
86
+ /**
87
+ * Returns the normalized controller binding payload from the first legal
88
+ * organization verification transaction entry when present.
89
+ */
90
+ export function getLegalOrganizationVerificationController(value) {
91
+ const entry = getFirstLegalOrganizationVerificationTransactionEntry(value);
92
+ const controller = asRecord(entry?.resource?.controller);
93
+ return controller
94
+ ? controller
95
+ : undefined;
96
+ }
97
+ /**
98
+ * Returns the normalized legal representative contact payload from the first
99
+ * legal-organization verification transaction entry when present.
100
+ *
101
+ * Compatibility note:
102
+ * - GW/SDK request builders use `resource.legalRepresentativePayload`
103
+ * - the ICA forwarding payload currently uses `resource.legalRepresentative`
104
+ * - this helper intentionally accepts both shapes
105
+ */
106
+ export function getLegalOrganizationVerificationRepresentativePayload(value) {
107
+ const entry = getFirstLegalOrganizationVerificationTransactionEntry(value);
108
+ const candidate = asRecord(entry?.resource?.legalRepresentativePayload)
109
+ || asRecord(entry?.resource?.legalRepresentative);
110
+ if (!candidate)
111
+ return undefined;
112
+ const email = normalizeText(candidate.email);
113
+ const sameAs = normalizeText(candidate.sameAs);
114
+ return {
115
+ ...(email ? { email } : {}),
116
+ ...(sameAs ? { sameAs } : {}),
117
+ };
118
+ }
@@ -0,0 +1,21 @@
1
+ export type ProfessionalEmployeeCredentialInput = Readonly<{
2
+ actorDid: string;
3
+ role: string;
4
+ additionalCredentialSubject?: Record<string, unknown>;
5
+ additionalCredential?: Record<string, unknown>;
6
+ }>;
7
+ export type ProfessionalSmartVpPayloadInput = Readonly<{
8
+ clientId: string;
9
+ actorDid: string;
10
+ role: string;
11
+ verifiableCredential?: string | Record<string, unknown> | ReadonlyArray<string | Record<string, unknown>>;
12
+ additionalVp?: Record<string, unknown>;
13
+ additionalPayload?: Record<string, unknown>;
14
+ }>;
15
+ export declare function buildProfessionalEmployeeCredential(input: ProfessionalEmployeeCredentialInput): Record<string, unknown>;
16
+ export declare function buildProfessionalSmartVpPayload(input: ProfessionalSmartVpPayloadInput): Record<string, unknown>;
17
+ export declare function buildUnsignedProfessionalSmartVpJwt(input: ProfessionalSmartVpPayloadInput, options?: Readonly<{
18
+ nowSeconds?: number;
19
+ ttlSeconds?: number;
20
+ nonce?: string;
21
+ }>): string;