@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.
- package/README.md +82 -0
- package/bin/ttsc +12 -0
- package/bin/ttsx +3 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +89 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/config.d.ts +7 -0
- package/dist/src/config.js +26 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/esm-loader-register.d.ts +1 -0
- package/dist/src/esm-loader-register.js +3 -0
- package/dist/src/esm-loader-register.js.map +1 -0
- package/dist/src/esm-loader.d.ts +4 -0
- package/dist/src/esm-loader.js +25 -0
- package/dist/src/esm-loader.js.map +1 -0
- package/dist/src/file-filter.d.ts +13 -0
- package/dist/src/file-filter.js +38 -0
- package/dist/src/file-filter.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +3 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/setup.d.ts +2 -0
- package/dist/src/setup.js +14 -0
- package/dist/src/setup.js.map +1 -0
- package/dist/src/transformer.d.ts +29 -0
- package/dist/src/transformer.js +472 -0
- package/dist/src/transformer.js.map +1 -0
- package/dist/src/tsc-plugin.d.ts +3 -0
- package/dist/src/tsc-plugin.js +9 -0
- package/dist/src/tsc-plugin.js.map +1 -0
- package/package.json +71 -0
- package/src/cli.ts +111 -0
- package/src/config.ts +35 -0
- package/src/esm-loader-register.ts +2 -0
- package/src/esm-loader.ts +26 -0
- package/src/file-filter.ts +44 -0
- package/src/index.ts +2 -0
- package/src/patch-fs.cjs +25 -0
- package/src/patch-tsconfig.cjs +52 -0
- package/src/setup.ts +29 -0
- package/src/transformer.ts +831 -0
- 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
package/dist/src/cli.js
ADDED
|
@@ -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,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 @@
|
|
|
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,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 @@
|
|
|
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,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
|
+
}
|