@eliasku/ts-transformers 0.0.8 → 0.0.10

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
@@ -3,7 +3,7 @@
3
3
 
4
4
  # @eliasku/ts-transformers
5
5
 
6
- TypeScript transformer for aggressive code minification through type-aware property renaming and const enum inlining.
6
+ TypeScript transformer for aggressive code minification through type-aware property renaming.
7
7
 
8
8
  ## Important Requirement
9
9
 
@@ -24,7 +24,7 @@ Two-phase optimization pipeline:
24
24
 
25
25
  Based on type analysis, properties are categorized as:
26
26
 
27
- - **Public (External)**: Exported from entry points → **no prefix** (preserved)
27
+ - **Public**: Exported from entry points → **no prefix** (preserved)
28
28
  - **Private**: Everything else → prefixed with `$_` (mangled by minifier)
29
29
 
30
30
  **Example:**
@@ -52,23 +52,7 @@ class A{publicApi(){},a(){},b=1}
52
52
 
53
53
  ### Const Enum Inlining
54
54
 
55
- Replaces const enum accesses with literal values and transforms declarations to remove codegen, but keep symbol to preserve default import/export flow.
56
-
57
- ```typescript
58
- // Before
59
- const enum Status {
60
- Active = 1,
61
- Inactive = 0,
62
- }
63
- export const status = Status.Active;
64
-
65
- // After transformer
66
- export let Status: {};
67
- export const status = 1;
68
-
69
- // After minifier
70
- export const status=1;
71
- ```
55
+ TypeScript currently inlines const enums, if you use traditional compiler for production build. Check if you have option `isolatedModules: false` disabled in `tsconfig.json`.
72
56
 
73
57
  ## Usage
74
58
 
@@ -165,10 +149,6 @@ class AppComponent {
165
149
  }
166
150
  ```
167
151
 
168
- ### inlineConstEnums (optional, default: true)
169
-
170
- Inline const enum values and transform declarations to preserve export/import flow.
171
-
172
152
  ## Complete Example
173
153
 
174
154
  ```typescript
