@elliots/typical 0.1.6 → 0.1.8

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.
@@ -14,6 +14,23 @@ export interface TypicalConfig {
14
14
  * Example: ["React.*", "Express.Request", "*.Event"]
15
15
  */
16
16
  ignoreTypes?: string[];
17
+ /**
18
+ * Skip validation for DOM types (Document, Element, Node, etc.) and their subclasses.
19
+ * These types have complex Window intersections that typia cannot process.
20
+ * Default: true
21
+ */
22
+ ignoreDOMTypes?: boolean;
23
+ /**
24
+ * Validate function parameters and return types at runtime.
25
+ * When enabled, typed function parameters get runtime validation calls injected.
26
+ * Default: true
27
+ */
28
+ validateFunctions?: boolean;
17
29
  }
18
30
  export declare const defaultConfig: TypicalConfig;
31
+ /**
32
+ * DOM types that typia cannot process due to Window global intersections.
33
+ * These are the base DOM types - classes extending them are checked separately.
34
+ */
35
+ export declare const DOM_TYPES_TO_IGNORE: string[];
19
36
  export declare function loadConfig(configPath?: string): TypicalConfig;
@@ -3,11 +3,54 @@ export const defaultConfig = {
3
3
  exclude: ["node_modules/**", "**/*.d.ts", "dist/**", "build/**"],
4
4
  reusableValidators: true,
5
5
  validateCasts: false,
6
+ validateFunctions: true,
6
7
  hoistRegex: true,
8
+ ignoreDOMTypes: true,
7
9
  debug: {
8
10
  writeIntermediateFiles: false,
9
11
  },
10
12
  };
13
+ // FIXME: find a better way to work out which types to ignore
14
+ /**
15
+ * DOM types that typia cannot process due to Window global intersections.
16
+ * These are the base DOM types - classes extending them are checked separately.
17
+ */
18
+ export const DOM_TYPES_TO_IGNORE = [
19
+ // Core DOM types
20
+ "Document",
21
+ "DocumentFragment",
22
+ "Element",
23
+ "Node",
24
+ "ShadowRoot",
25
+ "Window",
26
+ "EventTarget",
27
+ // HTML Elements
28
+ "HTML*Element",
29
+ "HTMLElement",
30
+ "HTMLCollection",
31
+ // SVG Elements
32
+ "SVG*Element",
33
+ "SVGElement",
34
+ // Events
35
+ "*Event",
36
+ // Other common DOM types
37
+ "NodeList",
38
+ "DOMTokenList",
39
+ "NamedNodeMap",
40
+ "CSSStyleDeclaration",
41
+ "Selection",
42
+ "Range",
43
+ "Text",
44
+ "Comment",
45
+ "CDATASection",
46
+ "ProcessingInstruction",
47
+ "DocumentType",
48
+ "Attr",
49
+ "Table",
50
+ "TableRow",
51
+ "TableCell",
52
+ "StyleSheet",
53
+ ];
11
54
  import fs from 'fs';
12
55
  import path from 'path';
