├── .gflowrc ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── 01_bug-report.md │ ├── 02_feature-request.md │ ├── 04_say-thank-you.md │ └── config.yml ├── dependabot.yml ├── stale.yml └── workflows │ ├── build.yml │ ├── close-issue-message.yml │ ├── code-ql.yml │ ├── rebase.yml │ └── website.yml ├── .gitignore ├── .husky ├── .gitignore ├── commit-msg ├── post-commit └── pre-commit ├── .lintstagedrc ├── .npmignore ├── .nvmrc ├── .prettierignore ├── .prettierrc ├── .yarn └── releases │ └── yarn-4.7.0.cjs ├── .yarnrc.yml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── commitlint.config.js ├── docs ├── .gitignore ├── .vuepress │ ├── components │ │ ├── CLI.vue │ │ ├── HomeBody.vue │ │ ├── SupportOptions.vue │ │ └── SupportUsBlock.vue │ ├── config.js │ ├── enhanceApp.js │ ├── package.json │ ├── public │ │ ├── .nojekyll │ │ ├── CNAME │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-512x512.png │ │ ├── api.json │ │ ├── apple-touch-icon.png │ │ ├── aws.png │ │ ├── azure.png │ │ ├── babel.svg │ │ ├── bg.svg │ │ ├── eslint.svg │ │ ├── express.png │ │ ├── expressjs.svg │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon.ico │ │ ├── hero-bg.svg │ │ ├── jest.svg │ │ ├── koa.svg │ │ ├── mochajs.svg │ │ ├── mongoose.png │ │ ├── passportjs.png │ │ ├── react.png │ │ ├── site.webmanifest │ │ ├── socketio.png │ │ ├── socketio.svg │ │ ├── sponsors.svg │ │ ├── swagger.svg │ │ ├── tsed-og.png │ │ ├── tsed.png │ │ ├── typegraphql.png │ │ ├── typeorm.png │ │ ├── typescript.png │ │ ├── vitest.png │ │ ├── vuejs.png │ │ └── webpack.svg │ ├── scripts │ │ ├── addWorkerScript.js │ │ ├── build.sh │ │ └── updateBuildScript.js │ └── window-boot.js ├── api.md ├── contributing.md ├── getting-started.md ├── package.json ├── readme.md ├── support.md └── yarn.lock ├── eslint.config.js ├── lerna.json ├── package.json ├── packages ├── barrels │ ├── .gitignore │ ├── .npmignore │ ├── bin │ │ ├── barrels.js │ │ ├── generate-barrel.js │ │ └── get-config.js │ ├── package.json │ ├── readme.md │ └── test │ │ ├── __mock__ │ │ ├── scenario-1 │ │ │ ├── file1.spec.ts │ │ │ ├── file1.ts │ │ │ ├── file2.ts │ │ │ └── sub-directory │ │ │ │ └── file2.ts │ │ ├── scenario-2 │ │ │ ├── sub-directory-1 │ │ │ │ └── file2.ts │ │ │ └── sub-directory-2 │ │ │ │ └── file2.ts │ │ ├── scenario-3 │ │ │ ├── sub-directory-1 │ │ │ │ ├── file2.ts │ │ │ │ └── sub-path │ │ │ │ │ └── file3.ts │ │ │ └── sub-directory-2 │ │ │ │ └── file2.ts │ │ └── tsconfig.json │ │ └── barrels.integration.spec.js ├── cli-core │ ├── .npmignore │ ├── package.json │ ├── readme.md │ ├── src │ │ ├── CliCore.spec.ts │ │ ├── CliCore.ts │ │ ├── decorators │ │ │ ├── command.ts │ │ │ ├── index.ts │ │ │ ├── on.ts │ │ │ ├── onAdd.spec.ts │ │ │ ├── onAdd.ts │ │ │ ├── onExec.spec.ts │ │ │ ├── onExec.ts │ │ │ ├── onPostInstall.spec.ts │ │ │ ├── onPostInstall.ts │ │ │ ├── onPrompt.spec.ts │ │ │ └── onPrompt.ts │ │ ├── domains │ │ │ ├── CliError.ts │ │ │ └── CommandStoreKeys.ts │ │ ├── index.ts │ │ ├── interfaces │ │ │ ├── CliDefaultOptions.ts │ │ │ ├── CommandMetadata.ts │ │ │ ├── CommandParameters.ts │ │ │ ├── CommandProvider.ts │ │ │ ├── PackageJson.ts │ │ │ ├── ProjectPreferences.ts │ │ │ ├── Tasks.ts │ │ │ └── index.ts │ │ ├── packageManagers │ │ │ ├── PackageManagersModule.spec.ts │ │ │ ├── PackageManagersModule.ts │ │ │ ├── index.ts │ │ │ └── supports │ │ │ │ ├── BaseManager.ts │ │ │ │ ├── BunManager.spec.ts │ │ │ │ ├── BunManager.ts │ │ │ │ ├── NpmManager.spec.ts │ │ │ │ ├── NpmManager.ts │ │ │ │ ├── PNpmManager.spec.ts │ │ │ │ ├── PNpmManager.ts │ │ │ │ ├── YarnBerryManager.spec.ts │ │ │ │ ├── YarnBerryManager.ts │ │ │ │ ├── YarnManager.spec.ts │ │ │ │ └── YarnManager.ts │ │ ├── services │ │ │ ├── CliConfiguration.ts │ │ │ ├── CliDockerComposeYaml.ts │ │ │ ├── CliExeca.ts │ │ │ ├── CliFs.ts │ │ │ ├── CliHooks.ts │ │ │ ├── CliHttpClient.spec.ts │ │ │ ├── CliHttpClient.ts │ │ │ ├── CliHttpLogClient.ts │ │ │ ├── CliLoadFile.spec.ts │ │ │ ├── CliLoadFile.ts │ │ │ ├── CliPackageJson.ts │ │ │ ├── CliPlugins.spec.ts │ │ │ ├── CliPlugins.ts │ │ │ ├── CliProxyAgent.spec.ts │ │ │ ├── CliProxyAgent.ts │ │ │ ├── CliService.ts │ │ │ ├── CliYaml.ts │ │ │ ├── NpmRegistryClient.spec.ts │ │ │ ├── NpmRegistryClient.ts │ │ │ ├── ProjectPackageJson.spec.ts │ │ │ ├── ProjectPackageJson.ts │ │ │ ├── __mock__ │ │ │ │ ├── package.json │ │ │ │ ├── settings.json │ │ │ │ └── settings.yml │ │ │ └── index.ts │ │ └── utils │ │ │ ├── coerce.spec.ts │ │ │ ├── coerce.ts │ │ │ ├── createInjector.spec.ts │ │ │ ├── createInjector.ts │ │ │ ├── createTasksRunner.ts │ │ │ ├── getCommandMetadata.spec.ts │ │ │ ├── getCommandMetadata.ts │ │ │ ├── getTemplateDirectory.ts │ │ │ ├── index.ts │ │ │ ├── isValidVersion.spec.ts │ │ │ ├── isValidVersion.ts │ │ │ ├── loadPlugins.ts │ │ │ ├── logToCurl.ts │ │ │ ├── mapCommanderArgs.spec.ts │ │ │ ├── mapCommanderArgs.ts │ │ │ ├── mapCommanderOptions.ts │ │ │ ├── parseOption.spec.ts │ │ │ ├── parseOption.ts │ │ │ ├── patchCommander.ts │ │ │ ├── resolveConfiguration.ts │ │ │ └── streamToObservable.ts │ ├── test │ │ └── integrations │ │ │ └── command.integration.spec.ts │ ├── tsconfig.esm.json │ └── vitest.config.mts ├── cli-generate-http-client │ ├── .npmignore │ ├── package.json │ ├── readme.md │ ├── src │ │ ├── commands │ │ │ └── GenerateHttpClientCmd.ts │ │ └── index.ts │ ├── tsconfig.esm.json │ └── vitest.config.mts ├── cli-generate-swagger │ ├── .npmignore │ ├── package.json │ ├── readme.md │ ├── src │ │ ├── commands │ │ │ └── GenerateSwaggerCmd.ts │ │ └── index.ts │ ├── tsconfig.esm.json │ └── vitest.config.mts ├── cli-plugin-eslint │ ├── .npmignore │ ├── package.json │ ├── readme.md │ ├── scripts │ │ └── templateDir.esm.js │ ├── src │ │ ├── CliPluginEslintModule.ts │ │ ├── hooks │ │ │ └── EslintInitHook.ts │ │ ├── index.ts │ │ └── utils │ │ │ └── templateDir.ts │ ├── templates │ │ └── init │ │ │ ├── .husky │ │ │ ├── .gitignore.hbs │ │ │ ├── _ │ │ │ │ ├── .gitignore.hbs │ │ │ │ └── husky.sh.hbs │ │ │ ├── post-commit.hbs │ │ │ └── pre-commit.hbs │ │ │ ├── .lintstagedrc.json.hbs │ │ │ ├── .prettierignore.hbs │ │ │ ├── .prettierrc.hbs │ │ │ └── eslint.config.mjs.hbs │ ├── tsconfig.esm.json │ └── vitest.config.mts ├── cli-plugin-jest │ ├── .npmignore │ ├── package.json │ ├── readme.md │ ├── scripts │ │ └── templateDir.esm.js │ ├── src │ │ ├── CliPluginJestModule.ts │ │ ├── hooks │ │ │ ├── JestGenerateHook.ts │ │ │ └── JestInitHook.ts │ │ ├── index.ts │ │ └── utils │ │ │ └── templateDir.ts │ ├── templates │ │ ├── generate │ │ │ ├── decorator.class.spec.hbs │ │ │ ├── decorator.endpoint.spec.hbs │ │ │ ├── decorator.method.spec.hbs │ │ │ ├── decorator.param.spec.hbs │ │ │ ├── decorator.parameter.spec.hbs │ │ │ ├── decorator.prop.spec.hbs │ │ │ ├── decorator.property.spec.hbs │ │ │ ├── generic.integration.hbs │ │ │ ├── generic.spec.hbs │ │ │ └── server.integration.hbs │ │ └── init │ │ │ └── jest.config.mjs.hbs │ ├── test │ │ └── integrations │ │ │ └── generate │ │ │ └── generate.controller.integration.spec.ts │ ├── tsconfig.esm.json │ └── vitest.config.mts ├── cli-plugin-mongoose │ ├── .npmignore │ ├── package.json │ ├── readme.md │ ├── scripts │ │ └── templateDir.esm.js │ ├── src │ │ ├── CliPluginMongooseModule.ts │ │ ├── hooks │ │ │ ├── MongooseGenerateHook.ts │ │ │ └── MongooseInitHook.ts │ │ ├── index.ts │ │ ├── services │ │ │ └── CliMongoose.ts │ │ └── utils │ │ │ └── templateDir.ts │ ├── templates │ │ ├── config.hbs │ │ ├── index.hbs │ │ ├── mongoose.model.hbs │ │ └── mongoose.schema.hbs │ ├── test │ │ └── integrations │ │ │ └── generate │ │ │ ├── generate.model.integration.spec.ts │ │ │ └── generate.schema.integration.spec.ts │ ├── tsconfig.esm.json │ └── vitest.config.mts ├── cli-plugin-oidc-provider │ ├── .npmignore │ ├── package.json │ ├── readme.md │ ├── scripts │ │ └── templateDir.esm.js │ ├── src │ │ ├── CliPluginOidcProviderModule.ts │ │ ├── hooks │ │ │ └── OidcProviderInitHook.ts │ │ ├── index.ts │ │ └── utils │ │ │ └── templateDir.ts │ ├── templates │ │ ├── init │ │ │ ├── src │ │ │ │ ├── config │ │ │ │ │ └── oidc │ │ │ │ │ │ └── index.ts.hbs │ │ │ │ ├── controllers │ │ │ │ │ └── oidc │ │ │ │ │ │ ├── InteractionsController.spec.ts │ │ │ │ │ │ └── InteractionsController.ts │ │ │ │ ├── interactions │ │ │ │ │ ├── AbortInteraction.ts │ │ │ │ │ ├── ConsentInteraction.spec.ts │ │ │ │ │ ├── ConsentInteraction.ts │ │ │ │ │ ├── CustomInteraction.ts │ │ │ │ │ ├── LoginInteraction.spec.ts │ │ │ │ │ ├── LoginInteraction.ts │ │ │ │ │ └── __mock__ │ │ │ │ │ │ └── oidcContext.fixture.ts │ │ │ │ ├── models │ │ │ │ │ └── Account.ts │ │ │ │ └── services │ │ │ │ │ └── Accounts.ts │ │ │ └── views │ │ │ │ ├── consent.ejs │ │ │ │ ├── forms │ │ │ │ ├── consent-form.ejs │ │ │ │ ├── login-form.ejs │ │ │ │ └── select-account-form.ejs │ │ │ │ ├── login.ejs │ │ │ │ ├── partials │ │ │ │ ├── footer.ejs │ │ │ │ ├── header.ejs │ │ │ │ └── login-help.ejs │ │ │ │ ├── repost.ejs │ │ │ │ └── select_account.ejs │ │ └── tsconfig.json │ ├── test │ │ └── init │ │ │ ├── __snapshots__ │ │ │ └── init.integration.spec.ts.snap │ │ │ └── init.integration.spec.ts │ ├── tsconfig.esm.json │ └── vitest.config.mts ├── cli-plugin-passport │ ├── .npmignore │ ├── package.json │ ├── readme.md │ ├── scripts │ │ └── templateDir.esm.js │ ├── src │ │ ├── CliPluginPassportModule.ts │ │ ├── hooks │ │ │ └── PassportGenerateHook.ts │ │ ├── index.ts │ │ ├── services │ │ │ └── PassportClient.ts │ │ └── utils │ │ │ └── templateDir.ts │ ├── templates │ │ ├── generic.protocol.hbs │ │ ├── passport-http.protocol.hbs │ │ └── passport-local.protocol.hbs │ ├── tsconfig.esm.json │ └── vitest.config.mts ├── cli-plugin-prisma │ ├── .npmignore │ ├── package.json │ ├── readme.md │ ├── scripts │ │ └── templateDir.esm.js │ ├── src │ │ ├── CliPluginPrismaModule.ts │ │ ├── commands │ │ │ └── PrismaCmd.ts │ │ ├── hooks │ │ │ └── PrismaInitHook.ts │ │ ├── index.ts │ │ ├── services │ │ │ ├── CliPrisma.spec.ts │ │ │ ├── CliPrisma.ts │ │ │ └── __snapshots__ │ │ │ │ └── CliPrisma.spec.ts.snap │ │ └── utils │ │ │ └── templateDir.ts │ ├── tsconfig.esm.json │ └── vitest.config.mts ├── cli-plugin-typegraphql │ ├── .npmignore │ ├── package.json │ ├── readme.md │ ├── scripts │ │ └── templateDir.esm.js │ ├── src │ │ ├── TypeGraphqlModule.ts │ │ ├── hooks │ │ │ └── TypeGraphqlInitHook.ts │ │ ├── index.ts │ │ └── utils │ │ │ └── templateDir.ts │ ├── templates │ │ └── init │ │ │ └── src │ │ │ ├── datasources │ │ │ ├── MyDataSource.ts │ │ │ └── index.ts │ │ │ ├── resolvers │ │ │ ├── index.ts │ │ │ └── recipes │ │ │ │ ├── Recipe.ts │ │ │ │ ├── RecipeNotFoundError.ts │ │ │ │ └── RecipeResolver.ts │ │ │ └── services │ │ │ └── RecipeService.ts │ ├── test │ │ └── init │ │ │ ├── __snapshots__ │ │ │ └── init.integration.spec.ts.snap │ │ │ └── init.integration.spec.ts │ ├── tsconfig.esm.json │ └── vitest.config.mts ├── cli-plugin-typeorm │ ├── .npmignore │ ├── package.json │ ├── readme.md │ ├── scripts │ │ └── templateDir.esm.js │ ├── src │ │ ├── CliPluginTypeORMModule.ts │ │ ├── hooks │ │ │ ├── TypeORMGenerateHook.ts │ │ │ └── TypeORMInitHook.ts │ │ ├── index.ts │ │ └── utils │ │ │ └── templateDir.ts │ ├── templates │ │ └── datasource.hbs │ ├── test │ │ └── integrations │ │ │ ├── generate │ │ │ ├── __snapshots__ │ │ │ │ └── generate.controller.integration.spec.ts.snap │ │ │ ├── data │ │ │ │ ├── TestDatasource.ts.txt │ │ │ │ └── docker-compose.yml.txt │ │ │ └── generate.controller.integration.spec.ts │ │ │ └── init │ │ │ ├── __snapshots__ │ │ │ └── init.integration.spec.ts.snap │ │ │ └── init.integration.spec.ts │ ├── tsconfig.esm.json │ └── vitest.config.mts ├── cli-plugin-vitest │ ├── .npmignore │ ├── package.json │ ├── readme.md │ ├── scripts │ │ └── templateDir.esm.js │ ├── src │ │ ├── CliPluginVitestModule.ts │ │ ├── hooks │ │ │ ├── VitestGenerateHook.ts │ │ │ └── VitestInitHook.ts │ │ ├── index.ts │ │ └── utils │ │ │ └── templateDir.ts │ ├── templates │ │ ├── generate │ │ │ ├── decorator.class.spec.hbs │ │ │ ├── decorator.endpoint.spec.hbs │ │ │ ├── decorator.method.spec.hbs │ │ │ ├── decorator.param.spec.hbs │ │ │ ├── decorator.parameter.spec.hbs │ │ │ ├── decorator.prop.spec.hbs │ │ │ ├── decorator.property.spec.hbs │ │ │ ├── generic.integration.hbs │ │ │ ├── generic.spec.hbs │ │ │ └── server.integration.hbs │ │ └── init │ │ │ └── vitest.config.mts.hbs │ ├── test │ │ └── integrations │ │ │ └── generate │ │ │ └── generate.controller.integration.spec.ts │ ├── tsconfig.esm.json │ └── vitest.config.mts ├── cli-testing │ ├── .npmignore │ ├── package.json │ ├── readme.md │ ├── src │ │ ├── CliPlatformTest.ts │ │ ├── FakeCliExeca.ts │ │ ├── FakeCliFs.ts │ │ ├── FakeCliHttpClient.ts │ │ ├── index.ts │ │ └── normalizePath.ts │ ├── tsconfig.esm.json │ └── vitest.config.mts └── cli │ ├── .gitignore │ ├── .npmignore │ ├── package.json │ ├── readme.md │ ├── scripts │ └── index.esm.js │ ├── src │ ├── Cli.ts │ ├── bin │ │ └── tsed.ts │ ├── commands │ │ ├── add │ │ │ └── AddCmd.ts │ │ ├── generate │ │ │ ├── GenerateCmd.spec.ts │ │ │ ├── GenerateCmd.ts │ │ │ └── ProviderTypes.ts │ │ ├── index.ts │ │ ├── init │ │ │ ├── InitCmd.spec.ts │ │ │ ├── InitCmd.ts │ │ │ ├── config │ │ │ │ ├── FeaturesPrompt.ts │ │ │ │ └── InitFileSchema.ts │ │ │ ├── interfaces │ │ │ │ ├── InitCmdContext.ts │ │ │ │ ├── InitOptions.ts │ │ │ │ └── InitPromptAnswers.ts │ │ │ ├── mappers │ │ │ │ ├── mapToContext.spec.ts │ │ │ │ ├── mapToContext.ts │ │ │ │ └── mapUniqFeatures.ts │ │ │ ├── prompts │ │ │ │ ├── getFeaturesPrompt.spec.ts │ │ │ │ └── getFeaturesPrompt.ts │ │ │ └── utils │ │ │ │ ├── hasFeature.spec.ts │ │ │ │ ├── hasFeature.ts │ │ │ │ └── isPlatform.ts │ │ ├── run │ │ │ ├── RunCmd.spec.ts │ │ │ └── RunCmd.ts │ │ └── update │ │ │ ├── UpdateCmd.spec.ts │ │ │ └── UpdateCmd.ts │ ├── constants │ │ └── index.ts │ ├── index.ts │ ├── interfaces │ │ ├── ArchitectureConvention.ts │ │ ├── PlatformType.ts │ │ ├── ProjectConvention.ts │ │ └── index.ts │ ├── loaders │ │ └── alias.hook.ts │ ├── pipes │ │ ├── ClassNamePipe.spec.ts │ │ ├── ClassNamePipe.ts │ │ ├── OutputFilePathPipe.spec.ts │ │ ├── OutputFilePathPipe.ts │ │ ├── RoutePipe.spec.ts │ │ ├── RoutePipe.ts │ │ └── index.ts │ ├── platforms │ │ ├── InitPlatformsModule.ts │ │ └── supports │ │ │ ├── InitBasePlatform.ts │ │ │ ├── InitExpressPlatform.ts │ │ │ ├── InitFastifyPlatform.ts │ │ │ └── InitKoaPlatform.ts │ ├── runtimes │ │ ├── RuntimesModule.ts │ │ ├── index.ts │ │ └── supports │ │ │ ├── BabelRuntime.ts │ │ │ ├── BaseRuntime.ts │ │ │ ├── BunRuntime.ts │ │ │ ├── NodeRuntime.ts │ │ │ └── WebpackRuntime.ts │ ├── services │ │ ├── CliRunScript.spec.ts │ │ ├── CliRunScript.ts │ │ ├── ProvidersInfoService.spec.ts │ │ ├── ProvidersInfoService.ts │ │ ├── Renderer.spec.ts │ │ └── Renderer.ts │ └── utils │ │ ├── __snapshots__ │ │ └── fillImport.spec.ts.snap │ │ ├── fillImport.spec.ts │ │ ├── fillImports.ts │ │ ├── hbs │ │ ├── array.ts │ │ ├── collection.ts │ │ ├── comparison.ts │ │ ├── index.ts │ │ ├── object.ts │ │ ├── switch.spec.ts │ │ └── switch.ts │ │ └── renderer │ │ ├── insertAfter.spec.ts │ │ ├── insertAfter.ts │ │ ├── insertImport.spec.ts │ │ └── insertImport.ts │ ├── templates │ ├── generate │ │ ├── async.factory.hbs │ │ ├── command.hbs │ │ ├── controller.hbs │ │ ├── decorator.class.hbs │ │ ├── decorator.endpoint.hbs │ │ ├── decorator.generic.hbs │ │ ├── decorator.method.hbs │ │ ├── decorator.middleware.hbs │ │ ├── decorator.param.hbs │ │ ├── decorator.parameters.hbs │ │ ├── decorator.prop.hbs │ │ ├── decorator.property.hbs │ │ ├── exception-filter.hbs │ │ ├── factory.hbs │ │ ├── injectable.hbs │ │ ├── interceptor.hbs │ │ ├── interface.hbs │ │ ├── middleware.hbs │ │ ├── model.hbs │ │ ├── module.hbs │ │ ├── pipe.hbs │ │ ├── prisma.service.hbs │ │ ├── repository.hbs │ │ ├── response-filter.hbs │ │ ├── server │ │ │ ├── _partials │ │ │ │ ├── server-footer.hbs │ │ │ │ └── server-header.hbs │ │ │ ├── express │ │ │ │ └── server.hbs │ │ │ ├── fastify │ │ │ │ └── server.hbs │ │ │ └── koa │ │ │ │ └── server.hbs │ │ ├── service.hbs │ │ └── value.hbs │ └── init │ │ ├── .babelrc.hbs │ │ ├── .barrels.json.hbs │ │ ├── .dockerignore.hbs │ │ ├── .gitignore.hbs │ │ ├── .npmrc.hbs │ │ ├── .swcrc.hbs │ │ ├── .yarnrc.hbs │ │ ├── README.md.hbs │ │ ├── docker-compose.yml.hbs │ │ ├── docker │ │ ├── _partials │ │ │ ├── docker-body.hbs │ │ │ ├── docker-dev-tools.hbs │ │ │ └── docker-header.hbs │ │ ├── bun │ │ │ └── Dockerfile.hbs │ │ ├── npm │ │ │ └── Dockerfile.hbs │ │ ├── pnpm │ │ │ └── Dockerfile.hbs │ │ ├── yarn │ │ │ └── Dockerfile.hbs │ │ └── yarn_berry │ │ │ └── Dockerfile.hbs │ │ ├── nodemon.json.hbs │ │ ├── pm2 │ │ ├── bun │ │ │ └── processes.config.cjs.hbs │ │ ├── node-compiled │ │ │ └── processes.config.cjs.hbs │ │ └── node-loader │ │ │ └── processes.config.cjs.hbs │ │ ├── src │ │ ├── bin │ │ │ └── index.ts.hbs │ │ ├── config │ │ │ ├── envs │ │ │ │ └── index.ts.hbs │ │ │ ├── index.ts.hbs │ │ │ └── logger │ │ │ │ └── index.ts.hbs │ │ ├── controllers │ │ │ └── pages │ │ │ │ └── IndexController.ts.hbs │ │ └── index.ts.hbs │ │ ├── tsconfig.base.json.hbs │ │ ├── tsconfig.json.hbs │ │ ├── tsconfig.node.json.hbs │ │ ├── tsconfig.spec.json.hbs │ │ ├── views │ │ └── swagger.ejs.hbs │ │ └── webpack.config.js.hbs │ ├── test │ └── integrations │ │ ├── generate │ │ ├── generate.async-factory.integration.spec.ts │ │ ├── generate.controller.integration.spec.ts │ │ ├── generate.decorator-class.integration.spec.ts │ │ ├── generate.decorator-endpoint.integration.spec.ts │ │ ├── generate.decorator-generic.integration.spec.ts │ │ ├── generate.decorator-method.integration.spec.ts │ │ ├── generate.decorator-middleware.integration.spec.ts │ │ ├── generate.exception-filter.integration.spec.ts │ │ └── generate.response-filter.integration.spec.ts │ │ └── init │ │ ├── __snapshots__ │ │ └── init.integration.spec.ts.snap │ │ └── init.integration.spec.ts │ ├── tsconfig.esm.json │ └── vitest.config.mts ├── readme.md ├── release.config.js ├── team.json ├── tools ├── integration │ ├── .swcrc │ ├── index.ts │ ├── package.json │ └── tsconfig.json ├── typescript │ ├── .npmignore.template │ ├── index.js │ ├── package.json │ ├── swc.node.json │ ├── tsconfig.node.json │ ├── tsconfig.template.esm.json │ ├── tsconfig.template.json │ └── tsconfig.template.spec.json └── vitest │ ├── index.js │ ├── package.json │ ├── plugins │ └── resolveWorkspaceFiles.js │ ├── presets │ ├── alias.js │ └── index.js │ └── templates │ └── vitest.config.mts ├── tsconfig.json ├── tsconfig.node.json ├── tsconfig.spec.json ├── tsdoc.config.cjs ├── vitest.workspace.mts └── yarn.lock /.gflowrc: -------------------------------------------------------------------------------- 1 | { 2 | "flow": "gflow", 3 | "remote": "origin", 4 | "develop": "master", 5 | "production": "master", 6 | "ignores": [], 7 | "syncAfterFinish": false, 8 | "postFinish": "", 9 | "skipTest": false, 10 | "charReplacement": "-", 11 | "charBranchNameSeparator": "-", 12 | "branchTypes": { 13 | "feat": "feat", 14 | "fix": "fix", 15 | "chore": "chore", 16 | "docs": "docs" 17 | }, 18 | "refs": {} 19 | } 20 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [romakita] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: tsed 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | custom: # Replace with a single custom sponsorship URL 10 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/01_bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F41B Bug report" 3 | about: Create a report to help us improve 4 | title: "[BUG] Title" 5 | labels: ":bug: bug" 6 | assignees: Romakita 7 | 8 | --- 9 | 10 | 20 | 21 | ## Information 22 | 23 | - **Version:** x.x 24 | - Packages: 25 | 26 | A few sentences describing the overall goals of the issue. 27 | 28 | ## Example 29 | 30 | ```ts 31 | 32 | ``` 33 | 34 | ## Acceptance criteria 35 | 36 | - [ ] Criteria 1 37 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/02_feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F680 Feature request" 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: ":sparkles: enhancement" 6 | assignees: Romakita 7 | 8 | --- 9 | 10 | 20 | 21 | 22 | ## Information 23 | 24 | **Is your feature request related to a problem? Please describe.** 25 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 26 | 27 | **Describe the solution you'd like** 28 | A clear and concise description of what you want to happen. 29 | 30 | ```ts 31 | 32 | ``` 33 | 34 | **Describe alternatives you've considered** 35 | A clear and concise description of any alternative solutions or features you've considered. 36 | 37 | ## Acceptance criteria 38 | 39 | - [ ] Criteria 1 40 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/04_say-thank-you.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "❤️ Say thank you" 3 | about: Tell us how you use Ts.ED & support our efforts in maintaining it 4 | title: '' 5 | labels: '' 6 | assignees: Romakita 7 | 8 | --- 9 | 10 | # ❤️ I'm using Ts.ED 11 | 12 | If you (or your company) are using the framework Ts.ED - please let us know. We'd love to hear from you! 13 | 14 | Ts.ED is a community driven project, which means it's not maintained by a company. If you would like to help us - any of the following is greatly appreciated. 15 | 16 | We would love to add a company section with your logos and an explanation of your usecases and give feedbacks. 17 | 18 | - [ ] Give the repository a star ⭐️ 19 | - [ ] Help out with issues 20 | - [ ] Review pull requests 21 | - [ ] Blog about this framework 22 | - [ ] Make tutorials 23 | - [ ] Give talks 24 | - [ ] Support us 25 | 26 | Thank you! 💐 27 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: 💬 Discussions 4 | url: https://github.com/tsedio/tsed/discussions 5 | about: Open a discussion that can be followed by the whole community on Github! 6 | - name: 💬 Community channel (Slack) 7 | url: https://slack.tsed.dev 8 | about: Join our slack workspace to discuss directly wiht the team! 9 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "npm" 4 | directory: "/" 5 | schedule: 6 | interval: "monthly" 7 | assignees: 8 | - "Romakita" 9 | reviewers: 10 | - "Romakita" 11 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 60 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned 8 | - security 9 | # Label to use when marking an issue as stale 10 | staleLabel: wontfix 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue has been automatically marked as stale because it has not had 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: false 18 | -------------------------------------------------------------------------------- /.github/workflows/close-issue-message.yml: -------------------------------------------------------------------------------- 1 | name: Closed Issue Message 2 | on: 3 | issues: 4 | types: [closed] 5 | jobs: 6 | auto_comment: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: aws-actions/closed-issue-message@v1 10 | with: 11 | # These inputs are both required 12 | repo-token: "${{ secrets.GITHUB_TOKEN }}" 13 | message: | 14 | ## 🎉 Are you happy? 15 | 16 | If you appreciated the support, know that it is **free** and is carried out on **personal time** ;) 17 | 18 | A support, even a little bit **makes a difference** for me and **continues to bring you answers**! 19 | 20 | [![github](https://img.shields.io/static/v1?label=Github%20sponsor&message=%E2%9D%A4&logo=GitHub&color=%23fe8e86)](https://github.com/sponsors/romakita) [![opencollective](https://img.shields.io/static/v1?label=OpenCollective%20sponsor&message=%E2%9D%A4&logo=OpenCollective&color=%23fe8e86)](https://opencollective.com/tsed) 21 | -------------------------------------------------------------------------------- /.github/workflows/rebase.yml: -------------------------------------------------------------------------------- 1 | on: 2 | issue_comment: 3 | types: [created] 4 | name: Automatic Rebase 5 | jobs: 6 | rebase: 7 | name: Rebase 8 | if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/rebase') 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout the latest code 12 | uses: actions/checkout@v2 13 | with: 14 | fetch-depth: 0 15 | - name: Automatic Rebase 16 | uses: cirrus-actions/rebase@1.3.1 17 | env: 18 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.github/workflows/website.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Website 5 | 6 | on: 7 | workflow_dispatch: 8 | 9 | permissions: 10 | contents: read 11 | pages: write 12 | id-token: write 13 | 14 | jobs: 15 | publish-docs: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v4 19 | - name: Setup Node.js 20 | uses: actions/setup-node@v4 21 | with: 22 | node-version: 20.x 23 | - name: Install dependencies 🚀 24 | run: yarn install --immutable --network-timeout 500000 25 | - name: Build pages 26 | env: 27 | CI: true 28 | run: yarn docs:build 📝 29 | - name: Publish pages 30 | env: 31 | CI: true 32 | GH_TOKEN: ${{ secrets.GH_TOKEN }} 33 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 34 | run: yarn docs:publish 35 | -------------------------------------------------------------------------------- /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn commitlint --edit $1 5 | -------------------------------------------------------------------------------- /.husky/post-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | git update-index --again 5 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx lint-staged $1 5 | -------------------------------------------------------------------------------- /.lintstagedrc: -------------------------------------------------------------------------------- 1 | { 2 | "**/*.{ts,js}": ["eslint --fix"], 3 | "**/*.{ts,js,json,md,yml,yaml}": ["prettier --write"] 4 | } 5 | 6 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | test 2 | typings 3 | bundled 4 | build 5 | temp 6 | coverage 7 | docs 8 | wiki 9 | karma.conf.js 10 | tsconfig.json 11 | tsconfig.compile.json 12 | tsconfig.test.json 13 | typings.json 14 | CONTRIBUTING.md 15 | ISSUE_TEMPLATE.md 16 | PULL_REQUEST_TEMPLATE.md 17 | tslint.json 18 | .travis.yml 19 | .gitignore 20 | .vscode 21 | .publishrc 22 | type_definitions 23 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 20.11.0 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | **/lib 3 | **/dist 4 | **/coverage 5 | **/.nyc_output 6 | **/node_modules 7 | *-lock.json 8 | *.lock 9 | benchmarks.* 10 | **/generated 11 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 140, 3 | "bracketSpacing": false, 4 | "trailingComma": "none", 5 | "arrowParens": "always" 6 | } 7 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | compressionLevel: mixed 2 | 3 | enableImmutableInstalls: false 4 | 5 | nodeLinker: node-modules 6 | 7 | yarnPath: .yarn/releases/yarn-4.7.0.cjs 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020 Romain Lenzotti 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | export default {extends: ["@commitlint/config-conventional"]}; 2 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | api 2 | .vuepress/public/api.json 3 | 4 | 5 | .pnp.* 6 | .yarn/* 7 | !.yarn/patches 8 | !.yarn/plugins 9 | !.yarn/releases 10 | !.yarn/cache 11 | !.yarn/sdks 12 | !.yarn/versions 13 | -------------------------------------------------------------------------------- /docs/.vuepress/enhanceApp.js: -------------------------------------------------------------------------------- 1 | import "./window-boot"; 2 | 3 | import VueAnalytics from "vue-analytics"; 4 | import VueTsED from "vuepress-theme-tsed/src/install"; 5 | 6 | import SupportUsBlock from "./components/SupportUsBlock"; 7 | 8 | export default ({ 9 | Vue, // the version of Vue being used in the VuePress app 10 | options, // the options for the root Vue instance 11 | router, // the router instance for the app 12 | siteData // site metadata 13 | }) => { 14 | try { 15 | Vue.use(VueTsED); 16 | Vue.component("SupportUsBlock", SupportUsBlock); 17 | Vue.use(VueAnalytics, { 18 | id: siteData.themeConfig.plugins[0][1].ga, 19 | router 20 | }); 21 | } catch (er) { 22 | console.warn("====", er); 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /docs/.vuepress/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "commonjs" 3 | } 4 | -------------------------------------------------------------------------------- /docs/.vuepress/public/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tsedio/tsed-cli/0be09b410eba756f9d9576b4e220af91cf581b80/docs/.vuepress/public/.nojekyll -------------------------------------------------------------------------------- /docs/.vuepress/public/CNAME: -------------------------------------------------------------------------------- 1 | logger.tsed.io 2 | -------------------------------------------------------------------------------- /docs/.vuepress/public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tsedio/tsed-cli/0be09b410eba756f9d9576b4e220af91cf581b80/docs/.vuepress/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /docs/.vuepress/public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tsedio/tsed-cli/0be09b410eba756f9d9576b4e220af91cf581b80/docs/.vuepress/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /docs/.vuepress/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tsedio/tsed-cli/0be09b410eba756f9d9576b4e220af91cf581b80/docs/.vuepress/public/apple-touch-icon.png -------------------------------------------------------------------------------- /docs/.vuepress/public/aws.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tsedio/tsed-cli/0be09b410eba756f9d9576b4e220af91cf581b80/docs/.vuepress/public/aws.png -------------------------------------------------------------------------------- /docs/.vuepress/public/azure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tsedio/tsed-cli/0be09b410eba756f9d9576b4e220af91cf581b80/docs/.vuepress/public/azure.png -------------------------------------------------------------------------------- /docs/.vuepress/public/express.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tsedio/tsed-cli/0be09b410eba756f9d9576b4e220af91cf581b80/docs/.vuepress/public/express.png -------------------------------------------------------------------------------- /docs/.vuepress/public/expressjs.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/.vuepress/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tsedio/tsed-cli/0be09b410eba756f9d9576b4e220af91cf581b80/docs/.vuepress/public/favicon-16x16.png -------------------------------------------------------------------------------- /docs/.vuepress/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tsedio/tsed-cli/0be09b410eba756f9d9576b4e220af91cf581b80/docs/.vuepress/public/favicon-32x32.png -------------------------------------------------------------------------------- /docs/.vuepress/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tsedio/tsed-cli/0be09b410eba756f9d9576b4e220af91cf581b80/docs/.vuepress/public/favicon.ico -------------------------------------------------------------------------------- /docs/.vuepress/public/mongoose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tsedio/tsed-cli/0be09b410eba756f9d9576b4e220af91cf581b80/docs/.vuepress/public/mongoose.png -------------------------------------------------------------------------------- /docs/.vuepress/public/passportjs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tsedio/tsed-cli/0be09b410eba756f9d9576b4e220af91cf581b80/docs/.vuepress/public/passportjs.png -------------------------------------------------------------------------------- /docs/.vuepress/public/react.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tsedio/tsed-cli/0be09b410eba756f9d9576b4e220af91cf581b80/docs/.vuepress/public/react.png -------------------------------------------------------------------------------- /docs/.vuepress/public/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Ts.ED CLI", 3 | "short_name": "Ts.ED CLI", 4 | "description": "A Node.js CLI to bootstrap and manage a Ts.ED project.", 5 | "icons": [ 6 | { 7 | "src": "/android-chrome-192x192.png", 8 | "sizes": "192x192", 9 | "type": "image/png" 10 | }, 11 | { 12 | "src": "/android-chrome-512x512.png", 13 | "sizes": "512x512", 14 | "type": "image/png" 15 | } 16 | ], 17 | "theme_color": "#0074D9", 18 | "background_color": "white", 19 | "display": "standalone" 20 | } 21 | -------------------------------------------------------------------------------- /docs/.vuepress/public/socketio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tsedio/tsed-cli/0be09b410eba756f9d9576b4e220af91cf581b80/docs/.vuepress/public/socketio.png -------------------------------------------------------------------------------- /docs/.vuepress/public/socketio.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/.vuepress/public/tsed-og.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tsedio/tsed-cli/0be09b410eba756f9d9576b4e220af91cf581b80/docs/.vuepress/public/tsed-og.png -------------------------------------------------------------------------------- /docs/.vuepress/public/tsed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tsedio/tsed-cli/0be09b410eba756f9d9576b4e220af91cf581b80/docs/.vuepress/public/tsed.png -------------------------------------------------------------------------------- /docs/.vuepress/public/typegraphql.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tsedio/tsed-cli/0be09b410eba756f9d9576b4e220af91cf581b80/docs/.vuepress/public/typegraphql.png -------------------------------------------------------------------------------- /docs/.vuepress/public/typeorm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tsedio/tsed-cli/0be09b410eba756f9d9576b4e220af91cf581b80/docs/.vuepress/public/typeorm.png -------------------------------------------------------------------------------- /docs/.vuepress/public/typescript.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tsedio/tsed-cli/0be09b410eba756f9d9576b4e220af91cf581b80/docs/.vuepress/public/typescript.png -------------------------------------------------------------------------------- /docs/.vuepress/public/vitest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tsedio/tsed-cli/0be09b410eba756f9d9576b4e220af91cf581b80/docs/.vuepress/public/vitest.png -------------------------------------------------------------------------------- /docs/.vuepress/public/vuejs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tsedio/tsed-cli/0be09b410eba756f9d9576b4e220af91cf581b80/docs/.vuepress/public/vuejs.png -------------------------------------------------------------------------------- /docs/.vuepress/public/webpack.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/.vuepress/scripts/build.sh: -------------------------------------------------------------------------------- 1 | export NODE_ENV=production 2 | export NODE_OPTIONS=--openssl-legacy-provider 3 | cp .vuepress/scripts/updateBuildScript.js node_modules/@vuepress/core/lib/node/build/index.js 4 | cp .vuepress/scripts/addWorkerScript.js node_modules/@vuepress/core/lib/node/build/worker.js 5 | vuepress build 6 | -------------------------------------------------------------------------------- /docs/.vuepress/window-boot.js: -------------------------------------------------------------------------------- 1 | if (typeof window !== "undefined") window.global = window; 2 | -------------------------------------------------------------------------------- /docs/api.md: -------------------------------------------------------------------------------- 1 | # Api Reference 2 | 3 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "npmClient": "yarn", 3 | "packages": [ 4 | "packages/*" 5 | ], 6 | "version": "6.4.3" 7 | } -------------------------------------------------------------------------------- /packages/barrels/.gitignore: -------------------------------------------------------------------------------- 1 | **/__mock__/**/index.ts 2 | -------------------------------------------------------------------------------- /packages/barrels/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | coverage 4 | tsconfig.json 5 | tsconfig.*.json 6 | __mock__ 7 | *.spec.js 8 | *.tsbuildinfo 9 | -------------------------------------------------------------------------------- /packages/barrels/bin/barrels.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import {generateBarrels} from "./generate-barrel.js"; 3 | import {getConfig} from "./get-config.js"; 4 | 5 | async function build() { 6 | const { 7 | directory = ["./src"], 8 | exclude = ["**/__mock__", "**/__mocks__", "**/*.spec.ts", "**/*.benchmark.ts"], 9 | noSemicolon = false, 10 | singleQuotes = false 11 | } = await getConfig(); 12 | 13 | await generateBarrels({exclude, directory, cwd: process.cwd(), noSemicolon, singleQuotes}); 14 | } 15 | 16 | await build(); 17 | -------------------------------------------------------------------------------- /packages/barrels/bin/get-config.js: -------------------------------------------------------------------------------- 1 | import {existsSync} from "node:fs"; 2 | import {readFile} from "node:fs/promises"; 3 | import {join} from "node:path"; 4 | 5 | function resolveConfig() { 6 | return [join(process.cwd(), ".barrelsby.json"), join(process.cwd(), ".barrels.json")].find((path) => { 7 | return existsSync(path); 8 | }); 9 | } 10 | 11 | async function readJSON(path) { 12 | const content = await readFile(path, "utf-8"); 13 | 14 | return JSON.parse(content); 15 | } 16 | 17 | export function getConfig() { 18 | const configPath = resolveConfig(); 19 | 20 | if (!configPath) { 21 | return {}; 22 | } 23 | 24 | return readJSON(configPath); 25 | } 26 | -------------------------------------------------------------------------------- /packages/barrels/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tsed/barrels", 3 | "description": "A simple tool to generate barrels for your TypeScript project", 4 | "version": "6.4.3", 5 | "type": "module", 6 | "bin": "bin/barrels.js", 7 | "keywords": [ 8 | "Ts.ED", 9 | "barrels" 10 | ], 11 | "engines": { 12 | "node": ">=20" 13 | }, 14 | "dependencies": { 15 | "globby": "14.0.2" 16 | }, 17 | "scripts": { 18 | "test": "node --test test/barrels.integration.spec.js" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/barrels/test/__mock__/scenario-1/file1.spec.ts: -------------------------------------------------------------------------------- 1 | import {file1} from "./file1"; 2 | 3 | describe("barrels", () => { 4 | it("should", () => { 5 | expect(file1).toEqual("file1"); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /packages/barrels/test/__mock__/scenario-1/file1.ts: -------------------------------------------------------------------------------- 1 | export const file1 = "file1"; 2 | -------------------------------------------------------------------------------- /packages/barrels/test/__mock__/scenario-1/file2.ts: -------------------------------------------------------------------------------- 1 | export const file2 = "file2"; 2 | -------------------------------------------------------------------------------- /packages/barrels/test/__mock__/scenario-1/sub-directory/file2.ts: -------------------------------------------------------------------------------- 1 | export const file3 = "file3"; 2 | -------------------------------------------------------------------------------- /packages/barrels/test/__mock__/scenario-2/sub-directory-1/file2.ts: -------------------------------------------------------------------------------- 1 | export const file3 = "file3"; 2 | -------------------------------------------------------------------------------- /packages/barrels/test/__mock__/scenario-2/sub-directory-2/file2.ts: -------------------------------------------------------------------------------- 1 | export const file3 = "file3"; 2 | -------------------------------------------------------------------------------- /packages/barrels/test/__mock__/scenario-3/sub-directory-1/file2.ts: -------------------------------------------------------------------------------- 1 | export const file2 = "file2"; 2 | -------------------------------------------------------------------------------- /packages/barrels/test/__mock__/scenario-3/sub-directory-1/sub-path/file3.ts: -------------------------------------------------------------------------------- 1 | export const file3 = "file3"; 2 | -------------------------------------------------------------------------------- /packages/barrels/test/__mock__/scenario-3/sub-directory-2/file2.ts: -------------------------------------------------------------------------------- 1 | export const file3 = "file3"; 2 | -------------------------------------------------------------------------------- /packages/barrels/test/__mock__/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "noEmit": true 4 | }, 5 | "include": ["**/*"] 6 | } 7 | -------------------------------------------------------------------------------- /packages/cli-core/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | coverage 4 | tsconfig.json 5 | tsconfig.*.json 6 | __mock__ 7 | *.spec.js 8 | *.tsbuildinfo 9 | src 10 | vitest.config.mts -------------------------------------------------------------------------------- /packages/cli-core/src/decorators/command.ts: -------------------------------------------------------------------------------- 1 | import {StoreSet, useDecorators} from "@tsed/core"; 2 | import {Injectable} from "@tsed/di"; 3 | 4 | import {CommandStoreKeys} from "../domains/CommandStoreKeys.js"; 5 | import type {CommandParameters} from "../interfaces/CommandParameters.js"; 6 | 7 | export function Command(options: CommandParameters): ClassDecorator { 8 | return useDecorators(Injectable({type: "command"}), StoreSet(CommandStoreKeys.COMMAND, options)) as any; 9 | } 10 | -------------------------------------------------------------------------------- /packages/cli-core/src/decorators/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./command.js"; 2 | export * from "./onAdd.js"; 3 | export * from "./onExec.js"; 4 | export * from "./onPostInstall.js"; 5 | export * from "./onPrompt.js"; 6 | -------------------------------------------------------------------------------- /packages/cli-core/src/decorators/on.ts: -------------------------------------------------------------------------------- 1 | import {StoreMerge} from "@tsed/core"; 2 | 3 | export function On(hookName: string, name: string): MethodDecorator { 4 | return (target, propertyKey) => { 5 | StoreMerge(hookName, { 6 | [name]: [propertyKey] 7 | })(target); 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /packages/cli-core/src/decorators/onAdd.spec.ts: -------------------------------------------------------------------------------- 1 | import {Store} from "@tsed/core"; 2 | 3 | import {CommandStoreKeys} from "../domains/CommandStoreKeys.js"; 4 | import {OnAdd} from "./onAdd.js"; 5 | 6 | class Test { 7 | @OnAdd("@tsed/cli-plugin") 8 | test() {} 9 | } 10 | 11 | describe("@OnAdd", () => { 12 | it("should store metadata", () => { 13 | const result = Store.from(Test).get(CommandStoreKeys.ADD); 14 | expect(result).toEqual({ 15 | "@tsed/cli-plugin": ["test"] 16 | }); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /packages/cli-core/src/decorators/onAdd.ts: -------------------------------------------------------------------------------- 1 | import {CommandStoreKeys} from "../domains/CommandStoreKeys.js"; 2 | import {On} from "./on.js"; 3 | 4 | export function OnAdd(cliPlugin: string): MethodDecorator { 5 | return On(CommandStoreKeys.ADD, cliPlugin); 6 | } 7 | -------------------------------------------------------------------------------- /packages/cli-core/src/decorators/onExec.spec.ts: -------------------------------------------------------------------------------- 1 | import {Store} from "@tsed/core"; 2 | 3 | import {CommandStoreKeys} from "../domains/CommandStoreKeys.js"; 4 | import {OnExec} from "./onExec.js"; 5 | 6 | class Test { 7 | @OnExec("cmd") 8 | test() {} 9 | } 10 | 11 | describe("@OnExec", () => { 12 | it("should store metadata", () => { 13 | const result = Store.from(Test).get(CommandStoreKeys.EXEC_HOOKS); 14 | 15 | expect(result).toEqual({ 16 | cmd: ["test"] 17 | }); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /packages/cli-core/src/decorators/onExec.ts: -------------------------------------------------------------------------------- 1 | import {CommandStoreKeys} from "../domains/CommandStoreKeys.js"; 2 | import {On} from "./on.js"; 3 | 4 | export function OnExec(cmdName: string): MethodDecorator { 5 | return On(CommandStoreKeys.EXEC_HOOKS, cmdName); 6 | } 7 | -------------------------------------------------------------------------------- /packages/cli-core/src/decorators/onPostInstall.spec.ts: -------------------------------------------------------------------------------- 1 | import {Store} from "@tsed/core"; 2 | 3 | import {CommandStoreKeys} from "../domains/CommandStoreKeys.js"; 4 | import {OnPostInstall} from "./onPostInstall.js"; 5 | 6 | class Test { 7 | @OnPostInstall("cmd") 8 | test() {} 9 | } 10 | 11 | describe("@OnPostIntall", () => { 12 | it("should store metadata", () => { 13 | const result = Store.from(Test).get(CommandStoreKeys.POST_INSTALL_HOOKS); 14 | 15 | expect(result).toEqual({ 16 | cmd: ["test"] 17 | }); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /packages/cli-core/src/decorators/onPostInstall.ts: -------------------------------------------------------------------------------- 1 | import {CommandStoreKeys} from "../domains/CommandStoreKeys.js"; 2 | import {On} from "./on.js"; 3 | 4 | export function OnPostInstall(cmdName: string): MethodDecorator { 5 | return On(CommandStoreKeys.POST_INSTALL_HOOKS, cmdName); 6 | } 7 | -------------------------------------------------------------------------------- /packages/cli-core/src/decorators/onPrompt.spec.ts: -------------------------------------------------------------------------------- 1 | import {Store} from "@tsed/core"; 2 | 3 | import {CommandStoreKeys} from "../domains/CommandStoreKeys.js"; 4 | import {OnPrompt} from "./onPrompt.js"; 5 | 6 | class Test { 7 | @OnPrompt("cmd") 8 | test() {} 9 | } 10 | 11 | describe("@OnPrompt", () => { 12 | it("should store metadata", () => { 13 | const result = Store.from(Test).get(CommandStoreKeys.PROMPT_HOOKS); 14 | 15 | expect(result).toEqual({ 16 | cmd: ["test"] 17 | }); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /packages/cli-core/src/decorators/onPrompt.ts: -------------------------------------------------------------------------------- 1 | import {CommandStoreKeys} from "../domains/CommandStoreKeys.js"; 2 | import {On} from "./on.js"; 3 | 4 | export function OnPrompt(cmdName: string): MethodDecorator { 5 | return On(CommandStoreKeys.PROMPT_HOOKS, cmdName); 6 | } 7 | -------------------------------------------------------------------------------- /packages/cli-core/src/domains/CliError.ts: -------------------------------------------------------------------------------- 1 | import type {CliCore} from "../CliCore.js"; 2 | 3 | export class CliError extends Error { 4 | name = "CLI_ERROR"; 5 | 6 | readonly cli: CliCore; 7 | readonly origin: Error; 8 | 9 | constructor({cli, origin}: {cli: CliCore; origin: Error}) { 10 | super(origin.message); 11 | this.cli = cli; 12 | this.origin = origin; 13 | this.stack = origin.stack; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/cli-core/src/domains/CommandStoreKeys.ts: -------------------------------------------------------------------------------- 1 | export enum CommandStoreKeys { 2 | COMMAND = "command", 3 | ADD = "$onAdd", 4 | EXEC_HOOKS = "$onExec", 5 | POST_INSTALL_HOOKS = "$onPostInstall", 6 | PROMPT_HOOKS = "$onPrompt" 7 | } 8 | -------------------------------------------------------------------------------- /packages/cli-core/src/index.ts: -------------------------------------------------------------------------------- 1 | import "./utils/patchCommander.js"; 2 | 3 | import Inquirer from "inquirer"; 4 | 5 | export * from "./CliCore.js"; 6 | export * from "./decorators/index.js"; 7 | export * from "./interfaces/index.js"; 8 | export * from "./packageManagers/index.js"; 9 | export * from "./services/index.js"; 10 | export * from "./utils/index.js"; 11 | export * from "@tsed/core"; 12 | export * from "@tsed/di"; 13 | export * from "@tsed/logger"; 14 | export * from "@tsed/normalize-path"; 15 | export {Inquirer}; 16 | -------------------------------------------------------------------------------- /packages/cli-core/src/interfaces/CliDefaultOptions.ts: -------------------------------------------------------------------------------- 1 | export interface CliDefaultOptions { 2 | verbose: boolean; 3 | rawArgs: string[]; 4 | } 5 | -------------------------------------------------------------------------------- /packages/cli-core/src/interfaces/CommandMetadata.ts: -------------------------------------------------------------------------------- 1 | import type {CommandArg, CommandOptions, CommandParameters} from "./CommandParameters.js"; 2 | 3 | export interface CommandMetadata extends CommandParameters { 4 | /** 5 | * CommandProvider arguments 6 | */ 7 | args: { 8 | [key: string]: CommandArg; 9 | }; 10 | /** 11 | * CommandProvider options 12 | */ 13 | options: { 14 | [key: string]: CommandOptions; 15 | }; 16 | 17 | allowUnknownOption: boolean; 18 | 19 | enableFeatures: string[]; 20 | 21 | disableReadUpPkg: boolean; 22 | 23 | bindLogger: boolean; 24 | } 25 | -------------------------------------------------------------------------------- /packages/cli-core/src/interfaces/PackageJson.ts: -------------------------------------------------------------------------------- 1 | export interface PackageJson { 2 | name: string; 3 | version: string; 4 | description: string; 5 | type: "module"; 6 | scripts: {[key: string]: string}; 7 | dependencies: {[key: string]: string}; 8 | devDependencies: {[key: string]: string}; 9 | 10 | [key: string]: any; 11 | } 12 | 13 | export interface PackageInfo { 14 | _id: string; 15 | _rev: string; 16 | name: string; 17 | type: "module"; 18 | "dist-tags": { 19 | [key: string]: string; 20 | }; 21 | versions: { 22 | [key: string]: PackageJson; 23 | }; 24 | time: { 25 | [key: string]: string; 26 | }; 27 | maintainers: {email: string; name: string}[]; 28 | description: string; 29 | homepage: string; 30 | keywords: string[]; 31 | repository: { 32 | type: string; 33 | url: string; 34 | }; 35 | author: { 36 | name: string; 37 | }; 38 | bugs: { 39 | url: string; 40 | }; 41 | license: string; 42 | readme: string; 43 | } 44 | -------------------------------------------------------------------------------- /packages/cli-core/src/interfaces/ProjectPreferences.ts: -------------------------------------------------------------------------------- 1 | export enum PackageManager { 2 | YARN = "yarn", 3 | YARN_BERRY = "yarn_berry", 4 | NPM = "npm", 5 | PNPM = "pnpm" 6 | } 7 | 8 | declare global { 9 | namespace TsED { 10 | interface ProjectPreferences { 11 | packageManager: PackageManager; 12 | } 13 | } 14 | } 15 | 16 | export interface ProjectPreferences extends TsED.ProjectPreferences, Record {} 17 | -------------------------------------------------------------------------------- /packages/cli-core/src/interfaces/Tasks.ts: -------------------------------------------------------------------------------- 1 | import {type ListrBaseClassOptions, type ListrContext, type ListrTask} from "listr2"; 2 | 3 | export interface TaskOptions extends ListrBaseClassOptions { 4 | concurrent?: boolean | number; 5 | verbose?: boolean; 6 | bindLogger?: boolean; 7 | } 8 | 9 | export type Task = ListrTask; 10 | export type Tasks = Task[]; 11 | -------------------------------------------------------------------------------- /packages/cli-core/src/packageManagers/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./PackageManagersModule.js"; 2 | export * from "./supports/BaseManager.js"; 3 | export * from "./supports/NpmManager.js"; 4 | export * from "./supports/PNpmManager.js"; 5 | export * from "./supports/YarnManager.js"; 6 | -------------------------------------------------------------------------------- /packages/cli-core/src/packageManagers/supports/BunManager.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from "@tsed/di"; 2 | import type {Options} from "execa"; 3 | import {Observable} from "rxjs"; 4 | 5 | import {BaseManager, type ManagerCmdOpts} from "./BaseManager.js"; 6 | 7 | @Injectable({ 8 | type: "package:manager" 9 | }) 10 | export class BunManager extends BaseManager { 11 | readonly name = "bun"; 12 | readonly cmd = "bun"; 13 | 14 | add(deps: string[], options: ManagerCmdOpts) { 15 | return this.run("add", [...deps], options); 16 | } 17 | 18 | addDev(deps: string[], options: ManagerCmdOpts) { 19 | return this.run("add", ["-d", ...deps], options); 20 | } 21 | 22 | install(options: {verbose?: boolean} & Options): Observable { 23 | return this.run("install", [options.verbose && "--verbose"], options); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/cli-core/src/packageManagers/supports/NpmManager.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from "@tsed/di"; 2 | import {Observable} from "rxjs"; 3 | 4 | import {BaseManager, type ManagerCmdOpts} from "./BaseManager.js"; 5 | 6 | @Injectable({ 7 | type: "package:manager" 8 | }) 9 | export class NpmManager extends BaseManager { 10 | readonly name: string = "npm"; 11 | readonly cmd: string = "npm"; 12 | 13 | add(deps: string[], options: ManagerCmdOpts): Observable { 14 | return this.run("install", ["--no-production", "--legacy-peer-deps", "--save", ...deps], options); 15 | } 16 | 17 | addDev(deps: string[], options: ManagerCmdOpts): Observable { 18 | return this.run("install", ["--no-production", "--legacy-peer-deps", "--save-dev", ...deps], options); 19 | } 20 | 21 | install(options: ManagerCmdOpts): Observable { 22 | return this.run("install", ["--no-production", "--legacy-peer-deps"], options); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/cli-core/src/packageManagers/supports/PNpmManager.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from "@tsed/di"; 2 | import {Observable} from "rxjs"; 3 | 4 | import {BaseManager, type ManagerCmdOpts} from "./BaseManager.js"; 5 | 6 | @Injectable({ 7 | type: "package:manager" 8 | }) 9 | export class PNpmManager extends BaseManager { 10 | readonly name = "pnpm"; 11 | readonly cmd = "pnpm"; 12 | 13 | add(deps: string[], options: ManagerCmdOpts): Observable { 14 | return this.run("add", ["--save-prod", ...deps], options); 15 | } 16 | 17 | addDev(deps: string[], options: ManagerCmdOpts): Observable { 18 | return this.run("add", ["--save-dev", ...deps], options); 19 | } 20 | 21 | install(options: ManagerCmdOpts): Observable { 22 | return this.run("install", ["--dev"].filter(Boolean), options); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/cli-core/src/packageManagers/supports/YarnManager.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from "@tsed/di"; 2 | import type {Options} from "execa"; 3 | import {Observable} from "rxjs"; 4 | 5 | import {BaseManager, type ManagerCmdOpts} from "./BaseManager.js"; 6 | 7 | @Injectable({ 8 | type: "package:manager" 9 | }) 10 | export class YarnManager extends BaseManager { 11 | readonly name = "yarn"; 12 | readonly cmd = "yarn"; 13 | 14 | add(deps: string[], options: ManagerCmdOpts) { 15 | return this.run("add", ["--ignore-engines", ...deps], options); 16 | } 17 | 18 | addDev(deps: string[], options: ManagerCmdOpts) { 19 | return this.run("add", ["-D", "--ignore-engines", ...deps], options); 20 | } 21 | 22 | install(options: {verbose?: boolean} & Options): Observable { 23 | return this.run("install", [options.verbose && "--verbose"], options); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/cli-core/src/services/CliConfiguration.ts: -------------------------------------------------------------------------------- 1 | import {DIConfiguration, Injectable} from "@tsed/di"; 2 | 3 | @Injectable() 4 | export class CliConfiguration extends DIConfiguration { 5 | constructor() { 6 | super({ 7 | project: { 8 | root: process.cwd(), 9 | srcDir: "src" 10 | } 11 | }); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/cli-core/src/services/CliHooks.ts: -------------------------------------------------------------------------------- 1 | import {Injectable, injector} from "@tsed/di"; 2 | 3 | @Injectable() 4 | export class CliHooks { 5 | async emit(hookName: string, cmd: string, ...args: any[]) { 6 | const inj = injector(); 7 | const providers = inj.getProviders(); 8 | let results: any = []; 9 | 10 | for (const provider of providers) { 11 | if (provider.useClass) { 12 | const instance: any = inj.get(provider.token)!; 13 | 14 | if (provider.store.has(hookName)) { 15 | const props = provider.store.get(hookName)[cmd]; 16 | if (props) { 17 | for (const propertyKey of props) { 18 | results = results.concat(await instance[propertyKey](...args)); 19 | } 20 | } 21 | } 22 | } 23 | } 24 | 25 | return results.filter((o: any) => o !== undefined); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/cli-core/src/services/CliPackageJson.ts: -------------------------------------------------------------------------------- 1 | import {Configuration, Inject, inject, registerProvider} from "@tsed/di"; 2 | 3 | import {type PackageJson} from "../interfaces/PackageJson.js"; 4 | 5 | export type CliPackageJson = PackageJson; 6 | 7 | export function CliPackageJson(): any { 8 | return Inject(CliPackageJson); 9 | } 10 | 11 | export function cliPackageJson() { 12 | return inject(CliPackageJson); 13 | } 14 | 15 | registerProvider({ 16 | provide: CliPackageJson, 17 | deps: [Configuration], 18 | useFactory(configuration: Configuration) { 19 | return configuration.get("pkg", {}); 20 | } 21 | }); 22 | -------------------------------------------------------------------------------- /packages/cli-core/src/services/CliYaml.ts: -------------------------------------------------------------------------------- 1 | import {inject, Injectable} from "@tsed/di"; 2 | import JsYaml from "js-yaml"; 3 | 4 | import {CliFs} from "./CliFs.js"; 5 | 6 | @Injectable() 7 | export class CliYaml { 8 | protected fs = inject(CliFs); 9 | 10 | async read(path: string) { 11 | const content = await this.fs.readFile(path, {encoding: "utf8"}); 12 | 13 | return JsYaml.load(content); 14 | } 15 | 16 | write(path: string, obj: any) { 17 | const content = JsYaml.dump(obj); 18 | 19 | return this.fs.writeFile(path, content, {encoding: "utf8"}); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/cli-core/src/services/__mock__/package.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /packages/cli-core/src/services/__mock__/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "projectName": "test", 3 | "platform": "express", 4 | "architecture": "default", 5 | "convention": "default", 6 | "features": [] 7 | } 8 | -------------------------------------------------------------------------------- /packages/cli-core/src/services/__mock__/settings.yml: -------------------------------------------------------------------------------- 1 | projectName: project-example 2 | platform: express 3 | architecture: default 4 | convention: default 5 | features: 6 | - babel 7 | -------------------------------------------------------------------------------- /packages/cli-core/src/services/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./CliConfiguration.js"; 2 | export * from "./CliDockerComposeYaml.js"; 3 | export * from "./CliExeca.js"; 4 | export * from "./CliFs.js"; 5 | export * from "./CliHttpClient.js"; 6 | export * from "./CliLoadFile.js"; 7 | export * from "./CliPackageJson.js"; 8 | export * from "./CliPlugins.js"; 9 | export * from "./CliProxyAgent.js"; 10 | export * from "./CliService.js"; 11 | export * from "./CliYaml.js"; 12 | export * from "./NpmRegistryClient.js"; 13 | export * from "./ProjectPackageJson.js"; 14 | -------------------------------------------------------------------------------- /packages/cli-core/src/utils/coerce.spec.ts: -------------------------------------------------------------------------------- 1 | import {coerce} from "./coerce.js"; 2 | 3 | describe("coerce", () => { 4 | it("should coerce given value", () => { 5 | expect(coerce("undefined")).toBeUndefined(); 6 | expect(coerce("null")).toBeNull(); 7 | expect(coerce("false")).toBe(false); 8 | expect(coerce("true")).toBe(true); 9 | expect(coerce("")).toBe(""); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/cli-core/src/utils/coerce.ts: -------------------------------------------------------------------------------- 1 | export function coerce(value: any) { 2 | if (["undefined"].includes(value)) { 3 | return undefined; 4 | } 5 | if (["null"].includes(value)) { 6 | return null; 7 | } 8 | 9 | if (["false"].includes(value)) { 10 | return false; 11 | } 12 | 13 | if (["true"].includes(value)) { 14 | return true; 15 | } 16 | 17 | return value; 18 | } 19 | -------------------------------------------------------------------------------- /packages/cli-core/src/utils/createInjector.spec.ts: -------------------------------------------------------------------------------- 1 | import {InjectorService} from "@tsed/di"; 2 | import {Logger} from "@tsed/logger"; 3 | 4 | import {CliConfiguration} from "../services/index.js"; 5 | import {createInjector} from "./createInjector.js"; 6 | 7 | describe("createInjector", () => { 8 | it("should create the injector", () => { 9 | const injector = createInjector(); 10 | 11 | expect(injector).toBeInstanceOf(InjectorService); 12 | expect(injector.settings).toBeInstanceOf(CliConfiguration); 13 | expect(injector.logger).toBeInstanceOf(Logger); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/cli-core/src/utils/getCommandMetadata.ts: -------------------------------------------------------------------------------- 1 | import {Store} from "@tsed/core"; 2 | import type {TokenProvider} from "@tsed/di"; 3 | 4 | import {CommandStoreKeys} from "../domains/CommandStoreKeys.js"; 5 | import type {CommandMetadata} from "../interfaces/CommandMetadata.js"; 6 | import type {CommandParameters} from "../interfaces/CommandParameters.js"; 7 | 8 | export function getCommandMetadata(token: TokenProvider): CommandMetadata { 9 | const { 10 | name, 11 | alias, 12 | args = {}, 13 | allowUnknownOption, 14 | description, 15 | options = {}, 16 | enableFeatures, 17 | disableReadUpPkg, 18 | bindLogger = true, 19 | ...opts 20 | } = Store.from(token)?.get(CommandStoreKeys.COMMAND) as CommandParameters; 21 | 22 | return { 23 | name, 24 | alias, 25 | args, 26 | description, 27 | options, 28 | allowUnknownOption: !!allowUnknownOption, 29 | enableFeatures: enableFeatures || [], 30 | disableReadUpPkg: !!disableReadUpPkg, 31 | bindLogger, 32 | ...opts 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /packages/cli-core/src/utils/getTemplateDirectory.ts: -------------------------------------------------------------------------------- 1 | import {dirname, join} from "node:path"; 2 | 3 | import {readPackageUpSync} from "read-pkg-up"; 4 | 5 | export function getTemplateDirectory(cwd: string) { 6 | const {path} = readPackageUpSync({ 7 | cwd: join(cwd, "..", "..") 8 | })!; 9 | 10 | return join(dirname(path), "templates"); 11 | } 12 | -------------------------------------------------------------------------------- /packages/cli-core/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./createInjector.js"; 2 | export * from "./createTasksRunner.js"; 3 | export * from "./getCommandMetadata.js"; 4 | export * from "./getTemplateDirectory.js"; 5 | export * from "./loadPlugins.js"; 6 | export * from "./logToCurl.js"; 7 | export * from "./mapCommanderArgs.js"; 8 | export * from "./mapCommanderOptions.js"; 9 | export * from "./parseOption.js"; 10 | export * from "./resolveConfiguration.js"; 11 | -------------------------------------------------------------------------------- /packages/cli-core/src/utils/isValidVersion.spec.ts: -------------------------------------------------------------------------------- 1 | import {isValidVersion} from "./isValidVersion.js"; 2 | 3 | describe("isValidVersion", () => { 4 | it("should validate version", () => { 5 | expect(isValidVersion(">=3.0.1")).toEqual(true); 6 | expect(isValidVersion("3.0.1")).toEqual(true); 7 | expect(isValidVersion(">3.0.1")).toEqual(true); 8 | expect(isValidVersion("<3.0.1")).toEqual(true); 9 | expect(isValidVersion("~3.0.1")).toEqual(true); 10 | expect(isValidVersion("latest")).toEqual(false); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/cli-core/src/utils/isValidVersion.ts: -------------------------------------------------------------------------------- 1 | import semver from "semver"; 2 | 3 | export function isValidVersion(version: string) { 4 | version = version.replace(/[~>=<]/gi, ""); 5 | return !!semver.valid(version); 6 | } 7 | -------------------------------------------------------------------------------- /packages/cli-core/src/utils/logToCurl.ts: -------------------------------------------------------------------------------- 1 | import parse from "url-parse"; 2 | 3 | export function logToCurl({url, method, params, query, data, headers = {}}: any) { 4 | const request = parse(url, true); 5 | if (params) { 6 | request.set("query", Object.assign(params, query)); 7 | } 8 | 9 | let curl = `curl -X ${method.toUpperCase()} '${request.toString()}'`; 10 | 11 | if (data) { 12 | curl += ` -d '${JSON.stringify(data)}'`; 13 | } 14 | 15 | curl += Object.entries(headers).reduce((curlHeaders, [key, value]) => `${curlHeaders} -H '${key}: ${value}'`, ""); 16 | 17 | return curl; 18 | } 19 | -------------------------------------------------------------------------------- /packages/cli-core/src/utils/mapCommanderOptions.ts: -------------------------------------------------------------------------------- 1 | import type {Command} from "commander"; 2 | 3 | export function mapCommanderOptions(commandName: string, commands: readonly Command[]) { 4 | const options: any = {}; 5 | 6 | commands.forEach((command) => { 7 | if (command.name() !== commandName) { 8 | return; 9 | } 10 | 11 | Object.entries(command.opts()) 12 | .filter(([key]) => !key.startsWith("_") && !["commands", "options", "parent", "rawArgs", "args"].includes(key)) 13 | .forEach(([key, value]) => { 14 | options[key] = value; 15 | }); 16 | }); 17 | 18 | return options; 19 | } 20 | -------------------------------------------------------------------------------- /packages/cli-core/src/utils/parseOption.spec.ts: -------------------------------------------------------------------------------- 1 | import {parseOption} from "./parseOption.js"; 2 | 3 | describe("parseOptions", () => { 4 | it("should parse string --path ", () => { 5 | expect(parseOption("string", {type: String})).toEqual("string"); 6 | }); 7 | it("should parse number --count ", () => { 8 | expect(parseOption("9", {type: Number})).toEqual(9); 9 | }); 10 | it("should parse boolean --use-db", () => { 11 | expect(parseOption("", {type: Boolean})).toEqual(true); 12 | }); 13 | it("should parse array --list ", () => { 14 | const result = parseOption("1,2,3", { 15 | type: Array, 16 | itemType: Number 17 | }); 18 | expect(result).toEqual([1, 2, 3]); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /packages/cli-core/src/utils/parseOption.ts: -------------------------------------------------------------------------------- 1 | import {Type} from "@tsed/core"; 2 | 3 | export function parseOption(value: any, options: {type?: Type; itemType?: Type; customParser?: any}) { 4 | const {type, itemType, customParser} = options; 5 | 6 | if (type) { 7 | switch (type) { 8 | case String: 9 | value = String(value); 10 | break; 11 | case Boolean: // the flag is added 12 | return true; 13 | case Number: 14 | value = +value; 15 | break; 16 | case Array: 17 | value = value.split(",").map((value: string) => parseOption(value, {type: itemType, customParser})); 18 | break; 19 | } 20 | } 21 | 22 | if (options.customParser) { 23 | value = options.customParser(value); 24 | } 25 | 26 | return value; 27 | } 28 | -------------------------------------------------------------------------------- /packages/cli-core/src/utils/resolveConfiguration.ts: -------------------------------------------------------------------------------- 1 | import {getValue} from "@tsed/core"; 2 | import type {TokenProvider} from "@tsed/di"; 3 | 4 | import {getCommandMetadata} from "./getCommandMetadata.js"; 5 | 6 | export function resolveConfiguration(settings: any) { 7 | const argv = getValue(settings, "argv", process.argv); 8 | const configResolvers = getValue(settings, "configResolvers", []); 9 | const commands = getValue(settings, "commands", []); 10 | 11 | const commandOpts = commands 12 | .map((token: TokenProvider) => getCommandMetadata(token)) 13 | .find((commandOpts: any) => argv.includes(commandOpts.name)); 14 | 15 | settings = { 16 | ...settings, 17 | commands, 18 | command: commandOpts || {}, 19 | argv 20 | }; 21 | 22 | configResolvers.map((resolver: (settings: any) => void) => resolver(settings)); 23 | 24 | return settings; 25 | } 26 | -------------------------------------------------------------------------------- /packages/cli-core/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsed/typescript/tsconfig.node.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "rootDir": "src", 6 | "outDir": "./lib/esm", 7 | "declarationDir": "./lib/types", 8 | "declaration": true, 9 | "composite": true, 10 | "noEmit": false, 11 | "sourceMap": false 12 | }, 13 | "include": ["src", "src/**/*.json"], 14 | "exclude": [ 15 | "node_modules", 16 | "test", 17 | "lib", 18 | "benchmark", 19 | "coverage", 20 | "spec", 21 | "**/*.benchmark.ts", 22 | "**/*.spec.ts", 23 | "keys", 24 | "**/__mock__/**", 25 | "webpack.config.js" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/cli-core/vitest.config.mts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import {presets} from "@tsed/vitest/presets"; 3 | import {defineConfig} from "vitest/config"; 4 | 5 | export default defineConfig( 6 | { 7 | ...presets, 8 | test: { 9 | ...presets.test, 10 | coverage: { 11 | ...presets.test?.coverage, 12 | thresholds: { 13 | statements: 0, 14 | branches: 0, 15 | functions: 0, 16 | lines: 0 17 | } 18 | } 19 | } 20 | } 21 | ); 22 | -------------------------------------------------------------------------------- /packages/cli-generate-http-client/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | coverage 4 | tsconfig.json 5 | tsconfig.*.json 6 | __mock__ 7 | *.spec.js 8 | *.tsbuildinfo 9 | src 10 | vitest.config.mts -------------------------------------------------------------------------------- /packages/cli-generate-http-client/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./commands/GenerateHttpClientCmd.js"; 2 | 3 | export default {}; 4 | -------------------------------------------------------------------------------- /packages/cli-generate-http-client/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsed/typescript/tsconfig.node.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "rootDir": "src", 6 | "outDir": "./lib/esm", 7 | "declarationDir": "./lib/types", 8 | "declaration": true, 9 | "composite": true, 10 | "noEmit": false, 11 | "sourceMap": false 12 | }, 13 | "include": ["src", "src/**/*.json"], 14 | "exclude": [ 15 | "node_modules", 16 | "test", 17 | "lib", 18 | "benchmark", 19 | "coverage", 20 | "spec", 21 | "**/*.benchmark.ts", 22 | "**/*.spec.ts", 23 | "keys", 24 | "**/__mock__/**", 25 | "webpack.config.js" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/cli-generate-http-client/vitest.config.mts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import {presets} from "@tsed/vitest/presets"; 3 | import {defineConfig} from "vitest/config"; 4 | 5 | export default defineConfig( 6 | { 7 | ...presets, 8 | test: { 9 | ...presets.test, 10 | coverage: { 11 | ...presets.test.coverage, 12 | thresholds: { 13 | statements: 0, 14 | branches: 0, 15 | functions: 0, 16 | lines: 0 17 | } 18 | } 19 | } 20 | } 21 | ); 22 | -------------------------------------------------------------------------------- /packages/cli-generate-swagger/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | coverage 4 | tsconfig.json 5 | tsconfig.*.json 6 | __mock__ 7 | *.spec.js 8 | *.tsbuildinfo 9 | src 10 | vitest.config.mts -------------------------------------------------------------------------------- /packages/cli-generate-swagger/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./commands/GenerateSwaggerCmd.js"; 2 | 3 | export default {}; 4 | -------------------------------------------------------------------------------- /packages/cli-generate-swagger/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsed/typescript/tsconfig.node.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "rootDir": "src", 6 | "outDir": "./lib/esm", 7 | "declarationDir": "./lib/types", 8 | "declaration": true, 9 | "composite": true, 10 | "noEmit": false, 11 | "sourceMap": false 12 | }, 13 | "include": ["src", "src/**/*.json"], 14 | "exclude": [ 15 | "node_modules", 16 | "test", 17 | "lib", 18 | "benchmark", 19 | "coverage", 20 | "spec", 21 | "**/*.benchmark.ts", 22 | "**/*.spec.ts", 23 | "keys", 24 | "**/__mock__/**", 25 | "webpack.config.js" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/cli-generate-swagger/vitest.config.mts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import {presets} from "@tsed/vitest/presets"; 3 | import {defineConfig} from "vitest/config"; 4 | 5 | export default defineConfig( 6 | { 7 | ...presets, 8 | test: { 9 | ...presets.test, 10 | coverage: { 11 | ...presets.test.coverage, 12 | thresholds: { 13 | statements: 0, 14 | branches: 0, 15 | functions: 0, 16 | lines: 0 17 | } 18 | } 19 | } 20 | } 21 | ); 22 | -------------------------------------------------------------------------------- /packages/cli-plugin-eslint/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | coverage 4 | tsconfig.json 5 | tsconfig.*.json 6 | __mock__ 7 | *.spec.js 8 | *.tsbuildinfo 9 | src 10 | vitest.config.mts -------------------------------------------------------------------------------- /packages/cli-plugin-eslint/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tsed/cli-plugin-eslint", 3 | "description": "Ts.ED CLI plugin. Add EsLint support", 4 | "version": "6.4.3", 5 | "type": "module", 6 | "main": "./lib/esm/index.js", 7 | "source": "./src/index.ts", 8 | "module": "./lib/esm/index.js", 9 | "typings": "./lib/types/index.d.ts", 10 | "exports": { 11 | ".": { 12 | "cli-tsed-source": "./src/index.ts", 13 | "types": "./lib/types/index.d.ts", 14 | "import": "./lib/esm/index.js", 15 | "default": "./lib/esm/index.js" 16 | } 17 | }, 18 | "scripts": { 19 | "build": "yarn build:ts", 20 | "build:ts": "tsc --build tsconfig.esm.json" 21 | }, 22 | "devDependencies": { 23 | "@tsed/cli": "workspace:*", 24 | "@tsed/cli-core": "workspace:*", 25 | "@tsed/typescript": "workspace:*", 26 | "cross-env": "7.0.3", 27 | "typescript": "5.6.2", 28 | "vitest": "3.0.9" 29 | }, 30 | "dependencies": { 31 | "tslib": "2.7.0" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/cli-plugin-eslint/scripts/templateDir.esm.js: -------------------------------------------------------------------------------- 1 | import path from "node:path"; 2 | import {fileURLToPath} from "node:url"; 3 | 4 | import {getTemplateDirectory} from "@tsed/cli-core"; 5 | 6 | export const TEMPLATE_DIR = getTemplateDirectory(path.dirname(fileURLToPath(import.meta.url))); 7 | -------------------------------------------------------------------------------- /packages/cli-plugin-eslint/src/CliPluginEslintModule.ts: -------------------------------------------------------------------------------- 1 | import {Module} from "@tsed/cli-core"; 2 | 3 | import {EslintInitHook} from "./hooks/EslintInitHook.js"; 4 | 5 | @Module({ 6 | imports: [EslintInitHook] 7 | }) 8 | export class CliPluginEslintModule {} 9 | -------------------------------------------------------------------------------- /packages/cli-plugin-eslint/src/index.ts: -------------------------------------------------------------------------------- 1 | import {CliPluginEslintModule} from "./CliPluginEslintModule.js"; 2 | 3 | export * from "./utils/templateDir.js"; 4 | 5 | export default CliPluginEslintModule; 6 | -------------------------------------------------------------------------------- /packages/cli-plugin-eslint/src/utils/templateDir.ts: -------------------------------------------------------------------------------- 1 | import {getTemplateDirectory} from "@tsed/cli-core"; 2 | 3 | export const TEMPLATE_DIR = getTemplateDirectory(import.meta.dirname); 4 | -------------------------------------------------------------------------------- /packages/cli-plugin-eslint/templates/init/.husky/.gitignore.hbs: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /packages/cli-plugin-eslint/templates/init/.husky/_/.gitignore.hbs: -------------------------------------------------------------------------------- 1 | * -------------------------------------------------------------------------------- /packages/cli-plugin-eslint/templates/init/.husky/_/husky.sh.hbs: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ -z "$husky_skip_init" ]; then 3 | debug () { 4 | if [ "$HUSKY_DEBUG" = "1" ]; then 5 | echo "husky (debug) - $1" 6 | fi 7 | } 8 | 9 | readonly hook_name="$(basename "$0")" 10 | debug "starting $hook_name..." 11 | 12 | if [ "$HUSKY" = "0" ]; then 13 | debug "HUSKY env variable is set to 0, skipping hook" 14 | exit 0 15 | fi 16 | 17 | if [ -f ~/.huskyrc ]; then 18 | debug "sourcing ~/.huskyrc" 19 | . ~/.huskyrc 20 | fi 21 | 22 | export readonly husky_skip_init=1 23 | sh -e "$0" "$@" 24 | exitCode="$?" 25 | 26 | if [ $exitCode != 0 ]; then 27 | echo "husky - $hook_name hook exited with code $exitCode (error)" 28 | fi 29 | 30 | exit $exitCode 31 | fi 32 | -------------------------------------------------------------------------------- /packages/cli-plugin-eslint/templates/init/.husky/post-commit.hbs: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | git update-index --again 5 | -------------------------------------------------------------------------------- /packages/cli-plugin-eslint/templates/init/.husky/pre-commit.hbs: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx lint-staged $1 5 | -------------------------------------------------------------------------------- /packages/cli-plugin-eslint/templates/init/.lintstagedrc.json.hbs: -------------------------------------------------------------------------------- 1 | { {{#if prettier}} 2 | "**/*.{ts,js}": ["eslint --fix"],{{/if}} 3 | "**/*.{ts,js,json,md,yml,yaml}": ["prettier --write"] 4 | } 5 | -------------------------------------------------------------------------------- /packages/cli-plugin-eslint/templates/init/.prettierignore.hbs: -------------------------------------------------------------------------------- 1 | dist 2 | docs 3 | node_modules 4 | *-lock.json 5 | *.lock 6 | -------------------------------------------------------------------------------- /packages/cli-plugin-eslint/templates/init/.prettierrc.hbs: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 140, 3 | "singleQuote": false, 4 | "jsxSingleQuote": true, 5 | "semi": true, 6 | "tabWidth": 2, 7 | "bracketSpacing": true, 8 | "arrowParens": "always", 9 | "trailingComma": "none" 10 | } 11 | -------------------------------------------------------------------------------- /packages/cli-plugin-eslint/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsed/typescript/tsconfig.node.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "rootDir": "src", 6 | "outDir": "./lib/esm", 7 | "declarationDir": "./lib/types", 8 | "declaration": true, 9 | "composite": true, 10 | "noEmit": false, 11 | "sourceMap": false 12 | }, 13 | "include": ["src", "src/**/*.json"], 14 | "exclude": [ 15 | "node_modules", 16 | "test", 17 | "lib", 18 | "benchmark", 19 | "coverage", 20 | "spec", 21 | "**/*.benchmark.ts", 22 | "**/*.spec.ts", 23 | "keys", 24 | "**/__mock__/**", 25 | "webpack.config.js" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/cli-plugin-eslint/vitest.config.mts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import {presets} from "@tsed/vitest/presets"; 3 | import {defineConfig} from "vitest/config"; 4 | 5 | export default defineConfig( 6 | { 7 | ...presets, 8 | test: { 9 | ...presets.test, 10 | coverage: { 11 | ...presets.test.coverage, 12 | thresholds: { 13 | statements: 0, 14 | branches: 0, 15 | functions: 0, 16 | lines: 0 17 | } 18 | } 19 | } 20 | } 21 | ); 22 | -------------------------------------------------------------------------------- /packages/cli-plugin-jest/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | coverage 4 | tsconfig.json 5 | tsconfig.*.json 6 | __mock__ 7 | *.spec.js 8 | *.tsbuildinfo 9 | src 10 | vitest.config.mts -------------------------------------------------------------------------------- /packages/cli-plugin-jest/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tsed/cli-plugin-jest", 3 | "description": "Ts.ED CLI plugin. Add Jest support", 4 | "version": "6.4.3", 5 | "type": "module", 6 | "main": "./lib/esm/index.js", 7 | "source": "./src/index.ts", 8 | "module": "./lib/esm/index.js", 9 | "typings": "./lib/types/index.d.ts", 10 | "exports": { 11 | ".": { 12 | "cli-tsed-source": "./src/index.ts", 13 | "types": "./lib/types/index.d.ts", 14 | "import": "./lib/esm/index.js", 15 | "default": "./lib/esm/index.js" 16 | } 17 | }, 18 | "scripts": { 19 | "build": "yarn build:ts", 20 | "build:ts": "tsc --build tsconfig.esm.json", 21 | "test": "vitest run", 22 | "test:ci": "vitest run --coverage.thresholds.autoUpdate=true" 23 | }, 24 | "devDependencies": { 25 | "@tsed/cli": "workspace:*", 26 | "@tsed/cli-core": "workspace:*", 27 | "@tsed/typescript": "workspace:*", 28 | "cross-env": "7.0.3", 29 | "typescript": "5.6.2", 30 | "vitest": "3.0.9" 31 | }, 32 | "dependencies": { 33 | "tslib": "2.7.0" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/cli-plugin-jest/scripts/templateDir.esm.js: -------------------------------------------------------------------------------- 1 | import path from "node:path"; 2 | import {fileURLToPath} from "node:url"; 3 | 4 | import {getTemplateDirectory} from "@tsed/cli-core"; 5 | 6 | export const TEMPLATE_DIR = getTemplateDirectory(path.dirname(fileURLToPath(import.meta.url))); 7 | -------------------------------------------------------------------------------- /packages/cli-plugin-jest/src/CliPluginJestModule.ts: -------------------------------------------------------------------------------- 1 | import {RuntimesModule} from "@tsed/cli"; 2 | import {inject, Module, OnAdd, ProjectPackageJson} from "@tsed/cli-core"; 3 | 4 | import {JestGenerateHook} from "./hooks/JestGenerateHook.js"; 5 | import {JestInitHook} from "./hooks/JestInitHook.js"; 6 | 7 | @Module({ 8 | imports: [JestInitHook, JestGenerateHook] 9 | }) 10 | export class CliPluginJestModule { 11 | protected runtimes = inject(RuntimesModule); 12 | protected packageJson = inject(ProjectPackageJson); 13 | 14 | @OnAdd("@tsed/cli-plugin-jest") 15 | install() { 16 | this.addScripts(); 17 | this.addDevDependencies(); 18 | } 19 | 20 | addScripts() { 21 | const runtime = this.runtimes.get(); 22 | 23 | this.packageJson.addScripts({ 24 | "test:unit": "cross-env NODE_OPTIONS=--experimental-vm-modules NODE_ENV=test jest", 25 | "test:coverage": `${runtime.run("test:unit")} ` 26 | }); 27 | } 28 | 29 | addDevDependencies() { 30 | this.packageJson.addDevDependencies({ 31 | "@types/jest": "latest", 32 | "@swc/jest": "latest", 33 | jest: "latest" 34 | }); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/cli-plugin-jest/src/hooks/JestInitHook.ts: -------------------------------------------------------------------------------- 1 | import {RootRendererService} from "@tsed/cli"; 2 | import {inject, Injectable, OnExec, ProjectPackageJson} from "@tsed/cli-core"; 3 | 4 | import {TEMPLATE_DIR} from "../utils/templateDir.js"; 5 | 6 | @Injectable() 7 | export class JestInitHook { 8 | protected packageJson = inject(ProjectPackageJson); 9 | protected rootRenderer = inject(RootRendererService); 10 | 11 | @OnExec("init") 12 | onInitExec() { 13 | return [ 14 | { 15 | title: "Generate files for jest", 16 | task: (ctx: any) => { 17 | return this.rootRenderer.renderAll(["jest.config.ts.hbs"], ctx, { 18 | templateDir: `${TEMPLATE_DIR}/init` 19 | }); 20 | } 21 | } 22 | ]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/cli-plugin-jest/src/index.ts: -------------------------------------------------------------------------------- 1 | import {CliPluginJestModule} from "./CliPluginJestModule.js"; 2 | 3 | export * from "./utils/templateDir.js"; 4 | 5 | export default CliPluginJestModule; 6 | -------------------------------------------------------------------------------- /packages/cli-plugin-jest/src/utils/templateDir.ts: -------------------------------------------------------------------------------- 1 | import {getTemplateDirectory} from "@tsed/cli-core"; 2 | 3 | export const TEMPLATE_DIR = getTemplateDirectory(import.meta.dirname); 4 | -------------------------------------------------------------------------------- /packages/cli-plugin-jest/templates/generate/decorator.class.spec.hbs: -------------------------------------------------------------------------------- 1 | import { {{symbolName}} } from "./{{symbolPathBasename}}.js"; 2 | 3 | describe("{{symbolName}}", () => { 4 | it("should do something", () => { 5 | @{{symbolName}}({}) 6 | class Test { 7 | } 8 | 9 | expect(typeof {{symbolName}}).toBe("function") 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/cli-plugin-jest/templates/generate/decorator.endpoint.spec.hbs: -------------------------------------------------------------------------------- 1 | import { Store } from "@tsed/core"; 2 | import { {{symbolName}} } from "./{{symbolPathBasename}}.js"; 3 | 4 | describe("{{symbolName}}", () => { 5 | it("should store options", () => { 6 | class Test { 7 | @{{symbolName}}({options: "options"}) 8 | method() param: string){} 9 | } 10 | 11 | const store = Store.fromMethod(Test, "method"); 12 | 13 | expect(store.get({{symbolName}})).toEqual({options: "options"}); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/cli-plugin-jest/templates/generate/decorator.method.spec.hbs: -------------------------------------------------------------------------------- 1 | import { {{symbolName}} } from "./{{symbolPathBasename}}.js"; 2 | 3 | describe("{{symbolName}}", () => { 4 | it("should do something", () => { 5 | class Test { 6 | @{{symbolName}}({}) 7 | method(){} 8 | } 9 | 10 | expect(typeof {{symbolName}}).toBe("function") 11 | expect(typeof {{symbolName}}()).toBe("function") 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /packages/cli-plugin-jest/templates/generate/decorator.param.spec.hbs: -------------------------------------------------------------------------------- 1 | import { Store } from "@tsed/core"; 2 | import { {{symbolName}} } from "./{{symbolPathBasename}}.js"; 3 | 4 | describe("{{symbolName}}", () => { 5 | it("should store options", () => { 6 | class Test { 7 | method(@{{symbolName}}({options: "options"}) param: string){} 8 | } 9 | 10 | const store = Store.from(Test, "method", 0) 11 | 12 | expect(store.get({{symbolName}})).toEqual({options: "options"}); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/cli-plugin-jest/templates/generate/decorator.parameter.spec.hbs: -------------------------------------------------------------------------------- 1 | import { {{symbolName}} } from "./{{symbolPathBasename}}.js"; 2 | 3 | describe("{{symbolName}}", () => { 4 | it("should do something", () => { 5 | class Test { 6 | method(@{{symbolName}}({}) param: string){} 7 | } 8 | 9 | expect(typeof {{symbolName}}).toBe("function") 10 | expect(typeof {{symbolName}}()).toBe("function") 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/cli-plugin-jest/templates/generate/decorator.prop.spec.hbs: -------------------------------------------------------------------------------- 1 | import { Store } from "@tsed/core"; 2 | import { {{symbolName}} } from "./{{symbolPathBasename}}.js"; 3 | 4 | describe("{{symbolName}}", () => { 5 | it("should store options", () => { 6 | class Test { 7 | @{{symbolName}}({options: "options"}) 8 | property: string; 9 | } 10 | 11 | const store = Store.from(Test, "property"); 12 | 13 | expect(store.get({{symbolName}})).toEqual({options: "options"}); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/cli-plugin-jest/templates/generate/decorator.property.spec.hbs: -------------------------------------------------------------------------------- 1 | import { {{symbolName}} } from "./{{symbolPathBasename}}.js"; 2 | 3 | describe("{{symbolName}}", () => { 4 | it("should do something", () => { 5 | class Test { 6 | @{{symbolName}}({}) 7 | property: string; 8 | } 9 | 10 | expect(typeof {{symbolName}}).toBe("function") 11 | expect(typeof {{symbolName}}()).toBe("function") 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /packages/cli-plugin-jest/templates/generate/generic.integration.hbs: -------------------------------------------------------------------------------- 1 | import { PlatformTest } from "@tsed/platform-http/testing"; 2 | import SuperTest from "supertest"; 3 | import { {{symbolName}} } from "./{{symbolPathBasename}}.js"; 4 | import { Server } from "{{relativeSrcPath}}/Server.js"; 5 | 6 | describe("{{symbolName}}", () => { 7 | beforeEach(PlatformTest.bootstrap(Server, { 8 | mount: { 9 | "/": [{{symbolName}}] 10 | } 11 | })); 12 | afterEach(PlatformTest.reset); 13 | 14 | it("should call GET {{route}}", async () => { 15 | const request = SuperTest(PlatformTest.callback()); 16 | const response = await request.get("{{route}}").expect(200); 17 | 18 | expect(response.text).toEqual("hello"); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /packages/cli-plugin-jest/templates/generate/generic.spec.hbs: -------------------------------------------------------------------------------- 1 | import { PlatformTest } from "@tsed/platform-http/testing"; 2 | import { {{symbolName}} } from "./{{symbolPathBasename}}.js"; 3 | 4 | describe("{{symbolName}}", () => { 5 | beforeEach(PlatformTest.create); 6 | afterEach(PlatformTest.reset); 7 | 8 | it("should do something", () => { 9 | const instance = PlatformTest.get<{{symbolName}}>({{symbolName}}); 10 | // const instance = PlatformTest.invoke<{{symbolName}}>({{symbolName}}); // get fresh instance 11 | 12 | expect(instance).toBeInstanceOf({{symbolName}}); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/cli-plugin-jest/templates/generate/server.integration.hbs: -------------------------------------------------------------------------------- 1 | import { PlatformTest } from "@tsed/platform-http/testing"; 2 | import SuperTest from "supertest"; 3 | import { {{symbolName}} } from "./{{symbolPathBasename}}.js"; 4 | 5 | describe("{{symbolName}}", () => { 6 | beforeEach(PlatformTest.bootstrap({{symbolName}})); 7 | afterEach(PlatformTest.reset); 8 | 9 | it("should call GET {{route}}", async () => { 10 | const request = SuperTest(PlatformTest.callback()); 11 | const response = await request.get("{{route}}").expect(404); 12 | 13 | expect(response.body).toEqual({ 14 | errors: [], 15 | message: 'Resource "/rest" not found', 16 | name: "NOT_FOUND", 17 | status: 404, 18 | }); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /packages/cli-plugin-jest/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsed/typescript/tsconfig.node.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "rootDir": "src", 6 | "outDir": "./lib/esm", 7 | "declarationDir": "./lib/types", 8 | "declaration": true, 9 | "composite": true, 10 | "noEmit": false, 11 | "sourceMap": false 12 | }, 13 | "include": ["src", "src/**/*.json"], 14 | "exclude": [ 15 | "node_modules", 16 | "test", 17 | "lib", 18 | "benchmark", 19 | "coverage", 20 | "spec", 21 | "**/*.benchmark.ts", 22 | "**/*.spec.ts", 23 | "keys", 24 | "**/__mock__/**", 25 | "webpack.config.js" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/cli-plugin-jest/vitest.config.mts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import {presets} from "@tsed/vitest/presets"; 3 | import {defineConfig} from "vitest/config"; 4 | 5 | export default defineConfig( 6 | { 7 | ...presets, 8 | test: { 9 | ...presets.test, 10 | coverage: { 11 | ...presets.test.coverage, 12 | thresholds: { 13 | statements: 0, 14 | branches: 0, 15 | functions: 0, 16 | lines: 0 17 | } 18 | } 19 | } 20 | } 21 | ); 22 | -------------------------------------------------------------------------------- /packages/cli-plugin-mongoose/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | coverage 4 | tsconfig.json 5 | tsconfig.*.json 6 | __mock__ 7 | *.spec.js 8 | *.tsbuildinfo 9 | src 10 | vitest.config.mts -------------------------------------------------------------------------------- /packages/cli-plugin-mongoose/scripts/templateDir.esm.js: -------------------------------------------------------------------------------- 1 | import path from "node:path"; 2 | import {fileURLToPath} from "node:url"; 3 | 4 | import {getTemplateDirectory} from "@tsed/cli-core"; 5 | 6 | export const TEMPLATE_DIR = getTemplateDirectory(path.dirname(fileURLToPath(import.meta.url))); 7 | -------------------------------------------------------------------------------- /packages/cli-plugin-mongoose/src/CliPluginMongooseModule.ts: -------------------------------------------------------------------------------- 1 | import {inject, Module, OnAdd, ProjectPackageJson} from "@tsed/cli-core"; 2 | 3 | import {MongooseGenerateHook} from "./hooks/MongooseGenerateHook.js"; 4 | import {MongooseInitHook} from "./hooks/MongooseInitHook.js"; 5 | import {CliMongoose} from "./services/CliMongoose.js"; 6 | 7 | @Module({ 8 | imports: [MongooseInitHook, MongooseGenerateHook, CliMongoose] 9 | }) 10 | export class CliPluginMongooseModule { 11 | protected packageJson = inject(ProjectPackageJson); 12 | 13 | @OnAdd("@tsed/cli-plugin-mongoose") 14 | install() { 15 | this.packageJson.addDependencies({ 16 | "@tsed/mongoose": this.packageJson.dependencies["@tsed/platform-http"], 17 | mongoose: "latest" 18 | }); 19 | 20 | this.packageJson.addDevDependencies({ 21 | "@tsed/testing-mongoose": this.packageJson.dependencies["@tsed/platform-http"] 22 | }); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/cli-plugin-mongoose/src/index.ts: -------------------------------------------------------------------------------- 1 | import {CliPluginMongooseModule} from "./CliPluginMongooseModule.js"; 2 | 3 | export * from "./hooks/MongooseGenerateHook.js"; 4 | export * from "./hooks/MongooseInitHook.js"; 5 | export * from "./services/CliMongoose.js"; 6 | export * from "./utils/templateDir.js"; 7 | 8 | export default CliPluginMongooseModule; 9 | -------------------------------------------------------------------------------- /packages/cli-plugin-mongoose/src/utils/templateDir.ts: -------------------------------------------------------------------------------- 1 | import {getTemplateDirectory} from "@tsed/cli-core"; 2 | 3 | export const TEMPLATE_DIR = getTemplateDirectory(import.meta.dirname); 4 | -------------------------------------------------------------------------------- /packages/cli-plugin-mongoose/templates/config.hbs: -------------------------------------------------------------------------------- 1 | export default { 2 | id: "{{name}}", 3 | url: process.env.{{symbolName}}_URL || "mongodb://localhost:27017/{{name}}", 4 | connectionOptions: { } 5 | }; 6 | -------------------------------------------------------------------------------- /packages/cli-plugin-mongoose/templates/index.hbs: -------------------------------------------------------------------------------- 1 | // @tsed/cli do not edit 2 | {{#forEach configs}} 3 | import {{symbolName}}Config from "./{{name}}.config"; 4 | {{/forEach}} 5 | 6 | export default [ 7 | {{#forEach configs}} 8 | {{symbolName}}Config{{#unless isLast}}, {{/unless}} 9 | {{/forEach}} 10 | ]; 11 | -------------------------------------------------------------------------------- /packages/cli-plugin-mongoose/templates/mongoose.model.hbs: -------------------------------------------------------------------------------- 1 | import { Model, ObjectID } from "@tsed/mongoose"; 2 | /** 3 | * ## How to inject model? 4 | * 5 | * ```typescript 6 | * import type { MongooseModel } from "@tsed/mongoose"; 7 | * import { Injectable, Inject } from "@tsed/di"; 8 | * 9 | * @Injectable() 10 | * class MyService { 11 | * @Inject({{ collectionName }}) 12 | * model: MongooseModel<{{ collectionName }}>; 13 | * } 14 | * ``` 15 | */ 16 | @Model({ 17 | name: "{{ collectionName }}" 18 | }) 19 | export class {{symbolName}} { 20 | @ObjectID("id") 21 | _id: string; 22 | } 23 | -------------------------------------------------------------------------------- /packages/cli-plugin-mongoose/templates/mongoose.schema.hbs: -------------------------------------------------------------------------------- 1 | import { Property } from "@tsed/schema"; 2 | import { Schema } from "@tsed/mongoose"; 3 | 4 | @Schema() 5 | export class {{symbolName}} { 6 | @Property() 7 | unique: string; 8 | } 9 | -------------------------------------------------------------------------------- /packages/cli-plugin-mongoose/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsed/typescript/tsconfig.node.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "rootDir": "src", 6 | "outDir": "./lib/esm", 7 | "declarationDir": "./lib/types", 8 | "declaration": true, 9 | "composite": true, 10 | "noEmit": false, 11 | "sourceMap": false 12 | }, 13 | "include": ["src", "src/**/*.json"], 14 | "exclude": [ 15 | "node_modules", 16 | "test", 17 | "lib", 18 | "benchmark", 19 | "coverage", 20 | "spec", 21 | "**/*.benchmark.ts", 22 | "**/*.spec.ts", 23 | "keys", 24 | "**/__mock__/**", 25 | "webpack.config.js" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/cli-plugin-mongoose/vitest.config.mts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import {presets} from "@tsed/vitest/presets"; 3 | import {defineConfig} from "vitest/config"; 4 | 5 | export default defineConfig( 6 | { 7 | ...presets, 8 | test: { 9 | ...presets.test, 10 | coverage: { 11 | ...presets.test.coverage, 12 | thresholds: { 13 | statements: 0, 14 | branches: 0, 15 | functions: 0, 16 | lines: 0 17 | } 18 | } 19 | } 20 | } 21 | ); 22 | -------------------------------------------------------------------------------- /packages/cli-plugin-oidc-provider/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | coverage 4 | tsconfig.json 5 | tsconfig.*.json 6 | __mock__ 7 | *.spec.js 8 | *.tsbuildinfo 9 | src 10 | vitest.config.mts -------------------------------------------------------------------------------- /packages/cli-plugin-oidc-provider/scripts/templateDir.esm.js: -------------------------------------------------------------------------------- 1 | import path from "node:path"; 2 | import {fileURLToPath} from "node:url"; 3 | 4 | import {getTemplateDirectory} from "@tsed/cli-core"; 5 | 6 | export const TEMPLATE_DIR = getTemplateDirectory(path.dirname(fileURLToPath(import.meta.url))); 7 | -------------------------------------------------------------------------------- /packages/cli-plugin-oidc-provider/src/CliPluginOidcProviderModule.ts: -------------------------------------------------------------------------------- 1 | import {inject, Module, OnAdd, ProjectPackageJson} from "@tsed/cli-core"; 2 | 3 | import {OidcProviderInitHook} from "./hooks/OidcProviderInitHook.js"; 4 | 5 | @Module({ 6 | imports: [OidcProviderInitHook] 7 | }) 8 | export class CliPluginOidcProviderModule { 9 | protected packageJson = inject(ProjectPackageJson); 10 | 11 | @OnAdd("@tsed/cli-plugin-oidc-provider") 12 | install() { 13 | this.packageJson.addDependencies({ 14 | "oidc-provider": "latest", 15 | "@tsed/oidc-provider": "latest", 16 | "@tsed/jwks": "latest", 17 | "@tsed/adapters": "latest", 18 | bcrypt: "latest" 19 | }); 20 | this.packageJson.addDevDependencies({ 21 | "@types/oidc-provider": "latest" 22 | }); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/cli-plugin-oidc-provider/src/index.ts: -------------------------------------------------------------------------------- 1 | import {CliPluginOidcProviderModule} from "./CliPluginOidcProviderModule.js"; 2 | 3 | export * from "./hooks/OidcProviderInitHook.js"; 4 | export * from "./utils/templateDir.js"; 5 | 6 | export default CliPluginOidcProviderModule; 7 | -------------------------------------------------------------------------------- /packages/cli-plugin-oidc-provider/src/utils/templateDir.ts: -------------------------------------------------------------------------------- 1 | import {getTemplateDirectory} from "@tsed/cli-core"; 2 | 3 | export const TEMPLATE_DIR = getTemplateDirectory(import.meta.dirname); 4 | -------------------------------------------------------------------------------- /packages/cli-plugin-oidc-provider/templates/init/src/config/oidc/index.ts.hbs: -------------------------------------------------------------------------------- 1 | import {OidcSettings} from "@tsed/oidc-provider"; 2 | import {Accounts} from "../../services/Accounts.js"; 3 | 4 | const settings: OidcSettings = { 5 | path: "{{oidcBasePath}}", 6 | Accounts: Accounts, 7 | jwksPath: "./jwks.jon", 8 | clients: [ 9 | { 10 | client_id: "client_id", 11 | client_secret: "client_secret", 12 | redirect_uris: [ 13 | "http://localhost:3000" 14 | ], 15 | response_types: ["id_token"], 16 | grant_types: ["implicit"], 17 | token_endpoint_auth_method: "none" 18 | } 19 | ], 20 | claims: { 21 | openid: ["sub"], 22 | email: ["email", "email_verified"] 23 | }, 24 | features: { 25 | // disable the packaged interactions 26 | devInteractions: {enabled: false}, 27 | encryption: {enabled: true}, 28 | introspection: {enabled: true}, 29 | revocation: {enabled: true} 30 | } 31 | } 32 | 33 | export default settings 34 | -------------------------------------------------------------------------------- /packages/cli-plugin-oidc-provider/templates/init/src/controllers/oidc/InteractionsController.spec.ts: -------------------------------------------------------------------------------- 1 | import {PlatformTest} from "@tsed/platform-http"; 2 | 3 | import {getOidcContextFixture} from "../../interactions/__mock__/oidcContext.fixture.js"; 4 | import {InteractionsController} from "./InteractionsController.js"; 5 | 6 | describe("InteractionsController", () => { 7 | beforeEach(() => PlatformTest.create()); 8 | afterEach(() => PlatformTest.reset()); 9 | 10 | describe("promptInteraction()", () => { 11 | it("should run the asked prompt interaction", async () => { 12 | const oidcContext = getOidcContextFixture(); 13 | const controller = await PlatformTest.invoke(InteractionsController); 14 | 15 | await controller.promptInteraction("name", oidcContext); 16 | 17 | expect(oidcContext.runInteraction).toHaveBeenCalledWith("name"); 18 | }); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /packages/cli-plugin-oidc-provider/templates/init/src/controllers/oidc/InteractionsController.ts: -------------------------------------------------------------------------------- 1 | import {Get, PathParams} from "@tsed/platform-http"; 2 | import {Interactions, OidcCtx} from "@tsed/oidc-provider"; 3 | import {Name} from "@tsed/schema"; 4 | import * as interactions from "../../interactions/index.js"; 5 | 6 | @Name("Oidc") 7 | @Interactions({ 8 | path: "/interaction/:uid", 9 | children: Object.values(interactions) 10 | }) 11 | export class InteractionsController { 12 | @Get("/:name?") 13 | promptInteraction(@PathParams("name") name: string | undefined, @OidcCtx() oidcCtx: OidcCtx) { 14 | return oidcCtx.runInteraction(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/cli-plugin-oidc-provider/templates/init/src/interactions/AbortInteraction.ts: -------------------------------------------------------------------------------- 1 | import {Inject} from "@tsed/platform-http"; 2 | import {Interaction, OidcCtx, OidcProvider, InteractionMethods} from "@tsed/oidc-provider"; 3 | import {View} from "@tsed/platform-views"; 4 | import {Name} from "@tsed/schema"; 5 | 6 | @Interaction({ 7 | name: "abort" 8 | }) 9 | @Name("Oidc") 10 | export class AbortInteraction implements InteractionMethods { 11 | @Inject() 12 | oidc: OidcProvider; 13 | 14 | @View("interaction") 15 | $prompt(@OidcCtx() oidcCtx: OidcCtx): Promise { 16 | return oidcCtx.interactionFinished( 17 | { 18 | error: "access_denied", 19 | error_description: "End-User aborted interaction" 20 | }, 21 | { 22 | mergeWithLastSubmission: false 23 | } 24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/cli-plugin-oidc-provider/templates/init/src/models/Account.ts: -------------------------------------------------------------------------------- 1 | import {Email, Name, Property} from "@tsed/schema"; 2 | 3 | export class Account { 4 | @Name("id") 5 | _id: string; 6 | 7 | @Email() 8 | email: string; 9 | 10 | @Property() 11 | @Name("email_verified") 12 | emailVerified: boolean; 13 | 14 | [key: string]: unknown; 15 | 16 | get accountId() { 17 | return this._id; 18 | } 19 | 20 | claims() { 21 | return { 22 | sub: this._id, 23 | email: this.email, 24 | email_verified: this.emailVerified 25 | }; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/cli-plugin-oidc-provider/templates/init/src/services/Accounts.ts: -------------------------------------------------------------------------------- 1 | import {Adapter, InjectAdapter} from "@tsed/adapters"; 2 | import {Injectable} from "@tsed/di"; 3 | import {deserialize} from "@tsed/json-mapper"; 4 | import {OidcAccountsMethods} from "@tsed/oidc-provider"; 5 | import {Account} from "../models/Account.js"; 6 | 7 | @Injectable() 8 | export class Accounts implements OidcAccountsMethods { 9 | @InjectAdapter("accounts", Account) 10 | adapter: Adapter; 11 | 12 | async $onInit() { 13 | const accounts = await this.adapter.findAll(); 14 | 15 | if (!accounts.length) { 16 | await this.adapter.create( 17 | deserialize( 18 | { 19 | email: "test@test.com", 20 | emailVerified: true 21 | }, 22 | {useAlias: false} 23 | ) 24 | ); 25 | } 26 | } 27 | 28 | findAccount(id: string) { 29 | return this.adapter.findById(id); 30 | } 31 | 32 | authenticate(email: string) { 33 | return this.adapter.findOne({email}); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/cli-plugin-oidc-provider/templates/init/views/consent.ejs: -------------------------------------------------------------------------------- 1 | <%- include('partials/header.ejs') %> 2 | 3 | 4 | 11 | 12 | <% include('partials/footer.ejs') %> 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /packages/cli-plugin-oidc-provider/templates/init/views/forms/login-form.ejs: -------------------------------------------------------------------------------- 1 | <% if (flash) { %> 2 |