@@ -0,0 +1,33 @@
1
+ import ts from 'typescript';
2
+
3
+ interface OptimizerOptions {
4
+ /**
5
+ * An array of entry source files which will used to detect exported and internal fields.
6
+ * Basically it should be entry point(s) of the library/project.
7
+ * @example ['./src/index.ts']
8
+ */
9
+ entrySourceFiles: string[];
10
+ /**
11
+ * Prefix of generated names for private fields
12
+ * @example '_private_'
13
+ * @example '$_' // default
14
+ */
15
+ privatePrefix: string;
16
+ /**
17
+ * Comment which will treat a class/interface/type/property/etc and all its children as "public".
18
+ * Set it to empty string to disable using JSDoc comment to detecting "visibility level".
19
+ * @example 'public' // default
20
+ * @example 'external'
21
+ * @example ''
22
+ */
23
+ publicJSDocTag: string;
24
+ /**
25
+ * Whether fields that were decorated should be renamed.
26
+ * A field is treated as "decorated" if itself or any its parent (on type level) has a decorator.
27
+ */
28
+ ignoreDecorated: boolean;
29
+ }
30
+
31
+ declare const optimizer: (program: ts.Program, options?: Partial<OptimizerOptions>) => ts.TransformerFactory<ts.SourceFile>;
32
+
33
+ export { type OptimizerOptions, optimizer };
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ import e from"typescript";var t=(t,r)=>(t.flags&e.SymbolFlags.Alias&&(t=r.getAliasedSymbol(t)),t),r=(r,o)=>{if(0===(r.flags&e.SymbolFlags.Transient))return[r];const i=n(r),s=[];for(const e of i){if(!a(e)||void 0===e.name)continue;const r=o.getSymbolAtLocation(e.name);void 0!==r&&s.push(t(r,o))}return s},n=e=>{const t=[];return void 0!==e.declarations&&t.push(...e.declarations),void 0!==e.valueDeclaration&&(t.includes(e.valueDeclaration)||t.push(e.valueDeclaration)),t},o=(r,n)=>{if(void 0!==n.exports){const o=n.exports.get(e.InternalSymbolName.ExportEquals);if(void 0!==o)return[t(o,r)]}const o=r.getExportsOfModule(n);if(void 0!==n.exports){const t=n.exports.get(e.InternalSymbolName.Default);void 0!==t&&(o.includes(t)||o.push(t))}return o.map(e=>t(e,r))},i=[e.SyntaxKind.InterfaceDeclaration,e.SyntaxKind.ClassDeclaration,e.SyntaxKind.EnumDeclaration,e.SyntaxKind.TypeAliasDeclaration,e.SyntaxKind.ModuleDeclaration,e.SyntaxKind.FunctionDeclaration,e.SyntaxKind.VariableDeclaration,e.SyntaxKind.PropertySignature,e.SyntaxKind.Parameter],a=e=>-1!==i.indexOf(e.kind),s=t=>e.isMethodDeclaration(t)||e.isPropertyDeclaration(t)||e.isGetAccessor(t)||e.isSetAccessor(t),c=t=>l(t,e.SyntaxKind.PrivateKeyword),l=(t,r)=>(t=>d(e)?e.canHaveModifiers(t)&&e.getModifiers(t)||[]:t.modifiers||[])(t).some(e=>e.kind===r),p=t=>0!==(t=>d(e)?e.canHaveDecorators(t)&&e.getDecorators(t)||[]:t.decorators||[])(t).length,f=t=>e.isParameter(t)&&e.isConstructorDeclaration(t.parent)&&(l(t,e.SyntaxKind.PublicKeyword)||l(t,e.SyntaxKind.ProtectedKeyword)||l(t,e.SyntaxKind.PrivateKeyword)||l(t,e.SyntaxKind.ReadonlyKeyword)),u=e=>{if(void 0===e)return[];const t=e.getDeclarations();return void 0===t?[]:t.filter(e=>s(e)||f(e))},d=e=>"canHaveDecorators"in e,g=class{constructor(e,t){this.exportsTree=new Map,this.program=e,this.computeTreeForExports(t)}isSymbolAccessibleFromExports(e){e=this.getActualSymbol(e);for(const[,t]of this.exportsTree)if(t.has(e))return!0;return!1}computeTreeForExports(e){this.exportsTree.clear();const t=this.program.getTypeChecker();for(const r of e){const e=this.program.getSourceFile(r);if(void 0===e)throw new Error(`Cannot find source file ${r}`);const i=t.getSymbolAtLocation(e);if(void 0!==i)for(const e of o(t,i)){const t=new Set;this.exportsTree.set(e,t);for(const r of n(e))this.computeTreeForChildren(t,r,new Set)}}}computeTreeForChildren(r,o,i){if(e.isNamespaceExport(o)){const a=this.program.getTypeChecker(),s=a.getSymbolAtLocation(o.name);if(void 0!==s&&s.flags&e.SymbolFlags.Alias){const e=a.getAliasedSymbol(s),o=a.getExportsOfModule(e);if(o&&o.length>0)for(const e of o){const o=t(e,a);if(!i.has(o)){i.add(o),r.add(o);for(const e of n(o))this.computeTreeForChildren(r,e,i)}}else console.warn("[computeTreeForChildren] Could not get exports for aliased symbol")}return}if(e.isExportDeclaration(o)&&void 0!==o.exportClause&&e.isNamedExports(o.exportClause)){const a=this.program.getTypeChecker();for(const s of o.exportClause.elements){const o=a.getSymbolAtLocation(s.name);if(void 0!==o&&0!==(o.flags&e.SymbolFlags.Alias)){const s=a.getAliasedSymbol(o);if(0!==(s.flags&e.SymbolFlags.NamespaceModule)){const e=a.getExportsOfModule(s);for(const o of e){const e=t(o,a);if(!i.has(e)){i.add(e),r.add(e);for(const t of n(e))this.computeTreeForChildren(r,t,i)}}}}}}if(e.isVariableDeclaration(o)){const e=this.program.getTypeChecker().getTypeAtLocation(o).getSymbol();return void(void 0!==e&&r.add(e))}e.forEachChild(o,e=>this.computeTreeForNode(r,e,i))}computeTreeForNode(t,o,i){if(e.isVariableStatement(o))for(const e of o.declarationList.declarations)this.computeTreeForNode(t,e,i);else if(!(o.kind===e.SyntaxKind.JSDoc||e.isBlock(o)||s(o)&&c(o))){if(e.isIdentifier(o)){const e=this.getSymbol(o);if(null===e)return;if(i.has(e))return;i.add(e);for(const o of r(e,this.program.getTypeChecker())){t.add(o);for(const e of n(o))this.computeTreeForChildren(t,e,i)}}this.computeTreeForChildren(t,o,i)}}getSymbol(e){const t=this.program.getTypeChecker().getSymbolAtLocation(e);return void 0===t?null:this.getActualSymbol(t)}getActualSymbol(e){return t(e,this.program.getTypeChecker())}},m=e=>{const t=e.getStart(),r=e.getStart(void 0,!0);return e.getSourceFile().getFullText().substring(r,t).trim()},y={entrySourceFiles:[],privatePrefix:"$_",publicJSDocTag:"public",ignoreDecorated:!1},S=(t,o)=>{const i={...y,...o},d=t.getTypeChecker(),S=new g(t,i.entrySourceFiles),h=new Map,x=(e,t)=>(h.set(e,t),t);return o=>{const g=e=>{const t=e.parent,r=d.getTypeAtLocation(e);if(!r.isStringLiteral())throw new Error(`Can't get type for left expression in ${e.parent.getText()}`);const n=r.value;return M(d.getTypeAtLocation(t.right),n)?e:P(n,0,o.factory.createStringLiteral)},y=e=>K(e),b=e=>{const t=O(e);return 1===t?e:w(e,t,o.factory.createStringLiteral)},T=e=>K(e),A=e=>K(e),v=e=>K(e),F=e=>K(e),D=e=>K(e),E=e=>{const t=O(e.name);return 1===t?e:w(e.name,t,t=>o.factory.createPropertyAssignment(t,e.name))},C=t=>{if(!e.isIdentifier(t.name))return t;const r=O(t);return 1===r?t:w(t.name,r,e=>o.factory.createBindingElement(t.dotDotDotToken,e,t.name,t.initializer))},L=e=>K(e),K=e=>{const t=O(e);return 1===t?e:w(e,t,o.factory.createIdentifier)},w=(t,r,n)=>{const o=d.getSymbolAtLocation(t);if(void 0===o)throw new Error(`Cannot get symbol for node "${t.getText()}"`);const i=e.unescapeLeadingUnderscores(o.escapedName);return P(i,r,n)},P=(e,t,r)=>r(N(e)),N=e=>`${i.privatePrefix}${e}`,k=t=>(t.flags&e.SymbolFlags.Alias&&(t=d.getAliasedSymbol(t)),t),I=e=>{const t=d.getSymbolAtLocation(e);return void 0===t?null:k(t)},M=(t,o)=>{if(t.flags&e.TypeFlags.Unknown||t.flags&e.TypeFlags.Any)return!0;if(t.flags&e.TypeFlags.IndexedAccess)return M(d.getApparentType(t),o);const i=t.getSymbol(),a=d.getPropertyOfType(t,o);if(t.flags&e.TypeFlags.Object){const r=t;if(r.objectFlags&e.ObjectFlags.Tuple)return!0;if(r.objectFlags&e.ObjectFlags.Reference){const e=r.target;if(e!==r&&M(e,o))return!0}const s=void 0!==a&&0!==n(a).length;if(r.objectFlags&e.ObjectFlags.Mapped&&void 0!==i&&!s&&1===B(i))return!0}if(t.isUnionOrIntersection()){const e=t.types.some(e=>M(e,o));if(e)return e}if(void 0!==i){const t=n(i);for(const r of t)if((e.isClassDeclaration(r)||e.isInterfaceDeclaration(r))&&void 0!==r.heritageClauses){if(r.heritageClauses.some(e=>e.types.some(e=>M(d.getTypeAtLocation(e),o))))return!0}}return void 0!==a&&[a,...r(a,d)].some(e=>1===B(e))},O=t=>{if(e.isPropertyAssignment(t.parent)||e.isShorthandPropertyAssignment(t.parent)){let r=t.parent.parent,n=t.parent.parent,o=t.parent.parent.parent;for(;e.isParenthesizedExpression(o)||e.isAsExpression(o);)e.isAsExpression(o)&&(r=n,n=o),o=o.parent;const i=d.getContextualType(r);if(void 0!==i&&M(i,t.getText()))return 1}if(e.isPropertyAccessExpression(t.parent)||e.isElementAccessExpression(t.parent)){if(e.isIdentifier(t.parent.expression)){const r=d.getSymbolAtLocation(t.parent.expression);if(void 0!==r){const o=n(r);if(o.some(t=>e.isNamespaceImport(t)||e.isModuleDeclaration(t)))return 1;if(o.some(t=>e.isImportSpecifier(t))){const r=d.getTypeAtLocation(t.parent.expression);if(r){const t=r.getSymbol();if(t&&(0!==(t.flags&e.SymbolFlags.NamespaceModule)||0!==(t.flags&e.SymbolFlags.Module)))return 1}}}}const r=d.getTypeAtLocation(t.parent.expression),o=t.getText();if(M(r,o))return 1}if(e.isBindingElement(t)&&M(d.getTypeAtLocation(t.parent),t.getText()))return 1;if(e.isBindingElement(t.parent)&&M(d.getTypeAtLocation(t.parent.parent),t.getText()))return 1;if(e.isJsxAttribute(t.parent)){const e=d.getSymbolAtLocation(t.parent.parent.parent.tagName);if(void 0!==e&&void 0!==e.valueDeclaration){const r=d.getTypeOfSymbolAtLocation(e,e.valueDeclaration);if(M(r,t.getText()))return 1}}const r=I(t),o=null!==r?(e=>{const t=u(e);if(0!==t.length){const e=t[0];return f(e)?e.parent.parent:e.parent}return null})(r):null;if(null!==o&&M(d.getTypeAtLocation(o),t.getText()))return 1;const i=e.isBindingElement(t)?$(t):r;return null===i?1:B(i)},B=t=>{t=k(t);const r=h.get(t);if(void 0!==r)return r;const o=n(t);if(o.some(j))return x(t,1);if(o.some(t=>l(t,e.SyntaxKind.DeclareKeyword)))return x(t,1);if("prototype"===t.escapedName)return x(t,1);if(0!==i.publicJSDocTag.length||i.ignoreDecorated)for(const r of o){let n=r;for(;!e.isSourceFile(n);){if(0!==i.publicJSDocTag.length&&m(n).includes(`@${i.publicJSDocTag}`))return x(t,1);if(i.ignoreDecorated&&p(n))return x(t,1);if(e.isEnumDeclaration(n))return x(t,1);n=n.parent}}if(u(t).some(c))return x(t,0);if(S.isSymbolAccessibleFromExports(t))return x(t,1);for(const e of o){if(!a(e.parent)||void 0===e.parent.name)continue;const r=I(e.parent.name);if(null!==r&&1===B(r))return x(t,1)}return x(t,0)},$=t=>{if(void 0!==t.propertyName)throw new Error(`Cannot handle binding element with property name: ${t.getText()} in ${t.getSourceFile().fileName}`);if(!e.isIdentifier(t.name))return null;const r=d.getTypeAtLocation(t.parent);return r.isUnion()?null:r.getProperty(e.idText(t.name))||null},j=e=>{const r=e.getSourceFile();return r.isDeclarationFile||t.isSourceFileDefaultLibrary(r)||/[\\/]node_modules[\\/]/.test(r.fileName)},J=t=>{return!!e.isIdentifier(t)&&(r=d.getSymbolAtLocation(t),0!==u(r).length);var r},U=t=>e.visitEachChild((t=>{if(e.isShorthandPropertyAssignment(t))return E(t);if(e.isBindingElement(t)&&void 0===t.propertyName)return t.parent&&e.isObjectBindingPattern(t.parent)?C(t):t;if(t.parent&&e.isStringLiteral(t)&&e.isBinaryExpression(t.parent)&&t.parent.operatorToken.kind===e.SyntaxKind.InKeyword)return g(t);if(e.isIdentifier(t)&&t.parent){if(e.isPropertyAccessExpression(t.parent)&&t.parent.name===t)return y(t);if(s(t.parent)&&t.parent.name===t)return T(t);if(e.isEnumMember(t.parent)&&t.parent.name===t)return A(t);if(e.isPropertyAssignment(t.parent)&&t.parent.name===t)return D(t);if(e.isBindingElement(t.parent)&&t.parent.propertyName===t)return v(t);if(e.isJsxAttribute(t.parent)&&t.parent.name===t)return F(t);if(f(t.parent)&&t.parent.name===t||J(t))return L(t)}return t.parent&&e.isStringLiteral(t)&&e.isElementAccessExpression(t.parent)&&t.parent.argumentExpression===t?b(t):t})(t),U,o);return e=>U(e)}};export{S as optimizer};//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/symbol-utils.ts","../src/exports/tracker.ts","../src/utils/ast-utils.ts","../src/types.ts","../src/index.ts"],"names":["ts","getActualSymbol","expressionType"],"mappings":"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","file":"index.js","sourcesContent":["import ts from \"typescript\";\n\nexport const getActualSymbol = (symbol: ts.Symbol, typeChecker: ts.TypeChecker): ts.Symbol => {\n if (symbol.flags & ts.SymbolFlags.Alias) {\n symbol = typeChecker.getAliasedSymbol(symbol);\n }\n\n return symbol;\n};\n\nexport const splitTransientSymbol = (symbol: ts.Symbol, typeChecker: ts.TypeChecker): ts.Symbol[] => {\n // actually I think we even don't need to operate/use \"Transient\" symbols anywhere\n // it's kind of aliased symbol, but just merged\n // but it's hard to refractor everything to use array of symbols instead of just symbol\n // so let's fix it for some places\n if ((symbol.flags & ts.SymbolFlags.Transient) === 0) {\n return [symbol];\n }\n\n // \"Transient\" symbol is kinda \"merged\" symbol\n // I don't really know is this way to \"split\" is correct\n // but it seems that it works for now\n const declarations = getDeclarationsForSymbol(symbol);\n const result: ts.Symbol[] = [];\n for (const declaration of declarations) {\n if (!isNodeNamedDeclaration(declaration) || declaration.name === undefined) {\n continue;\n }\n\n const sym = typeChecker.getSymbolAtLocation(declaration.name);\n if (sym === undefined) {\n continue;\n }\n\n result.push(getActualSymbol(sym, typeChecker));\n }\n\n return result;\n};\n\nexport const getDeclarationsForSymbol = (symbol: ts.Symbol): ts.Declaration[] => {\n const result: ts.Declaration[] = [];\n\n if (symbol.declarations !== undefined) {\n result.push(...symbol.declarations);\n }\n\n if (symbol.valueDeclaration !== undefined) {\n // push valueDeclaration might be already in declarations array\n // so let's check first to avoid duplication nodes\n if (!result.includes(symbol.valueDeclaration)) {\n result.push(symbol.valueDeclaration);\n }\n }\n\n return result;\n};\n\nexport const getExportsForSourceFile = (typeChecker: ts.TypeChecker, sourceFileSymbol: ts.Symbol): ts.Symbol[] => {\n if (sourceFileSymbol.exports !== undefined) {\n const commonJsExport = sourceFileSymbol.exports.get(ts.InternalSymbolName.ExportEquals);\n if (commonJsExport !== undefined) {\n return [getActualSymbol(commonJsExport, typeChecker)];\n }\n }\n\n const result: ts.Symbol[] = typeChecker.getExportsOfModule(sourceFileSymbol);\n\n if (sourceFileSymbol.exports !== undefined) {\n const defaultExportSymbol = sourceFileSymbol.exports.get(ts.InternalSymbolName.Default);\n if (defaultExportSymbol !== undefined) {\n if (!result.includes(defaultExportSymbol)) {\n // it seems that default export is always returned by getExportsOfModule\n // but let's add it to be sure add if there is no such export\n result.push(defaultExportSymbol);\n }\n }\n }\n\n return result.map((symbol: ts.Symbol) => getActualSymbol(symbol, typeChecker));\n};\n\nconst namedDeclarationKinds = [\n ts.SyntaxKind.InterfaceDeclaration,\n ts.SyntaxKind.ClassDeclaration,\n ts.SyntaxKind.EnumDeclaration,\n ts.SyntaxKind.TypeAliasDeclaration,\n ts.SyntaxKind.ModuleDeclaration,\n ts.SyntaxKind.FunctionDeclaration,\n ts.SyntaxKind.VariableDeclaration,\n ts.SyntaxKind.PropertySignature,\n ts.SyntaxKind.Parameter,\n];\n\nexport const isNodeNamedDeclaration = (node: ts.Node): node is ts.NamedDeclaration =>\n namedDeclarationKinds.indexOf(node.kind) !== -1;\n\nexport type ClassMember =\n | ts.MethodDeclaration\n | ts.PropertyDeclaration\n | ts.GetAccessorDeclaration\n | ts.SetAccessorDeclaration;\n\nexport const isClassMember = (node: ts.Node): node is ClassMember =>\n ts.isMethodDeclaration(node) || ts.isPropertyDeclaration(node) || ts.isGetAccessor(node) || ts.isSetAccessor(node);\n\nexport const getClassOfMemberSymbol = (\n nodeSymbol: ts.Symbol,\n): ts.ClassLikeDeclaration | ts.ObjectLiteralExpression | ts.TypeLiteralNode | ts.InterfaceDeclaration | null => {\n const classMembers = getClassMemberDeclarations(nodeSymbol);\n if (classMembers.length !== 0) {\n // we need any member to get class' declaration\n const classMember = classMembers[0];\n if (isConstructorParameter(classMember)) {\n return (classMember.parent as ts.ConstructorDeclaration).parent;\n }\n\n // we're sure that it is a class, not interface\n return classMember.parent as ts.ClassLikeDeclaration | ts.ObjectLiteralExpression;\n }\n\n return null;\n};\n\nexport const hasPrivateKeyword = (node: ClassMember | ts.ParameterDeclaration): boolean =>\n hasModifier(node, ts.SyntaxKind.PrivateKeyword);\n\nconst getModifiers = (node: ts.Node): readonly ts.Modifier[] => {\n if (isBreakingTypeScriptApi(ts)) {\n if (!ts.canHaveModifiers(node)) {\n return [];\n }\n\n return ts.getModifiers(node) || [];\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return node.modifiers || [];\n};\n\nexport const hasModifier = (node: ts.Node, modifier: ts.SyntaxKind): boolean =>\n getModifiers(node).some((mod) => mod.kind === modifier);\n\nconst getDecorators = (node: ts.Node): readonly unknown[] => {\n if (isBreakingTypeScriptApi(ts)) {\n if (!ts.canHaveDecorators(node)) {\n return [];\n }\n\n return ts.getDecorators(node) || [];\n }\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return node.decorators || [];\n};\n\nexport const hasDecorators = (node: ts.Node): boolean => getDecorators(node).length !== 0;\n\nexport const isConstructorParameter = (node: ts.Node): node is ts.ParameterDeclaration =>\n ts.isParameter(node) &&\n ts.isConstructorDeclaration(node.parent as ts.Node) &&\n (hasModifier(node, ts.SyntaxKind.PublicKeyword) ||\n hasModifier(node, ts.SyntaxKind.ProtectedKeyword) ||\n hasModifier(node, ts.SyntaxKind.PrivateKeyword) ||\n hasModifier(node, ts.SyntaxKind.ReadonlyKeyword));\n\nconst getClassMemberDeclarations = (symbol: ts.Symbol | undefined): (ClassMember | ts.ParameterDeclaration)[] => {\n if (symbol === undefined) {\n return [];\n }\n\n const declarations = symbol.getDeclarations();\n if (declarations === undefined) {\n return [];\n }\n\n return declarations.filter((x: ts.Declaration): x is ClassMember | ts.ParameterDeclaration => {\n return isClassMember(x) || isConstructorParameter(x);\n });\n};\n\nexport const isSymbolClassMember = (symbol: ts.Symbol | undefined): boolean =>\n getClassMemberDeclarations(symbol).length !== 0;\n\nexport const isPrivateClassMember = (symbol: ts.Symbol | undefined): boolean =>\n getClassMemberDeclarations(symbol).some(hasPrivateKeyword);\n\n// decorators and modifiers-related api added in ts 4.8\ninterface BreakingTypeScriptApi {\n canHaveDecorators(node: ts.Node): boolean;\n getDecorators(node: ts.Node): readonly ts.Decorator[] | undefined;\n canHaveModifiers(node: ts.Node): boolean;\n getModifiers(node: ts.Node): readonly ts.Modifier[] | undefined;\n}\n\nconst isBreakingTypeScriptApi = (compiler: object): compiler is BreakingTypeScriptApi =>\n \"canHaveDecorators\" in compiler;\n","import ts from \"typescript\";\n\nimport {\n getActualSymbol,\n splitTransientSymbol,\n isClassMember,\n hasPrivateKeyword,\n getExportsForSourceFile,\n getDeclarationsForSymbol,\n} from \"../utils/symbol-utils\";\nimport { LOGS } from \"../config\";\n\nexport class ExportsSymbolTree {\n private readonly program: ts.Program;\n private readonly exportsTree = new Map<ts.Symbol, Set<ts.Symbol>>();\n\n constructor(program: ts.Program, entrySourceFiles: readonly string[]) {\n this.program = program;\n this.computeTreeForExports(entrySourceFiles);\n }\n\n isSymbolAccessibleFromExports(symbol: ts.Symbol): boolean {\n symbol = this.getActualSymbol(symbol);\n for (const [, set] of this.exportsTree) {\n if (set.has(symbol)) {\n return true;\n }\n }\n return false;\n }\n\n private computeTreeForExports(entrySourceFiles: readonly string[]): void {\n this.exportsTree.clear();\n\n const typeChecker = this.program.getTypeChecker();\n for (const filePath of entrySourceFiles) {\n const sourceFile = this.program.getSourceFile(filePath);\n if (sourceFile === undefined) {\n throw new Error(`Cannot find source file ${filePath}`);\n }\n\n const entrySourceFile = typeChecker.getSymbolAtLocation(sourceFile);\n if (entrySourceFile === undefined) {\n // if a source file doesn't have any export - then it doesn't have a symbol as well\n // so just skip it here\n continue;\n }\n\n if (LOGS) {\n console.log(`[ExportsSymbolTree] Processing entry file: ${filePath}`);\n }\n for (const entryExportSymbol of getExportsForSourceFile(typeChecker, entrySourceFile)) {\n if (LOGS) {\n console.log(`[ExportsSymbolTree] Export symbol: ${entryExportSymbol.escapedName}`);\n }\n const exportSymbolsSet = new Set<ts.Symbol>();\n this.exportsTree.set(entryExportSymbol, exportSymbolsSet);\n\n for (const exportDeclaration of getDeclarationsForSymbol(entryExportSymbol)) {\n if (LOGS) {\n console.log(\n `[ExportsSymbolTree] Declaration: ${ts.SyntaxKind[exportDeclaration.kind]} - ${exportDeclaration.getText()}`,\n );\n }\n this.computeTreeForChildren(exportSymbolsSet, exportDeclaration, new Set<ts.Symbol>());\n }\n }\n }\n }\n\n private computeTreeForChildren(\n targetSymbolsSet: Set<ts.Symbol>,\n node: ts.Node,\n visitedSymbols: Set<ts.Symbol>,\n ): void {\n if (LOGS) {\n console.log(`[computeTreeForChildren] Processing: ${ts.SyntaxKind[node.kind]} - ${node.getText()}`);\n }\n\n // Handle namespace exports (export * as name from './module')\n // These create an alias symbol that points to the actual module symbol\n if (ts.isNamespaceExport(node)) {\n if (LOGS) {\n console.log(`[computeTreeForChildren] Found NamespaceExport!`);\n }\n const typeChecker = this.program.getTypeChecker();\n\n // Get the symbol at the namespace export's name (e.g., \"fun1\" in \"export * as fun1 from './module'\")\n const symbol = typeChecker.getSymbolAtLocation(node.name);\n if (LOGS) {\n console.log(\n `[computeTreeForChildren] Symbol: ${symbol?.name}, isAlias: ${symbol && (symbol.flags & ts.SymbolFlags.Alias) !== 0}`,\n );\n }\n if (symbol !== undefined && symbol.flags & ts.SymbolFlags.Alias) {\n // Resolve the alias to get the actual module symbol\n const aliasedSymbol = typeChecker.getAliasedSymbol(symbol);\n if (LOGS) {\n console.log(`[computeTreeForChildren] Aliased to: ${aliasedSymbol.escapedName}`);\n }\n\n // Get all exports from the referenced module\n const moduleExports = typeChecker.getExportsOfModule(aliasedSymbol);\n if (moduleExports && moduleExports.length > 0) {\n if (LOGS) {\n console.log(`[computeTreeForChildren] Module exports: ${moduleExports.map((e) => e.name).join(\", \")}`);\n }\n for (const exportSymbol of moduleExports) {\n const actualExport = getActualSymbol(exportSymbol, typeChecker);\n if (!visitedSymbols.has(actualExport)) {\n visitedSymbols.add(actualExport);\n targetSymbolsSet.add(actualExport);\n if (LOGS) {\n console.log(`[computeTreeForChildren] Adding: ${actualExport.escapedName}`);\n }\n\n for (const exportDeclaration of getDeclarationsForSymbol(actualExport)) {\n this.computeTreeForChildren(targetSymbolsSet, exportDeclaration, visitedSymbols);\n }\n }\n }\n } else {\n console.warn(`[computeTreeForChildren] Could not get exports for aliased symbol`);\n }\n }\n return;\n }\n\n // Handle re-export of namespace imports (import * as x from './module'; export { x })\n // This pattern creates an export that references a namespace import\n if (ts.isExportDeclaration(node) && node.exportClause !== undefined && ts.isNamedExports(node.exportClause)) {\n if (LOGS) {\n console.log(`[computeTreeForChildren] Found ExportDeclaration with named exports`);\n }\n const typeChecker = this.program.getTypeChecker();\n\n for (const exportSpecifier of node.exportClause.elements) {\n if (LOGS) {\n console.log(`[computeTreeForChildren] Export specifier: ${exportSpecifier.name.text}`);\n }\n // Get the symbol for this exported name\n const exportedSymbol = typeChecker.getSymbolAtLocation(exportSpecifier.name);\n if (exportedSymbol !== undefined) {\n if (LOGS) {\n console.log(\n `[computeTreeForChildren] Symbol: ${exportedSymbol.name}, flags: ${exportedSymbol.flags}`,\n );\n }\n\n // Check if this is an alias (e.g., from a namespace import)\n if ((exportedSymbol.flags & ts.SymbolFlags.Alias) !== 0) {\n const aliasedSymbol = typeChecker.getAliasedSymbol(exportedSymbol);\n if (LOGS) {\n console.log(\n `[computeTreeForChildren] Aliased to: ${aliasedSymbol.name}, flags: ${aliasedSymbol.flags}`,\n );\n }\n\n // Check if the aliased symbol is a namespace module\n if ((aliasedSymbol.flags & ts.SymbolFlags.NamespaceModule) !== 0) {\n if (LOGS) {\n console.log(`[computeTreeForChildren] Aliased symbol is a namespace module!`);\n }\n // Get all exports from this namespace module\n const moduleExports = typeChecker.getExportsOfModule(aliasedSymbol);\n if (LOGS) {\n console.log(\n `[computeTreeForChildren] Module exports: ${moduleExports.map((e) => e.name).join(\", \")}`,\n );\n }\n for (const exportSymbol of moduleExports) {\n const actualExport = getActualSymbol(exportSymbol, typeChecker);\n if (!visitedSymbols.has(actualExport)) {\n visitedSymbols.add(actualExport);\n targetSymbolsSet.add(actualExport);\n if (LOGS) {\n console.log(`[computeTreeForChildren] Adding: ${actualExport.escapedName}`);\n }\n\n // Recursively process the export's declarations\n for (const exportDeclaration of getDeclarationsForSymbol(actualExport)) {\n this.computeTreeForChildren(targetSymbolsSet, exportDeclaration, visitedSymbols);\n }\n }\n }\n }\n }\n }\n }\n // Don't return here - continue to process children\n }\n\n // it's similar to handling ts.Block node - both Block and variable's initializer are part of _implementation_\n // and we don't care about that implementation at all - we just only need to worry it's definition\n // for functions it is arguments and return type\n // for variables - the type of a variable\n if (ts.isVariableDeclaration(node)) {\n const typeChecker = this.program.getTypeChecker();\n const variableType = typeChecker.getTypeAtLocation(node);\n const variableTypeSymbol = variableType.getSymbol();\n if (variableTypeSymbol !== undefined) {\n targetSymbolsSet.add(variableTypeSymbol);\n if (LOGS) {\n console.log(`[computeTreeForChildren] Added variable type symbol: ${variableTypeSymbol.escapedName}`);\n }\n }\n\n return;\n }\n\n ts.forEachChild(node, (childNode: ts.Node) => this.computeTreeForNode(targetSymbolsSet, childNode, visitedSymbols));\n }\n\n private computeTreeForNode(targetSymbolsSet: Set<ts.Symbol>, node: ts.Node, visitedSymbols: Set<ts.Symbol>): void {\n if (ts.isVariableStatement(node)) {\n for (const varDeclaration of node.declarationList.declarations) {\n this.computeTreeForNode(targetSymbolsSet, varDeclaration, visitedSymbols);\n }\n\n return;\n }\n\n if (node.kind === ts.SyntaxKind.JSDoc || ts.isBlock(node)) {\n return;\n }\n\n if (isClassMember(node) && hasPrivateKeyword(node)) {\n return;\n }\n\n if (ts.isIdentifier(node)) {\n const symbol = this.getSymbol(node);\n if (symbol === null) {\n return;\n }\n\n if (visitedSymbols.has(symbol)) {\n return;\n }\n\n visitedSymbols.add(symbol);\n if (LOGS) {\n console.log(`[computeTreeForNode] Processing identifier: ${node.getText()} -> ${symbol.escapedName}`);\n }\n\n for (const childSymbol of splitTransientSymbol(symbol, this.program.getTypeChecker())) {\n targetSymbolsSet.add(childSymbol);\n if (LOGS) {\n console.log(`[computeTreeForNode] Added to set: ${childSymbol.escapedName}`);\n }\n\n for (const exportDeclaration of getDeclarationsForSymbol(childSymbol)) {\n this.computeTreeForChildren(targetSymbolsSet, exportDeclaration, visitedSymbols);\n }\n }\n }\n\n this.computeTreeForChildren(targetSymbolsSet, node, visitedSymbols);\n }\n\n private getSymbol(node: ts.Node): ts.Symbol | null {\n const nodeSymbol = this.program.getTypeChecker().getSymbolAtLocation(node);\n if (nodeSymbol === undefined) {\n return null;\n }\n\n return this.getActualSymbol(nodeSymbol);\n }\n\n private getActualSymbol(symbol: ts.Symbol): ts.Symbol {\n return getActualSymbol(symbol, this.program.getTypeChecker());\n }\n}\n","import ts from \"typescript\";\n\nexport const getNodeJSDocComment = (node: ts.Node): string => {\n const start = node.getStart();\n const jsDocStart = node.getStart(undefined, true);\n return node.getSourceFile().getFullText().substring(jsDocStart, start).trim();\n};\n","export interface OptimizerOptions {\n /**\n * An array of entry source files which will used to detect exported and internal fields.\n * Basically it should be entry point(s) of the library/project.\n * @example ['./src/index.ts']\n */\n entrySourceFiles: string[];\n\n /**\n * Prefix of generated names for private fields\n * @example '_private_'\n * @example '$_' // default\n */\n privatePrefix: string;\n\n /**\n * Comment which will treat a class/interface/type/property/etc and all its children as \"public\".\n * Set it to empty string to disable using JSDoc comment to detecting \"visibility level\".\n * @example 'public' // default\n * @example 'external'\n * @example ''\n */\n publicJSDocTag: string;\n\n /**\n * Whether fields that were decorated should be renamed.\n * A field is treated as \"decorated\" if itself or any its parent (on type level) has a decorator.\n */\n ignoreDecorated: boolean;\n}\n\nexport const enum VisibilityType {\n Private = 0,\n External = 1,\n}\n\nexport const defaultOptions: OptimizerOptions = {\n entrySourceFiles: [],\n privatePrefix: \"$_\",\n publicJSDocTag: \"public\",\n ignoreDecorated: false,\n};\n","import ts from \"typescript\";\nimport { ExportsSymbolTree } from \"./exports/tracker\";\nimport {\n getDeclarationsForSymbol,\n isClassMember,\n isConstructorParameter,\n isPrivateClassMember,\n isSymbolClassMember,\n getClassOfMemberSymbol,\n hasDecorators,\n hasModifier,\n splitTransientSymbol,\n isNodeNamedDeclaration,\n} from \"./utils/symbol-utils\";\nimport { getNodeJSDocComment } from \"./utils/ast-utils\";\nimport { OptimizerOptions, defaultOptions, VisibilityType } from \"./types\";\nimport { LOGS } from \"./config\";\n\nexport type { OptimizerOptions } from \"./types\";\n\nexport const optimizer = (\n program: ts.Program,\n options?: Partial<OptimizerOptions>,\n): ts.TransformerFactory<ts.SourceFile> => {\n const fullOptions: OptimizerOptions = { ...defaultOptions, ...options };\n const typeChecker = program.getTypeChecker();\n const exportsSymbolTree = new ExportsSymbolTree(program, fullOptions.entrySourceFiles);\n\n const cache = new Map<ts.Symbol, VisibilityType>();\n\n const putToCache = (nodeSymbol: ts.Symbol, val: VisibilityType): VisibilityType => {\n cache.set(nodeSymbol, val);\n return val;\n };\n\n return (context: ts.TransformationContext) => {\n const transformNode = (node: ts.Node): ts.Node | undefined => {\n // const a = { node }\n if (ts.isShorthandPropertyAssignment(node)) {\n return handleShorthandPropertyAssignment(node);\n }\n\n // const { node } = obj;\n if (ts.isBindingElement(node) && node.propertyName === undefined) {\n if (node.parent && ts.isObjectBindingPattern(node.parent)) {\n return handleShorthandObjectBindingElement(node);\n }\n return node;\n }\n\n // is not supported:\n // const { node = default_Value } = obj;\n\n // 'node' in obj\n if (\n node.parent &&\n ts.isStringLiteral(node) &&\n ts.isBinaryExpression(node.parent) &&\n node.parent.operatorToken.kind === ts.SyntaxKind.InKeyword\n ) {\n return handleInKeyword(node);\n }\n\n if (ts.isIdentifier(node) && node.parent) {\n // obj.node\n if (ts.isPropertyAccessExpression(node.parent) && node.parent.name === node) {\n return handlePropertyAccessIdentifier(node);\n }\n\n // private node\n // public node()\n if (isClassMember(node.parent) && node.parent.name === node) {\n return handleClassMember(node);\n }\n\n // enum Enum { node }\n if (ts.isEnumMember(node.parent) && node.parent.name === node) {\n return handleEnumMember(node);\n }\n\n // const a = { node: 123 }\n if (ts.isPropertyAssignment(node.parent) && node.parent.name === node) {\n return handlePropertyAssignment(node);\n }\n\n // const { node: localName } = obj;\n if (ts.isBindingElement(node.parent) && node.parent.propertyName === node) {\n return handleBindingElement(node);\n }\n\n // <Comp node={...} />\n if (ts.isJsxAttribute(node.parent) && node.parent.name === node) {\n return handleJsxAttributeName(node);\n }\n\n // constructor(public node: string) { // <--- this\n // console.log(node); // <--- and this\n // }\n if (\n (isConstructorParameter(node.parent) && node.parent.name === node) ||\n isConstructorParameterReference(node)\n ) {\n return handleCtorParameter(node);\n }\n }\n\n // obj['fooBar']\n if (\n node.parent &&\n ts.isStringLiteral(node) &&\n ts.isElementAccessExpression(node.parent) &&\n node.parent.argumentExpression === node\n ) {\n return handleElementAccessExpression(node);\n }\n\n return node;\n };\n\n const handleInKeyword = (node: ts.StringLiteral): ts.StringLiteral => {\n const parent = node.parent as ts.BinaryExpression;\n const nodeType = typeChecker.getTypeAtLocation(node);\n if (!nodeType.isStringLiteral()) {\n throw new Error(`Can't get type for left expression in ${node.parent.getText()}`);\n }\n\n const propertyName = nodeType.value;\n if (isTypePropertyExternal(typeChecker.getTypeAtLocation(parent.right), propertyName)) {\n return node;\n }\n\n return createNewNode(propertyName, VisibilityType.Private, context.factory.createStringLiteral);\n };\n\n // obj.node\n const handlePropertyAccessIdentifier = (node: ts.Identifier): ts.Identifier => createNewIdentifier(node);\n\n // obj['fooBar']\n const handleElementAccessExpression = (node: ts.StringLiteral): ts.StringLiteral => {\n const visibilityType = getNodeVisibilityType(node);\n if (visibilityType === VisibilityType.External) {\n return node;\n }\n\n return createNewNodeFromProperty(node, visibilityType, context.factory.createStringLiteral);\n };\n\n // private node\n // public node()\n const handleClassMember = (node: ts.Identifier): ts.Identifier => createNewIdentifier(node);\n\n // enum Enum { node }\n const handleEnumMember = (node: ts.Identifier): ts.Identifier => createNewIdentifier(node);\n\n // const { node: localName } = obj;\n const handleBindingElement = (node: ts.Identifier): ts.Identifier => createNewIdentifier(node);\n\n // <Comp node={...} />\n const handleJsxAttributeName = (node: ts.Identifier): ts.Identifier => createNewIdentifier(node);\n\n // const a = { node: 123 }\n const handlePropertyAssignment = (node: ts.Identifier): ts.Identifier => createNewIdentifier(node);\n\n // const a = { node }\n const handleShorthandPropertyAssignment = (\n node: ts.ShorthandPropertyAssignment,\n ): ts.PropertyAssignment | ts.ShorthandPropertyAssignment => {\n const visibilityType = getNodeVisibilityType(node.name);\n if (visibilityType === VisibilityType.External) {\n return node;\n }\n\n return createNewNodeFromProperty(node.name, visibilityType, (newName: string) => {\n return context.factory.createPropertyAssignment(newName, node.name);\n });\n };\n\n // const { node } = obj;\n const handleShorthandObjectBindingElement = (node: ts.BindingElement): ts.BindingElement => {\n if (!ts.isIdentifier(node.name)) {\n return node;\n }\n\n const visibilityType = getNodeVisibilityType(node);\n if (visibilityType === VisibilityType.External) {\n return node;\n }\n\n return createNewNodeFromProperty(node.name, visibilityType, (newName: string) => {\n return context.factory.createBindingElement(node.dotDotDotToken, newName, node.name, node.initializer);\n });\n };\n\n // constructor(public node: string) { // <--- this\n // console.log(node); // <--- and this\n // }\n const handleCtorParameter = (node: ts.Identifier): ts.Identifier => createNewIdentifier(node);\n\n const createNewIdentifier = (oldIdentifier: ts.Identifier): ts.Identifier => {\n const visibilityType = getNodeVisibilityType(oldIdentifier);\n if (visibilityType === VisibilityType.External) {\n return oldIdentifier;\n }\n\n return createNewNodeFromProperty(oldIdentifier, visibilityType, context.factory.createIdentifier);\n };\n\n const createNewNodeFromProperty = <T extends ts.Node>(\n oldProperty: ts.PropertyName,\n type: VisibilityType,\n createNode: (newName: string) => T,\n ): T => {\n const symbol = typeChecker.getSymbolAtLocation(oldProperty);\n if (symbol === undefined) {\n throw new Error(`Cannot get symbol for node \"${oldProperty.getText()}\"`);\n }\n\n const oldPropertyName = ts.unescapeLeadingUnderscores(symbol.escapedName);\n\n return createNewNode(oldPropertyName, type, createNode);\n };\n\n const createNewNode = <T extends ts.Node>(\n oldPropertyName: string,\n type: VisibilityType,\n createNode: (newName: string) => T,\n ): T => {\n const newPropertyName = getNewName(oldPropertyName);\n return createNode(newPropertyName);\n };\n\n const getNewName = (originalName: string): string => `${fullOptions.privatePrefix}${originalName}`;\n\n const getActualSymbol = (symbol: ts.Symbol): ts.Symbol => {\n if (symbol.flags & ts.SymbolFlags.Alias) {\n symbol = typeChecker.getAliasedSymbol(symbol);\n }\n\n return symbol;\n };\n\n const getNodeSymbol = (node: ts.Expression | ts.NamedDeclaration | ts.DeclarationName): ts.Symbol | null => {\n const symbol = typeChecker.getSymbolAtLocation(node);\n if (symbol === undefined) {\n return null;\n }\n\n return getActualSymbol(symbol);\n };\n\n const isTypePropertyExternal = (type: ts.Type, typePropertyName: string): boolean => {\n // if a type is unknown or any - they should be interpret as a public ones\n if (type.flags & ts.TypeFlags.Unknown || type.flags & ts.TypeFlags.Any) {\n return true;\n }\n\n if (type.flags & ts.TypeFlags.IndexedAccess) {\n return isTypePropertyExternal(typeChecker.getApparentType(type), typePropertyName);\n }\n\n const symbol = type.getSymbol();\n const propertySymbol = typeChecker.getPropertyOfType(type, typePropertyName);\n\n if (type.flags & ts.TypeFlags.Object) {\n const objectType = type as ts.ObjectType;\n\n // treat any tuple property as \"external\"\n if (objectType.objectFlags & ts.ObjectFlags.Tuple) {\n return true;\n }\n\n if (objectType.objectFlags & ts.ObjectFlags.Reference) {\n const target = (objectType as ts.TypeReference).target;\n if (target !== objectType && isTypePropertyExternal(target, typePropertyName)) {\n return true;\n }\n }\n\n // in case when we can't get where a property come from in mapped types\n // let's check the whole type explicitly\n // thus in case of when property doesn't have a declaration let's treat any property of a mapped type as \"external\" if its parent type is external\n // e.g. Readonly<Foo>.field will look for `field` in _Foo_ type (not in Readonly<Foo>), but { [K in 'foo' | 'bar']: any } won't\n // perhaps it would be awesome to handle exactly property we have, but ¯\\_(ツ)_/¯\n const propertyHasDeclarations =\n propertySymbol !== undefined ? getDeclarationsForSymbol(propertySymbol).length !== 0 : false;\n if (\n objectType.objectFlags & ts.ObjectFlags.Mapped &&\n symbol !== undefined &&\n !propertyHasDeclarations &&\n getSymbolVisibilityType(symbol) === VisibilityType.External\n ) {\n return true;\n }\n }\n\n if (type.isUnionOrIntersection()) {\n const hasExternalSubType = type.types.some((t: ts.Type) => isTypePropertyExternal(t, typePropertyName));\n if (hasExternalSubType) {\n return hasExternalSubType;\n }\n }\n\n if (symbol !== undefined) {\n const declarations = getDeclarationsForSymbol(symbol);\n for (const declaration of declarations) {\n if (\n (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration)) &&\n declaration.heritageClauses !== undefined\n ) {\n const hasHeritageClausesExternals = declaration.heritageClauses.some((clause: ts.HeritageClause) => {\n return clause.types.some((expr: ts.ExpressionWithTypeArguments) => {\n return isTypePropertyExternal(typeChecker.getTypeAtLocation(expr), typePropertyName);\n });\n });\n\n if (hasHeritageClausesExternals) {\n return true;\n }\n }\n }\n }\n\n if (propertySymbol === undefined) {\n return false;\n }\n\n return [propertySymbol, ...splitTransientSymbol(propertySymbol, typeChecker)].some(\n (sym: ts.Symbol) => getSymbolVisibilityType(sym) === VisibilityType.External,\n );\n };\n\n const getNodeVisibilityType = (\n node: ts.Expression | ts.Identifier | ts.StringLiteral | ts.BindingElement,\n ): VisibilityType => {\n if (ts.isPropertyAssignment(node.parent) || ts.isShorthandPropertyAssignment(node.parent)) {\n let expressionToGetTypeFrom: ts.Expression = node.parent.parent;\n let lastKnownExpression: ts.AsExpression | ts.ObjectLiteralExpression = node.parent.parent;\n let currentNode: ts.Node = node.parent.parent.parent;\n\n while (ts.isParenthesizedExpression(currentNode) || ts.isAsExpression(currentNode)) {\n if (ts.isAsExpression(currentNode)) {\n expressionToGetTypeFrom = lastKnownExpression;\n lastKnownExpression = currentNode;\n }\n\n currentNode = currentNode.parent;\n }\n\n // to get correct contextual type we need to provide the previous last expression rather than the last one\n const type = typeChecker.getContextualType(expressionToGetTypeFrom);\n if (type !== undefined && isTypePropertyExternal(type, node.getText())) {\n return VisibilityType.External;\n }\n }\n\n if (ts.isPropertyAccessExpression(node.parent) || ts.isElementAccessExpression(node.parent)) {\n if (ts.isIdentifier(node.parent.expression)) {\n const expressionSymbol = typeChecker.getSymbolAtLocation(node.parent.expression);\n if (LOGS) {\n console.log(\n `[transformer] PropertyAccess: expression=${node.parent.expression.getText()}, property=${node.getText()}`,\n );\n console.log(`[transformer] Expression symbol: ${expressionSymbol?.name}`);\n }\n if (expressionSymbol !== undefined) {\n // import * as foo from '...';\n // foo.node;\n // foo['node'];\n // or\n // namespace Foo { ... }\n // Foo.node\n // Foo['node'];\n const declarations = getDeclarationsForSymbol(expressionSymbol);\n if (LOGS) {\n console.log(`[transformer] Declarations: ${declarations.map((d) => ts.SyntaxKind[d.kind]).join(\", \")}`);\n }\n const isModuleOrStarImport = declarations.some(\n (decl: ts.Declaration) => ts.isNamespaceImport(decl) || ts.isModuleDeclaration(decl),\n );\n if (LOGS) {\n console.log(`[transformer] isModuleOrStarImport: ${isModuleOrStarImport}`);\n }\n if (isModuleOrStarImport) {\n // treat accessing to import-star or namespace as external one\n // because we can't rename them yet\n if (LOGS) {\n console.log(`[transformer] Returning External (module/star import)`);\n }\n return VisibilityType.External;\n }\n\n // import { foo } from '...';\n // where foo is a namespace re-export (export * as foo from './bar')\n // In this case, symbol for 'foo' is an alias to a module\n // Check if the symbol's type is a namespace module or regular module\n const hasImportSpecifier = declarations.some((decl) => ts.isImportSpecifier(decl));\n if (LOGS) {\n console.log(`[transformer] hasImportSpecifier: ${hasImportSpecifier}`);\n }\n if (hasImportSpecifier) {\n const expressionType = typeChecker.getTypeAtLocation(node.parent.expression);\n if (LOGS) {\n console.log(`[transformer] Expression type: ${expressionType?.flags}`);\n }\n if (expressionType) {\n const typeSymbol = expressionType.getSymbol();\n if (LOGS) {\n console.log(`[transformer] Type symbol: ${typeSymbol?.name}, flags: ${typeSymbol?.flags}`);\n }\n // Check if it's a module (NamespaceModule or regular Module)\n // NamespaceModule: 0x8000000, Module: 0x200\n const isModule =\n typeSymbol &&\n ((typeSymbol.flags & ts.SymbolFlags.NamespaceModule) !== 0 ||\n (typeSymbol.flags & ts.SymbolFlags.Module) !== 0);\n if (isModule) {\n // The expression's type is a module, so accessing its properties\n // means accessing exports from that module, which are external\n if (LOGS) {\n console.log(`[transformer] Returning External (module)`);\n }\n return VisibilityType.External;\n }\n }\n }\n }\n }\n\n const expressionType = typeChecker.getTypeAtLocation(node.parent.expression);\n const propertyText = node.getText();\n if (LOGS) {\n console.log(`[transformer] Checking isTypePropertyExternal for ${propertyText}`);\n }\n if (isTypePropertyExternal(expressionType, propertyText)) {\n if (LOGS) {\n console.log(`[transformer] Returning External (isTypePropertyExternal)`);\n }\n return VisibilityType.External;\n }\n }\n\n // shorthand binding element\n // const { node } = obj;\n if (\n ts.isBindingElement(node) &&\n isTypePropertyExternal(typeChecker.getTypeAtLocation(node.parent), node.getText())\n ) {\n return VisibilityType.External;\n }\n\n // full binding element\n // const { node: propName } = obj;\n if (\n ts.isBindingElement(node.parent) &&\n isTypePropertyExternal(typeChecker.getTypeAtLocation(node.parent.parent), node.getText())\n ) {\n return VisibilityType.External;\n }\n\n // <Comp node={...} />\n if (ts.isJsxAttribute(node.parent)) {\n const jsxTagSymbol = typeChecker.getSymbolAtLocation(node.parent.parent.parent.tagName);\n if (jsxTagSymbol !== undefined && jsxTagSymbol.valueDeclaration !== undefined) {\n const jsxPropsType = typeChecker.getTypeOfSymbolAtLocation(jsxTagSymbol, jsxTagSymbol.valueDeclaration);\n if (isTypePropertyExternal(jsxPropsType, node.getText())) {\n return VisibilityType.External;\n }\n }\n }\n\n const nodeSymbol = getNodeSymbol(node);\n const classOfMember = nodeSymbol !== null ? getClassOfMemberSymbol(nodeSymbol) : null;\n if (\n classOfMember !== null &&\n isTypePropertyExternal(typeChecker.getTypeAtLocation(classOfMember), node.getText())\n ) {\n return VisibilityType.External;\n }\n\n const symbol = ts.isBindingElement(node) ? getShorthandObjectBindingElementSymbol(node) : nodeSymbol;\n if (symbol === null) {\n return VisibilityType.External;\n }\n\n return getSymbolVisibilityType(symbol);\n };\n\n const getSymbolVisibilityType = (nodeSymbol: ts.Symbol): VisibilityType => {\n nodeSymbol = getActualSymbol(nodeSymbol);\n\n const cachedValue = cache.get(nodeSymbol);\n if (cachedValue !== undefined) {\n return cachedValue;\n }\n\n const symbolDeclarations = getDeclarationsForSymbol(nodeSymbol);\n if (symbolDeclarations.some(isDeclarationFromExternals)) {\n return putToCache(nodeSymbol, VisibilityType.External);\n }\n\n if (symbolDeclarations.some((decl: ts.Declaration) => hasModifier(decl, ts.SyntaxKind.DeclareKeyword))) {\n return putToCache(nodeSymbol, VisibilityType.External);\n }\n\n if (nodeSymbol.escapedName === \"prototype\") {\n return putToCache(nodeSymbol, VisibilityType.External);\n }\n\n if (fullOptions.publicJSDocTag.length !== 0 || fullOptions.ignoreDecorated) {\n for (const declaration of symbolDeclarations) {\n let currentNode: ts.Node = declaration;\n while (!ts.isSourceFile(currentNode)) {\n if (\n fullOptions.publicJSDocTag.length !== 0 &&\n getNodeJSDocComment(currentNode).includes(`@${fullOptions.publicJSDocTag}`)\n ) {\n return putToCache(nodeSymbol, VisibilityType.External);\n }\n\n if (fullOptions.ignoreDecorated && hasDecorators(currentNode)) {\n return putToCache(nodeSymbol, VisibilityType.External);\n }\n\n if (ts.isEnumDeclaration(currentNode)) {\n return putToCache(nodeSymbol, VisibilityType.External);\n }\n\n currentNode = currentNode.parent;\n }\n }\n }\n\n if (isPrivateClassMember(nodeSymbol)) {\n return putToCache(nodeSymbol, VisibilityType.Private);\n }\n\n if (exportsSymbolTree.isSymbolAccessibleFromExports(nodeSymbol)) {\n return putToCache(nodeSymbol, VisibilityType.External);\n }\n\n for (const declaration of symbolDeclarations) {\n if (!isNodeNamedDeclaration(declaration.parent) || declaration.parent.name === undefined) {\n continue;\n }\n\n const parentSymbol = getNodeSymbol(declaration.parent.name);\n if (parentSymbol === null) {\n continue;\n }\n\n if (getSymbolVisibilityType(parentSymbol) === VisibilityType.External) {\n return putToCache(nodeSymbol, VisibilityType.External);\n }\n }\n\n return putToCache(nodeSymbol, VisibilityType.Private);\n };\n\n const getShorthandObjectBindingElementSymbol = (element: ts.BindingElement): ts.Symbol | null => {\n if (element.propertyName !== undefined) {\n throw new Error(\n `Cannot handle binding element with property name: ${element.getText()} in ${\n element.getSourceFile().fileName\n }`,\n );\n }\n\n if (!ts.isIdentifier(element.name)) {\n return null;\n }\n\n // if no property name is set (const { a } = foo)\n // then node.propertyName is undefined and we need to find this property ourselves\n // so let's use go-to-definition algorithm from TSServer\n // see https://github.com/microsoft/TypeScript/blob/672b0e3e16ad18b422dbe0cec5a98fce49881b76/src/services/goToDefinition.ts#L58-L77\n const type = typeChecker.getTypeAtLocation(element.parent as ts.Node);\n if (type.isUnion()) {\n return null;\n }\n\n return type.getProperty(ts.idText(element.name)) || null;\n };\n\n const isDeclarationFromExternals = (declaration: ts.Declaration): boolean => {\n const sourceFile = declaration.getSourceFile();\n\n // all declarations from declaration source files are external by default\n return (\n sourceFile.isDeclarationFile ||\n program.isSourceFileDefaultLibrary(sourceFile) ||\n /[\\\\/]node_modules[\\\\/]/.test(sourceFile.fileName)\n );\n };\n\n const isConstructorParameterReference = (node: ts.Node): node is ts.Identifier => {\n if (!ts.isIdentifier(node)) {\n return false;\n }\n\n return isSymbolClassMember(typeChecker.getSymbolAtLocation(node));\n };\n const transformNodeAndChildren = (node: ts.Node): ts.Node | undefined =>\n ts.visitEachChild(transformNode(node), transformNodeAndChildren, context);\n\n return (sourceFile: ts.SourceFile) => transformNodeAndChildren(sourceFile) as ts.SourceFile;\n };\n};\n"]}
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@eliasku/ts-transformers",
3
3
  "description": "TypeScript transformer for code optimization",
