@enterprisestandard/react 0.0.5-beta.20260115.1 → 0.0.5-beta.20260115.3

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.
@@ -0,0 +1,519 @@
1
+ /**
2
+ * Validates a string field
3
+ */
4
+ function validateString(value, fieldName, required, issues, path) {
5
+ if (value === undefined || value === null) {
6
+ if (required) {
7
+ issues.push({
8
+ message: `${fieldName} is required`,
9
+ path,
10
+ });
11
+ }
12
+ return undefined;
13
+ }
14
+ if (typeof value !== 'string') {
15
+ issues.push({
16
+ message: `${fieldName} must be a string`,
17
+ path,
18
+ });
19
+ return undefined;
20
+ }
21
+ return value;
22
+ }
23
+ /**
24
+ * Validates a boolean field
25
+ */
26
+ function validateBoolean(value, fieldName, issues, path) {
27
+ if (value === undefined || value === null) {
28
+ return undefined;
29
+ }
30
+ if (typeof value !== 'boolean') {
31
+ issues.push({
32
+ message: `${fieldName} must be a boolean`,
33
+ path,
34
+ });
35
+ return undefined;
36
+ }
37
+ return value;
38
+ }
39
+ /**
40
+ * Validates a SCIM Name object
41
+ */
42
+ function validateName(value, issues, basePath) {
43
+ if (value === undefined || value === null) {
44
+ return undefined;
45
+ }
46
+ if (typeof value !== 'object' || value === null) {
47
+ issues.push({
48
+ message: 'name must be an object',
49
+ path: basePath,
50
+ });
51
+ return undefined;
52
+ }
53
+ const name = value;
54
+ const result = {};
55
+ result.formatted = validateString(name.formatted, 'formatted', false, issues, [...basePath, 'formatted']);
56
+ result.familyName = validateString(name.familyName, 'familyName', false, issues, [...basePath, 'familyName']);
57
+ result.givenName = validateString(name.givenName, 'givenName', false, issues, [...basePath, 'givenName']);
58
+ result.middleName = validateString(name.middleName, 'middleName', false, issues, [...basePath, 'middleName']);
59
+ result.honorificPrefix = validateString(name.honorificPrefix, 'honorificPrefix', false, issues, [
60
+ ...basePath,
61
+ 'honorificPrefix',
62
+ ]);
63
+ result.honorificSuffix = validateString(name.honorificSuffix, 'honorificSuffix', false, issues, [
64
+ ...basePath,
65
+ 'honorificSuffix',
66
+ ]);
67
+ return result;
68
+ }
69
+ /**
70
+ * Validates a SCIM Email array
71
+ */
72
+ function validateEmails(value, issues, basePath) {
73
+ if (value === undefined || value === null) {
74
+ return undefined;
75
+ }
76
+ if (!Array.isArray(value)) {
77
+ issues.push({
78
+ message: 'emails must be an array',
79
+ path: basePath,
80
+ });
81
+ return undefined;
82
+ }
83
+ const emails = [];
84
+ for (let i = 0; i < value.length; i++) {
85
+ const email = value[i];
86
+ const emailPath = [...basePath, i];
87
+ if (typeof email !== 'object' || email === null) {
88
+ issues.push({
89
+ message: 'email must be an object',
90
+ path: emailPath,
91
+ });
92
+ continue;
93
+ }
94
+ const emailObj = email;
95
+ const emailValue = validateString(emailObj.value, 'value', true, issues, [...emailPath, 'value']);
96
+ if (emailValue) {
97
+ emails.push({
98
+ value: emailValue,
99
+ display: validateString(emailObj.display, 'display', false, issues, [...emailPath, 'display']),
100
+ type: validateString(emailObj.type, 'type', false, issues, [...emailPath, 'type']),
101
+ primary: validateBoolean(emailObj.primary, 'primary', issues, [...emailPath, 'primary']),
102
+ });
103
+ }
104
+ }
105
+ return emails.length > 0 ? emails : undefined;
106
+ }
107
+ /**
108
+ * Validates a SCIM PhoneNumber array
109
+ */
110
+ function validatePhoneNumbers(value, issues, basePath) {
111
+ if (value === undefined || value === null) {
112
+ return undefined;
113
+ }
114
+ if (!Array.isArray(value)) {
115
+ issues.push({
116
+ message: 'phoneNumbers must be an array',
117
+ path: basePath,
118
+ });
119
+ return undefined;
120
+ }
121
+ const phoneNumbers = [];
122
+ for (let i = 0; i < value.length; i++) {
123
+ const phone = value[i];
124
+ const phonePath = [...basePath, i];
125
+ if (typeof phone !== 'object' || phone === null) {
126
+ issues.push({
127
+ message: 'phoneNumber must be an object',
128
+ path: phonePath,
129
+ });
130
+ continue;
131
+ }
132
+ const phoneObj = phone;
133
+ const phoneValue = validateString(phoneObj.value, 'value', true, issues, [...phonePath, 'value']);
134
+ if (phoneValue) {
135
+ phoneNumbers.push({
136
+ value: phoneValue,
137
+ display: validateString(phoneObj.display, 'display', false, issues, [...phonePath, 'display']),
138
+ type: validateString(phoneObj.type, 'type', false, issues, [...phonePath, 'type']),
139
+ primary: validateBoolean(phoneObj.primary, 'primary', issues, [...phonePath, 'primary']),
140
+ });
141
+ }
142
+ }
143
+ return phoneNumbers.length > 0 ? phoneNumbers : undefined;
144
+ }
145
+ /**
146
+ * Validates a SCIM Address array
147
+ */
148
+ function validateAddresses(value, issues, basePath) {
149
+ if (value === undefined || value === null) {
150
+ return undefined;
151
+ }
152
+ if (!Array.isArray(value)) {
153
+ issues.push({
154
+ message: 'addresses must be an array',
155
+ path: basePath,
156
+ });
157
+ return undefined;
158
+ }
159
+ const addresses = [];
160
+ for (let i = 0; i < value.length; i++) {
161
+ const address = value[i];
162
+ const addressPath = [...basePath, i];
163
+ if (typeof address !== 'object' || address === null) {
164
+ issues.push({
165
+ message: 'address must be an object',
166
+ path: addressPath,
167
+ });
168
+ continue;
169
+ }
170
+ const addressObj = address;
171
+ addresses.push({
172
+ formatted: validateString(addressObj.formatted, 'formatted', false, issues, [...addressPath, 'formatted']),
173
+ streetAddress: validateString(addressObj.streetAddress, 'streetAddress', false, issues, [
174
+ ...addressPath,
175
+ 'streetAddress',
176
+ ]),
177
+ locality: validateString(addressObj.locality, 'locality', false, issues, [...addressPath, 'locality']),
178
+ region: validateString(addressObj.region, 'region', false, issues, [...addressPath, 'region']),
179
+ postalCode: validateString(addressObj.postalCode, 'postalCode', false, issues, [...addressPath, 'postalCode']),
180
+ country: validateString(addressObj.country, 'country', false, issues, [...addressPath, 'country']),
181
+ type: validateString(addressObj.type, 'type', false, issues, [...addressPath, 'type']),
182
+ primary: validateBoolean(addressObj.primary, 'primary', issues, [...addressPath, 'primary']),
183
+ });
184
+ }
185
+ return addresses.length > 0 ? addresses : undefined;
186
+ }
187
+ /**
188
+ * Validates a SCIM Group array
189
+ */
190
+ function validateGroups(value, issues, basePath) {
191
+ if (value === undefined || value === null) {
192
+ return undefined;
193
+ }
194
+ if (!Array.isArray(value)) {
195
+ issues.push({
196
+ message: 'groups must be an array',
197
+ path: basePath,
198
+ });
199
+ return undefined;
200
+ }
201
+ const groups = [];
202
+ for (let i = 0; i < value.length; i++) {
203
+ const group = value[i];
204
+ const groupPath = [...basePath, i];
205
+ if (typeof group !== 'object' || group === null) {
206
+ issues.push({
207
+ message: 'group must be an object',
208
+ path: groupPath,
209
+ });
210
+ continue;
211
+ }
212
+ const groupObj = group;
213
+ const groupValue = validateString(groupObj.value, 'value', true, issues, [...groupPath, 'value']);
214
+ if (groupValue) {
215
+ groups.push({
216
+ value: groupValue,
217
+ $ref: validateString(groupObj.$ref, '$ref', false, issues, [...groupPath, '$ref']),
218
+ display: validateString(groupObj.display, 'display', false, issues, [...groupPath, 'display']),
219
+ type: validateString(groupObj.type, 'type', false, issues, [...groupPath, 'type']),
220
+ });
221
+ }
222
+ }
223
+ return groups.length > 0 ? groups : undefined;
224
+ }
225
+ /**
226
+ * Validates a SCIM Role array
227
+ */
228
+ function validateRoles(value, issues, basePath) {
229
+ if (value === undefined || value === null) {
230
+ return undefined;
231
+ }
232
+ if (!Array.isArray(value)) {
233
+ issues.push({
234
+ message: 'roles must be an array',
235
+ path: basePath,
236
+ });
237
+ return undefined;
238
+ }
239
+ const roles = [];
240
+ for (let i = 0; i < value.length; i++) {
241
+ const role = value[i];
242
+ const rolePath = [...basePath, i];
243
+ if (typeof role !== 'object' || role === null) {
244
+ issues.push({
245
+ message: 'role must be an object',
246
+ path: rolePath,
247
+ });
248
+ continue;
249
+ }
250
+ const roleObj = role;
251
+ const roleValue = validateString(roleObj.value, 'value', true, issues, [...rolePath, 'value']);
252
+ if (roleValue) {
253
+ roles.push({
254
+ value: roleValue,
255
+ display: validateString(roleObj.display, 'display', false, issues, [...rolePath, 'display']),
256
+ type: validateString(roleObj.type, 'type', false, issues, [...rolePath, 'type']),
257
+ primary: validateBoolean(roleObj.primary, 'primary', issues, [...rolePath, 'primary']),
258
+ });
259
+ }
260
+ }
261
+ return roles.length > 0 ? roles : undefined;
262
+ }
263
+ /**
264
+ * Validates a SCIM Enterprise User extension
265
+ */
266
+ function validateEnterpriseUser(value, issues, basePath) {
267
+ if (value === undefined || value === null) {
268
+ return undefined;
269
+ }
270
+ if (typeof value !== 'object' || value === null) {
271
+ issues.push({
272
+ message: 'Enterprise User extension must be an object',
273
+ path: basePath,
274
+ });
275
+ return undefined;
276
+ }
277
+ const enterprise = value;
278
+ const result = {};
279
+ result.employeeNumber = validateString(enterprise.employeeNumber, 'employeeNumber', false, issues, [
280
+ ...basePath,
281
+ 'employeeNumber',
282
+ ]);
283
+ result.costCenter = validateString(enterprise.costCenter, 'costCenter', false, issues, [...basePath, 'costCenter']);
284
+ result.organization = validateString(enterprise.organization, 'organization', false, issues, [
285
+ ...basePath,
286
+ 'organization',
287
+ ]);
288
+ result.division = validateString(enterprise.division, 'division', false, issues, [...basePath, 'division']);
289
+ result.department = validateString(enterprise.department, 'department', false, issues, [...basePath, 'department']);
290
+ if (enterprise.manager !== undefined && enterprise.manager !== null) {
291
+ if (typeof enterprise.manager !== 'object' || enterprise.manager === null) {
292
+ issues.push({
293
+ message: 'manager must be an object',
294
+ path: [...basePath, 'manager'],
295
+ });
296
+ }
297
+ else {
298
+ const manager = enterprise.manager;
299
+ result.manager = {
300
+ value: validateString(manager.value, 'value', false, issues, [...basePath, 'manager', 'value']),
301
+ $ref: validateString(manager.$ref, '$ref', false, issues, [...basePath, 'manager', '$ref']),
302
+ displayName: validateString(manager.displayName, 'displayName', false, issues, [
303
+ ...basePath,
304
+ 'manager',
305
+ 'displayName',
306
+ ]),
307
+ };
308
+ }
309
+ }
310
+ return result;
311
+ }
312
+ /**
313
+ * Creates a StandardSchemaV1 for validating SCIM User resources.
314
+ * @param vendor - The name of the vendor creating this schema
315
+ * @returns A StandardSchemaV1 instance for SCIM User resources
316
+ */
317
+ export function userSchema(vendor) {
318
+ return {
319
+ '~standard': {
320
+ version: 1,
321
+ vendor,
322
+ validate: (value) => {
323
+ if (typeof value !== 'object' || value === null) {
324
+ return {
325
+ issues: [
326
+ {
327
+ message: 'Expected an object',
328
+ },
329
+ ],
330
+ };
331
+ }
332
+ const user = value;
333
+ const issues = [];
334
+ const result = {};
335
+ // userName is REQUIRED
336
+ const userName = validateString(user.userName, 'userName', true, issues, ['userName']);
337
+ if (!userName) {
338
+ return { issues };
339
+ }
340
+ result.userName = userName;
341
+ // Optional string fields
342
+ result.id = validateString(user.id, 'id', false, issues, ['id']);
343
+ result.externalId = validateString(user.externalId, 'externalId', false, issues, ['externalId']);
344
+ result.displayName = validateString(user.displayName, 'displayName', false, issues, ['displayName']);
345
+ result.nickName = validateString(user.nickName, 'nickName', false, issues, ['nickName']);
346
+ result.profileUrl = validateString(user.profileUrl, 'profileUrl', false, issues, ['profileUrl']);
347
+ result.title = validateString(user.title, 'title', false, issues, ['title']);
348
+ result.userType = validateString(user.userType, 'userType', false, issues, ['userType']);
349
+ result.preferredLanguage = validateString(user.preferredLanguage, 'preferredLanguage', false, issues, [
350
+ 'preferredLanguage',
351
+ ]);
352
+ result.locale = validateString(user.locale, 'locale', false, issues, ['locale']);
353
+ result.timezone = validateString(user.timezone, 'timezone', false, issues, ['timezone']);
354
+ result.password = validateString(user.password, 'password', false, issues, ['password']);
355
+ // Boolean field
356
+ result.active = validateBoolean(user.active, 'active', issues, ['active']);
357
+ // Complex sub-attributes
358
+ result.name = validateName(user.name, issues, ['name']);
359
+ result.emails = validateEmails(user.emails, issues, ['emails']);
360
+ result.phoneNumbers = validatePhoneNumbers(user.phoneNumbers, issues, ['phoneNumbers']);
361
+ result.addresses = validateAddresses(user.addresses, issues, ['addresses']);
362
+ result.groups = validateGroups(user.groups, issues, ['groups']);
363
+ result.roles = validateRoles(user.roles, issues, ['roles']);
364
+ // Enterprise User Extension
365
+ const enterpriseKey = 'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User';
366
+ if (user[enterpriseKey] !== undefined) {
367
+ result[enterpriseKey] = validateEnterpriseUser(user[enterpriseKey], issues, [enterpriseKey]);
368
+ }
369
+ // Schemas array
370
+ if (user.schemas !== undefined) {
371
+ if (Array.isArray(user.schemas)) {
372
+ result.schemas = user.schemas.filter((s) => typeof s === 'string');
373
+ }
374
+ else {
375
+ issues.push({
376
+ message: 'schemas must be an array',
377
+ path: ['schemas'],
378
+ });
379
+ }
380
+ }
381
+ // Meta object (basic validation)
382
+ if (user.meta !== undefined) {
383
+ if (typeof user.meta === 'object' && user.meta !== null) {
384
+ const meta = user.meta;
385
+ result.meta = {
386
+ resourceType: typeof meta.resourceType === 'string' ? meta.resourceType : undefined,
387
+ created: typeof meta.created === 'string' ? meta.created : undefined,
388
+ lastModified: typeof meta.lastModified === 'string' ? meta.lastModified : undefined,
389
+ location: typeof meta.location === 'string' ? meta.location : undefined,
390
+ version: typeof meta.version === 'string' ? meta.version : undefined,
391
+ };
392
+ }
393
+ else {
394
+ issues.push({
395
+ message: 'meta must be an object',
396
+ path: ['meta'],
397
+ });
398
+ }
399
+ }
400
+ if (issues.length > 0) {
401
+ return { issues };
402
+ }
403
+ return { value: result };
404
+ },
405
+ },
406
+ };
407
+ }
408
+ /**
409
+ * Validates a SCIM GroupMember array
410
+ */
411
+ function validateMembers(value, issues, basePath) {
412
+ if (value === undefined || value === null) {
413
+ return undefined;
414
+ }
415
+ if (!Array.isArray(value)) {
416
+ issues.push({
417
+ message: 'members must be an array',
418
+ path: basePath,
419
+ });
420
+ return undefined;
421
+ }
422
+ const members = [];
423
+ for (let i = 0; i < value.length; i++) {
424
+ const member = value[i];
425
+ const memberPath = [...basePath, i];
426
+ if (typeof member !== 'object' || member === null) {
427
+ issues.push({
428
+ message: 'member must be an object',
429
+ path: memberPath,
430
+ });
431
+ continue;
432
+ }
433
+ const memberObj = member;
434
+ const memberValue = validateString(memberObj.value, 'value', true, issues, [...memberPath, 'value']);
435
+ if (memberValue) {
436
+ const memberType = validateString(memberObj.type, 'type', false, issues, [...memberPath, 'type']);
437
+ members.push({
438
+ value: memberValue,
439
+ $ref: validateString(memberObj.$ref, '$ref', false, issues, [...memberPath, '$ref']),
440
+ display: validateString(memberObj.display, 'display', false, issues, [...memberPath, 'display']),
441
+ type: memberType === 'User' || memberType === 'Group' ? memberType : undefined,
442
+ });
443
+ }
444
+ }
445
+ return members.length > 0 ? members : undefined;
446
+ }
447
+ /**
448
+ * Creates a StandardSchemaV1 for validating SCIM Group resources.
449
+ * @param vendor - The name of the vendor creating this schema
450
+ * @returns A StandardSchemaV1 instance for SCIM Group resources
451
+ */
452
+ export function groupResourceSchema(vendor) {
453
+ return {
454
+ '~standard': {
455
+ version: 1,
456
+ vendor,
457
+ validate: (value) => {
458
+ if (typeof value !== 'object' || value === null) {
459
+ return {
460
+ issues: [
461
+ {
462
+ message: 'Expected an object',
463
+ },
464
+ ],
465
+ };
466
+ }
467
+ const group = value;
468
+ const issues = [];
469
+ const result = {};
470
+ // displayName is REQUIRED
471
+ const displayName = validateString(group.displayName, 'displayName', true, issues, ['displayName']);
472
+ if (!displayName) {
473
+ return { issues };
474
+ }
475
+ result.displayName = displayName;
476
+ // Optional string fields
477
+ result.id = validateString(group.id, 'id', false, issues, ['id']);
478
+ result.externalId = validateString(group.externalId, 'externalId', false, issues, ['externalId']);
479
+ // Members array
480
+ result.members = validateMembers(group.members, issues, ['members']);
481
+ // Schemas array
482
+ if (group.schemas !== undefined) {
483
+ if (Array.isArray(group.schemas)) {
484
+ result.schemas = group.schemas.filter((s) => typeof s === 'string');
485
+ }
486
+ else {
487
+ issues.push({
488
+ message: 'schemas must be an array',
489
+ path: ['schemas'],
490
+ });
491
+ }
492
+ }
493
+ // Meta object (basic validation)
494
+ if (group.meta !== undefined) {
495
+ if (typeof group.meta === 'object' && group.meta !== null) {
496
+ const meta = group.meta;
497
+ result.meta = {
498
+ resourceType: typeof meta.resourceType === 'string' ? meta.resourceType : undefined,
499
+ created: typeof meta.created === 'string' ? meta.created : undefined,
500
+ lastModified: typeof meta.lastModified === 'string' ? meta.lastModified : undefined,
501
+ location: typeof meta.location === 'string' ? meta.location : undefined,
502
+ version: typeof meta.version === 'string' ? meta.version : undefined,
503
+ };
504
+ }
505
+ else {
506
+ issues.push({
507
+ message: 'meta must be an object',
508
+ path: ['meta'],
509
+ });
510
+ }
511
+ }
512
+ if (issues.length > 0) {
513
+ return { issues };
514
+ }
515
+ return { value: result };
516
+ },
517
+ },
518
+ };
519
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};