@elliots/typical 0.1.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 (42) hide show
  1. package/README.md +82 -0
  2. package/bin/ttsc +12 -0
  3. package/bin/ttsx +3 -0
  4. package/dist/src/cli.d.ts +2 -0
  5. package/dist/src/cli.js +89 -0
  6. package/dist/src/cli.js.map +1 -0
  7. package/dist/src/config.d.ts +7 -0
  8. package/dist/src/config.js +26 -0
  9. package/dist/src/config.js.map +1 -0
  10. package/dist/src/esm-loader-register.d.ts +1 -0
  11. package/dist/src/esm-loader-register.js +3 -0
  12. package/dist/src/esm-loader-register.js.map +1 -0
  13. package/dist/src/esm-loader.d.ts +4 -0
  14. package/dist/src/esm-loader.js +25 -0
  15. package/dist/src/esm-loader.js.map +1 -0
  16. package/dist/src/file-filter.d.ts +13 -0
  17. package/dist/src/file-filter.js +38 -0
  18. package/dist/src/file-filter.js.map +1 -0
  19. package/dist/src/index.d.ts +2 -0
  20. package/dist/src/index.js +3 -0
  21. package/dist/src/index.js.map +1 -0
  22. package/dist/src/setup.d.ts +2 -0
  23. package/dist/src/setup.js +14 -0
  24. package/dist/src/setup.js.map +1 -0
  25. package/dist/src/transformer.d.ts +29 -0
  26. package/dist/src/transformer.js +472 -0
  27. package/dist/src/transformer.js.map +1 -0
  28. package/dist/src/tsc-plugin.d.ts +3 -0
  29. package/dist/src/tsc-plugin.js +9 -0
  30. package/dist/src/tsc-plugin.js.map +1 -0
  31. package/package.json +71 -0
  32. package/src/cli.ts +111 -0
  33. package/src/config.ts +35 -0
  34. package/src/esm-loader-register.ts +2 -0
  35. package/src/esm-loader.ts +26 -0
  36. package/src/file-filter.ts +44 -0
  37. package/src/index.ts +2 -0
  38. package/src/patch-fs.cjs +25 -0
  39. package/src/patch-tsconfig.cjs +52 -0
  40. package/src/setup.ts +29 -0
  41. package/src/transformer.ts +831 -0
  42. package/src/tsc-plugin.ts +12 -0