13
56
  export function loadConfig(configPath) {
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAmBA,MAAM,CAAC,MAAM,aAAa,GAAkB;IAC1C,OAAO,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC;IAChC,OAAO,EAAE,CAAC,iBAAiB,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC;IAChE,kBAAkB,EAAE,IAAI;IACxB,aAAa,EAAE,KAAK;IACpB,UAAU,EAAE,IAAI;IAChB,KAAK,EAAE;QACL,sBAAsB,EAAE,KAAK;KAC9B;CACF,CAAC;AAEF,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,UAAU,UAAU,CAAC,UAAmB;IAC5C,MAAM,UAAU,GAAG,UAAU,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC;IAE1E,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YAC1D,MAAM,UAAU,GAA2B,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YAErE,OAAO;gBACL,GAAG,aAAa;gBAChB,GAAG,UAAU;aACd,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,+BAA+B,UAAU,GAAG,EAAE,KAAK,CAAC,CAAC;YAClE,OAAO,aAAa,CAAC;QACvB,CAAC;IACH,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AA+BA,MAAM,CAAC,MAAM,aAAa,GAAkB;IAC1C,OAAO,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC;IAChC,OAAO,EAAE,CAAC,iBAAiB,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC;IAChE,kBAAkB,EAAE,IAAI;IACxB,aAAa,EAAE,KAAK;IACpB,iBAAiB,EAAE,IAAI;IACvB,UAAU,EAAE,IAAI;IAChB,cAAc,EAAE,IAAI;IACpB,KAAK,EAAE;QACL,sBAAsB,EAAE,KAAK;KAC9B;CACF,CAAC;AAEF,6DAA6D;AAC7D;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,iBAAiB;IACjB,UAAU;IACV,kBAAkB;IAClB,SAAS;IACT,MAAM;IACN,YAAY;IACZ,QAAQ;IACR,aAAa;IACb,gBAAgB;IAChB,cAAc;IACd,aAAa;IACb,gBAAgB;IAChB,eAAe;IACf,aAAa;IACb,YAAY;IACZ,SAAS;IACT,QAAQ;IACR,yBAAyB;IACzB,UAAU;IACV,cAAc;IACd,cAAc;IACd,qBAAqB;IACrB,WAAW;IACX,OAAO;IACP,MAAM;IACN,SAAS;IACT,cAAc;IACd,uBAAuB;IACvB,cAAc;IACd,MAAM;IACN,OAAO;IACP,UAAU;IACV,WAAW;IACX,YAAY;CACb,CAAC;AAEF,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,UAAU,UAAU,CAAC,UAAmB;IAC5C,MAAM,UAAU,GAAG,UAAU,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC;IAE1E,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YAC1D,MAAM,UAAU,GAA2B,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YAErE,OAAO;gBACL,GAAG,aAAa;gBAChB,GAAG,UAAU;aACd,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,+BAA+B,UAAU,GAAG,EAAE,KAAK,CAAC,CAAC;YAClE,OAAO,aAAa,CAAC;QACvB,CAAC;IACH,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC"}
@@ -14,33 +14,64 @@ export declare class TypicalTransformer {
14
14
  private typeParsers;
15
15
  constructor(config?: TypicalConfig, program?: ts.Program, tsInstance?: typeof ts);
16
16
  createSourceFile(fileName: string, content: string): ts.SourceFile;
17
- transform(sourceFile: ts.SourceFile | string, mode: "basic" | "typia" | "js"): string;
18
- getTransformer(withTypia: boolean): ts.TransformerFactory<ts.SourceFile>;
17
+ transform(sourceFile: ts.SourceFile | string, mode: "basic" | "typia" | "js", skippedTypes?: Set<string>): string;
18
+ /**
19
+ * Apply typia transformation in a separate ts.transform() context.
20
+ * This avoids mixing program contexts and eliminates the need for import recreation.
21
+ * Returns either the transformed code string, or a retry signal with the failed type.
22
+ */
23
+ private applyTypiaTransform;
19
24
  /**
20
- * Re-create an import declaration as a fully synthetic node.
21
- * This prevents TypeScript from trying to look up symbol bindings
22
- * and eliding the import as "unused".
25
+ * Get a transformer that only applies typical's transformations (no typia).
26
+ * @param skippedTypes Set of type strings to skip validation for (used for retry after typia errors)
23
27
  */
24
- private recreateImportDeclaration;
28
+ private getTypicalOnlyTransformer;
29
+ /**
30
+ * Get a combined transformer for use with ts-patch/ttsc.
31
+ * This is used by the TSC plugin where we need a single transformer factory.
32
+ *
33
+ * Note: Even for ts-patch, we need to create a new program with the transformed
34
+ * source so typia can resolve the types from our generated typia.createAssert<T>() calls.
35
+ */
36
+ getTransformer(withTypia: boolean): ts.TransformerFactory<ts.SourceFile>;
25
37
  /**
26
38
  * Transform a single source file with TypeScript AST
27
39
  */
28
40
  private transformSourceFile;
29
41
  shouldTransformFile(fileName: string): boolean;
30
42
  /**
31
- * Check if a TypeNode represents any or unknown type.
32
- * These types are intentional escape hatches and shouldn't be validated.
43
+ * Check if a TypeNode represents a type that shouldn't be validated.
44
+ * This includes:
45
+ * - any/unknown (intentional escape hatches)
46
+ * - Type parameters (generics like T)
47
+ * - Constructor types (new (...args: any[]) => T)
48
+ * - Function types ((...args) => T)
33
49
  */
34
50
  private isAnyOrUnknownType;
35
51
  /**
36
- * Check if a Type has any or unknown flags.
52
+ * Check if a type contains any unvalidatable parts (type parameters, constructor types, etc.)
53
+ * This recursively checks intersection and union types.
54
+ */
55
+ private containsUnvalidatableType;
56
+ /**
57
+ * Check if a Type has any or unknown flags, or is a type parameter or function/constructor.
37
58
  */
38
59
  private isAnyOrUnknownTypeFlags;
39
60
  /**
40
61
  * Check if a type name matches any of the ignoreTypes patterns.
41
62
  * Supports wildcards: "React.*" matches "React.FormEvent", "React.ChangeEvent", etc.
63
+ * Also handles union types: "Document | Element" is ignored if "Document" or "Element" is in ignoreTypes.
42
64
  */
43
65
  private isIgnoredType;
66
+ /**
67
+ * Check if a single type (not a union) should be ignored.
68
+ * Checks both the type name and its base classes.
69
+ */
70
+ private isIgnoredSingleType;
71
+ /**
72
+ * Check if a single type name matches any ignore pattern.
73
+ */
74
+ private matchesIgnorePattern;
44
75
  /**
45
76
  * Find untransformed typia calls in the output code.
46
77
  * These indicate types that typia could not process.
@@ -73,6 +104,17 @@ export declare class TypicalTransformer {
73
104
  * getTypeFromTypeNode doesn't work correctly on them
74
105
  */
75
106
  private getTypeKey;
107
+ /**
108
+ * Simple string hash for creating unique identifiers from type strings.
109
+ */
110
+ private hashString;
111
+ /**
112
+ * Format typia's error message into a cleaner list format.
113
+ * Typia outputs verbose messages like:
114
+ * "unsupported type detected\n\n- Window.ondevicemotion: unknown\n - nonsensible intersection\n\n- Window.ondeviceorientation..."
115
+ * We want to extract just the problematic types and their issues.
116
+ */
117
+ private formatTypiaError;
76
118
  /**
77
119
  * Creates a readable name suffix from a type string.
78
120
  * For simple identifiers like "User" or "string", returns the name directly.