@elliots/typical 0.2.0-beta.1 → 0.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.
package/README.md CHANGED
@@ -286,12 +286,57 @@ Create a `typical.json` file in your project root (optional):
286
286
 
287
287
  ### Options
288
288
 
289
- | Option | Default | Description |
290
- | ------------------- | --------------------------------------------------------- | --------------------------------------------- |
291
- | `include` | `["**/*.ts", "**/*.tsx"]` | Files to transform |
292
- | `exclude` | `["node_modules/**", "**/*.d.ts", "dist/**", "build/**"]` | Files to skip |
293
- | `validateFunctions` | `true` | Validate function parameters and return types |
294
- | `validateCasts` | `false` | Validate type assertions (`as Type`) |
289
+ | Option | Default | Description |
290
+ | ------------------------ | --------------------------------------------------------- | ----------------------------------------------------------------- |
291
+ | `include` | `["**/*.ts", "**/*.tsx"]` | Files to transform |
292
+ | `exclude` | `["node_modules/**", "**/*.d.ts", "dist/**", "build/**"]` | Files to skip |
293
+ | `validateFunctions` | `true` | Validate function parameters and return types |
294
+ | `validateCasts` | `false` | Validate type assertions (`as Type`) |
295
+ | `transformJSONParse` | `true` | Transform `JSON.parse` to validate and filter to typed properties |
296
+ | `transformJSONStringify` | `true` | Transform `JSON.stringify` to only include typed properties |
297
+
298
+ ---
299
+
300
+ ## JSON Transformations
301
+
302
+ Typical automatically transforms `JSON.parse` and `JSON.stringify` calls when type information is available.
303
+
304
+ ### JSON.parse
305
+
306
+ When you cast the result of `JSON.parse`, Typical validates the parsed data and filters it to only include properties defined in your type:
307
+
308
+ ```ts
309
+ interface User {
310
+ name: string;
311
+ age: number;
312
+ }
313
+
314
+ // Input: '{"name":"Alice","age":30,"password":"secret"}'
315
+ const user = JSON.parse(jsonString) as User;
316
+ // Result: { name: "Alice", age: 30 } - password is filtered out!
317
+ // Throws TypeError if name isn't a string or age isn't a number
318
+ ```
319
+
320
+ ### JSON.stringify
321
+
322
+ When you use a type assertion with `JSON.stringify`, only properties defined in your type are included - preventing accidental data leaks:
323
+
324
+ ```ts
325
+ interface PublicUser {
326
+ name: string;
327
+ age: number;
328
+ }
329
+
330
+ const user = { name: "Alice", age: 30, password: "secret", ssn: "123-45-6789" };
331
+ const json = JSON.stringify(user as PublicUser);
332
+ // Result: '{"name":"Alice","age":30}' - sensitive data excluded!
333
+ ```
334
+
335
+ Both patterns detect type information from:
336
+
337
+ - Type assertions: `JSON.parse(str) as User` or `JSON.stringify(obj as User)`
338
+ - Variable declarations: `const user: User = JSON.parse(str)`
339
+ - Function return types: `function getUser(): User { return JSON.parse(str) }`
295
340
 
296
341
  ---
297
342
 
@@ -301,6 +346,16 @@ Typical uses a Go-based compiler that leverages the TypeScript type checker to a
301
346
 
302
347
  Types that can't be validated at runtime (like generic type parameters `T`) are skipped. You can still use `any` and `unknown` to opt out of validation.
303
348
 
349
+ ## Compiler Optimizations
350
+
351
+ The generated validation code is optimized for runtime performance:
352
+
353
+ - **Skip redundant validation** - When returning a validated parameter directly, the return validation is skipped (e.g., `return x` where `x: string` was already validated)
354
+ - **Subtype-aware skipping** - If a validated type is assignable to the return type, validation is skipped (e.g., `string` parameter returned as `string | null`)
355
+ - **Property chain tracking** - Accessing properties of validated objects skips re-validation (e.g., `return user.name` when `user: User` was validated)
356
+ - **Type-aware dirty tracking** - Primitives stay validated after being passed to functions (they're copied), but objects are re-validated (they could be mutated)
357
+ - **Union early bail-out** - Union type checks use if-else chains so the first matching type succeeds immediately
358
+
304
359
  ## Debugging
305
360
 
306
361
  Set `DEBUG=1` for verbose logging:
@@ -43,6 +43,18 @@ export interface TypicalConfig {
43
43
  * Default: true
44
44
  */
45
45
  validateFunctions?: boolean;
46
+ /**
47
+ * Transform JSON.parse<T>() calls to validate and filter the parsed result
48
+ * to only include properties defined in type T.
49
+ * Default: true
50
+ */
51
+ transformJSONParse?: boolean;
52
+ /**
53
+ * Transform JSON.stringify<T>() calls to only stringify properties defined
54
+ * in type T, preventing accidental data leaks.
55
+ * Default: true
56
+ */
57
+ transformJSONStringify?: boolean;
46
58
  /**
47
59
  * Source map generation settings.
48
60
  * Controls whether and how source maps are generated for transformed code.
@@ -4,6 +4,8 @@ export const defaultConfig = {
4
4
  reusableValidators: false, // Off by default for accurate source maps (set to true for production)
5
5
  validateCasts: false,
6
6
  validateFunctions: true,
7
+ transformJSONParse: true,
8
+ transformJSONStringify: true,
7
9
  hoistRegex: true,
8
10
  ignoreDOMTypes: true,
9
11
  debug: {
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elliots/typical",
3
- "version": "0.2.0-beta.1",
3
+ "version": "0.2.0",
4
4
  "description": "Runtime safe TypeScript transformer using typia",
5
5
  "keywords": [
6
6
  "runtime",
@@ -40,7 +40,7 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "commander": "14.0.2",
43
- "@elliots/typical-compiler": "0.2.0-beta.1"
43
+ "@elliots/typical-compiler": "0.2.0"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@types/node": "22",
package/src/config.ts CHANGED
@@ -45,6 +45,18 @@ export interface TypicalConfig {
45
45
  * Default: true
46
46
  */
47
47
  validateFunctions?: boolean
48
+ /**
49
+ * Transform JSON.parse<T>() calls to validate and filter the parsed result
50
+ * to only include properties defined in type T.
51
+ * Default: true
52
+ */
53
+ transformJSONParse?: boolean
54
+ /**
55
+ * Transform JSON.stringify<T>() calls to only stringify properties defined
56
+ * in type T, preventing accidental data leaks.
57
+ * Default: true
58
+ */
59
+ transformJSONStringify?: boolean
48
60
  /**
49
61
  * Source map generation settings.
50
62
  * Controls whether and how source maps are generated for transformed code.
@@ -71,6 +83,8 @@ export const defaultConfig: TypicalConfig = {
71
83
  reusableValidators: false, // Off by default for accurate source maps (set to true for production)
72
84
  validateCasts: false,
73
85
  validateFunctions: true,
86
+ transformJSONParse: true,
87
+ transformJSONStringify: true,
74
88
  hoistRegex: true,
75
89
  ignoreDOMTypes: true,
76
90
  debug: {