package/README.md ADDED
@@ -0,0 +1,82 @@
1
+ # Typical
2
+
3
+ Typical adds runtime validation to typescript, making TypeScript type-safe at runtime *with no changes to your code*.
4
+
5
+ It can be used as a TSC plugin, or ESM loader for Node.js.
6
+
7
+ (Could add unplugin/vite plugin, bun plugin etc. if needed.)
8
+
9
+ ## Why?
10
+
11
+ For some use cases it can mean you don't need to use zod, yup, ajv, or other runtime validation libraries, as your types are already validated automatically.
12
+
13
+ It protects you from leaking data via JSON.stringify by making sure only the properties defined in your types are included in the output.
14
+
15
+ Why not.
16
+
17
+ ## Features
18
+
19
+ - ✅ Automatic validation of function parameters
20
+ - ✅ Automatic validation of return types
21
+ - ✅ Replace `JSON.stringify` with a custom stringifier (very fast!)
22
+ - ✅ Replace `JSON.parse` with a custom parser and validator (very fast!)
23
+ - ✅ Configurable include/exclude patterns
24
+ - ✅ Optionally reuse validation logic for identical types to optimize performance (enabled by default)
25
+ - ✅ TSC plugin
26
+ - ✅ ESM loader for runtime transformation with `node --import typical/esm` (or `node --loader typical/esm-loader` for older Node versions)
27
+ - ✅ tsx wrapper (ttsx) for easy use like `npx ttsx script.ts`
28
+
29
+ ## Installation
30
+
31
+ ```bash
32
+ npm add typical
33
+ ```
34
+
35
+ ## Configuration
36
+
37
+ Optional: Create a `typical.json` file in your project root.
38
+
39
+ If not provided, these default settings will be used.
40
+
41
+ ```json
42
+ {
43
+ "include": ["src/**/*.ts", "src/**/*.tsx"],
44
+ "exclude": ["node_modules/**", "**/*.d.ts", "dist/**"],
45
+ "optimizeReused": true
46
+ }
47
+ ```
48
+
49
+ ## Usage
50
+
51
+ See ./samples/esm and ./samples/tsc and ./samples/ttsx
52
+
53
+ Quickest way to try it out is to use ttsx:
54
+
55
+ ```bash
56
+ npm add github:elliots/typical
57
+ npx ttsx your-script.ts
58
+ ```
59
+
60
+ ## Example
61
+
62
+ This code will run without errors when compiled normally, but will throw an error when using Typical.
63
+
64
+
65
+ ```ts
66
+ interface User {
67
+ name: string;
68
+ email: `${string}@${string}`;
69
+ }
70
+ const u = JSON.parse('{"name":"Alice","email":"oops-not-an-email"}') as User;
71
+ ```
72
+
73
+ ## How it works
74
+
75
+ Typical uses the TypeScript Compiler API to parse and transform your TypeScript code. It analyzes function signatures, return types, and JSON operations to inject appropriate typia validation calls.
76
+
77
+ But basically you shouldn't need to care about how it works internally, it makes typescript strongly typed*. You can still use `any` and `unknown` if you want to opt out of type safety.
78
+
79
+ * sort of. probably. something like it anyway.
80
+
81
+ ## Credits
82
+ The actual validation work is done by [typia](https://github.com/samchon/typia). This package just generates the necessary code to call typia's functions based on your TypeScript types.
package/bin/ttsc ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { execSync } from "child_process";
4
+
5
+ const tscCommand = `node $(node -p "require.resolve('ts-patch/compiler/tsc.js')") ${process.argv.slice(2).join(" ")}`;
6
+ const patchTsConfig = new URL("../src/patch-tsconfig.cjs", import.meta.url);
7
+
8
+ execSync(tscCommand, {
9
+ stdio: "inherit",
10
+ cwd: process.cwd(),
11
+ env: { ...process.env, NODE_OPTIONS: `--import ${patchTsConfig}` },
12
+ });
package/bin/ttsx ADDED
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+
3
+ NODE_OPTIONS="--import typical/esm" exec tsx $@
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import * as fs from 'fs';
4
+ import * as path from 'path';
5
+ import { TypicalTransformer } from './transformer.js';
6
+ import { loadConfig } from './config.js';
7
+ const program = new Command();
8
+ program
9
+ .name('typical')
10
+ .description('Runtime safe TypeScript transformer using typia')
11
+ .version('0.1.0');
12
+ program
13
+ .command('transform')
14
+ .description('Transform a TypeScript file with runtime validation')
15
+ .argument('<file>', 'TypeScript file to transform')
16
+ .option('-o, --output <file>', 'Output file')
17
+ .option('-c, --config <file>', 'Config file path', 'typical.json')
18
+ .option('-m, --mode <mode>', 'Transformation mode: basic, typia, js', 'basic')
19
+ .action(async (file, options) => {
20
+ try {
21
+ const config = loadConfig(options.config);
22
+ const transformer = new TypicalTransformer(config);
23
+ if (!fs.existsSync(file)) {
24
+ console.error(`File not found: ${file}`);
25
+ process.exit(1);
26
+ }
27
+ console.log(`Transforming ${file}...`);
28
+ const transformedCode = transformer.transform(path.resolve(file), options.mode ?? 'basic');
29
+ const outputFilename = options.output ? path.resolve(options.output) : options.mode === 'js' ? file + '.js' : file + '.transformed.ts';
30
+ const outputFile = options.output ? path.resolve(options.output) : file + '.transformed.ts';
31
+ fs.writeFileSync(outputFile, transformedCode);
32
+ console.log(`Transformed code written to ${outputFile}`);
33
+ }
34
+ catch (error) {
35
+ console.error('Transformation failed:', error);
36
+ process.exit(1);
37
+ }
38
+ });
39
+ // program
40
+ // .command('build')
41
+ // .description('Transform all TypeScript files in the project')
42
+ // .option('-c, --config <file>', 'Config file path')
43
+ // .option('--dry-run', 'Show what would be transformed without making changes')
44
+ // .action(async (options: { config?: string, dryRun?: boolean }) => {
45
+ // try {
46
+ // const transformer = new TypicalTransformer();
47
+ // const { glob } = await import('glob');
48
+ // const config = loadConfig(options.config);
49
+ // if (!config.include || config.include.length === 0) {
50
+ // console.error('No include patterns specified in config');
51
+ // process.exit(1);
52
+ // }
53
+ // const files: string[] = [];
54
+ // for (const pattern of config.include) {
55
+ // const matched = await glob(pattern, {
56
+ // ignore: config.exclude,
57
+ // absolute: true
58
+ // });
59
+ // files.push(...matched);
60
+ // }
61
+ // console.log(`Found ${files.length} files to transform`);
62
+ // if (options.dryRun) {
63
+ // files.forEach(file => console.log(`Would transform: ${file}`));
64
+ // return;
65
+ // }
66
+ // let transformed = 0;
67
+ // for (const file of files) {
68
+ // // Double-check with our shared filtering logic
69
+ // if (!shouldIncludeFile(file, config)) {
70
+ // console.log(`Skipping ${file} (excluded by filters)`);
71
+ // continue;
72
+ // }
73
+ // try {
74
+ // console.log(`Transforming ${file}...`);
75
+ // const transformedCode = transformer.transformFile(file, ts);
76
+ // fs.writeFileSync(file, transformedCode);
77
+ // transformed++;
78
+ // } catch (error) {
79
+ // console.error(`Failed to transform ${file}:`, error);
80
+ // }
81
+ // }
82
+ // console.log(`Successfully transformed ${transformed}/${files.length} files`);
83
+ // } catch (error) {
84
+ // console.error('Build failed:', error);
85
+ // process.exit(1);
86
+ // }
87
+ // });
88
+ program.parse();
89
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface TypicalConfig {
2
+ include?: string[];
3
+ exclude?: string[];
4
+ reusableValidators?: boolean;
5
+ }
6
+ export declare const defaultConfig: TypicalConfig;
7
+ export declare function loadConfig(configPath?: string): TypicalConfig;
@@ -0,0 +1,26 @@
1
+ export const defaultConfig = {
2
+ include: ["**/*.ts", "**/*.tsx"],
3
+ exclude: ["node_modules/**", "**/*.d.ts", "dist/**", "build/**"],
4
+ reusableValidators: true,
5
+ };
6
+ import fs from 'fs';
7
+ import path from 'path';
8
+ export function loadConfig(configPath) {
9
+ const configFile = configPath || path.join(process.cwd(), 'typical.json');
10
+ if (fs.existsSync(configFile)) {
11
+ try {
12
+ const configContent = fs.readFileSync(configFile, 'utf8');
13
+ const userConfig = JSON.parse(configContent);
14
+ return {
15
+ ...defaultConfig,
16
+ ...userConfig,
17
+ };
18
+ }
19
+ catch (error) {
20
+ console.warn(`Failed to parse config file ${configFile}:`, error);
21
+ return defaultConfig;
22
+ }
23
+ }
24
+ return defaultConfig;
25
+ }
26
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAMA,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;CACzB,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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ import { register } from 'node:module';
2
+ register('./esm-loader.js', { parentURL: import.meta.url });
3
+ //# sourceMappingURL=esm-loader-register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"esm-loader-register.js","sourceRoot":"","sources":["../../src/esm-loader-register.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,QAAQ,CAAC,iBAAiB,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Load hook - transforms TypeScript files on the fly
3
+ */
4
+ export declare function load(url: string, context: any, nextLoad: any): Promise<any>;
@@ -0,0 +1,25 @@
1
+ import { fileURLToPath } from "url";
2
+ import { TypicalTransformer } from "./transformer.js";
3
+ const transformer = new TypicalTransformer();
4
+ /**
5
+ * Load hook - transforms TypeScript files on the fly
6
+ */
7
+ export async function load(url, context, nextLoad) {
8
+ if (!url.endsWith(".ts")) {
9
+ return nextLoad(url, context);
10
+ }
11
+ const filePath = fileURLToPath(url);
12
+ try {
13
+ const transformedCode = transformer.transform(filePath, 'js');
14
+ return {
15
+ format: "module",
16
+ source: transformedCode,
17
+ shortCircuit: true,
18
+ };
19
+ }
20
+ catch (error) {
21
+ console.error(`Error transforming ${filePath}:`, error);
22
+ throw error;
23
+ }
24
+ }
25
+ //# sourceMappingURL=esm-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"esm-loader.js","sourceRoot":"","sources":["../../src/esm-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,WAAW,GAAG,IAAI,kBAAkB,EAAE,CAAC;AAE7C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,GAAW,EAAE,OAAY,EAAE,QAAa;IACjE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAChC,CAAC;IACD,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAEpC,IAAI,CAAC;QACH,MAAM,eAAe,GAAG,WAAW,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC9D,OAAO;YACL,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,eAAe;YACvB,YAAY,EAAE,IAAI;SACnB,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,sBAAsB,QAAQ,GAAG,EAAE,KAAK,CAAC,CAAC;QACxD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { TypicalConfig } from './config.js';
2
+ /**
3
+ * Determines if a file should be transformed based on include/exclude patterns
4
+ */
5
+ export declare function shouldTransformFile(fileName: string, config: TypicalConfig): boolean;
6
+ /**
7
+ * Checks if a file is a TypeScript file that can be transformed
8
+ */
9
+ export declare function isTransformableTypeScriptFile(fileName: string): boolean;
10
+ /**
11
+ * Combined check for both file type and include/exclude patterns
12
+ */
13
+ export declare function shouldIncludeFile(fileName: string, config: TypicalConfig): boolean;
@@ -0,0 +1,38 @@
1
+ import * as path from 'path';
2
+ import { minimatch } from 'minimatch';
3
+ /**
4
+ * Determines if a file should be transformed based on include/exclude patterns
5
+ */
6
+ export function shouldTransformFile(fileName, config) {
7
+ const relativePath = path.relative(process.cwd(), fileName);
8
+ // Check include patterns
9
+ const isIncluded = config.include?.some(pattern => {
10
+ return minimatch(relativePath, pattern);
11
+ }) ?? true;
12
+ if (!isIncluded)
13
+ return false;
14
+ // Check exclude patterns
15
+ const isExcluded = config.exclude?.some(pattern => {
16
+ return minimatch(relativePath, pattern);
17
+ }) ?? false;
18
+ return !isExcluded;
19
+ }
20
+ /**
21
+ * Checks if a file is a TypeScript file that can be transformed
22
+ */
23
+ export function isTransformableTypeScriptFile(fileName) {
24
+ // Only transform TypeScript files
25
+ if (!/\.(ts|tsx)$/.test(fileName))
26
+ return false;
27
+ // Skip declaration files
28
+ if (fileName.endsWith('.d.ts'))
29
+ return false;
30
+ return true;
31
+ }
32
+ /**
33
+ * Combined check for both file type and include/exclude patterns
34
+ */
35
+ export function shouldIncludeFile(fileName, config) {
36
+ return isTransformableTypeScriptFile(fileName) && shouldTransformFile(fileName, config);
37
+ }
38
+ //# sourceMappingURL=file-filter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-filter.js","sourceRoot":"","sources":["../../src/file-filter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGtC;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAAgB,EAAE,MAAqB;IACzE,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;IAE5D,yBAAyB;IACzB,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE;QAChD,OAAO,SAAS,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC,CAAC,IAAI,IAAI,CAAC;IAEX,IAAI,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IAE9B,yBAAyB;IACzB,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE;QAChD,OAAO,SAAS,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC,CAAC,IAAI,KAAK,CAAC;IAEZ,OAAO,CAAC,UAAU,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,6BAA6B,CAAC,QAAgB;IAC5D,kCAAkC;IAClC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAC;IAEhD,yBAAyB;IACzB,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IAE7C,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB,EAAE,MAAqB;IACvE,OAAO,6BAA6B,CAAC,QAAQ,CAAC,IAAI,mBAAmB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAC1F,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { TypicalTransformer } from './transformer.js';
2
+ export { loadConfig, defaultConfig, TypicalConfig } from './config.js';
@@ -0,0 +1,3 @@
1
+ export { TypicalTransformer } from './transformer.js';
2
+ export { loadConfig, defaultConfig } from './config.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAiB,MAAM,aAAa,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type ts from "typescript";
2
+ export declare function setupTsProgram(tsInstance: typeof ts): ts.Program;
@@ -0,0 +1,14 @@
1
+ export function setupTsProgram(tsInstance) {
2
+ // Find tsconfig.json
3
+ const tsConfigPath = tsInstance.findConfigFile(process.cwd(), tsInstance.sys.fileExists, "tsconfig.json");
4
+ if (!tsConfigPath) {
5
+ throw new Error("Could not find tsconfig.json");
6
+ }
7
+ // Load and parse tsconfig.json
8
+ const configFile = tsInstance.readConfigFile(tsConfigPath, tsInstance.sys.readFile);
9
+ const parsedConfig = tsInstance.parseJsonConfigFileContent(configFile.config, tsInstance.sys, process.cwd());
10
+ // Create the TypeScript program with all project files
11
+ const tsProgram = tsInstance.createProgram(parsedConfig.fileNames, parsedConfig.options);
12
+ return tsProgram;
13
+ }
14
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/setup.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,cAAc,CAAC,UAAqB;IAClD,qBAAqB;IACrB,MAAM,YAAY,GAAG,UAAU,CAAC,cAAc,CAC5C,OAAO,CAAC,GAAG,EAAE,EACb,UAAU,CAAC,GAAG,CAAC,UAAU,EACzB,eAAe,CAChB,CAAC;IACF,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAClD,CAAC;IAED,+BAA+B;IAC/B,MAAM,UAAU,GAAG,UAAU,CAAC,cAAc,CAAC,YAAY,EAAE,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACpF,MAAM,YAAY,GAAG,UAAU,CAAC,0BAA0B,CACxD,UAAU,CAAC,MAAM,EACjB,UAAU,CAAC,GAAG,EACd,OAAO,CAAC,GAAG,EAAE,CACd,CAAC;IAEF,uDAAuD;IACvD,MAAM,SAAS,GAAG,UAAU,CAAC,aAAa,CACxC,YAAY,CAAC,SAAS,EACtB,YAAY,CAAC,OAAO,CACrB,CAAC;IAEF,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,29 @@
1
+ import ts from "typescript";
2
+ import { TypicalConfig } from "./config.js";
3
+ export interface TransformContext {
4
+ ts: typeof ts;
5
+ factory: ts.NodeFactory;
6
+ context: ts.TransformationContext;
7
+ }
8
+ export declare class TypicalTransformer {
9
+ config: TypicalConfig;
10
+ private program;
11
+ private ts;
12
+ private typeValidators;
13
+ private typeStringifiers;
14
+ private typeParsers;
15
+ constructor(config?: TypicalConfig, program?: ts.Program, tsInstance?: typeof ts);
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>;
19
+ /**
20
+ * Transform a single source file with TypeScript AST
21
+ */
22
+ private transformSourceFile;
23
+ shouldTransformFile(fileName: string): boolean;
24
+ private addTypiaImport;
25
+ private getOrCreateValidator;
26
+ private getOrCreateStringifier;
27
+ private getOrCreateParser;
28
+ private createValidatorStatements;
29
+ }