4
- "version": "0.0.8",
4
+ "version": "0.0.10",
5
5
  "license": "MIT",
6
- "type": "module",
7
6
  "scripts": {
7
+ "build": "tsup ./src/index.ts --target esnext --platform neutral --format esm --dts --sourcemap --minify terser --treeshake smallest --splitting false",
8
8
  "test": "bun test",
9
9
  "format": "prettier --write **/*.{ts,json,md,yml}",
10
10
  "check": "tsc -p .",
@@ -22,12 +22,19 @@
22
22
  "rollup": "latest",
23
23
  "@rollup/plugin-typescript": "latest",
24
24
  "tslib": "latest",
25
- "esbuild": "latest"
25
+ "esbuild": "latest",
26
+ "tsup": "latest",
27
+ "terser": "latest"
26
28
  },
27
- "module": "./src/index.ts",
28
- "types": "./src/index.ts",
29
+ "type": "module",
30
+ "module": "./dist/index.js",
31
+ "types": "./dist/index.d.ts",
29
32
  "exports": {
30
- ".": "./src/index.ts"
33
+ ".": {
34
+ "types": "./dist/index.d.ts",
35
+ "import": "./dist/index.js"
36
+ },
37
+ "./ts": "./scr/index.ts"
31
38
  },
32
39
  "repository": {
33
40
  "type": "git",
@@ -40,7 +47,6 @@
40
47
  "plugin",
41
48
  "transformer",
42
49
  "minify",
43
- "const-enum",
44
50
  "treeshake",
45
51
  "mangle"
46
52
  ],
