@ddd-ts/freeze 0.0.42 → 0.0.43
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/dist/_virtual/_rolldown/runtime.js +29 -0
- package/dist/entrypoints/freeze-decorator.entrypoint.js +78 -0
- package/dist/entrypoints/freeze-decorator.entrypoint.mjs +77 -0
- package/dist/entrypoints/freeze-function.entrypoint.js +80 -0
- package/dist/entrypoints/freeze-function.entrypoint.mjs +79 -0
- package/dist/entrypoints/freeze.entrypoint.js +2 -0
- package/dist/entrypoints/freeze.entrypoint.mjs +4 -0
- package/dist/entrypoints/project.js +9 -0
- package/dist/entrypoints/project.mjs +8 -0
- package/dist/package.js +11 -0
- package/dist/package.mjs +5 -0
- package/dist/utils/explore-type.js +78 -0
- package/dist/utils/explore-type.mjs +76 -0
- package/dist/utils/get-pretty-type.js +27 -0
- package/dist/utils/get-pretty-type.mjs +26 -0
- package/package.json +11 -7
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
+
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
13
|
+
__defProp(to, key, {
|
|
14
|
+
get: ((k) => from[k]).bind(null, key),
|
|
15
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
23
|
+
value: mod,
|
|
24
|
+
enumerable: true
|
|
25
|
+
}) : target, mod));
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
|
|
29
|
+
exports.__toESM = __toESM;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
const require_runtime = require('../_virtual/_rolldown/runtime.js');
|
|
2
|
+
const require_explore_type = require('../utils/explore-type.js');
|
|
3
|
+
const require_project = require('./project.js');
|
|
4
|
+
const require_package = require('../package.js');
|
|
5
|
+
let ts_morph = require("ts-morph");
|
|
6
|
+
let node_path = require("node:path");
|
|
7
|
+
let node_fs = require("node:fs");
|
|
8
|
+
node_fs = require_runtime.__toESM(node_fs);
|
|
9
|
+
|
|
10
|
+
//#region src/entrypoints/freeze-decorator.entrypoint.ts
|
|
11
|
+
const cwd = process.cwd();
|
|
12
|
+
const decoratorFile = require_project.project.getSourceFile(`${__dirname}/../references/freeze.decorator.d.ts`);
|
|
13
|
+
if (!decoratorFile) throw new Error("The @Freeze decorator is not used in the project.");
|
|
14
|
+
const references = decoratorFile.getFunction("Freeze")?.findReferences();
|
|
15
|
+
if (!references) throw new Error("The @Freeze decorator is imported, but not used in the project.");
|
|
16
|
+
function lowercasefirstletter(str) {
|
|
17
|
+
return str.charAt(0).toLowerCase() + str.slice(1);
|
|
18
|
+
}
|
|
19
|
+
for (const ref of references) for (const refref of ref.getReferences()) {
|
|
20
|
+
const decorator = refref.getNode().getParent()?.getParent()?.asKind(ts_morph.ts.SyntaxKind.Decorator);
|
|
21
|
+
if (!decorator) continue;
|
|
22
|
+
const rpath = (0, node_path.relative)(cwd, decorator.getSourceFile().getFilePath());
|
|
23
|
+
const classDeclaration = decorator.getParentIfKind(ts_morph.ts.SyntaxKind.ClassDeclaration);
|
|
24
|
+
if (!classDeclaration) continue;
|
|
25
|
+
const typeParameter = decorator.getTypeArguments()[0];
|
|
26
|
+
if (typeParameter) {
|
|
27
|
+
console.log(`${classDeclaration.getName()}: Already frozen with <${typeParameter.getText()}>`);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const serializeProperty = classDeclaration.getType().getProperty("serialize");
|
|
31
|
+
if (!serializeProperty) {
|
|
32
|
+
console.log(`${rpath} - ${classDeclaration.getName()}: No serialize property`);
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
const serializeMethod = require_project.project.getTypeChecker().getTypeOfSymbolAtLocation(serializeProperty, classDeclaration).getCallSignatures()[0];
|
|
36
|
+
let serialized = serializeMethod.getReturnType();
|
|
37
|
+
if (serialized.getSymbol()?.getName() === "Promise") serialized = serialized.getTypeArguments()[0];
|
|
38
|
+
const version = serialized.getProperty("version")?.getTypeAtLocation(classDeclaration).getText();
|
|
39
|
+
if (!version || Number.isNaN(Number(version))) {
|
|
40
|
+
console.log(`${rpath} - ${classDeclaration.getName()}: No version property (or not a number) : ${version}`);
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
console.log(`${rpath} - ${classDeclaration.getName()}: Freezing with version ${version}`);
|
|
44
|
+
const other = /* @__PURE__ */ new Map();
|
|
45
|
+
const result = require_explore_type.exploreType(serialized.compilerType, require_project.project.getTypeChecker().compilerObject, other);
|
|
46
|
+
const type = serializeMethod.getParameters()[0].getTypeAtLocation(classDeclaration);
|
|
47
|
+
const symbol = type.getSymbol()?.getName();
|
|
48
|
+
const aliasSymbol = type.getAliasSymbol()?.getName();
|
|
49
|
+
let name$1;
|
|
50
|
+
if (symbol) {
|
|
51
|
+
name$1 = symbol;
|
|
52
|
+
console.log(`${rpath} - ${classDeclaration.getName()}: Using symbol ${symbol}`);
|
|
53
|
+
} else if (aliasSymbol) {
|
|
54
|
+
name$1 = aliasSymbol;
|
|
55
|
+
console.log(`${rpath} - ${classDeclaration.getName()}: Using aliasSymbol ${aliasSymbol}`);
|
|
56
|
+
}
|
|
57
|
+
if (!name$1) {
|
|
58
|
+
console.log(`${rpath} - ${classDeclaration.getName()}: Cannot find name of serialized type`);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const serializedName = `${name$1}Serialized${version}n`;
|
|
62
|
+
const serializedFilename = lowercasefirstletter(`${name$1}.serialized.${version}n`);
|
|
63
|
+
const directory = refref.getSourceFile().getDirectory();
|
|
64
|
+
decorator.getSourceFile().addImportDeclaration({
|
|
65
|
+
moduleSpecifier: `./${serializedFilename}`,
|
|
66
|
+
namedImports: [serializedName]
|
|
67
|
+
});
|
|
68
|
+
decorator.addTypeArgument(serializedName);
|
|
69
|
+
require_project.project.saveSync();
|
|
70
|
+
const output = [
|
|
71
|
+
`// Auto-generated by ${require_package.name}`,
|
|
72
|
+
...other.values(),
|
|
73
|
+
`export type ${serializedName} = ${result}`
|
|
74
|
+
].join("\n");
|
|
75
|
+
node_fs.default.writeFileSync(`${directory.getPath()}/${serializedFilename}.ts`, output);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
//#endregion
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { exploreType } from "../utils/explore-type.mjs";
|
|
2
|
+
import { project } from "./project.mjs";
|
|
3
|
+
import { name } from "../package.mjs";
|
|
4
|
+
import { ts } from "ts-morph";
|
|
5
|
+
import { relative } from "node:path";
|
|
6
|
+
import fs from "node:fs";
|
|
7
|
+
|
|
8
|
+
//#region src/entrypoints/freeze-decorator.entrypoint.ts
|
|
9
|
+
const cwd = process.cwd();
|
|
10
|
+
const decoratorFile = project.getSourceFile(`${__dirname}/../references/freeze.decorator.d.ts`);
|
|
11
|
+
if (!decoratorFile) throw new Error("The @Freeze decorator is not used in the project.");
|
|
12
|
+
const references = decoratorFile.getFunction("Freeze")?.findReferences();
|
|
13
|
+
if (!references) throw new Error("The @Freeze decorator is imported, but not used in the project.");
|
|
14
|
+
function lowercasefirstletter(str) {
|
|
15
|
+
return str.charAt(0).toLowerCase() + str.slice(1);
|
|
16
|
+
}
|
|
17
|
+
for (const ref of references) for (const refref of ref.getReferences()) {
|
|
18
|
+
const decorator = refref.getNode().getParent()?.getParent()?.asKind(ts.SyntaxKind.Decorator);
|
|
19
|
+
if (!decorator) continue;
|
|
20
|
+
const rpath = relative(cwd, decorator.getSourceFile().getFilePath());
|
|
21
|
+
const classDeclaration = decorator.getParentIfKind(ts.SyntaxKind.ClassDeclaration);
|
|
22
|
+
if (!classDeclaration) continue;
|
|
23
|
+
const typeParameter = decorator.getTypeArguments()[0];
|
|
24
|
+
if (typeParameter) {
|
|
25
|
+
console.log(`${classDeclaration.getName()}: Already frozen with <${typeParameter.getText()}>`);
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
const serializeProperty = classDeclaration.getType().getProperty("serialize");
|
|
29
|
+
if (!serializeProperty) {
|
|
30
|
+
console.log(`${rpath} - ${classDeclaration.getName()}: No serialize property`);
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
const serializeMethod = project.getTypeChecker().getTypeOfSymbolAtLocation(serializeProperty, classDeclaration).getCallSignatures()[0];
|
|
34
|
+
let serialized = serializeMethod.getReturnType();
|
|
35
|
+
if (serialized.getSymbol()?.getName() === "Promise") serialized = serialized.getTypeArguments()[0];
|
|
36
|
+
const version = serialized.getProperty("version")?.getTypeAtLocation(classDeclaration).getText();
|
|
37
|
+
if (!version || Number.isNaN(Number(version))) {
|
|
38
|
+
console.log(`${rpath} - ${classDeclaration.getName()}: No version property (or not a number) : ${version}`);
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
console.log(`${rpath} - ${classDeclaration.getName()}: Freezing with version ${version}`);
|
|
42
|
+
const other = /* @__PURE__ */ new Map();
|
|
43
|
+
const result = exploreType(serialized.compilerType, project.getTypeChecker().compilerObject, other);
|
|
44
|
+
const type = serializeMethod.getParameters()[0].getTypeAtLocation(classDeclaration);
|
|
45
|
+
const symbol = type.getSymbol()?.getName();
|
|
46
|
+
const aliasSymbol = type.getAliasSymbol()?.getName();
|
|
47
|
+
let name$1;
|
|
48
|
+
if (symbol) {
|
|
49
|
+
name$1 = symbol;
|
|
50
|
+
console.log(`${rpath} - ${classDeclaration.getName()}: Using symbol ${symbol}`);
|
|
51
|
+
} else if (aliasSymbol) {
|
|
52
|
+
name$1 = aliasSymbol;
|
|
53
|
+
console.log(`${rpath} - ${classDeclaration.getName()}: Using aliasSymbol ${aliasSymbol}`);
|
|
54
|
+
}
|
|
55
|
+
if (!name$1) {
|
|
56
|
+
console.log(`${rpath} - ${classDeclaration.getName()}: Cannot find name of serialized type`);
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
const serializedName = `${name$1}Serialized${version}n`;
|
|
60
|
+
const serializedFilename = lowercasefirstletter(`${name$1}.serialized.${version}n`);
|
|
61
|
+
const directory = refref.getSourceFile().getDirectory();
|
|
62
|
+
decorator.getSourceFile().addImportDeclaration({
|
|
63
|
+
moduleSpecifier: `./${serializedFilename}`,
|
|
64
|
+
namedImports: [serializedName]
|
|
65
|
+
});
|
|
66
|
+
decorator.addTypeArgument(serializedName);
|
|
67
|
+
project.saveSync();
|
|
68
|
+
const output = [
|
|
69
|
+
`// Auto-generated by ${name}`,
|
|
70
|
+
...other.values(),
|
|
71
|
+
`export type ${serializedName} = ${result}`
|
|
72
|
+
].join("\n");
|
|
73
|
+
fs.writeFileSync(`${directory.getPath()}/${serializedFilename}.ts`, output);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
//#endregion
|
|
77
|
+
export { };
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
const require_runtime = require('../_virtual/_rolldown/runtime.js');
|
|
2
|
+
const require_explore_type = require('../utils/explore-type.js');
|
|
3
|
+
const require_project = require('./project.js');
|
|
4
|
+
const require_package = require('../package.js');
|
|
5
|
+
const require_get_pretty_type = require('../utils/get-pretty-type.js');
|
|
6
|
+
let ts_morph = require("ts-morph");
|
|
7
|
+
let node_path = require("node:path");
|
|
8
|
+
let node_fs = require("node:fs");
|
|
9
|
+
node_fs = require_runtime.__toESM(node_fs);
|
|
10
|
+
|
|
11
|
+
//#region src/entrypoints/freeze-function.entrypoint.ts
|
|
12
|
+
const cwd = process.cwd();
|
|
13
|
+
const functionFile = require_project.project.getSourceFile(`${__dirname}/../references/freeze.function.d.ts`);
|
|
14
|
+
if (!functionFile) throw new Error("The freeze function is not used in the project.");
|
|
15
|
+
const references = functionFile.getFunction("freeze")?.findReferences();
|
|
16
|
+
if (!references) throw new Error("The freeze function is imported, but not used in the project.");
|
|
17
|
+
function lowercasefirstletter(str) {
|
|
18
|
+
return str.charAt(0).toLowerCase() + str.slice(1);
|
|
19
|
+
}
|
|
20
|
+
for (const ref of references) for (const refref of ref.getReferences()) {
|
|
21
|
+
const callExpression = refref.getNode().getParentIfKind(ts_morph.ts.SyntaxKind.CallExpression);
|
|
22
|
+
if (!callExpression) continue;
|
|
23
|
+
const rpath = (0, node_path.relative)(cwd, callExpression.getSourceFile().getFilePath());
|
|
24
|
+
const typeArguments = callExpression.getTypeArguments();
|
|
25
|
+
const freezeParameters = typeArguments[0].asKind(ts_morph.ts.SyntaxKind.TypeLiteral);
|
|
26
|
+
const alreadyFrozen = typeArguments[1];
|
|
27
|
+
if (!freezeParameters) {
|
|
28
|
+
console.log(`${rpath}:${callExpression.getStartLineNumber()}: No freeze parameters`);
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
const nameProperty = freezeParameters.getProperty("name");
|
|
32
|
+
if (!nameProperty) {
|
|
33
|
+
console.log(`${rpath}:${callExpression.getStartLineNumber()}: No name property`);
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const name$1 = nameProperty.getType().getLiteralValue();
|
|
37
|
+
if (typeof name$1 !== "string") {
|
|
38
|
+
console.log(`${rpath}:${callExpression.getStartLineNumber()}: Name is not a string literal`);
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (alreadyFrozen) {
|
|
42
|
+
console.log(`${rpath} - ${name$1}: Already frozen with <${alreadyFrozen.getText()}>`);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const typeProperty = freezeParameters.getProperty("type");
|
|
46
|
+
if (!typeProperty) {
|
|
47
|
+
console.log(`${rpath} - ${name$1}: No type property`);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
const prettyType = require_get_pretty_type.getPrettyType(typeProperty.getType(), callExpression);
|
|
51
|
+
const other = /* @__PURE__ */ new Map();
|
|
52
|
+
let result = require_explore_type.exploreType(prettyType.type.compilerType, require_project.project.getTypeChecker().compilerObject, other);
|
|
53
|
+
const aliasName = prettyType.alias.getName();
|
|
54
|
+
prettyType.dispose();
|
|
55
|
+
for (const [key, value] of other) {
|
|
56
|
+
if (key.name !== aliasName) continue;
|
|
57
|
+
result = result.replace(new RegExp(`\\b${aliasName}\\b`, "g"), value.replace(new RegExp(`^type ${aliasName} = `), ""));
|
|
58
|
+
other.delete(key);
|
|
59
|
+
}
|
|
60
|
+
const serializedName = name$1;
|
|
61
|
+
const filenamePropertyValue = freezeParameters.getProperty("filename")?.getType().getLiteralValue();
|
|
62
|
+
const serializedExtension = freezeParameters.getProperty("extension")?.getType().getLiteralValue() ?? ".serialized";
|
|
63
|
+
const serializedFilename = filenamePropertyValue ?? lowercasefirstletter(`${serializedName}${serializedExtension}`);
|
|
64
|
+
const directory = refref.getSourceFile().getDirectory();
|
|
65
|
+
callExpression.getSourceFile().addImportDeclaration({
|
|
66
|
+
moduleSpecifier: `./${serializedFilename}`,
|
|
67
|
+
namedImports: [serializedName]
|
|
68
|
+
});
|
|
69
|
+
callExpression.addTypeArgument(serializedName);
|
|
70
|
+
require_project.project.saveSync();
|
|
71
|
+
const output = [
|
|
72
|
+
`// Auto-generated by ${require_package.name}`,
|
|
73
|
+
...other.values(),
|
|
74
|
+
`export type ${serializedName} = ${result}`
|
|
75
|
+
].join("\n");
|
|
76
|
+
node_fs.default.writeFileSync(`${directory.getPath()}/${serializedFilename}.ts`, output);
|
|
77
|
+
console.log(`${rpath} - ${name$1}: Frozen as ${serializedName} in ${serializedFilename}.ts`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
//#endregion
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { exploreType } from "../utils/explore-type.mjs";
|
|
2
|
+
import { project } from "./project.mjs";
|
|
3
|
+
import { name } from "../package.mjs";
|
|
4
|
+
import { getPrettyType } from "../utils/get-pretty-type.mjs";
|
|
5
|
+
import { ts } from "ts-morph";
|
|
6
|
+
import { relative } from "node:path";
|
|
7
|
+
import fs from "node:fs";
|
|
8
|
+
|
|
9
|
+
//#region src/entrypoints/freeze-function.entrypoint.ts
|
|
10
|
+
const cwd = process.cwd();
|
|
11
|
+
const functionFile = project.getSourceFile(`${__dirname}/../references/freeze.function.d.ts`);
|
|
12
|
+
if (!functionFile) throw new Error("The freeze function is not used in the project.");
|
|
13
|
+
const references = functionFile.getFunction("freeze")?.findReferences();
|
|
14
|
+
if (!references) throw new Error("The freeze function is imported, but not used in the project.");
|
|
15
|
+
function lowercasefirstletter(str) {
|
|
16
|
+
return str.charAt(0).toLowerCase() + str.slice(1);
|
|
17
|
+
}
|
|
18
|
+
for (const ref of references) for (const refref of ref.getReferences()) {
|
|
19
|
+
const callExpression = refref.getNode().getParentIfKind(ts.SyntaxKind.CallExpression);
|
|
20
|
+
if (!callExpression) continue;
|
|
21
|
+
const rpath = relative(cwd, callExpression.getSourceFile().getFilePath());
|
|
22
|
+
const typeArguments = callExpression.getTypeArguments();
|
|
23
|
+
const freezeParameters = typeArguments[0].asKind(ts.SyntaxKind.TypeLiteral);
|
|
24
|
+
const alreadyFrozen = typeArguments[1];
|
|
25
|
+
if (!freezeParameters) {
|
|
26
|
+
console.log(`${rpath}:${callExpression.getStartLineNumber()}: No freeze parameters`);
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const nameProperty = freezeParameters.getProperty("name");
|
|
30
|
+
if (!nameProperty) {
|
|
31
|
+
console.log(`${rpath}:${callExpression.getStartLineNumber()}: No name property`);
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const name$1 = nameProperty.getType().getLiteralValue();
|
|
35
|
+
if (typeof name$1 !== "string") {
|
|
36
|
+
console.log(`${rpath}:${callExpression.getStartLineNumber()}: Name is not a string literal`);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (alreadyFrozen) {
|
|
40
|
+
console.log(`${rpath} - ${name$1}: Already frozen with <${alreadyFrozen.getText()}>`);
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
const typeProperty = freezeParameters.getProperty("type");
|
|
44
|
+
if (!typeProperty) {
|
|
45
|
+
console.log(`${rpath} - ${name$1}: No type property`);
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
const prettyType = getPrettyType(typeProperty.getType(), callExpression);
|
|
49
|
+
const other = /* @__PURE__ */ new Map();
|
|
50
|
+
let result = exploreType(prettyType.type.compilerType, project.getTypeChecker().compilerObject, other);
|
|
51
|
+
const aliasName = prettyType.alias.getName();
|
|
52
|
+
prettyType.dispose();
|
|
53
|
+
for (const [key, value] of other) {
|
|
54
|
+
if (key.name !== aliasName) continue;
|
|
55
|
+
result = result.replace(new RegExp(`\\b${aliasName}\\b`, "g"), value.replace(new RegExp(`^type ${aliasName} = `), ""));
|
|
56
|
+
other.delete(key);
|
|
57
|
+
}
|
|
58
|
+
const serializedName = name$1;
|
|
59
|
+
const filenamePropertyValue = freezeParameters.getProperty("filename")?.getType().getLiteralValue();
|
|
60
|
+
const serializedExtension = freezeParameters.getProperty("extension")?.getType().getLiteralValue() ?? ".serialized";
|
|
61
|
+
const serializedFilename = filenamePropertyValue ?? lowercasefirstletter(`${serializedName}${serializedExtension}`);
|
|
62
|
+
const directory = refref.getSourceFile().getDirectory();
|
|
63
|
+
callExpression.getSourceFile().addImportDeclaration({
|
|
64
|
+
moduleSpecifier: `./${serializedFilename}`,
|
|
65
|
+
namedImports: [serializedName]
|
|
66
|
+
});
|
|
67
|
+
callExpression.addTypeArgument(serializedName);
|
|
68
|
+
project.saveSync();
|
|
69
|
+
const output = [
|
|
70
|
+
`// Auto-generated by ${name}`,
|
|
71
|
+
...other.values(),
|
|
72
|
+
`export type ${serializedName} = ${result}`
|
|
73
|
+
].join("\n");
|
|
74
|
+
fs.writeFileSync(`${directory.getPath()}/${serializedFilename}.ts`, output);
|
|
75
|
+
console.log(`${rpath} - ${name$1}: Frozen as ${serializedName} in ${serializedFilename}.ts`);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
//#endregion
|
|
79
|
+
export { };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
const require_runtime = require('../_virtual/_rolldown/runtime.js');
|
|
2
|
+
let ts_morph = require("ts-morph");
|
|
3
|
+
|
|
4
|
+
//#region src/entrypoints/project.ts
|
|
5
|
+
const tsConfigFilePath = `${process.cwd()}/tsconfig.json`;
|
|
6
|
+
const project = new ts_morph.Project({ tsConfigFilePath });
|
|
7
|
+
|
|
8
|
+
//#endregion
|
|
9
|
+
exports.project = project;
|
package/dist/package.js
ADDED
package/dist/package.mjs
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
const require_runtime = require('../_virtual/_rolldown/runtime.js');
|
|
2
|
+
let typescript = require("typescript");
|
|
3
|
+
typescript = require_runtime.__toESM(typescript);
|
|
4
|
+
|
|
5
|
+
//#region src/utils/explore-type.ts
|
|
6
|
+
function exploreType(type, checker, declarations = /* @__PURE__ */ new Map(), seen = new Set(["Date", "Record"])) {
|
|
7
|
+
if (type.aliasSymbol && seen.has(type.aliasSymbol.getName())) {
|
|
8
|
+
const a = type.aliasTypeArguments;
|
|
9
|
+
return `${type.aliasSymbol.name}${a ? `<${a.map((a) => exploreType(a, checker, declarations, seen)).join(", ")}>` : ""}`;
|
|
10
|
+
}
|
|
11
|
+
if (type.aliasSymbol) {
|
|
12
|
+
const aliasType = checker.getDeclaredTypeOfSymbol(type.aliasSymbol);
|
|
13
|
+
seen.add(type.aliasSymbol.getName());
|
|
14
|
+
const definition = exploreNativeType(aliasType, checker, declarations, seen);
|
|
15
|
+
declarations.set(type.aliasSymbol, `type ${type.aliasSymbol.name} = ${definition}`);
|
|
16
|
+
return exploreType(aliasType, checker, declarations, seen);
|
|
17
|
+
}
|
|
18
|
+
return exploreNativeType(type, checker, declarations, seen);
|
|
19
|
+
}
|
|
20
|
+
const PrimitiveFlag = 402784252;
|
|
21
|
+
function exploreNativeType(type, checker, declarations = /* @__PURE__ */ new Map(), seen = /* @__PURE__ */ new Set()) {
|
|
22
|
+
if (type.flags & typescript.TypeFlags.EnumLiteral) {
|
|
23
|
+
const v = type.value;
|
|
24
|
+
if (typeof v === "string") return `"${v}"`;
|
|
25
|
+
return v;
|
|
26
|
+
}
|
|
27
|
+
if (type.flags & PrimitiveFlag) return checker.typeToString(type);
|
|
28
|
+
if (type.isUnionOrIntersection()) {
|
|
29
|
+
const operator = type.isUnion() ? "|" : "&";
|
|
30
|
+
return type.types.map((t) => exploreType(t, checker, declarations, seen)).join(` ${operator} `);
|
|
31
|
+
}
|
|
32
|
+
if (type.getSymbol()?.getName() === "ReadonlyArray") {
|
|
33
|
+
const typeReference = type;
|
|
34
|
+
const elementType = typeReference.typeArguments ? typeReference.typeArguments[0] : void 0;
|
|
35
|
+
return elementType ? `readonly (${exploreType(elementType, checker, declarations, seen)})[]` : "ReadonlyArray<any>";
|
|
36
|
+
}
|
|
37
|
+
if (checker.isTupleType(type)) return `[${(type.typeArguments || []).map((t) => exploreType(t, checker, declarations, seen)).join(", ")}]`;
|
|
38
|
+
if (checker.isArrayType(type)) {
|
|
39
|
+
const typeReference = type;
|
|
40
|
+
const elementType = typeReference.typeArguments ? typeReference.typeArguments[0] : void 0;
|
|
41
|
+
return elementType ? `(${exploreType(elementType, checker, declarations, seen)})[]` : "any[]";
|
|
42
|
+
}
|
|
43
|
+
if (type.aliasTypeArguments) {
|
|
44
|
+
const elementTypes = type.aliasTypeArguments || [];
|
|
45
|
+
return `${type.aliasSymbol?.name}<${elementTypes.map((t) => t.symbol.name).join(", ")}>`;
|
|
46
|
+
}
|
|
47
|
+
if (type.getSymbol()?.getName() === "Date") return "Date";
|
|
48
|
+
if (type.flags & typescript.TypeFlags.Object) {
|
|
49
|
+
const properties = checker.getPropertiesOfType(type);
|
|
50
|
+
const indexInfos = checker.getIndexInfosOfType(type);
|
|
51
|
+
let index = "";
|
|
52
|
+
if (indexInfos.length > 0) {
|
|
53
|
+
const indexInfo = indexInfos[0];
|
|
54
|
+
const indexType = indexInfo.keyType;
|
|
55
|
+
const indexTypeString = exploreType(indexType, checker, declarations, seen);
|
|
56
|
+
const valueType = indexInfo.type;
|
|
57
|
+
index = `[key: ${indexTypeString}]: ${exploreType(valueType, checker, declarations, seen)}; `;
|
|
58
|
+
}
|
|
59
|
+
return `{ ${index}${properties.reduce((acc, property) => {
|
|
60
|
+
const propertyType = checker.getTypeOfSymbol(property);
|
|
61
|
+
const optional = property.flags & typescript.SymbolFlags.Optional ? "?" : "";
|
|
62
|
+
return `${acc}${property.getDeclarations()?.some((declaration) => typescript.isPropertySignature(declaration) && declaration.modifiers?.some((modifier) => modifier.kind === typescript.SyntaxKind.ReadonlyKeyword)) ? "readonly " : ""}${property.name}${optional}: ${exploreType(propertyType, checker, declarations, seen)}; `;
|
|
63
|
+
}, "")}}`;
|
|
64
|
+
}
|
|
65
|
+
if (type.flags & typescript.TypeFlags.TypeParameter) return type.symbol.name;
|
|
66
|
+
return JSON.stringify({
|
|
67
|
+
name: checker.typeToString(type),
|
|
68
|
+
flags: listTypeFlagsNames(type.flags)
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
function listTypeFlagsNames(flags) {
|
|
72
|
+
const names = [];
|
|
73
|
+
for (const flagName in typescript.TypeFlags) if (typescript.TypeFlags[flagName] & flags) names.push([flagName, typescript.TypeFlags[flagName]]);
|
|
74
|
+
return names;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
//#endregion
|
|
78
|
+
exports.exploreType = exploreType;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import * as ts from "typescript";
|
|
2
|
+
|
|
3
|
+
//#region src/utils/explore-type.ts
|
|
4
|
+
function exploreType(type, checker, declarations = /* @__PURE__ */ new Map(), seen = new Set(["Date", "Record"])) {
|
|
5
|
+
if (type.aliasSymbol && seen.has(type.aliasSymbol.getName())) {
|
|
6
|
+
const a = type.aliasTypeArguments;
|
|
7
|
+
return `${type.aliasSymbol.name}${a ? `<${a.map((a) => exploreType(a, checker, declarations, seen)).join(", ")}>` : ""}`;
|
|
8
|
+
}
|
|
9
|
+
if (type.aliasSymbol) {
|
|
10
|
+
const aliasType = checker.getDeclaredTypeOfSymbol(type.aliasSymbol);
|
|
11
|
+
seen.add(type.aliasSymbol.getName());
|
|
12
|
+
const definition = exploreNativeType(aliasType, checker, declarations, seen);
|
|
13
|
+
declarations.set(type.aliasSymbol, `type ${type.aliasSymbol.name} = ${definition}`);
|
|
14
|
+
return exploreType(aliasType, checker, declarations, seen);
|
|
15
|
+
}
|
|
16
|
+
return exploreNativeType(type, checker, declarations, seen);
|
|
17
|
+
}
|
|
18
|
+
const PrimitiveFlag = 402784252;
|
|
19
|
+
function exploreNativeType(type, checker, declarations = /* @__PURE__ */ new Map(), seen = /* @__PURE__ */ new Set()) {
|
|
20
|
+
if (type.flags & ts.TypeFlags.EnumLiteral) {
|
|
21
|
+
const v = type.value;
|
|
22
|
+
if (typeof v === "string") return `"${v}"`;
|
|
23
|
+
return v;
|
|
24
|
+
}
|
|
25
|
+
if (type.flags & PrimitiveFlag) return checker.typeToString(type);
|
|
26
|
+
if (type.isUnionOrIntersection()) {
|
|
27
|
+
const operator = type.isUnion() ? "|" : "&";
|
|
28
|
+
return type.types.map((t) => exploreType(t, checker, declarations, seen)).join(` ${operator} `);
|
|
29
|
+
}
|
|
30
|
+
if (type.getSymbol()?.getName() === "ReadonlyArray") {
|
|
31
|
+
const typeReference = type;
|
|
32
|
+
const elementType = typeReference.typeArguments ? typeReference.typeArguments[0] : void 0;
|
|
33
|
+
return elementType ? `readonly (${exploreType(elementType, checker, declarations, seen)})[]` : "ReadonlyArray<any>";
|
|
34
|
+
}
|
|
35
|
+
if (checker.isTupleType(type)) return `[${(type.typeArguments || []).map((t) => exploreType(t, checker, declarations, seen)).join(", ")}]`;
|
|
36
|
+
if (checker.isArrayType(type)) {
|
|
37
|
+
const typeReference = type;
|
|
38
|
+
const elementType = typeReference.typeArguments ? typeReference.typeArguments[0] : void 0;
|
|
39
|
+
return elementType ? `(${exploreType(elementType, checker, declarations, seen)})[]` : "any[]";
|
|
40
|
+
}
|
|
41
|
+
if (type.aliasTypeArguments) {
|
|
42
|
+
const elementTypes = type.aliasTypeArguments || [];
|
|
43
|
+
return `${type.aliasSymbol?.name}<${elementTypes.map((t) => t.symbol.name).join(", ")}>`;
|
|
44
|
+
}
|
|
45
|
+
if (type.getSymbol()?.getName() === "Date") return "Date";
|
|
46
|
+
if (type.flags & ts.TypeFlags.Object) {
|
|
47
|
+
const properties = checker.getPropertiesOfType(type);
|
|
48
|
+
const indexInfos = checker.getIndexInfosOfType(type);
|
|
49
|
+
let index = "";
|
|
50
|
+
if (indexInfos.length > 0) {
|
|
51
|
+
const indexInfo = indexInfos[0];
|
|
52
|
+
const indexType = indexInfo.keyType;
|
|
53
|
+
const indexTypeString = exploreType(indexType, checker, declarations, seen);
|
|
54
|
+
const valueType = indexInfo.type;
|
|
55
|
+
index = `[key: ${indexTypeString}]: ${exploreType(valueType, checker, declarations, seen)}; `;
|
|
56
|
+
}
|
|
57
|
+
return `{ ${index}${properties.reduce((acc, property) => {
|
|
58
|
+
const propertyType = checker.getTypeOfSymbol(property);
|
|
59
|
+
const optional = property.flags & ts.SymbolFlags.Optional ? "?" : "";
|
|
60
|
+
return `${acc}${property.getDeclarations()?.some((declaration) => ts.isPropertySignature(declaration) && declaration.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.ReadonlyKeyword)) ? "readonly " : ""}${property.name}${optional}: ${exploreType(propertyType, checker, declarations, seen)}; `;
|
|
61
|
+
}, "")}}`;
|
|
62
|
+
}
|
|
63
|
+
if (type.flags & ts.TypeFlags.TypeParameter) return type.symbol.name;
|
|
64
|
+
return JSON.stringify({
|
|
65
|
+
name: checker.typeToString(type),
|
|
66
|
+
flags: listTypeFlagsNames(type.flags)
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
function listTypeFlagsNames(flags) {
|
|
70
|
+
const names = [];
|
|
71
|
+
for (const flagName in ts.TypeFlags) if (ts.TypeFlags[flagName] & flags) names.push([flagName, ts.TypeFlags[flagName]]);
|
|
72
|
+
return names;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
//#endregion
|
|
76
|
+
export { exploreType };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const require_runtime = require('../_virtual/_rolldown/runtime.js');
|
|
2
|
+
let ts_morph = require("ts-morph");
|
|
3
|
+
|
|
4
|
+
//#region src/utils/get-pretty-type.ts
|
|
5
|
+
function getPrettyType(type, contextNode) {
|
|
6
|
+
const project = contextNode.getProject();
|
|
7
|
+
const typeTextForEmbedding = project.getTypeChecker().compilerObject.typeToString(type.compilerType, contextNode.compilerNode, ts_morph.ts.TypeFormatFlags.NoTruncation | ts_morph.ts.TypeFormatFlags.UseFullyQualifiedType | ts_morph.ts.TypeFormatFlags.InTypeAlias);
|
|
8
|
+
const fileName = `__pretty_${Date.now()}_${Math.random().toString(16).slice(2)}.ts`;
|
|
9
|
+
const sf = project.createSourceFile(fileName, `
|
|
10
|
+
type Pretty<T> = { [K in keyof T]: T[K] } & {};
|
|
11
|
+
declare const __v: ${typeTextForEmbedding};
|
|
12
|
+
export type __X = Pretty<typeof __v>;
|
|
13
|
+
`, { overwrite: true });
|
|
14
|
+
const alias = sf.getTypeAliasOrThrow("__X");
|
|
15
|
+
const pretty = alias.getType();
|
|
16
|
+
const dispose = () => {
|
|
17
|
+
project.removeSourceFile(sf);
|
|
18
|
+
};
|
|
19
|
+
return {
|
|
20
|
+
type: pretty,
|
|
21
|
+
alias,
|
|
22
|
+
dispose
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
//#endregion
|
|
27
|
+
exports.getPrettyType = getPrettyType;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Project, ts } from "ts-morph";
|
|
2
|
+
|
|
3
|
+
//#region src/utils/get-pretty-type.ts
|
|
4
|
+
function getPrettyType(type, contextNode) {
|
|
5
|
+
const project = contextNode.getProject();
|
|
6
|
+
const typeTextForEmbedding = project.getTypeChecker().compilerObject.typeToString(type.compilerType, contextNode.compilerNode, ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.UseFullyQualifiedType | ts.TypeFormatFlags.InTypeAlias);
|
|
7
|
+
const fileName = `__pretty_${Date.now()}_${Math.random().toString(16).slice(2)}.ts`;
|
|
8
|
+
const sf = project.createSourceFile(fileName, `
|
|
9
|
+
type Pretty<T> = { [K in keyof T]: T[K] } & {};
|
|
10
|
+
declare const __v: ${typeTextForEmbedding};
|
|
11
|
+
export type __X = Pretty<typeof __v>;
|
|
12
|
+
`, { overwrite: true });
|
|
13
|
+
const alias = sf.getTypeAliasOrThrow("__X");
|
|
14
|
+
const pretty = alias.getType();
|
|
15
|
+
const dispose = () => {
|
|
16
|
+
project.removeSourceFile(sf);
|
|
17
|
+
};
|
|
18
|
+
return {
|
|
19
|
+
type: pretty,
|
|
20
|
+
alias,
|
|
21
|
+
dispose
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
//#endregion
|
|
26
|
+
export { getPrettyType };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ddd-ts/freeze",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.43",
|
|
4
4
|
"types": "dist/index.d.ts",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -17,13 +17,13 @@
|
|
|
17
17
|
"typescript": "^5.5.4"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@ddd-ts/core": "0.0.
|
|
21
|
-
"@ddd-ts/shape": "0.0.
|
|
22
|
-
"@ddd-ts/traits": "0.0.
|
|
23
|
-
"@ddd-ts/types": "0.0.
|
|
20
|
+
"@ddd-ts/core": "0.0.43",
|
|
21
|
+
"@ddd-ts/shape": "0.0.43",
|
|
22
|
+
"@ddd-ts/traits": "0.0.43",
|
|
23
|
+
"@ddd-ts/types": "0.0.43"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@ddd-ts/tools": "0.0.
|
|
26
|
+
"@ddd-ts/tools": "0.0.43",
|
|
27
27
|
"@types/jest": "^29.5.1",
|
|
28
28
|
"@types/node": "^17.0.13"
|
|
29
29
|
},
|
|
@@ -32,12 +32,16 @@
|
|
|
32
32
|
"import": "./dist/index.mjs",
|
|
33
33
|
"require": "./dist/index.js"
|
|
34
34
|
},
|
|
35
|
+
"./entrypoints/freeze.entrypoint": {
|
|
36
|
+
"import": "./dist/entrypoints/freeze.entrypoint.mjs",
|
|
37
|
+
"require": "./dist/entrypoints/freeze.entrypoint.js"
|
|
38
|
+
},
|
|
35
39
|
"./package.json": "./package.json"
|
|
36
40
|
},
|
|
37
41
|
"main": "./dist/index.js",
|
|
38
42
|
"module": "./dist/index.mjs",
|
|
39
43
|
"scripts": {
|
|
40
|
-
"build": "tsdown --config node_modules/@ddd-ts/tools/tsdown.config.js",
|
|
44
|
+
"build": "tsdown --config node_modules/@ddd-ts/tools/tsdown.config.js src/index.ts src/entrypoints/freeze.entrypoint.ts",
|
|
41
45
|
"test": "jest --config node_modules/@ddd-ts/tools/jest.config.js"
|
|
42
46
|
}
|
|
43
47
|
}
|