@plasius/schema 1.1.0 → 1.1.1
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/dist/index.cjs +1934 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +391 -0
- package/dist/index.d.ts +391 -0
- package/dist/index.js +1883 -0
- package/dist/index.js.map +1 -0
- package/package.json +18 -6
- package/.eslintrc.cjs +0 -7
- package/.github/workflows/cd.yml +0 -236
- package/.github/workflows/ci.yml +0 -16
- package/.nvmrc +0 -1
- package/.vscode/launch.json +0 -15
- package/CHANGELOG.md +0 -120
- package/CODE_OF_CONDUCT.md +0 -79
- package/CONTRIBUTING.md +0 -201
- package/CONTRIBUTORS.md +0 -27
- package/SECURITY.md +0 -17
- package/docs/adrs/adr-0001: schema.md +0 -45
- package/docs/adrs/adr-template.md +0 -67
- package/legal/CLA-REGISTRY.csv +0 -2
- package/legal/CLA.md +0 -22
- package/legal/CORPORATE_CLA.md +0 -57
- package/legal/INDIVIDUAL_CLA.md +0 -91
- package/sbom.cdx.json +0 -66
- package/src/components.ts +0 -39
- package/src/field.builder.ts +0 -239
- package/src/field.ts +0 -153
- package/src/index.ts +0 -7
- package/src/infer.ts +0 -34
- package/src/pii.ts +0 -165
- package/src/schema.ts +0 -893
- package/src/types.ts +0 -156
- package/src/validation/countryCode.ISO3166.ts +0 -256
- package/src/validation/currencyCode.ISO4217.ts +0 -191
- package/src/validation/dateTime.ISO8601.ts +0 -60
- package/src/validation/email.RFC5322.ts +0 -9
- package/src/validation/generalText.OWASP.ts +0 -39
- package/src/validation/index.ts +0 -13
- package/src/validation/languageCode.BCP47.ts +0 -299
- package/src/validation/name.OWASP.ts +0 -25
- package/src/validation/percentage.ISO80000-1.ts +0 -8
- package/src/validation/phone.E.164.ts +0 -9
- package/src/validation/richtext.OWASP.ts +0 -34
- package/src/validation/url.WHATWG.ts +0 -16
- package/src/validation/user.MS-GOOGLE-APPLE.ts +0 -31
- package/src/validation/uuid.RFC4122.ts +0 -10
- package/src/validation/version.SEMVER2.0.0.ts +0 -10
- package/tests/field.builder.test.ts +0 -81
- package/tests/fields.test.ts +0 -213
- package/tests/pii.test.ts +0 -139
- package/tests/schema.test.ts +0 -501
- package/tests/test-utils.ts +0 -97
- package/tests/validate.test.ts +0 -97
- package/tests/validation.test.ts +0 -98
- package/tsconfig.build.json +0 -19
- package/tsconfig.json +0 -7
- package/tsup.config.ts +0 -10
- package/vitest.config.js +0 -20
package/src/pii.ts
DELETED
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
export type PIIClassification = "none" | "low" | "high";
|
|
2
|
-
|
|
3
|
-
export type PIIAction = "encrypt" | "hash" | "clear" | "none";
|
|
4
|
-
|
|
5
|
-
export type PIILogHandling = "redact" | "omit" | "pseudonym" | "plain";
|
|
6
|
-
|
|
7
|
-
export type PiiEnforcement = "strict" | "warn" | "none";
|
|
8
|
-
|
|
9
|
-
export interface PII {
|
|
10
|
-
classification: PIIClassification;
|
|
11
|
-
action: PIIAction;
|
|
12
|
-
logHandling?: PIILogHandling; // How should this PII be handled in logs?
|
|
13
|
-
purpose?: string; // optional, for audit: e.g. "user contact", "analytics"
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Centralized PII enforcement for field-level validation.
|
|
18
|
-
* Returns { shortCircuit: true } when in strict mode and value is missing for high PII.
|
|
19
|
-
*/
|
|
20
|
-
export function enforcePIIField(
|
|
21
|
-
parentKey: string,
|
|
22
|
-
key: string,
|
|
23
|
-
value: any,
|
|
24
|
-
def: any,
|
|
25
|
-
enforcement: PiiEnforcement = "none",
|
|
26
|
-
errors?: string[],
|
|
27
|
-
logger?: { warn: (msg: string) => void }
|
|
28
|
-
): { shortCircuit: boolean } {
|
|
29
|
-
const path = parentKey ? `${parentKey}.${key}` : key;
|
|
30
|
-
if (def?._pii?.classification === "high" && (def?.isRequired ?? true)) {
|
|
31
|
-
const missing = value === undefined || value === null || value === "";
|
|
32
|
-
if (missing) {
|
|
33
|
-
const msg = `High PII field must not be empty: ${path}`;
|
|
34
|
-
if (enforcement === "strict") {
|
|
35
|
-
errors?.push(msg);
|
|
36
|
-
return { shortCircuit: true };
|
|
37
|
-
}
|
|
38
|
-
if (enforcement === "warn") {
|
|
39
|
-
logger?.warn?.(`WARN (PII Enforcement): ${msg}`);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return { shortCircuit: false };
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Apply storage-time PII transforms based on field definitions in shape.
|
|
48
|
-
*/
|
|
49
|
-
export function prepareForStorage(
|
|
50
|
-
shape: Record<string, any>,
|
|
51
|
-
input: Record<string, any>,
|
|
52
|
-
encryptFn: (value: any) => string,
|
|
53
|
-
hashFn: (value: any) => string
|
|
54
|
-
): Record<string, any> {
|
|
55
|
-
const result: any = {};
|
|
56
|
-
for (const key in shape) {
|
|
57
|
-
const def = shape[key];
|
|
58
|
-
if (!def) continue;
|
|
59
|
-
const value = input[key];
|
|
60
|
-
if (def._pii?.action === "encrypt") {
|
|
61
|
-
result[key + "Encrypted"] = encryptFn(value);
|
|
62
|
-
} else if (def._pii?.action === "hash") {
|
|
63
|
-
result[key + "Hash"] = hashFn(value);
|
|
64
|
-
} else {
|
|
65
|
-
result[key] = value;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
return result;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Apply read-time PII transforms (e.g., decrypt) based on field definitions in shape.
|
|
73
|
-
*/
|
|
74
|
-
export function prepareForRead(
|
|
75
|
-
shape: Record<string, any>,
|
|
76
|
-
stored: Record<string, any>,
|
|
77
|
-
decryptFn: (value: string) => any
|
|
78
|
-
): Record<string, any> {
|
|
79
|
-
const result: any = {};
|
|
80
|
-
for (const key in shape) {
|
|
81
|
-
const def = shape[key];
|
|
82
|
-
if (!def) continue;
|
|
83
|
-
if (def._pii?.action === "encrypt") {
|
|
84
|
-
result[key] = decryptFn(stored[key + "Encrypted"]);
|
|
85
|
-
} else {
|
|
86
|
-
result[key] = stored[key];
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
return result;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Sanitize data for logging according to PII logHandling.
|
|
94
|
-
*/
|
|
95
|
-
export function sanitizeForLog(
|
|
96
|
-
shape: Record<string, any>,
|
|
97
|
-
data: Record<string, any>,
|
|
98
|
-
pseudonymFn: (value: any) => string
|
|
99
|
-
): Record<string, any> {
|
|
100
|
-
const output: any = {};
|
|
101
|
-
for (const key in shape) {
|
|
102
|
-
const def = shape[key];
|
|
103
|
-
if (!def) continue;
|
|
104
|
-
const value = data[key];
|
|
105
|
-
const handling = def._pii?.logHandling as PIILogHandling | undefined;
|
|
106
|
-
if (handling === "omit") continue;
|
|
107
|
-
if (handling === "redact") {
|
|
108
|
-
output[key] = "[REDACTED]";
|
|
109
|
-
} else if (handling === "pseudonym") {
|
|
110
|
-
output[key] = pseudonymFn(value);
|
|
111
|
-
} else {
|
|
112
|
-
output[key] = value;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
return output;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Produce a PII audit list for the given shape.
|
|
120
|
-
*/
|
|
121
|
-
export function getPiiAudit(shape: Record<string, any>): Array<{
|
|
122
|
-
field: string;
|
|
123
|
-
classification: PIIClassification;
|
|
124
|
-
action: PIIAction;
|
|
125
|
-
logHandling?: PIILogHandling;
|
|
126
|
-
purpose?: string;
|
|
127
|
-
}> {
|
|
128
|
-
const piiFields: Array<any> = [];
|
|
129
|
-
for (const key in shape) {
|
|
130
|
-
const def = shape[key];
|
|
131
|
-
if (!def) continue;
|
|
132
|
-
if (def._pii && def._pii.classification !== "none") {
|
|
133
|
-
piiFields.push({
|
|
134
|
-
field: key,
|
|
135
|
-
classification: def._pii.classification,
|
|
136
|
-
action: def._pii.action,
|
|
137
|
-
logHandling: def._pii.logHandling,
|
|
138
|
-
purpose: def._pii.purpose,
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
return piiFields;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Scrub PII fields for delete/retention workflows.
|
|
147
|
-
*/
|
|
148
|
-
export function scrubPiiForDelete(
|
|
149
|
-
shape: Record<string, any>,
|
|
150
|
-
stored: Record<string, any>
|
|
151
|
-
): Record<string, any> {
|
|
152
|
-
const result: any = { ...stored };
|
|
153
|
-
for (const key in shape) {
|
|
154
|
-
const def = shape[key];
|
|
155
|
-
if (!def) continue;
|
|
156
|
-
if (def._pii?.action === "encrypt") {
|
|
157
|
-
result[key + "Encrypted"] = null;
|
|
158
|
-
} else if (def._pii?.action === "hash") {
|
|
159
|
-
result[key + "Hash"] = null;
|
|
160
|
-
} else if (def._pii?.action === "clear") {
|
|
161
|
-
result[key] = null;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
return result;
|
|
165
|
-
}
|