@plasius/schema 1.2.5 → 1.2.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.
- package/README.md +42 -0
- package/dist/index.cjs +123 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.js +123 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -10,6 +10,7 @@ interface PII {
|
|
|
10
10
|
|
|
11
11
|
type FieldType$1 = "string" | "number" | "boolean" | "object" | "array" | "ref";
|
|
12
12
|
|
|
13
|
+
type FieldExposure = "public" | "internal";
|
|
13
14
|
declare class FieldBuilder<TExternal = unknown, TInternal = TExternal> {
|
|
14
15
|
type: FieldType$1;
|
|
15
16
|
_type: TExternal;
|
|
@@ -35,6 +36,7 @@ declare class FieldBuilder<TExternal = unknown, TInternal = TExternal> {
|
|
|
35
36
|
itemType?: FieldBuilder<any>;
|
|
36
37
|
refType?: string;
|
|
37
38
|
_pii: PII;
|
|
39
|
+
_exposure: FieldExposure;
|
|
38
40
|
enumValues?: readonly TInternal[];
|
|
39
41
|
constructor(type: FieldType$1, options?: {
|
|
40
42
|
shape?: Record<string, FieldBuilder<any>>;
|
|
@@ -43,6 +45,9 @@ declare class FieldBuilder<TExternal = unknown, TInternal = TExternal> {
|
|
|
43
45
|
});
|
|
44
46
|
immutable(): FieldBuilder<TExternal, TInternal>;
|
|
45
47
|
system(): FieldBuilder<TExternal, TInternal>;
|
|
48
|
+
exposure(exposure: FieldExposure): FieldBuilder<TExternal, TInternal>;
|
|
49
|
+
internal(): FieldBuilder<TExternal, TInternal>;
|
|
50
|
+
public(): FieldBuilder<TExternal, TInternal>;
|
|
46
51
|
required(): FieldBuilder<TExternal, TInternal>;
|
|
47
52
|
optional(): FieldBuilder<TExternal, TInternal>;
|
|
48
53
|
validator(fn: (value: TInternal) => boolean): FieldBuilder<TExternal, TInternal>;
|
|
@@ -136,6 +141,9 @@ interface SchemaOptions {
|
|
|
136
141
|
piiEnforcement?: PIIEnforcement;
|
|
137
142
|
schemaUpgrade?: SchemaUpgradeStep[] | SchemaUpgradeFunction | undefined;
|
|
138
143
|
}
|
|
144
|
+
interface SerializeOptions {
|
|
145
|
+
includeInternal?: boolean;
|
|
146
|
+
}
|
|
139
147
|
type SchemaShape = Record<string, FieldBuilder<any>>;
|
|
140
148
|
interface FieldDefinition<T = unknown> {
|
|
141
149
|
type: FieldType;
|
|
@@ -153,6 +161,7 @@ interface FieldDefinition<T = unknown> {
|
|
|
153
161
|
enum?: string[];
|
|
154
162
|
_shape?: SchemaShape;
|
|
155
163
|
pii?: PII;
|
|
164
|
+
exposure?: FieldExposure;
|
|
156
165
|
validator?: (value: any) => boolean;
|
|
157
166
|
}
|
|
158
167
|
interface ValidateCompositionOptions {
|
|
@@ -182,6 +191,7 @@ interface Schema<T extends SchemaShape> {
|
|
|
182
191
|
};
|
|
183
192
|
validate: (input: unknown, existing?: Record<string, any>) => ValidationResult<Infer<T>>;
|
|
184
193
|
validateComposition: (entity: Infer<T>, options: ValidateCompositionOptions) => Promise<void>;
|
|
194
|
+
serialize: (input: Record<string, any>, options?: SerializeOptions) => Record<string, any>;
|
|
185
195
|
tableName?: () => string | undefined;
|
|
186
196
|
prepareForRead(stored: Record<string, any>, decryptFn: (value: string) => any | null): Record<string, any>;
|
|
187
197
|
prepareForStorage(input: Record<string, any>, encryptFn: (value: any) => string, hashFn: (value: any) => string): Record<string, any>;
|
|
@@ -209,6 +219,7 @@ interface Schema<T extends SchemaShape> {
|
|
|
209
219
|
enum: string[] | null;
|
|
210
220
|
refType: string | null;
|
|
211
221
|
pii: PII | null;
|
|
222
|
+
exposure: FieldExposure;
|
|
212
223
|
}>;
|
|
213
224
|
};
|
|
214
225
|
}
|
|
@@ -302,6 +313,7 @@ declare function renderSchemaDescription(schema: Schema<any>): {
|
|
|
302
313
|
description: string;
|
|
303
314
|
deprecated: boolean;
|
|
304
315
|
pii?: string;
|
|
316
|
+
exposure: "public" | "internal";
|
|
305
317
|
}>;
|
|
306
318
|
};
|
|
307
319
|
|
|
@@ -624,4 +636,4 @@ declare function isPrivateUseSubtag(value: string): boolean;
|
|
|
624
636
|
*/
|
|
625
637
|
declare function validateLanguage(value: unknown): boolean;
|
|
626
638
|
|
|
627
|
-
export { type DeepReadonly, FieldBuilder, type FieldDefinition, type FieldType, type FieldTypeMap, type Infer, IsoLanguageCode, type PIIEnforcement, type RefEntityId, type Schema, type SchemaOptions, type SchemaShape, type SchemaUpgradeFunction, type SchemaUpgradeResult, type SchemaUpgradeSpec, type SchemaUpgradeStep, type ValidateCompositionOptions, type ValidationResult, createComponentSchema, createSchema, field, getAllComponentSchemas, getAllSchemas, getComponentSchema, getSchemaForType, isExtensionSingleton, isExtensionSubtag, isIsoLanguageCode, isPrivateUseSingleton, isPrivateUseSubtag, isRegionSubtag, isScriptSubtag, isVariantSubtag, isoCountryCodes, isoCurrencyCodes, registerComponentSchema, renderSchemaDescription, validateCountryCode, validateCurrencyCode, validateDateTimeISO, validateEmail, validateLanguage, validateName, validatePercentage, validatePhone, validateRichText, validateSafeText, validateSemVer, validateUUID, validateUrl, validateUserId, validateUserIdArray };
|
|
639
|
+
export { type DeepReadonly, FieldBuilder, type FieldDefinition, type FieldExposure, type FieldType, type FieldTypeMap, type Infer, IsoLanguageCode, type PIIEnforcement, type RefEntityId, type Schema, type SchemaOptions, type SchemaShape, type SchemaUpgradeFunction, type SchemaUpgradeResult, type SchemaUpgradeSpec, type SchemaUpgradeStep, type SerializeOptions, type ValidateCompositionOptions, type ValidationResult, createComponentSchema, createSchema, field, getAllComponentSchemas, getAllSchemas, getComponentSchema, getSchemaForType, isExtensionSingleton, isExtensionSubtag, isIsoLanguageCode, isPrivateUseSingleton, isPrivateUseSubtag, isRegionSubtag, isScriptSubtag, isVariantSubtag, isoCountryCodes, isoCurrencyCodes, registerComponentSchema, renderSchemaDescription, validateCountryCode, validateCurrencyCode, validateDateTimeISO, validateEmail, validateLanguage, validateName, validatePercentage, validatePhone, validateRichText, validateSafeText, validateSemVer, validateUUID, validateUrl, validateUserId, validateUserIdArray };
|
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ interface PII {
|
|
|
10
10
|
|
|
11
11
|
type FieldType$1 = "string" | "number" | "boolean" | "object" | "array" | "ref";
|
|
12
12
|
|
|
13
|
+
type FieldExposure = "public" | "internal";
|
|
13
14
|
declare class FieldBuilder<TExternal = unknown, TInternal = TExternal> {
|
|
14
15
|
type: FieldType$1;
|
|
15
16
|
_type: TExternal;
|
|
@@ -35,6 +36,7 @@ declare class FieldBuilder<TExternal = unknown, TInternal = TExternal> {
|
|
|
35
36
|
itemType?: FieldBuilder<any>;
|
|
36
37
|
refType?: string;
|
|
37
38
|
_pii: PII;
|
|
39
|
+
_exposure: FieldExposure;
|
|
38
40
|
enumValues?: readonly TInternal[];
|
|
39
41
|
constructor(type: FieldType$1, options?: {
|
|
40
42
|
shape?: Record<string, FieldBuilder<any>>;
|
|
@@ -43,6 +45,9 @@ declare class FieldBuilder<TExternal = unknown, TInternal = TExternal> {
|
|
|
43
45
|
});
|
|
44
46
|
immutable(): FieldBuilder<TExternal, TInternal>;
|
|
45
47
|
system(): FieldBuilder<TExternal, TInternal>;
|
|
48
|
+
exposure(exposure: FieldExposure): FieldBuilder<TExternal, TInternal>;
|
|
49
|
+
internal(): FieldBuilder<TExternal, TInternal>;
|
|
50
|
+
public(): FieldBuilder<TExternal, TInternal>;
|
|
46
51
|
required(): FieldBuilder<TExternal, TInternal>;
|
|
47
52
|
optional(): FieldBuilder<TExternal, TInternal>;
|
|
48
53
|
validator(fn: (value: TInternal) => boolean): FieldBuilder<TExternal, TInternal>;
|
|
@@ -136,6 +141,9 @@ interface SchemaOptions {
|
|
|
136
141
|
piiEnforcement?: PIIEnforcement;
|
|
137
142
|
schemaUpgrade?: SchemaUpgradeStep[] | SchemaUpgradeFunction | undefined;
|
|
138
143
|
}
|
|
144
|
+
interface SerializeOptions {
|
|
145
|
+
includeInternal?: boolean;
|
|
146
|
+
}
|
|
139
147
|
type SchemaShape = Record<string, FieldBuilder<any>>;
|
|
140
148
|
interface FieldDefinition<T = unknown> {
|
|
141
149
|
type: FieldType;
|
|
@@ -153,6 +161,7 @@ interface FieldDefinition<T = unknown> {
|
|
|
153
161
|
enum?: string[];
|
|
154
162
|
_shape?: SchemaShape;
|
|
155
163
|
pii?: PII;
|
|
164
|
+
exposure?: FieldExposure;
|
|
156
165
|
validator?: (value: any) => boolean;
|
|
157
166
|
}
|
|
158
167
|
interface ValidateCompositionOptions {
|
|
@@ -182,6 +191,7 @@ interface Schema<T extends SchemaShape> {
|
|
|
182
191
|
};
|
|
183
192
|
validate: (input: unknown, existing?: Record<string, any>) => ValidationResult<Infer<T>>;
|
|
184
193
|
validateComposition: (entity: Infer<T>, options: ValidateCompositionOptions) => Promise<void>;
|
|
194
|
+
serialize: (input: Record<string, any>, options?: SerializeOptions) => Record<string, any>;
|
|
185
195
|
tableName?: () => string | undefined;
|
|
186
196
|
prepareForRead(stored: Record<string, any>, decryptFn: (value: string) => any | null): Record<string, any>;
|
|
187
197
|
prepareForStorage(input: Record<string, any>, encryptFn: (value: any) => string, hashFn: (value: any) => string): Record<string, any>;
|
|
@@ -209,6 +219,7 @@ interface Schema<T extends SchemaShape> {
|
|
|
209
219
|
enum: string[] | null;
|
|
210
220
|
refType: string | null;
|
|
211
221
|
pii: PII | null;
|
|
222
|
+
exposure: FieldExposure;
|
|
212
223
|
}>;
|
|
213
224
|
};
|
|
214
225
|
}
|
|
@@ -302,6 +313,7 @@ declare function renderSchemaDescription(schema: Schema<any>): {
|
|
|
302
313
|
description: string;
|
|
303
314
|
deprecated: boolean;
|
|
304
315
|
pii?: string;
|
|
316
|
+
exposure: "public" | "internal";
|
|
305
317
|
}>;
|
|
306
318
|
};
|
|
307
319
|
|
|
@@ -624,4 +636,4 @@ declare function isPrivateUseSubtag(value: string): boolean;
|
|
|
624
636
|
*/
|
|
625
637
|
declare function validateLanguage(value: unknown): boolean;
|
|
626
638
|
|
|
627
|
-
export { type DeepReadonly, FieldBuilder, type FieldDefinition, type FieldType, type FieldTypeMap, type Infer, IsoLanguageCode, type PIIEnforcement, type RefEntityId, type Schema, type SchemaOptions, type SchemaShape, type SchemaUpgradeFunction, type SchemaUpgradeResult, type SchemaUpgradeSpec, type SchemaUpgradeStep, type ValidateCompositionOptions, type ValidationResult, createComponentSchema, createSchema, field, getAllComponentSchemas, getAllSchemas, getComponentSchema, getSchemaForType, isExtensionSingleton, isExtensionSubtag, isIsoLanguageCode, isPrivateUseSingleton, isPrivateUseSubtag, isRegionSubtag, isScriptSubtag, isVariantSubtag, isoCountryCodes, isoCurrencyCodes, registerComponentSchema, renderSchemaDescription, validateCountryCode, validateCurrencyCode, validateDateTimeISO, validateEmail, validateLanguage, validateName, validatePercentage, validatePhone, validateRichText, validateSafeText, validateSemVer, validateUUID, validateUrl, validateUserId, validateUserIdArray };
|
|
639
|
+
export { type DeepReadonly, FieldBuilder, type FieldDefinition, type FieldExposure, type FieldType, type FieldTypeMap, type Infer, IsoLanguageCode, type PIIEnforcement, type RefEntityId, type Schema, type SchemaOptions, type SchemaShape, type SchemaUpgradeFunction, type SchemaUpgradeResult, type SchemaUpgradeSpec, type SchemaUpgradeStep, type SerializeOptions, type ValidateCompositionOptions, type ValidationResult, createComponentSchema, createSchema, field, getAllComponentSchemas, getAllSchemas, getComponentSchema, getSchemaForType, isExtensionSingleton, isExtensionSubtag, isIsoLanguageCode, isPrivateUseSingleton, isPrivateUseSubtag, isRegionSubtag, isScriptSubtag, isVariantSubtag, isoCountryCodes, isoCurrencyCodes, registerComponentSchema, renderSchemaDescription, validateCountryCode, validateCurrencyCode, validateDateTimeISO, validateEmail, validateLanguage, validateName, validatePercentage, validatePhone, validateRichText, validateSafeText, validateSemVer, validateUUID, validateUrl, validateUserId, validateUserIdArray };
|
package/dist/index.js
CHANGED
|
@@ -25,6 +25,7 @@ var FieldBuilder = class _FieldBuilder {
|
|
|
25
25
|
logHandling: "plain",
|
|
26
26
|
purpose: "an ordinary value"
|
|
27
27
|
};
|
|
28
|
+
_exposure = "public";
|
|
28
29
|
enumValues;
|
|
29
30
|
immutable() {
|
|
30
31
|
this.isImmutable = true;
|
|
@@ -34,6 +35,16 @@ var FieldBuilder = class _FieldBuilder {
|
|
|
34
35
|
this.isSystem = true;
|
|
35
36
|
return this;
|
|
36
37
|
}
|
|
38
|
+
exposure(exposure) {
|
|
39
|
+
this._exposure = exposure;
|
|
40
|
+
return this;
|
|
41
|
+
}
|
|
42
|
+
internal() {
|
|
43
|
+
return this.exposure("internal");
|
|
44
|
+
}
|
|
45
|
+
public() {
|
|
46
|
+
return this.exposure("public");
|
|
47
|
+
}
|
|
37
48
|
required() {
|
|
38
49
|
this.isRequired = true;
|
|
39
50
|
return this;
|
|
@@ -168,6 +179,7 @@ var FieldBuilder = class _FieldBuilder {
|
|
|
168
179
|
clone._description = this._description;
|
|
169
180
|
clone._version = this._version;
|
|
170
181
|
clone._pii = this._pii;
|
|
182
|
+
clone._exposure = this._exposure;
|
|
171
183
|
clone._validator = this._validator;
|
|
172
184
|
clone._default = this._default;
|
|
173
185
|
clone._upgrade = this._upgrade;
|
|
@@ -1371,6 +1383,94 @@ function deepClone(value) {
|
|
|
1371
1383
|
};
|
|
1372
1384
|
return cloneAny(value);
|
|
1373
1385
|
}
|
|
1386
|
+
function shouldIncludeField(def, options) {
|
|
1387
|
+
return options.includeInternal === true || (def?._exposure ?? "public") !== "internal";
|
|
1388
|
+
}
|
|
1389
|
+
function serializeFieldValue(def, value, options) {
|
|
1390
|
+
if (value === void 0) {
|
|
1391
|
+
return void 0;
|
|
1392
|
+
}
|
|
1393
|
+
if (value === null) {
|
|
1394
|
+
return null;
|
|
1395
|
+
}
|
|
1396
|
+
switch (def?.type) {
|
|
1397
|
+
case "string":
|
|
1398
|
+
case "number":
|
|
1399
|
+
case "boolean":
|
|
1400
|
+
return deepClone(value);
|
|
1401
|
+
case "ref": {
|
|
1402
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
1403
|
+
return deepClone(value);
|
|
1404
|
+
}
|
|
1405
|
+
const shape = getShape(def);
|
|
1406
|
+
if (!shape || Object.keys(shape).length === 0) {
|
|
1407
|
+
return deepClone(value);
|
|
1408
|
+
}
|
|
1409
|
+
const serializedRef = {};
|
|
1410
|
+
if (typeof value.type === "string") {
|
|
1411
|
+
serializedRef.type = value.type;
|
|
1412
|
+
}
|
|
1413
|
+
if (typeof value.id === "string") {
|
|
1414
|
+
serializedRef.id = value.id;
|
|
1415
|
+
}
|
|
1416
|
+
for (const [childKey, childDef] of Object.entries(shape)) {
|
|
1417
|
+
if (!shouldIncludeField(childDef, options)) {
|
|
1418
|
+
continue;
|
|
1419
|
+
}
|
|
1420
|
+
if (!Object.prototype.hasOwnProperty.call(value, childKey)) {
|
|
1421
|
+
continue;
|
|
1422
|
+
}
|
|
1423
|
+
const serializedChild = serializeFieldValue(
|
|
1424
|
+
childDef,
|
|
1425
|
+
value[childKey],
|
|
1426
|
+
options
|
|
1427
|
+
);
|
|
1428
|
+
if (serializedChild !== void 0) {
|
|
1429
|
+
serializedRef[childKey] = serializedChild;
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
return serializedRef;
|
|
1433
|
+
}
|
|
1434
|
+
case "object": {
|
|
1435
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
1436
|
+
return deepClone(value);
|
|
1437
|
+
}
|
|
1438
|
+
const shape = getShape(def);
|
|
1439
|
+
if (!shape || Object.keys(shape).length === 0) {
|
|
1440
|
+
return deepClone(value);
|
|
1441
|
+
}
|
|
1442
|
+
const serializedObject = {};
|
|
1443
|
+
for (const [childKey, childDef] of Object.entries(shape)) {
|
|
1444
|
+
if (!shouldIncludeField(childDef, options)) {
|
|
1445
|
+
continue;
|
|
1446
|
+
}
|
|
1447
|
+
if (!Object.prototype.hasOwnProperty.call(value, childKey)) {
|
|
1448
|
+
continue;
|
|
1449
|
+
}
|
|
1450
|
+
const serializedChild = serializeFieldValue(
|
|
1451
|
+
childDef,
|
|
1452
|
+
value[childKey],
|
|
1453
|
+
options
|
|
1454
|
+
);
|
|
1455
|
+
if (serializedChild !== void 0) {
|
|
1456
|
+
serializedObject[childKey] = serializedChild;
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
return serializedObject;
|
|
1460
|
+
}
|
|
1461
|
+
case "array": {
|
|
1462
|
+
if (!Array.isArray(value)) {
|
|
1463
|
+
return deepClone(value);
|
|
1464
|
+
}
|
|
1465
|
+
if (!def.itemType) {
|
|
1466
|
+
return deepClone(value);
|
|
1467
|
+
}
|
|
1468
|
+
return value.map((item) => serializeFieldValue(def.itemType, item, options));
|
|
1469
|
+
}
|
|
1470
|
+
default:
|
|
1471
|
+
return deepClone(value);
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1374
1474
|
function cmpSemver(a, b) {
|
|
1375
1475
|
const pa = a.split(".").map((n) => parseInt(n, 10));
|
|
1376
1476
|
const pb = b.split(".").map((n) => parseInt(n, 10));
|
|
@@ -2142,6 +2242,25 @@ function createSchema(_shape, entityType, options = {
|
|
|
2142
2242
|
}
|
|
2143
2243
|
return store;
|
|
2144
2244
|
},
|
|
2245
|
+
serialize(input, options2 = {}) {
|
|
2246
|
+
if (typeof input !== "object" || input === null) {
|
|
2247
|
+
return {};
|
|
2248
|
+
}
|
|
2249
|
+
const serialized = {};
|
|
2250
|
+
for (const [key, def] of Object.entries(schema._shape)) {
|
|
2251
|
+
if (!shouldIncludeField(def, options2)) {
|
|
2252
|
+
continue;
|
|
2253
|
+
}
|
|
2254
|
+
if (!Object.prototype.hasOwnProperty.call(input, key)) {
|
|
2255
|
+
continue;
|
|
2256
|
+
}
|
|
2257
|
+
const value = serializeFieldValue(def, input[key], options2);
|
|
2258
|
+
if (value !== void 0) {
|
|
2259
|
+
serialized[key] = value;
|
|
2260
|
+
}
|
|
2261
|
+
}
|
|
2262
|
+
return serialized;
|
|
2263
|
+
},
|
|
2145
2264
|
/**
|
|
2146
2265
|
* Transforms an input object for persistence by applying PII protection
|
|
2147
2266
|
* according to field annotations (e.g., encryption and hashing).
|
|
@@ -2211,7 +2330,8 @@ function createSchema(_shape, entityType, options = {
|
|
|
2211
2330
|
deprecatedVersion: def.deprecatedVersion === void 0 ? null : def.deprecatedVersion,
|
|
2212
2331
|
enum: getEnumValues(def) ?? null,
|
|
2213
2332
|
refType: def.refType ?? null,
|
|
2214
|
-
pii: !def._pii || def._pii.classification === "none" ? null : def._pii
|
|
2333
|
+
pii: !def._pii || def._pii.classification === "none" ? null : def._pii,
|
|
2334
|
+
exposure: def._exposure ?? "public"
|
|
2215
2335
|
};
|
|
2216
2336
|
}
|
|
2217
2337
|
return {
|
|
@@ -2241,7 +2361,8 @@ function renderSchemaDescription(schema) {
|
|
|
2241
2361
|
optional: def.optional,
|
|
2242
2362
|
description: def.description,
|
|
2243
2363
|
deprecated: def.deprecated,
|
|
2244
|
-
pii: def.pii ? def.pii.classification : void 0
|
|
2364
|
+
pii: def.pii ? def.pii.classification : void 0,
|
|
2365
|
+
exposure: def.exposure
|
|
2245
2366
|
}))
|
|
2246
2367
|
};
|
|
2247
2368
|
}
|