├── packages ├── creator │ ├── demo │ │ ├── fixtures.ts │ │ └── runner.ts │ ├── .npmignore │ ├── src │ │ ├── index.ts │ │ ├── statements.ts │ │ ├── class.ts │ │ ├── import.ts │ │ └── export.ts │ ├── tsconfig.json │ ├── README.md │ ├── jest.config.ts │ ├── package.json │ └── tests │ │ ├── statements.test.ts │ │ └── import.test.ts ├── helper │ ├── demo │ │ ├── fixtures.ts │ │ └── runner.ts │ ├── tests │ │ ├── fixtures │ │ │ ├── empty.fixture.ts │ │ │ ├── export.fixture.ts │ │ │ ├── import.fixture.ts │ │ │ ├── util.fixture.ts │ │ │ └── class.fixture.ts │ │ ├── export.test.ts │ │ ├── util.test.ts │ │ └── import.test.ts │ ├── .npmignore │ ├── src │ │ ├── index.ts │ │ └── util.ts │ ├── tsconfig.json │ ├── README.md │ ├── jest.config.ts │ └── package.json ├── modifier │ ├── demo │ │ ├── fixtures.ts │ │ └── runner.ts │ ├── tests │ │ └── fixtures │ │ │ ├── empty.fixture.ts │ │ │ ├── import.fixture.ts │ │ │ ├── export.fixture.ts │ │ │ ├── util.fixture.ts │ │ │ └── class.fixture.ts │ ├── .npmignore │ ├── src │ │ ├── index.ts │ │ ├── export.ts │ │ └── class.ts │ ├── README.md │ ├── tsconfig.json │ ├── jest.config.ts │ └── package.json ├── checker │ ├── tests │ │ ├── fixtures │ │ │ ├── empty.fixture.ts │ │ │ ├── export.fixture.ts │ │ │ ├── import.fixture.ts │ │ │ └── class.fixture.ts │ │ ├── export.test.ts │ │ └── class.test.ts │ ├── .npmignore │ ├── demo │ │ ├── fixtures.ts │ │ └── runner.ts │ ├── src │ │ ├── index.ts │ │ ├── export.ts │ │ └── class.ts │ ├── tsconfig.json │ ├── README.md │ ├── jest.config.ts │ └── package.json ├── cleaner │ ├── tests │ │ ├── fixtures │ │ │ ├── empty.fixture.ts │ │ │ ├── import.fixture.ts │ │ │ ├── export.fixture.ts │ │ │ ├── util.fixture.ts │ │ │ └── class.fixture.ts │ │ ├── class.test.ts │ │ └── import.test.ts │ ├── .npmignore │ ├── src │ │ ├── index.ts │ │ ├── import.ts │ │ └── class.ts │ ├── tsconfig.json │ ├── README.md │ ├── jest.config.ts │ └── package.json ├── example │ ├── src │ │ ├── check-import │ │ │ ├── source-without-import.ts │ │ │ ├── source-with-import.ts │ │ │ └── index.ts │ │ ├── append-statements │ │ │ ├── source.ts │ │ │ └── index.ts │ │ ├── create-import │ │ │ ├── source.ts │ │ │ └── index.ts │ │ ├── create-class │ │ │ ├── source.ts │ │ │ └── index.ts │ │ └── create-export │ │ │ ├── source.ts │ │ │ └── index.ts │ ├── tsconfig.json │ └── package.json └── types │ ├── .npmignore │ ├── src │ ├── index.ts │ ├── class.ts │ ├── import.ts │ └── types.ts │ ├── tsconfig.json │ ├── README.md │ └── package.json ├── jest.setup.ts ├── docs ├── example-docs │ ├── README.md │ └── .nojekyll ├── .vuepress │ ├── public │ │ ├── media │ │ │ ├── logo.jpeg │ │ │ └── VuePress_+_Netlify_CMS.png │ │ └── admin │ │ │ ├── index.html │ │ │ └── config.yml │ └── config.js ├── types-docs │ ├── .nojekyll │ ├── modules │ │ ├── import.md │ │ ├── class.md │ │ ├── types.md │ │ └── index.md │ ├── README.md │ ├── interfaces │ │ ├── types.IInterfaceProperty.md │ │ ├── types.IGenericTypeParam.md │ │ ├── types.IBaseDecoratorStruct.md │ │ ├── types.ISharedTypeStructure.md │ │ ├── types.IInterfaceIndexSignature.md │ │ ├── types.IBaseClassStructure.md │ │ ├── types.IBaseMethodParamStruct.md │ │ ├── types.IBasePropStruct.md │ │ └── types.IBaseMethodStruct.md │ └── enums │ │ ├── class.ClassMemberType.md │ │ └── import.ImportType.md ├── checker-docs │ ├── .nojekyll │ ├── README.md │ └── modules │ │ └── export.md ├── cleaner-docs │ ├── .nojekyll │ ├── README.md │ └── modules │ │ ├── index.md │ │ ├── import.md │ │ └── class.md ├── creator-docs │ ├── .nojekyll │ ├── README.md │ └── modules │ │ ├── statements.md │ │ ├── index.md │ │ ├── import.md │ │ ├── class.md │ │ └── export.md ├── helper-docs │ ├── .nojekyll │ ├── README.md │ └── modules │ │ └── util.md ├── modifier-docs │ ├── .nojekyll │ ├── README.md │ ├── interfaces │ │ ├── export.IBaseDeclarationStructure.md │ │ ├── export.IBaseVariableExportStructure.md │ │ ├── export.IBaseTypeAliasStructure.md │ │ └── export.IBaseInterfaceStructure.md │ └── modules │ │ ├── index.md │ │ └── import.md └── index.md ├── .npmignore ├── .husky ├── commit-msg └── pre-commit ├── lerna.json ├── .changeset ├── config.json └── README.md ├── tsconfig.build.json ├── DRAFT.md ├── tsconfig.json ├── jest.ci-config.ts ├── jest.preset.js ├── LICENSE ├── .github └── workflows │ └── ci.yml ├── jest.config.ts ├── .commitlintrc.js ├── scripts └── docs-gen.ts ├── README.md ├── .gitignore ├── package.json └── .cz-config.js /packages/creator/demo/fixtures.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /jest.setup.ts: -------------------------------------------------------------------------------- 1 | jest.setTimeout(10000); 2 | -------------------------------------------------------------------------------- /packages/helper/demo/fixtures.ts: -------------------------------------------------------------------------------- 1 | import * as fs from "fs"; 2 | -------------------------------------------------------------------------------- /packages/helper/tests/fixtures/empty.fixture.ts: -------------------------------------------------------------------------------- 1 | const a = "foo"; 2 | -------------------------------------------------------------------------------- /packages/modifier/demo/fixtures.ts: -------------------------------------------------------------------------------- 1 | export type B = { a: "1" }; 2 | -------------------------------------------------------------------------------- /packages/checker/tests/fixtures/empty.fixture.ts: -------------------------------------------------------------------------------- 1 | const foo = "foo"; 2 | -------------------------------------------------------------------------------- /packages/cleaner/tests/fixtures/empty.fixture.ts: -------------------------------------------------------------------------------- 1 | const a = "foo"; 2 | -------------------------------------------------------------------------------- /packages/modifier/tests/fixtures/empty.fixture.ts: -------------------------------------------------------------------------------- 1 | const a = "foo"; 2 | -------------------------------------------------------------------------------- /docs/example-docs/README.md: -------------------------------------------------------------------------------- 1 | @ts-morpher/example 2 | 3 | # @ts-morpher/example 4 | -------------------------------------------------------------------------------- /packages/example/src/check-import/source-without-import.ts: -------------------------------------------------------------------------------- 1 | const foo = "bar"; 2 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | coverage 3 | tests 4 | jest.config.ts 5 | jest.setup.ts 6 | LICENSE -------------------------------------------------------------------------------- /packages/checker/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | coverage 3 | tests 4 | jest.config.ts 5 | jest.setup.ts 6 | LICENSE -------------------------------------------------------------------------------- /packages/cleaner/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | coverage 3 | tests 4 | jest.config.ts 5 | jest.setup.ts 6 | LICENSE -------------------------------------------------------------------------------- /packages/creator/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | coverage 3 | tests 4 | jest.config.ts 5 | jest.setup.ts 6 | LICENSE -------------------------------------------------------------------------------- /packages/helper/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | coverage 3 | tests 4 | jest.config.ts 5 | jest.setup.ts 6 | LICENSE -------------------------------------------------------------------------------- /packages/modifier/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | coverage 3 | tests 4 | jest.config.ts 5 | jest.setup.ts 6 | LICENSE -------------------------------------------------------------------------------- /packages/types/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | coverage 3 | tests 4 | jest.config.ts 5 | jest.setup.ts 6 | LICENSE -------------------------------------------------------------------------------- /packages/checker/demo/fixtures.ts: -------------------------------------------------------------------------------- 1 | export class Foo { 2 | ss: string; 3 | static async ss() {} 4 | } 5 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn commitlint --edit $1 --verbose 5 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npm run docs:gen 5 | npm run test 6 | -------------------------------------------------------------------------------- /packages/checker/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./import"; 2 | export * from "./export"; 3 | export * from "./class"; 4 | -------------------------------------------------------------------------------- /packages/cleaner/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./import"; 2 | export * from "./export"; 3 | export * from "./class"; 4 | -------------------------------------------------------------------------------- /packages/types/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./import"; 2 | export * from "./types"; 3 | export * from "./class"; 4 | -------------------------------------------------------------------------------- /packages/modifier/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./import"; 2 | export * from "./export"; 3 | export * from "./class"; 4 | -------------------------------------------------------------------------------- /docs/.vuepress/public/media/logo.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinbuduLab/morpher/HEAD/docs/.vuepress/public/media/logo.jpeg -------------------------------------------------------------------------------- /packages/example/src/check-import/source-with-import.ts: -------------------------------------------------------------------------------- 1 | // pretend this is a required polyfill... 2 | import "typescript"; 3 | -------------------------------------------------------------------------------- /packages/helper/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./import"; 2 | export * from "./util"; 3 | export * from "./class"; 4 | export * from "./export"; 5 | -------------------------------------------------------------------------------- /packages/creator/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./import"; 2 | export * from "./statements"; 3 | export * from "./export"; 4 | export * from "./class"; 5 | -------------------------------------------------------------------------------- /docs/.vuepress/public/media/VuePress_+_Netlify_CMS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinbuduLab/morpher/HEAD/docs/.vuepress/public/media/VuePress_+_Netlify_CMS.png -------------------------------------------------------------------------------- /docs/types-docs/.nojekyll: -------------------------------------------------------------------------------- 1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. -------------------------------------------------------------------------------- /packages/modifier/README.md: -------------------------------------------------------------------------------- 1 | # TSMorpher-Modifier 2 | 3 | - [Documentation](https://ts-morpher.vercel.app) 4 | - [GitHub](https://github.com/LinbuduLab/morpher/) 5 | -------------------------------------------------------------------------------- /docs/checker-docs/.nojekyll: -------------------------------------------------------------------------------- 1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. -------------------------------------------------------------------------------- /docs/cleaner-docs/.nojekyll: -------------------------------------------------------------------------------- 1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. -------------------------------------------------------------------------------- /docs/creator-docs/.nojekyll: -------------------------------------------------------------------------------- 1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. -------------------------------------------------------------------------------- /docs/example-docs/.nojekyll: -------------------------------------------------------------------------------- 1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. -------------------------------------------------------------------------------- /docs/helper-docs/.nojekyll: -------------------------------------------------------------------------------- 1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. -------------------------------------------------------------------------------- /docs/modifier-docs/.nojekyll: -------------------------------------------------------------------------------- 1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. -------------------------------------------------------------------------------- /packages/example/src/append-statements/source.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs-extra"; 2 | import * as path from "path"; 3 | 4 | const singler = "Maroon 5"; 5 | 6 | const songName = "Sugar"; 7 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "packages/*" 4 | ], 5 | "npmClient": "yarn", 6 | "version": "0.5.0", 7 | "registry": "https://registry.npmjs.org/", 8 | "useWorkspaces": true 9 | } 10 | -------------------------------------------------------------------------------- /docs/types-docs/modules/import.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/types](../README.md) / import 2 | 3 | # Module: import 4 | 5 | ## Table of contents 6 | 7 | ### Enumerations 8 | 9 | - [ImportType](../enums/import.ImportType.md) 10 | -------------------------------------------------------------------------------- /docs/types-docs/modules/class.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/types](../README.md) / class 2 | 3 | # Module: class 4 | 5 | ## Table of contents 6 | 7 | ### Enumerations 8 | 9 | - [ClassMemberType](../enums/class.ClassMemberType.md) 10 | -------------------------------------------------------------------------------- /packages/checker/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.build.json", 3 | "compilerOptions": { 4 | "outDir": "dist" 5 | }, 6 | "include": ["src/**/*"], 7 | "exclude": ["dist", "node_modules", "tests"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/cleaner/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.build.json", 3 | "compilerOptions": { 4 | "outDir": "dist" 5 | }, 6 | "include": ["src/**/*"], 7 | "exclude": ["dist", "node_modules", "tests"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/creator/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.build.json", 3 | "compilerOptions": { 4 | "outDir": "dist" 5 | }, 6 | "include": ["src/**/*"], 7 | "exclude": ["dist", "node_modules", "tests"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.build.json", 3 | "compilerOptions": { 4 | "outDir": "dist" 5 | }, 6 | "include": ["src/**/*"], 7 | "exclude": ["dist", "node_modules", "tests"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/helper/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.build.json", 3 | "compilerOptions": { 4 | "outDir": "dist" 5 | }, 6 | "include": ["src/**/*"], 7 | "exclude": ["dist", "node_modules", "tests"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/modifier/tests/fixtures/import.fixture.ts: -------------------------------------------------------------------------------- 1 | import * as pathHelper from "path"; 2 | import fs from "fs"; 3 | import { transpileModule } from "typescript"; 4 | import { spawn, spawnSync, execFileSync } from "child_process"; 5 | -------------------------------------------------------------------------------- /packages/modifier/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.build.json", 3 | "compilerOptions": { 4 | "outDir": "dist" 5 | }, 6 | "include": ["src/**/*"], 7 | "exclude": ["dist", "node_modules", "tests"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/types/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.build.json", 3 | "compilerOptions": { 4 | "outDir": "dist" 5 | }, 6 | "include": ["src/**/*"], 7 | "exclude": ["dist", "node_modules", "tests"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/checker/tests/fixtures/export.fixture.ts: -------------------------------------------------------------------------------- 1 | export var varFoo = 1; 2 | export let letFoo = 1; 3 | export const constFoo = 1; 4 | 5 | export type Foo = string; 6 | 7 | export interface Bar { 8 | [key: string]: unknown; 9 | } 10 | -------------------------------------------------------------------------------- /packages/helper/tests/fixtures/export.fixture.ts: -------------------------------------------------------------------------------- 1 | export var varFoo = 1; 2 | export let letFoo = 1; 3 | export const constFoo = 1; 4 | 5 | export type Foo = string; 6 | 7 | export interface Bar { 8 | [key: string]: unknown; 9 | } 10 | -------------------------------------------------------------------------------- /packages/types/src/class.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @enum Class member scope (aka modifiers) 3 | */ 4 | export enum ClassMemberType { 5 | Static = "static", 6 | Protected = "protected", 7 | Public = "public", 8 | Private = "private", 9 | } 10 | -------------------------------------------------------------------------------- /packages/helper/README.md: -------------------------------------------------------------------------------- 1 | # TSMorpher-Helper 2 | 3 | Helper package of ts-morpher, dead simple TypeScript AST tool built on top of ts-morph. 4 | 5 | - [Documentation](https://ts-morpher.vercel.app) 6 | - [GitHub](https://github.com/LinbuduLab/morpher/) 7 | -------------------------------------------------------------------------------- /packages/types/README.md: -------------------------------------------------------------------------------- 1 | # TSMorpher-Types 2 | 3 | Types package of ts-morpher, dead simple TypeScript AST tool built on top of ts-morph. 4 | 5 | - [Documentation](https://ts-morpher.vercel.app) 6 | - [GitHub](https://github.com/LinbuduLab/morpher/) 7 | -------------------------------------------------------------------------------- /packages/checker/README.md: -------------------------------------------------------------------------------- 1 | # TSMorpher-Checker 2 | 3 | Checker package of ts-morpher, dead simple TypeScript AST tool built on top of ts-morph. 4 | 5 | - [Documentation](https://ts-morpher.vercel.app) 6 | - [GitHub](https://github.com/LinbuduLab/morpher/) 7 | -------------------------------------------------------------------------------- /packages/cleaner/README.md: -------------------------------------------------------------------------------- 1 | # TSMorpher-Cleaner 2 | 3 | Cleaner package of ts-morpher, dead simple TypeScript AST tool built on top of ts-morph. 4 | 5 | - [Documentation](https://ts-morpher.vercel.app) 6 | - [GitHub](https://github.com/LinbuduLab/morpher/) 7 | -------------------------------------------------------------------------------- /packages/creator/README.md: -------------------------------------------------------------------------------- 1 | # TSMorpher-Creator 2 | 3 | Creator package of ts-morpher, dead simple TypeScript AST tool built on top of ts-morph. 4 | 5 | - [Documentation](https://ts-morpher.vercel.app) 6 | - [GitHub](https://github.com/LinbuduLab/morpher/) 7 | -------------------------------------------------------------------------------- /docs/types-docs/README.md: -------------------------------------------------------------------------------- 1 | @ts-morpher/types 2 | 3 | # @ts-morpher/types 4 | 5 | ## Table of contents 6 | 7 | ### Modules 8 | 9 | - [class](modules/class.md) 10 | - [import](modules/import.md) 11 | - [index](modules/index.md) 12 | - [types](modules/types.md) 13 | -------------------------------------------------------------------------------- /docs/checker-docs/README.md: -------------------------------------------------------------------------------- 1 | @ts-morpher/checker 2 | 3 | # @ts-morpher/checker 4 | 5 | ## Table of contents 6 | 7 | ### Modules 8 | 9 | - [class](modules/class.md) 10 | - [export](modules/export.md) 11 | - [import](modules/import.md) 12 | - [index](modules/index.md) 13 | -------------------------------------------------------------------------------- /docs/cleaner-docs/README.md: -------------------------------------------------------------------------------- 1 | @ts-morpher/cleaner 2 | 3 | # @ts-morpher/cleaner 4 | 5 | ## Table of contents 6 | 7 | ### Modules 8 | 9 | - [class](modules/class.md) 10 | - [export](modules/export.md) 11 | - [import](modules/import.md) 12 | - [index](modules/index.md) 13 | -------------------------------------------------------------------------------- /docs/modifier-docs/README.md: -------------------------------------------------------------------------------- 1 | @ts-morpher/modifier 2 | 3 | # @ts-morpher/modifier 4 | 5 | ## Table of contents 6 | 7 | ### Modules 8 | 9 | - [class](modules/class.md) 10 | - [export](modules/export.md) 11 | - [import](modules/import.md) 12 | - [index](modules/index.md) 13 | -------------------------------------------------------------------------------- /docs/helper-docs/README.md: -------------------------------------------------------------------------------- 1 | @ts-morpher/helper 2 | 3 | # @ts-morpher/helper 4 | 5 | ## Table of contents 6 | 7 | ### Modules 8 | 9 | - [class](modules/class.md) 10 | - [export](modules/export.md) 11 | - [import](modules/import.md) 12 | - [index](modules/index.md) 13 | - [util](modules/util.md) 14 | -------------------------------------------------------------------------------- /packages/cleaner/tests/fixtures/import.fixture.ts: -------------------------------------------------------------------------------- 1 | import * as pathHelper from "path"; 2 | import fs from "fs"; 3 | import { transpileModule } from "typescript"; 4 | import cp, { spawnSync } from "child_process"; 5 | import type { BlobOptions } from "buffer"; 6 | import type { CompilerOptions } from "typescript"; 7 | -------------------------------------------------------------------------------- /packages/helper/tests/fixtures/import.fixture.ts: -------------------------------------------------------------------------------- 1 | import * as pathHelper from "path"; 2 | import fs from "fs"; 3 | import { transpileModule } from "typescript"; 4 | import cp, { spawnSync } from "child_process"; 5 | import type { BlobOptions } from "buffer"; 6 | import type { CompilerOptions } from "typescript"; 7 | -------------------------------------------------------------------------------- /docs/creator-docs/README.md: -------------------------------------------------------------------------------- 1 | @ts-morpher/creator 2 | 3 | # @ts-morpher/creator 4 | 5 | ## Table of contents 6 | 7 | ### Modules 8 | 9 | - [class](modules/class.md) 10 | - [export](modules/export.md) 11 | - [import](modules/import.md) 12 | - [index](modules/index.md) 13 | - [statements](modules/statements.md) 14 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@1.6.1/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "linked": [], 6 | "access": "restricted", 7 | "baseBranch": "master", 8 | "updateInternalDependencies": "patch", 9 | "ignore": [] 10 | } -------------------------------------------------------------------------------- /packages/example/src/create-import/source.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs-extra"; 2 | import * as path from "path"; 3 | import { exec, execSync, spawn, spawnSync } from "child_process"; 4 | import ts, { transpileModule, CompilerOptions, factory } from "typescript"; 5 | import type { SourceFile, VariableDeclarationKind } from "ts-morph"; 6 | -------------------------------------------------------------------------------- /packages/checker/tests/fixtures/import.fixture.ts: -------------------------------------------------------------------------------- 1 | import * as pathHelper from "path"; 2 | import fs from "fs"; 3 | import { transpileModule } from "typescript"; 4 | import cp, { spawnSync } from "child_process"; 5 | import type { BlobOptions } from "buffer"; 6 | import type { CompilerOptions } from "typescript"; 7 | import "net"; 8 | -------------------------------------------------------------------------------- /packages/helper/demo/runner.ts: -------------------------------------------------------------------------------- 1 | import path from "path"; 2 | import { Project, SyntaxKind } from "ts-morph"; 3 | import { getDefaultImportDeclarations } from "../src"; 4 | 5 | const source = new Project().addSourceFileAtPath( 6 | path.resolve(__dirname, "./fixtures.ts") 7 | ); 8 | 9 | getDefaultImportDeclarations(source); 10 | -------------------------------------------------------------------------------- /packages/checker/jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | preset: "../../jest.preset.js", 3 | transform: { 4 | "^.+\\.ts$": "ts-jest", 5 | }, 6 | collectCoverageFrom: ["/src/**/*"], 7 | moduleFileExtensions: ["ts", "js"], 8 | globals: { "ts-jest": { tsconfig: "/tsconfig.json" } }, 9 | displayName: "checker", 10 | }; 11 | -------------------------------------------------------------------------------- /packages/cleaner/jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | preset: "../../jest.preset.js", 3 | transform: { 4 | "^.+\\.ts$": "ts-jest", 5 | }, 6 | collectCoverageFrom: ["/src/**/*"], 7 | moduleFileExtensions: ["ts", "js"], 8 | globals: { "ts-jest": { tsconfig: "/tsconfig.json" } }, 9 | displayName: "cleaner", 10 | }; 11 | -------------------------------------------------------------------------------- /packages/creator/jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | preset: "../../jest.preset.js", 3 | transform: { 4 | "^.+\\.ts$": "ts-jest", 5 | }, 6 | collectCoverageFrom: ["/src/**/*"], 7 | moduleFileExtensions: ["ts", "js"], 8 | globals: { "ts-jest": { tsconfig: "/tsconfig.json" } }, 9 | displayName: "creator", 10 | }; 11 | -------------------------------------------------------------------------------- /packages/helper/jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | preset: "../../jest.preset.js", 3 | transform: { 4 | "^.+\\.ts$": "ts-jest", 5 | }, 6 | collectCoverageFrom: ["/src/**/*"], 7 | moduleFileExtensions: ["ts", "js"], 8 | globals: { "ts-jest": { tsconfig: "/tsconfig.json" } }, 9 | displayName: "helper", 10 | }; 11 | -------------------------------------------------------------------------------- /packages/cleaner/tests/fixtures/export.fixture.ts: -------------------------------------------------------------------------------- 1 | export var varFoo = 1; 2 | export let letFoo = 1; 3 | export const constFoo = 1; 4 | 5 | export type Foo1 = string; 6 | export type Foo2 = string; 7 | 8 | export interface Bar1 { 9 | [key: string]: unknown; 10 | } 11 | 12 | export interface Bar2 { 13 | [key: string]: unknown; 14 | } 15 | -------------------------------------------------------------------------------- /packages/cleaner/tests/fixtures/util.fixture.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs"; 2 | 3 | function deco1(): ClassDecorator { 4 | return () => {}; 5 | } 6 | 7 | @deco1() 8 | export class Foo { 9 | prop1: string; 10 | 11 | method1() {} 12 | } 13 | 14 | export type TT = string; 15 | 16 | export const foo = "foo"; 17 | 18 | export interface IIn {} 19 | -------------------------------------------------------------------------------- /packages/helper/tests/fixtures/util.fixture.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs"; 2 | 3 | function deco1(): ClassDecorator { 4 | return () => {}; 5 | } 6 | 7 | @deco1() 8 | export class Foo { 9 | prop1: string; 10 | 11 | method1() {} 12 | } 13 | 14 | export type TT = string; 15 | 16 | export const foo = "foo"; 17 | 18 | export interface IIn {} 19 | -------------------------------------------------------------------------------- /packages/modifier/jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | preset: "../../jest.preset.js", 3 | transform: { 4 | "^.+\\.ts$": "ts-jest", 5 | }, 6 | collectCoverageFrom: ["/src/**/*"], 7 | moduleFileExtensions: ["ts", "js"], 8 | globals: { "ts-jest": { tsconfig: "/tsconfig.json" } }, 9 | displayName: "modifier", 10 | }; 11 | -------------------------------------------------------------------------------- /packages/modifier/tests/fixtures/export.fixture.ts: -------------------------------------------------------------------------------- 1 | export var varFoo = 1; 2 | export let letFoo = 1; 3 | export const constFoo = 1; 4 | 5 | export type Foo1 = string; 6 | export type Foo2 = string; 7 | 8 | export interface Bar1 { 9 | [key: string]: unknown; 10 | } 11 | 12 | export interface Bar2 { 13 | [key: string]: unknown; 14 | } 15 | -------------------------------------------------------------------------------- /packages/modifier/tests/fixtures/util.fixture.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs"; 2 | 3 | function deco1(): ClassDecorator { 4 | return () => {}; 5 | } 6 | 7 | @deco1() 8 | export class Foo { 9 | prop1: string; 10 | 11 | method1() {} 12 | } 13 | 14 | export type TT = string; 15 | 16 | export const foo = "foo"; 17 | 18 | export interface IIn {} 19 | -------------------------------------------------------------------------------- /packages/checker/demo/runner.ts: -------------------------------------------------------------------------------- 1 | // import path from "path"; 2 | // import { Project, SyntaxKind } from "ts-morph"; 3 | // import { checkIsClassMemberStatic } from "../src"; 4 | 5 | // const source = new Project().addSourceFileAtPath( 6 | // path.resolve(__dirname, "./fixtures.ts") 7 | // ); 8 | 9 | // checkIsClassMemberStatic(source, "Foo", "ss"); 10 | -------------------------------------------------------------------------------- /packages/modifier/demo/runner.ts: -------------------------------------------------------------------------------- 1 | import { updateTypeExportStructure } from "../src/export"; 2 | import path from "path"; 3 | import { Project } from "ts-morph"; 4 | 5 | const source = new Project().addSourceFileAtPath( 6 | path.resolve(__dirname, "./fixtures.ts") 7 | ); 8 | 9 | updateTypeExportStructure(source, "A", { 10 | name: "B", 11 | type: "{a:'1'}", 12 | }); 13 | -------------------------------------------------------------------------------- /packages/example/src/create-class/source.ts: -------------------------------------------------------------------------------- 1 | import { PrimaryGeneratedColumn, Column, BaseEntity, Entity } from "typeorm"; 2 | 3 | export interface IUser { 4 | id: number; 5 | name: string; 6 | } 7 | 8 | @Entity() 9 | export default class User extends BaseEntity implements IUser { 10 | @PrimaryGeneratedColumn() 11 | id: number; 12 | @Column() 13 | name: string; 14 | } 15 | -------------------------------------------------------------------------------- /docs/.vuepress/public/admin/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Netlify CMS 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /packages/example/src/create-export/source.ts: -------------------------------------------------------------------------------- 1 | import { CompilerOptions, ParsedCommandLine } from "typescript"; 2 | 3 | export type DeepPartial = { 4 | [K in keyof T]?: T extends Record ? DeepPartial : T[K]; 5 | }; 6 | 7 | export interface IEmpty { 8 | [key: string]: any; 9 | } 10 | 11 | export interface IFoo extends IEmpty { 12 | parsedCommandLine: DeepPartial; 13 | compilerOptions: DeepPartial; 14 | } 15 | -------------------------------------------------------------------------------- /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": true, 3 | "compilerOptions": { 4 | "target": "ES2018", 5 | "module": "commonjs", 6 | "moduleResolution": "node", 7 | "lib": ["es2018", "esnext.asynciterable"], 8 | "experimentalDecorators": true, 9 | "emitDecoratorMetadata": true, 10 | "inlineSourceMap": false, 11 | "noImplicitThis": true, 12 | "noUnusedLocals": false, 13 | "stripInternal": true, 14 | "skipLibCheck": true, 15 | "pretty": true, 16 | "declaration": true, 17 | "esModuleInterop": true 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /DRAFT.md: -------------------------------------------------------------------------------- 1 | # Draft of API 2 | 3 | 分类:import / export / class / statements / types / function / jsx(tsx) 4 | 5 | ## Checker 6 | 7 | - 检查 class 是否有 xx 装饰器 8 | - 检查 class 是否存在 9 | - 检查 statements 是否存在 10 | - 检查 interface type 是否存在 11 | - 检查函数是否拥有重载 12 | - 检查函数是否有参数,返回值 13 | - 检查函数是否是箭头函数 14 | - 检查函数是否存在 15 | 16 | ## Helper 17 | 18 | ## Cleaner 19 | 20 | - 基于 ms 移除导入 21 | - 移除所有导入 22 | - 移除所有仅类型导入 23 | - 基于 var 移除导出 24 | - 基于 export type 移除导出 25 | - 移除 type interface 导出 26 | 27 | ## Creator 28 | 29 | - 创建导入 30 | - 创建仅类型导入 31 | - 创建导出 32 | - 创建类型导出 33 | 34 | ## Modifier 35 | 36 | ## Types 37 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": true, 3 | "compilerOptions": { 4 | "target": "ES2018", 5 | "module": "commonjs", 6 | "moduleResolution": "node", 7 | "lib": ["es2018"], 8 | "experimentalDecorators": true, 9 | "emitDecoratorMetadata": true, 10 | "sourceMap": true, 11 | "declarationMap": true, 12 | "inlineSourceMap": false, 13 | "noImplicitThis": true, 14 | "noUnusedLocals": false, 15 | "stripInternal": true, 16 | "skipLibCheck": true, 17 | "pretty": true, 18 | "strict": true, 19 | "strictNullChecks": true, 20 | "declaration": true, 21 | "esModuleInterop": true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/types/src/import.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @enum Import declaration type 3 | */ 4 | export enum ImportType { 5 | /** 6 | * e.g. import * as fs from "fs"; 7 | */ 8 | NAMESPACE_IMPORT = "NAMESPACE_IMPORT", 9 | /** 10 | * e.g. import { exec } from "child_process"; 11 | */ 12 | NAMED_IMPORT = "NAMED_IMPORT", 13 | /** 14 | * e.g. import path from "path"; 15 | */ 16 | DEFAULT_IMPORT = "DEFAULT_IMPORT", 17 | /** 18 | * e.g. import ts, { transpileModule } from "typescript"; 19 | */ 20 | DEFAULT_WITH_NAMED_IMPORT = "DEFAULT_WITH_NAMED_IMPORT", 21 | /** 22 | * e.g. import "ui-library/dist/index.css" 23 | */ 24 | DIRECTLY_IMPORT = "DIRECTLY_IMPORT", 25 | } 26 | -------------------------------------------------------------------------------- /packages/cleaner/tests/fixtures/class.fixture.ts: -------------------------------------------------------------------------------- 1 | function classDeco(): ClassDecorator { 2 | return () => {}; 3 | } 4 | 5 | function methodDeco(): MethodDecorator { 6 | return () => {}; 7 | } 8 | 9 | function propDeco(): PropertyDecorator { 10 | return () => {}; 11 | } 12 | 13 | @classDeco() 14 | class Foo { 15 | @propDeco() 16 | prop1: number; 17 | static prop2: string; 18 | private readonly prop3: string; 19 | public prop4: string; 20 | protected prop5: string; 21 | 22 | @methodDeco() 23 | public method1() {} 24 | 25 | private async method2() {} 26 | 27 | protected async method3() {} 28 | 29 | static method4() {} 30 | 31 | method5() {} 32 | } 33 | 34 | class Bar {} 35 | -------------------------------------------------------------------------------- /packages/helper/tests/fixtures/class.fixture.ts: -------------------------------------------------------------------------------- 1 | function classDeco(): ClassDecorator { 2 | return () => {}; 3 | } 4 | 5 | function methodDeco(): MethodDecorator { 6 | return () => {}; 7 | } 8 | 9 | function propDeco(): PropertyDecorator { 10 | return () => {}; 11 | } 12 | 13 | @classDeco() 14 | class Foo { 15 | @propDeco() 16 | prop1: number; 17 | static prop2: string; 18 | private readonly prop3: string; 19 | public prop4: string; 20 | protected prop5: string; 21 | 22 | @methodDeco() 23 | public method1() {} 24 | 25 | private async method2() {} 26 | 27 | protected async method3() {} 28 | 29 | static method4() {} 30 | 31 | method5() {} 32 | } 33 | 34 | class Bar {} 35 | -------------------------------------------------------------------------------- /packages/modifier/tests/fixtures/class.fixture.ts: -------------------------------------------------------------------------------- 1 | function classDeco(): ClassDecorator { 2 | return () => {}; 3 | } 4 | 5 | function methodDeco(): MethodDecorator { 6 | return () => {}; 7 | } 8 | 9 | function propDeco(): PropertyDecorator { 10 | return () => {}; 11 | } 12 | 13 | @classDeco() 14 | class Foo { 15 | @propDeco() 16 | prop1: number; 17 | static prop2: string; 18 | private readonly prop3: string; 19 | public prop4: string; 20 | protected prop5: string; 21 | 22 | @methodDeco() 23 | public method1() {} 24 | 25 | private async method2() {} 26 | 27 | protected async method3() {} 28 | 29 | static method4() {} 30 | 31 | method5() {} 32 | } 33 | 34 | class Bar {} 35 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | home: true 3 | heroText: Ts Morpher 4 | tagline: Dead simple TypeScript AST tools 5 | actionText: Get Started → 6 | actionLink: /quick-start/ 7 | features: 8 | - title: Yes, AST operations can be simple like this, no knowledge of compilation principles is required. 9 | details: Check declaration, get declaration, update declaration, and save declaration. 10 | - title: Various frequently used AST operations with specific package. 11 | details: We got 100+ functions for now, and it continues to grow. 12 | - title: Build library on top of this. 13 | details: Make your own CodeMod、Code Processor、AST Checker on top of ts morpher. 14 | footer: MIT Licensed | Copyright © 2021-present LinudbuLab 15 | --- 16 | -------------------------------------------------------------------------------- /packages/checker/tests/fixtures/class.fixture.ts: -------------------------------------------------------------------------------- 1 | function classDeco(): ClassDecorator { 2 | return () => {}; 3 | } 4 | 5 | function methodDeco(): MethodDecorator { 6 | return () => {}; 7 | } 8 | 9 | function propDeco(): PropertyDecorator { 10 | return () => {}; 11 | } 12 | 13 | const nonFactoryDeco: ClassDecorator = () => {}; 14 | 15 | @classDeco() 16 | @nonFactoryDeco 17 | class Foo { 18 | @propDeco() 19 | prop1: number; 20 | static prop2: string; 21 | private readonly prop3: string; 22 | public prop4: string; 23 | protected prop5: string; 24 | 25 | @methodDeco() 26 | public method1() {} 27 | 28 | private async method2() {} 29 | 30 | protected async method3() {} 31 | 32 | static method4() {} 33 | 34 | method5() {} 35 | } 36 | 37 | class Bar {} 38 | -------------------------------------------------------------------------------- /docs/types-docs/modules/types.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/types](../README.md) / types 2 | 3 | # Module: types 4 | 5 | ## Table of contents 6 | 7 | ### Interfaces 8 | 9 | - [IBaseClassStructure](../interfaces/types.IBaseClassStructure.md) 10 | - [IBaseDecoratorStruct](../interfaces/types.IBaseDecoratorStruct.md) 11 | - [IBaseMethodParamStruct](../interfaces/types.IBaseMethodParamStruct.md) 12 | - [IBaseMethodStruct](../interfaces/types.IBaseMethodStruct.md) 13 | - [IBasePropStruct](../interfaces/types.IBasePropStruct.md) 14 | - [IGenericTypeParam](../interfaces/types.IGenericTypeParam.md) 15 | - [IInterfaceIndexSignature](../interfaces/types.IInterfaceIndexSignature.md) 16 | - [IInterfaceProperty](../interfaces/types.IInterfaceProperty.md) 17 | - [ISharedTypeStructure](../interfaces/types.ISharedTypeStructure.md) 18 | -------------------------------------------------------------------------------- /jest.ci-config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | clearMocks: true, 3 | collectCoverage: true, 4 | coverageDirectory: "coverage", 5 | coverageProvider: "v8", 6 | coverageThreshold: {}, 7 | coverageReporters: ["json", "text", "lcov", "clover"], 8 | maxWorkers: 1, 9 | moduleDirectories: ["node_modules"], 10 | moduleFileExtensions: ["js", "ts"], 11 | projects: [ 12 | "/packages/checker", 13 | "/packages/creator", 14 | "/packages/cleaner", 15 | "/packages/modifier", 16 | // "/packages/helper", 17 | ], 18 | preset: "ts-jest", 19 | roots: [""], 20 | runner: "jest-runner", 21 | testEnvironment: "jest-environment-node", 22 | testMatch: ["**/__tests__/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).[tj]s?(x)"], 23 | testPathIgnorePatterns: ["/node_modules/"], 24 | verbose: true, 25 | }; 26 | -------------------------------------------------------------------------------- /packages/creator/demo/runner.ts: -------------------------------------------------------------------------------- 1 | import { createBaseInterfaceExport } from "../src/export"; 2 | import path from "path"; 3 | import { Project } from "ts-morph"; 4 | 5 | const source = new Project().addSourceFileAtPath( 6 | path.resolve(__dirname, "./fixtures.ts") 7 | ); 8 | 9 | createBaseInterfaceExport( 10 | source, 11 | "Foo", 12 | ["Bar", "Baz"], 13 | [ 14 | { 15 | keyName: "Foo", 16 | keyType: "string", 17 | returnType: "unknown", 18 | isReadonly: false, 19 | }, 20 | ], 21 | [ 22 | { 23 | name: "name", 24 | type: "string", 25 | }, 26 | { 27 | name: "age", 28 | type: "number", 29 | hasQuestionToken: true, 30 | }, 31 | { 32 | name: "other", 33 | type: "T", 34 | }, 35 | ], 36 | [ 37 | { 38 | name: "T", 39 | default: "'default_string_literal'", 40 | constraint: "string", 41 | }, 42 | ] 43 | ); 44 | -------------------------------------------------------------------------------- /packages/example/src/append-statements/index.ts: -------------------------------------------------------------------------------- 1 | import { Project } from "ts-morph"; 2 | import path from "path"; 3 | import fs from "fs-extra"; 4 | import assert from "assert"; 5 | import { 6 | createImportDeclaration, 7 | appendStatementAfterImportDeclarations, 8 | } from "@ts-morpher/creator"; 9 | import { ImportType } from "@ts-morpher/types"; 10 | 11 | const sourceFilePath = path.join(__dirname, "./source.ts"); 12 | 13 | fs.rmSync(sourceFilePath); 14 | fs.ensureFileSync(sourceFilePath); 15 | 16 | const p = new Project(); 17 | const source = p.addSourceFileAtPath(sourceFilePath); 18 | 19 | createImportDeclaration(source, "fs", "fs-extra", ImportType.DEFAULT_IMPORT); 20 | 21 | createImportDeclaration(source, "path", "path", ImportType.NAMESPACE_IMPORT); 22 | 23 | appendStatementAfterImportDeclarations(source, "const songName = 'Sugar';"); 24 | appendStatementAfterImportDeclarations(source, "const singler = 'Maroon 5'"); 25 | -------------------------------------------------------------------------------- /jest.preset.js: -------------------------------------------------------------------------------- 1 | /* 2 | * For a detailed explanation regarding each configuration property and type check, visit: 3 | * https://jestjs.io/docs/configuration 4 | */ 5 | 6 | module.exports = { 7 | clearMocks: true, 8 | collectCoverage: true, 9 | coverageDirectory: "coverage", 10 | coverageProvider: "v8", 11 | coverageReporters: ["json", "text", "lcov", "clover"], 12 | maxWorkers: "80%", 13 | moduleDirectories: ["node_modules"], 14 | moduleFileExtensions: ["js", "ts"], 15 | preset: "ts-jest", 16 | globals: { 17 | "ts-jest": { 18 | useESM: true, 19 | }, 20 | }, 21 | moduleNameMapper: { 22 | "^(\\.{1,2}/.*)\\.js$": "$1", 23 | }, 24 | roots: [""], 25 | runner: "jest-runner", 26 | testEnvironment: "jest-environment-node", 27 | testMatch: ["**/__tests__/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).[tj]s?(x)"], 28 | testPathIgnorePatterns: ["/node_modules/"], 29 | verbose: true, 30 | }; 31 | -------------------------------------------------------------------------------- /docs/creator-docs/modules/statements.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/creator](../README.md) / statements 2 | 3 | # Module: statements 4 | 5 | ## Table of contents 6 | 7 | ### Functions 8 | 9 | - [appendStatementAfterImportDeclarations](statements.md#appendstatementafterimportdeclarations) 10 | 11 | ## Functions 12 | 13 | ### appendStatementAfterImportDeclarations 14 | 15 | ▸ **appendStatementAfterImportDeclarations**(`source`, `appendStatement`, `apply?`): `void` 16 | 17 | Append statements after import declarations with new line, 18 | will append in top of file if no import declaration found. 19 | 20 | #### Parameters 21 | 22 | | Name | Type | Default value | Description | 23 | | :------ | :------ | :------ | :------ | 24 | | `source` | `SourceFile` | `undefined` | SourceFile | 25 | | `appendStatement` | `MaybeArray`<`string`\> | `undefined` | plain statements to insert | 26 | | `apply` | `boolean` | `true` | save source file | 27 | 28 | #### Returns 29 | 30 | `void` 31 | 32 | #### Defined in 33 | 34 | [statements.ts:11](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/creator/src/statements.ts#L11) 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Linbudu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/example/src/check-import/index.ts: -------------------------------------------------------------------------------- 1 | import { Project } from "ts-morph"; 2 | import path from "path"; 3 | import assert from "assert"; 4 | import { 5 | checkImportExistByModuleSpecifier, 6 | checkImportType, 7 | checkSourceFileHasImports, 8 | } from "@ts-morpher/checker"; 9 | import { getImportDeclarations } from "@ts-morpher/helper"; 10 | import { ImportType } from "@ts-morpher/types"; 11 | 12 | const sourceWithImportFilePath = path.join( 13 | __dirname, 14 | "./source-with-import.ts" 15 | ); 16 | 17 | const sourceWithoutImportFilePath = path.join( 18 | __dirname, 19 | "./source-without-import.ts" 20 | ); 21 | 22 | const p = new Project(); 23 | const source1 = p.addSourceFileAtPath(sourceWithImportFilePath); 24 | const source2 = p.addSourceFileAtPath(sourceWithoutImportFilePath); 25 | 26 | const i = getImportDeclarations(source1, "typescript"); 27 | const type = checkImportType(i); 28 | 29 | assert(checkSourceFileHasImports(source1) === true); 30 | assert(checkSourceFileHasImports(source2) === false); 31 | assert(type === ImportType.DIRECTLY_IMPORT); 32 | assert(checkImportExistByModuleSpecifier(source1, "typescript") === true); 33 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: TSMorpher-CI 2 | 3 | on: 4 | push: 5 | branches: [master, main] 6 | pull_request: 7 | types: [assigned, opened, synchronize, reopened] 8 | 9 | jobs: 10 | build: 11 | name: Build 12 | 13 | strategy: 14 | matrix: 15 | node-version: [14.x, 16.x] 16 | os: [ubuntu-latest, macOS-latest, windows-latest] 17 | 18 | runs-on: ${{ matrix.os }} 19 | 20 | steps: 21 | - name: Checkout 22 | uses: actions/checkout@master 23 | 24 | - name: Use Node.js ${{ matrix.node-version }} 25 | uses: actions/setup-node@v1 26 | with: 27 | node-version: ${{ matrix.node-version }} 28 | 29 | - name: Install Dependencies 30 | run: | 31 | yarn 32 | yarn workspaces info 33 | 34 | - name: Bootstrap 35 | run: | 36 | # npx lerna exec -- yarn 37 | # lerna link 38 | 39 | - name: Build Project 40 | run: yarn build 41 | 42 | - name: Unit Tests 43 | if: runner.os != 'Windows' 44 | run: | 45 | yarn test:ci 46 | bash <(curl -s https://codecov.io/bash) 47 | -------------------------------------------------------------------------------- /docs/types-docs/interfaces/types.IInterfaceProperty.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/types](../README.md) / [types](../modules/types.md) / IInterfaceProperty 2 | 3 | # Interface: IInterfaceProperty 4 | 5 | [types](../modules/types.md).IInterfaceProperty 6 | 7 | Interface property structure 8 | 9 | ## Table of contents 10 | 11 | ### Properties 12 | 13 | - [hasQuestionToken](types.IInterfaceProperty.md#hasquestiontoken) 14 | - [name](types.IInterfaceProperty.md#name) 15 | - [type](types.IInterfaceProperty.md#type) 16 | 17 | ## Properties 18 | 19 | ### hasQuestionToken 20 | 21 | • `Optional` **hasQuestionToken**: `boolean` 22 | 23 | #### Defined in 24 | 25 | [types.ts:42](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L42) 26 | 27 | ___ 28 | 29 | ### name 30 | 31 | • **name**: `string` 32 | 33 | #### Defined in 34 | 35 | [types.ts:41](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L41) 36 | 37 | ___ 38 | 39 | ### type 40 | 41 | • **type**: `string` \| `WriterFunction` 42 | 43 | #### Defined in 44 | 45 | [types.ts:43](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L43) 46 | -------------------------------------------------------------------------------- /jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | clearMocks: true, 3 | collectCoverage: true, 4 | coverageDirectory: "coverage", 5 | coverageProvider: "v8", 6 | coverageThreshold: { 7 | global: { 8 | branches: 100, 9 | functions: 100, 10 | lines: 100, 11 | statements: 100, 12 | }, 13 | }, 14 | coverageReporters: ["json", "text", "lcov", "clover", "html"], 15 | maxWorkers: "80%", 16 | moduleDirectories: ["node_modules"], 17 | moduleFileExtensions: ["js", "ts"], 18 | projects: [ 19 | "/packages/checker", 20 | "/packages/creator", 21 | "/packages/cleaner", 22 | "/packages/modifier", 23 | "/packages/helper", 24 | ], 25 | preset: "ts-jest", 26 | globals: { 27 | "ts-jest": { 28 | useESM: true, 29 | }, 30 | }, 31 | moduleNameMapper: { 32 | "^(\\.{1,2}/.*)\\.js$": "$1", 33 | }, 34 | roots: [""], 35 | runner: "jest-runner", 36 | testEnvironment: "jest-environment-node", 37 | testMatch: ["**/__tests__/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).[tj]s?(x)"], 38 | testPathIgnorePatterns: ["/node_modules/"], 39 | verbose: true, 40 | }; 41 | -------------------------------------------------------------------------------- /packages/creator/src/statements.ts: -------------------------------------------------------------------------------- 1 | import { SourceFile, SyntaxKind } from "ts-morph"; 2 | import { ensureArray, MaybeArray } from "@ts-morpher/helper"; 3 | 4 | /** 5 | * Append statements after import declarations with new line, 6 | * will append in top of file if no import declaration found. 7 | * @param source SourceFile 8 | * @param appendStatement plain statements to insert 9 | * @param apply save source file 10 | */ 11 | export function appendStatementAfterImportDeclarations( 12 | source: SourceFile, 13 | appendStatement: MaybeArray, 14 | apply = true 15 | ) { 16 | const importDeclarationList = source 17 | .getFirstChildByKind(SyntaxKind.SyntaxList) 18 | .getChildrenOfKind(SyntaxKind.ImportDeclaration); 19 | 20 | const appendIdx = importDeclarationList.length 21 | ? source.getLastChildByKind(SyntaxKind.ImportDeclaration)!.getChildIndex() + 22 | 1 23 | : 0; 24 | 25 | ensureArray(appendStatement).forEach((statement, idx) => { 26 | source.insertStatements(appendIdx, (writer) => { 27 | idx === 0 && writer.newLine(); 28 | writer.write(statement); 29 | }); 30 | }); 31 | 32 | apply && source.saveSync(); 33 | } 34 | -------------------------------------------------------------------------------- /packages/types/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ts-morpher/types", 3 | "version": "0.5.0", 4 | "main": "dist/index.js", 5 | "typedocMain": "src/index.ts", 6 | "license": "MIT", 7 | "private": false, 8 | "publishConfig": { 9 | "access": "public" 10 | }, 11 | "description": "Types package of ts-morpher, dead simple TypeScript AST tool built on top of ts-morph.", 12 | "keywords": [ 13 | "AST", 14 | "TypeScript", 15 | "ts-morph", 16 | "ts-morpher", 17 | "AST Operations" 18 | ], 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/linbudu599/morpher.git" 22 | }, 23 | "bugs": { 24 | "url": "https://github.com/linbudu599/morpher.git" 25 | }, 26 | "author": "linbudu599", 27 | "files": [ 28 | "dist/**/*.js", 29 | "dist/**/*.d.ts" 30 | ], 31 | "scripts": { 32 | "test": "jest", 33 | "dev": "tsnd --respawn --transpile-only ./demo.ts", 34 | "build": "tsc", 35 | "check": "tsc --noEmit" 36 | }, 37 | "dependencies": { 38 | "ow": "^0.28.1" 39 | }, 40 | "peerDependencies": { 41 | "ts-morph": "^12.0.0" 42 | }, 43 | "gitHead": "3f0d3a16c498b5b8ae929822a02273dfe1ade149" 44 | } 45 | -------------------------------------------------------------------------------- /docs/.vuepress/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | title: "LinubuduLab: TSMorpher", 3 | logo: "/media/logo.jpeg", 4 | description: "Dead simple TypeScript AST utilities", 5 | themeConfig: { 6 | nav: [ 7 | { 8 | text: "Packages", 9 | items: [ 10 | { text: "Checker", link: "/checker-docs/" }, 11 | { text: "Creator", link: "/creator-docs/" }, 12 | { text: "Cleaner", link: "/cleaner-docs/" }, 13 | { text: "Modifier", link: "/modifier-docs/" }, 14 | { text: "Helper", link: "/helper-docs/" }, 15 | ], 16 | }, 17 | { 18 | text: "Learn ts-morph", 19 | link: "https://ts-morph.com", 20 | }, 21 | { 22 | text: "GitHub", 23 | link: "https://github.com/LinbuduLab/morpher", 24 | }, 25 | ], 26 | sidebar: "auto", 27 | // algolia: { 28 | // apiKey: "", 29 | // indexName: "", 30 | // }, 31 | }, 32 | displayAllHeaders: true, 33 | lastUpdated: "Last Updated", 34 | nextLinks: false, 35 | prevLinks: false, 36 | editLinks: true, 37 | editLinkText: "Help me improve this page!", 38 | smoothScroll: true, 39 | }; 40 | -------------------------------------------------------------------------------- /packages/helper/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ts-morpher/helper", 3 | "version": "0.5.0", 4 | "main": "dist/index.js", 5 | "typedocMain": "src/index.ts", 6 | "license": "MIT", 7 | "private": false, 8 | "publishConfig": { 9 | "access": "public" 10 | }, 11 | "description": "Helper package of ts-morpher, dead simple TypeScript AST tool built on top of ts-morph.", 12 | "keywords": [ 13 | "AST", 14 | "TypeScript", 15 | "ts-morph", 16 | "ts-morpher", 17 | "AST Operations" 18 | ], 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/linbudu599/morpher.git" 22 | }, 23 | "bugs": { 24 | "url": "https://github.com/linbudu599/morpher.git" 25 | }, 26 | "author": "linbudu599", 27 | "files": [ 28 | "dist/**/*.js", 29 | "dist/**/*.d.ts" 30 | ], 31 | "scripts": { 32 | "test": "jest", 33 | "dev": "tsnd --respawn --transpile-only ./demo.ts", 34 | "build": "tsc", 35 | "check": "tsc --noEmit" 36 | }, 37 | "dependencies": { 38 | "@ts-morpher/types": "^0.5.0", 39 | "ow": "^0.28.1" 40 | }, 41 | "peerDependencies": { 42 | "ts-morph": "^12.0.0" 43 | }, 44 | "gitHead": "3f0d3a16c498b5b8ae929822a02273dfe1ade149" 45 | } 46 | -------------------------------------------------------------------------------- /packages/checker/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ts-morpher/checker", 3 | "version": "0.5.0", 4 | "main": "dist/index.js", 5 | "typedocMain": "src/index.ts", 6 | "license": "MIT", 7 | "private": false, 8 | "publishConfig": { 9 | "access": "public" 10 | }, 11 | "description": "Checker package of ts-morpher, dead simple TypeScript AST tool built on top of ts-morph.", 12 | "keywords": [ 13 | "AST", 14 | "TypeScript", 15 | "ts-morph", 16 | "ts-morpher", 17 | "AST Operations" 18 | ], 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/linbudu599/morpher.git" 22 | }, 23 | "bugs": { 24 | "url": "https://github.com/linbudu599/morpher.git" 25 | }, 26 | "author": "linbudu599", 27 | "files": [ 28 | "dist/**/*.js", 29 | "dist/**/*.d.ts" 30 | ], 31 | "scripts": { 32 | "test": "jest", 33 | "dev": "tsnd --respawn --transpile-only ./demo.ts", 34 | "build": "tsc", 35 | "check": "tsc --noEmit" 36 | }, 37 | "dependencies": { 38 | "@ts-morpher/helper": "^0.5.0", 39 | "@ts-morpher/types": "^0.5.0", 40 | "ow": "^0.28.1" 41 | }, 42 | "peerDependencies": { 43 | "ts-morph": "^12.0.0" 44 | }, 45 | "gitHead": "3f0d3a16c498b5b8ae929822a02273dfe1ade149" 46 | } 47 | -------------------------------------------------------------------------------- /.commitlintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extents: ["cz", "@commitlint/config-conventional"], 3 | rules: { 4 | "body-leading-blank": [2, "always"], 5 | "footer-leading-blank": [2, "always"], 6 | "header-max-length": [2, "always", 71], 7 | "scope-case": [ 8 | 2, 9 | "never", 10 | ["sentence-case", "start-case", "pascal-case", "upper-case"], 11 | ], 12 | "subject-case": [ 13 | 1, 14 | "never", 15 | ["sentence-case", "start-case", "pascal-case", "upper-case"], 16 | ], 17 | "subject-empty": [1, "always"], 18 | "subject-full-stop": [1, "always", "."], 19 | "type-case": [2, "always", "lower-case"], 20 | "type-empty": [2, "never"], 21 | "type-enum": [ 22 | 2, 23 | "always", 24 | [ 25 | "init", 26 | "feat", 27 | "fix", 28 | "chore", 29 | "docs", 30 | "perf", 31 | "ui", 32 | "ci", 33 | "fix-ci", 34 | "test", 35 | "refactor", 36 | "deploy", 37 | "style", 38 | "workspace", 39 | "i18n", 40 | "add", 41 | "minus", 42 | "del", 43 | "release", 44 | "example", 45 | "lint", 46 | "clean", 47 | "i18n", 48 | ], 49 | ], 50 | }, 51 | }; 52 | -------------------------------------------------------------------------------- /packages/cleaner/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ts-morpher/cleaner", 3 | "version": "0.5.0", 4 | "main": "dist/index.js", 5 | "typedocMain": "src/index.ts", 6 | "license": "MIT", 7 | "private": false, 8 | "publishConfig": { 9 | "access": "public" 10 | }, 11 | "description": "Cleaner package of ts-morpher, dead simple TypeScript AST tool built on top of ts-morph.", 12 | "keywords": [ 13 | "AST", 14 | "TypeScript", 15 | "ts-morph", 16 | "ts-morpher", 17 | "AST Operations" 18 | ], 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/linbudu599/morpher.git" 22 | }, 23 | "bugs": { 24 | "url": "https://github.com/linbudu599/morpher.git" 25 | }, 26 | "author": "linbudu599", 27 | "files": [ 28 | "dist/**/*.js", 29 | "dist/**/*.d.ts" 30 | ], 31 | "scripts": { 32 | "test": "jest", 33 | "dev": "tsnd --respawn --transpile-only ./demo.ts", 34 | "build": "tsc", 35 | "check": "tsc --noEmit" 36 | }, 37 | "dependencies": { 38 | "@ts-morpher/checker": "^0.5.0", 39 | "@ts-morpher/helper": "^0.5.0", 40 | "@ts-morpher/types": "^0.5.0", 41 | "ow": "^0.28.1" 42 | }, 43 | "peerDependencies": { 44 | "ts-morph": "^12.0.0" 45 | }, 46 | "gitHead": "3f0d3a16c498b5b8ae929822a02273dfe1ade149" 47 | } 48 | -------------------------------------------------------------------------------- /packages/creator/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ts-morpher/creator", 3 | "version": "0.5.0", 4 | "main": "dist/index.js", 5 | "typedocMain": "src/index.ts", 6 | "license": "MIT", 7 | "private": false, 8 | "publishConfig": { 9 | "access": "public" 10 | }, 11 | "description": "Creator package of ts-morpher, dead simple TypeScript AST tool built on top of ts-morph.", 12 | "keywords": [ 13 | "AST", 14 | "TypeScript", 15 | "ts-morph", 16 | "ts-morpher", 17 | "AST Operations" 18 | ], 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/linbudu599/morpher.git" 22 | }, 23 | "bugs": { 24 | "url": "https://github.com/linbudu599/morpher.git" 25 | }, 26 | "author": "linbudu599", 27 | "files": [ 28 | "dist/**/*.js", 29 | "dist/**/*.d.ts" 30 | ], 31 | "scripts": { 32 | "test": "jest", 33 | "dev": "tsnd --respawn --transpile-only ./demo.ts", 34 | "build": "tsc", 35 | "check": "tsc --noEmit" 36 | }, 37 | "dependencies": { 38 | "@ts-morpher/checker": "^0.5.0", 39 | "@ts-morpher/helper": "^0.5.0", 40 | "@ts-morpher/types": "^0.5.0", 41 | "ow": "^0.28.1" 42 | }, 43 | "peerDependencies": { 44 | "ts-morph": "^12.0.0" 45 | }, 46 | "gitHead": "3f0d3a16c498b5b8ae929822a02273dfe1ade149" 47 | } 48 | -------------------------------------------------------------------------------- /scripts/docs-gen.ts: -------------------------------------------------------------------------------- 1 | import execa from "execa"; 2 | import fs from "fs-extra"; 3 | import path from "path"; 4 | 5 | interface IPackageDocItem { 6 | entryPoints: string; 7 | tsconfig: string; 8 | out: string; 9 | } 10 | 11 | async function main() { 12 | const packageDocInfoList: IPackageDocItem[] = []; 13 | const packageList = fs.readdirSync(path.resolve(__dirname, "../packages")); 14 | const commandList = []; 15 | 16 | for (const pkg of packageList) { 17 | pkg !== "example" && 18 | packageDocInfoList.push({ 19 | entryPoints: `packages/${pkg}/src`, 20 | tsconfig: `packages/${pkg}/tsconfig.json`, 21 | out: `docs/${pkg}-docs`, 22 | }); 23 | } 24 | 25 | for (const docInfo of packageDocInfoList) { 26 | commandList.push( 27 | `typedoc --entryPointStrategy expand --entryPoints ${docInfo.entryPoints} --tsconfig ${docInfo.tsconfig} --out ${docInfo.out} --readme none` 28 | ); 29 | } 30 | 31 | for (const command of commandList) { 32 | try { 33 | await execa(command, { 34 | stdio: "inherit", 35 | shell: true, 36 | preferLocal: true, 37 | }); 38 | } catch (error) { 39 | console.log("error: ", error); 40 | } 41 | } 42 | 43 | // Postprocess 44 | } 45 | 46 | (async () => { 47 | await main(); 48 | })(); 49 | -------------------------------------------------------------------------------- /docs/types-docs/interfaces/types.IGenericTypeParam.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/types](../README.md) / [types](../modules/types.md) / IGenericTypeParam 2 | 3 | # Interface: IGenericTypeParam 4 | 5 | [types](../modules/types.md).IGenericTypeParam 6 | 7 | Shared type parameter structure 8 | 9 | ## Table of contents 10 | 11 | ### Properties 12 | 13 | - [constraint](types.IGenericTypeParam.md#constraint) 14 | - [default](types.IGenericTypeParam.md#default) 15 | - [name](types.IGenericTypeParam.md#name) 16 | 17 | ## Properties 18 | 19 | ### constraint 20 | 21 | • `Optional` **constraint**: `string` \| `WriterFunction` 22 | 23 | Default in `T extends Condition = Default` 24 | 25 | #### Defined in 26 | 27 | [types.ts:17](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L17) 28 | 29 | ___ 30 | 31 | ### default 32 | 33 | • `Optional` **default**: `string` \| `WriterFunction` 34 | 35 | Condition in `T extends Condition = Default` 36 | 37 | #### Defined in 38 | 39 | [types.ts:13](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L13) 40 | 41 | ___ 42 | 43 | ### name 44 | 45 | • **name**: `string` 46 | 47 | T in `T extends Condition = Default` 48 | 49 | #### Defined in 50 | 51 | [types.ts:9](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L9) 52 | -------------------------------------------------------------------------------- /docs/types-docs/enums/class.ClassMemberType.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/types](../README.md) / [class](../modules/class.md) / ClassMemberType 2 | 3 | # Enumeration: ClassMemberType 4 | 5 | [class](../modules/class.md).ClassMemberType 6 | 7 | ## Table of contents 8 | 9 | ### Enumeration members 10 | 11 | - [Private](class.ClassMemberType.md#private) 12 | - [Protected](class.ClassMemberType.md#protected) 13 | - [Public](class.ClassMemberType.md#public) 14 | - [Static](class.ClassMemberType.md#static) 15 | 16 | ## Enumeration members 17 | 18 | ### Private 19 | 20 | • **Private** = `"private"` 21 | 22 | #### Defined in 23 | 24 | [class.ts:8](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/class.ts#L8) 25 | 26 | ___ 27 | 28 | ### Protected 29 | 30 | • **Protected** = `"protected"` 31 | 32 | #### Defined in 33 | 34 | [class.ts:6](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/class.ts#L6) 35 | 36 | ___ 37 | 38 | ### Public 39 | 40 | • **Public** = `"public"` 41 | 42 | #### Defined in 43 | 44 | [class.ts:7](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/class.ts#L7) 45 | 46 | ___ 47 | 48 | ### Static 49 | 50 | • **Static** = `"static"` 51 | 52 | #### Defined in 53 | 54 | [class.ts:5](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/class.ts#L5) 55 | -------------------------------------------------------------------------------- /docs/types-docs/interfaces/types.IBaseDecoratorStruct.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/types](../README.md) / [types](../modules/types.md) / IBaseDecoratorStruct 2 | 3 | # Interface: IBaseDecoratorStruct 4 | 5 | [types](../modules/types.md).IBaseDecoratorStruct 6 | 7 | Decorator structure 8 | 9 | ## Table of contents 10 | 11 | ### Properties 12 | 13 | - [arguments](types.IBaseDecoratorStruct.md#arguments) 14 | - [name](types.IBaseDecoratorStruct.md#name) 15 | - [typeArguments](types.IBaseDecoratorStruct.md#typearguments) 16 | 17 | ## Properties 18 | 19 | ### arguments 20 | 21 | • `Optional` **arguments**: `WriterFunction` \| (`string` \| `WriterFunction`)[] 22 | 23 | Arguments for a decorator factory. 24 | 25 | **`remarks`** Provide an empty array to make the structure a decorator factory. 26 | 27 | #### Defined in 28 | 29 | [types.ts:78](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L78) 30 | 31 | ___ 32 | 33 | ### name 34 | 35 | • **name**: `string` 36 | 37 | #### Defined in 38 | 39 | [types.ts:73](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L73) 40 | 41 | ___ 42 | 43 | ### typeArguments 44 | 45 | • `Optional` **typeArguments**: `string`[] 46 | 47 | #### Defined in 48 | 49 | [types.ts:79](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L79) 50 | -------------------------------------------------------------------------------- /packages/modifier/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ts-morpher/modifier", 3 | "version": "0.5.0", 4 | "main": "dist/index.js", 5 | "typedocMain": "src/index.ts", 6 | "license": "MIT", 7 | "private": false, 8 | "publishConfig": { 9 | "access": "public" 10 | }, 11 | "description": "Modifier package of ts-morpher, dead simple TypeScript AST tool built on top of ts-morph.", 12 | "keywords": [ 13 | "AST", 14 | "TypeScript", 15 | "ts-morph", 16 | "ts-morpher", 17 | "AST Operations" 18 | ], 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/linbudu599/morpher.git" 22 | }, 23 | "bugs": { 24 | "url": "https://github.com/linbudu599/morpher.git" 25 | }, 26 | "author": "linbudu599", 27 | "files": [ 28 | "dist/**/*.js", 29 | "dist/**/*.d.ts" 30 | ], 31 | "scripts": { 32 | "test": "jest", 33 | "dev": "tsnd --respawn --transpile-only ./demo.ts", 34 | "build": "tsc", 35 | "check": "tsc --noEmit" 36 | }, 37 | "dependencies": { 38 | "@ts-morpher/checker": "^0.5.0", 39 | "@ts-morpher/creator": "^0.5.0", 40 | "@ts-morpher/helper": "^0.5.0", 41 | "@ts-morpher/types": "^0.5.0", 42 | "ow": "^0.28.1" 43 | }, 44 | "peerDependencies": { 45 | "ts-morph": "^12.0.0" 46 | }, 47 | "gitHead": "3f0d3a16c498b5b8ae929822a02273dfe1ade149" 48 | } 49 | -------------------------------------------------------------------------------- /packages/example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ts-morpher/example", 3 | "version": "0.5.0", 4 | "description": "> TODO: description", 5 | "author": "linbudu599 ", 6 | "homepage": "https://github.com/linbudu599/morpher#readme", 7 | "publishConfig": { 8 | "access": "public" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/linbudu599/morpher.git" 13 | }, 14 | "scripts": { 15 | "dev:create-import": "ts-node-dev --respawn --transpile-only src/create-import/index.ts", 16 | "dev:create-class": "ts-node-dev --respawn --transpile-only src/create-class/index.ts", 17 | "dev:create-export": "ts-node-dev --respawn --transpile-only src/create-export/index.ts", 18 | "dev:append-statements": "ts-node-dev --respawn --transpile-only src/append-statements/index.ts", 19 | "dev:check-import": "ts-node-dev --respawn --transpile-only src/check-import/index.ts" 20 | }, 21 | "bugs": { 22 | "url": "https://github.com/linbudu599/morpher/issues" 23 | }, 24 | "dependencies": { 25 | "@ts-morpher/checker": "^0.5.0", 26 | "@ts-morpher/cleaner": "^0.5.0", 27 | "@ts-morpher/creator": "^0.5.0", 28 | "@ts-morpher/helper": "^0.5.0", 29 | "@ts-morpher/modifier": "^0.5.0", 30 | "@ts-morpher/types": "^0.5.0", 31 | "fs-extra": "^10.0.0", 32 | "ts-morph": "^12.0.0", 33 | "ts-node-dev": "^1.1.8" 34 | }, 35 | "gitHead": "3f0d3a16c498b5b8ae929822a02273dfe1ade149" 36 | } 37 | -------------------------------------------------------------------------------- /packages/example/src/create-export/index.ts: -------------------------------------------------------------------------------- 1 | import { Project } from "ts-morph"; 2 | import path from "path"; 3 | import fs from "fs-extra"; 4 | import assert from "assert"; 5 | import { 6 | createBaseInterfaceExport, 7 | createBaseTypeExport, 8 | createImportDeclaration, 9 | } from "@ts-morpher/creator"; 10 | import { ImportType } from "@ts-morpher/types"; 11 | 12 | const sourceFilePath = path.join(__dirname, "./source.ts"); 13 | 14 | fs.rmSync(sourceFilePath); 15 | fs.ensureFileSync(sourceFilePath); 16 | 17 | const p = new Project(); 18 | const source = p.addSourceFileAtPath(sourceFilePath); 19 | 20 | createImportDeclaration( 21 | source, 22 | ["CompilerOptions", "ParsedCommandLine"], 23 | "typescript", 24 | ImportType.NAMED_IMPORT 25 | ); 26 | 27 | createBaseTypeExport( 28 | source, 29 | "DeepPartial", 30 | `{ 31 | [K in keyof T]?: T extends Record ? DeepPartial : T[K]; 32 | }`, 33 | [{ name: "T", constraint: "any" }] 34 | ); 35 | 36 | createBaseInterfaceExport( 37 | source, 38 | "IEmpty", 39 | [], 40 | [{ keyName: "key", keyType: "string", returnType: "any" }], 41 | [] 42 | ); 43 | 44 | createBaseInterfaceExport( 45 | source, 46 | "IFoo", 47 | ["IEmpty"], 48 | [], 49 | [ 50 | { 51 | name: "parsedCommandLine", 52 | type: "DeepPartial", 53 | }, 54 | { 55 | name: "compilerOptions", 56 | type: "DeepPartial", 57 | }, 58 | ] 59 | ); 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Morpher 2 | 3 | ![GitHub Workflow Status](https://img.shields.io/github/workflow/status/LinbuduLab/morpher/TSMorpher-CI) 4 | ![Codecov](https://img.shields.io/codecov/c/github/LinbuduLab/morpher) 5 | ![npm (scoped)](https://img.shields.io/npm/v/@ts-morpher/checker) 6 | 7 | ## Packages 8 | 9 | | Package | Version | 10 | | ----------------------------- | :----------------------------------------------------------------------------------- | 11 | | [checker](packages/checker) | ![checker version](https://img.shields.io/npm/v/@ts-morpher/checker.svg?label=%20) | 12 | | [cleaner](packages/cleaner) | ![cleaner version](https://img.shields.io/npm/v/@ts-morpher/cleaner.svg?label=%20) | 13 | | [types](packages/types) | ![types version](https://img.shields.io/npm/v/@ts-morpher/types.svg?label=%20) | 14 | | [modifier](packages/modifier) | ![modifier version](https://img.shields.io/npm/v/@ts-morpher/modifier.svg?label=%20) | 15 | | [creator](packages/creator) | ![creator version](https://img.shields.io/npm/v/@ts-morpher/creator.svg?label=%20) | 16 | | [helper](packages/helper) | ![helper version](https://img.shields.io/npm/v/@ts-morpher/helper.svg?label=%20) | 17 | 18 | ## License 19 | 20 | [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FLinbuduLab%2Fmorpher.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2FLinbuduLab%2Fmorpher?ref=badge_shield) 21 | -------------------------------------------------------------------------------- /docs/types-docs/interfaces/types.ISharedTypeStructure.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/types](../README.md) / [types](../modules/types.md) / ISharedTypeStructure 2 | 3 | # Interface: ISharedTypeStructure 4 | 5 | [types](../modules/types.md).ISharedTypeStructure 6 | 7 | Type alias structure 8 | 9 | ## Table of contents 10 | 11 | ### Properties 12 | 13 | - [hasDeclareKeyword](types.ISharedTypeStructure.md#hasdeclarekeyword) 14 | - [isExported](types.ISharedTypeStructure.md#isexported) 15 | - [name](types.ISharedTypeStructure.md#name) 16 | - [typeParameters](types.ISharedTypeStructure.md#typeparameters) 17 | 18 | ## Properties 19 | 20 | ### hasDeclareKeyword 21 | 22 | • `Optional` **hasDeclareKeyword**: `boolean` 23 | 24 | #### Defined in 25 | 26 | [types.ts:55](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L55) 27 | 28 | ___ 29 | 30 | ### isExported 31 | 32 | • `Optional` **isExported**: `boolean` 33 | 34 | #### Defined in 35 | 36 | [types.ts:54](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L54) 37 | 38 | ___ 39 | 40 | ### name 41 | 42 | • **name**: `string` 43 | 44 | #### Defined in 45 | 46 | [types.ts:49](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L49) 47 | 48 | ___ 49 | 50 | ### typeParameters 51 | 52 | • `Optional` **typeParameters**: [`IGenericTypeParam`](types.IGenericTypeParam.md)[] 53 | 54 | [IGenericTypeParam](types.IGenericTypeParam.md) 55 | 56 | #### Defined in 57 | 58 | [types.ts:53](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L53) 59 | -------------------------------------------------------------------------------- /docs/types-docs/interfaces/types.IInterfaceIndexSignature.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/types](../README.md) / [types](../modules/types.md) / IInterfaceIndexSignature 2 | 3 | # Interface: IInterfaceIndexSignature 4 | 5 | [types](../modules/types.md).IInterfaceIndexSignature 6 | 7 | Interface index signature structure 8 | 9 | ## Table of contents 10 | 11 | ### Properties 12 | 13 | - [isReadonly](types.IInterfaceIndexSignature.md#isreadonly) 14 | - [keyName](types.IInterfaceIndexSignature.md#keyname) 15 | - [keyType](types.IInterfaceIndexSignature.md#keytype) 16 | - [returnType](types.IInterfaceIndexSignature.md#returntype) 17 | 18 | ## Properties 19 | 20 | ### isReadonly 21 | 22 | • `Optional` **isReadonly**: `boolean` 23 | 24 | #### Defined in 25 | 26 | [types.ts:35](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L35) 27 | 28 | ___ 29 | 30 | ### keyName 31 | 32 | • **keyName**: `string` 33 | 34 | key in `[key: string]: any` 35 | 36 | #### Defined in 37 | 38 | [types.ts:26](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L26) 39 | 40 | ___ 41 | 42 | ### keyType 43 | 44 | • **keyType**: `string` 45 | 46 | string in `[key: string]: any` 47 | 48 | #### Defined in 49 | 50 | [types.ts:30](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L30) 51 | 52 | ___ 53 | 54 | ### returnType 55 | 56 | • **returnType**: `string` \| `WriterFunction` 57 | 58 | any in `[key: string]: any` 59 | 60 | #### Defined in 61 | 62 | [types.ts:34](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L34) 63 | -------------------------------------------------------------------------------- /docs/modifier-docs/interfaces/export.IBaseDeclarationStructure.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/modifier](../README.md) / [export](../modules/export.md) / IBaseDeclarationStructure 2 | 3 | # Interface: IBaseDeclarationStructure 4 | 5 | [export](../modules/export.md).IBaseDeclarationStructure 6 | 7 | Basic variable declaration structure. 8 | 9 | ## Table of contents 10 | 11 | ### Properties 12 | 13 | - [hasExclamationToken](export.IBaseDeclarationStructure.md#hasexclamationtoken) 14 | - [initializer](export.IBaseDeclarationStructure.md#initializer) 15 | - [name](export.IBaseDeclarationStructure.md#name) 16 | - [type](export.IBaseDeclarationStructure.md#type) 17 | 18 | ## Properties 19 | 20 | ### hasExclamationToken 21 | 22 | • `Optional` **hasExclamationToken**: `boolean` 23 | 24 | #### Defined in 25 | 26 | [modifier/src/export.ts:69](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/modifier/src/export.ts#L69) 27 | 28 | ___ 29 | 30 | ### initializer 31 | 32 | • `Optional` **initializer**: `string` \| `WriterFunction` 33 | 34 | #### Defined in 35 | 36 | [modifier/src/export.ts:70](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/modifier/src/export.ts#L70) 37 | 38 | ___ 39 | 40 | ### name 41 | 42 | • **name**: `string` 43 | 44 | #### Defined in 45 | 46 | [modifier/src/export.ts:68](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/modifier/src/export.ts#L68) 47 | 48 | ___ 49 | 50 | ### type 51 | 52 | • `Optional` **type**: `string` \| `WriterFunction` 53 | 54 | #### Defined in 55 | 56 | [modifier/src/export.ts:71](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/modifier/src/export.ts#L71) 57 | -------------------------------------------------------------------------------- /packages/example/src/create-class/index.ts: -------------------------------------------------------------------------------- 1 | import { Project } from "ts-morph"; 2 | import path from "path"; 3 | import fs from "fs-extra"; 4 | import { 5 | createBaseClass, 6 | createBaseClassProp, 7 | createBaseClassDecorator, 8 | createBaseInterfaceExport, 9 | createImportDeclaration, 10 | } from "@ts-morpher/creator"; 11 | import { ImportType } from "@ts-morpher/types"; 12 | 13 | const sourceFilePath = path.join(__dirname, "./source.ts"); 14 | 15 | fs.rmSync(sourceFilePath); 16 | fs.ensureFileSync(sourceFilePath); 17 | 18 | const p = new Project(); 19 | const source = p.addSourceFileAtPath(sourceFilePath); 20 | 21 | createImportDeclaration( 22 | source, 23 | ["PrimaryGeneratedColumn", "Column", "BaseEntity", "Entity"], 24 | "typeorm", 25 | ImportType.NAMED_IMPORT 26 | ); 27 | 28 | createBaseInterfaceExport( 29 | source, 30 | "IUser", 31 | [], 32 | [], 33 | [ 34 | { 35 | name: "id", 36 | type: "number", 37 | }, 38 | { 39 | name: "name", 40 | type: "string", 41 | }, 42 | ] 43 | ); 44 | 45 | createBaseClass(source, { 46 | name: "User", 47 | isDefaultExport: true, 48 | extends: "BaseEntity", 49 | implements: ["IUser"], 50 | }); 51 | 52 | createBaseClassDecorator(source, "User", { 53 | name: "Entity", 54 | arguments: [], 55 | }); 56 | 57 | createBaseClassProp(source, "User", { 58 | name: "id", 59 | type: "number", 60 | decorators: [{ name: "PrimaryGeneratedColumn", arguments: [] }], 61 | }); 62 | 63 | createBaseClassProp(source, "User", { 64 | name: "name", 65 | type: "string", 66 | decorators: [{ name: "Column", arguments: [] }], 67 | }); 68 | -------------------------------------------------------------------------------- /packages/creator/tests/statements.test.ts: -------------------------------------------------------------------------------- 1 | import { Project, Scope, SourceFile, VariableDeclarationKind } from "ts-morph"; 2 | import tmp from "tmp"; 3 | import { createImportDeclaration } from "../src/import"; 4 | import { createBaseVariableExport } from "../src/export"; 5 | import { ImportType } from "@ts-morpher/types"; 6 | import { appendStatementAfterImportDeclarations } from "../src/statements"; 7 | 8 | let source: SourceFile; 9 | 10 | beforeEach(() => { 11 | source = new Project().addSourceFileAtPath(tmp.fileSync().name); 12 | }); 13 | 14 | // TODO: check by ChildIndex 15 | 16 | describe("package/creator-statements", () => { 17 | it("should append before statements", () => { 18 | createBaseVariableExport( 19 | source, 20 | "foo", 21 | "'foo'", 22 | VariableDeclarationKind.Const 23 | ); 24 | 25 | appendStatementAfterImportDeclarations(source, ['const foo = "foo";']); 26 | 27 | expect(source.getText()).toContain(`const foo = "foo";`); 28 | }); 29 | it("should append after imports", () => { 30 | createImportDeclaration( 31 | source, 32 | ["transpileModule"], 33 | "typescript", 34 | ImportType.NAMED_IMPORT 35 | ); 36 | 37 | appendStatementAfterImportDeclarations(source, ['const foo = "foo";']); 38 | 39 | expect(source.getText()).toContain( 40 | `import { transpileModule } from "typescript";` 41 | ); 42 | expect(source.getText()).toContain(`const foo = "foo";`); 43 | }); 44 | 45 | it("should append top if no imports found", () => { 46 | appendStatementAfterImportDeclarations(source, ['const foo = "foo";']); 47 | 48 | expect(source.getText()).toContain(`const foo = "foo";`); 49 | }); 50 | }); 51 | -------------------------------------------------------------------------------- /packages/example/src/create-import/index.ts: -------------------------------------------------------------------------------- 1 | import { Project } from "ts-morph"; 2 | import path from "path"; 3 | import fs from "fs-extra"; 4 | import assert from "assert"; 5 | import { createImportDeclaration } from "@ts-morpher/creator"; 6 | import { checkImportExistByModuleSpecifier } from "@ts-morpher/checker"; 7 | import { ImportType } from "@ts-morpher/types"; 8 | 9 | const sourceFilePath = path.join(__dirname, "./source.ts"); 10 | 11 | fs.rmSync(sourceFilePath); 12 | fs.ensureFileSync(sourceFilePath); 13 | 14 | const p = new Project(); 15 | const source = p.addSourceFileAtPath(sourceFilePath); 16 | 17 | createImportDeclaration(source, "fs", "fs-extra", ImportType.DEFAULT_IMPORT); 18 | 19 | createImportDeclaration(source, "path", "path", ImportType.NAMESPACE_IMPORT); 20 | 21 | createImportDeclaration( 22 | source, 23 | ["exec", "execSync", "spawn", "spawnSync"], 24 | "child_process", 25 | ImportType.NAMED_IMPORT 26 | ); 27 | 28 | createImportDeclaration( 29 | source, 30 | // First item will be regarded as default import, and rest will be used as named imports. 31 | ["ts", "transpileModule", "CompilerOptions", "factory"], 32 | "typescript", 33 | ImportType.DEFAULT_WITH_NAMED_IMPORT 34 | ); 35 | 36 | createImportDeclaration( 37 | source, 38 | ["SourceFile", "VariableDeclarationKind"], 39 | "ts-morph", 40 | ImportType.NAMED_IMPORT, 41 | true 42 | ); 43 | 44 | assert(checkImportExistByModuleSpecifier(source, "fs-extra") === true); 45 | assert(checkImportExistByModuleSpecifier(source, "path") === true); 46 | assert(checkImportExistByModuleSpecifier(source, "child_process") === true); 47 | assert(checkImportExistByModuleSpecifier(source, "typescript") === true); 48 | assert(checkImportExistByModuleSpecifier(source, "ts-morph") === true); 49 | -------------------------------------------------------------------------------- /docs/modifier-docs/interfaces/export.IBaseVariableExportStructure.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/modifier](../README.md) / [export](../modules/export.md) / IBaseVariableExportStructure 2 | 3 | # Interface: IBaseVariableExportStructure 4 | 5 | [export](../modules/export.md).IBaseVariableExportStructure 6 | 7 | Basic variable structure. 8 | 9 | ## Table of contents 10 | 11 | ### Properties 12 | 13 | - [declarationKind](export.IBaseVariableExportStructure.md#declarationkind) 14 | - [declarations](export.IBaseVariableExportStructure.md#declarations) 15 | - [isDefaultExport](export.IBaseVariableExportStructure.md#isdefaultexport) 16 | - [isExported](export.IBaseVariableExportStructure.md#isexported) 17 | 18 | ## Properties 19 | 20 | ### declarationKind 21 | 22 | • `Optional` **declarationKind**: `VariableDeclarationKind` 23 | 24 | #### Defined in 25 | 26 | [modifier/src/export.ts:78](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/modifier/src/export.ts#L78) 27 | 28 | ___ 29 | 30 | ### declarations 31 | 32 | • `Optional` **declarations**: [`IBaseDeclarationStructure`](export.IBaseDeclarationStructure.md)[] 33 | 34 | [IBaseDeclarationStructure](export.IBaseDeclarationStructure.md) 35 | 36 | #### Defined in 37 | 38 | [modifier/src/export.ts:83](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/modifier/src/export.ts#L83) 39 | 40 | ___ 41 | 42 | ### isDefaultExport 43 | 44 | • `Optional` **isDefaultExport**: `boolean` 45 | 46 | #### Defined in 47 | 48 | [modifier/src/export.ts:86](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/modifier/src/export.ts#L86) 49 | 50 | ___ 51 | 52 | ### isExported 53 | 54 | • `Optional` **isExported**: `boolean` 55 | 56 | #### Defined in 57 | 58 | [modifier/src/export.ts:85](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/modifier/src/export.ts#L85) 59 | -------------------------------------------------------------------------------- /packages/helper/src/util.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ClassDeclaration, 3 | Decorator, 4 | ImportDeclaration, 5 | InterfaceDeclaration, 6 | MethodDeclaration, 7 | PropertyDeclaration, 8 | SyntaxKind, 9 | TypeAliasDeclaration, 10 | VariableStatement, 11 | } from "ts-morph"; 12 | 13 | /** 14 | * @private 15 | */ 16 | export type MaybeArray = T | T[]; 17 | 18 | /** 19 | * @private 20 | */ 21 | export function uniqArray(array: T[]): T[] { 22 | return [...new Set(array)]; 23 | } 24 | 25 | /** 26 | * @private 27 | */ 28 | export function ensureArray(maybeArray: MaybeArray): T[] { 29 | return Array.isArray(maybeArray) ? maybeArray : [maybeArray]; 30 | } 31 | 32 | /** 33 | * @private 34 | */ 35 | export function getDeclarationIdentifierByKind( 36 | dec: 37 | | ClassDeclaration 38 | | MethodDeclaration 39 | | PropertyDeclaration 40 | | ImportDeclaration 41 | | Decorator 42 | ): string { 43 | switch (dec.getKind()) { 44 | case SyntaxKind.ClassDeclaration: 45 | case SyntaxKind.MethodDeclaration: 46 | case SyntaxKind.PropertyDeclaration: 47 | case SyntaxKind.Decorator: 48 | return (dec as ClassDeclaration).getName(); 49 | 50 | case SyntaxKind.ImportDeclaration: 51 | return dec.asKind(SyntaxKind.ImportDeclaration).getModuleSpecifierValue(); 52 | } 53 | } 54 | 55 | /** 56 | * @private 57 | */ 58 | export function getVariableIdentifier(statement: VariableStatement): string { 59 | return statement 60 | .getFirstChildByKind(SyntaxKind.VariableDeclarationList) 61 | .getFirstChildByKind(SyntaxKind.SyntaxList) 62 | .getFirstChildByKind(SyntaxKind.VariableDeclaration) 63 | .getFirstChildByKind(SyntaxKind.Identifier) 64 | .getText(); 65 | } 66 | 67 | /** 68 | * @private 69 | */ 70 | export function getTypeOrInterfaceIdentifier( 71 | declaration: TypeAliasDeclaration | InterfaceDeclaration 72 | ): string { 73 | return declaration.getName(); 74 | } 75 | -------------------------------------------------------------------------------- /docs/creator-docs/modules/index.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/creator](../README.md) / index 2 | 3 | # Module: index 4 | 5 | ## Table of contents 6 | 7 | ### References 8 | 9 | - [appendStatementAfterImportDeclarations](index.md#appendstatementafterimportdeclarations) 10 | - [createBaseClass](index.md#createbaseclass) 11 | - [createBaseClassDecorator](index.md#createbaseclassdecorator) 12 | - [createBaseClassMethod](index.md#createbaseclassmethod) 13 | - [createBaseClassProp](index.md#createbaseclassprop) 14 | - [createBaseInterfaceExport](index.md#createbaseinterfaceexport) 15 | - [createBaseTypeExport](index.md#createbasetypeexport) 16 | - [createBaseVariableExport](index.md#createbasevariableexport) 17 | - [createImportDeclaration](index.md#createimportdeclaration) 18 | 19 | ## References 20 | 21 | ### appendStatementAfterImportDeclarations 22 | 23 | Re-exports [appendStatementAfterImportDeclarations](statements.md#appendstatementafterimportdeclarations) 24 | 25 | ___ 26 | 27 | ### createBaseClass 28 | 29 | Re-exports [createBaseClass](class.md#createbaseclass) 30 | 31 | ___ 32 | 33 | ### createBaseClassDecorator 34 | 35 | Re-exports [createBaseClassDecorator](class.md#createbaseclassdecorator) 36 | 37 | ___ 38 | 39 | ### createBaseClassMethod 40 | 41 | Re-exports [createBaseClassMethod](class.md#createbaseclassmethod) 42 | 43 | ___ 44 | 45 | ### createBaseClassProp 46 | 47 | Re-exports [createBaseClassProp](class.md#createbaseclassprop) 48 | 49 | ___ 50 | 51 | ### createBaseInterfaceExport 52 | 53 | Re-exports [createBaseInterfaceExport](export.md#createbaseinterfaceexport) 54 | 55 | ___ 56 | 57 | ### createBaseTypeExport 58 | 59 | Re-exports [createBaseTypeExport](export.md#createbasetypeexport) 60 | 61 | ___ 62 | 63 | ### createBaseVariableExport 64 | 65 | Re-exports [createBaseVariableExport](export.md#createbasevariableexport) 66 | 67 | ___ 68 | 69 | ### createImportDeclaration 70 | 71 | Re-exports [createImportDeclaration](import.md#createimportdeclaration) 72 | -------------------------------------------------------------------------------- /docs/modifier-docs/interfaces/export.IBaseTypeAliasStructure.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/modifier](../README.md) / [export](../modules/export.md) / IBaseTypeAliasStructure 2 | 3 | # Interface: IBaseTypeAliasStructure 4 | 5 | [export](../modules/export.md).IBaseTypeAliasStructure 6 | 7 | Basic type alias structure 8 | 9 | ## Hierarchy 10 | 11 | - `ISharedTypeStructure` 12 | 13 | ↳ **`IBaseTypeAliasStructure`** 14 | 15 | ## Table of contents 16 | 17 | ### Properties 18 | 19 | - [hasDeclareKeyword](export.IBaseTypeAliasStructure.md#hasdeclarekeyword) 20 | - [isExported](export.IBaseTypeAliasStructure.md#isexported) 21 | - [name](export.IBaseTypeAliasStructure.md#name) 22 | - [type](export.IBaseTypeAliasStructure.md#type) 23 | - [typeParameters](export.IBaseTypeAliasStructure.md#typeparameters) 24 | 25 | ## Properties 26 | 27 | ### hasDeclareKeyword 28 | 29 | • `Optional` **hasDeclareKeyword**: `boolean` 30 | 31 | #### Inherited from 32 | 33 | ISharedTypeStructure.hasDeclareKeyword 34 | 35 | #### Defined in 36 | 37 | types/dist/types.d.ts:55 38 | 39 | ___ 40 | 41 | ### isExported 42 | 43 | • `Optional` **isExported**: `boolean` 44 | 45 | #### Inherited from 46 | 47 | ISharedTypeStructure.isExported 48 | 49 | #### Defined in 50 | 51 | types/dist/types.d.ts:54 52 | 53 | ___ 54 | 55 | ### name 56 | 57 | • **name**: `string` 58 | 59 | #### Inherited from 60 | 61 | ISharedTypeStructure.name 62 | 63 | #### Defined in 64 | 65 | types/dist/types.d.ts:49 66 | 67 | ___ 68 | 69 | ### type 70 | 71 | • `Optional` **type**: `string` \| `WriterFunction` 72 | 73 | #### Defined in 74 | 75 | [modifier/src/export.ts:118](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/modifier/src/export.ts#L118) 76 | 77 | ___ 78 | 79 | ### typeParameters 80 | 81 | • `Optional` **typeParameters**: `IGenericTypeParam`[] 82 | 83 | {@link IGenericTypeParam} 84 | 85 | #### Inherited from 86 | 87 | ISharedTypeStructure.typeParameters 88 | 89 | #### Defined in 90 | 91 | types/dist/types.d.ts:53 92 | -------------------------------------------------------------------------------- /docs/modifier-docs/interfaces/export.IBaseInterfaceStructure.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/modifier](../README.md) / [export](../modules/export.md) / IBaseInterfaceStructure 2 | 3 | # Interface: IBaseInterfaceStructure 4 | 5 | [export](../modules/export.md).IBaseInterfaceStructure 6 | 7 | Basic interface structure. 8 | 9 | ## Hierarchy 10 | 11 | - `ISharedTypeStructure` 12 | 13 | ↳ **`IBaseInterfaceStructure`** 14 | 15 | ## Table of contents 16 | 17 | ### Properties 18 | 19 | - [extends](export.IBaseInterfaceStructure.md#extends) 20 | - [hasDeclareKeyword](export.IBaseInterfaceStructure.md#hasdeclarekeyword) 21 | - [isExported](export.IBaseInterfaceStructure.md#isexported) 22 | - [name](export.IBaseInterfaceStructure.md#name) 23 | - [typeParameters](export.IBaseInterfaceStructure.md#typeparameters) 24 | 25 | ## Properties 26 | 27 | ### extends 28 | 29 | • `Optional` **extends**: `WriterFunction` \| (`string` \| `WriterFunction`)[] 30 | 31 | #### Defined in 32 | 33 | [modifier/src/export.ts:150](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/modifier/src/export.ts#L150) 34 | 35 | ___ 36 | 37 | ### hasDeclareKeyword 38 | 39 | • `Optional` **hasDeclareKeyword**: `boolean` 40 | 41 | #### Inherited from 42 | 43 | ISharedTypeStructure.hasDeclareKeyword 44 | 45 | #### Defined in 46 | 47 | types/dist/types.d.ts:55 48 | 49 | ___ 50 | 51 | ### isExported 52 | 53 | • `Optional` **isExported**: `boolean` 54 | 55 | #### Inherited from 56 | 57 | ISharedTypeStructure.isExported 58 | 59 | #### Defined in 60 | 61 | types/dist/types.d.ts:54 62 | 63 | ___ 64 | 65 | ### name 66 | 67 | • **name**: `string` 68 | 69 | #### Inherited from 70 | 71 | ISharedTypeStructure.name 72 | 73 | #### Defined in 74 | 75 | types/dist/types.d.ts:49 76 | 77 | ___ 78 | 79 | ### typeParameters 80 | 81 | • `Optional` **typeParameters**: `IGenericTypeParam`[] 82 | 83 | {@link IGenericTypeParam} 84 | 85 | #### Inherited from 86 | 87 | ISharedTypeStructure.typeParameters 88 | 89 | #### Defined in 90 | 91 | types/dist/types.d.ts:53 92 | -------------------------------------------------------------------------------- /docs/types-docs/enums/import.ImportType.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/types](../README.md) / [import](../modules/import.md) / ImportType 2 | 3 | # Enumeration: ImportType 4 | 5 | [import](../modules/import.md).ImportType 6 | 7 | ## Table of contents 8 | 9 | ### Enumeration members 10 | 11 | - [DEFAULT\_IMPORT](import.ImportType.md#default_import) 12 | - [DEFAULT\_WITH\_NAMED\_IMPORT](import.ImportType.md#default_with_named_import) 13 | - [DIRECTLY\_IMPORT](import.ImportType.md#directly_import) 14 | - [NAMED\_IMPORT](import.ImportType.md#named_import) 15 | - [NAMESPACE\_IMPORT](import.ImportType.md#namespace_import) 16 | 17 | ## Enumeration members 18 | 19 | ### DEFAULT\_IMPORT 20 | 21 | • **DEFAULT\_IMPORT** = `"DEFAULT_IMPORT"` 22 | 23 | e.g. import path from "path"; 24 | 25 | #### Defined in 26 | 27 | [import.ts:16](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/import.ts#L16) 28 | 29 | ___ 30 | 31 | ### DEFAULT\_WITH\_NAMED\_IMPORT 32 | 33 | • **DEFAULT\_WITH\_NAMED\_IMPORT** = `"DEFAULT_WITH_NAMED_IMPORT"` 34 | 35 | e.g. import ts, { transpileModule } from "typescript"; 36 | 37 | #### Defined in 38 | 39 | [import.ts:20](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/import.ts#L20) 40 | 41 | ___ 42 | 43 | ### DIRECTLY\_IMPORT 44 | 45 | • **DIRECTLY\_IMPORT** = `"DIRECTLY_IMPORT"` 46 | 47 | e.g. import "ui-library/dist/index.css" 48 | 49 | #### Defined in 50 | 51 | [import.ts:24](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/import.ts#L24) 52 | 53 | ___ 54 | 55 | ### NAMED\_IMPORT 56 | 57 | • **NAMED\_IMPORT** = `"NAMED_IMPORT"` 58 | 59 | e.g. import { exec } from "child_process"; 60 | 61 | #### Defined in 62 | 63 | [import.ts:12](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/import.ts#L12) 64 | 65 | ___ 66 | 67 | ### NAMESPACE\_IMPORT 68 | 69 | • **NAMESPACE\_IMPORT** = `"NAMESPACE_IMPORT"` 70 | 71 | e.g. import * as fs from "fs"; 72 | 73 | #### Defined in 74 | 75 | [import.ts:8](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/import.ts#L8) 76 | -------------------------------------------------------------------------------- /docs/types-docs/interfaces/types.IBaseClassStructure.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/types](../README.md) / [types](../modules/types.md) / IBaseClassStructure 2 | 3 | # Interface: IBaseClassStructure 4 | 5 | [types](../modules/types.md).IBaseClassStructure 6 | 7 | Class declaration structure 8 | 9 | ## Table of contents 10 | 11 | ### Properties 12 | 13 | - [extends](types.IBaseClassStructure.md#extends) 14 | - [implements](types.IBaseClassStructure.md#implements) 15 | - [isAbstract](types.IBaseClassStructure.md#isabstract) 16 | - [isDefaultExport](types.IBaseClassStructure.md#isdefaultexport) 17 | - [isExported](types.IBaseClassStructure.md#isexported) 18 | - [name](types.IBaseClassStructure.md#name) 19 | 20 | ## Properties 21 | 22 | ### extends 23 | 24 | • `Optional` **extends**: `string` \| `WriterFunction` 25 | 26 | #### Defined in 27 | 28 | [types.ts:63](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L63) 29 | 30 | ___ 31 | 32 | ### implements 33 | 34 | • `Optional` **implements**: `WriterFunction` \| (`string` \| `WriterFunction`)[] 35 | 36 | #### Defined in 37 | 38 | [types.ts:62](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L62) 39 | 40 | ___ 41 | 42 | ### isAbstract 43 | 44 | • `Optional` **isAbstract**: `boolean` 45 | 46 | #### Defined in 47 | 48 | [types.ts:64](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L64) 49 | 50 | ___ 51 | 52 | ### isDefaultExport 53 | 54 | • `Optional` **isDefaultExport**: `boolean` 55 | 56 | #### Defined in 57 | 58 | [types.ts:66](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L66) 59 | 60 | ___ 61 | 62 | ### isExported 63 | 64 | • `Optional` **isExported**: `boolean` 65 | 66 | #### Defined in 67 | 68 | [types.ts:65](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L65) 69 | 70 | ___ 71 | 72 | ### name 73 | 74 | • **name**: `string` 75 | 76 | #### Defined in 77 | 78 | [types.ts:61](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L61) 79 | -------------------------------------------------------------------------------- /packages/helper/tests/export.test.ts: -------------------------------------------------------------------------------- 1 | import { Project } from "ts-morph"; 2 | import path from "path"; 3 | import { 4 | getExportVariableIdentifiers, 5 | getExportVariableStatements, 6 | getInterfaceExportDeclaration, 7 | getInterfaceExportIdentifiers, 8 | getTypeExportDeclaration, 9 | getTypeExportIdentifiers, 10 | } from "../src/export"; 11 | 12 | const source = new Project().addSourceFileAtPath( 13 | path.resolve(__dirname, "./fixtures/export.fixture.ts") 14 | ); 15 | 16 | describe("package/helper-export", () => { 17 | it("should return var statements", () => { 18 | expect(getExportVariableStatements(source).length).toBe(3); 19 | expect(getExportVariableStatements(source, "varFoo")).toBeDefined(); 20 | expect(getExportVariableStatements(source, "noop")).toBeUndefined(); 21 | expect(getExportVariableStatements(source, ["varFoo", "noop"]).length).toBe( 22 | 1 23 | ); 24 | expect( 25 | getExportVariableStatements(source, ["varFoo", "letFoo"]).length 26 | ).toBe(2); 27 | expect(getExportVariableStatements(source, ["noopFoo"]).length).toBe(0); 28 | }); 29 | 30 | it("should return identifiers", () => { 31 | expect(getExportVariableIdentifiers(source)).toEqual([ 32 | "varFoo", 33 | "letFoo", 34 | "constFoo", 35 | ]); 36 | 37 | expect(getTypeExportIdentifiers(source)).toEqual(["Foo"]); 38 | expect(getInterfaceExportIdentifiers(source)).toEqual(["Bar"]); 39 | }); 40 | 41 | it("should return declarations", () => { 42 | expect(getTypeExportDeclaration(source).length).toBe(1); 43 | expect(getTypeExportDeclaration(source, ["Foo"]).length).toBe(1); 44 | expect(getTypeExportDeclaration(source, ["Foo1"]).length).toBe(0); 45 | expect(getTypeExportDeclaration(source, "Foo")).toBeDefined; 46 | 47 | expect(getInterfaceExportDeclaration(source).length).toBe(1); 48 | expect(getInterfaceExportDeclaration(source, ["Bar"]).length).toBe(1); 49 | expect(getInterfaceExportDeclaration(source, ["Bar1"]).length).toBe(0); 50 | expect(getInterfaceExportDeclaration(source, "Bar")).toBeDefined(); 51 | }); 52 | }); 53 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | temp 10 | 11 | # Diagnostic reports (https://nodejs.org/api/report.html) 12 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 13 | 14 | # Runtime data 15 | pids 16 | *.pid 17 | *.seed 18 | *.pid.lock 19 | 20 | # Directory for instrumented libs generated by jscoverage/JSCover 21 | lib-cov 22 | 23 | # Coverage directory used by tools like istanbul 24 | coverage 25 | *.lcov 26 | 27 | # nyc test coverage 28 | .nyc_output 29 | 30 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 31 | .grunt 32 | 33 | # Bower dependency directory (https://bower.io/) 34 | bower_components 35 | 36 | # node-waf configuration 37 | .lock-wscript 38 | 39 | # Compiled binary addons (https://nodejs.org/api/addons.html) 40 | build/Release 41 | 42 | # Dependency directories 43 | node_modules/ 44 | jspm_packages/ 45 | 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | 106 | 107 | .ultra.cache.json -------------------------------------------------------------------------------- /docs/types-docs/modules/index.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/types](../README.md) / index 2 | 3 | # Module: index 4 | 5 | ## Table of contents 6 | 7 | ### References 8 | 9 | - [ClassMemberType](index.md#classmembertype) 10 | - [IBaseClassStructure](index.md#ibaseclassstructure) 11 | - [IBaseDecoratorStruct](index.md#ibasedecoratorstruct) 12 | - [IBaseMethodParamStruct](index.md#ibasemethodparamstruct) 13 | - [IBaseMethodStruct](index.md#ibasemethodstruct) 14 | - [IBasePropStruct](index.md#ibasepropstruct) 15 | - [IGenericTypeParam](index.md#igenerictypeparam) 16 | - [IInterfaceIndexSignature](index.md#iinterfaceindexsignature) 17 | - [IInterfaceProperty](index.md#iinterfaceproperty) 18 | - [ISharedTypeStructure](index.md#isharedtypestructure) 19 | - [ImportType](index.md#importtype) 20 | 21 | ## References 22 | 23 | ### ClassMemberType 24 | 25 | Re-exports [ClassMemberType](../enums/class.ClassMemberType.md) 26 | 27 | ___ 28 | 29 | ### IBaseClassStructure 30 | 31 | Re-exports [IBaseClassStructure](../interfaces/types.IBaseClassStructure.md) 32 | 33 | ___ 34 | 35 | ### IBaseDecoratorStruct 36 | 37 | Re-exports [IBaseDecoratorStruct](../interfaces/types.IBaseDecoratorStruct.md) 38 | 39 | ___ 40 | 41 | ### IBaseMethodParamStruct 42 | 43 | Re-exports [IBaseMethodParamStruct](../interfaces/types.IBaseMethodParamStruct.md) 44 | 45 | ___ 46 | 47 | ### IBaseMethodStruct 48 | 49 | Re-exports [IBaseMethodStruct](../interfaces/types.IBaseMethodStruct.md) 50 | 51 | ___ 52 | 53 | ### IBasePropStruct 54 | 55 | Re-exports [IBasePropStruct](../interfaces/types.IBasePropStruct.md) 56 | 57 | ___ 58 | 59 | ### IGenericTypeParam 60 | 61 | Re-exports [IGenericTypeParam](../interfaces/types.IGenericTypeParam.md) 62 | 63 | ___ 64 | 65 | ### IInterfaceIndexSignature 66 | 67 | Re-exports [IInterfaceIndexSignature](../interfaces/types.IInterfaceIndexSignature.md) 68 | 69 | ___ 70 | 71 | ### IInterfaceProperty 72 | 73 | Re-exports [IInterfaceProperty](../interfaces/types.IInterfaceProperty.md) 74 | 75 | ___ 76 | 77 | ### ISharedTypeStructure 78 | 79 | Re-exports [ISharedTypeStructure](../interfaces/types.ISharedTypeStructure.md) 80 | 81 | ___ 82 | 83 | ### ImportType 84 | 85 | Re-exports [ImportType](../enums/import.ImportType.md) 86 | -------------------------------------------------------------------------------- /packages/helper/tests/util.test.ts: -------------------------------------------------------------------------------- 1 | import { Project } from "ts-morph"; 2 | import path from "path"; 3 | import { 4 | ensureArray, 5 | getDeclarationIdentifierByKind, 6 | getClassDeclarations, 7 | getClassDecorators, 8 | getClassPropDeclarations, 9 | getClassMethodDeclarations, 10 | getImportDeclarations, 11 | getVariableIdentifier, 12 | getTypeOrInterfaceIdentifier, 13 | getExportVariableStatements, 14 | getTypeExportDeclaration, 15 | getInterfaceExportDeclaration, 16 | uniqArray, 17 | } from "../src"; 18 | 19 | const source = new Project().addSourceFileAtPath( 20 | path.resolve(__dirname, "./fixtures/util.fixture.ts") 21 | ); 22 | 23 | describe("package/helper-util", () => { 24 | it("should ensure array", () => { 25 | expect(ensureArray("1")).toEqual(["1"]); 26 | expect(ensureArray(["1"])).toEqual(["1"]); 27 | }); 28 | 29 | it("should return declaration identifier", () => { 30 | expect( 31 | getDeclarationIdentifierByKind(getClassDeclarations(source, "Foo")!) 32 | ).toBe("Foo"); 33 | 34 | expect( 35 | getDeclarationIdentifierByKind( 36 | getClassMethodDeclarations(source, "Foo", "method1")! 37 | ) 38 | ).toBe("method1"); 39 | 40 | expect( 41 | getDeclarationIdentifierByKind( 42 | getClassPropDeclarations(source, "Foo", "prop1")! 43 | ) 44 | ).toBe("prop1"); 45 | 46 | expect( 47 | getDeclarationIdentifierByKind(getImportDeclarations(source, "fs")!) 48 | ).toBe("fs"); 49 | 50 | expect( 51 | getDeclarationIdentifierByKind( 52 | getClassDecorators(source, "Foo", "deco1")! 53 | ) 54 | ).toBe("deco1"); 55 | }); 56 | 57 | it("should get variable identifier", () => { 58 | expect( 59 | getVariableIdentifier(getExportVariableStatements(source, "foo")!) 60 | ).toBe("foo"); 61 | }); 62 | 63 | it("should get type/interface identifier", () => { 64 | expect( 65 | getTypeOrInterfaceIdentifier(getTypeExportDeclaration(source, "TT")) 66 | ).toBe("TT"); 67 | 68 | expect( 69 | getTypeOrInterfaceIdentifier(getInterfaceExportDeclaration(source, "IIn")) 70 | ).toBe("IIn"); 71 | }); 72 | 73 | it("should uniq array", () => { 74 | expect(uniqArray([1, 1, 2])).toEqual([1, 2]); 75 | expect(uniqArray([1, 2])).toEqual([1, 2]); 76 | }); 77 | }); 78 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ts-morpher", 3 | "version": "0.0.1", 4 | "license": "MIT", 5 | "private": true, 6 | "repository": "https://github.com/linbudu599/morpher.git", 7 | "author": "linbudu599", 8 | "workspaces": [ 9 | "packages/*" 10 | ], 11 | "scripts": { 12 | "commit": "git add -A && git-cz", 13 | "pub:patch": "yarn build && lerna publish patch", 14 | "pub:minor": "yarn build && lerna publish minor", 15 | "pub:beta": "yarn build && lerna publish --canary", 16 | "test:ci": "jest --no-cache --runInBand --logHeapUsage --config jest.ci-config.ts", 17 | "test": "jest", 18 | "build": "ultra -r --filter '@ts-morpher/*' --topology build", 19 | "rebuild": "ultra -r --filter '@ts-morpher/*' --topology rebuild", 20 | "tsc-check": "ultra -r --filter '@ts-morpher/*' --topology check", 21 | "docs:dev": "vuepress dev docs", 22 | "docs:gen": "ts-node scripts/docs-gen.ts && git add -A", 23 | "docs:build": "vuepress build docs", 24 | "demo:import": "lerna exec yarn dev:import --scope @ts-morpher/example", 25 | "demo:class": "lerna exec yarn dev:class --scope @ts-morpher/example" 26 | }, 27 | "dependencies": { 28 | "ts-morph": "^12.0.0" 29 | }, 30 | "devDependencies": { 31 | "@changesets/cli": "^2.17.0", 32 | "@commitlint/cli": "^13.2.1", 33 | "@commitlint/config-conventional": "^13.2.0", 34 | "@types/debug": "^4.1.7", 35 | "@types/fs-extra": "^9.0.13", 36 | "@types/jest": "^27.0.2", 37 | "@types/node": "^16.10.2", 38 | "@types/tmp": "^0.2.1", 39 | "commitizen": "^4.2.4", 40 | "commitlint-config-cz": "^0.13.2", 41 | "conventional-changelog": "^3.1.24", 42 | "cz-conventional-changelog": "^3.3.0", 43 | "cz-customizable": "^6.3.0", 44 | "debug": "^4.3.2", 45 | "execa": "^5.1.1", 46 | "fliegdoc": "^0.5.1", 47 | "fs-extra": "^10.0.0", 48 | "husky": "^7.0.2", 49 | "jest": "^27.2.4", 50 | "lerna": "^4.0.0", 51 | "oao": "^2.0.2", 52 | "prettier": "^2.4.1", 53 | "tmp": "^0.2.1", 54 | "ts-jest": "^27.0.5", 55 | "ts-node": "^10.3.0", 56 | "ts-node-dev": "^1.1.8", 57 | "typedoc": "^0.22.6", 58 | "typedoc-plugin-markdown": "^3.11.3", 59 | "typescript": "^4.4.3", 60 | "ultra-runner": "^3.10.5", 61 | "vuepress": "^1.8.2" 62 | }, 63 | "config": { 64 | "commitizen": { 65 | "path": "node_modules/cz-customizable" 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /packages/creator/tests/import.test.ts: -------------------------------------------------------------------------------- 1 | import { Project, SourceFile } from "ts-morph"; 2 | import path from "path"; 3 | import tmp from "tmp"; 4 | import { createImportDeclaration } from "../src/import"; 5 | 6 | import { ImportType } from "@ts-morpher/types"; 7 | import { 8 | checkImportTypeByModuleSpecifier, 9 | checkIsTypeOnlyImportByModuleSpecifier, 10 | } from "@ts-morpher/checker"; 11 | import { getImportDeclarations } from "@ts-morpher/helper"; 12 | 13 | let source: SourceFile; 14 | 15 | beforeEach(() => { 16 | source = new Project().addSourceFileAtPath(tmp.fileSync().name); 17 | }); 18 | 19 | describe("package/creator-import", () => { 20 | it("should create default import declarations", () => { 21 | createImportDeclaration( 22 | source, 23 | "fs", 24 | "fs", 25 | ImportType.DEFAULT_IMPORT, 26 | true 27 | ); 28 | 29 | expect(getImportDeclarations(source, "fs")).toBeDefined(); 30 | expect(checkImportTypeByModuleSpecifier(source, "fs")).toBe( 31 | ImportType.DEFAULT_IMPORT 32 | ); 33 | }); 34 | 35 | it("should create named import declarations", () => { 36 | createImportDeclaration( 37 | source, 38 | ["CompilerOptions"], 39 | "typescript", 40 | ImportType.NAMED_IMPORT, 41 | true, 42 | true 43 | ); 44 | 45 | expect(getImportDeclarations(source, "typescript")).toBeDefined(); 46 | expect( 47 | checkIsTypeOnlyImportByModuleSpecifier(source, "typescript") 48 | ).toBeTruthy(); 49 | expect(checkImportTypeByModuleSpecifier(source, "typescript")).toBe( 50 | ImportType.NAMED_IMPORT 51 | ); 52 | }); 53 | 54 | it("should create default with named import declarations", () => { 55 | createImportDeclaration( 56 | source, 57 | ["fs", "copySync"], 58 | "fs", 59 | ImportType.DEFAULT_WITH_NAMED_IMPORT, 60 | true 61 | ); 62 | 63 | expect(getImportDeclarations(source, "fs")).toBeDefined(); 64 | expect(checkImportTypeByModuleSpecifier(source, "fs")).toBe( 65 | ImportType.DEFAULT_WITH_NAMED_IMPORT 66 | ); 67 | }); 68 | 69 | it("should create namespace import declarations", () => { 70 | createImportDeclaration( 71 | source, 72 | "path", 73 | "path", 74 | ImportType.NAMESPACE_IMPORT, 75 | true 76 | ); 77 | 78 | expect(getImportDeclarations(source, "path")).toBeDefined(); 79 | expect(checkImportTypeByModuleSpecifier(source, "path")).toBe( 80 | ImportType.NAMESPACE_IMPORT 81 | ); 82 | }); 83 | }); 84 | -------------------------------------------------------------------------------- /docs/cleaner-docs/modules/index.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/cleaner](../README.md) / index 2 | 3 | # Module: index 4 | 5 | ## Table of contents 6 | 7 | ### References 8 | 9 | - [removeAllImports](index.md#removeallimports) 10 | - [removeAllTypeOnlyImports](index.md#removealltypeonlyimports) 11 | - [removeClass](index.md#removeclass) 12 | - [removeClassDecorator](index.md#removeclassdecorator) 13 | - [removeClassMethod](index.md#removeclassmethod) 14 | - [removeClassProp](index.md#removeclassprop) 15 | - [removeExportStatementsByExportType](index.md#removeexportstatementsbyexporttype) 16 | - [removeExportStatementsByIdentifier](index.md#removeexportstatementsbyidentifier) 17 | - [removeImportDeclarationByModuleSpecifier](index.md#removeimportdeclarationbymodulespecifier) 18 | - [removeImportDeclarationByType](index.md#removeimportdeclarationbytype) 19 | - [removeInterfaceExportByIdentifier](index.md#removeinterfaceexportbyidentifier) 20 | - [removeTypeExportByIdentifier](index.md#removetypeexportbyidentifier) 21 | 22 | ## References 23 | 24 | ### removeAllImports 25 | 26 | Re-exports [removeAllImports](import.md#removeallimports) 27 | 28 | ___ 29 | 30 | ### removeAllTypeOnlyImports 31 | 32 | Re-exports [removeAllTypeOnlyImports](import.md#removealltypeonlyimports) 33 | 34 | ___ 35 | 36 | ### removeClass 37 | 38 | Re-exports [removeClass](class.md#removeclass) 39 | 40 | ___ 41 | 42 | ### removeClassDecorator 43 | 44 | Re-exports [removeClassDecorator](class.md#removeclassdecorator) 45 | 46 | ___ 47 | 48 | ### removeClassMethod 49 | 50 | Re-exports [removeClassMethod](class.md#removeclassmethod) 51 | 52 | ___ 53 | 54 | ### removeClassProp 55 | 56 | Re-exports [removeClassProp](class.md#removeclassprop) 57 | 58 | ___ 59 | 60 | ### removeExportStatementsByExportType 61 | 62 | Re-exports [removeExportStatementsByExportType](export.md#removeexportstatementsbyexporttype) 63 | 64 | ___ 65 | 66 | ### removeExportStatementsByIdentifier 67 | 68 | Re-exports [removeExportStatementsByIdentifier](export.md#removeexportstatementsbyidentifier) 69 | 70 | ___ 71 | 72 | ### removeImportDeclarationByModuleSpecifier 73 | 74 | Re-exports [removeImportDeclarationByModuleSpecifier](import.md#removeimportdeclarationbymodulespecifier) 75 | 76 | ___ 77 | 78 | ### removeImportDeclarationByType 79 | 80 | Re-exports [removeImportDeclarationByType](import.md#removeimportdeclarationbytype) 81 | 82 | ___ 83 | 84 | ### removeInterfaceExportByIdentifier 85 | 86 | Re-exports [removeInterfaceExportByIdentifier](export.md#removeinterfaceexportbyidentifier) 87 | 88 | ___ 89 | 90 | ### removeTypeExportByIdentifier 91 | 92 | Re-exports [removeTypeExportByIdentifier](export.md#removetypeexportbyidentifier) 93 | -------------------------------------------------------------------------------- /docs/.vuepress/public/admin/config.yml: -------------------------------------------------------------------------------- 1 | backend: 2 | name: github 3 | repo: LinbuduLab/nx-plugins 4 | 5 | media_folder: 'docs/.vuepress/public/media' 6 | public_folder: '/media' 7 | 8 | locale: 'en' 9 | 10 | publish_mode: editorial_workflow 11 | show_preview_links: true 12 | 13 | collections: 14 | - label: 'Home' 15 | name: 'home' 16 | files: 17 | - label: 'Homepage' 18 | name: 'homepage' 19 | file: 'docs/index.md' 20 | delete: false 21 | fields: 22 | - { label: 'Home', name: 'home', widget: 'hidden', default: true } 23 | - { 24 | label: 'Hero image', 25 | name: 'heroImage', 26 | widget: 'image', 27 | required: false, 28 | } 29 | - { label: 'Hero text', name: 'heroText', widget: 'string' } 30 | - { 31 | label: 'Tagline', 32 | name: 'tagline', 33 | widget: 'string', 34 | required: false, 35 | } 36 | - { label: 'Action text', name: 'actionText', widget: 'string' } 37 | - { label: 'Action link', name: 'actionLink', widget: 'string' } 38 | - label: Features 39 | name: features 40 | widget: list 41 | fields: 42 | - { label: 'Title', name: 'title', widget: 'string' } 43 | - { label: 'Details', name: 'details', widget: 'string' } 44 | - { 45 | label: 'Footer', 46 | name: 'footer', 47 | widget: 'string', 48 | required: false, 49 | } 50 | - { label: 'Body', name: body, widget: markdown, required: false } 51 | - label: 'Nx Plugin' 52 | name: 'nx_plugin' 53 | folder: 'docs/nx' 54 | create: true 55 | fields: 56 | - { label: 'Title', name: 'title', widget: 'string' } 57 | - { label: 'Meta description', name: 'description', widget: 'string' } 58 | - { label: 'Body', name: 'body', widget: 'markdown' } 59 | - { 60 | label: 'Permalink', 61 | name: 'permalink', 62 | widget: 'hidden', 63 | default: '/:slug', 64 | } 65 | - label: 'Derived Plugin' 66 | name: 'derived_plugin' 67 | folder: 'docs/derived_plugin' 68 | create: true 69 | fields: 70 | - { label: 'Title', name: 'title', widget: 'string' } 71 | - { label: 'Meta description', name: 'description', widget: 'string' } 72 | - { label: 'Body', name: 'body', widget: 'markdown' } 73 | - { 74 | label: 'Permalink', 75 | name: 'permalink', 76 | widget: 'hidden', 77 | default: '/:slug', 78 | } 79 | -------------------------------------------------------------------------------- /packages/checker/tests/export.test.ts: -------------------------------------------------------------------------------- 1 | import { Project, VariableDeclarationKind } from "ts-morph"; 2 | import path from "path"; 3 | import { 4 | checkSourceFileHasExports, 5 | checkExportDeclarationKindByIdentifier, 6 | checkExportDeclarationKindByStatement, 7 | checkExportExistByIdentifier, 8 | checkInterfaceExportExistByIdentifier, 9 | checkTypeExportExistByIdentifier, 10 | checkSourceFileHasTypeExports, 11 | } from "../src/export"; 12 | import { getExportVariableStatements } from "@ts-morpher/helper"; 13 | 14 | const source = new Project().addSourceFileAtPath( 15 | path.resolve(__dirname, "./fixtures/export.fixture.ts") 16 | ); 17 | 18 | const source2 = new Project().addSourceFileAtPath( 19 | path.resolve(__dirname, "./fixtures/empty.fixture.ts") 20 | ); 21 | 22 | describe("package/checker-export", () => { 23 | it("should check source file", () => { 24 | expect(checkSourceFileHasExports(source)).toBeTruthy(); 25 | expect(checkSourceFileHasExports(source2)).toBeFalsy(); 26 | expect(checkSourceFileHasTypeExports(source)).toBeTruthy(); 27 | expect(checkSourceFileHasTypeExports(source2)).toBeFalsy(); 28 | }); 29 | 30 | it("should check by identifier", () => { 31 | expect(checkExportExistByIdentifier(source, "varFoo")).toBeTruthy(); 32 | expect(checkExportExistByIdentifier(source, "letFoo")).toBeTruthy(); 33 | expect(checkExportExistByIdentifier(source, "constFoo")).toBeTruthy(); 34 | expect(checkExportExistByIdentifier(source, "nonExistFoo")).toBeFalsy(); 35 | 36 | expect(checkExportDeclarationKindByIdentifier(source, "varFoo")).toBe( 37 | VariableDeclarationKind.Var 38 | ); 39 | expect(checkExportDeclarationKindByIdentifier(source, "letFoo")).toBe( 40 | VariableDeclarationKind.Let 41 | ); 42 | expect(checkExportDeclarationKindByIdentifier(source, "constFoo")).toBe( 43 | VariableDeclarationKind.Const 44 | ); 45 | 46 | expect( 47 | checkExportDeclarationKindByIdentifier(source, "inexistFoo") 48 | ).toBeUndefined(); 49 | 50 | expect(checkTypeExportExistByIdentifier(source, "Foo")).toBeTruthy(); 51 | expect(checkTypeExportExistByIdentifier(source, "Foo1")).toBeFalsy(); 52 | 53 | expect(checkInterfaceExportExistByIdentifier(source, "Bar")).toBeTruthy(); 54 | expect(checkInterfaceExportExistByIdentifier(source, "Bar1")).toBeFalsy(); 55 | }); 56 | it("should check by statement", () => { 57 | expect( 58 | checkExportDeclarationKindByStatement( 59 | getExportVariableStatements(source, "varFoo")! 60 | ) 61 | ).toBe(VariableDeclarationKind.Var); 62 | 63 | expect( 64 | checkExportDeclarationKindByStatement( 65 | getExportVariableStatements(source, "letFoo")! 66 | ) 67 | ).toBe(VariableDeclarationKind.Let); 68 | 69 | expect( 70 | checkExportDeclarationKindByStatement( 71 | getExportVariableStatements(source, "constFoo")! 72 | ) 73 | ).toBe(VariableDeclarationKind.Const); 74 | }); 75 | }); 76 | -------------------------------------------------------------------------------- /packages/cleaner/src/import.ts: -------------------------------------------------------------------------------- 1 | import { SourceFile } from "ts-morph"; 2 | import { 3 | getDeclarationIdentifierByKind, 4 | getImportDeclarations, 5 | } from "@ts-morpher/helper"; 6 | import { 7 | checkImportExistByModuleSpecifier, 8 | checkSourceFileHasImports, 9 | checkImportTypeByModuleSpecifier, 10 | } from "@ts-morpher/checker"; 11 | import { ImportType } from "@ts-morpher/types"; 12 | 13 | /** 14 | * Remove all imports in source file. 15 | * @param source SourceFile 16 | * @param apply save source file 17 | */ 18 | export function removeAllImports(source: SourceFile, apply = true) { 19 | getImportDeclarations(source).forEach((i) => i.remove()); 20 | apply && source.saveSync(); 21 | } 22 | 23 | /** 24 | * Remove all type-only imports in source file. 25 | * @param source SourceFile 26 | * @param apply save source file 27 | */ 28 | export function removeAllTypeOnlyImports(source: SourceFile, apply = true) { 29 | getImportDeclarations(source).forEach((i) => i.isTypeOnly() && i.remove()); 30 | apply && source.saveSync(); 31 | } 32 | 33 | /** 34 | * Remove imports by `Module Specifier`. 35 | * @param source SourceFile 36 | * @param specifiers specifiers of imports to remove 37 | * @param apply save source file 38 | */ 39 | export function removeImportDeclarationByModuleSpecifier( 40 | source: SourceFile, 41 | specifiers: string[], 42 | apply = true 43 | ) { 44 | const validImportSpecToRemove = specifiers.filter((spec) => 45 | checkImportExistByModuleSpecifier(source, spec) 46 | ); 47 | 48 | validImportSpecToRemove.forEach((spec) => { 49 | const targetImport = getImportDeclarations(source, spec); 50 | targetImport.remove(); 51 | }); 52 | 53 | apply && source.saveSync(); 54 | } 55 | 56 | /** 57 | * Remove imports by `Import Type`{@link ImportType}. 58 | * @param source SourceFile 59 | * @param removeTypes types of imports to remove: "namespace" | "default" | "named" 60 | * @param apply save source file 61 | * @returns 62 | */ 63 | export function removeImportDeclarationByType( 64 | source: SourceFile, 65 | removeTypes?: Partial>, 66 | apply = true 67 | ) { 68 | if (!checkSourceFileHasImports(source)) { 69 | return; 70 | } 71 | 72 | const sourceImports = getImportDeclarations(source); 73 | 74 | sourceImports.forEach((imp) => { 75 | switch ( 76 | checkImportTypeByModuleSpecifier( 77 | source, 78 | getDeclarationIdentifierByKind(imp) 79 | ) 80 | ) { 81 | case ImportType.DEFAULT_IMPORT: 82 | removeTypes.default && imp.remove(); 83 | break; 84 | 85 | case ImportType.NAMED_IMPORT: 86 | removeTypes.named && imp.remove(); 87 | break; 88 | 89 | case ImportType.NAMESPACE_IMPORT: 90 | removeTypes.namespace && imp.remove(); 91 | break; 92 | 93 | default: 94 | break; 95 | } 96 | }); 97 | 98 | apply && source.saveSync(); 99 | } 100 | -------------------------------------------------------------------------------- /packages/cleaner/src/class.ts: -------------------------------------------------------------------------------- 1 | import { SourceFile } from "ts-morph"; 2 | 3 | import { 4 | getClassDeclarations, 5 | getClassMethodDeclarations, 6 | getClassPropDeclarations, 7 | getClassDecorators, 8 | } from "@ts-morpher/helper"; 9 | import { 10 | checkClassExistInSourceFile, 11 | checkMethodExistInClass, 12 | checkPropExistInClass, 13 | checkDecoratorExistInClass, 14 | } from "@ts-morpher/checker"; 15 | 16 | /** 17 | * Remove class declaration by identifier. 18 | * @param source SourceFile 19 | * @param classIdentifier 20 | * @param apply save source file 21 | * @returns 22 | */ 23 | export function removeClass( 24 | source: SourceFile, 25 | classIdentifier: string, 26 | apply = true 27 | ) { 28 | if (!checkClassExistInSourceFile(source, classIdentifier)) { 29 | return; 30 | } 31 | 32 | getClassDeclarations(source, classIdentifier).remove(); 33 | 34 | apply && source.saveSync(); 35 | } 36 | 37 | /** 38 | * Remove class method declaration by identifier. 39 | * @param source SourceFile 40 | * @param classIdentifier 41 | * @param methodIdentifier 42 | * @param apply save source file 43 | * @returns 44 | */ 45 | export function removeClassMethod( 46 | source: SourceFile, 47 | classIdentifier: string, 48 | methodIdentifier: string, 49 | apply = true 50 | ) { 51 | if ( 52 | !checkClassExistInSourceFile(source, classIdentifier) || 53 | !checkMethodExistInClass(source, classIdentifier, methodIdentifier) 54 | ) { 55 | return; 56 | } 57 | 58 | getClassMethodDeclarations( 59 | source, 60 | classIdentifier, 61 | methodIdentifier 62 | ).remove(); 63 | 64 | apply && source.saveSync(); 65 | } 66 | 67 | /** 68 | * Remove class property declaration by identifier. 69 | * @param source SourceFile 70 | * @param classIdentifier 71 | * @param propIdentifier 72 | * @param apply save source file 73 | * @returns 74 | */ 75 | export function removeClassProp( 76 | source: SourceFile, 77 | classIdentifier: string, 78 | propIdentifier: string, 79 | apply = true 80 | ) { 81 | if ( 82 | !checkClassExistInSourceFile(source, classIdentifier) || 83 | !checkPropExistInClass(source, classIdentifier, propIdentifier) 84 | ) { 85 | return; 86 | } 87 | 88 | getClassPropDeclarations(source, classIdentifier, propIdentifier).remove(); 89 | 90 | apply && source.saveSync(); 91 | } 92 | 93 | /** 94 | * Remove class decorator declaration by identifier. 95 | * @param source SourceFile 96 | * @param classIdentifier 97 | * @param decoratorIdentifier 98 | * @param apply save source file 99 | * @returns 100 | */ 101 | export function removeClassDecorator( 102 | source: SourceFile, 103 | classIdentifier: string, 104 | decoratorIdentifier: string, 105 | apply = true 106 | ) { 107 | if ( 108 | !checkClassExistInSourceFile(source, classIdentifier) || 109 | !checkDecoratorExistInClass(source, classIdentifier, decoratorIdentifier) 110 | ) { 111 | return; 112 | } 113 | 114 | getClassDecorators(source, classIdentifier, decoratorIdentifier).remove(); 115 | 116 | apply && source.saveSync(); 117 | } 118 | -------------------------------------------------------------------------------- /packages/checker/tests/class.test.ts: -------------------------------------------------------------------------------- 1 | import { Project } from "ts-morph"; 2 | import path from "path"; 3 | import { 4 | checkClassExistInSourceFile, 5 | checkClassHasDecorators, 6 | checkClassHasMethods, 7 | checkClassHasProps, 8 | checkDecoratorExistInClass, 9 | checkIsDecoratorFactory, 10 | checkMethodExistInClass, 11 | checkPropExistInClass, 12 | checkSourceFileHasClass, 13 | } from "../src/class"; 14 | import {} from "@ts-morpher/helper"; 15 | import {} from "@ts-morpher/types"; 16 | 17 | const source = new Project().addSourceFileAtPath( 18 | path.resolve(__dirname, "./fixtures/class.fixture.ts") 19 | ); 20 | 21 | const source2 = new Project().addSourceFileAtPath( 22 | path.resolve(__dirname, "./fixtures/empty.fixture.ts") 23 | ); 24 | 25 | describe("packages/checker-class", () => { 26 | it("should check class declarations", () => { 27 | expect(checkSourceFileHasClass(source)).toBeTruthy(); 28 | expect(checkSourceFileHasClass(source2)).toBeFalsy(); 29 | 30 | expect(checkClassExistInSourceFile(source, "Foo")).toBeTruthy(); 31 | expect(checkClassExistInSourceFile(source, "Foo1")).toBeFalsy(); 32 | expect(checkClassExistInSourceFile(source2, "Foo")).toBeFalsy(); 33 | 34 | expect(checkClassHasMethods(source, "Foo")).toBeTruthy(); 35 | expect(checkClassHasMethods(source, "Foo1")).toBeFalsy(); 36 | expect(checkClassHasMethods(source2, "Foo")).toBeFalsy(); 37 | 38 | expect(checkClassHasProps(source, "Foo")).toBeTruthy(); 39 | expect(checkClassHasProps(source, "Foo1")).toBeFalsy(); 40 | expect(checkClassHasProps(source2, "Foo")).toBeFalsy(); 41 | 42 | expect(checkClassHasDecorators(source, "Foo")).toBeTruthy(); 43 | expect(checkClassHasDecorators(source, "Foo1")).toBeFalsy(); 44 | expect(checkClassHasDecorators(source2, "Foo")).toBeFalsy(); 45 | }); 46 | it("should check method declarations", () => { 47 | expect(checkMethodExistInClass(source, "Foo", "method599")).toBeFalsy(); 48 | expect(checkMethodExistInClass(source, "Foo", "method1")).toBeTruthy(); 49 | expect(checkMethodExistInClass(source, "Foo1", "method599")).toBeFalsy(); 50 | expect(checkMethodExistInClass(source, "Foo1", "method1")).toBeFalsy(); 51 | }); 52 | it("should check prop declarations", () => { 53 | expect(checkPropExistInClass(source, "Foo", "prop599")).toBeFalsy(); 54 | expect(checkPropExistInClass(source, "Foo", "prop1")).toBeTruthy(); 55 | expect(checkPropExistInClass(source, "Foo1", "prop599")).toBeFalsy(); 56 | expect(checkPropExistInClass(source, "Foo1", "prop1")).toBeFalsy(); 57 | }); 58 | it("should check decorator declarations", () => { 59 | expect(checkDecoratorExistInClass(source, "Foo", "deco599")).toBeFalsy(); 60 | expect(checkDecoratorExistInClass(source, "Foo", "classDeco")).toBeTruthy(); 61 | expect(checkDecoratorExistInClass(source, "Foo1", "deco599")).toBeFalsy(); 62 | expect(checkDecoratorExistInClass(source, "Foo1", "classDeco")).toBeFalsy(); 63 | 64 | expect(checkIsDecoratorFactory(source, "Foo", "classDeco")).toBeTruthy(); 65 | expect( 66 | checkIsDecoratorFactory(source, "Foo", "nonFactoryDeco") 67 | ).toBeFalsy(); 68 | expect(checkIsDecoratorFactory(source, "Foo", "nonExistDeco")).toBeFalsy(); 69 | }); 70 | }); 71 | -------------------------------------------------------------------------------- /docs/cleaner-docs/modules/import.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/cleaner](../README.md) / import 2 | 3 | # Module: import 4 | 5 | ## Table of contents 6 | 7 | ### Functions 8 | 9 | - [removeAllImports](import.md#removeallimports) 10 | - [removeAllTypeOnlyImports](import.md#removealltypeonlyimports) 11 | - [removeImportDeclarationByModuleSpecifier](import.md#removeimportdeclarationbymodulespecifier) 12 | - [removeImportDeclarationByType](import.md#removeimportdeclarationbytype) 13 | 14 | ## Functions 15 | 16 | ### removeAllImports 17 | 18 | ▸ **removeAllImports**(`source`, `apply?`): `void` 19 | 20 | Remove all imports in source file. 21 | 22 | #### Parameters 23 | 24 | | Name | Type | Default value | Description | 25 | | :------ | :------ | :------ | :------ | 26 | | `source` | `SourceFile` | `undefined` | SourceFile | 27 | | `apply` | `boolean` | `true` | save source file | 28 | 29 | #### Returns 30 | 31 | `void` 32 | 33 | #### Defined in 34 | 35 | [import.ts:18](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/cleaner/src/import.ts#L18) 36 | 37 | ___ 38 | 39 | ### removeAllTypeOnlyImports 40 | 41 | ▸ **removeAllTypeOnlyImports**(`source`, `apply?`): `void` 42 | 43 | Remove all type-only imports in source file. 44 | 45 | #### Parameters 46 | 47 | | Name | Type | Default value | Description | 48 | | :------ | :------ | :------ | :------ | 49 | | `source` | `SourceFile` | `undefined` | SourceFile | 50 | | `apply` | `boolean` | `true` | save source file | 51 | 52 | #### Returns 53 | 54 | `void` 55 | 56 | #### Defined in 57 | 58 | [import.ts:28](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/cleaner/src/import.ts#L28) 59 | 60 | ___ 61 | 62 | ### removeImportDeclarationByModuleSpecifier 63 | 64 | ▸ **removeImportDeclarationByModuleSpecifier**(`source`, `specifiers`, `apply?`): `void` 65 | 66 | Remove imports by `Module Specifier`. 67 | 68 | #### Parameters 69 | 70 | | Name | Type | Default value | Description | 71 | | :------ | :------ | :------ | :------ | 72 | | `source` | `SourceFile` | `undefined` | SourceFile | 73 | | `specifiers` | `string`[] | `undefined` | specifiers of imports to remove | 74 | | `apply` | `boolean` | `true` | save source file | 75 | 76 | #### Returns 77 | 78 | `void` 79 | 80 | #### Defined in 81 | 82 | [import.ts:39](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/cleaner/src/import.ts#L39) 83 | 84 | ___ 85 | 86 | ### removeImportDeclarationByType 87 | 88 | ▸ **removeImportDeclarationByType**(`source`, `removeTypes?`, `apply?`): `void` 89 | 90 | Remove imports by `Import Type`{@link ImportType}. 91 | 92 | #### Parameters 93 | 94 | | Name | Type | Default value | Description | 95 | | :------ | :------ | :------ | :------ | 96 | | `source` | `SourceFile` | `undefined` | SourceFile | 97 | | `removeTypes?` | `Partial`<`Record`<``"namespace"`` \| ``"default"`` \| ``"named"``, `boolean`\>\> | `undefined` | types of imports to remove: "namespace" \| "default" \| "named" | 98 | | `apply` | `boolean` | `true` | save source file | 99 | 100 | #### Returns 101 | 102 | `void` 103 | 104 | #### Defined in 105 | 106 | [import.ts:63](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/cleaner/src/import.ts#L63) 107 | -------------------------------------------------------------------------------- /docs/types-docs/interfaces/types.IBaseMethodParamStruct.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/types](../README.md) / [types](../modules/types.md) / IBaseMethodParamStruct 2 | 3 | # Interface: IBaseMethodParamStruct 4 | 5 | [types](../modules/types.md).IBaseMethodParamStruct 6 | 7 | Class method param declaration structure 8 | 9 | ## Table of contents 10 | 11 | ### Properties 12 | 13 | - [decorators](types.IBaseMethodParamStruct.md#decorators) 14 | - [hasOverrideKeyword](types.IBaseMethodParamStruct.md#hasoverridekeyword) 15 | - [hasQuestionToken](types.IBaseMethodParamStruct.md#hasquestiontoken) 16 | - [initializer](types.IBaseMethodParamStruct.md#initializer) 17 | - [isReadonly](types.IBaseMethodParamStruct.md#isreadonly) 18 | - [isRestParameter](types.IBaseMethodParamStruct.md#isrestparameter) 19 | - [name](types.IBaseMethodParamStruct.md#name) 20 | - [scope](types.IBaseMethodParamStruct.md#scope) 21 | - [type](types.IBaseMethodParamStruct.md#type) 22 | 23 | ## Properties 24 | 25 | ### decorators 26 | 27 | • `Optional` **decorators**: [`IBaseDecoratorStruct`](types.IBaseDecoratorStruct.md)[] 28 | 29 | [IBaseDecoratorStruct](types.IBaseDecoratorStruct.md) 30 | 31 | #### Defined in 32 | 33 | [types.ts:102](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L102) 34 | 35 | ___ 36 | 37 | ### hasOverrideKeyword 38 | 39 | • `Optional` **hasOverrideKeyword**: `boolean` 40 | 41 | #### Defined in 42 | 43 | [types.ts:92](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L92) 44 | 45 | ___ 46 | 47 | ### hasQuestionToken 48 | 49 | • `Optional` **hasQuestionToken**: `boolean` 50 | 51 | #### Defined in 52 | 53 | [types.ts:91](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L91) 54 | 55 | ___ 56 | 57 | ### initializer 58 | 59 | • `Optional` **initializer**: `string` \| `WriterFunction` 60 | 61 | e.g. foo in `method(arg1 = 'foo'){}` 62 | 63 | #### Defined in 64 | 65 | [types.ts:96](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L96) 66 | 67 | ___ 68 | 69 | ### isReadonly 70 | 71 | • `Optional` **isReadonly**: `boolean` 72 | 73 | #### Defined in 74 | 75 | [types.ts:90](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L90) 76 | 77 | ___ 78 | 79 | ### isRestParameter 80 | 81 | • `Optional` **isRestParameter**: `boolean` 82 | 83 | #### Defined in 84 | 85 | [types.ts:97](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L97) 86 | 87 | ___ 88 | 89 | ### name 90 | 91 | • **name**: `string` 92 | 93 | #### Defined in 94 | 95 | [types.ts:85](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L85) 96 | 97 | ___ 98 | 99 | ### scope 100 | 101 | • `Optional` **scope**: `Scope` 102 | 103 | #### Defined in 104 | 105 | [types.ts:98](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L98) 106 | 107 | ___ 108 | 109 | ### type 110 | 111 | • `Optional` **type**: `string` \| `WriterFunction` 112 | 113 | string in `method(arg1: string){}` 114 | 115 | #### Defined in 116 | 117 | [types.ts:89](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L89) 118 | -------------------------------------------------------------------------------- /docs/cleaner-docs/modules/class.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/cleaner](../README.md) / class 2 | 3 | # Module: class 4 | 5 | ## Table of contents 6 | 7 | ### Functions 8 | 9 | - [removeClass](class.md#removeclass) 10 | - [removeClassDecorator](class.md#removeclassdecorator) 11 | - [removeClassMethod](class.md#removeclassmethod) 12 | - [removeClassProp](class.md#removeclassprop) 13 | 14 | ## Functions 15 | 16 | ### removeClass 17 | 18 | ▸ **removeClass**(`source`, `classIdentifier`, `apply?`): `void` 19 | 20 | Remove class declaration by identifier. 21 | 22 | #### Parameters 23 | 24 | | Name | Type | Default value | Description | 25 | | :------ | :------ | :------ | :------ | 26 | | `source` | `SourceFile` | `undefined` | SourceFile | 27 | | `classIdentifier` | `string` | `undefined` | | 28 | | `apply` | `boolean` | `true` | save source file | 29 | 30 | #### Returns 31 | 32 | `void` 33 | 34 | #### Defined in 35 | 36 | [class.ts:23](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/cleaner/src/class.ts#L23) 37 | 38 | ___ 39 | 40 | ### removeClassDecorator 41 | 42 | ▸ **removeClassDecorator**(`source`, `classIdentifier`, `decoratorIdentifier`, `apply?`): `void` 43 | 44 | Remove class decorator declaration by identifier. 45 | 46 | #### Parameters 47 | 48 | | Name | Type | Default value | Description | 49 | | :------ | :------ | :------ | :------ | 50 | | `source` | `SourceFile` | `undefined` | SourceFile | 51 | | `classIdentifier` | `string` | `undefined` | | 52 | | `decoratorIdentifier` | `string` | `undefined` | | 53 | | `apply` | `boolean` | `true` | save source file | 54 | 55 | #### Returns 56 | 57 | `void` 58 | 59 | #### Defined in 60 | 61 | [class.ts:101](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/cleaner/src/class.ts#L101) 62 | 63 | ___ 64 | 65 | ### removeClassMethod 66 | 67 | ▸ **removeClassMethod**(`source`, `classIdentifier`, `methodIdentifier`, `apply?`): `void` 68 | 69 | Remove class method declaration by identifier. 70 | 71 | #### Parameters 72 | 73 | | Name | Type | Default value | Description | 74 | | :------ | :------ | :------ | :------ | 75 | | `source` | `SourceFile` | `undefined` | SourceFile | 76 | | `classIdentifier` | `string` | `undefined` | | 77 | | `methodIdentifier` | `string` | `undefined` | | 78 | | `apply` | `boolean` | `true` | save source file | 79 | 80 | #### Returns 81 | 82 | `void` 83 | 84 | #### Defined in 85 | 86 | [class.ts:45](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/cleaner/src/class.ts#L45) 87 | 88 | ___ 89 | 90 | ### removeClassProp 91 | 92 | ▸ **removeClassProp**(`source`, `classIdentifier`, `propIdentifier`, `apply?`): `void` 93 | 94 | Remove class property declaration by identifier. 95 | 96 | #### Parameters 97 | 98 | | Name | Type | Default value | Description | 99 | | :------ | :------ | :------ | :------ | 100 | | `source` | `SourceFile` | `undefined` | SourceFile | 101 | | `classIdentifier` | `string` | `undefined` | | 102 | | `propIdentifier` | `string` | `undefined` | | 103 | | `apply` | `boolean` | `true` | save source file | 104 | 105 | #### Returns 106 | 107 | `void` 108 | 109 | #### Defined in 110 | 111 | [class.ts:75](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/cleaner/src/class.ts#L75) 112 | -------------------------------------------------------------------------------- /docs/helper-docs/modules/util.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/helper](../README.md) / util 2 | 3 | # Module: util 4 | 5 | ## Table of contents 6 | 7 | ### Type aliases 8 | 9 | - [MaybeArray](util.md#maybearray) 10 | 11 | ### Functions 12 | 13 | - [ensureArray](util.md#ensurearray) 14 | - [getDeclarationIdentifierByKind](util.md#getdeclarationidentifierbykind) 15 | - [getTypeOrInterfaceIdentifier](util.md#gettypeorinterfaceidentifier) 16 | - [getVariableIdentifier](util.md#getvariableidentifier) 17 | - [uniqArray](util.md#uniqarray) 18 | 19 | ## Type aliases 20 | 21 | ### MaybeArray 22 | 23 | Ƭ `Private` **MaybeArray**<`T`\>: `T` \| `T`[] 24 | 25 | #### Type parameters 26 | 27 | | Name | 28 | | :------ | 29 | | `T` | 30 | 31 | #### Defined in 32 | 33 | [util.ts:16](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/helper/src/util.ts#L16) 34 | 35 | ## Functions 36 | 37 | ### ensureArray 38 | 39 | ▸ `Private` **ensureArray**<`T`\>(`maybeArray`): `T`[] 40 | 41 | #### Type parameters 42 | 43 | | Name | 44 | | :------ | 45 | | `T` | 46 | 47 | #### Parameters 48 | 49 | | Name | Type | 50 | | :------ | :------ | 51 | | `maybeArray` | [`MaybeArray`](util.md#maybearray)<`T`\> | 52 | 53 | #### Returns 54 | 55 | `T`[] 56 | 57 | #### Defined in 58 | 59 | [util.ts:28](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/helper/src/util.ts#L28) 60 | 61 | ___ 62 | 63 | ### getDeclarationIdentifierByKind 64 | 65 | ▸ `Private` **getDeclarationIdentifierByKind**(`dec`): `string` 66 | 67 | #### Parameters 68 | 69 | | Name | Type | 70 | | :------ | :------ | 71 | | `dec` | `ClassDeclaration` \| `MethodDeclaration` \| `Decorator` \| `PropertyDeclaration` \| `ImportDeclaration` | 72 | 73 | #### Returns 74 | 75 | `string` 76 | 77 | #### Defined in 78 | 79 | [util.ts:35](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/helper/src/util.ts#L35) 80 | 81 | ___ 82 | 83 | ### getTypeOrInterfaceIdentifier 84 | 85 | ▸ `Private` **getTypeOrInterfaceIdentifier**(`declaration`): `string` 86 | 87 | #### Parameters 88 | 89 | | Name | Type | 90 | | :------ | :------ | 91 | | `declaration` | `TypeAliasDeclaration` \| `InterfaceDeclaration` | 92 | 93 | #### Returns 94 | 95 | `string` 96 | 97 | #### Defined in 98 | 99 | [util.ts:70](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/helper/src/util.ts#L70) 100 | 101 | ___ 102 | 103 | ### getVariableIdentifier 104 | 105 | ▸ `Private` **getVariableIdentifier**(`statement`): `string` 106 | 107 | #### Parameters 108 | 109 | | Name | Type | 110 | | :------ | :------ | 111 | | `statement` | `VariableStatement` | 112 | 113 | #### Returns 114 | 115 | `string` 116 | 117 | #### Defined in 118 | 119 | [util.ts:58](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/helper/src/util.ts#L58) 120 | 121 | ___ 122 | 123 | ### uniqArray 124 | 125 | ▸ `Private` **uniqArray**<`T`\>(`array`): `T`[] 126 | 127 | #### Type parameters 128 | 129 | | Name | 130 | | :------ | 131 | | `T` | 132 | 133 | #### Parameters 134 | 135 | | Name | Type | 136 | | :------ | :------ | 137 | | `array` | `T`[] | 138 | 139 | #### Returns 140 | 141 | `T`[] 142 | 143 | #### Defined in 144 | 145 | [util.ts:21](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/helper/src/util.ts#L21) 146 | -------------------------------------------------------------------------------- /docs/creator-docs/modules/import.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/creator](../README.md) / import 2 | 3 | # Module: import 4 | 5 | ## Table of contents 6 | 7 | ### Functions 8 | 9 | - [createImportDeclaration](import.md#createimportdeclaration) 10 | 11 | ## Functions 12 | 13 | ### createImportDeclaration 14 | 15 | ▸ **createImportDeclaration**(`source`, `namespace`, `moduleSpecifier`, `importType`, `apply?`): `void` 16 | 17 | Add a namespace import declaration. 18 | 19 | #### Parameters 20 | 21 | | Name | Type | Description | 22 | | :------ | :------ | :------ | 23 | | `source` | `SourceFile` | SourceFile | 24 | | `namespace` | `string` | import namespace | 25 | | `moduleSpecifier` | `string` | import specifier | 26 | | `importType` | `NAMESPACE_IMPORT` | ImportType.NAMESPACE_IMPORT | 27 | | `apply?` | `boolean` | save source file | 28 | 29 | #### Returns 30 | 31 | `void` 32 | 33 | void 34 | 35 | #### Defined in 36 | 37 | [import.ts:16](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/creator/src/import.ts#L16) 38 | 39 | ▸ **createImportDeclaration**(`source`, `namedImports`, `moduleSpecifier`, `importType`, `isTypeOnly?`, `apply?`): `void` 40 | 41 | Add a named import declaration. 42 | 43 | #### Parameters 44 | 45 | | Name | Type | Description | 46 | | :------ | :------ | :------ | 47 | | `source` | `SourceFile` | SourceFile | 48 | | `namedImports` | `MaybeArray`<`string`\> | named imports member | 49 | | `moduleSpecifier` | `string` | import specifier | 50 | | `importType` | `NAMED_IMPORT` | ImportType.NAMED_IMPORT | 51 | | `isTypeOnly?` | `boolean` | create type only import | 52 | | `apply?` | `boolean` | save source file | 53 | 54 | #### Returns 55 | 56 | `void` 57 | 58 | void 59 | 60 | #### Defined in 61 | 62 | [import.ts:34](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/creator/src/import.ts#L34) 63 | 64 | ▸ **createImportDeclaration**(`source`, `defaultImport`, `moduleSpecifier`, `importType`, `apply?`): `void` 65 | 66 | Add a default import declaration. 67 | 68 | #### Parameters 69 | 70 | | Name | Type | Description | 71 | | :------ | :------ | :------ | 72 | | `source` | `SourceFile` | SourceFile | 73 | | `defaultImport` | `string` | - | 74 | | `moduleSpecifier` | `string` | import specifier | 75 | | `importType` | `DEFAULT_IMPORT` | ImportType.DEFAULT_IMPORT | 76 | | `apply?` | `boolean` | save source file | 77 | 78 | #### Returns 79 | 80 | `void` 81 | 82 | void 83 | 84 | #### Defined in 85 | 86 | [import.ts:53](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/creator/src/import.ts#L53) 87 | 88 | ▸ **createImportDeclaration**(`source`, `namedImports`, `moduleSpecifier`, `importType`, `apply?`): `void` 89 | 90 | Add a default with named import declaration. 91 | 92 | #### Parameters 93 | 94 | | Name | Type | Description | 95 | | :------ | :------ | :------ | 96 | | `source` | `SourceFile` | SourceFile | 97 | | `namedImports` | `MaybeArray`<`string`\> | - | 98 | | `moduleSpecifier` | `string` | import specifier | 99 | | `importType` | `DEFAULT_WITH_NAMED_IMPORT` | ImportType.DEFAULT_WITH_NAMED_IMPORT | 100 | | `apply?` | `boolean` | save source file | 101 | 102 | #### Returns 103 | 104 | `void` 105 | 106 | void 107 | 108 | #### Defined in 109 | 110 | [import.ts:70](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/creator/src/import.ts#L70) 111 | -------------------------------------------------------------------------------- /.cz-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | types: [ 3 | { 4 | value: "init", 5 | name: "initial commit", 6 | emoji: "🎉", 7 | }, 8 | { 9 | value: "feat", 10 | name: "add features", 11 | emoji: "✨", 12 | }, 13 | { 14 | value: "workspace", 15 | name: "workspace configuration", 16 | emoji: "🏗️", 17 | }, 18 | { 19 | value: "docs", 20 | name: "update documentation", 21 | emoji: "📝", 22 | }, 23 | { 24 | value: "scripts", 25 | name: "workspace scripts", 26 | emoji: "🛠️", 27 | }, 28 | { 29 | value: "docs", 30 | name: "docs site enhancement", 31 | emoji: "📝", 32 | }, 33 | { 34 | value: "typo", 35 | name: "fix documentation typo", 36 | emoji: "✏️", 37 | }, 38 | { 39 | value: "chore", 40 | name: "related works", 41 | emoji: "🏗️", 42 | }, 43 | { 44 | value: "example", 45 | name: "update examples", 46 | emoji: "🎬", 47 | }, 48 | { 49 | value: "fix", 50 | name: "bug fixtures", 51 | emoji: "🐛", 52 | }, 53 | { 54 | value: "perf", 55 | name: "performance optimization", 56 | emoji: "⚡", 57 | }, 58 | { 59 | value: "ci", 60 | name: "add CI build", 61 | emoji: "👷", 62 | }, 63 | { 64 | value: "fix-ci", 65 | name: "fix CI build", 66 | emoji: "💚", 67 | }, 68 | { 69 | value: "test", 70 | name: "add test cases", 71 | emoji: "✅", 72 | }, 73 | { 74 | value: "refactor", 75 | name: "code refactor", 76 | emoji: "🔨", 77 | }, 78 | { 79 | value: "clean", 80 | name: "clean file", 81 | emoji: "🔥", 82 | }, 83 | { 84 | value: "lint", 85 | name: "code lint", 86 | emoji: "🎨", 87 | }, 88 | { 89 | value: "i18n", 90 | name: "i18n", 91 | emoji: "🌐", 92 | }, 93 | { 94 | value: "upgrade-deps", 95 | name: "upgrade deps", 96 | emoji: "⬆️", 97 | }, 98 | { 99 | value: "release", 100 | name: "release project", 101 | emoji: "🔖", 102 | }, 103 | ], 104 | scopes: [ 105 | "checker", 106 | "cleaner", 107 | "helper", 108 | "creator", 109 | "modifier", 110 | "types", 111 | "workspace", 112 | ], 113 | disableEmoji: false, 114 | maxMessageLength: 164, 115 | minMessageLength: 3, 116 | questions: ["type", "scope", "subject", "breaking", "body", "issues"], 117 | messages: { 118 | type: "Select the type of change that you're committing:", 119 | scope: "\nDenote the SCOPE of this change (optional):", 120 | // used if allowCustomScopes is true 121 | customScope: "Denote the SCOPE of this change:", 122 | subject: "Write a SHORT, IMPERATIVE tense description of the change:\n", 123 | body: 124 | 'Provide a LONGER description of the change (optional). Use "|" to break new line:\n', 125 | breaking: "List any BREAKING CHANGES (optional):\n", 126 | footer: 127 | "List any ISSUES CLOSED by this change (optional). E.g.: #31, #34:\n", 128 | confirmCommit: "Are you sure you want to proceed with the commit above?", 129 | }, 130 | allowCustomScopes: true, 131 | allowBreakingChanges: ["feat", "fix"], 132 | footerPrefix: "ISSUES CLOSED:", 133 | }; 134 | -------------------------------------------------------------------------------- /packages/creator/src/class.ts: -------------------------------------------------------------------------------- 1 | import { SourceFile } from "ts-morph"; 2 | 3 | import { getClassDeclarations } from "@ts-morpher/helper"; 4 | import { 5 | checkClassExistInSourceFile, 6 | checkMethodExistInClass, 7 | checkPropExistInClass, 8 | checkDecoratorExistInClass, 9 | } from "@ts-morpher/checker"; 10 | import { 11 | IBaseMethodStruct, 12 | IBaseClassStructure, 13 | IBasePropStruct, 14 | IBaseDecoratorStruct, 15 | } from "@ts-morpher/types"; 16 | 17 | /** 18 | * Create class declaration from base structure. 19 | * @param source SourceFile 20 | * @param baseClassStruct {@link IBaseClassStructure} 21 | * @param apply save source file 22 | * @returns 23 | */ 24 | export function createBaseClass( 25 | source: SourceFile, 26 | baseClassStruct: IBaseClassStructure, 27 | apply = true 28 | ) { 29 | if (checkClassExistInSourceFile(source, baseClassStruct.name)) { 30 | return; 31 | } 32 | 33 | source.addClass({ 34 | ...baseClassStruct, 35 | properties: [], 36 | methods: [], 37 | decorators: [], 38 | }); 39 | 40 | apply && source.saveSync(); 41 | } 42 | 43 | /** 44 | * Create method declaration for target class, from base structure. 45 | * @param source SourceFile 46 | * @param className 47 | * @param baseMethodStruct {@link IBaseMethodStruct} 48 | * @param apply save source file 49 | * @returns 50 | */ 51 | export function createBaseClassMethod( 52 | source: SourceFile, 53 | className: string, 54 | baseMethodStruct: IBaseMethodStruct, 55 | apply = true 56 | ) { 57 | if (checkMethodExistInClass(source, className, baseMethodStruct.name)) { 58 | return; 59 | } 60 | 61 | const targetClass = getClassDeclarations(source, className); 62 | 63 | if (!targetClass) { 64 | return; 65 | } 66 | 67 | targetClass.addMethod(baseMethodStruct); 68 | 69 | apply && source.saveSync(); 70 | } 71 | 72 | /** 73 | * Create prop declaration for target class, from base structure. 74 | * @param source SourceFile 75 | * @param className 76 | * @param basePropStruct {@link IBasePropStruct} 77 | * @param apply save source file 78 | * @returns 79 | */ 80 | export function createBaseClassProp( 81 | source: SourceFile, 82 | className: string, 83 | basePropStruct: IBasePropStruct, 84 | apply = true 85 | ) { 86 | if (checkPropExistInClass(source, className, basePropStruct.name)) { 87 | return; 88 | } 89 | 90 | const targetClass = getClassDeclarations(source, className); 91 | 92 | if (!targetClass) { 93 | return; 94 | } 95 | 96 | targetClass.addProperty(basePropStruct); 97 | 98 | apply && source.saveSync(); 99 | } 100 | 101 | /** 102 | * Create decorator declaration for target class, from base structure. 103 | * @param source SourceFile 104 | * @param className 105 | * @param baseDecoratorStruct {@link IBaseDecoratorStruct} 106 | * @param apply save source file 107 | * @returns 108 | */ 109 | export function createBaseClassDecorator( 110 | source: SourceFile, 111 | className: string, 112 | baseDecoratorStruct: IBaseDecoratorStruct, 113 | apply = true 114 | ) { 115 | if (checkDecoratorExistInClass(source, className, baseDecoratorStruct.name)) { 116 | return; 117 | } 118 | 119 | const targetClass = getClassDeclarations(source, className); 120 | 121 | if (!targetClass) { 122 | return; 123 | } 124 | 125 | targetClass.addDecorator(baseDecoratorStruct); 126 | 127 | apply && source.saveSync(); 128 | } 129 | -------------------------------------------------------------------------------- /docs/creator-docs/modules/class.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/creator](../README.md) / class 2 | 3 | # Module: class 4 | 5 | ## Table of contents 6 | 7 | ### Functions 8 | 9 | - [createBaseClass](class.md#createbaseclass) 10 | - [createBaseClassDecorator](class.md#createbaseclassdecorator) 11 | - [createBaseClassMethod](class.md#createbaseclassmethod) 12 | - [createBaseClassProp](class.md#createbaseclassprop) 13 | 14 | ## Functions 15 | 16 | ### createBaseClass 17 | 18 | ▸ **createBaseClass**(`source`, `baseClassStruct`, `apply?`): `void` 19 | 20 | Create class declaration from base structure. 21 | 22 | #### Parameters 23 | 24 | | Name | Type | Default value | Description | 25 | | :------ | :------ | :------ | :------ | 26 | | `source` | `SourceFile` | `undefined` | SourceFile | 27 | | `baseClassStruct` | `IBaseClassStructure` | `undefined` | {@link IBaseClassStructure} | 28 | | `apply` | `boolean` | `true` | save source file | 29 | 30 | #### Returns 31 | 32 | `void` 33 | 34 | #### Defined in 35 | 36 | [class.ts:24](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/creator/src/class.ts#L24) 37 | 38 | ___ 39 | 40 | ### createBaseClassDecorator 41 | 42 | ▸ **createBaseClassDecorator**(`source`, `className`, `baseDecoratorStruct`, `apply?`): `void` 43 | 44 | Create decorator declaration for target class, from base structure. 45 | 46 | #### Parameters 47 | 48 | | Name | Type | Default value | Description | 49 | | :------ | :------ | :------ | :------ | 50 | | `source` | `SourceFile` | `undefined` | SourceFile | 51 | | `className` | `string` | `undefined` | | 52 | | `baseDecoratorStruct` | `IBaseDecoratorStruct` | `undefined` | {@link IBaseDecoratorStruct} | 53 | | `apply` | `boolean` | `true` | save source file | 54 | 55 | #### Returns 56 | 57 | `void` 58 | 59 | #### Defined in 60 | 61 | [class.ts:109](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/creator/src/class.ts#L109) 62 | 63 | ___ 64 | 65 | ### createBaseClassMethod 66 | 67 | ▸ **createBaseClassMethod**(`source`, `className`, `baseMethodStruct`, `apply?`): `void` 68 | 69 | Create method declaration for target class, from base structure. 70 | 71 | #### Parameters 72 | 73 | | Name | Type | Default value | Description | 74 | | :------ | :------ | :------ | :------ | 75 | | `source` | `SourceFile` | `undefined` | SourceFile | 76 | | `className` | `string` | `undefined` | | 77 | | `baseMethodStruct` | `IBaseMethodStruct` | `undefined` | {@link IBaseMethodStruct} | 78 | | `apply` | `boolean` | `true` | save source file | 79 | 80 | #### Returns 81 | 82 | `void` 83 | 84 | #### Defined in 85 | 86 | [class.ts:51](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/creator/src/class.ts#L51) 87 | 88 | ___ 89 | 90 | ### createBaseClassProp 91 | 92 | ▸ **createBaseClassProp**(`source`, `className`, `basePropStruct`, `apply?`): `void` 93 | 94 | Create prop declaration for target class, from base structure. 95 | 96 | #### Parameters 97 | 98 | | Name | Type | Default value | Description | 99 | | :------ | :------ | :------ | :------ | 100 | | `source` | `SourceFile` | `undefined` | SourceFile | 101 | | `className` | `string` | `undefined` | | 102 | | `basePropStruct` | `IBasePropStruct` | `undefined` | {@link IBasePropStruct} | 103 | | `apply` | `boolean` | `true` | save source file | 104 | 105 | #### Returns 106 | 107 | `void` 108 | 109 | #### Defined in 110 | 111 | [class.ts:80](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/creator/src/class.ts#L80) 112 | -------------------------------------------------------------------------------- /packages/checker/src/export.ts: -------------------------------------------------------------------------------- 1 | import { 2 | SourceFile, 3 | SyntaxKind, 4 | VariableDeclarationKind, 5 | VariableStatement, 6 | } from "ts-morph"; 7 | import { 8 | getExportVariableStatements, 9 | getExportVariableIdentifiers, 10 | getTypeExportIdentifiers, 11 | getInterfaceExportIdentifiers, 12 | } from "@ts-morpher/helper"; 13 | 14 | /** 15 | * Check dose source file has `Export Variable Statement`(`export const foo = 'foo';`) defined. 16 | * @param source SourceFile 17 | * @example 18 | */ 19 | export function checkSourceFileHasExports(source: SourceFile): boolean { 20 | return Boolean(getExportVariableStatements(source).length); 21 | } 22 | 23 | /** 24 | * Check dose Source File has `Type Alias Export`(`export type A = string;`) or `Interface Export`(`export interface IFoo {}`) defined. 25 | * @param source SourceFile 26 | * @example 27 | */ 28 | export function checkSourceFileHasTypeExports(source: SourceFile): boolean { 29 | return ( 30 | Boolean(getTypeExportIdentifiers(source).length) || 31 | Boolean(getInterfaceExportIdentifiers(source).length) 32 | ); 33 | } 34 | 35 | /** 36 | * Check does export statements exist by export identifier. 37 | * @param source SourceFile 38 | * @param identifier `foo` in `export const foo = 123`; 39 | * @returns 40 | */ 41 | export function checkExportExistByIdentifier( 42 | source: SourceFile, 43 | identifier: string 44 | ): boolean { 45 | return getExportVariableIdentifiers(source).includes(identifier); 46 | } 47 | 48 | /** 49 | * Check export declare kind(var, let, const) by identifier. 50 | * @param source SourceFile 51 | * @param identifier `foo` in `export const foo = 123`; 52 | * @returns 53 | */ 54 | export function checkExportDeclarationKindByIdentifier( 55 | source: SourceFile, 56 | identifier: string 57 | ): VariableDeclarationKind | undefined { 58 | const statement = getExportVariableStatements(source, identifier); 59 | 60 | if (!statement) return; 61 | 62 | const declareList = statement.getFirstChildByKind( 63 | SyntaxKind.VariableDeclarationList 64 | ); 65 | 66 | return declareList.getDeclarationKind(); 67 | } 68 | 69 | /** 70 | * Check export declare kind(var, let, const) by statement. 71 | * @param source SourceFile 72 | * @param statement variable statement, use {@link getExportVariableStatements} to get statement definition 73 | * @returns 74 | */ 75 | export function checkExportDeclarationKindByStatement( 76 | statement: VariableStatement 77 | ): VariableDeclarationKind { 78 | const declareList = statement.getFirstChildByKind( 79 | SyntaxKind.VariableDeclarationList 80 | ); 81 | 82 | return declareList.getDeclarationKind(); 83 | } 84 | 85 | /** 86 | * Check does type alias export exist by identifier. 87 | * @param source SourceFile 88 | * @param identifier 'Foo' in `export type Foo = string;` 89 | * @returns 90 | */ 91 | export function checkTypeExportExistByIdentifier( 92 | source: SourceFile, 93 | identifier: string 94 | ) { 95 | return getTypeExportIdentifiers(source).includes(identifier); 96 | } 97 | 98 | /** 99 | * Check does interface export exist by identifier. 100 | * @param source SourceFile 101 | * @param identifier 'Foo' in `export interface Foo {};` 102 | * @returns 103 | */ 104 | export function checkInterfaceExportExistByIdentifier( 105 | source: SourceFile, 106 | identifier: string 107 | ) { 108 | return getInterfaceExportIdentifiers(source).includes(identifier); 109 | } 110 | -------------------------------------------------------------------------------- /docs/types-docs/interfaces/types.IBasePropStruct.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/types](../README.md) / [types](../modules/types.md) / IBasePropStruct 2 | 3 | # Interface: IBasePropStruct 4 | 5 | [types](../modules/types.md).IBasePropStruct 6 | 7 | Class property declaration structure 8 | 9 | ## Table of contents 10 | 11 | ### Properties 12 | 13 | - [decorators](types.IBasePropStruct.md#decorators) 14 | - [hasExclamationToken](types.IBasePropStruct.md#hasexclamationtoken) 15 | - [hasOverrideKeyword](types.IBasePropStruct.md#hasoverridekeyword) 16 | - [hasQuestionToken](types.IBasePropStruct.md#hasquestiontoken) 17 | - [initializer](types.IBasePropStruct.md#initializer) 18 | - [isAbstract](types.IBasePropStruct.md#isabstract) 19 | - [isReadonly](types.IBasePropStruct.md#isreadonly) 20 | - [isStatic](types.IBasePropStruct.md#isstatic) 21 | - [name](types.IBasePropStruct.md#name) 22 | - [scope](types.IBasePropStruct.md#scope) 23 | - [type](types.IBasePropStruct.md#type) 24 | 25 | ## Properties 26 | 27 | ### decorators 28 | 29 | • `Optional` **decorators**: [`IBaseDecoratorStruct`](types.IBaseDecoratorStruct.md)[] 30 | 31 | [IBaseDecoratorStruct](types.IBaseDecoratorStruct.md) 32 | 33 | #### Defined in 34 | 35 | [types.ts:148](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L148) 36 | 37 | ___ 38 | 39 | ### hasExclamationToken 40 | 41 | • `Optional` **hasExclamationToken**: `boolean` 42 | 43 | #### Defined in 44 | 45 | [types.ts:136](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L136) 46 | 47 | ___ 48 | 49 | ### hasOverrideKeyword 50 | 51 | • `Optional` **hasOverrideKeyword**: `boolean` 52 | 53 | #### Defined in 54 | 55 | [types.ts:137](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L137) 56 | 57 | ___ 58 | 59 | ### hasQuestionToken 60 | 61 | • `Optional` **hasQuestionToken**: `boolean` 62 | 63 | #### Defined in 64 | 65 | [types.ts:138](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L138) 66 | 67 | ___ 68 | 69 | ### initializer 70 | 71 | • `Optional` **initializer**: `string` \| `WriterFunction` 72 | 73 | #### Defined in 74 | 75 | [types.ts:140](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L140) 76 | 77 | ___ 78 | 79 | ### isAbstract 80 | 81 | • `Optional` **isAbstract**: `boolean` 82 | 83 | #### Defined in 84 | 85 | [types.ts:141](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L141) 86 | 87 | ___ 88 | 89 | ### isReadonly 90 | 91 | • `Optional` **isReadonly**: `boolean` 92 | 93 | #### Defined in 94 | 95 | [types.ts:142](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L142) 96 | 97 | ___ 98 | 99 | ### isStatic 100 | 101 | • `Optional` **isStatic**: `boolean` 102 | 103 | #### Defined in 104 | 105 | [types.ts:143](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L143) 106 | 107 | ___ 108 | 109 | ### name 110 | 111 | • **name**: `string` 112 | 113 | #### Defined in 114 | 115 | [types.ts:135](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L135) 116 | 117 | ___ 118 | 119 | ### scope 120 | 121 | • `Optional` **scope**: `Scope` 122 | 123 | #### Defined in 124 | 125 | [types.ts:144](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L144) 126 | 127 | ___ 128 | 129 | ### type 130 | 131 | • `Optional` **type**: `string` \| `WriterFunction` 132 | 133 | #### Defined in 134 | 135 | [types.ts:139](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L139) 136 | -------------------------------------------------------------------------------- /packages/helper/tests/import.test.ts: -------------------------------------------------------------------------------- 1 | import { Project } from "ts-morph"; 2 | import path from "path"; 3 | import { 4 | getImportDeclarations, 5 | getDefaultImportDeclarations, 6 | getDefaultImportModuleSpecifiers, 7 | getImportModuleSpecifiers, 8 | getNamedImportDeclarations, 9 | getNamedImportModuleSpecifiers, 10 | getNamespaceImportDeclarations, 11 | getNamespaceImportModuleSpecifiers, 12 | getNodeInternalImportDeclarations, 13 | getNodeInternalImportModuleSpecifiers, 14 | getNodeModuleImportDeclarations, 15 | getNodeModuleImportModuleSpecifiers, 16 | getTypeOnlyImportDeclarations, 17 | getTypeOnlyImportModuleSpecifiers, 18 | } from "../src/import"; 19 | 20 | const source = new Project().addSourceFileAtPath( 21 | path.resolve(__dirname, "./fixtures/import.fixture.ts") 22 | ); 23 | 24 | const source2 = new Project().addSourceFileAtPath( 25 | path.resolve(__dirname, "./fixtures/empty.fixture.ts") 26 | ); 27 | 28 | describe("package/helper-import", () => { 29 | it("should return empty", () => { 30 | expect(getImportDeclarations(source2)).toEqual([]); 31 | expect(getImportDeclarations(source2, "chalk")).toBeUndefined(); 32 | expect(getImportDeclarations(source2, ["chalk"])).toEqual([]); 33 | }); 34 | 35 | it("should return import declarations", () => { 36 | expect(getImportDeclarations(source).length).toBe(6); 37 | 38 | expect(getImportDeclarations(source, "path")).toBeDefined(); 39 | expect(getImportDeclarations(source, "chalk")).toBeUndefined(); 40 | expect(getImportDeclarations(source, ["chalk"])).toEqual([]); 41 | expect(getImportDeclarations(source, ["fs", "typescript"]).length).toBe(3); 42 | 43 | expect(getImportDeclarations(source, ["fs", "chalk"]).length).toBe(1); 44 | expect(getImportDeclarations(source, ["typescript", "chalk"]).length).toBe( 45 | 2 46 | ); 47 | expect(getNamedImportDeclarations(source).length).toBe(4); 48 | expect(getDefaultImportDeclarations(source).length).toBe(2); 49 | expect(getNamespaceImportDeclarations(source).length).toBe(1); 50 | expect(getTypeOnlyImportDeclarations(source).length).toBe(2); 51 | 52 | expect(getTypeOnlyImportDeclarations(source, "typescript")).toBeDefined(); 53 | 54 | expect( 55 | getTypeOnlyImportDeclarations(source, ["typescript", "buffer"]).length 56 | ).toBe(2); 57 | 58 | expect( 59 | getTypeOnlyImportDeclarations(source, ["typescript", "chalk"]).length 60 | ).toBe(1); 61 | 62 | expect(getTypeOnlyImportDeclarations(source, "chalk")).toBeUndefined(); 63 | 64 | expect(getNodeInternalImportDeclarations(source).length).toBe(4); 65 | expect(getNodeModuleImportDeclarations(source).length).toBe(2); 66 | }); 67 | }); 68 | 69 | it("should get identifiers", () => { 70 | expect(getDefaultImportModuleSpecifiers(source)).toEqual([ 71 | "fs", 72 | "child_process", 73 | ]); 74 | 75 | expect(getImportModuleSpecifiers(source)).toEqual([ 76 | "path", 77 | "fs", 78 | "typescript", 79 | "child_process", 80 | "buffer", 81 | ]); 82 | 83 | expect(getNamedImportModuleSpecifiers(source)).toEqual([ 84 | "typescript", 85 | "child_process", 86 | "buffer", 87 | ]); 88 | 89 | expect(getNamespaceImportModuleSpecifiers(source)).toEqual(["path"]); 90 | 91 | expect(getNodeInternalImportModuleSpecifiers(source)).toEqual([ 92 | "path", 93 | "fs", 94 | "child_process", 95 | "buffer", 96 | ]); 97 | 98 | expect(getNodeModuleImportModuleSpecifiers(source)).toEqual(["typescript"]); 99 | 100 | expect(getTypeOnlyImportModuleSpecifiers(source)).toEqual([ 101 | "buffer", 102 | "typescript", 103 | ]); 104 | }); 105 | -------------------------------------------------------------------------------- /packages/checker/src/class.ts: -------------------------------------------------------------------------------- 1 | import { SourceFile } from "ts-morph"; 2 | 3 | import { 4 | getClassDeclarations, 5 | getClassIdentifiers, 6 | getClassMethodDeclarations, 7 | getClassMethodIdentifiers, 8 | getClassPropDeclarations, 9 | getClassPropIdentifiers, 10 | getClassDecorators, 11 | getClassDecoratorIdentifiers, 12 | } from "@ts-morpher/helper"; 13 | 14 | /** 15 | * Check source file has class declarations exist. 16 | * @param source SourceFile 17 | * @returns 18 | */ 19 | export function checkSourceFileHasClass(source: SourceFile): boolean { 20 | return Boolean(getClassDeclarations(source).length); 21 | } 22 | 23 | /** 24 | * Check does class declaration exist in source file by class identifier. 25 | * @param source SourceFile 26 | * @param classIdentifier 27 | * @returns 28 | */ 29 | export function checkClassExistInSourceFile( 30 | source: SourceFile, 31 | classIdentifier: string 32 | ): boolean { 33 | return getClassIdentifiers(source).includes(classIdentifier); 34 | } 35 | 36 | /** 37 | * Check does method exist in class declaration. 38 | * @param source SourceFile 39 | * @param className 40 | * @param methodName 41 | * @returns 42 | */ 43 | export function checkMethodExistInClass( 44 | source: SourceFile, 45 | className: string, 46 | methodName: string 47 | ): boolean { 48 | return getClassMethodIdentifiers(source, className).includes(methodName); 49 | } 50 | 51 | /** 52 | * Check does prop exist in class. 53 | * @param source SourceFile 54 | * @param className 55 | * @param propName 56 | * @returns 57 | */ 58 | export function checkPropExistInClass( 59 | source: SourceFile, 60 | className: string, 61 | propName: string 62 | ): boolean { 63 | return getClassPropIdentifiers(source, className).includes(propName); 64 | } 65 | 66 | /** 67 | * Check does decorator exist in class. 68 | * @param source SourceFile 69 | * @param className 70 | * @param decoratorName 71 | * @returns 72 | */ 73 | export function checkDecoratorExistInClass( 74 | source: SourceFile, 75 | className: string, 76 | decoratorName: string 77 | ): boolean { 78 | return getClassDecoratorIdentifiers(source, className).includes( 79 | decoratorName 80 | ); 81 | } 82 | 83 | /** 84 | * Check does class has method defined. 85 | * @param source SourceFile 86 | * @param className 87 | * @returns 88 | */ 89 | export function checkClassHasMethods( 90 | source: SourceFile, 91 | className: string 92 | ): boolean { 93 | return Boolean(getClassMethodDeclarations(source, className).length); 94 | } 95 | 96 | /** 97 | * Check class has prop defined. 98 | * @param source SourceFile 99 | * @param prop 100 | * @returns 101 | */ 102 | export function checkClassHasProps(source: SourceFile, prop: string): boolean { 103 | return Boolean(getClassPropDeclarations(source, prop).length); 104 | } 105 | 106 | /** 107 | * Check class has decorator defined. 108 | * @param source SourceFile 109 | * @param className 110 | * @returns 111 | */ 112 | export function checkClassHasDecorators( 113 | source: SourceFile, 114 | className: string 115 | ): boolean { 116 | return Boolean(getClassDecorators(source, className).length); 117 | } 118 | 119 | /** 120 | * Check is a decorator factory (`@Foo()`) 121 | * @param source SourceFile 122 | * @param className 123 | * @param decoratorName 124 | * @returns 125 | */ 126 | export function checkIsDecoratorFactory( 127 | source: SourceFile, 128 | className: string, 129 | decoratorName: string 130 | ): boolean { 131 | const targetDecorator = getClassDecorators(source, className, decoratorName); 132 | 133 | return targetDecorator ? targetDecorator.isDecoratorFactory() : false; 134 | } 135 | -------------------------------------------------------------------------------- /packages/types/src/types.ts: -------------------------------------------------------------------------------- 1 | import { Scope, WriterFunction } from "ts-morph"; 2 | /** 3 | * Shared type parameter structure 4 | */ 5 | export interface IGenericTypeParam { 6 | /** 7 | * T in `T extends Condition = Default` 8 | */ 9 | name: string; 10 | /** 11 | * Condition in `T extends Condition = Default` 12 | */ 13 | default?: string | WriterFunction; 14 | /** 15 | * Default in `T extends Condition = Default` 16 | */ 17 | constraint?: string | WriterFunction; 18 | } 19 | /** 20 | * Interface index signature structure 21 | */ 22 | export interface IInterfaceIndexSignature { 23 | /** 24 | * key in `[key: string]: any` 25 | */ 26 | keyName: string; 27 | /** 28 | * string in `[key: string]: any` 29 | */ 30 | keyType: string; 31 | /** 32 | * any in `[key: string]: any` 33 | */ 34 | returnType: string | WriterFunction; 35 | isReadonly?: boolean; 36 | } 37 | /** 38 | * Interface property structure 39 | */ 40 | export interface IInterfaceProperty { 41 | name: string; 42 | hasQuestionToken?: boolean; 43 | type: string | WriterFunction; 44 | } 45 | /** 46 | * Type alias structure 47 | */ 48 | export interface ISharedTypeStructure { 49 | name: string; 50 | /** 51 | * {@link IGenericTypeParam} 52 | */ 53 | typeParameters?: IGenericTypeParam[]; 54 | isExported?: boolean; 55 | hasDeclareKeyword?: boolean; 56 | } 57 | /** 58 | * Class declaration structure 59 | */ 60 | export interface IBaseClassStructure { 61 | name: string; 62 | implements?: WriterFunction | (string | WriterFunction)[]; 63 | extends?: string | WriterFunction; 64 | isAbstract?: boolean; 65 | isExported?: boolean; 66 | isDefaultExport?: boolean; 67 | } 68 | 69 | /** 70 | * Decorator structure 71 | */ 72 | export interface IBaseDecoratorStruct { 73 | name: string; 74 | /** 75 | * Arguments for a decorator factory. 76 | * @remarks Provide an empty array to make the structure a decorator factory. 77 | */ 78 | arguments?: (string | WriterFunction)[] | WriterFunction; 79 | typeArguments?: string[]; 80 | } 81 | /** 82 | * Class method param declaration structure 83 | */ 84 | export interface IBaseMethodParamStruct { 85 | name: string; 86 | /** 87 | * string in `method(arg1: string){}` 88 | */ 89 | type?: string | WriterFunction; 90 | isReadonly?: boolean; 91 | hasQuestionToken?: boolean; 92 | hasOverrideKeyword?: boolean; 93 | /** 94 | * e.g. foo in `method(arg1 = 'foo'){}` 95 | */ 96 | initializer?: string | WriterFunction; 97 | isRestParameter?: boolean; 98 | scope?: Scope; 99 | /** 100 | * {@link IBaseDecoratorStruct} 101 | */ 102 | decorators?: IBaseDecoratorStruct[]; 103 | } 104 | /** 105 | * Class method declaration structure 106 | */ 107 | export interface IBaseMethodStruct { 108 | name: string; 109 | isAbstract?: boolean; 110 | isAsync?: boolean; 111 | isGenerator?: boolean; 112 | isStatic?: boolean; 113 | hasQuestionToken?: boolean; 114 | hasOverrideKeyword?: boolean; 115 | /** 116 | * {@link IBaseMethodParamStruct} 117 | */ 118 | parameters?: IBaseMethodParamStruct[]; 119 | /** 120 | * {@link IGenericTypeParam} 121 | */ 122 | typeParameters?: (IGenericTypeParam | string)[]; 123 | statements?: string | WriterFunction | (string | WriterFunction)[]; 124 | returnType?: string | WriterFunction; 125 | scope?: Scope; 126 | /** 127 | * {@link IBaseDecoratorStruct} 128 | */ 129 | decorators?: IBaseDecoratorStruct[]; 130 | } 131 | /** 132 | * Class property declaration structure 133 | */ 134 | export interface IBasePropStruct { 135 | name: string; 136 | hasExclamationToken?: boolean; 137 | hasOverrideKeyword?: boolean; 138 | hasQuestionToken?: boolean; 139 | type?: string | WriterFunction; 140 | initializer?: string | WriterFunction; 141 | isAbstract?: boolean; 142 | isReadonly?: boolean; 143 | isStatic?: boolean; 144 | scope?: Scope; 145 | /** 146 | * {@link IBaseDecoratorStruct} 147 | */ 148 | decorators?: IBaseDecoratorStruct[]; 149 | } 150 | -------------------------------------------------------------------------------- /packages/cleaner/tests/class.test.ts: -------------------------------------------------------------------------------- 1 | import { Project, SourceFile } from "ts-morph"; 2 | import path from "path"; 3 | import fs from "fs-extra"; 4 | import { 5 | checkClassExistInSourceFile, 6 | checkDecoratorExistInClass, 7 | checkPropExistInClass, 8 | checkMethodExistInClass, 9 | } from "@ts-morpher/checker"; 10 | 11 | import { 12 | removeClass, 13 | removeClassDecorator, 14 | removeClassMethod, 15 | removeClassProp, 16 | } from "../src/class"; 17 | 18 | const p = new Project(); 19 | 20 | let source: SourceFile; 21 | 22 | let source2: SourceFile; 23 | 24 | const savedContent = fs.readFileSync( 25 | path.resolve(__dirname, "./fixtures/class.fixture.ts") 26 | ); 27 | 28 | const savedContent2 = fs.readFileSync( 29 | path.resolve(__dirname, "./fixtures/empty.fixture.ts") 30 | ); 31 | 32 | beforeEach(() => { 33 | source && p.removeSourceFile(source); 34 | source && p.removeSourceFile(source2); 35 | 36 | source = p.addSourceFileAtPath( 37 | path.resolve(__dirname, "./fixtures/class.fixture.ts") 38 | ); 39 | 40 | source2 = p.addSourceFileAtPath( 41 | path.resolve(__dirname, "./fixtures/empty.fixture.ts") 42 | ); 43 | }); 44 | 45 | afterEach(() => { 46 | fs.writeFileSync( 47 | path.resolve(__dirname, "./fixtures/class.fixture.ts"), 48 | savedContent 49 | ); 50 | 51 | fs.writeFileSync( 52 | path.resolve(__dirname, "./fixtures/empty.fixture.ts"), 53 | savedContent2 54 | ); 55 | }); 56 | 57 | describe("package/cleaner-class", () => { 58 | it("should remove class declarations", () => { 59 | expect(checkClassExistInSourceFile(source, "Foo")).toBeTruthy(); 60 | removeClass(source, "Foo"); 61 | expect(checkClassExistInSourceFile(source, "Foo")).toBeFalsy(); 62 | 63 | expect(checkClassExistInSourceFile(source2, "Foo")).toBeFalsy(); 64 | removeClass(source2, "Foo"); 65 | expect(checkClassExistInSourceFile(source2, "Foo")).toBeFalsy(); 66 | }); 67 | it("should remove class method declarations", () => { 68 | expect(checkMethodExistInClass(source, "Foo", "method1")).toBeTruthy(); 69 | removeClassMethod(source, "Foo", "method1"); 70 | expect(checkMethodExistInClass(source, "Foo", "method1")).toBeFalsy(); 71 | 72 | expect(checkMethodExistInClass(source, "Foo", "method599")).toBeFalsy(); 73 | removeClassMethod(source, "Foo", "method599"); 74 | expect(checkMethodExistInClass(source, "Foo", "method1")).toBeFalsy(); 75 | 76 | expect(checkMethodExistInClass(source2, "Foo", "method599")).toBeFalsy(); 77 | removeClassMethod(source2, "Foo", "method599"); 78 | expect(checkMethodExistInClass(source2, "Foo", "method599")).toBeFalsy(); 79 | }); 80 | it("should remove class prop declarations", () => { 81 | expect(checkPropExistInClass(source, "Foo", "prop1")).toBeTruthy(); 82 | removeClassProp(source, "Foo", "prop1"); 83 | expect(checkPropExistInClass(source, "Foo", "prop1")).toBeFalsy(); 84 | 85 | expect(checkPropExistInClass(source, "Foo", "prop111")).toBeFalsy(); 86 | removeClassProp(source, "Foo", "prop111"); 87 | expect(checkPropExistInClass(source, "Foo", "prop111")).toBeFalsy(); 88 | 89 | expect(checkPropExistInClass(source2, "Foo", "prop111")).toBeFalsy(); 90 | removeClassProp(source2, "Foo", "prop111"); 91 | expect(checkPropExistInClass(source2, "Foo", "prop111")).toBeFalsy(); 92 | }); 93 | it("should remove class decorator declarations", () => { 94 | expect(checkDecoratorExistInClass(source, "Foo", "classDeco")).toBeTruthy(); 95 | removeClassDecorator(source, "Foo", "classDeco"); 96 | expect(checkDecoratorExistInClass(source, "Foo", "classDeco")).toBeFalsy(); 97 | 98 | expect( 99 | checkDecoratorExistInClass(source, "Foo", "classDeco111") 100 | ).toBeFalsy(); 101 | removeClassDecorator(source, "Foo", "classDeco111"); 102 | expect( 103 | checkDecoratorExistInClass(source, "Foo", "classDeco111") 104 | ).toBeFalsy(); 105 | 106 | expect( 107 | checkDecoratorExistInClass(source2, "Foo", "classDeco111") 108 | ).toBeFalsy(); 109 | removeClassDecorator(source2, "Foo", "classDeco111"); 110 | expect( 111 | checkDecoratorExistInClass(source2, "Foo", "classDeco111") 112 | ).toBeFalsy(); 113 | }); 114 | }); 115 | -------------------------------------------------------------------------------- /packages/creator/src/import.ts: -------------------------------------------------------------------------------- 1 | import { SourceFile } from "ts-morph"; 2 | import ow from "ow"; 3 | 4 | import { ensureArray, MaybeArray } from "@ts-morpher/helper"; 5 | import { ImportType } from "@ts-morpher/types"; 6 | 7 | /** 8 | * Add a namespace import declaration. 9 | * @param source SourceFile 10 | * @param namespace import namespace 11 | * @param moduleSpecifier import specifier 12 | * @param importType ImportType.NAMESPACE_IMPORT 13 | * @param apply save source file 14 | * @returns void 15 | */ 16 | export function createImportDeclaration( 17 | source: SourceFile, 18 | namespace: string, 19 | moduleSpecifier: string, 20 | importType: ImportType.NAMESPACE_IMPORT, 21 | apply?: boolean 22 | ): void; 23 | 24 | /** 25 | * Add a named import declaration. 26 | * @param source SourceFile 27 | * @param namedImports named imports member 28 | * @param moduleSpecifier import specifier 29 | * @param importType ImportType.NAMED_IMPORT 30 | * @param isTypeOnly create type only import 31 | * @param apply save source file 32 | * @returns void 33 | */ 34 | export function createImportDeclaration( 35 | source: SourceFile, 36 | namedImports: MaybeArray, 37 | moduleSpecifier: string, 38 | importType: ImportType.NAMED_IMPORT, 39 | isTypeOnly?: boolean, 40 | apply?: boolean 41 | ): void; 42 | 43 | /** 44 | * Add a default import declaration. 45 | * @param source SourceFile 46 | * @param importClause import clause 47 | * @param moduleSpecifier import specifier 48 | * @param importType ImportType.DEFAULT_IMPORT 49 | * @param isTypeOnly create type only import 50 | * @param apply save source file 51 | * @returns void 52 | */ 53 | export function createImportDeclaration( 54 | source: SourceFile, 55 | defaultImport: string, 56 | moduleSpecifier: string, 57 | importType: ImportType.DEFAULT_IMPORT, 58 | apply?: boolean 59 | ): void; 60 | 61 | /** 62 | * Add a default with named import declaration. 63 | * @param source SourceFile 64 | * @param defaultAndNamedImports default and named imports member, the 1st item will be regarded as default 65 | * @param moduleSpecifier import specifier 66 | * @param importType ImportType.DEFAULT_WITH_NAMED_IMPORT 67 | * @param apply save source file 68 | * @returns void 69 | */ 70 | export function createImportDeclaration( 71 | source: SourceFile, 72 | namedImports: MaybeArray, 73 | moduleSpecifier: string, 74 | importType: ImportType.DEFAULT_WITH_NAMED_IMPORT, 75 | apply?: boolean 76 | ): void; 77 | 78 | /** 79 | * Add a new import declaration of specified type. 80 | * @param source SourceFile 81 | * @param importClause namespace / named imports / default import depends on importType 82 | * @param moduleSpecifier import specifier 83 | * @param importType import type to create 84 | * @param isTypeOnly create type only import 85 | * @param apply save source file 86 | * @returns void 87 | */ 88 | export function createImportDeclaration( 89 | source: SourceFile, 90 | importClause: MaybeArray, 91 | moduleSpecifier: string, 92 | importType: ImportType, 93 | isTypeOnly = false, 94 | apply = true 95 | ): void { 96 | switch (importType) { 97 | case ImportType.DEFAULT_IMPORT: 98 | ow(importClause, ow.string); 99 | 100 | source.addImportDeclaration({ 101 | defaultImport: importClause, 102 | moduleSpecifier, 103 | isTypeOnly: false, 104 | }); 105 | 106 | break; 107 | 108 | case ImportType.NAMED_IMPORT: 109 | source.addImportDeclaration({ 110 | namedImports: ensureArray(importClause), 111 | moduleSpecifier, 112 | isTypeOnly, 113 | }); 114 | 115 | break; 116 | 117 | case ImportType.NAMESPACE_IMPORT: 118 | ow(importClause, ow.string); 119 | 120 | source.addImportDeclaration({ 121 | namespaceImport: importClause, 122 | moduleSpecifier: moduleSpecifier, 123 | isTypeOnly: false, 124 | }); 125 | 126 | break; 127 | 128 | case ImportType.DEFAULT_WITH_NAMED_IMPORT: 129 | const [defaultImport, ...namedImports] = ensureArray(importClause); 130 | 131 | source.addImportDeclaration({ 132 | defaultImport, 133 | namedImports, 134 | moduleSpecifier, 135 | isTypeOnly: false, 136 | }); 137 | 138 | break; 139 | } 140 | 141 | apply && source.saveSync(); 142 | } 143 | -------------------------------------------------------------------------------- /docs/types-docs/interfaces/types.IBaseMethodStruct.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/types](../README.md) / [types](../modules/types.md) / IBaseMethodStruct 2 | 3 | # Interface: IBaseMethodStruct 4 | 5 | [types](../modules/types.md).IBaseMethodStruct 6 | 7 | Class method declaration structure 8 | 9 | ## Table of contents 10 | 11 | ### Properties 12 | 13 | - [decorators](types.IBaseMethodStruct.md#decorators) 14 | - [hasOverrideKeyword](types.IBaseMethodStruct.md#hasoverridekeyword) 15 | - [hasQuestionToken](types.IBaseMethodStruct.md#hasquestiontoken) 16 | - [isAbstract](types.IBaseMethodStruct.md#isabstract) 17 | - [isAsync](types.IBaseMethodStruct.md#isasync) 18 | - [isGenerator](types.IBaseMethodStruct.md#isgenerator) 19 | - [isStatic](types.IBaseMethodStruct.md#isstatic) 20 | - [name](types.IBaseMethodStruct.md#name) 21 | - [parameters](types.IBaseMethodStruct.md#parameters) 22 | - [returnType](types.IBaseMethodStruct.md#returntype) 23 | - [scope](types.IBaseMethodStruct.md#scope) 24 | - [statements](types.IBaseMethodStruct.md#statements) 25 | - [typeParameters](types.IBaseMethodStruct.md#typeparameters) 26 | 27 | ## Properties 28 | 29 | ### decorators 30 | 31 | • `Optional` **decorators**: [`IBaseDecoratorStruct`](types.IBaseDecoratorStruct.md)[] 32 | 33 | [IBaseDecoratorStruct](types.IBaseDecoratorStruct.md) 34 | 35 | #### Defined in 36 | 37 | [types.ts:129](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L129) 38 | 39 | ___ 40 | 41 | ### hasOverrideKeyword 42 | 43 | • `Optional` **hasOverrideKeyword**: `boolean` 44 | 45 | #### Defined in 46 | 47 | [types.ts:114](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L114) 48 | 49 | ___ 50 | 51 | ### hasQuestionToken 52 | 53 | • `Optional` **hasQuestionToken**: `boolean` 54 | 55 | #### Defined in 56 | 57 | [types.ts:113](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L113) 58 | 59 | ___ 60 | 61 | ### isAbstract 62 | 63 | • `Optional` **isAbstract**: `boolean` 64 | 65 | #### Defined in 66 | 67 | [types.ts:109](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L109) 68 | 69 | ___ 70 | 71 | ### isAsync 72 | 73 | • `Optional` **isAsync**: `boolean` 74 | 75 | #### Defined in 76 | 77 | [types.ts:110](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L110) 78 | 79 | ___ 80 | 81 | ### isGenerator 82 | 83 | • `Optional` **isGenerator**: `boolean` 84 | 85 | #### Defined in 86 | 87 | [types.ts:111](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L111) 88 | 89 | ___ 90 | 91 | ### isStatic 92 | 93 | • `Optional` **isStatic**: `boolean` 94 | 95 | #### Defined in 96 | 97 | [types.ts:112](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L112) 98 | 99 | ___ 100 | 101 | ### name 102 | 103 | • **name**: `string` 104 | 105 | #### Defined in 106 | 107 | [types.ts:108](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L108) 108 | 109 | ___ 110 | 111 | ### parameters 112 | 113 | • `Optional` **parameters**: [`IBaseMethodParamStruct`](types.IBaseMethodParamStruct.md)[] 114 | 115 | [IBaseMethodParamStruct](types.IBaseMethodParamStruct.md) 116 | 117 | #### Defined in 118 | 119 | [types.ts:118](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L118) 120 | 121 | ___ 122 | 123 | ### returnType 124 | 125 | • `Optional` **returnType**: `string` \| `WriterFunction` 126 | 127 | #### Defined in 128 | 129 | [types.ts:124](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L124) 130 | 131 | ___ 132 | 133 | ### scope 134 | 135 | • `Optional` **scope**: `Scope` 136 | 137 | #### Defined in 138 | 139 | [types.ts:125](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L125) 140 | 141 | ___ 142 | 143 | ### statements 144 | 145 | • `Optional` **statements**: `string` \| `WriterFunction` \| (`string` \| `WriterFunction`)[] 146 | 147 | #### Defined in 148 | 149 | [types.ts:123](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L123) 150 | 151 | ___ 152 | 153 | ### typeParameters 154 | 155 | • `Optional` **typeParameters**: (`string` \| [`IGenericTypeParam`](types.IGenericTypeParam.md))[] 156 | 157 | [IGenericTypeParam](types.IGenericTypeParam.md) 158 | 159 | #### Defined in 160 | 161 | [types.ts:122](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/types/src/types.ts#L122) 162 | -------------------------------------------------------------------------------- /packages/creator/src/export.ts: -------------------------------------------------------------------------------- 1 | import { SourceFile, VariableDeclarationKind, WriterFunction } from "ts-morph"; 2 | 3 | import { 4 | IGenericTypeParam, 5 | IInterfaceIndexSignature, 6 | IInterfaceProperty, 7 | } from "@ts-morpher/types"; 8 | 9 | /** 10 | * Create export variable statement from base structure. 11 | * @param source SourceFile 12 | * @param identifier variable identifier, 'foo' in `export const foo = 'bar'` 13 | * @param initializer initializer, 'bar' in `export const foo = 'bar'` 14 | * @param kind declaration kind {@link VariableDeclarationKind} 15 | * @param apply save source file 16 | */ 17 | export function createBaseVariableExport( 18 | source: SourceFile, 19 | identifier: string, 20 | initializer: string | WriterFunction, 21 | kind: VariableDeclarationKind, 22 | apply = true 23 | ) { 24 | source.addVariableStatement({ 25 | isExported: true, 26 | declarations: [ 27 | { 28 | name: identifier, 29 | initializer, 30 | }, 31 | ], 32 | declarationKind: kind, 33 | }); 34 | 35 | apply && source.saveSync(); 36 | } 37 | 38 | /** 39 | * Create type alias export from base structure. 40 | * @param source SourceFile 41 | * @param identifier 'Foo' in `export type Foo = string` 42 | * @param typeInitializer 'string' in `export type Foo = string` 43 | * @param genericTypeParams {@link IGenericTypeParam} 44 | * @param apply save source file 45 | * @example 46 | * ```typescript 47 | * createBaseTypeExport(source, "Foo", "Record", [ 48 | { 49 | name: "T", 50 | default: "'default_string_literal'", 51 | constraint: "string", 52 | }, 53 | ]); 54 | 55 | // create following statement: 56 | export type Foo = Record< 57 | T, 58 | unknown 59 | >; 60 | ``` 61 | */ 62 | export function createBaseTypeExport( 63 | source: SourceFile, 64 | identifier: string, 65 | typeInitializer: string | WriterFunction, 66 | genericTypeParams?: (IGenericTypeParam | string)[], 67 | apply = true 68 | ) { 69 | source.addTypeAlias({ 70 | isExported: true, 71 | name: identifier, 72 | type: typeInitializer, 73 | typeParameters: genericTypeParams, 74 | }); 75 | 76 | apply && source.saveSync(); 77 | } 78 | 79 | /** 80 | * Create base interface export 81 | * @param source 82 | * @param identifier 83 | * @param interfaceExtends extra interfaces to extend 84 | * @param indexSignatures {@link IInterfaceIndexSignature} specify index-signatures like [key:string]: any 85 | * @param properties {@link IInterfaceProperty} interface properties structure 86 | * @param genericTypeParams {@link IGenericTypeParam} generic type params to use in interface 87 | * @param apply save source file 88 | * @example 89 | * ```typescript 90 | * createBaseInterfaceExport( 91 | source, 92 | "Foo", 93 | ["Bar", "Baz"], 94 | [ 95 | { 96 | keyName: "Foo", 97 | keyType: "string", 98 | returnType: "unknown", 99 | isReadonly: false, 100 | }, 101 | ], 102 | [ 103 | { 104 | name: "name", 105 | type: "string", 106 | }, 107 | { 108 | name: "age", 109 | type: "number", 110 | hasQuestionToken: true, 111 | }, 112 | { 113 | name: "other", 114 | type: "T", 115 | }, 116 | ], 117 | [ 118 | { 119 | name: "T", 120 | default: "'default_string_literal'", 121 | constraint: "string", 122 | }, 123 | ] 124 | ); 125 | 126 | // create following statement: 127 | export interface Foo extends Bar, Baz { 128 | [Foo: string]: unknown; 129 | name: string; 130 | age?: number; 131 | other: T; 132 | } 133 | ``` 134 | 135 | */ 136 | export function createBaseInterfaceExport( 137 | source: SourceFile, 138 | identifier: string, 139 | interfaceExtends: string[] = [], 140 | indexSignatures: IInterfaceIndexSignature[] = [], 141 | properties: IInterfaceProperty[] = [], 142 | genericTypeParams: (IGenericTypeParam | string)[] = [], 143 | apply = true 144 | ) { 145 | source.addInterface({ 146 | isExported: true, 147 | name: identifier, 148 | extends: interfaceExtends, 149 | typeParameters: genericTypeParams, 150 | indexSignatures, 151 | properties, 152 | }); 153 | 154 | apply && source.saveSync(); 155 | } 156 | -------------------------------------------------------------------------------- /docs/modifier-docs/modules/index.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/modifier](../README.md) / index 2 | 3 | # Module: index 4 | 5 | ## Table of contents 6 | 7 | ### References 8 | 9 | - [IBaseDeclarationStructure](index.md#ibasedeclarationstructure) 10 | - [IBaseInterfaceStructure](index.md#ibaseinterfacestructure) 11 | - [IBaseTypeAliasStructure](index.md#ibasetypealiasstructure) 12 | - [IBaseVariableExportStructure](index.md#ibasevariableexportstructure) 13 | - [addNamedImportMembers](index.md#addnamedimportmembers) 14 | - [removeNamedImportMembers](index.md#removenamedimportmembers) 15 | - [updateBaseClassDecoratorStructure](index.md#updatebaseclassdecoratorstructure) 16 | - [updateBaseClassMethodStructure](index.md#updatebaseclassmethodstructure) 17 | - [updateBaseClassPropStructure](index.md#updatebaseclasspropstructure) 18 | - [updateBaseClassStructure](index.md#updatebaseclassstructure) 19 | - [updateClassDecoratorIdentifier](index.md#updateclassdecoratoridentifier) 20 | - [updateClassIdentifier](index.md#updateclassidentifier) 21 | - [updateDefaultImportClause](index.md#updatedefaultimportclause) 22 | - [updateImportSpecifier](index.md#updateimportspecifier) 23 | - [updateInterfaceExportStructure](index.md#updateinterfaceexportstructure) 24 | - [updateNamespaceImportClause](index.md#updatenamespaceimportclause) 25 | - [updateTypeExportStructure](index.md#updatetypeexportstructure) 26 | - [updateVariableExportIdentifier](index.md#updatevariableexportidentifier) 27 | - [updateVariableExportKind](index.md#updatevariableexportkind) 28 | - [updateVariableExportStructure](index.md#updatevariableexportstructure) 29 | 30 | ## References 31 | 32 | ### IBaseDeclarationStructure 33 | 34 | Re-exports [IBaseDeclarationStructure](../interfaces/export.IBaseDeclarationStructure.md) 35 | 36 | ___ 37 | 38 | ### IBaseInterfaceStructure 39 | 40 | Re-exports [IBaseInterfaceStructure](../interfaces/export.IBaseInterfaceStructure.md) 41 | 42 | ___ 43 | 44 | ### IBaseTypeAliasStructure 45 | 46 | Re-exports [IBaseTypeAliasStructure](../interfaces/export.IBaseTypeAliasStructure.md) 47 | 48 | ___ 49 | 50 | ### IBaseVariableExportStructure 51 | 52 | Re-exports [IBaseVariableExportStructure](../interfaces/export.IBaseVariableExportStructure.md) 53 | 54 | ___ 55 | 56 | ### addNamedImportMembers 57 | 58 | Re-exports [addNamedImportMembers](import.md#addnamedimportmembers) 59 | 60 | ___ 61 | 62 | ### removeNamedImportMembers 63 | 64 | Re-exports [removeNamedImportMembers](import.md#removenamedimportmembers) 65 | 66 | ___ 67 | 68 | ### updateBaseClassDecoratorStructure 69 | 70 | Re-exports [updateBaseClassDecoratorStructure](class.md#updatebaseclassdecoratorstructure) 71 | 72 | ___ 73 | 74 | ### updateBaseClassMethodStructure 75 | 76 | Re-exports [updateBaseClassMethodStructure](class.md#updatebaseclassmethodstructure) 77 | 78 | ___ 79 | 80 | ### updateBaseClassPropStructure 81 | 82 | Re-exports [updateBaseClassPropStructure](class.md#updatebaseclasspropstructure) 83 | 84 | ___ 85 | 86 | ### updateBaseClassStructure 87 | 88 | Re-exports [updateBaseClassStructure](class.md#updatebaseclassstructure) 89 | 90 | ___ 91 | 92 | ### updateClassDecoratorIdentifier 93 | 94 | Re-exports [updateClassDecoratorIdentifier](class.md#updateclassdecoratoridentifier) 95 | 96 | ___ 97 | 98 | ### updateClassIdentifier 99 | 100 | Re-exports [updateClassIdentifier](class.md#updateclassidentifier) 101 | 102 | ___ 103 | 104 | ### updateDefaultImportClause 105 | 106 | Re-exports [updateDefaultImportClause](import.md#updatedefaultimportclause) 107 | 108 | ___ 109 | 110 | ### updateImportSpecifier 111 | 112 | Re-exports [updateImportSpecifier](import.md#updateimportspecifier) 113 | 114 | ___ 115 | 116 | ### updateInterfaceExportStructure 117 | 118 | Re-exports [updateInterfaceExportStructure](export.md#updateinterfaceexportstructure) 119 | 120 | ___ 121 | 122 | ### updateNamespaceImportClause 123 | 124 | Re-exports [updateNamespaceImportClause](import.md#updatenamespaceimportclause) 125 | 126 | ___ 127 | 128 | ### updateTypeExportStructure 129 | 130 | Re-exports [updateTypeExportStructure](export.md#updatetypeexportstructure) 131 | 132 | ___ 133 | 134 | ### updateVariableExportIdentifier 135 | 136 | Re-exports [updateVariableExportIdentifier](export.md#updatevariableexportidentifier) 137 | 138 | ___ 139 | 140 | ### updateVariableExportKind 141 | 142 | Re-exports [updateVariableExportKind](export.md#updatevariableexportkind) 143 | 144 | ___ 145 | 146 | ### updateVariableExportStructure 147 | 148 | Re-exports [updateVariableExportStructure](export.md#updatevariableexportstructure) 149 | -------------------------------------------------------------------------------- /docs/modifier-docs/modules/import.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/modifier](../README.md) / import 2 | 3 | # Module: import 4 | 5 | ## Table of contents 6 | 7 | ### Functions 8 | 9 | - [addNamedImportMembers](import.md#addnamedimportmembers) 10 | - [removeNamedImportMembers](import.md#removenamedimportmembers) 11 | - [updateDefaultImportClause](import.md#updatedefaultimportclause) 12 | - [updateImportSpecifier](import.md#updateimportspecifier) 13 | - [updateNamespaceImportClause](import.md#updatenamespaceimportclause) 14 | 15 | ## Functions 16 | 17 | ### addNamedImportMembers 18 | 19 | ▸ **addNamedImportMembers**(`source`, `importSpec`, `members`, `createOnInexist?`, `apply?`): `void` 20 | 21 | Add new members to the namespace import. 22 | 23 | #### Parameters 24 | 25 | | Name | Type | Default value | Description | 26 | | :------ | :------ | :------ | :------ | 27 | | `source` | `SourceFile` | `undefined` | SourceFile | 28 | | `importSpec` | `string` | `undefined` | namespace import specifier | 29 | | `members` | `string`[] | `undefined` | import clause members to add | 30 | | `createOnInexist` | `boolean` | `false` | create a namespace import declaration when target import not found | 31 | | `apply` | `boolean` | `true` | save source file | 32 | 33 | #### Returns 34 | 35 | `void` 36 | 37 | #### Defined in 38 | 39 | [modifier/src/import.ts:56](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/modifier/src/import.ts#L56) 40 | 41 | ___ 42 | 43 | ### removeNamedImportMembers 44 | 45 | ▸ **removeNamedImportMembers**(`source`, `importSpec`, `members`, `apply?`): `void` 46 | 47 | Remove members in the namespace import. 48 | 49 | #### Parameters 50 | 51 | | Name | Type | Default value | Description | 52 | | :------ | :------ | :------ | :------ | 53 | | `source` | `SourceFile` | `undefined` | SourceFile | 54 | | `importSpec` | `string` | `undefined` | namespace import specifier | 55 | | `members` | `string`[] | `undefined` | import clause members to remove | 56 | | `apply` | `boolean` | `true` | save source file | 57 | 58 | #### Returns 59 | 60 | `void` 61 | 62 | #### Defined in 63 | 64 | [modifier/src/import.ts:103](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/modifier/src/import.ts#L103) 65 | 66 | ___ 67 | 68 | ### updateDefaultImportClause 69 | 70 | ▸ **updateDefaultImportClause**(`source`, `specifier`, `updatedClause`, `apply?`): `void` 71 | 72 | Set import clause of default import directly. 73 | 74 | #### Parameters 75 | 76 | | Name | Type | Default value | Description | 77 | | :------ | :------ | :------ | :------ | 78 | | `source` | `SourceFile` | `undefined` | SourceFile | 79 | | `specifier` | `string` | `undefined` | import specifier | 80 | | `updatedClause` | `string` | `undefined` | import clause to set | 81 | | `apply` | `boolean` | `true` | save source file | 82 | 83 | #### Returns 84 | 85 | `void` 86 | 87 | #### Defined in 88 | 89 | [modifier/src/import.ts:172](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/modifier/src/import.ts#L172) 90 | 91 | ___ 92 | 93 | ### updateImportSpecifier 94 | 95 | ▸ **updateImportSpecifier**(`source`, `moduleSpecifier`, `updatedModuleSpecifier`, `apply?`): `void` 96 | 97 | Update import module specifier. 98 | 99 | #### Parameters 100 | 101 | | Name | Type | Default value | Description | 102 | | :------ | :------ | :------ | :------ | 103 | | `source` | `SourceFile` | `undefined` | SourceFile | 104 | | `moduleSpecifier` | `string` | `undefined` | import specifier | 105 | | `updatedModuleSpecifier` | `string` | `undefined` | updated import specifier | 106 | | `apply` | `boolean` | `true` | save source file | 107 | 108 | #### Returns 109 | 110 | `void` 111 | 112 | #### Defined in 113 | 114 | [modifier/src/import.ts:147](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/modifier/src/import.ts#L147) 115 | 116 | ___ 117 | 118 | ### updateNamespaceImportClause 119 | 120 | ▸ **updateNamespaceImportClause**(`source`, `specifier`, `updatedNamespace`, `apply?`): `void` 121 | 122 | Set import clause of namespace import directly. 123 | 124 | #### Parameters 125 | 126 | | Name | Type | Default value | Description | 127 | | :------ | :------ | :------ | :------ | 128 | | `source` | `SourceFile` | `undefined` | SourceFile | 129 | | `specifier` | `string` | `undefined` | import specifier | 130 | | `updatedNamespace` | `string` | `undefined` | import clause to set | 131 | | `apply` | `boolean` | `true` | save source file | 132 | 133 | #### Returns 134 | 135 | `void` 136 | 137 | #### Defined in 138 | 139 | [modifier/src/import.ts:197](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/modifier/src/import.ts#L197) 140 | -------------------------------------------------------------------------------- /docs/creator-docs/modules/export.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/creator](../README.md) / export 2 | 3 | # Module: export 4 | 5 | ## Table of contents 6 | 7 | ### Functions 8 | 9 | - [createBaseInterfaceExport](export.md#createbaseinterfaceexport) 10 | - [createBaseTypeExport](export.md#createbasetypeexport) 11 | - [createBaseVariableExport](export.md#createbasevariableexport) 12 | 13 | ## Functions 14 | 15 | ### createBaseInterfaceExport 16 | 17 | ▸ **createBaseInterfaceExport**(`source`, `identifier`, `interfaceExtends?`, `indexSignatures?`, `properties?`, `genericTypeParams?`, `apply?`): `void` 18 | 19 | Create base interface export 20 | 21 | **`example`** 22 | ```typescript 23 | createBaseInterfaceExport( 24 | source, 25 | "Foo", 26 | ["Bar", "Baz"], 27 | [ 28 | { 29 | keyName: "Foo", 30 | keyType: "string", 31 | returnType: "unknown", 32 | isReadonly: false, 33 | }, 34 | ], 35 | [ 36 | { 37 | name: "name", 38 | type: "string", 39 | }, 40 | { 41 | name: "age", 42 | type: "number", 43 | hasQuestionToken: true, 44 | }, 45 | { 46 | name: "other", 47 | type: "T", 48 | }, 49 | ], 50 | [ 51 | { 52 | name: "T", 53 | default: "'default_string_literal'", 54 | constraint: "string", 55 | }, 56 | ] 57 | ); 58 | 59 | // create following statement: 60 | export interface Foo extends Bar, Baz { 61 | [Foo: string]: unknown; 62 | name: string; 63 | age?: number; 64 | other: T; 65 | } 66 | ``` 67 | 68 | #### Parameters 69 | 70 | | Name | Type | Default value | Description | 71 | | :------ | :------ | :------ | :------ | 72 | | `source` | `SourceFile` | `undefined` | | 73 | | `identifier` | `string` | `undefined` | | 74 | | `interfaceExtends` | `string`[] | `[]` | extra interfaces to extend | 75 | | `indexSignatures` | `IInterfaceIndexSignature`[] | `[]` | {@link IInterfaceIndexSignature} specify index-signatures like [key:string]: any | 76 | | `properties` | `IInterfaceProperty`[] | `[]` | {@link IInterfaceProperty} interface properties structure | 77 | | `genericTypeParams` | (`string` \| `IGenericTypeParam`)[] | `[]` | {@link IGenericTypeParam} generic type params to use in interface | 78 | | `apply` | `boolean` | `true` | save source file | 79 | 80 | #### Returns 81 | 82 | `void` 83 | 84 | #### Defined in 85 | 86 | [export.ts:136](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/creator/src/export.ts#L136) 87 | 88 | ___ 89 | 90 | ### createBaseTypeExport 91 | 92 | ▸ **createBaseTypeExport**(`source`, `identifier`, `typeInitializer`, `genericTypeParams?`, `apply?`): `void` 93 | 94 | Create type alias export from base structure. 95 | 96 | **`example`** 97 | ```typescript 98 | createBaseTypeExport(source, "Foo", "Record", [ 99 | { 100 | name: "T", 101 | default: "'default_string_literal'", 102 | constraint: "string", 103 | }, 104 | ]); 105 | 106 | // create following statement: 107 | export type Foo = Record< 108 | T, 109 | unknown 110 | >; 111 | ``` 112 | 113 | #### Parameters 114 | 115 | | Name | Type | Default value | Description | 116 | | :------ | :------ | :------ | :------ | 117 | | `source` | `SourceFile` | `undefined` | SourceFile | 118 | | `identifier` | `string` | `undefined` | 'Foo' in `export type Foo = string` | 119 | | `typeInitializer` | `string` \| `WriterFunction` | `undefined` | 'string' in `export type Foo = string` | 120 | | `genericTypeParams?` | (`string` \| `IGenericTypeParam`)[] | `undefined` | {@link IGenericTypeParam} | 121 | | `apply` | `boolean` | `true` | save source file | 122 | 123 | #### Returns 124 | 125 | `void` 126 | 127 | #### Defined in 128 | 129 | [export.ts:62](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/creator/src/export.ts#L62) 130 | 131 | ___ 132 | 133 | ### createBaseVariableExport 134 | 135 | ▸ **createBaseVariableExport**(`source`, `identifier`, `initializer`, `kind`, `apply?`): `void` 136 | 137 | Create export variable statement from base structure. 138 | 139 | #### Parameters 140 | 141 | | Name | Type | Default value | Description | 142 | | :------ | :------ | :------ | :------ | 143 | | `source` | `SourceFile` | `undefined` | SourceFile | 144 | | `identifier` | `string` | `undefined` | variable identifier, 'foo' in `export const foo = 'bar'` | 145 | | `initializer` | `string` \| `WriterFunction` | `undefined` | initializer, 'bar' in `export const foo = 'bar'` | 146 | | `kind` | `VariableDeclarationKind` | `undefined` | declaration kind {@link VariableDeclarationKind} | 147 | | `apply` | `boolean` | `true` | save source file | 148 | 149 | #### Returns 150 | 151 | `void` 152 | 153 | #### Defined in 154 | 155 | [export.ts:17](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/creator/src/export.ts#L17) 156 | -------------------------------------------------------------------------------- /packages/cleaner/tests/import.test.ts: -------------------------------------------------------------------------------- 1 | import { Project, SourceFile } from "ts-morph"; 2 | import path from "path"; 3 | import fs from "fs-extra"; 4 | import { checkSourceFileHasImports } from "@ts-morpher/checker"; 5 | import { 6 | getImportDeclarations, 7 | getImportModuleSpecifiers, 8 | getTypeOnlyImportModuleSpecifiers, 9 | } from "@ts-morpher/helper"; 10 | 11 | import { 12 | removeAllImports, 13 | removeAllTypeOnlyImports, 14 | removeImportDeclarationByModuleSpecifier, 15 | removeImportDeclarationByType, 16 | } from "../src/import"; 17 | 18 | const p = new Project(); 19 | 20 | let source: SourceFile; 21 | 22 | let source2: SourceFile; 23 | 24 | const savedContent = fs.readFileSync( 25 | path.resolve(__dirname, "./fixtures/import.fixture.ts") 26 | ); 27 | 28 | const savedContent2 = fs.readFileSync( 29 | path.resolve(__dirname, "./fixtures/empty.fixture.ts") 30 | ); 31 | 32 | beforeEach(() => { 33 | source && p.removeSourceFile(source); 34 | source && p.removeSourceFile(source2); 35 | 36 | source = p.addSourceFileAtPath( 37 | path.resolve(__dirname, "./fixtures/import.fixture.ts") 38 | ); 39 | 40 | source2 = p.addSourceFileAtPath( 41 | path.resolve(__dirname, "./fixtures/empty.fixture.ts") 42 | ); 43 | }); 44 | 45 | afterEach(() => { 46 | fs.writeFileSync( 47 | path.resolve(__dirname, "./fixtures/import.fixture.ts"), 48 | savedContent 49 | ); 50 | 51 | fs.writeFileSync( 52 | path.resolve(__dirname, "./fixtures/empty.fixture.ts"), 53 | savedContent2 54 | ); 55 | }); 56 | 57 | describe("package/cleaner-cleaner", () => { 58 | it("should remove all imports", () => { 59 | expect(checkSourceFileHasImports(source)).toBeTruthy(); 60 | removeAllImports(source); 61 | expect(checkSourceFileHasImports(source)).toBeFalsy(); 62 | 63 | expect(checkSourceFileHasImports(source2)).toBeFalsy(); 64 | removeAllImports(source2); 65 | expect(checkSourceFileHasImports(source2)).toBeFalsy(); 66 | }); 67 | 68 | it("should remove all type-only imports", () => { 69 | expect(checkSourceFileHasImports(source)).toBeTruthy(); 70 | removeAllTypeOnlyImports(source); 71 | expect(checkSourceFileHasImports(source)).toBeTruthy(); 72 | expect(getTypeOnlyImportModuleSpecifiers(source)).toEqual([]); 73 | expect(getImportDeclarations(source).length).toBe(4); 74 | }); 75 | 76 | it("should remove by module specifiers 1", () => { 77 | expect(checkSourceFileHasImports(source)).toBeTruthy(); 78 | expect(getImportDeclarations(source).length).toBe(6); 79 | removeImportDeclarationByModuleSpecifier(source, ["path"]); 80 | expect(checkSourceFileHasImports(source)).toBeTruthy(); 81 | expect(getImportDeclarations(source).length).toBe(5); 82 | expect(getImportDeclarations(source, "path")).toBeUndefined(); 83 | }); 84 | 85 | it("should remove by module specifiers 2", () => { 86 | expect(checkSourceFileHasImports(source)).toBeTruthy(); 87 | expect(getImportDeclarations(source).length).toBe(6); 88 | removeImportDeclarationByModuleSpecifier(source, ["path", "buffer"]); 89 | expect(checkSourceFileHasImports(source)).toBeTruthy(); 90 | expect(getImportDeclarations(source).length).toBe(4); 91 | expect(getImportDeclarations(source, "path")).toBeUndefined(); 92 | expect(getImportDeclarations(source, "buffer")).toBeUndefined(); 93 | }); 94 | 95 | it("should remove by import type - named", () => { 96 | expect(checkSourceFileHasImports(source)).toBeTruthy(); 97 | removeImportDeclarationByType(source, { named: true }); 98 | expect(checkSourceFileHasImports(source)).toBeTruthy(); 99 | expect(getImportModuleSpecifiers(source).sort()).toEqual( 100 | ["path", "fs", "child_process"].sort() 101 | ); 102 | }); 103 | 104 | it("should remove by import type - namespace", () => { 105 | expect(checkSourceFileHasImports(source)).toBeTruthy(); 106 | removeImportDeclarationByType(source, { namespace: true }); 107 | expect(checkSourceFileHasImports(source)).toBeTruthy(); 108 | expect(getImportModuleSpecifiers(source).sort()).toEqual( 109 | ["typescript", "buffer", "fs", "child_process"].sort() 110 | ); 111 | }); 112 | 113 | it("should remove by import type - default", () => { 114 | expect(checkSourceFileHasImports(source)).toBeTruthy(); 115 | removeImportDeclarationByType(source, { default: true }); 116 | expect(checkSourceFileHasImports(source)).toBeTruthy(); 117 | expect(getImportModuleSpecifiers(source).sort()).toEqual( 118 | ["path", "typescript", "child_process", "buffer"].sort() 119 | ); 120 | }); 121 | 122 | it("should remove by import type - skipped", () => { 123 | expect(checkSourceFileHasImports(source2)).toBeFalsy(); 124 | removeImportDeclarationByType(source2, { default: true }); 125 | expect(checkSourceFileHasImports(source2)).toBeFalsy(); 126 | }); 127 | }); 128 | -------------------------------------------------------------------------------- /packages/modifier/src/export.ts: -------------------------------------------------------------------------------- 1 | import { SourceFile, VariableDeclarationKind, WriterFunction } from "ts-morph"; 2 | 3 | import { 4 | getTypeExportDeclaration, 5 | getTypeExportIdentifiers, 6 | getInterfaceExportDeclaration, 7 | getInterfaceExportIdentifiers, 8 | getExportVariableIdentifiers, 9 | getExportVariableStatements, 10 | } from "@ts-morpher/helper"; 11 | import { ISharedTypeStructure } from "@ts-morpher/types"; 12 | 13 | /** 14 | * update variable export identifier. 15 | * @param source SourceFile 16 | * @param identifier previous identifier 17 | * @param updatedIdentifier updated identifier 18 | * @param apply save source file 19 | */ 20 | export function updateVariableExportIdentifier( 21 | source: SourceFile, 22 | identifier: string, 23 | updatedIdentifier: string, 24 | apply = true 25 | ) { 26 | const initializer = getExportVariableStatements(source, identifier) 27 | ?.getDeclarations()[0] 28 | ?.getInitializer() 29 | ?.getText(); 30 | 31 | updateVariableExportStructure( 32 | source, 33 | identifier, 34 | { 35 | declarations: [{ name: updatedIdentifier, initializer }], 36 | }, 37 | apply 38 | ); 39 | } 40 | 41 | /** 42 | * update variable export declaration kind. 43 | * @param source SourceFile 44 | * @param identifier previous identifier 45 | * @param declarationKind updated declaration kind 46 | * @param apply save source file 47 | */ 48 | export function updateVariableExportKind( 49 | source: SourceFile, 50 | identifier: string, 51 | declarationKind: VariableDeclarationKind, 52 | apply = true 53 | ) { 54 | updateVariableExportStructure( 55 | source, 56 | identifier, 57 | { 58 | declarationKind, 59 | }, 60 | apply 61 | ); 62 | } 63 | 64 | /** 65 | * Basic variable declaration structure. 66 | */ 67 | export interface IBaseDeclarationStructure { 68 | name: string; 69 | hasExclamationToken?: boolean; 70 | initializer?: string | WriterFunction; 71 | type?: string | WriterFunction; 72 | } 73 | 74 | /** 75 | * Basic variable structure. 76 | */ 77 | export interface IBaseVariableExportStructure { 78 | declarationKind?: VariableDeclarationKind; 79 | 80 | /** 81 | * {@link IBaseDeclarationStructure} 82 | */ 83 | declarations?: IBaseDeclarationStructure[]; 84 | 85 | isExported?: boolean; 86 | isDefaultExport?: boolean; 87 | } 88 | 89 | /** 90 | * update base structure of variable export. 91 | * @param source SourceFile 92 | * @param identifier variable identifier 93 | * @param structure {@link IBaseVariableExportStructure} updated structure 94 | * @param apply save source file 95 | * @returns void 96 | */ 97 | export function updateVariableExportStructure( 98 | source: SourceFile, 99 | identifier: string, 100 | structure: IBaseVariableExportStructure, 101 | apply = true 102 | ) { 103 | if (!getExportVariableIdentifiers(source).includes(identifier)) { 104 | return; 105 | } 106 | 107 | const target = getExportVariableStatements(source, identifier); 108 | 109 | target.set(structure); 110 | 111 | apply && source.saveSync(); 112 | } 113 | 114 | /** 115 | * Basic type alias structure 116 | */ 117 | export interface IBaseTypeAliasStructure extends ISharedTypeStructure { 118 | type?: string | WriterFunction; 119 | } 120 | 121 | /** 122 | * update base structure of type alias export. 123 | * @param source SourceFile 124 | * @param identifier type alias identifier 125 | * @param structure {@link IBaseTypeAliasStructure} updated structure 126 | * @param apply save source file 127 | * @returns 128 | */ 129 | export function updateTypeExportStructure( 130 | source: SourceFile, 131 | identifier: string, 132 | structure: IBaseTypeAliasStructure, 133 | apply = true 134 | ) { 135 | if (!getTypeExportIdentifiers(source).includes(identifier)) { 136 | return; 137 | } 138 | 139 | const target = getTypeExportDeclaration(source, identifier); 140 | 141 | target.set(structure); 142 | 143 | apply && source.saveSync(); 144 | } 145 | 146 | /** 147 | * Basic interface structure. 148 | */ 149 | export interface IBaseInterfaceStructure extends ISharedTypeStructure { 150 | extends?: (string | WriterFunction)[] | WriterFunction; 151 | } 152 | 153 | /** 154 | * update base structure of interface export. 155 | * @param source SourceFile 156 | * @param identifier interface identifier 157 | * @param structure {@link IBaseInterfaceStructure } updated structure 158 | * @param apply save source file 159 | * @returns void 160 | */ 161 | export function updateInterfaceExportStructure( 162 | source: SourceFile, 163 | identifier: string, 164 | structure: IBaseInterfaceStructure, 165 | apply = true 166 | ) { 167 | if (!getInterfaceExportIdentifiers(source).includes(identifier)) { 168 | return; 169 | } 170 | 171 | const target = getInterfaceExportDeclaration(source, identifier); 172 | 173 | target.set(structure); 174 | 175 | apply && source.saveSync(); 176 | } 177 | -------------------------------------------------------------------------------- /docs/checker-docs/modules/export.md: -------------------------------------------------------------------------------- 1 | [@ts-morpher/checker](../README.md) / export 2 | 3 | # Module: export 4 | 5 | ## Table of contents 6 | 7 | ### Functions 8 | 9 | - [checkExportDeclarationKindByIdentifier](export.md#checkexportdeclarationkindbyidentifier) 10 | - [checkExportDeclarationKindByStatement](export.md#checkexportdeclarationkindbystatement) 11 | - [checkExportExistByIdentifier](export.md#checkexportexistbyidentifier) 12 | - [checkInterfaceExportExistByIdentifier](export.md#checkinterfaceexportexistbyidentifier) 13 | - [checkSourceFileHasExports](export.md#checksourcefilehasexports) 14 | - [checkSourceFileHasTypeExports](export.md#checksourcefilehastypeexports) 15 | - [checkTypeExportExistByIdentifier](export.md#checktypeexportexistbyidentifier) 16 | 17 | ## Functions 18 | 19 | ### checkExportDeclarationKindByIdentifier 20 | 21 | ▸ **checkExportDeclarationKindByIdentifier**(`source`, `identifier`): `VariableDeclarationKind` \| `undefined` 22 | 23 | Check export declare kind(var, let, const) by identifier. 24 | 25 | #### Parameters 26 | 27 | | Name | Type | Description | 28 | | :------ | :------ | :------ | 29 | | `source` | `SourceFile` | SourceFile | 30 | | `identifier` | `string` | `foo` in `export const foo = 123`; | 31 | 32 | #### Returns 33 | 34 | `VariableDeclarationKind` \| `undefined` 35 | 36 | #### Defined in 37 | 38 | [export.ts:54](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/checker/src/export.ts#L54) 39 | 40 | ___ 41 | 42 | ### checkExportDeclarationKindByStatement 43 | 44 | ▸ **checkExportDeclarationKindByStatement**(`statement`): `VariableDeclarationKind` 45 | 46 | Check export declare kind(var, let, const) by statement. 47 | 48 | #### Parameters 49 | 50 | | Name | Type | Description | 51 | | :------ | :------ | :------ | 52 | | `statement` | `VariableStatement` | variable statement, use {@link getExportVariableStatements} to get statement definition | 53 | 54 | #### Returns 55 | 56 | `VariableDeclarationKind` 57 | 58 | #### Defined in 59 | 60 | [export.ts:75](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/checker/src/export.ts#L75) 61 | 62 | ___ 63 | 64 | ### checkExportExistByIdentifier 65 | 66 | ▸ **checkExportExistByIdentifier**(`source`, `identifier`): `boolean` 67 | 68 | Check does export statements exist by export identifier. 69 | 70 | #### Parameters 71 | 72 | | Name | Type | Description | 73 | | :------ | :------ | :------ | 74 | | `source` | `SourceFile` | SourceFile | 75 | | `identifier` | `string` | `foo` in `export const foo = 123`; | 76 | 77 | #### Returns 78 | 79 | `boolean` 80 | 81 | #### Defined in 82 | 83 | [export.ts:41](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/checker/src/export.ts#L41) 84 | 85 | ___ 86 | 87 | ### checkInterfaceExportExistByIdentifier 88 | 89 | ▸ **checkInterfaceExportExistByIdentifier**(`source`, `identifier`): `boolean` 90 | 91 | Check does interface export exist by identifier. 92 | 93 | #### Parameters 94 | 95 | | Name | Type | Description | 96 | | :------ | :------ | :------ | 97 | | `source` | `SourceFile` | SourceFile | 98 | | `identifier` | `string` | 'Foo' in `export interface Foo {};` | 99 | 100 | #### Returns 101 | 102 | `boolean` 103 | 104 | #### Defined in 105 | 106 | [export.ts:104](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/checker/src/export.ts#L104) 107 | 108 | ___ 109 | 110 | ### checkSourceFileHasExports 111 | 112 | ▸ **checkSourceFileHasExports**(`source`): `boolean` 113 | 114 | Check dose source file has `Export Variable Statement`(`export const foo = 'foo';`) defined. 115 | 116 | **`example`** 117 | 118 | #### Parameters 119 | 120 | | Name | Type | Description | 121 | | :------ | :------ | :------ | 122 | | `source` | `SourceFile` | SourceFile | 123 | 124 | #### Returns 125 | 126 | `boolean` 127 | 128 | #### Defined in 129 | 130 | [export.ts:19](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/checker/src/export.ts#L19) 131 | 132 | ___ 133 | 134 | ### checkSourceFileHasTypeExports 135 | 136 | ▸ **checkSourceFileHasTypeExports**(`source`): `boolean` 137 | 138 | Check dose Source File has `Type Alias Export`(`export type A = string;`) or `Interface Export`(`export interface IFoo {}`) defined. 139 | 140 | **`example`** 141 | 142 | #### Parameters 143 | 144 | | Name | Type | Description | 145 | | :------ | :------ | :------ | 146 | | `source` | `SourceFile` | SourceFile | 147 | 148 | #### Returns 149 | 150 | `boolean` 151 | 152 | #### Defined in 153 | 154 | [export.ts:28](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/checker/src/export.ts#L28) 155 | 156 | ___ 157 | 158 | ### checkTypeExportExistByIdentifier 159 | 160 | ▸ **checkTypeExportExistByIdentifier**(`source`, `identifier`): `boolean` 161 | 162 | Check does type alias export exist by identifier. 163 | 164 | #### Parameters 165 | 166 | | Name | Type | Description | 167 | | :------ | :------ | :------ | 168 | | `source` | `SourceFile` | SourceFile | 169 | | `identifier` | `string` | 'Foo' in `export type Foo = string;` | 170 | 171 | #### Returns 172 | 173 | `boolean` 174 | 175 | #### Defined in 176 | 177 | [export.ts:91](https://github.com/linbudu599/morpher/blob/2a43a9a/packages/checker/src/export.ts#L91) 178 | -------------------------------------------------------------------------------- /packages/modifier/src/class.ts: -------------------------------------------------------------------------------- 1 | import { SourceFile } from "ts-morph"; 2 | 3 | import { 4 | getClassDeclarations, 5 | getClassMethodDeclarations, 6 | getClassPropDeclarations, 7 | getClassDecorators, 8 | } from "@ts-morpher/helper"; 9 | import { 10 | IBaseMethodStruct, 11 | IBaseClassStructure, 12 | IBasePropStruct, 13 | IBaseDecoratorStruct, 14 | } from "@ts-morpher/types"; 15 | 16 | /** 17 | * Update class identifier. 18 | * @param source SourceFile 19 | * @param classIdentifier 20 | * @param updatedIdentifier 21 | * @param apply save source file 22 | * @returns 23 | */ 24 | export function updateClassIdentifier( 25 | source: SourceFile, 26 | classIdentifier: string, 27 | updatedIdentifier: string, 28 | apply = true 29 | ): void { 30 | const targetClass = getClassDeclarations(source, classIdentifier); 31 | 32 | if (!targetClass) return; 33 | 34 | targetClass.set({ 35 | name: updatedIdentifier, 36 | }); 37 | 38 | apply && source.saveSync(); 39 | } 40 | 41 | /** 42 | * Update class decorator identifier. 43 | * @param source SourceFile 44 | * @param classIdentifier 45 | * @param decoratorIdentifier 46 | * @param updatedIdentifier 47 | * @param apply save source file 48 | * @returns 49 | */ 50 | export function updateClassDecoratorIdentifier( 51 | source: SourceFile, 52 | classIdentifier: string, 53 | decoratorIdentifier: string, 54 | updatedIdentifier: string, 55 | apply = true 56 | ) { 57 | const targetClass = getClassDeclarations(source, classIdentifier); 58 | 59 | if (!targetClass) return; 60 | 61 | const targetDecorator = getClassDecorators( 62 | source, 63 | classIdentifier, 64 | decoratorIdentifier 65 | ); 66 | 67 | if (!targetDecorator) return; 68 | 69 | targetDecorator.set({ 70 | name: updatedIdentifier, 71 | }); 72 | 73 | apply && source.saveSync(); 74 | } 75 | 76 | /** 77 | * Update base class structure. 78 | * @param source SourceFile 79 | * @param classIdentifier 80 | * @param baseClassStruct {@link IBaseClassStructure} 81 | * @param apply save source file 82 | * @returns 83 | */ 84 | export function updateBaseClassStructure( 85 | source: SourceFile, 86 | classIdentifier: string, 87 | baseClassStruct: IBaseClassStructure, 88 | apply = true 89 | ) { 90 | const targetClass = getClassDeclarations(source, classIdentifier); 91 | 92 | if (!targetClass) return; 93 | 94 | targetClass.set(baseClassStruct); 95 | 96 | apply && source.saveSync(); 97 | } 98 | 99 | /** 100 | * Update base class method declaration structure. 101 | * @param source SourceFile 102 | * @param classIdentifier 103 | * @param methodIdentifier 104 | * @param baseMethodStruct {@link IBaseMethodStruct} 105 | * @param apply save source file 106 | * @returns 107 | */ 108 | export function updateBaseClassMethodStructure( 109 | source: SourceFile, 110 | classIdentifier: string, 111 | methodIdentifier: string, 112 | baseMethodStruct: IBaseMethodStruct, 113 | apply = true 114 | ) { 115 | const targetClass = getClassDeclarations(source, classIdentifier); 116 | 117 | if (!targetClass) return; 118 | 119 | const targetMethod = getClassMethodDeclarations( 120 | source, 121 | classIdentifier, 122 | methodIdentifier 123 | ); 124 | 125 | if (!targetMethod) return; 126 | 127 | targetMethod.set(baseMethodStruct); 128 | 129 | apply && source.saveSync(); 130 | } 131 | 132 | /** 133 | * Update base class prop declaration structure. 134 | * @param source SourceFile 135 | * @param classIdentifier 136 | * @param propIdentifier 137 | * @param basePropStruct {@link IBasePropStruct} 138 | * @param apply save source file 139 | * @returns 140 | */ 141 | export function updateBaseClassPropStructure( 142 | source: SourceFile, 143 | classIdentifier: string, 144 | propIdentifier: string, 145 | basePropStruct: IBasePropStruct, 146 | apply = true 147 | ) { 148 | const targetClass = getClassDeclarations(source, classIdentifier); 149 | 150 | if (!targetClass) return; 151 | 152 | const targetProp = getClassPropDeclarations( 153 | source, 154 | classIdentifier, 155 | propIdentifier 156 | ); 157 | 158 | if (!targetProp) return; 159 | 160 | targetProp.set(basePropStruct); 161 | 162 | apply && source.saveSync(); 163 | } 164 | 165 | /** 166 | * Update base class decorator declaration structure. 167 | * @param source SourceFile 168 | * @param classIdentifier 169 | * @param decoratorIdentifier 170 | * @param baseDecoratorStruct {@link IBaseDecoratorStruct} 171 | * @param apply save source file 172 | * @returns 173 | */ 174 | export function updateBaseClassDecoratorStructure( 175 | source: SourceFile, 176 | classIdentifier: string, 177 | decoratorIdentifier: string, 178 | baseDecoratorStruct: IBaseDecoratorStruct, 179 | apply = true 180 | ) { 181 | const targetClass = getClassDeclarations(source, classIdentifier); 182 | 183 | if (!targetClass) return; 184 | 185 | const targetDecorator = getClassDecorators( 186 | source, 187 | classIdentifier, 188 | decoratorIdentifier 189 | ); 190 | 191 | if (!targetDecorator) return; 192 | 193 | targetDecorator.set(baseDecoratorStruct); 194 | 195 | apply && source.saveSync(); 196 | } 197 | --------------------------------------------------------------------------------