@plasius/schema 1.1.1 → 1.2.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/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # @plasius/schema
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/@plasius/schema.svg)](https://www.npmjs.com/package/@plasius/schema)
4
- [![Build Status](https://img.shields.io/github/actions/workflow/status/Plasius-LTD/schema/ci.yml?branch=main&label=build&style=flat)](https://github.com/plasius/schema/actions/workflows/ci.yml)
4
+ [![Build Status](https://img.shields.io/github/actions/workflow/status/Plasius-LTD/schema/ci.yml?branch=main&label=build&style=flat)](https://github.com/Plasius-LTD/schema/actions/workflows/ci.yml)
5
5
  [![coverage](https://img.shields.io/codecov/c/github/Plasius-LTD/schema)](https://codecov.io/gh/Plasius-LTD/schema)
6
6
  [![License](https://img.shields.io/github/license/Plasius-LTD/schema)](./LICENSE)
7
7
  [![Code of Conduct](https://img.shields.io/badge/code%20of%20conduct-yes-blue.svg)](./CODE_OF_CONDUCT.md)
@@ -46,7 +46,8 @@ import {
46
46
  createSchema,
47
47
  field,
48
48
  getSchemaForType,
49
- getAllSchemas
49
+ getAllSchemas,
50
+ Infer
50
51
  } from "@plasius/schema";
51
52
  ```
52
53
 
@@ -56,25 +57,27 @@ import {
56
57
 
57
58
  ```ts
58
59
  const UserFields = {
59
- id: field.string().uuid().required().description("Unique user id"),
60
+ id: field.uuid().required().description("Unique user id"),
60
61
  email: field.email().required(),
61
- name: field.name().optional(),
62
- age: field.number().int().min(0).optional(),
62
+ name: field.generalText().optional(),
63
+ age: field.number().min(0).optional(),
63
64
  roles: field.array(field.string().enum(["admin", "user"]))
64
- .default(["user"]).description("RBAC roles"),
65
- createdAt: field.dateTimeISO().default(() => new Date()),
65
+ .default(["user"])
66
+ .description("RBAC roles"),
67
+ createdAt: field.dateTimeISO().default(() => new Date().toISOString()),
66
68
  };
67
69
  ```
68
70
 
69
71
  Common methods (non‑exhaustive): `.required()`, `.optional()`, `.default(v|fn)`, `.description(text)`, and type‑specific helpers like `.email()`, `.uuid()`, `.min()`, `.max()`, `.enum([...])`.
72
+ Defaults are applied during validation when inputs are missing/`undefined`.
73
+ Fields are required by default; call `.optional()` (or provide `.default()`) to allow omission.
70
74
 
71
75
  ### 2) Create a **versioned** schema (enforces `type` + `version`)
72
76
 
73
77
  ```ts
74
- export const UserSchema = createSchema({
75
- entityType: "user",
78
+ export const UserSchema = createSchema(UserFields, "user", {
76
79
  version: "1.0.0",
77
- fields: UserFields,
80
+ piiEnforcement: "strict",
78
81
  });
79
82
 
80
83
  // Strongly-typed entity from a schema definition
@@ -99,7 +102,7 @@ const raw = {
99
102
  email: "alice@example.com",
100
103
  };
101
104
 
102
- const result = UserSchemavalidate(raw);
105
+ const result = UserSchema.validate(raw);
103
106
  if (result.valid && result.errors.length == 0) {
104
107
  // result.value is typed as User
105
108
  const user: User = result.value;
@@ -111,6 +114,17 @@ if (result.valid && result.errors.length == 0) {
111
114
 
112
115
  > If your validation layer also exposes a throwing variant (e.g. `validateOrThrow(UserSchema, raw)`), you can use that in places where exceptions are preferred.
113
116
 
117
+ - Validation highlights:
118
+ - Array item validators (e.g. `.pattern()`, `.min()`, `.max()`) run per element for primitive arrays.
119
+ - Arrays of refs validate nested ref shapes (defaults, required fields, and validators) when provided.
120
+ - Ref fields enforce their declared `refType` during validation, catching mismatches early.
121
+ - PII helpers recurse through nested objects/arrays/refs so encrypted/hashed/cleared fields are handled throughout the structure (including array items).
122
+ - ISO lists stay current (`PS` country code, `SLE` currency code) and the validation package exports `validateLanguage` for BCP 47 tags.
123
+ - Numeric enums are enforced like string enums instead of accepting out-of-range values.
124
+ - Immutable flags are honored on nested object/array/ref children when an existing entity is provided.
125
+ - PII strict/warn enforcement runs on nested fields, preventing empty high-PII subfields from slipping through.
126
+ - Validation deep-clones inputs before applying defaults, so caller-provided objects/arrays aren’t mutated and non-JSON-safe values (e.g., `Date`) are preserved.
127
+
114
128
  ### 4) Version enforcement in action
115
129
 
116
130
  If either `type` or `version` doesn’t match the schema, validation fails.
@@ -126,14 +140,14 @@ const bad = UserSchema.validate(wrong);
126
140
  Keep new versions side‑by‑side and migrate at edges:
127
141
 
128
142
  ```ts
129
- export const UserV2 = createSchema({
130
- entityType: "user",
131
- version: "2.0.0",
132
- fields: {
143
+ export const UserV2 = createSchema(
144
+ {
133
145
  ...UserFields,
134
146
  displayName: field.string().min(1).max(100).optional(),
135
147
  },
136
- });
148
+ "user",
149
+ { version: "2.0.0", piiEnforcement: "strict" }
150
+ );
137
151
  ```
138
152
 
139
153
  > Write a small migration function in your app to transform `User (1.0.0)` → `User (2.0.0)` where needed.
@@ -161,10 +175,9 @@ const UserV3Fields = {
161
175
  }),
162
176
  };
163
177
 
164
- export const UserV3 = createSchema({
165
- entityType: "user",
178
+ export const UserV3 = createSchema(UserV3Fields, "user", {
166
179
  version: "3.0.0",
167
- fields: UserV3Fields,
180
+ piiEnforcement: "strict",
168
181
  });
169
182
  ```
170
183