@plasius/schema 1.1.0 → 1.2.0

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 (59) hide show
  1. package/README.md +31 -18
  2. package/dist/index.cjs +2370 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.d.cts +627 -0
  5. package/dist/index.d.ts +627 -0
  6. package/dist/index.js +2308 -0
  7. package/dist/index.js.map +1 -0
  8. package/package.json +18 -6
  9. package/.eslintrc.cjs +0 -7
  10. package/.github/workflows/cd.yml +0 -236
  11. package/.github/workflows/ci.yml +0 -16
  12. package/.nvmrc +0 -1
  13. package/.vscode/launch.json +0 -15
  14. package/CHANGELOG.md +0 -120
  15. package/CODE_OF_CONDUCT.md +0 -79
  16. package/CONTRIBUTING.md +0 -201
  17. package/CONTRIBUTORS.md +0 -27
  18. package/SECURITY.md +0 -17
  19. package/docs/adrs/adr-0001: schema.md +0 -45
  20. package/docs/adrs/adr-template.md +0 -67
  21. package/legal/CLA-REGISTRY.csv +0 -2
  22. package/legal/CLA.md +0 -22
  23. package/legal/CORPORATE_CLA.md +0 -57
  24. package/legal/INDIVIDUAL_CLA.md +0 -91
  25. package/sbom.cdx.json +0 -66
  26. package/src/components.ts +0 -39
  27. package/src/field.builder.ts +0 -239
  28. package/src/field.ts +0 -153
  29. package/src/index.ts +0 -7
  30. package/src/infer.ts +0 -34
  31. package/src/pii.ts +0 -165
  32. package/src/schema.ts +0 -893
  33. package/src/types.ts +0 -156
  34. package/src/validation/countryCode.ISO3166.ts +0 -256
  35. package/src/validation/currencyCode.ISO4217.ts +0 -191
  36. package/src/validation/dateTime.ISO8601.ts +0 -60
  37. package/src/validation/email.RFC5322.ts +0 -9
  38. package/src/validation/generalText.OWASP.ts +0 -39
  39. package/src/validation/index.ts +0 -13
  40. package/src/validation/languageCode.BCP47.ts +0 -299
  41. package/src/validation/name.OWASP.ts +0 -25
  42. package/src/validation/percentage.ISO80000-1.ts +0 -8
  43. package/src/validation/phone.E.164.ts +0 -9
  44. package/src/validation/richtext.OWASP.ts +0 -34
  45. package/src/validation/url.WHATWG.ts +0 -16
  46. package/src/validation/user.MS-GOOGLE-APPLE.ts +0 -31
  47. package/src/validation/uuid.RFC4122.ts +0 -10
  48. package/src/validation/version.SEMVER2.0.0.ts +0 -10
  49. package/tests/field.builder.test.ts +0 -81
  50. package/tests/fields.test.ts +0 -213
  51. package/tests/pii.test.ts +0 -139
  52. package/tests/schema.test.ts +0 -501
  53. package/tests/test-utils.ts +0 -97
  54. package/tests/validate.test.ts +0 -97
  55. package/tests/validation.test.ts +0 -98
  56. package/tsconfig.build.json +0 -19
  57. package/tsconfig.json +0 -7
  58. package/tsup.config.ts +0 -10
  59. 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
- }