<%= flash %>

3 | <% } %> 4 | 5 |
6 | autofocus="on"<% } else { %> value="<%= params.login_hint %>" <% } %>> 7 | 8 | autofocus="on"<% } %>> 9 | 10 | 11 |
12 | -------------------------------------------------------------------------------- /packages/cli-plugin-oidc-provider/templates/init/views/forms/select-account-form.ejs: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 | 6 | 7 |
-------------------------------------------------------------------------------- /packages/cli-plugin-oidc-provider/templates/init/views/login.ejs: -------------------------------------------------------------------------------- 1 | <%- include('partials/header.ejs') %> 2 | 3 | 4 | 11 | 12 | <%- include('partials/footer.ejs') %> 13 | 14 | 15 | -------------------------------------------------------------------------------- /packages/cli-plugin-oidc-provider/templates/init/views/partials/footer.ejs: -------------------------------------------------------------------------------- 1 |
2 |
3 | (Click to expand) DEBUG information 4 |
5 | uid: <%= uid %> 6 |
7 | 8 | <% if (session) { %> 9 |
10 | SESSION
11 | =========
12 | <%- session %> 13 |
14 | <% } %> 15 | 16 |
17 | PARAMS
18 | ========
19 | <%- dbg.params %> 20 |
21 | 22 |
23 | PROMPT
24 | ========
25 | <%- dbg.prompt %> 26 |
27 |
28 |
29 | -------------------------------------------------------------------------------- /packages/cli-plugin-oidc-provider/templates/init/views/partials/login-help.ejs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/cli-plugin-oidc-provider/templates/init/views/select_account.ejs: -------------------------------------------------------------------------------- 1 | <%- include('partials/header.ejs') %> 2 | 3 | 4 | 11 | 12 | <% include('partials/footer.ejs') %> 13 | 14 | 15 | -------------------------------------------------------------------------------- /packages/cli-plugin-oidc-provider/templates/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsed/typescript/tsconfig.node.json", 3 | "compilerOptions": { 4 | "noEmit": true, 5 | "noEmitOnError": true 6 | }, 7 | "include": ["init/**/*.ts"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/cli-plugin-oidc-provider/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsed/typescript/tsconfig.node.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "rootDir": "src", 6 | "outDir": "./lib/esm", 7 | "declarationDir": "./lib/types", 8 | "declaration": true, 9 | "composite": true, 10 | "noEmit": false, 11 | "sourceMap": false 12 | }, 13 | "include": ["src", "src/**/*.json"], 14 | "exclude": [ 15 | "node_modules", 16 | "test", 17 | "lib", 18 | "benchmark", 19 | "coverage", 20 | "spec", 21 | "**/*.benchmark.ts", 22 | "**/*.spec.ts", 23 | "keys", 24 | "**/__mock__/**", 25 | "webpack.config.js" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/cli-plugin-oidc-provider/vitest.config.mts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import {presets} from "@tsed/vitest/presets"; 3 | import {defineConfig} from "vitest/config"; 4 | 5 | export default defineConfig( 6 | { 7 | ...presets, 8 | test: { 9 | ...presets.test, 10 | 11 | coverage: { 12 | ...presets.test.coverage, 13 | thresholds: { 14 | statements: 0, 15 | branches: 0, 16 | functions: 0, 17 | lines: 0 18 | } 19 | } 20 | } 21 | } 22 | ); 23 | -------------------------------------------------------------------------------- /packages/cli-plugin-passport/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | coverage 4 | tsconfig.json 5 | tsconfig.*.json 6 | __mock__ 7 | *.spec.js 8 | *.tsbuildinfo 9 | src 10 | vitest.config.mts -------------------------------------------------------------------------------- /packages/cli-plugin-passport/scripts/templateDir.esm.js: -------------------------------------------------------------------------------- 1 | import path from "node:path"; 2 | import {fileURLToPath} from "node:url"; 3 | 4 | import {getTemplateDirectory} from "@tsed/cli-core"; 5 | 6 | export const TEMPLATE_DIR = getTemplateDirectory(path.dirname(fileURLToPath(import.meta.url))); 7 | -------------------------------------------------------------------------------- /packages/cli-plugin-passport/src/CliPluginPassportModule.ts: -------------------------------------------------------------------------------- 1 | import {inject, Module, OnAdd, ProjectPackageJson} from "@tsed/cli-core"; 2 | import {Inject} from "@tsed/di"; 3 | 4 | import {PassportGenerateHook} from "./hooks/PassportGenerateHook.js"; 5 | 6 | @Module({ 7 | imports: [PassportGenerateHook] 8 | }) 9 | export class CliPluginPassportModule { 10 | protected packageJson = inject(ProjectPackageJson); 11 | 12 | @OnAdd("@tsed/cli-plugin-passport") 13 | install() { 14 | this.packageJson.addDependencies({ 15 | "@tsed/passport": this.packageJson.dependencies["@tsed/platform-http"], 16 | passport: "latest" 17 | }); 18 | 19 | this.packageJson.addDevDependencies({ 20 | "@types/passport": "latest" 21 | }); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/cli-plugin-passport/src/index.ts: -------------------------------------------------------------------------------- 1 | import {CliPluginPassportModule} from "./CliPluginPassportModule.js"; 2 | 3 | export * from "./hooks/PassportGenerateHook.js"; 4 | export * from "./services/PassportClient.js"; 5 | export * from "./utils/templateDir.js"; 6 | 7 | export default CliPluginPassportModule; 8 | -------------------------------------------------------------------------------- /packages/cli-plugin-passport/src/services/PassportClient.ts: -------------------------------------------------------------------------------- 1 | import {CliHttpClient, inject, Injectable} from "@tsed/cli-core"; 2 | 3 | const HOST = "http://www.passportjs.org/packages"; 4 | 5 | @Injectable() 6 | export class PassportClient { 7 | protected httpClient = inject(CliHttpClient); 8 | 9 | async getPackages(): Promise { 10 | const result = await this.httpClient.get(`${HOST}/-/all.json`, {}); 11 | 12 | return Object.values(result).filter((o: any) => { 13 | return o.name && o.name.startsWith("passport-"); 14 | }); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/cli-plugin-passport/src/utils/templateDir.ts: -------------------------------------------------------------------------------- 1 | import {getTemplateDirectory} from "@tsed/cli-core"; 2 | 3 | export const TEMPLATE_DIR = getTemplateDirectory(import.meta.dirname); 4 | -------------------------------------------------------------------------------- /packages/cli-plugin-passport/templates/generic.protocol.hbs: -------------------------------------------------------------------------------- 1 | import {Req} from "@tsed/platform-http"; 2 | import {BodyParams} from "@tsed/platform-params"; 3 | import {OnInstall, OnVerify, Protocol, Args} from "@tsed/passport"; 4 | import {Strategy} from "{{passportPackage}}"; 5 | 6 | @Protocol({ 7 | name: "{{protocolName}}", 8 | useStrategy: Strategy, 9 | settings: {} 10 | }) 11 | export class {{symbolName}} implements OnVerify, OnInstall { 12 | async $onVerify(@Req() request: Req, @Args() args: any[]) { 13 | const [] = args; 14 | 15 | } 16 | 17 | $onInstall(strategy: Strategy): void { 18 | // intercept the strategy instance to adding extra configuration 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/cli-plugin-passport/templates/passport-http.protocol.hbs: -------------------------------------------------------------------------------- 1 | import {Req} from "@tsed/platform-http"; 2 | import {BodyParams} from "@tsed/platform-params"; 3 | import {OnInstall, OnVerify, Protocol} from "@tsed/passport"; 4 | import {BasicStrategy} from "passport-http"; 5 | 6 | @Protocol({ 7 | name: "{{protocolName}}", 8 | useStrategy: BasicStrategy, 9 | settings: {} 10 | }) 11 | export class {{symbolName}} implements OnVerify, OnInstall { 12 | async $onVerify(@Req() request: Req, @BodyParams() credentials: any) { 13 | const {username, password} = credentials; 14 | 15 | } 16 | 17 | $onInstall(strategy: Strategy): void { 18 | // intercept the strategy instance to adding extra configuration 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/cli-plugin-passport/templates/passport-local.protocol.hbs: -------------------------------------------------------------------------------- 1 | import {Req} from "@tsed/platform-http"; 2 | import {BodyParams} from "@tsed/platform-params"; 3 | import {OnInstall, OnVerify, Protocol} from "@tsed/passport"; 4 | import {IStrategyOptions, Strategy} from "passport-local"; 5 | 6 | @Protocol({ 7 | name: "{{protocolName}}", 8 | useStrategy: Strategy, 9 | settings: { 10 | usernameField: "email", 11 | passwordField: "password" 12 | } 13 | }) 14 | export class {{symbolName}} implements OnVerify, OnInstall { 15 | async $onVerify(@Req() request: Req, @BodyParams() credentials: any) { 16 | const {email, password} = credentials; 17 | 18 | } 19 | 20 | $onInstall(strategy: Strategy): void { 21 | // intercept the strategy instance to adding extra configuration 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/cli-plugin-passport/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsed/typescript/tsconfig.node.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "rootDir": "src", 6 | "outDir": "./lib/esm", 7 | "declarationDir": "./lib/types", 8 | "declaration": true, 9 | "composite": true, 10 | "noEmit": false, 11 | "sourceMap": false 12 | }, 13 | "include": ["src", "src/**/*.json"], 14 | "exclude": [ 15 | "node_modules", 16 | "test", 17 | "lib", 18 | "benchmark", 19 | "coverage", 20 | "spec", 21 | "**/*.benchmark.ts", 22 | "**/*.spec.ts", 23 | "keys", 24 | "**/__mock__/**", 25 | "webpack.config.js" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/cli-plugin-passport/vitest.config.mts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import {presets} from "@tsed/vitest/presets"; 3 | import {defineConfig} from "vitest/config"; 4 | 5 | export default defineConfig( 6 | { 7 | ...presets, 8 | test: { 9 | ...presets.test, 10 | coverage: { 11 | ...presets.test.coverage, 12 | thresholds: { 13 | statements: 0, 14 | branches: 0, 15 | functions: 0, 16 | lines: 0 17 | } 18 | } 19 | } 20 | } 21 | ); 22 | -------------------------------------------------------------------------------- /packages/cli-plugin-prisma/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | coverage 4 | tsconfig.json 5 | tsconfig.*.json 6 | __mock__ 7 | *.spec.js 8 | *.tsbuildinfo 9 | src 10 | vitest.config.mts -------------------------------------------------------------------------------- /packages/cli-plugin-prisma/scripts/templateDir.esm.js: -------------------------------------------------------------------------------- 1 | import path from "node:path"; 2 | import {fileURLToPath} from "node:url"; 3 | 4 | import {getTemplateDirectory} from "@tsed/cli-core"; 5 | 6 | export const TEMPLATE_DIR = getTemplateDirectory(path.dirname(fileURLToPath(import.meta.url))); 7 | -------------------------------------------------------------------------------- /packages/cli-plugin-prisma/src/CliPluginPrismaModule.ts: -------------------------------------------------------------------------------- 1 | import {Module} from "@tsed/cli-core"; 2 | 3 | import {PrismaCmd} from "./commands/PrismaCmd.js"; 4 | import {PrismaInitHook} from "./hooks/PrismaInitHook.js"; 5 | 6 | @Module({ 7 | imports: [PrismaInitHook, PrismaCmd] 8 | }) 9 | export class CliPluginPrismaModule {} 10 | -------------------------------------------------------------------------------- /packages/cli-plugin-prisma/src/commands/PrismaCmd.ts: -------------------------------------------------------------------------------- 1 | import {type CliDefaultOptions, Command, type CommandProvider, inject} from "@tsed/cli-core"; 2 | 3 | import {CliPrisma} from "../services/CliPrisma.js"; 4 | 5 | export interface PrismaContext extends CliDefaultOptions { 6 | command: string; 7 | } 8 | 9 | @Command({ 10 | name: "prisma", 11 | description: "Run a prisma command", 12 | args: { 13 | command: { 14 | description: "The prisma command", 15 | type: String, 16 | required: true 17 | } 18 | }, 19 | options: {}, 20 | allowUnknownOption: true 21 | }) 22 | export class PrismaCmd implements CommandProvider { 23 | protected cli = inject(CliPrisma); 24 | 25 | $exec(ctx: PrismaContext) { 26 | return [ 27 | { 28 | title: `Run Prisma CLI ${ctx.command}`, 29 | task: () => this.cli.run(ctx.command, ctx.rawArgs) 30 | } 31 | ]; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/cli-plugin-prisma/src/index.ts: -------------------------------------------------------------------------------- 1 | import {CliPluginPrismaModule} from "./CliPluginPrismaModule.js"; 2 | 3 | export * from "./hooks/PrismaInitHook.js"; 4 | export * from "./services/CliPrisma.js"; 5 | export * from "./utils/templateDir.js"; 6 | 7 | export default CliPluginPrismaModule; 8 | -------------------------------------------------------------------------------- /packages/cli-plugin-prisma/src/services/__snapshots__/CliPrisma.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`CliPrisma > patchPrismaSchema() > should patch the schema 1`] = ` 4 | "datasource db { 5 | provider = "sqlite" 6 | url = env("DATABASE_URL") 7 | } 8 | 9 | generator client { 10 | provider = "prisma-client-js" 11 | } 12 | 13 | generator tsed { 14 | provider = "tsed-prisma" 15 | } 16 | 17 | model User { 18 | id Int @default(autoincrement()) @id 19 | email String @unique 20 | name String? 21 | } 22 | " 23 | `; 24 | -------------------------------------------------------------------------------- /packages/cli-plugin-prisma/src/utils/templateDir.ts: -------------------------------------------------------------------------------- 1 | import {getTemplateDirectory} from "@tsed/cli-core"; 2 | 3 | export const TEMPLATE_DIR = getTemplateDirectory(import.meta.dirname); 4 | -------------------------------------------------------------------------------- /packages/cli-plugin-prisma/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsed/typescript/tsconfig.node.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "rootDir": "src", 6 | "outDir": "./lib/esm", 7 | "declarationDir": "./lib/types", 8 | "declaration": true, 9 | "composite": true, 10 | "noEmit": false, 11 | "sourceMap": false 12 | }, 13 | "include": ["src", "src/**/*.json"], 14 | "exclude": [ 15 | "node_modules", 16 | "test", 17 | "lib", 18 | "benchmark", 19 | "coverage", 20 | "spec", 21 | "**/*.benchmark.ts", 22 | "**/*.spec.ts", 23 | "keys", 24 | "**/__mock__/**", 25 | "webpack.config.js" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/cli-plugin-prisma/vitest.config.mts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import {presets} from "@tsed/vitest/presets"; 3 | import {defineConfig} from "vitest/config"; 4 | 5 | export default defineConfig( 6 | { 7 | ...presets, 8 | test: { 9 | ...presets.test, 10 | coverage: { 11 | ...presets.test.coverage, 12 | thresholds: { 13 | statements: 0, 14 | branches: 0, 15 | functions: 0, 16 | lines: 0 17 | } 18 | } 19 | } 20 | } 21 | ); 22 | -------------------------------------------------------------------------------- /packages/cli-plugin-typegraphql/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | coverage 4 | tsconfig.json 5 | tsconfig.*.json 6 | __mock__ 7 | *.spec.js 8 | *.tsbuildinfo 9 | src 10 | vitest.config.mts -------------------------------------------------------------------------------- /packages/cli-plugin-typegraphql/scripts/templateDir.esm.js: -------------------------------------------------------------------------------- 1 | import path from "node:path"; 2 | import {fileURLToPath} from "node:url"; 3 | 4 | import {getTemplateDirectory} from "@tsed/cli-core"; 5 | 6 | export const TEMPLATE_DIR = getTemplateDirectory(path.dirname(fileURLToPath(import.meta.url))); 7 | -------------------------------------------------------------------------------- /packages/cli-plugin-typegraphql/src/TypeGraphqlModule.ts: -------------------------------------------------------------------------------- 1 | import {inject, Module, OnAdd, ProjectPackageJson} from "@tsed/cli-core"; 2 | import {Inject} from "@tsed/di"; 3 | 4 | import {TypeGraphqlInitHook} from "./hooks/TypeGraphqlInitHook.js"; 5 | 6 | @Module({ 7 | imports: [TypeGraphqlInitHook] 8 | }) 9 | export class TypeGraphqlModule { 10 | protected packageJson = inject(ProjectPackageJson); 11 | 12 | @OnAdd("@tsed/cli-plugin-typegraphql") 13 | install(ctx: any) { 14 | this.packageJson.addDependencies( 15 | { 16 | "@tsed/typegraphql": "{{tsedVersion}}", 17 | "apollo-datasource": "^3.3.1", 18 | "apollo-datasource-rest": "^3.5.1", 19 | "apollo-server-core": "^3.6.2", 20 | "type-graphql": "^1.1.1", 21 | "class-validator": "^0.13.2", 22 | graphql: "^15.7.2" 23 | }, 24 | ctx 25 | ); 26 | this.packageJson.addDevDependencies( 27 | { 28 | "@types/validator": "latest", 29 | "apollo-server-testing": "latest" 30 | }, 31 | ctx 32 | ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/cli-plugin-typegraphql/src/index.ts: -------------------------------------------------------------------------------- 1 | import {TypeGraphqlModule} from "./TypeGraphqlModule.js"; 2 | 3 | export * from "./hooks/TypeGraphqlInitHook.js"; 4 | export * from "./utils/templateDir.js"; 5 | 6 | export default TypeGraphqlModule; 7 | -------------------------------------------------------------------------------- /packages/cli-plugin-typegraphql/src/utils/templateDir.ts: -------------------------------------------------------------------------------- 1 | import {getTemplateDirectory} from "@tsed/cli-core"; 2 | 3 | export const TEMPLATE_DIR = getTemplateDirectory(import.meta.dirname); 4 | -------------------------------------------------------------------------------- /packages/cli-plugin-typegraphql/templates/init/src/datasources/MyDataSource.ts: -------------------------------------------------------------------------------- 1 | import {DataSourceService} from "@tsed/typegraphql"; 2 | import {RESTDataSource} from "apollo-datasource-rest"; 3 | 4 | @DataSourceService() 5 | export class MyDataSource extends RESTDataSource { 6 | constructor() { 7 | super(); 8 | this.baseURL = "http://localhost:8001"; 9 | } 10 | 11 | willSendRequest(request: any) { 12 | request.headers.set("Authorization", this.context.token); 13 | } 14 | 15 | getMyData(id: string) { 16 | return this.get(`/rest/calendars/${id}`); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/cli-plugin-typegraphql/templates/init/src/datasources/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./MyDataSource.js"; 2 | -------------------------------------------------------------------------------- /packages/cli-plugin-typegraphql/templates/init/src/resolvers/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./recipes/Recipe.js"; 2 | export * from "./recipes/RecipeNotFoundError.js"; 3 | export * from "./recipes/RecipeResolver.js"; 4 | -------------------------------------------------------------------------------- /packages/cli-plugin-typegraphql/templates/init/src/resolvers/recipes/Recipe.ts: -------------------------------------------------------------------------------- 1 | import {Field, ID, ObjectType} from "type-graphql"; 2 | 3 | @ObjectType({description: "Object representing cooking recipe"}) 4 | export class Recipe { 5 | @Field((type) => ID) 6 | id: string; 7 | 8 | @Field() 9 | title: string; 10 | 11 | @Field({nullable: true}) 12 | description?: string; 13 | 14 | @Field() 15 | creationDate: Date; 16 | 17 | @Field((type) => [String]) 18 | ingredients: string[]; 19 | 20 | constructor(options: Partial = {}) { 21 | options.id && (this.id = options.id); 22 | options.title && (this.title = options.title); 23 | options.description && (this.description = options.description); 24 | options.creationDate && (this.creationDate = options.creationDate); 25 | options.ingredients && (this.ingredients = options.ingredients); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/cli-plugin-typegraphql/templates/init/src/resolvers/recipes/RecipeNotFoundError.ts: -------------------------------------------------------------------------------- 1 | import {NotFound} from "@tsed/exceptions"; 2 | 3 | export class RecipeNotFoundError extends NotFound { 4 | constructor(private id: string) { 5 | super("Recipe not found"); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/cli-plugin-typegraphql/templates/init/src/resolvers/recipes/RecipeResolver.ts: -------------------------------------------------------------------------------- 1 | import {ResolverService} from "@tsed/typegraphql"; 2 | import {Arg, Query} from "type-graphql"; 3 | import {RecipeService} from "../../services/RecipeService.js"; 4 | import {Recipe} from "./Recipe.js"; 5 | import {RecipeNotFoundError} from "./RecipeNotFoundError.js"; 6 | 7 | @ResolverService(Recipe) 8 | export class RecipeResolver { 9 | constructor(private recipeService: RecipeService) {} 10 | 11 | @Query((returns) => Recipe) 12 | async recipe(@Arg("id") id: string) { 13 | const recipe = await this.recipeService.findById(id); 14 | 15 | if (recipe === undefined) { 16 | throw new RecipeNotFoundError(id); 17 | } 18 | 19 | return recipe; 20 | } 21 | 22 | @Query((returns) => [Recipe], {description: "Get all the recipes from around the world "}) 23 | recipes(): Promise { 24 | return this.recipeService.findAll({}); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/cli-plugin-typegraphql/templates/init/src/services/RecipeService.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from "@tsed/di"; 2 | import {Recipe} from "../resolvers.js"; 3 | 4 | @Injectable() 5 | export class RecipeService { 6 | findById(id: string) { 7 | return new Recipe({id}) 8 | } 9 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 10 | findAll(query: any) { 11 | return [] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/cli-plugin-typegraphql/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsed/typescript/tsconfig.node.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "rootDir": "src", 6 | "outDir": "./lib/esm", 7 | "declarationDir": "./lib/types", 8 | "declaration": true, 9 | "composite": true, 10 | "noEmit": false, 11 | "sourceMap": false 12 | }, 13 | "include": ["src", "src/**/*.json"], 14 | "exclude": [ 15 | "node_modules", 16 | "test", 17 | "lib", 18 | "benchmark", 19 | "coverage", 20 | "spec", 21 | "**/*.benchmark.ts", 22 | "**/*.spec.ts", 23 | "keys", 24 | "**/__mock__/**", 25 | "webpack.config.js" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/cli-plugin-typegraphql/vitest.config.mts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import {presets} from "@tsed/vitest/presets"; 3 | import {defineConfig} from "vitest/config"; 4 | 5 | export default defineConfig( 6 | { 7 | ...presets, 8 | test: { 9 | ...presets.test, 10 | coverage: { 11 | ...presets.test.coverage, 12 | thresholds: { 13 | statements: 0, 14 | branches: 0, 15 | functions: 0, 16 | lines: 0 17 | } 18 | } 19 | } 20 | } 21 | ); 22 | -------------------------------------------------------------------------------- /packages/cli-plugin-typeorm/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | coverage 4 | tsconfig.json 5 | tsconfig.*.json 6 | __mock__ 7 | *.spec.js 8 | *.tsbuildinfo 9 | src 10 | vitest.config.mts -------------------------------------------------------------------------------- /packages/cli-plugin-typeorm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tsed/cli-plugin-typeorm", 3 | "description": "Ts.ED CLI plugin. Add TypeORM support", 4 | "version": "6.4.3", 5 | "type": "module", 6 | "main": "./lib/esm/index.js", 7 | "source": "./src/index.ts", 8 | "module": "./lib/esm/index.js", 9 | "typings": "./lib/types/index.d.ts", 10 | "exports": { 11 | ".": { 12 | "cli-tsed-source": "./src/index.ts", 13 | "types": "./lib/types/index.d.ts", 14 | "import": "./lib/esm/index.js", 15 | "default": "./lib/esm/index.js" 16 | } 17 | }, 18 | "scripts": { 19 | "build": "yarn build:ts", 20 | "build:ts": "tsc --build tsconfig.esm.json", 21 | "test": "vitest run", 22 | "test:ci": "vitest run --coverage.thresholds.autoUpdate=true" 23 | }, 24 | "dependencies": { 25 | "change-case": "5.4.4", 26 | "tslib": "2.7.0" 27 | }, 28 | "devDependencies": { 29 | "@tsed/cli": "workspace:*", 30 | "@tsed/cli-core": "workspace:*", 31 | "@tsed/typescript": "workspace:*", 32 | "cross-env": "7.0.3", 33 | "typescript": "5.6.2", 34 | "vitest": "3.0.9" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/cli-plugin-typeorm/scripts/templateDir.esm.js: -------------------------------------------------------------------------------- 1 | import path from "node:path"; 2 | import {fileURLToPath} from "node:url"; 3 | 4 | import {getTemplateDirectory} from "@tsed/cli-core"; 5 | 6 | export const TEMPLATE_DIR = getTemplateDirectory(path.dirname(fileURLToPath(import.meta.url))); 7 | -------------------------------------------------------------------------------- /packages/cli-plugin-typeorm/src/CliPluginTypeORMModule.ts: -------------------------------------------------------------------------------- 1 | import {inject, Module, OnAdd, ProjectPackageJson} from "@tsed/cli-core"; 2 | 3 | import {TypeORMGenerateHook} from "./hooks/TypeORMGenerateHook.js"; 4 | import {TypeORMInitHook} from "./hooks/TypeORMInitHook.js"; 5 | 6 | @Module({ 7 | imports: [TypeORMInitHook, TypeORMGenerateHook] 8 | }) 9 | export class CliPluginTypeORMModule { 10 | protected packageJson = inject(ProjectPackageJson); 11 | 12 | @OnAdd("@tsed/cli-plugin-typeorm") 13 | install() { 14 | this.packageJson.addDependencies({ 15 | typeorm: "latest" 16 | }); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/cli-plugin-typeorm/src/index.ts: -------------------------------------------------------------------------------- 1 | import {CliPluginTypeORMModule} from "./CliPluginTypeORMModule.js"; 2 | 3 | export * from "./hooks/TypeORMGenerateHook.js"; 4 | export * from "./hooks/TypeORMInitHook.js"; 5 | export * from "./utils/templateDir.js"; 6 | 7 | export default CliPluginTypeORMModule; 8 | -------------------------------------------------------------------------------- /packages/cli-plugin-typeorm/src/utils/templateDir.ts: -------------------------------------------------------------------------------- 1 | import {getTemplateDirectory} from "@tsed/cli-core"; 2 | 3 | export const TEMPLATE_DIR = getTemplateDirectory(import.meta.dirname); 4 | -------------------------------------------------------------------------------- /packages/cli-plugin-typeorm/test/integrations/generate/data/TestDatasource.ts.txt: -------------------------------------------------------------------------------- 1 | import {registerProvider} from "@tsed/di"; 2 | import {DataSource} from "typeorm"; 3 | import {Logger} from "@tsed/logger"; 4 | 5 | export const TEST_DATA_SOURCE = Symbol.for("TestDataSource"); 6 | export const TestDataSource = new DataSource({ 7 | type: "mysql", 8 | entities: [], 9 | host: "localhost", 10 | port: 3306, 11 | username: "test", 12 | password: "test", 13 | database: "test" 14 | }); 15 | 16 | registerProvider({ 17 | provide: TEST_DATA_SOURCE, 18 | type: "typeorm:datasource", 19 | deps: [Logger], 20 | async useAsyncFactory(logger: Logger) { 21 | await TestDataSource.initialize(); 22 | 23 | logger.info("Connected with typeorm to database: Test"); 24 | 25 | return TestDataSource; 26 | }, 27 | hooks: { 28 | $onDestroy(dataSource) { 29 | return dataSource.isInitialized && dataSource.close(); 30 | } 31 | } 32 | }); 33 | -------------------------------------------------------------------------------- /packages/cli-plugin-typeorm/test/integrations/generate/data/docker-compose.yml.txt: -------------------------------------------------------------------------------- 1 | services: 2 | test: 3 | image: mysql:8.0.28-oracle 4 | ports: 5 | - '3306:3306' 6 | environment: 7 | MYSQL_ROOT_PASSWORD: admin 8 | MYSQL_USER: test 9 | MYSQL_PASSWORD: test 10 | MYSQL_DATABASE: test 11 | -------------------------------------------------------------------------------- /packages/cli-plugin-typeorm/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsed/typescript/tsconfig.node.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "rootDir": "src", 6 | "outDir": "./lib/esm", 7 | "declarationDir": "./lib/types", 8 | "declaration": true, 9 | "composite": true, 10 | "noEmit": false, 11 | "sourceMap": false 12 | }, 13 | "include": ["src", "src/**/*.json"], 14 | "exclude": [ 15 | "node_modules", 16 | "test", 17 | "lib", 18 | "benchmark", 19 | "coverage", 20 | "spec", 21 | "**/*.benchmark.ts", 22 | "**/*.spec.ts", 23 | "keys", 24 | "**/__mock__/**", 25 | "webpack.config.js" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/cli-plugin-typeorm/vitest.config.mts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import {presets} from "@tsed/vitest/presets"; 3 | import {defineConfig} from "vitest/config"; 4 | 5 | export default defineConfig( 6 | { 7 | ...presets, 8 | test: { 9 | ...presets.test, 10 | coverage: { 11 | ...presets.test.coverage, 12 | thresholds: { 13 | statements: 0, 14 | branches: 0, 15 | functions: 0, 16 | lines: 0 17 | } 18 | } 19 | } 20 | } 21 | ); 22 | -------------------------------------------------------------------------------- /packages/cli-plugin-vitest/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | coverage 4 | tsconfig.json 5 | tsconfig.*.json 6 | __mock__ 7 | *.spec.js 8 | *.tsbuildinfo 9 | src 10 | vitest.config.mts -------------------------------------------------------------------------------- /packages/cli-plugin-vitest/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tsed/cli-plugin-vitest", 3 | "description": "Ts.ED CLI plugin. Add Jest support", 4 | "version": "6.4.3", 5 | "type": "module", 6 | "main": "./lib/esm/index.js", 7 | "source": "./src/index.ts", 8 | "module": "./lib/esm/index.js", 9 | "typings": "./lib/types/index.d.ts", 10 | "exports": { 11 | ".": { 12 | "cli-tsed-source": "./src/index.ts", 13 | "types": "./lib/types/index.d.ts", 14 | "import": "./lib/esm/index.js", 15 | "default": "./lib/esm/index.js" 16 | } 17 | }, 18 | "scripts": { 19 | "build": "yarn build:ts", 20 | "build:ts": "tsc --build tsconfig.esm.json", 21 | "test": "vitest run", 22 | "test:ci": "vitest run --coverage.thresholds.autoUpdate=true" 23 | }, 24 | "devDependencies": { 25 | "@tsed/cli": "workspace:*", 26 | "@tsed/cli-core": "workspace:*", 27 | "@tsed/typescript": "workspace:*", 28 | "cross-env": "7.0.3", 29 | "typescript": "5.6.2", 30 | "vitest": "3.0.9" 31 | }, 32 | "dependencies": { 33 | "tslib": "2.7.0" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/cli-plugin-vitest/scripts/templateDir.esm.js: -------------------------------------------------------------------------------- 1 | import path from "node:path"; 2 | import {fileURLToPath} from "node:url"; 3 | 4 | import {getTemplateDirectory} from "@tsed/cli-core"; 5 | 6 | export const TEMPLATE_DIR = getTemplateDirectory(path.dirname(fileURLToPath(import.meta.url))); 7 | -------------------------------------------------------------------------------- /packages/cli-plugin-vitest/src/hooks/VitestInitHook.ts: -------------------------------------------------------------------------------- 1 | import {RootRendererService} from "@tsed/cli"; 2 | import {inject, Injectable, OnExec, ProjectPackageJson} from "@tsed/cli-core"; 3 | 4 | import {TEMPLATE_DIR} from "../utils/templateDir.js"; 5 | 6 | @Injectable() 7 | export class VitestInitHook { 8 | protected packageJson = inject(ProjectPackageJson); 9 | protected rootRenderer = inject(RootRendererService); 10 | 11 | @OnExec("init") 12 | onInitExec() { 13 | return [ 14 | { 15 | title: "Generate files for vitest", 16 | task: (ctx: any) => { 17 | return this.rootRenderer.renderAll(["vitest.config.mts.hbs"], ctx, { 18 | templateDir: `${TEMPLATE_DIR}/init` 19 | }); 20 | } 21 | } 22 | ]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/cli-plugin-vitest/src/index.ts: -------------------------------------------------------------------------------- 1 | import {CliPluginVitestModule} from "./CliPluginVitestModule.js"; 2 | 3 | export * from "./utils/templateDir.js"; 4 | 5 | export default CliPluginVitestModule; 6 | -------------------------------------------------------------------------------- /packages/cli-plugin-vitest/src/utils/templateDir.ts: -------------------------------------------------------------------------------- 1 | import {getTemplateDirectory} from "@tsed/cli-core"; 2 | 3 | export const TEMPLATE_DIR = getTemplateDirectory(import.meta.dirname); 4 | -------------------------------------------------------------------------------- /packages/cli-plugin-vitest/templates/generate/decorator.class.spec.hbs: -------------------------------------------------------------------------------- 1 | import { expect, describe, it } from "vitest"; 2 | import { {{symbolName}} } from "./{{symbolPathBasename}}.js"; 3 | 4 | describe("{{symbolName}}", () => { 5 | it("should do something", () => { 6 | @{{symbolName}}({}) 7 | class Test { 8 | } 9 | 10 | expect(typeof {{symbolName}}).toBe("function") 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/cli-plugin-vitest/templates/generate/decorator.endpoint.spec.hbs: -------------------------------------------------------------------------------- 1 | import { expect, describe, it } from "vitest"; 2 | import { Store } from "@tsed/core"; 3 | import { {{symbolName}} } from "./{{symbolPathBasename}}.js"; 4 | 5 | describe("{{symbolName}}", () => { 6 | it("should store options", () => { 7 | class Test { 8 | @{{symbolName}}({options: "options"}) 9 | method() param: string){} 10 | } 11 | 12 | const store = Store.fromMethod(Test, "method"); 13 | 14 | expect(store.get({{symbolName}})).toEqual({options: "options"}); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/cli-plugin-vitest/templates/generate/decorator.method.spec.hbs: -------------------------------------------------------------------------------- 1 | import { expect, describe, it } from "vitest"; 2 | import { {{symbolName}} } from "./{{symbolPathBasename}}.js"; 3 | 4 | describe("{{symbolName}}", () => { 5 | it("should do something", () => { 6 | class Test { 7 | @{{symbolName}}({}) 8 | method(){} 9 | } 10 | 11 | expect(typeof {{symbolName}}).toBe("function") 12 | expect(typeof {{symbolName}}()).toBe("function") 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/cli-plugin-vitest/templates/generate/decorator.param.spec.hbs: -------------------------------------------------------------------------------- 1 | import { expect, describe, it } from "vitest"; 2 | import { Store } from "@tsed/core"; 3 | import { {{symbolName}} } from "./{{symbolPathBasename}}.js"; 4 | 5 | describe("{{symbolName}}", () => { 6 | it("should store options", () => { 7 | class Test { 8 | method(@{{symbolName}}({options: "options"}) param: string){} 9 | } 10 | 11 | const store = Store.from(Test, "method", 0) 12 | 13 | expect(store.get({{symbolName}})).toEqual({options: "options"}); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/cli-plugin-vitest/templates/generate/decorator.parameter.spec.hbs: -------------------------------------------------------------------------------- 1 | import { expect, describe, it } from "vitest"; 2 | import { {{symbolName}} } from "./{{symbolPathBasename}}.js"; 3 | 4 | describe("{{symbolName}}", () => { 5 | it("should do something", () => { 6 | class Test { 7 | method(@{{symbolName}}({}) param: string){} 8 | } 9 | 10 | expect(typeof {{symbolName}}).toBe("function") 11 | expect(typeof {{symbolName}}()).toBe("function") 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /packages/cli-plugin-vitest/templates/generate/decorator.prop.spec.hbs: -------------------------------------------------------------------------------- 1 | import { expect, describe, it } from "vitest"; 2 | import { Store } from "@tsed/core"; 3 | import { {{symbolName}} } from "./{{symbolPathBasename}}.js"; 4 | 5 | describe("{{symbolName}}", () => { 6 | it("should store options", () => { 7 | class Test { 8 | @{{symbolName}}({options: "options"}) 9 | property: string; 10 | } 11 | 12 | const store = Store.from(Test, "property"); 13 | 14 | expect(store.get({{symbolName}})).toEqual({options: "options"}); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/cli-plugin-vitest/templates/generate/decorator.property.spec.hbs: -------------------------------------------------------------------------------- 1 | import { expect, describe, it } from "vitest"; 2 | import { {{symbolName}} } from "./{{symbolPathBasename}}.js"; 3 | 4 | describe("{{symbolName}}", () => { 5 | it("should do something", () => { 6 | class Test { 7 | @{{symbolName}}({}) 8 | property: string; 9 | } 10 | 11 | expect(typeof {{symbolName}}).toBe("function") 12 | expect(typeof {{symbolName}}()).toBe("function") 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/cli-plugin-vitest/templates/generate/generic.integration.hbs: -------------------------------------------------------------------------------- 1 | import { expect, describe, it, afterAll, beforeAll } from "vitest"; 2 | import { PlatformTest } from "@tsed/platform-http/testing"; 3 | import SuperTest from "supertest"; 4 | import { {{symbolName}} } from "./{{symbolPathBasename}}.js"; 5 | import { Server } from "{{relativeSrcPath}}/Server.js"; 6 | 7 | describe("{{symbolName}}", () => { 8 | beforeAll(PlatformTest.bootstrap(Server, { 9 | mount: { 10 | "/": [{{symbolName}}] 11 | } 12 | })); 13 | afterAll(PlatformTest.reset); 14 | 15 | it("should call GET {{route}}", async () => { 16 | const request = SuperTest(PlatformTest.callback()); 17 | const response = await request.get("{{route}}").expect(200); 18 | 19 | expect(response.text).toEqual("hello"); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/cli-plugin-vitest/templates/generate/generic.spec.hbs: -------------------------------------------------------------------------------- 1 | import { expect, describe, it, beforeEach, afterEach } from "vitest"; 2 | import { PlatformTest } from "@tsed/platform-http/testing"; 3 | import { {{symbolName}} } from "./{{symbolPathBasename}}.js"; 4 | 5 | describe("{{symbolName}}", () => { 6 | beforeEach(PlatformTest.create); 7 | afterEach(PlatformTest.reset); 8 | 9 | it("should do something", () => { 10 | const instance = PlatformTest.get<{{symbolName}}>({{symbolName}}); 11 | // const instance = PlatformTest.invoke<{{symbolName}}>({{symbolName}}); // get fresh instance 12 | 13 | expect(instance).toBeInstanceOf({{symbolName}}); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/cli-plugin-vitest/templates/generate/server.integration.hbs: -------------------------------------------------------------------------------- 1 | import { expect, describe, it, beforeAll, afterAll } from "vitest"; 2 | import { PlatformTest } from "@tsed/platform-http/testing"; 3 | import SuperTest from "supertest"; 4 | import { {{symbolName}} } from "./{{symbolPathBasename}}.js"; 5 | 6 | describe("{{symbolName}}", () => { 7 | beforeAll(PlatformTest.bootstrap({{symbolName}})); 8 | afterAll(PlatformTest.reset); 9 | 10 | it("should call GET {{route}}", async () => { 11 | const request = SuperTest(PlatformTest.callback()); 12 | const response = await request.get("{{route}}").expect(404); 13 | 14 | expect(response.body).toEqual({ 15 | errors: [], 16 | message: 'Resource "/rest" not found', 17 | name: "NOT_FOUND", 18 | status: 404, 19 | }); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/cli-plugin-vitest/templates/init/vitest.config.mts.hbs: -------------------------------------------------------------------------------- 1 | import swc from "unplugin-swc"; 2 | import {defineConfig} from "vitest/config"; 3 | 4 | export default defineConfig({ 5 | test: { 6 | globals: true, 7 | root: "./" 8 | }, 9 | plugins: [ 10 | // This is required to build the test files with SWC 11 | swc.vite({ 12 | // Explicitly set the module type to avoid inheriting this value from a `.swcrc` config file 13 | module: {type: "es6"}, 14 | jsc: { 15 | transform: { 16 | useDefineForClassFields: false 17 | } 18 | } 19 | }) 20 | ] 21 | }); 22 | -------------------------------------------------------------------------------- /packages/cli-plugin-vitest/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsed/typescript/tsconfig.node.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "rootDir": "src", 6 | "outDir": "./lib/esm", 7 | "declarationDir": "./lib/types", 8 | "declaration": true, 9 | "composite": true, 10 | "noEmit": false, 11 | "sourceMap": false 12 | }, 13 | "include": ["src", "src/**/*.json"], 14 | "exclude": [ 15 | "node_modules", 16 | "test", 17 | "lib", 18 | "benchmark", 19 | "coverage", 20 | "spec", 21 | "**/*.benchmark.ts", 22 | "**/*.spec.ts", 23 | "keys", 24 | "**/__mock__/**", 25 | "webpack.config.js" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/cli-plugin-vitest/vitest.config.mts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import {presets} from "@tsed/vitest/presets"; 3 | import {defineConfig} from "vitest/config"; 4 | 5 | export default defineConfig( 6 | { 7 | ...presets, 8 | test: { 9 | ...presets.test, 10 | coverage: { 11 | ...presets.test.coverage, 12 | thresholds: { 13 | statements: 0, 14 | branches: 0, 15 | functions: 0, 16 | lines: 0 17 | } 18 | } 19 | } 20 | } 21 | ); 22 | -------------------------------------------------------------------------------- /packages/cli-testing/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | coverage 4 | tsconfig.json 5 | tsconfig.*.json 6 | __mock__ 7 | *.spec.js 8 | *.tsbuildinfo 9 | src 10 | vitest.config.mts -------------------------------------------------------------------------------- /packages/cli-testing/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tsed/cli-testing", 3 | "description": "Utils to test you CLI based on Ts.ED CLI", 4 | "version": "6.4.3", 5 | "type": "module", 6 | "main": "./lib/esm/index.js", 7 | "source": "./src/index.ts", 8 | "module": "./lib/esm/index.js", 9 | "typings": "./lib/types/index.d.ts", 10 | "exports": { 11 | ".": { 12 | "cli-tsed-source": "./src/index.ts", 13 | "types": "./lib/types/index.d.ts", 14 | "import": "./lib/esm/index.js", 15 | "default": "./lib/esm/index.js" 16 | } 17 | }, 18 | "scripts": { 19 | "build": "yarn build:ts", 20 | "build:ts": "tsc --build tsconfig.esm.json" 21 | }, 22 | "keywords": [ 23 | "Ts.ED", 24 | "cli", 25 | "typescript", 26 | "framework", 27 | "rest", 28 | "api", 29 | "express", 30 | "decorators" 31 | ], 32 | "dependencies": { 33 | "@tsed/cli-core": "workspace:*", 34 | "tslib": "2.7.0" 35 | }, 36 | "devDependencies": { 37 | "@tsed/typescript": "workspace:*", 38 | "cross-env": "7.0.3", 39 | "typescript": "5.6.2", 40 | "vitest": "3.0.9" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /packages/cli-testing/src/FakeCliExeca.ts: -------------------------------------------------------------------------------- 1 | import {CliExeca} from "@tsed/cli-core"; 2 | import {Observable} from "rxjs"; 3 | 4 | export class FakeCliExeca extends CliExeca { 5 | static entries = new Map(); 6 | 7 | run(cmd: string, args: string[], opts?: any): any { 8 | const result = FakeCliExeca.entries.get(cmd + " " + args.join(" ")); 9 | 10 | return new Observable((observer) => { 11 | observer.next(result); 12 | observer.complete(); 13 | }); 14 | } 15 | 16 | getAsync(cmd: string, args: string[], opts?: any): Promise { 17 | if (["npm"].includes(cmd) && args.includes("view")) { 18 | return Promise.resolve( 19 | JSON.stringify({ 20 | "dist-tags": { 21 | latest: "1.0.0" 22 | } 23 | }) 24 | ); 25 | } 26 | 27 | return Promise.resolve(FakeCliExeca.entries.get(cmd + " " + args.join(" "))); 28 | } 29 | 30 | runSync(cmd: string, args: string[], opts?: any): any { 31 | return { 32 | stdout: FakeCliExeca.entries.get(cmd + " " + args.join(" ")) 33 | }; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/cli-testing/src/FakeCliHttpClient.ts: -------------------------------------------------------------------------------- 1 | import {CliHttpClient, type CliHttpClientOptions} from "@tsed/cli-core"; 2 | import type {OnDestroy} from "@tsed/di"; 3 | 4 | export class FakeCliHttpClient extends CliHttpClient implements OnDestroy { 5 | static entries = new Map(); 6 | 7 | get(endpoint: string, options: CliHttpClientOptions = {}): Promise { 8 | const key = endpoint + ":" + JSON.stringify(options); 9 | 10 | if (key.includes("https://registry.")) { 11 | return Promise.resolve({ 12 | "dist-tags": { 13 | latest: "1.0.0" 14 | } 15 | }); 16 | } 17 | 18 | if (!FakeCliHttpClient.entries.has(key)) { 19 | process.stdout.write("Entries missing for FakeCliHttpClient: " + key + "\n"); 20 | } 21 | 22 | return FakeCliHttpClient.entries.get(key)?.(endpoint, options); 23 | } 24 | 25 | $onDestroy() { 26 | FakeCliHttpClient.entries.clear(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/cli-testing/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./CliPlatformTest.js"; 2 | export * from "./FakeCliFs.js"; 3 | export * from "./FakeCliHttpClient.js"; 4 | export * from "./normalizePath.js"; 5 | -------------------------------------------------------------------------------- /packages/cli-testing/src/normalizePath.ts: -------------------------------------------------------------------------------- 1 | import {isString} from "@tsed/core"; 2 | import {normalizePath as n} from "@tsed/normalize-path"; 3 | 4 | export function normalizePath(item: any) { 5 | if (isString(item)) { 6 | return n(item); 7 | } 8 | 9 | return item.map(normalizePath); 10 | } 11 | -------------------------------------------------------------------------------- /packages/cli-testing/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsed/typescript/tsconfig.node.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "rootDir": "src", 6 | "outDir": "./lib/esm", 7 | "declarationDir": "./lib/types", 8 | "declaration": true, 9 | "composite": true, 10 | "noEmit": false, 11 | "sourceMap": false 12 | }, 13 | "include": ["src", "src/**/*.json"], 14 | "exclude": [ 15 | "node_modules", 16 | "test", 17 | "lib", 18 | "benchmark", 19 | "coverage", 20 | "spec", 21 | "**/*.benchmark.ts", 22 | "**/*.spec.ts", 23 | "keys", 24 | "**/__mock__/**", 25 | "webpack.config.js" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/cli-testing/vitest.config.mts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import {presets} from "@tsed/vitest/presets"; 3 | import {defineConfig} from "vitest/config"; 4 | 5 | export default defineConfig( 6 | { 7 | ...presets, 8 | test: { 9 | ...presets.test, 10 | coverage: { 11 | ...presets.test.coverage, 12 | thresholds: { 13 | statements: 0, 14 | branches: 0, 15 | functions: 0, 16 | lines: 0 17 | } 18 | } 19 | } 20 | } 21 | ); 22 | -------------------------------------------------------------------------------- /packages/cli/.gitignore: -------------------------------------------------------------------------------- 1 | .tmp 2 | test/integrations/init/data/project-name -------------------------------------------------------------------------------- /packages/cli/.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | coverage 4 | tsconfig.json 5 | tsconfig.*.json 6 | __mock__ 7 | *.spec.js 8 | *.tsbuildinfo 9 | -------------------------------------------------------------------------------- /packages/cli/scripts/index.esm.js: -------------------------------------------------------------------------------- 1 | import {dirname, join} from "node:path"; 2 | import {fileURLToPath} from "node:url"; 3 | 4 | import readPkgUp from "read-pkg-up"; 5 | 6 | const {path, packageJson} = readPkgUp.sync({ 7 | cwd: join(fileURLToPath(import.meta.url), "..", "..") 8 | }); 9 | export const PKG = packageJson; 10 | export const MINIMAL_TSED_VERSION = "7"; 11 | export const DEFAULT_TSED_TAGS = "latest"; 12 | export const IGNORE_VERSIONS = ["6.0.0"]; 13 | export const IGNORE_TAGS = false; // /alpha|beta/ 14 | export const TEMPLATE_DIR = join(dirname(path), "templates"); 15 | //# sourceMappingURL=index.js.map 16 | -------------------------------------------------------------------------------- /packages/cli/src/bin/tsed.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import {register} from "node:module"; 3 | import {join} from "node:path"; 4 | import {pathToFileURL} from "node:url"; 5 | 6 | const EXT = process.env.CLI_MODE === "ts" ? "ts" : "js"; 7 | 8 | register(pathToFileURL(join(import.meta.dirname, `../loaders/alias.hook.${EXT}`)), { 9 | parentURL: import.meta.dirname, 10 | data: { 11 | "@tsed/core": import.meta.resolve("@tsed/core"), 12 | "@tsed/di": import.meta.resolve("@tsed/di"), 13 | "@tsed/schema": import.meta.resolve("@tsed/schema"), 14 | "@tsed/cli-core": import.meta.resolve("@tsed/cli-core"), 15 | "@tsed/cli": import.meta.resolve("@tsed/cli") 16 | }, 17 | transferList: [] 18 | }); 19 | 20 | const {Cli} = await import("../Cli.js"); 21 | 22 | Cli.bootstrap({}).catch((error) => { 23 | console.error(error); 24 | process.exit(-1); 25 | }); 26 | -------------------------------------------------------------------------------- /packages/cli/src/commands/index.ts: -------------------------------------------------------------------------------- 1 | import {AddCmd} from "./add/AddCmd.js"; 2 | import {GenerateCmd} from "./generate/GenerateCmd.js"; 3 | import {InitCmd} from "./init/InitCmd.js"; 4 | import {RunCmd} from "./run/RunCmd.js"; 5 | import {UpdateCmd} from "./update/UpdateCmd.js"; 6 | 7 | export default [AddCmd, InitCmd, GenerateCmd, UpdateCmd, RunCmd]; 8 | -------------------------------------------------------------------------------- /packages/cli/src/commands/init/interfaces/InitCmdContext.ts: -------------------------------------------------------------------------------- 1 | import type {CliDefaultOptions} from "@tsed/cli-core"; 2 | 3 | import type {InitOptions} from "./InitOptions.js"; 4 | 5 | export interface InitCmdContext extends InitOptions, CliDefaultOptions, Record { 6 | root: string; 7 | srcDir: string; 8 | } 9 | -------------------------------------------------------------------------------- /packages/cli/src/commands/init/interfaces/InitOptions.ts: -------------------------------------------------------------------------------- 1 | import {PackageManager} from "@tsed/cli-core"; 2 | 3 | import {ArchitectureConvention} from "../../../interfaces/ArchitectureConvention.js"; 4 | import {PlatformType} from "../../../interfaces/PlatformType.js"; 5 | import {ProjectConvention} from "../../../interfaces/ProjectConvention.js"; 6 | import {FeatureType} from "../config/FeaturesPrompt.js"; 7 | 8 | export interface InitOptions { 9 | root: string; 10 | projectName: string; 11 | features: FeatureType[]; 12 | skipPrompt: boolean; 13 | platform: PlatformType; 14 | tsedVersion: string; 15 | cliVersion: string; 16 | architecture: ArchitectureConvention; 17 | convention: ProjectConvention; 18 | packageManager: PackageManager; 19 | runtime: "node" | "babel" | "swc" | "webpack" | "bun"; 20 | oidcBasePath: string; 21 | file: string; 22 | } 23 | -------------------------------------------------------------------------------- /packages/cli/src/commands/init/interfaces/InitPromptAnswers.ts: -------------------------------------------------------------------------------- 1 | import {PackageManager} from "@tsed/cli-core"; 2 | 3 | import {ArchitectureConvention, PlatformType, ProjectConvention} from "../../../interfaces/index.js"; 4 | 5 | export interface InitPromptAnswers { 6 | projectName: string; 7 | platform: PlatformType; 8 | architecture: ArchitectureConvention; 9 | convention: ProjectConvention; 10 | features: string[]; 11 | featuresDB: string[]; 12 | featuresTypeORM: string; 13 | featuresTesting: string; 14 | featuresExtraLinter: string[]; 15 | featuresBundler: string; 16 | oidcBasePath: string; 17 | packageManager: PackageManager; 18 | } 19 | -------------------------------------------------------------------------------- /packages/cli/src/commands/init/mappers/mapToContext.ts: -------------------------------------------------------------------------------- 1 | import {camelCase} from "change-case"; 2 | 3 | import type {InitCmdContext} from "../interfaces/InitCmdContext.js"; 4 | import {mapUniqFeatures} from "./mapUniqFeatures.js"; 5 | 6 | export function mapToContext(options: any): InitCmdContext { 7 | options = mapUniqFeatures(options); 8 | 9 | options.features.forEach((feature: string) => { 10 | feature.split(":").forEach((type) => { 11 | options[camelCase(type)] = true; 12 | }); 13 | }); 14 | 15 | return options; 16 | } 17 | -------------------------------------------------------------------------------- /packages/cli/src/commands/init/mappers/mapUniqFeatures.ts: -------------------------------------------------------------------------------- 1 | import {FeatureType} from "../config/FeaturesPrompt.js"; 2 | import type {InitOptions} from "../interfaces/InitOptions.js"; 3 | import type {InitPromptAnswers} from "../interfaces/InitPromptAnswers.js"; 4 | 5 | export function mapUniqFeatures(answers: InitPromptAnswers & any): InitOptions { 6 | const features: string[] = []; 7 | 8 | Object.entries(answers) 9 | .filter(([key]) => key.startsWith("features")) 10 | .forEach(([key, value]: any[]) => { 11 | delete answers[key]; 12 | features.push(...[].concat(value)); 13 | }); 14 | 15 | return { 16 | ...answers, 17 | features: [...new Set(features).values()] as FeatureType[] 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /packages/cli/src/commands/init/utils/hasFeature.spec.ts: -------------------------------------------------------------------------------- 1 | import {hasFeature, hasValue} from "./hasFeature.js"; 2 | 3 | describe("hasValue", () => { 4 | it("should return false", () => { 5 | expect(hasValue("featuresDb.type", "")({featuresDb: {type: "test"}})).toEqual(false); 6 | }); 7 | it("should return true", () => { 8 | expect(hasValue("featuresDb.type", "test")({featuresDb: {type: "test"}})).toEqual(true); 9 | }); 10 | }); 11 | 12 | describe("hasFeature", () => { 13 | it("should return false", () => { 14 | expect(hasFeature("feat")({features: []})).toEqual(false); 15 | }); 16 | it("should return true", () => { 17 | expect( 18 | hasFeature("feat")({ 19 | features: ["feat"] 20 | }) 21 | ).toEqual(true); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /packages/cli/src/commands/init/utils/hasFeature.ts: -------------------------------------------------------------------------------- 1 | import {getValue} from "@tsed/core"; 2 | 3 | export function hasValue(expression: string, value: string | string[]) { 4 | return (ctx: any) => [].concat(value as any).includes(getValue(expression, ctx)!); 5 | } 6 | 7 | export function hasFeature(feature: string) { 8 | return (ctx: any): boolean => !!ctx.features.find((item: string) => item === feature); 9 | } 10 | -------------------------------------------------------------------------------- /packages/cli/src/commands/init/utils/isPlatform.ts: -------------------------------------------------------------------------------- 1 | export function isPlatform(...types: string[]) { 2 | return (ctx: any) => [types].includes(ctx.platform); 3 | } 4 | -------------------------------------------------------------------------------- /packages/cli/src/constants/index.ts: -------------------------------------------------------------------------------- 1 | import {dirname, join} from "node:path"; 2 | 3 | import {readPackageUpSync} from "read-pkg-up"; 4 | 5 | const {path, packageJson} = readPackageUpSync({ 6 | cwd: join(import.meta.dirname, "..", "..") 7 | })!; 8 | 9 | export const PKG = packageJson; 10 | export const MINIMAL_TSED_VERSION = "8"; 11 | export const DEFAULT_TSED_TAGS = "latest"; 12 | export const IGNORE_VERSIONS = ["6.0.0"]; 13 | export const IGNORE_TAGS: false | RegExp = false; // /alpha|beta/ 14 | export const TEMPLATE_DIR = join(dirname(path), "templates"); 15 | -------------------------------------------------------------------------------- /packages/cli/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./Cli.js"; 2 | export * from "./commands/add/AddCmd.js"; 3 | export * from "./commands/generate/GenerateCmd.js"; 4 | export * from "./commands/init/config/FeaturesPrompt.js"; 5 | export * from "./commands/init/config/FeaturesPrompt.js"; 6 | export * from "./commands/init/InitCmd.js"; 7 | export * from "./commands/init/interfaces/InitCmdContext.js"; 8 | export * from "./commands/init/interfaces/InitOptions.js"; 9 | export * from "./commands/init/prompts/getFeaturesPrompt.js"; 10 | export * from "./commands/update/UpdateCmd.js"; 11 | export * from "./constants/index.js"; 12 | export * from "./interfaces/index.js"; 13 | export * from "./pipes/index.js"; 14 | export * from "./runtimes/index.js"; 15 | export * from "./services/ProvidersInfoService.js"; 16 | export * from "./services/Renderer.js"; 17 | -------------------------------------------------------------------------------- /packages/cli/src/interfaces/ArchitectureConvention.ts: -------------------------------------------------------------------------------- 1 | export enum ArchitectureConvention { 2 | DEFAULT = "arc_default", 3 | FEATURE = "feature" 4 | } 5 | 6 | declare global { 7 | namespace TsED { 8 | interface ProjectPreferences { 9 | architecture: ArchitectureConvention; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/cli/src/interfaces/PlatformType.ts: -------------------------------------------------------------------------------- 1 | export enum PlatformType { 2 | EXPRESS = "express", 3 | KOA = "koa", 4 | FASTIFY = "fastify" 5 | } 6 | -------------------------------------------------------------------------------- /packages/cli/src/interfaces/ProjectConvention.ts: -------------------------------------------------------------------------------- 1 | export enum ProjectConvention { 2 | DEFAULT = "conv_default", 3 | ANGULAR = "angular" 4 | } 5 | 6 | declare global { 7 | namespace TsED { 8 | interface ProjectPreferences { 9 | convention: ProjectConvention; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/cli/src/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./ArchitectureConvention.js"; 2 | export * from "./PlatformType.js"; 3 | export * from "./ProjectConvention.js"; 4 | -------------------------------------------------------------------------------- /packages/cli/src/loaders/alias.hook.ts: -------------------------------------------------------------------------------- 1 | function generateAliasesResolver(aliases: Record, options?: any) { 2 | return (specifier: any, parentModuleURL: any, defaultResolve: any) => { 3 | if (aliases[specifier]) { 4 | return defaultResolve(aliases[specifier], parentModuleURL); 5 | } 6 | 7 | return defaultResolve(specifier, parentModuleURL); 8 | }; 9 | } 10 | 11 | let resolver: any = null; 12 | 13 | export async function initialize(aliases: Record) { 14 | resolver = generateAliasesResolver(aliases); 15 | } 16 | 17 | export function resolve(specifier: any, context: any, nextResolve: any) { 18 | return resolver(specifier, context, nextResolve); 19 | } 20 | -------------------------------------------------------------------------------- /packages/cli/src/pipes/RoutePipe.spec.ts: -------------------------------------------------------------------------------- 1 | import {RoutePipe} from "./RoutePipe.js"; 2 | 3 | describe("RoutePipe", () => { 4 | it("should return the output file", () => { 5 | const pipe = new RoutePipe(); 6 | expect(pipe.transform("/test/Path-les")).toEqual("/test/path-les"); 7 | expect(pipe.transform("/users/User")).toEqual("/users"); 8 | expect(pipe.transform("/users/Users")).toEqual("/users"); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/cli/src/pipes/RoutePipe.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from "@tsed/cli-core"; 2 | import {kebabCase} from "change-case"; 3 | 4 | @Injectable() 5 | export class RoutePipe { 6 | transform(route: string) { 7 | const r = route 8 | .split("/") 9 | .reduce((paths: string[], path) => { 10 | const word = kebabCase(path); 11 | 12 | if (paths.includes(`${word}s`) || paths.includes(word)) { 13 | return paths; 14 | } 15 | 16 | return [...paths, kebabCase(path)]; 17 | }, []) 18 | .join("/"); 19 | 20 | return `/${r}`.replace(/\/\//gi, "/"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/cli/src/pipes/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./ClassNamePipe.js"; 2 | export * from "./OutputFilePathPipe.js"; 3 | export * from "./RoutePipe.js"; 4 | -------------------------------------------------------------------------------- /packages/cli/src/platforms/InitPlatformsModule.ts: -------------------------------------------------------------------------------- 1 | import {injectMany} from "@tsed/cli-core"; 2 | import {Module} from "@tsed/di"; 3 | 4 | import type {InitBasePlatform} from "./supports/InitBasePlatform.js"; 5 | import {InitExpressPlatform} from "./supports/InitExpressPlatform.js"; 6 | import {InitFastifyPlatform} from "./supports/InitFastifyPlatform.js"; 7 | import {InitKoaPlatform} from "./supports/InitKoaPlatform.js"; 8 | 9 | @Module({ 10 | imports: [InitExpressPlatform, InitKoaPlatform, InitFastifyPlatform] 11 | }) 12 | export class InitPlatformsModule { 13 | private platforms = injectMany("platform:init"); 14 | 15 | get(name: string) { 16 | return this.platforms.find((platform) => platform.name === name)!; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/cli/src/platforms/supports/InitBasePlatform.ts: -------------------------------------------------------------------------------- 1 | export interface InitBasePlatform { 2 | readonly name: string; 3 | 4 | dependencies(ctx: any): Record; 5 | 6 | devDependencies(ctx: any): Record; 7 | } 8 | -------------------------------------------------------------------------------- /packages/cli/src/platforms/supports/InitExpressPlatform.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from "@tsed/cli-core"; 2 | 3 | import type {InitBasePlatform} from "./InitBasePlatform.js"; 4 | 5 | @Injectable({ 6 | type: "platform:init" 7 | }) 8 | export class InitExpressPlatform implements InitBasePlatform { 9 | readonly name = "express"; 10 | 11 | dependencies(ctx: any) { 12 | return { 13 | "@tsed/platform-express": ctx.tsedVersion, 14 | "body-parser": "latest", 15 | cors: "latest", 16 | compression: "latest", 17 | "cookie-parser": "latest", 18 | express: "latest", 19 | "method-override": "latest" 20 | }; 21 | } 22 | 23 | devDependencies(ctx: any) { 24 | return { 25 | "@types/cors": "latest", 26 | "@types/express": "latest", 27 | "@types/compression": "latest", 28 | "@types/cookie-parser": "latest", 29 | "@types/method-override": "latest" 30 | }; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/cli/src/platforms/supports/InitFastifyPlatform.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from "@tsed/cli-core"; 2 | 3 | import type {InitBasePlatform} from "./InitBasePlatform.js"; 4 | 5 | @Injectable({ 6 | type: "platform:init" 7 | }) 8 | export class InitFastifyPlatform implements InitBasePlatform { 9 | readonly name = "fastify"; 10 | 11 | dependencies(ctx: any) { 12 | return { 13 | "@tsed/platform-fastify": ctx.tsedVersion, 14 | "@fastify/accepts": "latest", 15 | "@fastify/middie": "latest", 16 | "@fastify/static": "latest", 17 | "@fastify/cookie": "latest", 18 | "@fastify/formbody": "latest", 19 | "@fastify/session": "latest", 20 | fastify: "latest", 21 | "fastify-raw-body": "latest" 22 | }; 23 | } 24 | 25 | devDependencies(ctx: any) { 26 | return { 27 | "@types/content-disposition": "latest" 28 | }; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/cli/src/platforms/supports/InitKoaPlatform.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from "@tsed/cli-core"; 2 | 3 | import type {InitBasePlatform} from "./InitBasePlatform.js"; 4 | 5 | @Injectable({ 6 | type: "platform:init" 7 | }) 8 | export class InitKoaPlatform implements InitBasePlatform { 9 | readonly name = "koa"; 10 | 11 | dependencies(ctx: any) { 12 | return { 13 | "@tsed/platform-koa": ctx.tsedVersion, 14 | koa: "latest", 15 | "@koa/cors": "latest", 16 | "@koa/router": "latest", 17 | "koa-qs": "latest", 18 | "koa-bodyparser": "latest", 19 | "koa-override": "latest", 20 | "koa-compress": "latest" 21 | }; 22 | } 23 | 24 | devDependencies(ctx: any) { 25 | return { 26 | "@types/koa": "latest", 27 | "@types/koa-qs": "latest", 28 | "@types/koa-json": "latest", 29 | "@types/koa-bodyparser": "latest", 30 | "@types/koa__router": "latest", 31 | "@types/koa-compress": "latest", 32 | "@types/koa-send": "latest", 33 | "@types/koa__cors": "latest" 34 | }; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/cli/src/runtimes/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./RuntimesModule.js"; 2 | export * from "./supports/BabelRuntime.js"; 3 | export * from "./supports/BaseRuntime.js"; 4 | export * from "./supports/BunRuntime.js"; 5 | export * from "./supports/NodeRuntime.js"; 6 | export * from "./supports/WebpackRuntime.js"; 7 | -------------------------------------------------------------------------------- /packages/cli/src/runtimes/supports/BunRuntime.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from "@tsed/di"; 2 | 3 | import {BaseRuntime} from "./BaseRuntime.js"; 4 | 5 | @Injectable({ 6 | type: "runtime" 7 | }) 8 | export class BunRuntime extends BaseRuntime { 9 | readonly name = "bun"; 10 | readonly cmd = "bun"; 11 | readonly order: number = 4; 12 | 13 | compile(src: string, out: string) { 14 | return `${this.cmd} build --target=bun ${src} --outfile=${out}`; 15 | } 16 | 17 | startDev(main: string) { 18 | return `${this.cmd} --watch ${main}`; 19 | } 20 | 21 | startProd(args: string) { 22 | return `${this.cmd} ${args}`; 23 | } 24 | 25 | dependencies(): Record { 26 | return { 27 | typescript: "latest" 28 | }; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/cli/src/runtimes/supports/WebpackRuntime.ts: -------------------------------------------------------------------------------- 1 | import {dirname} from "node:path"; 2 | 3 | import {Injectable} from "@tsed/di"; 4 | 5 | import {BabelRuntime} from "./BabelRuntime.js"; 6 | 7 | @Injectable({ 8 | type: "runtime" 9 | }) 10 | export class WebpackRuntime extends BabelRuntime { 11 | readonly name = "webpack"; 12 | readonly order: number = 2; 13 | 14 | isCompiled() { 15 | return true; 16 | } 17 | 18 | files() { 19 | return [...super.files(), "/init/webpack.config.js.hbs"]; 20 | } 21 | 22 | compile(src: string, out: string): string { 23 | return "tsc && cross-env NODE_ENV=production webpack"; 24 | } 25 | 26 | startProd(main: string): string { 27 | return `${this.cmd} ${dirname(main)}/app.bundle.js`; 28 | } 29 | 30 | devDependencies() { 31 | return { 32 | ...super.devDependencies(), 33 | typescript: "latest", 34 | "babel-loader": "latest", 35 | webpack: "latest", 36 | "webpack-cli": "latest" 37 | }; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /packages/cli/src/services/CliRunScript.spec.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import runScript from "@npmcli/run-script"; 3 | // @ts-ignore 4 | import {CliPlatformTest} from "@tsed/cli-testing"; 5 | 6 | import {CliRunScript} from "./CliRunScript.js"; 7 | 8 | vi.mock("@npmcli/run-script"); 9 | 10 | describe("CliRunScript", () => { 11 | beforeEach(() => CliPlatformTest.create()); 12 | afterEach(() => CliPlatformTest.reset()); 13 | 14 | it("should run a script", async () => { 15 | const service = CliPlatformTest.get(CliRunScript); 16 | 17 | await service.run("ts-node", ["-o"], { 18 | env: { 19 | node: "env" 20 | } 21 | }); 22 | 23 | expect(runScript).toHaveBeenCalledWith({ 24 | banner: false, 25 | cmd: "ts-node -o", 26 | env: {node: "env"}, 27 | event: "run", 28 | path: "./tmp", 29 | stdio: "inherit" 30 | }); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /packages/cli/src/services/CliRunScript.ts: -------------------------------------------------------------------------------- 1 | import {ProjectPackageJson} from "@tsed/cli-core"; 2 | import {inject, Injectable} from "@tsed/di"; 3 | 4 | @Injectable() 5 | export class CliRunScript { 6 | async run(cmd: string, args: string[], options: any = {}) { 7 | // @ts-ignore 8 | const mod = await import("@npmcli/run-script"); 9 | 10 | return (mod.default || mod)({ 11 | event: "run", 12 | ...options, 13 | cmd: `${cmd} ${args.join(" ")}`, 14 | path: options.cwd || inject(ProjectPackageJson).dir, 15 | env: options.env || {}, 16 | stdio: options.stdio || "inherit", 17 | banner: false 18 | }); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/cli/src/utils/hbs/index.ts: -------------------------------------------------------------------------------- 1 | import handlebars from "handlebars"; 2 | 3 | import {helpers as array} from "./array.js"; 4 | import {helpers as collection} from "./collection.js"; 5 | import {helpers as comparison} from "./comparison.js"; 6 | import {helpers as object} from "./object.js"; 7 | import {helpers as switchHelpers} from "./switch.js"; 8 | 9 | handlebars.registerHelper(array); 10 | handlebars.registerHelper(object); 11 | handlebars.registerHelper(collection); 12 | handlebars.registerHelper(comparison); 13 | handlebars.registerHelper(switchHelpers); 14 | -------------------------------------------------------------------------------- /packages/cli/src/utils/hbs/switch.spec.ts: -------------------------------------------------------------------------------- 1 | import {helpers} from "./switch.js"; 2 | 3 | describe("switch", () => { 4 | it("should use switch statement", () => { 5 | const options = { 6 | fn: vi.fn() 7 | }; 8 | const ctx = {}; 9 | 10 | helpers.switch.call(ctx, 1, options); 11 | 12 | expect(options.fn).toHaveBeenCalled(); 13 | expect(ctx).toEqual({switch_value: 1}); 14 | }); 15 | 16 | it("should use case statement", () => { 17 | const options = { 18 | fn: vi.fn() 19 | }; 20 | const ctx = {switch_value: 1}; 21 | 22 | helpers.case.call(ctx, 1, options); 23 | 24 | expect(options.fn).toHaveBeenCalled(); 25 | }); 26 | 27 | it("should use case statement (false)", () => { 28 | const options = { 29 | fn: vi.fn() 30 | }; 31 | const ctx = {switch_value: 0}; 32 | 33 | helpers.case.call(ctx, 1, options); 34 | 35 | expect(options.fn).not.toHaveBeenCalled(); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /packages/cli/src/utils/hbs/switch.ts: -------------------------------------------------------------------------------- 1 | export const helpers: any = {}; 2 | helpers.switch = function (value: any, options: any) { 3 | this.switch_value = value; 4 | return options.fn(this); 5 | }; 6 | 7 | helpers.case = function (value: any, options: any) { 8 | if (value == this.switch_value) { 9 | return options.fn(this); 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /packages/cli/src/utils/renderer/insertAfter.ts: -------------------------------------------------------------------------------- 1 | export function insertAfter(fileContent: string, content: string, pattern: RegExp) { 2 | const lines = fileContent.split("\n"); 3 | 4 | const index = lines.findIndex((line) => { 5 | return line.match(pattern); 6 | }); 7 | 8 | const indent = lines[index].replace(lines[index].trim(), ""); 9 | lines[index] = lines[index] + "\n" + indent + content; 10 | 11 | if (!["]", "}"].includes(lines[index + 1].trim()) && lines[index - 1].slice(-1) === ",") { 12 | lines[index] += ","; 13 | } 14 | 15 | return lines.join("\n"); 16 | } 17 | -------------------------------------------------------------------------------- /packages/cli/src/utils/renderer/insertImport.spec.ts: -------------------------------------------------------------------------------- 1 | import {insertImport} from "./insertImport.js"; 2 | 3 | describe("insertImport", () => { 4 | it("should inject import", () => { 5 | const fileContent = 6 | "#!/usr/bin/env node\n" + 7 | 'import {CliCore} from "@tsed/cli-core";\n' + 8 | 'import {config} from "../config.js";\n' + 9 | "\n" + 10 | "CliCore.bootstrap({\n" + 11 | " ...config,\n" + 12 | " commands: [\n" + 13 | " ]\n" + 14 | "}).catch(console.error);"; 15 | 16 | const result = insertImport(fileContent, 'import {HelloCmd} from "./HelloCmd.js";'); 17 | 18 | expect(result).toEqual( 19 | "#!/usr/bin/env node\n" + 20 | 'import {CliCore} from "@tsed/cli-core";\n' + 21 | 'import {config} from "../config.js";\n' + 22 | 'import {HelloCmd} from "./HelloCmd.js";\n' + 23 | "\n" + 24 | "CliCore.bootstrap({\n" + 25 | " ...config,\n" + 26 | " commands: [\n" + 27 | " ]\n" + 28 | "}).catch(console.error);" 29 | ); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /packages/cli/src/utils/renderer/insertImport.ts: -------------------------------------------------------------------------------- 1 | export function insertImport(fileContent: string, content: string) { 2 | const lines = fileContent.split("\n"); 3 | 4 | const index = lines.findIndex((line) => { 5 | if (line.startsWith("#!")) { 6 | return false; 7 | } 8 | return !line.startsWith("import "); 9 | }); 10 | 11 | lines[index] = content + "\n" + lines[index]; 12 | 13 | return lines.join("\n"); 14 | } 15 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/async.factory.hbs: -------------------------------------------------------------------------------- 1 | import {Configuration, Inject, registerProvider} from "@tsed/di"; 2 | 3 | /** 4 | * Inject {{symbolName}} to the service, controller, etc... 5 | * 6 | * ## Usage 7 | * 8 | * ```typescript 9 | * import {Injectable} from "@tsed/di"; 10 | * import {{{symbolName}}} from "./{{symbolName}}"; 11 | * 12 | * @Injectable() 13 | * class MyService { 14 | * @{{symbolName}}() 15 | * private factory: {{symbolName}}; 16 | * 17 | * // or 18 | * constructor(@{{symbolName}}() private factory: {{symbolName}}){} 19 | * } 20 | * 21 | * @decorator 22 | */ 23 | export function {{symbolName}}() { 24 | return Inject({{symbolName}}); 25 | } 26 | 27 | export type {{symbolName}} = any; // implement type or interface for type checking 28 | 29 | registerProvider({ 30 | provide: {{symbolName}}, 31 | deps: [Configuration], 32 | async useAsyncFactory(settings: Configuration) { 33 | return {}; 34 | } 35 | }); 36 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/controller.hbs: -------------------------------------------------------------------------------- 1 | import {Controller} from "@tsed/di"; 2 | import {Get} from "@tsed/schema"; 3 | 4 | @Controller("{{route}}") 5 | export class {{symbolName}} { 6 | @Get("/") 7 | get() { 8 | return "hello"; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/decorator.class.hbs: -------------------------------------------------------------------------------- 1 | 2 | export interface {{symbolName}}Options { 3 | 4 | } 5 | 6 | export function {{symbolName}}(options: {{symbolName}}Options): ClassDecorator { 7 | return (target: any): any => { 8 | return class extends target { 9 | constructor(...args: any[]) { 10 | super(...args); 11 | } 12 | }; 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/decorator.endpoint.hbs: -------------------------------------------------------------------------------- 1 | import {useDecorators} from "@tsed/core"; 2 | import {JsonEntityFn, JsonEntityStore} from "@tsed/schema"; 3 | 4 | export interface {{symbolName}}Options { 5 | 6 | } 7 | 8 | export function {{symbolName}}(options: {{symbolName}}Options): MethodDecorator { 9 | return useDecorators( 10 | JsonEntityFn((entity: JsonEntityStore) => { 11 | entity.store.set({{symbolName}}, options); 12 | }) 13 | // add other decorator like Use(), UseBefore, UseAuth, etc... 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/decorator.generic.hbs: -------------------------------------------------------------------------------- 1 | import {DecoratorTypes, UnsupportedDecoratorType, decoratorTypeOf} from "@tsed/core"; 2 | 3 | export interface {{symbolName}}Options { 4 | 5 | } 6 | 7 | export function {{symbolName}}(options: {{symbolName}}Options): any { 8 | return (...args: DecoratorParameters): any => { 9 | switch(decoratorTypeOf(args)) { 10 | case DecoratorTypes.CLASS: 11 | case DecoratorTypes.PROP: 12 | console.log("do something") 13 | break; 14 | 15 | default: 16 | throw new UnsupportedDecoratorType({{symbolName}}, args); 17 | } 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/decorator.method.hbs: -------------------------------------------------------------------------------- 1 | export interface {{symbolName}}Options { 2 | 3 | } 4 | 5 | export function {{symbolName}}(options: {{symbolName}}Options): MethodDecorator { 6 | return (target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor) => { 7 | const originalMethod = descriptor.value; 8 | 9 | descriptor.value = function wrappedMethod (...args: any[]) { 10 | // do something before 11 | const result = originalMethod.apply(this, args) 12 | // do something after 13 | return result 14 | }; 15 | }; 16 | } 17 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/decorator.param.hbs: -------------------------------------------------------------------------------- 1 | import {useDecorators} from "@tsed/core"; 2 | import {ParamMetadata, ParamFn} from "@tsed/platform-params"; 3 | 4 | export interface {{symbolName}}Options { 5 | 6 | } 7 | 8 | export function {{symbolName}}(options: {{symbolName}}Options): ParameterDecorator { 9 | return useDecorators( 10 | ParamFn((param: ParamMetadata) => { 11 | param.store.set({{symbolName}}, options) 12 | }) 13 | // Add UsePipe decorator to invoke custom pipe on the parameter 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/decorator.parameters.hbs: -------------------------------------------------------------------------------- 1 | export interface {{symbolName}}Options { 2 | 3 | } 4 | 5 | export function {{symbolName}}(options: {{symbolName}}Options): ParameterDecorator { 6 | return (target: Object, propertyKey: string | symbol, index: number) => { 7 | 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/decorator.prop.hbs: -------------------------------------------------------------------------------- 1 | import {useDecorators} from "@tsed/core"; 2 | import {JsonEntityFn, JsonEntityStore} from "@tsed/schema"; 3 | 4 | export interface {{symbolName}}Options { 5 | 6 | } 7 | 8 | export function {{symbolName}}(options: {{symbolName}}Options): PropertyDecorator { 9 | return useDecorators( 10 | JsonEntityFn((entity: JsonEntityStore) => { 11 | 12 | }) 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/decorator.property.hbs: -------------------------------------------------------------------------------- 1 | export function {{symbolName}}(): PropertyDecorator { 2 | return (target: Object, propertyKey: string | symbol) => { 3 | 4 | }; 5 | } 6 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/exception-filter.hbs: -------------------------------------------------------------------------------- 1 | import {BaseContext} from "@tsed/di"; 2 | import {Catch, ExceptionFilterMethods} from "@tsed/platform-exceptions"; 3 | 4 | @Catch(Error) 5 | export class HttpExceptionFilter implements ExceptionFilterMethods { 6 | catch(exception: Exception, ctx: BaseContext) { 7 | 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/factory.hbs: -------------------------------------------------------------------------------- 1 | import {constant, injectable} from "@tsed/di"; 2 | 3 | export type {{symbolName}} = any; // implement type or interface for type checking 4 | export const {{symbolName}} = injectable(Symbol.for("{{symbolName}}") 5 | .factory(() => { 6 | // retrieve custom configuration from settings (e.g.: `@Configuration({hello: "value"})`) 7 | const hello = constant("hello"); 8 | 9 | return {hello}; 10 | }) 11 | .token(); 12 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/injectable.hbs: -------------------------------------------------------------------------------- 1 | import {Injectable} from "@tsed/di"; 2 | 3 | @Injectable() 4 | export class {{symbolName}} { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/interceptor.hbs: -------------------------------------------------------------------------------- 1 | import {InterceptorMethods, InterceptorContext, InterceptorMethods, Interceptor} from "@tsed/di"; 2 | 3 | @Interceptor() 4 | export class {{symbolName}} implements InterceptorMethods { 5 | /** 6 | * ctx: The context that holds the dynamic data related to the method execution and the proceed method 7 | * to proceed with the original method execution 8 | * 9 | * opts: Static params that can be provided when the interceptor is attached to a specific method 10 | */ 11 | async intercept(context: InterceptorContext, next: InterceptorMethods) { 12 | console.log(`the method ${context.propertyKey} will be executed with args ${context.args} and static data ${context.options}`); 13 | // let the original method by calling next function 14 | const result = await next(); 15 | 16 | console.log(`the method was executed, and returned ${result}`); 17 | 18 | // must return the returned value back to the caller 19 | return result; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/interface.hbs: -------------------------------------------------------------------------------- 1 | export interface {{symbolName}} { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/middleware.hbs: -------------------------------------------------------------------------------- 1 | import {Middleware, MiddlewareMethods} from "@tsed/platform-middlewares"; 2 | import {Context} from "@tsed/platform-params"; 3 | 4 | @Middleware() 5 | export class {{symbolName}} implements MiddlewareMethods { 6 | use(@Context() ctx: Context) { 7 | 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/model.hbs: -------------------------------------------------------------------------------- 1 | import {Property} from "@tsed/schema"; 2 | 3 | export class {{symbolName}} { 4 | @Property() 5 | id: string; 6 | } 7 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/module.hbs: -------------------------------------------------------------------------------- 1 | import {Module} from "@tsed/di"; 2 | 3 | @Module() 4 | export class {{symbolName}} { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/pipe.hbs: -------------------------------------------------------------------------------- 1 | import {Injectable} from "@tsed/di"; 2 | import {PipeMethods, ParamMetadata} from "@tsed/platform-params"; 3 | 4 | @Injectable() 5 | export class {{symbolName}} extends PipeMethods { 6 | transform(value: any, param: ParamMetadata) { 7 | return null; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/prisma.service.hbs: -------------------------------------------------------------------------------- 1 | import { Injectable, OnInit, OnDestroy } from "@tsed/di"; 2 | import { PrismaClient } from "@prisma/client"; 3 | 4 | @Injectable() 5 | export class PrismaService extends PrismaClient implements OnInit, OnDestroy { 6 | async $onInit() { 7 | await this.$connect(); 8 | } 9 | 10 | async $onDestroy() { 11 | await this.$disconnect(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/repository.hbs: -------------------------------------------------------------------------------- 1 | import {Injectable} from "@tsed/di"; 2 | 3 | @Injectable() 4 | export class {{symbolName}} { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/response-filter.hbs: -------------------------------------------------------------------------------- 1 | import {ResponseFilter, ResponseFilterMethods} from "@tsed/platform-response-filter"; 2 | import {BaseContext} from "@tsed/di"; 3 | 4 | @ResponseFilter("text/xml") 5 | export class XmlResponseFilter implements ResponseFilterMethods { 6 | transform(data: any, ctx: BaseContext) { 7 | return jsToXML(data); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/server/_partials/server-footer.hbs: -------------------------------------------------------------------------------- 1 | views: { 2 | root: join(process.cwd(), "../views"), 3 | extensions: { 4 | ejs: "ejs" 5 | } 6 | } 7 | }) 8 | export class {{symbolName}} { 9 | protected app = application(); 10 | } 11 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/server/_partials/server-header.hbs: -------------------------------------------------------------------------------- 1 | import {join} from "node:path"; 2 | import {Configuration} from "@tsed/di"; 3 | import {application} from "@tsed/platform-http"; 4 | {{#forEach imports}}{{#if tsIngore}} 5 | // @ts-ignore 6 | {{/if}}import {{symbols}}{{#if symbols}} from {{/if}}"{{from}}";{{comment}} 7 | {{/forEach}} 8 | 9 | @Configuration({ 10 | ...config, 11 | acceptMimes: ["application/json"], 12 | httpPort: process.env.PORT || 8083, 13 | httpsPort: false, // CHANGE 14 | mount: { 15 | "{{route}}": [ 16 | ...Object.values(rest) 17 | ]{{#or swagger oidc}}, 18 | "/": [{{#if swagger}} 19 | ...Object.values(pages){{/if}}{{#and swagger oidc}},{{/and}}{{#if oidc}} 20 | InteractionsController{{/if}} 21 | ]{{/or}} 22 | },{{#if swagger}} 23 | swagger: [ 24 | { 25 | path: "/doc", 26 | specVersion: "3.0.1" 27 | } 28 | ],{{/if}}{{#if scalar}} 29 | scalar: [ 30 | { 31 | path: {{#if swagger}}"/scalar/doc"{{else}}"/doc"{{/if}}, 32 | specVersion: "3.0.1" 33 | } 34 | ],{{/if}} 35 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/server/express/server.hbs: -------------------------------------------------------------------------------- 1 | {{> server-header }} 2 | middlewares: [ 3 | "cors", 4 | "cookie-parser", 5 | "compression", 6 | "method-override", 7 | "json-parser", 8 | { use: "urlencoded-parser", options: { extended: true }} 9 | ], 10 | {{> server-footer }} 11 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/server/fastify/server.hbs: -------------------------------------------------------------------------------- 1 | {{> server-header }} 2 | plugins: [ 3 | "@fastify/accepts", 4 | "@fastify/cookie", 5 | { 6 | use: "fastify-raw-body", 7 | options: { 8 | global: false, 9 | runFirst: true 10 | } 11 | }, 12 | "@fastify/formbody" 13 | ], 14 | {{> server-footer }} 15 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/server/koa/server.hbs: -------------------------------------------------------------------------------- 1 | {{> server-header }} 2 | middlewares: [ 3 | "@koa/cors", 4 | "koa-compress", 5 | "koa-override", 6 | "koa-bodyparser" 7 | ], 8 | {{> server-footer }} 9 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/service.hbs: -------------------------------------------------------------------------------- 1 | import {Injectable} from "@tsed/di"; 2 | 3 | @Injectable() 4 | export class {{symbolName}} { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /packages/cli/templates/generate/value.hbs: -------------------------------------------------------------------------------- 1 | import {injectable} from "@tsed/di"; 2 | 3 | export const {{symbolName}} = injectable(Symbol.for("{{symbolName}}")).value({}).token(); 4 | -------------------------------------------------------------------------------- /packages/cli/templates/init/.babelrc.hbs: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/env", {"targets": {"node": true}}], 4 | "@babel/typescript" 5 | ], 6 | "plugins": [ 7 | "babel-plugin-transform-typescript-metadata", 8 | ["@babel/plugin-proposal-decorators", { "legacy": true }], 9 | ["@babel/plugin-proposal-class-properties", { "loose": true }], 10 | "@babel/proposal-object-rest-spread" 11 | ] 12 | } -------------------------------------------------------------------------------- /packages/cli/templates/init/.barrels.json.hbs: -------------------------------------------------------------------------------- 1 | { 2 | "directory": {{{barrels}}}, 3 | "exclude": [ 4 | "**/__mock__", 5 | "**/__mocks__", 6 | "**/*.spec.ts" 7 | ], 8 | "delete": true 9 | } 10 | -------------------------------------------------------------------------------- /packages/cli/templates/init/.dockerignore.hbs: -------------------------------------------------------------------------------- 1 | node_modules 2 | Dockerfile 3 | .env.local 4 | .env.development 5 | **/*.spec.ts 6 | -------------------------------------------------------------------------------- /packages/cli/templates/init/.gitignore.hbs: -------------------------------------------------------------------------------- 1 | ### Node template 2 | .DS_Store 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | 13 | # Directory for instrumented libs generated by jscoverage/JSCover 14 | lib-cov 15 | 16 | # Coverage directory used by tools like istanbul 17 | coverage 18 | 19 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 20 | .grunt 21 | 22 | # node-waf configuration 23 | .lock-wscript 24 | 25 | # Compiled binary addons (http://nodejs.org/api/addons.html) 26 | build/Release 27 | 28 | # Dependency directory 29 | # https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git 30 | node_modules 31 | .npmrc 32 | *.log 33 | 34 | # Typings 35 | typings/ 36 | 37 | # Typescript 38 | {{srcDir}}/**/*.js 39 | {{srcDir}}/**/*.js.map 40 | test/**/*.js 41 | test/**/*.js.map 42 | 43 | # Test 44 | /.tmp 45 | /.nyc_output 46 | 47 | # IDE 48 | .vscode 49 | .idea 50 | 51 | # Project 52 | /public 53 | /dist 54 | 55 | #env 56 | .env.local 57 | .env.development 58 | -------------------------------------------------------------------------------- /packages/cli/templates/init/.npmrc.hbs: -------------------------------------------------------------------------------- 1 | @tsedio:registry=https://npm.pkg.github.com 2 | //npm.pkg.github.com/:_authToken=${GH_TOKEN} 3 | -------------------------------------------------------------------------------- /packages/cli/templates/init/.swcrc.hbs: -------------------------------------------------------------------------------- 1 | { 2 | "sourceMaps": true, 3 | "jsc": { 4 | "parser": { 5 | "syntax": "typescript", 6 | "decorators": true, 7 | "dynamicImport": true 8 | }, 9 | "target": "es2022", 10 | "externalHelpers": true, 11 | "keepClassNames": true, 12 | "transform": { 13 | "useDefineForClassFields": false, 14 | "legacyDecorator": true, 15 | "decoratorMetadata": true 16 | } 17 | }, 18 | "module": { 19 | "type": "es6" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/cli/templates/init/.yarnrc.hbs: -------------------------------------------------------------------------------- 1 | "@tsedio:registry" "https://npm.pkg.github.com/tsedio" -------------------------------------------------------------------------------- /packages/cli/templates/init/docker-compose.yml.hbs: -------------------------------------------------------------------------------- 1 | version: '3.5' 2 | services: 3 | server: 4 | build: 5 | context: . 6 | dockerfile: ./Dockerfile 7 | args: 8 | - http_proxy 9 | - https_proxy 10 | - no_proxy 11 | image: {{projectName}}/server:latest 12 | ports: 13 | - "8081:8081" 14 | 15 | -------------------------------------------------------------------------------- /packages/cli/templates/init/docker/_partials/docker-body.hbs: -------------------------------------------------------------------------------- 1 | COPY . . 2 | 3 | EXPOSE 8081 4 | ENV PORT 8081 5 | ENV NODE_ENV production 6 | -------------------------------------------------------------------------------- /packages/cli/templates/init/docker/_partials/docker-dev-tools.hbs: -------------------------------------------------------------------------------- 1 | RUN apk update && apk add build-base git curl 2 | RUN npm install -g pm2 3 | -------------------------------------------------------------------------------- /packages/cli/templates/init/docker/npm/Dockerfile.hbs: -------------------------------------------------------------------------------- 1 | {{> docker-header }} 2 | 3 | ARG NODE_VERSION=20.11.0 4 | 5 | FROM node:${NODE_VERSION}-alpine AS build 6 | WORKDIR /opt 7 | 8 | COPY package.json package-lock.json tsconfig.json tsconfig.base.json tsconfig.node.json tsconfig.spec.json .barrels.json .swcrc ./ 9 | 10 | RUN npm ci 11 | 12 | COPY ./src ./src 13 | 14 | RUN npm run build 15 | 16 | FROM node:${NODE_VERSION}-alpine AS runtime 17 | ENV WORKDIR /opt 18 | WORKDIR $WORKDIR 19 | 20 | {{> docker-dev-tools }} 21 | 22 | COPY --from=build /opt . 23 | 24 | RUN npm ci --omit=dev --ignore-scripts 25 | 26 | {{> docker-body}} 27 | 28 | CMD ["pm2-runtime", "start", "processes.config.cjs", "--env", "production"] 29 | -------------------------------------------------------------------------------- /packages/cli/templates/init/docker/pnpm/Dockerfile.hbs: -------------------------------------------------------------------------------- 1 | {{> docker-header }} 2 | 3 | ARG NODE_VERSION=20.11.0 4 | 5 | FROM node:${NODE_VERSION}-alpine AS build 6 | WORKDIR /opt 7 | 8 | COPY package.json pnpm-lock.yaml tsconfig.json tsconfig.base.json tsconfig.node.json tsconfig.spec.json .barrels.json .swcrc ./ 9 | 10 | RUN pnpm install --frozen-lockfile 11 | 12 | COPY ./src ./src 13 | 14 | RUN pnpm run build 15 | 16 | FROM node:${NODE_VERSION}-alpine AS runtime 17 | ENV WORKDIR /opt 18 | WORKDIR $WORKDIR 19 | 20 | {{> docker-dev-tools }} 21 | 22 | COPY --from=build /opt . 23 | 24 | RUN pnpm install --frozen-lockfile --prod 25 | 26 | {{> docker-body}} 27 | 28 | CMD ["pm2-runtime", "start", "processes.config.cjs", "--env", "production"] 29 | -------------------------------------------------------------------------------- /packages/cli/templates/init/docker/yarn/Dockerfile.hbs: -------------------------------------------------------------------------------- 1 | {{> docker-header }} 2 | 3 | ARG NODE_VERSION=20.11.0 4 | 5 | FROM node:${NODE_VERSION}-alpine AS build 6 | WORKDIR /opt 7 | 8 | COPY package.json yarn.lock tsconfig.json tsconfig.base.json tsconfig.node.json tsconfig.spec.json .barrels.json .swcrc ./ 9 | 10 | RUN yarn install --pure-lockfile 11 | 12 | COPY ./src ./src 13 | 14 | RUN yarn build 15 | 16 | FROM node:${NODE_VERSION}-alpine AS runtime 17 | ENV WORKDIR /opt 18 | WORKDIR $WORKDIR 19 | 20 | {{> docker-dev-tools }} 21 | 22 | COPY --from=build /opt . 23 | 24 | RUN yarn install --pure-lockfile --production 25 | 26 | {{> docker-body}} 27 | 28 | CMD ["pm2-runtime", "start", "processes.config.cjs", "--env", "production"] 29 | -------------------------------------------------------------------------------- /packages/cli/templates/init/docker/yarn_berry/Dockerfile.hbs: -------------------------------------------------------------------------------- 1 | {{> docker-header }} 2 | 3 | ARG NODE_VERSION=20.11.0 4 | 5 | FROM node:${NODE_VERSION}-alpine AS build 6 | WORKDIR /opt 7 | 8 | COPY package.json yarn.lock yarn.lock tsconfig.json tsconfig.base.json tsconfig.node.json tsconfig.spec.json .barrels.json .swcrc ./ 9 | 10 | RUN yarn set version berry 11 | RUN yarn install --immutable 12 | 13 | COPY ./src ./src 14 | 15 | RUN yarn build 16 | 17 | FROM node:${NODE_VERSION}-alpine AS runtime 18 | ENV WORKDIR /opt 19 | WORKDIR $WORKDIR 20 | 21 | {{> docker-dev-tools }} 22 | 23 | COPY --from=build /opt . 24 | 25 | RUN yarn set version berry 26 | RUN yarn install --immutable 27 | ## RUN yarn workspaces focus --all --production 28 | 29 | {{> docker-body}} 30 | 31 | CMD ["pm2-runtime", "start", "processes.config.cjs", "--env", "production"] 32 | -------------------------------------------------------------------------------- /packages/cli/templates/init/nodemon.json.hbs: -------------------------------------------------------------------------------- 1 | { 2 | "extensions": ["ts"], 3 | "watch": ["src"], 4 | "ignore": ["**/*.spec.ts"], 5 | "delay": 100, 6 | "execMap": { 7 | "ts": "node --enable-source-maps --import @swc-node/register/esm-register" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/cli/templates/init/pm2/bun/processes.config.cjs.hbs: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const path = require('path') 4 | const defaultLogFile = path.join(__dirname, '/logs/project-server.log') 5 | 6 | module.exports = { 7 | 'apps': [ 8 | { 9 | name: 'api', 10 | interpreter: '~/.bun/bin/bun', 11 | 'script': `${process.env.WORKDIR}/dist/index.js`, 12 | 'cwd': process.env.WORKDIR, 13 | exec_mode: 'cluster', 14 | instances: process.env.NODE_ENV === 'test' ? 1 : process.env.NB_INSTANCES || 2, 15 | autorestart: true, 16 | max_memory_restart: process.env.MAX_MEMORY_RESTART || '750M', 17 | 'out_file': defaultLogFile, 18 | 'error_file': defaultLogFile, 19 | 'merge_logs': true, 20 | 'kill_timeout': 30000, 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /packages/cli/templates/init/pm2/node-compiled/processes.config.cjs.hbs: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const path = require('path') 4 | const defaultLogFile = path.join(__dirname, '/logs/project-server.log') 5 | 6 | module.exports = { 7 | 'apps': [ 8 | { 9 | name: 'api', 10 | 'script': `${process.env.WORKDIR}/dist/index.js`, 11 | 'cwd': process.env.WORKDIR, 12 | exec_mode: "cluster", 13 | instances: process.env.NODE_ENV === 'test' ? 1 : process.env.NB_INSTANCES || 2, 14 | autorestart: true, 15 | max_memory_restart: process.env.MAX_MEMORY_RESTART || '750M', 16 | 'out_file': defaultLogFile, 17 | 'error_file': defaultLogFile, 18 | 'merge_logs': true, 19 | 'kill_timeout': 30000, 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /packages/cli/templates/init/pm2/node-loader/processes.config.cjs.hbs: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const path = require('path') 4 | const defaultLogFile = path.join(__dirname, '/logs/project-server.log') 5 | 6 | module.exports = { 7 | 'apps': [ 8 | { 9 | name: 'api', 10 | 'interpreter': 'node', 11 | interpreter_args: '--import @swc-node/register/esm-register --enable-source-maps', 12 | 'script': `${process.env.WORKDIR}/src/index.ts`, 13 | 'cwd': process.env.WORKDIR, 14 | exec_mode: 'cluster', 15 | instances: process.env.NODE_ENV === 'test' ? 1 : process.env.NB_INSTANCES || 2, 16 | autorestart: true, 17 | max_memory_restart: process.env.MAX_MEMORY_RESTART || '750M', 18 | 'out_file': defaultLogFile, 19 | 'error_file': defaultLogFile, 20 | 'merge_logs': true, 21 | 'kill_timeout': 30000, 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /packages/cli/templates/init/src/bin/index.ts.hbs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import {CliCore} from "@tsed/cli-core"; 3 | import {config} from "../config/index.js"; 4 | 5 | CliCore.bootstrap({ 6 | ...config, 7 | commands: [ 8 | ] 9 | }).catch(console.error); 10 | -------------------------------------------------------------------------------- /packages/cli/templates/init/src/config/envs/index.ts.hbs: -------------------------------------------------------------------------------- 1 | import dotenv from "dotenv-flow"; 2 | 3 | process.env.NODE_ENV = process.env.NODE_ENV || "development"; 4 | 5 | export const config = dotenv.config(); 6 | export const isProduction = process.env.NODE_ENV === "production"; 7 | export const envs = process.env 8 | -------------------------------------------------------------------------------- /packages/cli/templates/init/src/config/index.ts.hbs: -------------------------------------------------------------------------------- 1 | import {readFileSync} from "node:fs"; 2 | import {envs} from "./envs/index.js"; 3 | import loggerConfig from "./logger/index.js";{{#if mongoose}} 4 | import mongooseConfig from "./mongoose/index.js"; 5 | {{/if}}{{#if oidc}} 6 | import oidcConfig from "./oidc/index.js"; 7 | import {FileSyncAdapter} from "@tsed/adapters"; 8 | {{/if}} 9 | 10 | const pkg = JSON.parse(readFileSync("./package.json", {encoding: "utf8"})); 11 | 12 | export const config: Partial = { 13 | version: pkg.version, 14 | envs, 15 | ajv: { 16 | returnsCoercedValues: true 17 | }, 18 | logger: loggerConfig, 19 | {{#if mongoose}} 20 | mongoose: mongooseConfig, 21 | {{/if}} 22 | {{#if graphql}} 23 | graphql: { 24 | default: { 25 | path: "/graphql", 26 | buildSchemaOptions: { 27 | } 28 | } 29 | }, 30 | {{/if}} 31 | {{#if oidc}} 32 | oidc: oidcConfig, 33 | adapters: [ 34 | FileSyncAdapter 35 | ] 36 | {{/if}} 37 | // additional shared configuration 38 | }; 39 | -------------------------------------------------------------------------------- /packages/cli/templates/init/src/config/logger/index.ts.hbs: -------------------------------------------------------------------------------- 1 | import {DILoggerOptions} from "@tsed/di"; 2 | import {$log} from "@tsed/logger"; 3 | import {isProduction} from "../envs/index.js"; 4 | 5 | if (isProduction) { 6 | $log.appenders.set("stdout", { 7 | type: "stdout", 8 | levels: ["info", "debug"], 9 | layout: { 10 | type: "json" 11 | } 12 | }); 13 | 14 | $log.appenders.set("stderr", { 15 | levels: ["trace", "fatal", "error", "warn"], 16 | type: "stderr", 17 | layout: { 18 | type: "json" 19 | } 20 | }); 21 | } 22 | 23 | export default { 24 | disableRoutesSummary: isProduction 25 | }; 26 | -------------------------------------------------------------------------------- /packages/cli/templates/init/src/controllers/pages/IndexController.ts.hbs: -------------------------------------------------------------------------------- 1 | import {Constant, Controller} from "@tsed/di"; 2 | import {HeaderParams} from "@tsed/platform-params"; 3 | import {View} from "@tsed/platform-views"; 4 | import {SwaggerSettings} from "@tsed/swagger"; 5 | import {Hidden, Get, Returns} from "@tsed/schema"; 6 | 7 | @Hidden() 8 | @Controller("/") 9 | export class IndexController { 10 | @Constant("swagger", []) 11 | private swagger: SwaggerSettings[]; 12 | 13 | @Get("/") 14 | @View("swagger.ejs") 15 | @(Returns(200, String).ContentType("text/html")) 16 | get(@HeaderParams("x-forwarded-proto") protocol: string, @HeaderParams("host") host: string) { 17 | const hostUrl = `${protocol || "http"}://${host}`; 18 | 19 | return { 20 | BASE_URL: hostUrl, 21 | docs: this.swagger.map((conf) => { 22 | return { 23 | url: hostUrl + conf.path, 24 | ...conf 25 | }; 26 | }) 27 | }; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/cli/templates/init/src/index.ts.hbs: -------------------------------------------------------------------------------- 1 | import {$log} from "@tsed/logger"; 2 | import { {{platformSymbol}} } from "@tsed/platform-{{platform}}"; 3 | import {Server} from "./{{entryServer}}.js"; 4 | 5 | const SIG_EVENTS = [ 6 | "beforeExit", 7 | "SIGHUP", 8 | "SIGINT", 9 | "SIGQUIT", 10 | "SIGILL", 11 | "SIGTRAP", 12 | "SIGABRT", 13 | "SIGBUS", 14 | "SIGFPE", 15 | "SIGUSR1", 16 | "SIGSEGV", 17 | "SIGUSR2", 18 | "SIGTERM" 19 | ]; 20 | 21 | try { 22 | const platform = await {{platformSymbol}}.bootstrap(Server); 23 | await platform.listen(); 24 | 25 | SIG_EVENTS.forEach((evt) => process.on(evt, () => platform.stop())); 26 | 27 | ["uncaughtException", "unhandledRejection"].forEach((evt) => 28 | process.on(evt, async (error) => { 29 | $log.error({event: "SERVER_" + evt.toUpperCase(), message: error.message, stack: error.stack}); 30 | await platform.stop(); 31 | }) 32 | ); 33 | } catch (error) { 34 | $log.error({event: "SERVER_BOOTSTRAP_ERROR", message: error.message, stack: error.stack}); 35 | } 36 | 37 | -------------------------------------------------------------------------------- /packages/cli/templates/init/tsconfig.base.json.hbs: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "NodeNext", 4 | "target": "ESNext", 5 | "experimentalDecorators": true, 6 | "emitDecoratorMetadata": true, 7 | "moduleResolution": "NodeNext", 8 | "downlevelIteration": false, 9 | "isolatedModules": false, 10 | "suppressImplicitAnyIndexErrors": false, 11 | "noImplicitAny": true, 12 | "strictNullChecks": true, 13 | "noUnusedLocals": false, 14 | "noUnusedParameters": false, 15 | "esModuleInterop": true, 16 | "allowSyntheticDefaultImports": true, 17 | "useDefineForClassFields": false, 18 | "importHelpers": true, 19 | "resolveJsonModule": true, 20 | "newLine": "LF", 21 | "skipLibCheck": true, 22 | "lib": ["ESNext", "esnext.asynciterable"], 23 | "declaration": false, 24 | "noResolve": false, 25 | "preserveConstEnums": true, 26 | "sourceMap": true, 27 | "noEmit": true 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/cli/templates/init/tsconfig.json.hbs: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "noEmit": true 6 | }, 7 | "include": [], 8 | "references": [ 9 | { 10 | "path": "./tsconfig.node.json" 11 | }{{#if testing}}, 12 | { 13 | "path": "./tsconfig.spec.json" 14 | }{{/if}} 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /packages/cli/templates/init/tsconfig.node.json.hbs: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | "compilerOptions": { 4 | "baseUrl": "." 5 | }, 6 | "include": [ 7 | "src/**/*" 8 | ], 9 | "exclude": [ 10 | "src/**/*.spec.ts", 11 | "dist", 12 | "node_modules", 13 | "**/helpers/*Fixture.ts", 14 | "**/__mock__/**", 15 | "coverage" 16 | ], 17 | "linterOptions": { 18 | "exclude": [] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/cli/templates/init/tsconfig.spec.json.hbs: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "rootDir": ".", 6 | "noEmit": true, 7 | "types": [{{#if vitest}} 8 | "vitest/globals", 9 | "vitest/importMeta", 10 | "vite/client", 11 | "vitest",{{/if}}{{#if jest}} 12 | "jest",{{/if}} 13 | "node" 14 | ] 15 | }, 16 | "include": [{{#if vitest}} 17 | "vitest.config.mts",{{/if}} 18 | "src/**/*" 19 | ], 20 | "exclude": [ 21 | "dist", 22 | "coverage", 23 | "node_modules" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /packages/cli/tsconfig.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsed/typescript/tsconfig.node.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "rootDir": "src", 6 | "outDir": "./lib/esm", 7 | "declarationDir": "./lib/types", 8 | "declaration": true, 9 | "composite": true, 10 | "noEmit": false, 11 | "sourceMap": false 12 | }, 13 | "include": ["src", "src/**/*.json"], 14 | "exclude": [ 15 | "node_modules", 16 | "test", 17 | "lib", 18 | "benchmark", 19 | "coverage", 20 | "spec", 21 | "**/*.benchmark.ts", 22 | "**/*.spec.ts", 23 | "keys", 24 | "**/__mock__/**", 25 | "webpack.config.js" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /packages/cli/vitest.config.mts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import {presets} from "@tsed/vitest/presets"; 3 | import {defineConfig} from "vitest/config"; 4 | 5 | export default defineConfig( 6 | { 7 | ...presets, 8 | test: { 9 | ...presets.test, 10 | coverage: { 11 | ...presets.test?.coverage, 12 | thresholds: { 13 | statements: 0, 14 | branches: 0, 15 | functions: 0, 16 | lines: 0 17 | } 18 | } 19 | } 20 | } 21 | ); 22 | -------------------------------------------------------------------------------- /tools/integration/.swcrc: -------------------------------------------------------------------------------- 1 | { 2 | "sourceMaps": "inline", 3 | "jsc": { 4 | "parser": { 5 | "syntax": "typescript", 6 | "decorators": true, 7 | "dynamicImport": true, 8 | "tsx": true 9 | }, 10 | "target": "esnext", 11 | "externalHelpers": true, 12 | "keepClassNames": true, 13 | "transform": { 14 | "useDefineForClassFields": false, 15 | "legacyDecorator": true, 16 | "decoratorMetadata": true, 17 | "react": { 18 | "pragma": "React.createElement", 19 | "pragmaFrag": "React.Fragment", 20 | "throwIfNamespace": true, 21 | "development": false, 22 | "useBuiltins": false, 23 | "runtime": "automatic" 24 | } 25 | } 26 | }, 27 | "module": { 28 | "type": "es6" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tools/integration/index.ts: -------------------------------------------------------------------------------- 1 | import "@tsed/cli/bin"; 2 | -------------------------------------------------------------------------------- /tools/integration/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../typescript/tsconfig.node.json"], 3 | "compilerOptions": { 4 | "baseUrl": "../..", 5 | "paths": { 6 | "@tsed/cli": ["./packages/cli/src/index.ts"], 7 | "@tsed/cli/bin": ["./packages/cli/src/bin/tsed.ts"], 8 | "@tsed/cli-core": ["./packages/cli-core/src/index.ts"] 9 | } 10 | }, 11 | "include": ["**/*.ts"] 12 | } 13 | -------------------------------------------------------------------------------- /tools/typescript/.npmignore.template: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | coverage 4 | tsconfig.json 5 | tsconfig.*.json 6 | __mock__ 7 | *.spec.js 8 | *.tsbuildinfo 9 | src 10 | vitest.config.mts -------------------------------------------------------------------------------- /tools/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tsed/typescript", 3 | "version": "6.4.3", 4 | "description": "Util to compile source", 5 | "type": "module", 6 | "private": true, 7 | "main": "index.js", 8 | "exports": { 9 | ".": "./index.js", 10 | "./tsconfig.node.json": "./tsconfig.node.json" 11 | }, 12 | "scripts": { 13 | "build:references": "node ./index.js" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tools/typescript/swc.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "sourceMaps": "inline", 3 | "jsc": { 4 | "target": "es2021", 5 | "externalHelpers": true, 6 | "keepClassNames": true, 7 | "parser": { 8 | "syntax": "typescript", 9 | "tsx": true, 10 | "decorators": true, 11 | "dynamicImport": true, 12 | "privateMethod": true, 13 | "exportDefaultFrom": true, 14 | "importMeta": true, 15 | "preserveAllComments": true 16 | }, 17 | "transform": { 18 | "hidden": { 19 | "jest": true 20 | }, 21 | "legacyDecorator": true, 22 | "decoratorMetadata": true 23 | } 24 | }, 25 | "module": { 26 | "type": "es6", 27 | "strict": false, 28 | "strictMode": true, 29 | "lazy": false, 30 | "noInterop": false 31 | }, 32 | "isModule": true 33 | } 34 | -------------------------------------------------------------------------------- /tools/typescript/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "NodeNext", 4 | "target": "ESNext", 5 | "experimentalDecorators": true, 6 | "emitDecoratorMetadata": true, 7 | "moduleResolution": "NodeNext", 8 | "downlevelIteration": false, 9 | "isolatedModules": false, 10 | "suppressImplicitAnyIndexErrors": false, 11 | "noImplicitAny": true, 12 | "strictNullChecks": true, 13 | "noUnusedLocals": false, 14 | "noUnusedParameters": false, 15 | "esModuleInterop": true, 16 | "allowSyntheticDefaultImports": true, 17 | "useDefineForClassFields": false, 18 | "importHelpers": true, 19 | "resolveJsonModule": true, 20 | "newLine": "LF", 21 | "skipLibCheck": true, 22 | "lib": ["ESNext", "esnext.asynciterable"], 23 | "declaration": false, 24 | "noResolve": false, 25 | "preserveConstEnums": true, 26 | "verbatimModuleSyntax": true, 27 | "sourceMap": false, 28 | "declarationMap": false, 29 | "noEmit": true 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tools/typescript/tsconfig.template.esm.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsed/typescript/tsconfig.node.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "rootDir": "src", 6 | "outDir": "./lib/esm", 7 | "declarationDir": "./lib/types", 8 | "declaration": true, 9 | "composite": true, 10 | "noEmit": false 11 | }, 12 | "include": ["src", "src/**/*.json"], 13 | "exclude": [ 14 | "node_modules", 15 | "test", 16 | "lib", 17 | "benchmark", 18 | "coverage", 19 | "spec", 20 | "**/*.benchmark.ts", 21 | "**/*.spec.ts", 22 | "keys", 23 | "**/__mock__/**", 24 | "webpack.config.js" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /tools/typescript/tsconfig.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsed/typescript/tsconfig.node.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "noEmit": true 6 | }, 7 | "include": [] 8 | } 9 | -------------------------------------------------------------------------------- /tools/typescript/tsconfig.template.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsed/typescript/tsconfig.node.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "rootDir": ".", 6 | "declaration": false, 7 | "composite": false, 8 | "noEmit": true 9 | }, 10 | "include": ["src/**/*.spec.ts", "test/**/*.spec.ts"], 11 | "exclude": ["node_modules", "test", "lib", "benchmark", "coverage"] 12 | } 13 | -------------------------------------------------------------------------------- /tools/vitest/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tsed/vitest", 3 | "type": "module", 4 | "version": "6.4.3", 5 | "private": true, 6 | "exports": { 7 | ".": "./index.js", 8 | "./plugins/*": "./plugins/*", 9 | "./presets": "./presets/index.js" 10 | }, 11 | "devDependencies": { 12 | "vitest": "3.0.9" 13 | }, 14 | "scripts": { 15 | "generate": "node index.js" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tools/vitest/plugins/resolveWorkspaceFiles.js: -------------------------------------------------------------------------------- 1 | export function resolveWorkspaceFiles() { 2 | return { 3 | name: "resolve-workspace-files", 4 | resolveId(id) { 5 | if (id.includes("@tsed")) { 6 | return id.replace(".js", ".ts"); 7 | } 8 | } 9 | }; 10 | } 11 | -------------------------------------------------------------------------------- /tools/vitest/templates/vitest.config.mts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import {presets} from "@tsed/vitest/presets"; 3 | import {defineConfig} from "vitest/config"; 4 | 5 | export default defineConfig( 6 | { 7 | ...presets, 8 | test: { 9 | ...presets.test, 10 | coverage: { 11 | ...presets.test.coverage, 12 | thresholds: { 13 | statements: 0, 14 | branches: 0, 15 | functions: 0, 16 | lines: 0 17 | } 18 | } 19 | } 20 | } 21 | ); 22 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "compilerOptions": { 4 | "baseUrl": "." 5 | }, 6 | "include": [], 7 | "references": [ 8 | { 9 | "path": "./tsconfig.node.json" 10 | }, 11 | { 12 | "path": "./tsconfig.spec.json" 13 | } 14 | ], 15 | "exclude": ["node_modules"] 16 | } 17 | -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsed/typescript/tsconfig.node.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "noEmit": true, 6 | "paths": { 7 | "@tsed/cli": ["./packages/cli/src/index.ts"], 8 | "@tsed/cli-core": ["./packages/cli-core/src/index.ts"] 9 | } 10 | }, 11 | "include": ["./packages/*/src/**/*.ts", "**/tsup.config.ts", "**/vite.config.mts"], 12 | "exclude": [ 13 | "./packages/*/src/**/*.spec.ts", 14 | "./packages/**/project-name/**/*.ts", 15 | "**/__tests__/**/*.ts", 16 | "**/__mock__/**/*.ts", 17 | "**/helpers/**/*.ts", 18 | "node_modules", 19 | "**/lib/**", 20 | "**/templates/**", 21 | "**/barrels/**" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsed/typescript/tsconfig.node.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "noEmit": true, 6 | "composite": false, 7 | "declarationMap": false, 8 | "types": ["vitest/globals", "vitest/importMeta", "vite/client", "node", "vitest"], 9 | "paths": { 10 | "@tsed/cli": ["./packages/cli/src/index.ts"], 11 | "@tsed/cli-core": ["./packages/cli-core/src/index.ts"], 12 | "@tsed/cli-testing": ["./packages/cli-testing/src/index.ts"] 13 | } 14 | }, 15 | "include": ["vitest.*.mts", "**/vitest.*.mts", "**/*.ts"], 16 | "exclude": ["dist", "**/lib/**", "**/templates/**", "**/barrels/**", "./packages/**/project-name/**/*.ts"] 17 | } 18 | -------------------------------------------------------------------------------- /tsdoc.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rootDir: process.cwd(), 3 | packagesDir: "packages/", 4 | scanPatterns: ["/packages/{cli,cli-core}/lib/types/**/*.d.ts", "!**/*.spec.ts", "!**/node_modules", "!**/__mock__/**"], 5 | outputDir: "/docs/api", 6 | baseUrl: "/api", 7 | jsonOutputDir: "/docs/.vuepress/public", 8 | scope: "@tsed", 9 | modules: {} 10 | }; 11 | -------------------------------------------------------------------------------- /vitest.workspace.mts: -------------------------------------------------------------------------------- 1 | export default [ 2 | 'packages/**/vitest.config.{mts,ts}', 3 | ] 4 | --------------------------------------------------------------------------------