@@ -48,6 +54,7 @@
48
54
  "access": "public"
49
55
  },
50
56
  "files": [
57
+ "dist",
51
58
  "src"
52
59
  ]
53
60
  }
@@ -14,12 +14,12 @@ export class ExportsSymbolTree {
14
14
  private readonly program: ts.Program;
15
15
  private readonly exportsTree = new Map<ts.Symbol, Set<ts.Symbol>>();
16
16
 
17
- public constructor(program: ts.Program, entrySourceFiles: readonly string[]) {
17
+ constructor(program: ts.Program, entrySourceFiles: readonly string[]) {
18
18
  this.program = program;
19
19
  this.computeTreeForExports(entrySourceFiles);
20
20
  }
21
21
 
22
- public isSymbolAccessibleFromExports(symbol: ts.Symbol): boolean {
22
+ isSymbolAccessibleFromExports(symbol: ts.Symbol): boolean {
23
23
  symbol = this.getActualSymbol(symbol);
24
24
  for (const [, set] of this.exportsTree) {
25
25
  if (set.has(symbol)) {
@@ -122,24 +122,6 @@ export class ExportsSymbolTree {
122
122
  } else {
123
123
  console.warn(`[computeTreeForChildren] Could not get exports for aliased symbol`);
124
124
  }
125
- if (LOGS) {
126
- console.log(`[computeTreeForChildren] Module exports: ${moduleExports.map((e) => e.name).join(", ")}`);
127
- }
128
- for (const exportSymbol of moduleExports) {
129
- const actualExport = getActualSymbol(exportSymbol, typeChecker);
130
- if (!visitedSymbols.has(actualExport)) {
131
- visitedSymbols.add(actualExport);
132
- targetSymbolsSet.add(actualExport);
133
- if (LOGS) {
134
- console.log(`[computeTreeForChildren] Adding: ${actualExport.escapedName}`);
135
- }
136
-
137
- // Recursively process the export's declarations
138
- for (const exportDeclaration of getDeclarationsForSymbol(actualExport)) {
139
- this.computeTreeForChildren(targetSymbolsSet, exportDeclaration, visitedSymbols);
140
- }
141
- }
142
- }
143
125
  }
144
126
  return;
145
127
  }
package/src/index.ts CHANGED
@@ -1,6 +1,4 @@
1
1
  import ts from "typescript";
2
- export type { OptimizerOptions } from "./types";
3
-
4
2
  import { ExportsSymbolTree } from "./exports/tracker";
5
3
  import {
6
4
  getDeclarationsForSymbol,
@@ -16,45 +14,27 @@ import {
16
14
  } from "./utils/symbol-utils";
17
15
  import { getNodeJSDocComment } from "./utils/ast-utils";
18
16
  import { OptimizerOptions, defaultOptions, VisibilityType } from "./types";
19
- import { ConstEnumRegistry } from "./const-enum/registry";
20
- import { EnumEvaluator } from "./const-enum/evaluator";
21
- import { isConstEnumType } from "./const-enum/utils";
22
17
  import { LOGS } from "./config";
23
18
 
24
- export const optimizer = (
25
- program: ts.Program,
26
- config?: Partial<OptimizerOptions>,
27
- ): ts.TransformerFactory<ts.SourceFile> => createTransformerFactory(program, config);
19
+ export type { OptimizerOptions } from "./types";
28
20
 
29
- function createTransformerFactory(
21
+ export const optimizer = (
30
22
  program: ts.Program,
31
23
  options?: Partial<OptimizerOptions>,
32
- ): ts.TransformerFactory<ts.SourceFile> {
24
+ ): ts.TransformerFactory<ts.SourceFile> => {
33
25
  const fullOptions: OptimizerOptions = { ...defaultOptions, ...options };
34
26
  const typeChecker = program.getTypeChecker();
35
27
  const exportsSymbolTree = new ExportsSymbolTree(program, fullOptions.entrySourceFiles);
36
- const constEnumRegistry = new ConstEnumRegistry(program);
37
- const enumEvaluator = new EnumEvaluator();
38
28
 
39
29
  const cache = new Map<ts.Symbol, VisibilityType>();
40
30
 
41
- function putToCache(nodeSymbol: ts.Symbol, val: VisibilityType): VisibilityType {
31
+ const putToCache = (nodeSymbol: ts.Symbol, val: VisibilityType): VisibilityType => {
42
32
  cache.set(nodeSymbol, val);
43
33
  return val;
44
- }
34
+ };
45
35
 
46
36
  return (context: ts.TransformationContext) => {
47
- function transformNode(node: ts.Node): ts.Node | undefined {
48
- if (fullOptions.inlineConstEnums !== false) {
49
- if (ts.isPropertyAccessExpression(node)) {
50
- const inlined = tryInlineConstEnum(node);
51
- if (inlined) {
52
- ts.setOriginalNode(inlined, node);
53
- return inlined;
54
- }
55
- }
56
- }
57
-
37
+ const transformNode = (node: ts.Node): ts.Node | undefined => {
58
38
  // const a = { node }
59
39
  if (ts.isShorthandPropertyAssignment(node)) {
60
40
  return handleShorthandPropertyAssignment(node);
@@ -135,9 +115,9 @@ function createTransformerFactory(
135
115
  }
136
116
 
137
117
  return node;
138
- }
118
+ };
139
119
 
140
- function handleInKeyword(node: ts.StringLiteral): ts.StringLiteral {
120
+ const handleInKeyword = (node: ts.StringLiteral): ts.StringLiteral => {
141
121
  const parent = node.parent as ts.BinaryExpression;
142
122
  const nodeType = typeChecker.getTypeAtLocation(node);
143
123
  if (!nodeType.isStringLiteral()) {
@@ -150,53 +130,41 @@ function createTransformerFactory(
150
130
  }
151
131
 
152
132
  return createNewNode(propertyName, VisibilityType.Private, context.factory.createStringLiteral);
153
- }
133
+ };
154
134
 
155
135
  // obj.node
156
- function handlePropertyAccessIdentifier(node: ts.Identifier): ts.Identifier {
157
- return createNewIdentifier(node);
158
- }
136
+ const handlePropertyAccessIdentifier = (node: ts.Identifier): ts.Identifier => createNewIdentifier(node);
159
137
 
160
138
  // obj['fooBar']
161
- function handleElementAccessExpression(node: ts.StringLiteral): ts.StringLiteral {
139
+ const handleElementAccessExpression = (node: ts.StringLiteral): ts.StringLiteral => {
162
140
  const visibilityType = getNodeVisibilityType(node);
163
141
  if (visibilityType === VisibilityType.External) {
164
142
  return node;
165
143
  }
166
144
 
167
145
  return createNewNodeFromProperty(node, visibilityType, context.factory.createStringLiteral);
168
- }
146
+ };
169
147
 
170
148
  // private node
171
149
  // public node()
172
- function handleClassMember(node: ts.Identifier): ts.Identifier {
173
- return createNewIdentifier(node);
174
- }
150
+ const handleClassMember = (node: ts.Identifier): ts.Identifier => createNewIdentifier(node);
175
151
 
176
152
  // enum Enum { node }
177
- function handleEnumMember(node: ts.Identifier): ts.Identifier {
178
- return createNewIdentifier(node);
179
- }
153
+ const handleEnumMember = (node: ts.Identifier): ts.Identifier => createNewIdentifier(node);
180
154
 
181
155
  // const { node: localName } = obj;
182
- function handleBindingElement(node: ts.Identifier): ts.Identifier {
183
- return createNewIdentifier(node);
184
- }
156
+ const handleBindingElement = (node: ts.Identifier): ts.Identifier => createNewIdentifier(node);
185
157
 
186
158
  // <Comp node={...} />
187
- function handleJsxAttributeName(node: ts.Identifier): ts.Identifier {
188
- return createNewIdentifier(node);
189
- }
159
+ const handleJsxAttributeName = (node: ts.Identifier): ts.Identifier => createNewIdentifier(node);
190
160
 
191
161
  // const a = { node: 123 }
192
- function handlePropertyAssignment(node: ts.Identifier): ts.Identifier {
193
- return createNewIdentifier(node);
194
- }
162
+ const handlePropertyAssignment = (node: ts.Identifier): ts.Identifier => createNewIdentifier(node);
195
163
 
196
164
  // const a = { node }
197
- function handleShorthandPropertyAssignment(
165
+ const handleShorthandPropertyAssignment = (
198
166
  node: ts.ShorthandPropertyAssignment,
199
- ): ts.PropertyAssignment | ts.ShorthandPropertyAssignment {
167
+ ): ts.PropertyAssignment | ts.ShorthandPropertyAssignment => {
200
168
  const visibilityType = getNodeVisibilityType(node.name);
201
169
  if (visibilityType === VisibilityType.External) {
202
170
  return node;
@@ -205,10 +173,10 @@ function createTransformerFactory(
205
173
  return createNewNodeFromProperty(node.name, visibilityType, (newName: string) => {
206
174
  return context.factory.createPropertyAssignment(newName, node.name);
207
175
  });
208
- }
176
+ };
209
177
 
210
178
  // const { node } = obj;
211
- function handleShorthandObjectBindingElement(node: ts.BindingElement): ts.BindingElement {
179
+ const handleShorthandObjectBindingElement = (node: ts.BindingElement): ts.BindingElement => {
212
180
  if (!ts.isIdentifier(node.name)) {
213
181
  return node;
214
182
  }
@@ -221,29 +189,27 @@ function createTransformerFactory(
221
189
  return createNewNodeFromProperty(node.name, visibilityType, (newName: string) => {
222
190
  return context.factory.createBindingElement(node.dotDotDotToken, newName, node.name, node.initializer);
223
191
  });
224
- }
192
+ };
225
193
 
226
194
  // constructor(public node: string) { // <--- this
227
195
  // console.log(node); // <--- and this
228
196
  // }
229
- function handleCtorParameter(node: ts.Identifier): ts.Identifier {
230
- return createNewIdentifier(node);
231
- }
197
+ const handleCtorParameter = (node: ts.Identifier): ts.Identifier => createNewIdentifier(node);
232
198
 
233
- function createNewIdentifier(oldIdentifier: ts.Identifier): ts.Identifier {
199
+ const createNewIdentifier = (oldIdentifier: ts.Identifier): ts.Identifier => {
234
200
  const visibilityType = getNodeVisibilityType(oldIdentifier);
235
201
  if (visibilityType === VisibilityType.External) {
236
202
  return oldIdentifier;
237
203
  }
238
204
 
239
205
  return createNewNodeFromProperty(oldIdentifier, visibilityType, context.factory.createIdentifier);
240
- }
206
+ };
241
207
 
242
- function createNewNodeFromProperty<T extends ts.Node>(
208
+ const createNewNodeFromProperty = <T extends ts.Node>(
243
209
  oldProperty: ts.PropertyName,
244
210
  type: VisibilityType,
245
211
  createNode: (newName: string) => T,
246
- ): T {
212
+ ): T => {
247
213
  const symbol = typeChecker.getSymbolAtLocation(oldProperty);
248
214
  if (symbol === undefined) {
249
215
  throw new Error(`Cannot get symbol for node "${oldProperty.getText()}"`);
@@ -252,39 +218,37 @@ function createTransformerFactory(
252
218
  const oldPropertyName = ts.unescapeLeadingUnderscores(symbol.escapedName);
253
219
 
254
220
  return createNewNode(oldPropertyName, type, createNode);
255
- }
221
+ };
256
222
 
257
- function createNewNode<T extends ts.Node>(
223
+ const createNewNode = <T extends ts.Node>(
258
224
  oldPropertyName: string,
259
225
  type: VisibilityType,
260
226
  createNode: (newName: string) => T,
261
- ): T {
227
+ ): T => {
262
228
  const newPropertyName = getNewName(oldPropertyName);
263
229
  return createNode(newPropertyName);
264
- }
230
+ };
265
231
 
266
- function getNewName(originalName: string): string {
267
- return `${fullOptions.privatePrefix}${originalName}`;
268
- }
232
+ const getNewName = (originalName: string): string => `${fullOptions.privatePrefix}${originalName}`;
269
233
 
270
- function getActualSymbol(symbol: ts.Symbol): ts.Symbol {
234
+ const getActualSymbol = (symbol: ts.Symbol): ts.Symbol => {
271
235
  if (symbol.flags & ts.SymbolFlags.Alias) {
272
236
  symbol = typeChecker.getAliasedSymbol(symbol);
273
237
  }
274
238
 
275
239
  return symbol;
276
- }
240
+ };
277
241
 
278
- function getNodeSymbol(node: ts.Expression | ts.NamedDeclaration | ts.DeclarationName): ts.Symbol | null {
242
+ const getNodeSymbol = (node: ts.Expression | ts.NamedDeclaration | ts.DeclarationName): ts.Symbol | null => {
279
243
  const symbol = typeChecker.getSymbolAtLocation(node);
280
244
  if (symbol === undefined) {
281
245
  return null;
282
246
  }
283
247
 
284
248
  return getActualSymbol(symbol);
285
- }
249
+ };
286
250
 
287
- function isTypePropertyExternal(type: ts.Type, typePropertyName: string): boolean {
251
+ const isTypePropertyExternal = (type: ts.Type, typePropertyName: string): boolean => {
288
252
  // if a type is unknown or any - they should be interpret as a public ones
289
253
  if (type.flags & ts.TypeFlags.Unknown || type.flags & ts.TypeFlags.Any) {
290
254
  return true;
@@ -363,11 +327,11 @@ function createTransformerFactory(
363
327
  return [propertySymbol, ...splitTransientSymbol(propertySymbol, typeChecker)].some(
364
328
  (sym: ts.Symbol) => getSymbolVisibilityType(sym) === VisibilityType.External,
365
329
  );
366
- }
330
+ };
367
331
 
368
- function getNodeVisibilityType(
332
+ const getNodeVisibilityType = (
369
333
  node: ts.Expression | ts.Identifier | ts.StringLiteral | ts.BindingElement,
370
- ): VisibilityType {
334
+ ): VisibilityType => {
371
335
  if (ts.isPropertyAssignment(node.parent) || ts.isShorthandPropertyAssignment(node.parent)) {
372
336
  let expressionToGetTypeFrom: ts.Expression = node.parent.parent;
373
337
  let lastKnownExpression: ts.AsExpression | ts.ObjectLiteralExpression = node.parent.parent;
@@ -519,9 +483,9 @@ function createTransformerFactory(
519
483
  }
520
484
 
521
485
  return getSymbolVisibilityType(symbol);
522
- }
486
+ };
523
487
 
524
- function getSymbolVisibilityType(nodeSymbol: ts.Symbol): VisibilityType {
488
+ const getSymbolVisibilityType = (nodeSymbol: ts.Symbol): VisibilityType => {
525
489
  nodeSymbol = getActualSymbol(nodeSymbol);
526
490
 
527
491
  const cachedValue = cache.get(nodeSymbol);
@@ -590,9 +554,9 @@ function createTransformerFactory(
590
554
  }
591
555
 
592
556
  return putToCache(nodeSymbol, VisibilityType.Private);
593
- }
557
+ };
594
558
 
595
- function getShorthandObjectBindingElementSymbol(element: ts.BindingElement): ts.Symbol | null {
559
+ const getShorthandObjectBindingElementSymbol = (element: ts.BindingElement): ts.Symbol | null => {
596
560
  if (element.propertyName !== undefined) {
597
561
  throw new Error(
598
562
  `Cannot handle binding element with property name: ${element.getText()} in ${
@@ -615,9 +579,9 @@ function createTransformerFactory(
615
579
  }
616
580
 
617
581
  return type.getProperty(ts.idText(element.name)) || null;
618
- }
582
+ };
619
583
 
620
- function isDeclarationFromExternals(declaration: ts.Declaration): boolean {
584
+ const isDeclarationFromExternals = (declaration: ts.Declaration): boolean => {
621
585
  const sourceFile = declaration.getSourceFile();
622
586
 
623
587
  // all declarations from declaration source files are external by default
@@ -626,87 +590,18 @@ function createTransformerFactory(
626
590
  program.isSourceFileDefaultLibrary(sourceFile) ||
627
591
  /[\\/]node_modules[\\/]/.test(sourceFile.fileName)
628
592
  );
629
- }
593
+ };
630
594
 
631
- function isConstructorParameterReference(node: ts.Node): node is ts.Identifier {
595
+ const isConstructorParameterReference = (node: ts.Node): node is ts.Identifier => {
632
596
  if (!ts.isIdentifier(node)) {
633
597
  return false;
634
598
  }
635
599
 
636
600
  return isSymbolClassMember(typeChecker.getSymbolAtLocation(node));
637
- }
638
-
639
- function tryInlineConstEnum(node: ts.PropertyAccessExpression): ts.Expression | null {
640
- const expressionType = typeChecker.getTypeAtLocation(node.expression);
641
- if (!isConstEnumType(expressionType)) return null;
642
-
643
- const enumSymbol = expressionType.symbol || expressionType.aliasSymbol;
644
- if (!enumSymbol) return null;
645
-
646
- const enumInfo = constEnumRegistry.getEnumInfo(enumSymbol);
647
- if (!enumInfo) return null;
648
-
649
- const memberValue = enumInfo.members.get(node.name.text)?.value;
650
- if (memberValue === undefined || memberValue === null) return null;
651
- const newNode = enumEvaluator.createLiteral(memberValue);
652
-
653
- const r = ts.setOriginalNode(newNode, node);
654
- ts.setSourceMapRange(newNode, ts.getSourceMapRange(node));
655
- (newNode as any).symbol = (node as any).symbol; // eslint-disable-line @typescript-eslint/no-explicit-any
656
- return r;
657
- }
658
-
659
- return (sourceFile: ts.SourceFile) => {
660
- function handleEnumDeclaration(node: ts.EnumDeclaration): ts.EnumDeclaration | undefined {
661
- if (fullOptions.inlineConstEnums === false) {
662
- return node;
663
- }
664
- if (!hasModifier(node, ts.SyntaxKind.ConstKeyword)) {
665
- return node;
666
- }
667
-
668
- if (sourceFile.isDeclarationFile) {
669
- return ts.factory.updateEnumDeclaration(
670
- node,
671
- node.modifiers?.filter((m) => m.kind !== ts.SyntaxKind.ConstKeyword),
672
- node.name,
673
- node.members,
674
- );
675
- }
676
-
677
- return ts.factory.createVariableStatement(
678
- [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
679
- ts.factory.createVariableDeclarationList(
680
- [
681
- ts.factory.createVariableDeclaration(
682
- node.name, // Reuse enum name
683
- undefined,
684
- ts.factory.createTypeLiteralNode([]), // Empty object type: {}
685
- undefined, // No initializer (empty declaration)
686
- ),
687
- ],
688
- ts.NodeFlags.Let, // Sets the 'const' modifier
689
- ),
690
- ) as unknown as ts.EnumDeclaration;
691
- }
692
-
693
- function wrapTransformNode(node: ts.Node): ts.Node | undefined {
694
- if (ts.isEnumDeclaration(node)) {
695
- const result = handleEnumDeclaration(node);
696
- if (result !== node) {
697
- if (result) {
698
- return transformNode(result);
699
- }
700
- return result;
701
- }
702
- }
703
- return transformNode(node);
704
- }
705
-
706
- const wrappedTransformNodeAndChildren = (node: ts.Node): ts.Node | undefined =>
707
- ts.visitEachChild(wrapTransformNode(node), wrappedTransformNodeAndChildren, context);
708
-
709
- return wrappedTransformNodeAndChildren(sourceFile) as ts.SourceFile;
710
601
  };
602
+ const transformNodeAndChildren = (node: ts.Node): ts.Node | undefined =>
603
+ ts.visitEachChild(transformNode(node), transformNodeAndChildren, context);
604
+
605
+ return (sourceFile: ts.SourceFile) => transformNodeAndChildren(sourceFile) as ts.SourceFile;
711
606
  };
712
- }
607
+ };
package/src/types.ts CHANGED
@@ -27,11 +27,6 @@ export interface OptimizerOptions {
27
27
  * A field is treated as "decorated" if itself or any its parent (on type level) has a decorator.
28
28
  */
29
29
  ignoreDecorated: boolean;
30
-
31
- /**
32
- * Whether to inline const enum values.
33
- */
34
- inlineConstEnums?: boolean;
35
30
  }
36
31
 
37
32
  export const enum VisibilityType {
@@ -44,5 +39,4 @@ export const defaultOptions: OptimizerOptions = {
44
39
  privatePrefix: "$_",
45
40
  publicJSDocTag: "public",
46
41
  ignoreDecorated: false,
47
- inlineConstEnums: true,
48
42
  };
@@ -1,7 +1,7 @@
1
1
  import ts from "typescript";
2
2
 
3
- export function getNodeJSDocComment(node: ts.Node): string {
3
+ export const getNodeJSDocComment = (node: ts.Node): string => {
4
4
  const start = node.getStart();
5
5
  const jsDocStart = node.getStart(undefined, true);
6
6
  return node.getSourceFile().getFullText().substring(jsDocStart, start).trim();
7
- }
7
+ };
@@ -1,14 +1,14 @@
1
1
  import ts from "typescript";
2
2
 
3
- export function getActualSymbol(symbol: ts.Symbol, typeChecker: ts.TypeChecker): ts.Symbol {
3
+ export const getActualSymbol = (symbol: ts.Symbol, typeChecker: ts.TypeChecker): ts.Symbol => {
4
4
  if (symbol.flags & ts.SymbolFlags.Alias) {
5
5
  symbol = typeChecker.getAliasedSymbol(symbol);
6
6
  }
7
7
 
8
8
  return symbol;
9
- }
9
+ };
10
10
 
11
- export function splitTransientSymbol(symbol: ts.Symbol, typeChecker: ts.TypeChecker): ts.Symbol[] {
11
+ export const splitTransientSymbol = (symbol: ts.Symbol, typeChecker: ts.TypeChecker): ts.Symbol[] => {
12
12
  // actually I think we even don't need to operate/use "Transient" symbols anywhere
13
13
  // it's kind of aliased symbol, but just merged
14
14
  // but it's hard to refractor everything to use array of symbols instead of just symbol
@@ -36,9 +36,9 @@ export function splitTransientSymbol(symbol: ts.Symbol, typeChecker: ts.TypeChec
36
36
  }
37
37
 
38
38
  return result;
39
- }
39
+ };
40
40
 
41
- export function getDeclarationsForSymbol(symbol: ts.Symbol): ts.Declaration[] {
41
+ export const getDeclarationsForSymbol = (symbol: ts.Symbol): ts.Declaration[] => {
42
42
  const result: ts.Declaration[] = [];
43
43
 
44
44
  if (symbol.declarations !== undefined) {
@@ -54,9 +54,9 @@ export function getDeclarationsForSymbol(symbol: ts.Symbol): ts.Declaration[] {
54
54
  }
55
55
 
56
56
  return result;
57
- }
57
+ };
58
58
 
59
- export function getExportsForSourceFile(typeChecker: ts.TypeChecker, sourceFileSymbol: ts.Symbol): ts.Symbol[] {
59
+ export const getExportsForSourceFile = (typeChecker: ts.TypeChecker, sourceFileSymbol: ts.Symbol): ts.Symbol[] => {
60
60
  if (sourceFileSymbol.exports !== undefined) {
61
61
  const commonJsExport = sourceFileSymbol.exports.get(ts.InternalSymbolName.ExportEquals);
62
62
  if (commonJsExport !== undefined) {
@@ -78,7 +78,7 @@ export function getExportsForSourceFile(typeChecker: ts.TypeChecker, sourceFileS
78
78
  }
79
79
 
80
80
  return result.map((symbol: ts.Symbol) => getActualSymbol(symbol, typeChecker));
81
- }
81
+ };
82
82
 
83
83
  const namedDeclarationKinds = [
84
84
  ts.SyntaxKind.InterfaceDeclaration,
@@ -92,9 +92,8 @@ const namedDeclarationKinds = [
92
92
  ts.SyntaxKind.Parameter,
93
93
  ];
94
94
 
95
- export function isNodeNamedDeclaration(node: ts.Node): node is ts.NamedDeclaration {
96
- return namedDeclarationKinds.indexOf(node.kind) !== -1;
97
- }
95
+ export const isNodeNamedDeclaration = (node: ts.Node): node is ts.NamedDeclaration =>
96
+ namedDeclarationKinds.indexOf(node.kind) !== -1;
98
97
 
99
98
  export type ClassMember =
100
99
  | ts.MethodDeclaration
@@ -102,15 +101,12 @@ export type ClassMember =
102
101
  | ts.GetAccessorDeclaration
103
102
  | ts.SetAccessorDeclaration;
104
103
 
105
- export function isClassMember(node: ts.Node): node is ClassMember {
106
- return (
107
- ts.isMethodDeclaration(node) || ts.isPropertyDeclaration(node) || ts.isGetAccessor(node) || ts.isSetAccessor(node)
108
- );
109
- }
104
+ export const isClassMember = (node: ts.Node): node is ClassMember =>
105
+ ts.isMethodDeclaration(node) || ts.isPropertyDeclaration(node) || ts.isGetAccessor(node) || ts.isSetAccessor(node);
110
106
 
111
- export function getClassOfMemberSymbol(
107
+ export const getClassOfMemberSymbol = (
112
108
  nodeSymbol: ts.Symbol,
113
- ): ts.ClassLikeDeclaration | ts.ObjectLiteralExpression | ts.TypeLiteralNode | ts.InterfaceDeclaration | null {
109
+ ): ts.ClassLikeDeclaration | ts.ObjectLiteralExpression | ts.TypeLiteralNode | ts.InterfaceDeclaration | null => {
114
110
  const classMembers = getClassMemberDeclarations(nodeSymbol);
115
111
  if (classMembers.length !== 0) {
116
112
  // we need any member to get class' declaration
@@ -124,13 +120,12 @@ export function getClassOfMemberSymbol(
124
120
  }
125
121
 
126
122
  return null;
127
- }
123
+ };
128
124
 
129
- export function hasPrivateKeyword(node: ClassMember | ts.ParameterDeclaration): boolean {
130
- return hasModifier(node, ts.SyntaxKind.PrivateKeyword);
131
- }
125
+ export const hasPrivateKeyword = (node: ClassMember | ts.ParameterDeclaration): boolean =>
126
+ hasModifier(node, ts.SyntaxKind.PrivateKeyword);
132
127
 
133
- function getModifiers(node: ts.Node): readonly ts.Modifier[] {
128
+ const getModifiers = (node: ts.Node): readonly ts.Modifier[] => {
134
129
  if (isBreakingTypeScriptApi(ts)) {
135
130
  if (!ts.canHaveModifiers(node)) {
136
131
  return [];
@@ -142,13 +137,12 @@ function getModifiers(node: ts.Node): readonly ts.Modifier[] {
142
137
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
143
138
  // @ts-ignore
144
139
  return node.modifiers || [];
145
- }
140
+ };
146
141
 
147
- export function hasModifier(node: ts.Node, modifier: ts.SyntaxKind): boolean {
148
- return getModifiers(node).some((mod) => mod.kind === modifier);
149
- }
142
+ export const hasModifier = (node: ts.Node, modifier: ts.SyntaxKind): boolean =>
143
+ getModifiers(node).some((mod) => mod.kind === modifier);
150
144
 
151
- function getDecorators(node: ts.Node): readonly unknown[] {
145
+ const getDecorators = (node: ts.Node): readonly unknown[] => {
152
146
  if (isBreakingTypeScriptApi(ts)) {
153
147
  if (!ts.canHaveDecorators(node)) {
154
148
  return [];
@@ -160,24 +154,19 @@ function getDecorators(node: ts.Node): readonly unknown[] {
160
154
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
161
155
  // @ts-ignore
162
156
  return node.decorators || [];
163
- }
157
+ };
164
158
 
165
- export function hasDecorators(node: ts.Node): boolean {
166
- return getDecorators(node).length !== 0;
167
- }
159
+ export const hasDecorators = (node: ts.Node): boolean => getDecorators(node).length !== 0;
168
160
 
169
- export function isConstructorParameter(node: ts.Node): node is ts.ParameterDeclaration {
170
- return (
171
- ts.isParameter(node) &&
172
- ts.isConstructorDeclaration(node.parent as ts.Node) &&
173
- (hasModifier(node, ts.SyntaxKind.PublicKeyword) ||
174
- hasModifier(node, ts.SyntaxKind.ProtectedKeyword) ||
175
- hasModifier(node, ts.SyntaxKind.PrivateKeyword) ||
176
- hasModifier(node, ts.SyntaxKind.ReadonlyKeyword))
177
- );
178
- }
161
+ export const isConstructorParameter = (node: ts.Node): node is ts.ParameterDeclaration =>
162
+ ts.isParameter(node) &&
163
+ ts.isConstructorDeclaration(node.parent as ts.Node) &&
164
+ (hasModifier(node, ts.SyntaxKind.PublicKeyword) ||
165
+ hasModifier(node, ts.SyntaxKind.ProtectedKeyword) ||
166
+ hasModifier(node, ts.SyntaxKind.PrivateKeyword) ||
167
+ hasModifier(node, ts.SyntaxKind.ReadonlyKeyword));
179
168
 
180
- function getClassMemberDeclarations(symbol: ts.Symbol | undefined): (ClassMember | ts.ParameterDeclaration)[] {
169
+ const getClassMemberDeclarations = (symbol: ts.Symbol | undefined): (ClassMember | ts.ParameterDeclaration)[] => {
181
170
  if (symbol === undefined) {
182
171
  return [];
183
172
  }
@@ -190,15 +179,13 @@ function getClassMemberDeclarations(symbol: ts.Symbol | undefined): (ClassMember
190
179
  return declarations.filter((x: ts.Declaration): x is ClassMember | ts.ParameterDeclaration => {
191
180
  return isClassMember(x) || isConstructorParameter(x);
192
181
  });
193
- }
182
+ };
194
183
 
195
- export function isSymbolClassMember(symbol: ts.Symbol | undefined): boolean {
196
- return getClassMemberDeclarations(symbol).length !== 0;
197
- }
184
+ export const isSymbolClassMember = (symbol: ts.Symbol | undefined): boolean =>
185
+ getClassMemberDeclarations(symbol).length !== 0;
198
186
 
199
- export function isPrivateClassMember(symbol: ts.Symbol | undefined): boolean {
200
- return getClassMemberDeclarations(symbol).some(hasPrivateKeyword);
201
- }
187
+ export const isPrivateClassMember = (symbol: ts.Symbol | undefined): boolean =>
188
+ getClassMemberDeclarations(symbol).some(hasPrivateKeyword);
202
189
 
203
190
  // decorators and modifiers-related api added in ts 4.8
204
191
  interface BreakingTypeScriptApi {
@@ -208,6 +195,5 @@ interface BreakingTypeScriptApi {
208
195
  getModifiers(node: ts.Node): readonly ts.Modifier[] | undefined;
209
196
  }
210
197
 
211
- function isBreakingTypeScriptApi(compiler: object): compiler is BreakingTypeScriptApi {
212
- return "canHaveDecorators" in compiler;
213
- }
198
+ const isBreakingTypeScriptApi = (compiler: object): compiler is BreakingTypeScriptApi =>
199
+ "canHaveDecorators" in compiler;
@@ -1,158 +0,0 @@
1
- import ts from "typescript";
2
-
3
- export type EnumValue = string | number;
4
-
5
- export interface EvaluationContext {
6
- localMembers: Map<string, EnumValue>;
7
- allowEnumReferences: boolean;
8
- }
9
-
10
- export class EnumEvaluator {
11
- private lastImplicitValue = -1;
12
-
13
- reset(): void {
14
- this.lastImplicitValue = -1;
15
- }
16
-
17
- evaluate(expr: ts.Expression, context: EvaluationContext): EnumValue {
18
- if (ts.isPrefixUnaryExpression(expr)) {
19
- return this.evaluateUnary(expr, context);
20
- } else if (ts.isBinaryExpression(expr)) {
21
- return this.evaluateBinary(expr, context);
22
- } else if (ts.isStringLiteralLike(expr)) {
23
- return expr.text;
24
- } else if (ts.isNumericLiteral(expr)) {
25
- return +expr.text;
26
- } else if (ts.isParenthesizedExpression(expr)) {
27
- return this.evaluate(expr.expression, context);
28
- } else if (ts.isIdentifier(expr)) {
29
- return this.evaluateIdentifier(expr, context);
30
- } else if (
31
- expr.kind === ts.SyntaxKind.TrueKeyword ||
32
- expr.kind === ts.SyntaxKind.FalseKeyword ||
33
- expr.kind === ts.SyntaxKind.NullKeyword
34
- ) {
35
- throw this.createError(expr, `Unsupported literal: ${ts.SyntaxKind[expr.kind]}`);
36
- }
37
-
38
- throw this.createError(expr, `Cannot evaluate expression: ${expr.getText()}`);
39
- }
40
-
41
- evaluateEnumMember(member: ts.EnumMember, context: EvaluationContext): EnumValue {
42
- if (!member.initializer) {
43
- return this.evaluateImplicitMember(member);
44
- }
45
-
46
- const value = this.evaluate(member.initializer, context);
47
-
48
- if (typeof value === "number") {
49
- this.lastImplicitValue = value;
50
- }
51
-
52
- return value;
53
- }
54
-
55
- private evaluateImplicitMember(member: ts.EnumMember): EnumValue {
56
- const name = ts.isIdentifier(member.name) ? member.name.text : `<computed>`;
57
- void name;
58
-
59
- if (this.lastImplicitValue === -1) {
60
- this.lastImplicitValue = 0;
61
- return 0;
62
- }
63
-
64
- const nextValue = this.lastImplicitValue + 1;
65
- this.lastImplicitValue = nextValue;
66
- return nextValue;
67
- }
68
-
69
- createLiteral(value: EnumValue): ts.Expression {
70
- if (typeof value === "string") {
71
- return ts.factory.createStringLiteral(value);
72
- } else {
73
- if (value < 0) {
74
- return ts.factory.createPrefixMinus(ts.factory.createNumericLiteral(Math.abs(value).toString()));
75
- }
76
- return ts.factory.createNumericLiteral(value.toString());
77
- }
78
- }
79
-
80
- private evaluateUnary(expr: ts.PrefixUnaryExpression, context: EvaluationContext): number {
81
- const value = this.evaluate(expr.operand, context);
82
- if (typeof value !== "number") {
83
- throw this.createError(expr, `Unary operator requires numeric value, got ${typeof value}`);
84
- }
85
-
86
- switch (expr.operator) {
87
- case ts.SyntaxKind.PlusToken:
88
- return value;
89
- case ts.SyntaxKind.MinusToken:
90
- return -value;
91
- case ts.SyntaxKind.TildeToken:
92
- return ~value;
93
- default:
94
- throw this.createError(expr, `Unsupported unary operator: ${ts.SyntaxKind[expr.operator]}`);
95
- }
96
- }
97
-
98
- private evaluateBinary(expr: ts.BinaryExpression, context: EvaluationContext): EnumValue {
99
- const left = this.evaluate(expr.left, context);
100
- const right = this.evaluate(expr.right, context);
101
-
102
- if (typeof left === "string" && typeof right === "string" && expr.operatorToken.kind === ts.SyntaxKind.PlusToken) {
103
- return left + right;
104
- }
105
-
106
- if (typeof left === "number" && typeof right === "number") {
107
- switch (expr.operatorToken.kind) {
108
- case ts.SyntaxKind.BarToken:
109
- return left | right;
110
- case ts.SyntaxKind.AmpersandToken:
111
- return left & right;
112
- case ts.SyntaxKind.GreaterThanGreaterThanToken:
113
- return left >> right;
114
- case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
115
- return left >>> right;
116
- case ts.SyntaxKind.LessThanLessThanToken:
117
- return left << right;
118
- case ts.SyntaxKind.CaretToken:
119
- return left ^ right;
120
- case ts.SyntaxKind.AsteriskToken:
121
- return left * right;
122
- case ts.SyntaxKind.SlashToken:
123
- return left / right;
124
- case ts.SyntaxKind.PlusToken:
125
- return left + right;
126
- case ts.SyntaxKind.MinusToken:
127
- return left - right;
128
- case ts.SyntaxKind.PercentToken:
129
- return left % right;
130
- case ts.SyntaxKind.AsteriskAsteriskToken:
131
- return left ** right;
132
- default:
133
- throw this.createError(expr, `Unsupported binary operator: ${ts.SyntaxKind[expr.operatorToken.kind]}`);
134
- }
135
- }
136
-
137
- throw this.createError(expr, `Cannot evaluate binary expression with types ${typeof left} and ${typeof right}`);
138
- }
139
-
140
- private evaluateIdentifier(expr: ts.Identifier, context: EvaluationContext): EnumValue {
141
- if (!context.allowEnumReferences) {
142
- throw this.createError(expr, `Cannot reference enum member here`);
143
- }
144
-
145
- const value = context.localMembers.get(expr.text);
146
- if (value === undefined) {
147
- throw this.createError(expr, `Undefined enum member: ${expr.text}`);
148
- }
149
-
150
- return value;
151
- }
152
-
153
- private createError(node: ts.Node, message: string): Error {
154
- const sourceFile = node.getSourceFile();
155
- const pos = sourceFile.getLineAndCharacterOfPosition(node.getStart());
156
- return new Error(`${sourceFile.fileName}:${pos.line + 1}:${pos.character}: ${message}`);
157
- }
158
- }
@@ -1,152 +0,0 @@
1
- import ts from "typescript";
2
- import { EnumValue, EvaluationContext } from "./evaluator";
3
- import { EnumEvaluator } from "./evaluator";
4
- import { isConstEnumSymbol } from "./utils";
5
- import { hasModifier } from "../utils/symbol-utils";
6
-
7
- export interface ConstEnumInfo {
8
- declaration: ts.EnumDeclaration;
9
- members: Map<string, ConstEnumMemberInfo>;
10
- isExported: boolean;
11
- sourceFile: ts.SourceFile;
12
- }
13
-
14
- export interface ConstEnumMemberInfo {
15
- declaration: ts.EnumMember;
16
- name: string;
17
- value: EnumValue | null;
18
- }
19
-
20
- export class ConstEnumRegistry {
21
- private readonly program: ts.Program;
22
- private readonly typeChecker: ts.TypeChecker;
23
- private readonly enumDeclarations: Map<string, ConstEnumInfo>;
24
-
25
- constructor(program: ts.Program) {
26
- this.program = program;
27
- this.typeChecker = program.getTypeChecker();
28
- this.enumDeclarations = new Map();
29
- this.collectConstEnumsFromEntryPoints();
30
- }
31
-
32
- getEnum(enumName: string): ConstEnumInfo | undefined {
33
- return this.enumDeclarations.get(enumName);
34
- }
35
-
36
- getEnumInfo(symbol: ts.Symbol): ConstEnumInfo | undefined {
37
- const name = this.getEnumSymbolName(symbol);
38
- return this.enumDeclarations.get(name);
39
- }
40
-
41
- getMemberValue(enumName: string, memberName: string): EnumValue | undefined {
42
- const enumInfo = this.enumDeclarations.get(enumName);
43
- if (!enumInfo) return undefined;
44
- const memberInfo = enumInfo.members.get(memberName);
45
- return memberInfo?.value ?? undefined;
46
- }
47
-
48
- getAllEnums(): ConstEnumInfo[] {
49
- return Array.from(this.enumDeclarations.values());
50
- }
51
-
52
- getEnumCount(): number {
53
- return this.enumDeclarations.size;
54
- }
55
-
56
- private collectConstEnumsFromEntryPoints(): void {
57
- const sourceFiles = this.program.getSourceFiles();
58
-
59
- for (const sourceFile of sourceFiles) {
60
- if (sourceFile.isDeclarationFile) {
61
- continue;
62
- }
63
-
64
- this.registerConstEnumFromSource(sourceFile);
65
- }
66
- }
67
-
68
- private registerConstEnumFromSource(sourceFile: ts.SourceFile): void {
69
- ts.forEachChild(sourceFile, (node) => {
70
- if (ts.isEnumDeclaration(node) && hasModifier(node, ts.SyntaxKind.ConstKeyword)) {
71
- const symbol = this.typeChecker.getSymbolAtLocation(node.name);
72
- if (symbol && isConstEnumSymbol(symbol)) {
73
- this.registerEnum(symbol, node, sourceFile);
74
- }
75
- }
76
- });
77
- }
78
-
79
- private registerEnum(symbol: ts.Symbol, declaration: ts.EnumDeclaration, sourceFile: ts.SourceFile): void {
80
- const name = this.getEnumSymbolName(symbol);
81
-
82
- if (this.enumDeclarations.has(name)) {
83
- return;
84
- }
85
-
86
- const isExported = this.hasExportModifier(declaration);
87
-
88
- const enumInfo: ConstEnumInfo = {
89
- declaration,
90
- members: new Map(),
91
- isExported,
92
- sourceFile,
93
- };
94
-
95
- this.evaluateEnumMembers(enumInfo);
96
-
97
- this.enumDeclarations.set(name, enumInfo);
98
- }
99
-
100
- private hasExportModifier(node: ts.Node): boolean {
101
- if (!ts.canHaveModifiers(node)) {
102
- return false;
103
- }
104
- const modifiers = ts.getModifiers(node);
105
- if (!modifiers) {
106
- return false;
107
- }
108
- return modifiers.some((m) => m.kind === ts.SyntaxKind.ExportKeyword);
109
- }
110
-
111
- private evaluateEnumMembers(enumInfo: ConstEnumInfo): void {
112
- const evaluator = new EnumEvaluator();
113
- evaluator.reset();
114
- const context: EvaluationContext = {
115
- localMembers: new Map(),
116
- allowEnumReferences: true,
117
- };
118
-
119
- for (const member of enumInfo.declaration.members) {
120
- if (!ts.isIdentifier(member.name)) continue;
121
-
122
- try {
123
- const value = evaluator.evaluateEnumMember(member, context);
124
- context.localMembers.set(member.name.text, value);
125
- enumInfo.members.set(member.name.text, {
126
- declaration: member,
127
- name: member.name.text,
128
- value,
129
- });
130
- } catch (error) {
131
- throw new Error(
132
- `Failed to evaluate const enum member ${enumInfo.declaration.name.text}.${member.name.text}: ${error}`,
133
- );
134
- }
135
- }
136
- }
137
-
138
- private getEnumDeclaration(symbol: ts.Symbol): ts.EnumDeclaration | null {
139
- const decl = symbol.declarations?.[0];
140
- if (decl && ts.isEnumDeclaration(decl)) {
141
- return decl;
142
- }
143
- return null;
144
- }
145
-
146
- private getEnumSymbolName(symbol: ts.Symbol): string {
147
- if (symbol.flags & ts.SymbolFlags.Alias) {
148
- return this.typeChecker.getAliasedSymbol(symbol).name;
149
- }
150
- return symbol.name;
151
- }
152
- }
@@ -1,13 +0,0 @@
1
- import ts from "typescript";
2
-
3
- export const isConstEnumSymbol = (symbol: ts.Symbol): boolean => (symbol.flags & ts.SymbolFlags.ConstEnum) !== 0;
4
-
5
- export const isConstEnumType = (type: ts.Type | undefined): boolean => {
6
- if (type) {
7
- const symbol = type.symbol || type.aliasSymbol;
8
- if (symbol) {
9
- return (symbol.flags & ts.SymbolFlags.ConstEnum) !== 0;
10
- }
11
- }
12
- return false;
13
- };