├── .nvmrc ├── templates ├── application │ ├── preact │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── index.css │ │ │ └── App.tsx │ │ ├── module-federation.config.ts │ │ ├── index.html │ │ ├── .babelrc │ │ ├── tsconfig.json │ │ ├── package.json │ │ ├── gitignore │ │ └── rspack.config.ts.ejs │ ├── lit-html │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── index.css │ │ │ └── App.ts │ │ ├── module-federation.config.ts │ │ ├── .babelrc │ │ ├── index.html │ │ ├── tsconfig.json │ │ ├── package.json │ │ ├── rspack.config.ts.ejs │ │ └── gitignore │ ├── react-18 │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── index.css │ │ │ └── App.tsx │ │ ├── module-federation.config.ts │ │ ├── .babelrc │ │ ├── index.html │ │ ├── tsconfig.json │ │ ├── package.json │ │ ├── gitignore │ │ └── rspack.config.ts.ejs │ ├── react-19 │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── index.css │ │ │ └── App.tsx │ │ ├── module-federation.config.ts │ │ ├── .babelrc │ │ ├── index.html │ │ ├── tsconfig.json │ │ ├── package.json │ │ ├── gitignore │ │ └── rspack.config.ts.ejs │ ├── solid-js │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── index.css │ │ │ └── App.tsx │ │ ├── module-federation.config.ts │ │ ├── .babelrc │ │ ├── index.html │ │ ├── tsconfig.json │ │ ├── package.json │ │ ├── rspack.config.ts.ejs │ │ └── gitignore │ ├── vue3 │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── bootloader.ts │ │ │ ├── vue-shim.d.ts │ │ │ ├── index.css │ │ │ └── App.vue │ │ ├── .babelrc │ │ ├── module-federation.config.ts │ │ ├── index.html │ │ ├── tsconfig.json │ │ ├── package.json │ │ ├── gitignore │ │ └── rspack.config.ts.ejs │ ├── svelte │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── App.svelte │ │ │ ├── index.css │ │ │ └── bootloader.ts │ │ ├── module-federation.config.ts │ │ ├── .babelrc │ │ ├── index.html │ │ ├── tsconfig.json │ │ ├── package.json │ │ ├── gitignore │ │ └── rspack.config.ts.ejs │ └── vanilla │ │ ├── module-federation.config.ts │ │ ├── .babelrc │ │ ├── src │ │ ├── index.css │ │ └── index.ts │ │ ├── index.html │ │ ├── tsconfig.json │ │ ├── package.json │ │ ├── rspack.config.ts.ejs │ │ └── gitignore ├── application-extras │ └── tailwind │ │ ├── src │ │ └── index.css │ │ └── postcss.config.mjs ├── server │ ├── nestjs-auth │ │ ├── .prettierrc │ │ ├── src │ │ │ ├── config.ts │ │ │ ├── auth │ │ │ │ ├── constants.ts │ │ │ │ ├── jwt-auth.guard.ts │ │ │ │ ├── local-auth.guard.ts │ │ │ │ ├── jwt.strategy.ts │ │ │ │ ├── local.strategy.ts │ │ │ │ ├── auth.module.ts │ │ │ │ └── auth.service.ts │ │ │ ├── users │ │ │ │ ├── users.module.ts │ │ │ │ └── users.service.ts │ │ │ ├── modules │ │ │ │ ├── authorized │ │ │ │ │ ├── authorized.module.ts │ │ │ │ │ └── authorized.controller.ts │ │ │ │ └── unauthorized │ │ │ │ │ ├── unauthorized.module.ts │ │ │ │ │ └── unauthorized.controller.ts │ │ │ ├── main.ts │ │ │ ├── app.controller.ts │ │ │ └── app.module.ts │ │ ├── nest-cli.json │ │ ├── public │ │ │ ├── placeholder.txt │ │ │ └── .DS_Store │ │ ├── .DS_Store │ │ ├── tsconfig.build.json │ │ ├── test │ │ │ ├── jest-e2e.json │ │ │ └── app.e2e-spec.ts │ │ ├── gitignore │ │ ├── tsconfig.json │ │ ├── .eslintrc.js │ │ ├── README.md │ │ └── package.json │ ├── nestjs-todo │ │ ├── .prettierrc │ │ ├── nest-cli.json │ │ ├── tsconfig.build.json │ │ ├── src │ │ │ ├── app.module.ts │ │ │ ├── modules │ │ │ │ └── todos │ │ │ │ │ ├── todo.module.ts │ │ │ │ │ └── todo.controller.ts │ │ │ └── main.ts │ │ ├── test │ │ │ ├── jest-e2e.json │ │ │ └── app.e2e-spec.ts │ │ ├── gitignore │ │ ├── tsconfig.json │ │ ├── .eslintrc.js │ │ └── package.json │ ├── express │ │ ├── index.ts │ │ ├── gitignore │ │ ├── package.json │ │ └── yarn.lock │ ├── graphql-nexus │ │ ├── gitignore │ │ ├── package.json │ │ ├── src │ │ │ └── index.ts │ │ └── tsconfig.json │ ├── graphql-apollo │ │ ├── package.json │ │ ├── gitignore │ │ ├── src │ │ │ └── index.ts │ │ └── tsconfig.json │ └── graphql-subscriptions │ │ ├── gitignore │ │ ├── package.json │ │ ├── src │ │ └── index.ts │ │ └── tsconfig.json └── library │ └── typescript │ ├── src │ └── index.ts │ ├── package.json │ ├── yarn.lock │ ├── gitignore │ └── tsconfig.json ├── .husky └── pre-commit ├── .prettierrc ├── .gitignore ├── .npmignore ├── tsconfig.json ├── eslint.config.mjs ├── LICENSE ├── package.json ├── README.md ├── src ├── __tests__ │ └── index.test.ts └── index.ts └── bin └── create-mf-app.ts /.nvmrc: -------------------------------------------------------------------------------- 1 | v18.16.0 -------------------------------------------------------------------------------- /templates/application/preact/src/index.ts: -------------------------------------------------------------------------------- 1 | import("./App"); 2 | -------------------------------------------------------------------------------- /templates/application/lit-html/src/index.ts: -------------------------------------------------------------------------------- 1 | import("./App"); 2 | -------------------------------------------------------------------------------- /templates/application/react-18/src/index.ts: -------------------------------------------------------------------------------- 1 | import("./App"); 2 | -------------------------------------------------------------------------------- /templates/application/react-19/src/index.ts: -------------------------------------------------------------------------------- 1 | import("./App"); 2 | -------------------------------------------------------------------------------- /templates/application/solid-js/src/index.ts: -------------------------------------------------------------------------------- 1 | import("./App"); 2 | -------------------------------------------------------------------------------- /templates/application/vue3/src/index.ts: -------------------------------------------------------------------------------- 1 | import("./bootloader"); 2 | -------------------------------------------------------------------------------- /templates/application/svelte/src/index.ts: -------------------------------------------------------------------------------- 1 | import("./bootloader"); 2 | -------------------------------------------------------------------------------- /templates/application-extras/tailwind/src/index.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss"; 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | pnpm lint 5 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": false, 3 | "trailingComma": "es5", 4 | "semi": true 5 | } 6 | -------------------------------------------------------------------------------- /templates/server/nestjs-auth/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all" 4 | } -------------------------------------------------------------------------------- /templates/server/nestjs-todo/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all" 4 | } -------------------------------------------------------------------------------- /templates/server/nestjs-auth/src/config.ts: -------------------------------------------------------------------------------- 1 | export const JWT_SECRET = process.env.JWT_SECRET || 'secret'; 2 | -------------------------------------------------------------------------------- /templates/application/vue3/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-typescript", "@babel/preset-env"] 3 | } 4 | -------------------------------------------------------------------------------- /templates/server/nestjs-auth/src/auth/constants.ts: -------------------------------------------------------------------------------- 1 | export const jwtConstants = { 2 | secret: 'secretKey', 3 | }; 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | bin/create-mf-app.js 3 | src/index.js 4 | src/types.js 5 | pnpm-lock.yaml 6 | .DS_Store 7 | -------------------------------------------------------------------------------- /templates/server/nestjs-auth/nest-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "collection": "@nestjs/schematics", 3 | "sourceRoot": "src" 4 | } 5 | -------------------------------------------------------------------------------- /templates/server/nestjs-auth/public/placeholder.txt: -------------------------------------------------------------------------------- 1 | Put your static files in this directory and then delete this file. 2 | -------------------------------------------------------------------------------- /templates/server/nestjs-todo/nest-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "collection": "@nestjs/schematics", 3 | "sourceRoot": "src" 4 | } 5 | -------------------------------------------------------------------------------- /templates/server/nestjs-auth/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jherr/create-mf-app/HEAD/templates/server/nestjs-auth/.DS_Store -------------------------------------------------------------------------------- /templates/library/typescript/src/index.ts: -------------------------------------------------------------------------------- 1 | const addNumbers = (a: number, b: number): number => a + b; 2 | export default addNumbers; 3 | -------------------------------------------------------------------------------- /templates/application-extras/tailwind/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | "@tailwindcss/postcss": {}, 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /templates/server/nestjs-auth/public/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jherr/create-mf-app/HEAD/templates/server/nestjs-auth/public/.DS_Store -------------------------------------------------------------------------------- /templates/application/vanilla/module-federation.config.ts: -------------------------------------------------------------------------------- 1 | export const mfConfig = { 2 | name: "{{SAFE_NAME}}", 3 | exposes: {}, 4 | shared: [], 5 | }; 6 | -------------------------------------------------------------------------------- /templates/application/vue3/module-federation.config.ts: -------------------------------------------------------------------------------- 1 | export const mfConfig = { 2 | name: "{{SAFE_NAME}}", 3 | exposes: {}, 4 | shared: ["vue"], 5 | }; 6 | -------------------------------------------------------------------------------- /templates/server/nestjs-auth/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /templates/server/nestjs-todo/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /templates/application/preact/module-federation.config.ts: -------------------------------------------------------------------------------- 1 | export const mfConfig = { 2 | name: "{{SAFE_NAME}}", 3 | exposes: {}, 4 | shared: ["preact"], 5 | }; 6 | -------------------------------------------------------------------------------- /templates/application/svelte/module-federation.config.ts: -------------------------------------------------------------------------------- 1 | export const mfConfig = { 2 | name: "{{SAFE_NAME}}", 3 | exposes: {}, 4 | shared: ["svelte"], 5 | }; 6 | -------------------------------------------------------------------------------- /templates/application/svelte/src/App.svelte: -------------------------------------------------------------------------------- 1 |
2 |
Name: {{ NAME }}
3 |
Framework: {{ FRAMEWORK }}
4 |
5 | -------------------------------------------------------------------------------- /templates/application/lit-html/module-federation.config.ts: -------------------------------------------------------------------------------- 1 | export const mfConfig = { 2 | name: "{{SAFE_NAME}}", 3 | exposes: {}, 4 | shared: ["lit-html"], 5 | }; 6 | -------------------------------------------------------------------------------- /templates/application/solid-js/module-federation.config.ts: -------------------------------------------------------------------------------- 1 | export const mfConfig = { 2 | name: "{{SAFE_NAME}}", 3 | exposes: {}, 4 | shared: ["solid-js"], 5 | }; 6 | -------------------------------------------------------------------------------- /templates/application/react-18/module-federation.config.ts: -------------------------------------------------------------------------------- 1 | export const mfConfig = { 2 | name: "{{SAFE_NAME}}", 3 | exposes: {}, 4 | shared: ["react", "react-dom"], 5 | }; 6 | -------------------------------------------------------------------------------- /templates/application/react-19/module-federation.config.ts: -------------------------------------------------------------------------------- 1 | export const mfConfig = { 2 | name: "{{SAFE_NAME}}", 3 | exposes: {}, 4 | shared: ["react", "react-dom"], 5 | }; 6 | -------------------------------------------------------------------------------- /templates/application/svelte/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-typescript", "@babel/preset-env"], 3 | "plugins": [ 4 | ["@babel/transform-runtime"] 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /templates/application/vanilla/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-typescript", "@babel/preset-env"], 3 | "plugins": [ 4 | ["@babel/transform-runtime"] 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /templates/application/lit-html/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-typescript", "@babel/preset-env"], 3 | "plugins": [ 4 | ["@babel/transform-runtime"] 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /templates/application/vue3/src/bootloader.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from "vue"; 2 | 3 | import "./index.css"; 4 | 5 | import App from "./App.vue"; 6 | 7 | createApp(App).mount("#app"); 8 | -------------------------------------------------------------------------------- /templates/application/react-18/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-typescript", "@babel/preset-react", "@babel/preset-env"], 3 | "plugins": [ 4 | ["@babel/transform-runtime"] 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /templates/application/react-19/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-typescript", "@babel/preset-react", "@babel/preset-env"], 3 | "plugins": [ 4 | ["@babel/transform-runtime"] 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /templates/application/solid-js/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-typescript", "babel-preset-solid", "@babel/preset-env"], 3 | "plugins": [ 4 | ["@babel/transform-runtime"] 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /templates/application/vue3/src/vue-shim.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.vue" { 2 | import { defineComponent } from "vue"; 3 | const Component: ReturnType; 4 | export default Component; 5 | } 6 | -------------------------------------------------------------------------------- /templates/application/preact/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: Arial, Helvetica, sans-serif; 3 | } 4 | 5 | .container { 6 | font-size: 3rem; 7 | margin: auto; 8 | max-width: 800px; 9 | margin-top: 20px; 10 | } -------------------------------------------------------------------------------- /templates/application/svelte/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: Arial, Helvetica, sans-serif; 3 | } 4 | 5 | .container { 6 | font-size: 3rem; 7 | margin: auto; 8 | max-width: 800px; 9 | margin-top: 20px; 10 | } -------------------------------------------------------------------------------- /templates/application/vanilla/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: Arial, Helvetica, sans-serif; 3 | } 4 | 5 | .container { 6 | font-size: 3rem; 7 | margin: auto; 8 | max-width: 800px; 9 | margin-top: 20px; 10 | } -------------------------------------------------------------------------------- /templates/application/vue3/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: Arial, Helvetica, sans-serif; 3 | } 4 | 5 | .container { 6 | font-size: 3rem; 7 | margin: auto; 8 | max-width: 800px; 9 | margin-top: 20px; 10 | } -------------------------------------------------------------------------------- /templates/application/lit-html/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: Arial, Helvetica, sans-serif; 3 | } 4 | 5 | .container { 6 | font-size: 3rem; 7 | margin: auto; 8 | max-width: 800px; 9 | margin-top: 20px; 10 | } -------------------------------------------------------------------------------- /templates/application/react-18/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: Arial, Helvetica, sans-serif; 3 | } 4 | 5 | .container { 6 | font-size: 3rem; 7 | margin: auto; 8 | max-width: 800px; 9 | margin-top: 20px; 10 | } -------------------------------------------------------------------------------- /templates/application/react-19/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: Arial, Helvetica, sans-serif; 3 | } 4 | 5 | .container { 6 | font-size: 3rem; 7 | margin: auto; 8 | max-width: 800px; 9 | margin-top: 20px; 10 | } -------------------------------------------------------------------------------- /templates/application/solid-js/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: Arial, Helvetica, sans-serif; 3 | } 4 | 5 | .container { 6 | font-size: 3rem; 7 | margin: auto; 8 | max-width: 800px; 9 | margin-top: 20px; 10 | } -------------------------------------------------------------------------------- /templates/server/nestjs-auth/src/auth/jwt-auth.guard.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { AuthGuard } from '@nestjs/passport'; 3 | 4 | @Injectable() 5 | export class JwtAuthGuard extends AuthGuard('jwt') {} 6 | -------------------------------------------------------------------------------- /templates/application/vanilla/src/index.ts: -------------------------------------------------------------------------------- 1 | import "./index.css"; 2 | 3 | document.getElementById("app").innerHTML = ` 4 |
5 |
Name: {{NAME}}
6 |
Framework: {{FRAMEWORK}}
7 |
8 | `; -------------------------------------------------------------------------------- /templates/server/nestjs-auth/src/auth/local-auth.guard.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { AuthGuard } from '@nestjs/passport'; 3 | 4 | @Injectable() 5 | export class LocalAuthGuard extends AuthGuard('local') {} 6 | -------------------------------------------------------------------------------- /templates/server/nestjs-todo/src/app.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { TodosModule } from './modules/todos/todo.module'; 3 | 4 | @Module({ 5 | imports: [TodosModule], 6 | }) 7 | export class AppModule {} 8 | -------------------------------------------------------------------------------- /templates/application/svelte/src/bootloader.ts: -------------------------------------------------------------------------------- 1 | import App from "./App.svelte"; 2 | 3 | import "./index.css"; 4 | 5 | const app = new App({ 6 | target: document.getElementById("app"), 7 | }); 8 | 9 | window.app = app; 10 | 11 | export default app; 12 | -------------------------------------------------------------------------------- /templates/server/nestjs-todo/src/modules/todos/todo.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | 3 | import { TodosController } from './todo.controller'; 4 | 5 | @Module({ 6 | controllers: [TodosController], 7 | }) 8 | export class TodosModule {} 9 | -------------------------------------------------------------------------------- /templates/server/nestjs-auth/test/jest-e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "moduleFileExtensions": ["js", "json", "ts"], 3 | "rootDir": ".", 4 | "testEnvironment": "node", 5 | "testRegex": ".e2e-spec.ts$", 6 | "transform": { 7 | "^.+\\.(t|j)s$": "ts-jest" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /templates/server/nestjs-todo/test/jest-e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "moduleFileExtensions": ["js", "json", "ts"], 3 | "rootDir": ".", 4 | "testEnvironment": "node", 5 | "testRegex": ".e2e-spec.ts$", 6 | "transform": { 7 | "^.+\\.(t|j)s$": "ts-jest" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /templates/server/nestjs-auth/src/users/users.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | 3 | import { UsersService } from './users.service'; 4 | 5 | @Module({ 6 | providers: [UsersService], 7 | exports: [UsersService], 8 | }) 9 | export class UsersModule {} 10 | -------------------------------------------------------------------------------- /templates/server/nestjs-auth/src/modules/authorized/authorized.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | 3 | import { AuthorizedController } from './authorized.controller'; 4 | 5 | @Module({ 6 | controllers: [AuthorizedController], 7 | }) 8 | export class AuthorizedModule {} 9 | -------------------------------------------------------------------------------- /templates/server/nestjs-auth/src/modules/unauthorized/unauthorized.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | 3 | import { UnauthorizedController } from './unauthorized.controller'; 4 | 5 | @Module({ 6 | controllers: [UnauthorizedController], 7 | }) 8 | export class UnauthorizedModule {} 9 | -------------------------------------------------------------------------------- /templates/server/nestjs-todo/src/main.ts: -------------------------------------------------------------------------------- 1 | import { NestFactory } from '@nestjs/core'; 2 | import { AppModule } from './app.module'; 3 | 4 | async function bootstrap() { 5 | const app = await NestFactory.create(AppModule); 6 | app.enableCors(); 7 | await app.listen({{PORT}}); 8 | } 9 | bootstrap(); 10 | -------------------------------------------------------------------------------- /templates/library/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{NAME}}", 3 | "version": "1.0.0", 4 | "main": "dist/index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "build": "tsc", 8 | "watch": "tsc --watch" 9 | }, 10 | "devDependencies": { 11 | "typescript": "^4.4.4" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # https://docs.npmjs.com/misc/developers#keeping-files-out-of-your-package 2 | 3 | #node 4 | yarn.lock 5 | 6 | #misc 7 | .husky 8 | assets 9 | 10 | #tests 11 | test 12 | coverage 13 | 14 | #linters 15 | .eslintrc* 16 | .eslintignore 17 | 18 | #editor settings 19 | .vscode 20 | .idea 21 | .editorconfig -------------------------------------------------------------------------------- /templates/server/nestjs-auth/src/main.ts: -------------------------------------------------------------------------------- 1 | import { NestFactory } from '@nestjs/core'; 2 | 3 | import { AppModule } from './app.module'; 4 | 5 | async function bootstrap() { 6 | const app = await NestFactory.create(AppModule); 7 | app.enableCors(); 8 | await app.listen({{PORT}}); 9 | } 10 | bootstrap(); 11 | -------------------------------------------------------------------------------- /templates/application/lit-html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {{NAME}} 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /templates/application/preact/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {{NAME}} 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /templates/application/react-18/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {{NAME}} 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /templates/application/react-19/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {{NAME}} 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /templates/application/solid-js/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {{NAME}} 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /templates/application/svelte/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {{NAME}} 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /templates/application/vanilla/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {{NAME}} 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /templates/application/vue3/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {{NAME}} 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /templates/server/express/index.ts: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | 3 | const app = express(); 4 | const port = {{PORT}}; 5 | 6 | app.get("/", (req, res) => { 7 | res.send("Hello from {{NAME}}"); 8 | }); 9 | 10 | app.listen(port, () => { 11 | console.log(`{{NAME}} listening at http://localhost:${port}`); 12 | }); 13 | -------------------------------------------------------------------------------- /templates/application/lit-html/src/App.ts: -------------------------------------------------------------------------------- 1 | import { html, render } from "lit-html"; 2 | 3 | import "./index.css"; 4 | 5 | const myTemplate = html`
6 |
Name: {{ NAME }}
7 |
Framework: {{ FRAMEWORK }}
8 |
`; 9 | 10 | render(myTemplate, document.getElementById("app")); 11 | -------------------------------------------------------------------------------- /templates/server/graphql-nexus/gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.o 3 | *.pyc 4 | *.d 5 | .DS_Store* 6 | *.swp 7 | 8 | obj/ 9 | lib/ 10 | bin/ 11 | build/ 12 | build-dep-src/ 13 | build-dep-install/ 14 | python/nexus/proto/ 15 | python/nexus.egg-info/ 16 | 17 | cmake-build*/ 18 | .clion.source.upload.marker 19 | .clangd/ 20 | compile_commands.json -------------------------------------------------------------------------------- /templates/application/preact/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { render, h } from "preact"; 2 | 3 | import "./index.css"; 4 | 5 | const App = () => ( 6 |
7 |
Name: {{ NAME }}
8 |
Framework: {{ FRAMEWORK }}
9 |
10 | ); 11 | 12 | render(, document.getElementById("app")); 13 | -------------------------------------------------------------------------------- /templates/application/solid-js/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { render } from "solid-js/web"; 2 | 3 | import "./index.css"; 4 | 5 | const App = () => ( 6 |
7 |
Name: {{ NAME }}
8 |
Framework: {{ FRAMEWORK }}
9 |
10 | ); 11 | 12 | render(App, document.getElementById("app")); 13 | -------------------------------------------------------------------------------- /templates/application/vue3/src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 13 | -------------------------------------------------------------------------------- /templates/server/nestjs-auth/src/modules/unauthorized/unauthorized.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller, Get, Param } from '@nestjs/common'; 2 | 3 | @Controller('unauthorized') 4 | export class UnauthorizedController { 5 | constructor() {} 6 | 7 | @Get() 8 | async index(): Promise { 9 | return true; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /templates/server/express/gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store* 3 | Icon? 4 | ._* 5 | 6 | # Windows 7 | Thumbs.db 8 | ehthumbs.db 9 | Desktop.ini 10 | 11 | # Linux 12 | .directory 13 | *~ 14 | 15 | 16 | # npm 17 | node_modules 18 | package-lock.json 19 | *.log 20 | *.gz 21 | 22 | 23 | # Coveralls 24 | coverage 25 | 26 | # Benchmarking 27 | benchmarks/graphs -------------------------------------------------------------------------------- /templates/application/preact/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-react", 5 | { 6 | "runtime": "automatic", 7 | "importSource": "preact" 8 | } 9 | ] 10 | ], 11 | "plugins": [ 12 | ["@babel/plugin-transform-react-jsx", { 13 | "pragma": "h", 14 | "pragmaFrag": "Fragment" 15 | }] 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "outDir": ".", 5 | "module": "commonjs", 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "strict": true, 9 | "skipLibCheck": true 10 | }, 11 | "include": ["src/**/*", "bin/**/*"], 12 | "exclude": ["node_modules", "src/__tests__/**/*"] 13 | } 14 | -------------------------------------------------------------------------------- /templates/server/express/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{NAME}}", 3 | "version": "1.0.0", 4 | "license": "MIT", 5 | "scripts": { 6 | "start": "ts-node index.ts" 7 | }, 8 | "dependencies": { 9 | "express": "^4.17.1" 10 | }, 11 | "devDependencies": { 12 | "@types/express": "^4.17.13", 13 | "ts-node": "^10.4.0", 14 | "typescript": "^4.4.4" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /templates/application/react-19/src/App.tsx: -------------------------------------------------------------------------------- 1 | import ReactDOM from "react-dom/client"; 2 | 3 | import "./index.css"; 4 | 5 | const App = () => ( 6 |
7 |
Name: {{ NAME }}
8 |
Framework: {{ FRAMEWORK }}
9 |
10 | ); 11 | 12 | const root = ReactDOM.createRoot(document.getElementById("app") as HTMLElement); 13 | 14 | root.render(); -------------------------------------------------------------------------------- /templates/library/typescript/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | typescript@^4.4.4: 6 | version "4.4.4" 7 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.4.tgz#2cd01a1a1f160704d3101fd5a58ff0f9fcb8030c" 8 | integrity sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA== 9 | -------------------------------------------------------------------------------- /templates/application/react-18/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom/client"; 3 | 4 | import "./index.css"; 5 | 6 | const App = () => ( 7 |
8 |
Name: {{ NAME }}
9 |
Framework: {{ FRAMEWORK }}
10 |
11 | ); 12 | 13 | const root = ReactDOM.createRoot(document.getElementById("app") as HTMLElement); 14 | root.render(); -------------------------------------------------------------------------------- /templates/server/nestjs-auth/src/modules/authorized/authorized.controller.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Controller, 3 | Get, 4 | Request, 5 | UseGuards, 6 | } from '@nestjs/common'; 7 | import { JwtAuthGuard } from '../../auth/jwt-auth.guard'; 8 | 9 | @Controller('authorized') 10 | export class AuthorizedController { 11 | constructor() {} 12 | 13 | @Get() 14 | @UseGuards(JwtAuthGuard) 15 | async index(@Request() req): Promise<{userId: number}> { 16 | return { userId: req.user.userId }; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import tseslint from "typescript-eslint"; 2 | 3 | /** @type {import('eslint').Linter.Config[]} */ 4 | export default { 5 | plugins: { 6 | "@typescript-eslint": tseslint.plugin, 7 | }, 8 | languageOptions: { 9 | parser: tseslint.parser, 10 | parserOptions: { 11 | projectService: true, 12 | tsconfigRootDir: import.meta.dirname, 13 | }, 14 | }, 15 | files: ["bin/*.ts", "src/*.ts"], 16 | ignores: ["bin/*.js", "src/*.js", "templates", "node_modules"], 17 | }; 18 | -------------------------------------------------------------------------------- /templates/server/nestjs-auth/src/app.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller, Post, UseGuards, Request } from '@nestjs/common'; 2 | import { LocalAuthGuard } from './auth/local-auth.guard'; 3 | import { AuthService } from './auth/auth.service'; 4 | 5 | @Controller() 6 | export class AppController { 7 | constructor(private authService: AuthService) {} 8 | 9 | @UseGuards(LocalAuthGuard) 10 | @Post('auth/login') 11 | async login(@Request() req) { 12 | return this.authService.login(req.user); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /templates/server/graphql-apollo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{NAME}}", 3 | "version": "1.0.0", 4 | "license": "MIT", 5 | "scripts": { 6 | "start": "ts-node src/index.ts", 7 | "dev": "tsnd --respawn src/index.ts", 8 | "build": "tsc", 9 | "serve": "node dist/index.js" 10 | }, 11 | "dependencies": { 12 | "apollo-server": "^3.4.0", 13 | "graphql": "^15.6.1" 14 | }, 15 | "devDependencies": { 16 | "ts-node": "^10.4.0", 17 | "ts-node-dev": "^1.1.8", 18 | "typescript": "^4.4.4" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /templates/server/graphql-apollo/gitignore: -------------------------------------------------------------------------------- 1 | # Ignore the compiled output. 2 | dist/ 3 | 4 | # TypeScript incremental compilation cache 5 | *.tsbuildinfo 6 | 7 | # Logs 8 | logs 9 | *.log 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Coverage (from Jest) 15 | coverage/ 16 | 17 | # JUnit Reports (used mainly in CircleCI) 18 | reports/ 19 | junit.xml 20 | 21 | # Node modules 22 | node_modules/ 23 | 24 | # Mac OS 25 | .DS_Store 26 | 27 | # Intellij Configuration Files 28 | .idea/ 29 | 30 | # Local Netlify folder 31 | .netlify -------------------------------------------------------------------------------- /templates/server/graphql-subscriptions/gitignore: -------------------------------------------------------------------------------- 1 | # Ignore the compiled output. 2 | dist/ 3 | 4 | # TypeScript incremental compilation cache 5 | *.tsbuildinfo 6 | 7 | # Logs 8 | logs 9 | *.log 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Coverage (from Jest) 15 | coverage/ 16 | 17 | # JUnit Reports (used mainly in CircleCI) 18 | reports/ 19 | junit.xml 20 | 21 | # Node modules 22 | node_modules/ 23 | 24 | # Mac OS 25 | .DS_Store 26 | 27 | # Intellij Configuration Files 28 | .idea/ 29 | 30 | # Local Netlify folder 31 | .netlify -------------------------------------------------------------------------------- /templates/server/graphql-nexus/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{NAME}}", 3 | "version": "1.0.0", 4 | "license": "MIT", 5 | "scripts": { 6 | "start": "ts-node src/index.ts", 7 | "dev": "tsnd --respawn src/index.ts", 8 | "build": "tsc", 9 | "serve": "node dist/index.js" 10 | }, 11 | "dependencies": { 12 | "apollo-server": "^3.4.0", 13 | "graphql": "^15.6.1", 14 | "nexus": "^1.1.0" 15 | }, 16 | "devDependencies": { 17 | "ts-node": "^10.4.0", 18 | "ts-node-dev": "^1.1.8", 19 | "typescript": "^4.4.4" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /templates/server/nestjs-auth/gitignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist 3 | /node_modules 4 | 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | pnpm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | lerna-debug.log* 13 | 14 | # OS 15 | .DS_Store 16 | 17 | # Tests 18 | /coverage 19 | /.nyc_output 20 | 21 | # IDEs and editors 22 | /.idea 23 | .project 24 | .classpath 25 | .c9/ 26 | *.launch 27 | .settings/ 28 | *.sublime-workspace 29 | 30 | # IDE - VSCode 31 | .vscode/* 32 | !.vscode/settings.json 33 | !.vscode/tasks.json 34 | !.vscode/launch.json 35 | !.vscode/extensions.json -------------------------------------------------------------------------------- /templates/server/nestjs-todo/gitignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist 3 | /node_modules 4 | 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | pnpm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | lerna-debug.log* 13 | 14 | # OS 15 | .DS_Store 16 | 17 | # Tests 18 | /coverage 19 | /.nyc_output 20 | 21 | # IDEs and editors 22 | /.idea 23 | .project 24 | .classpath 25 | .c9/ 26 | *.launch 27 | .settings/ 28 | *.sublime-workspace 29 | 30 | # IDE - VSCode 31 | .vscode/* 32 | !.vscode/settings.json 33 | !.vscode/tasks.json 34 | !.vscode/launch.json 35 | !.vscode/extensions.json -------------------------------------------------------------------------------- /templates/application/vue3/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "lib": ["DOM", "ES2020"], 5 | "module": "ESNext", 6 | "jsx": "react-jsx", 7 | "strict": true, 8 | "noEmit": true, 9 | "skipLibCheck": true, 10 | "isolatedModules": true, 11 | "resolveJsonModule": true, 12 | "moduleResolution": "bundler", 13 | "useDefineForClassFields": true, 14 | "allowImportingTsExtensions": true, 15 | "paths": { 16 | "*": ["./@mf-types/*"] 17 | } 18 | }, 19 | "include": ["src"], 20 | "ts-node": { 21 | "compilerOptions": { 22 | "module": "CommonJS" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /templates/server/nestjs-auth/src/users/users.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | 3 | export type User = { 4 | userId: number; 5 | username: string; 6 | password: string; 7 | }; 8 | 9 | @Injectable() 10 | export class UsersService { 11 | private readonly users = [ 12 | { 13 | userId: 1, 14 | username: 'sally', 15 | password: '123', 16 | }, 17 | { 18 | userId: 2, 19 | username: 'maria', 20 | password: '123', 21 | }, 22 | ]; 23 | 24 | async findOne(username: string): Promise { 25 | return this.users.find((user) => user.username === username); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /templates/application/lit-html/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "lib": ["DOM", "ES2020"], 5 | "module": "ESNext", 6 | "jsx": "react-jsx", 7 | "strict": true, 8 | "noEmit": true, 9 | "skipLibCheck": true, 10 | "isolatedModules": true, 11 | "resolveJsonModule": true, 12 | "moduleResolution": "bundler", 13 | "useDefineForClassFields": true, 14 | "allowImportingTsExtensions": true, 15 | "paths": { 16 | "*": ["./@mf-types/*"] 17 | } 18 | }, 19 | "include": ["src"], 20 | "ts-node": { 21 | "compilerOptions": { 22 | "module": "CommonJS" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /templates/application/react-18/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "lib": ["DOM", "ES2020"], 5 | "module": "ESNext", 6 | "jsx": "react-jsx", 7 | "strict": true, 8 | "noEmit": true, 9 | "skipLibCheck": true, 10 | "isolatedModules": true, 11 | "resolveJsonModule": true, 12 | "moduleResolution": "bundler", 13 | "useDefineForClassFields": true, 14 | "allowImportingTsExtensions": true, 15 | "paths": { 16 | "*": ["./@mf-types/*"] 17 | } 18 | }, 19 | "include": ["src"], 20 | "ts-node": { 21 | "compilerOptions": { 22 | "module": "CommonJS" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /templates/application/react-19/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "lib": ["DOM", "ES2020"], 5 | "module": "ESNext", 6 | "jsx": "react-jsx", 7 | "strict": true, 8 | "noEmit": true, 9 | "skipLibCheck": true, 10 | "isolatedModules": true, 11 | "resolveJsonModule": true, 12 | "moduleResolution": "bundler", 13 | "useDefineForClassFields": true, 14 | "allowImportingTsExtensions": true, 15 | "paths": { 16 | "*": ["./@mf-types/*"] 17 | } 18 | }, 19 | "include": ["src"], 20 | "ts-node": { 21 | "compilerOptions": { 22 | "module": "CommonJS" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /templates/application/svelte/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "lib": ["DOM", "ES2020"], 5 | "module": "ESNext", 6 | "jsx": "react-jsx", 7 | "strict": true, 8 | "noEmit": true, 9 | "skipLibCheck": true, 10 | "isolatedModules": true, 11 | "resolveJsonModule": true, 12 | "moduleResolution": "bundler", 13 | "useDefineForClassFields": true, 14 | "allowImportingTsExtensions": true, 15 | "paths": { 16 | "*": ["./@mf-types/*"] 17 | } 18 | }, 19 | "include": ["src"], 20 | "ts-node": { 21 | "compilerOptions": { 22 | "module": "CommonJS" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /templates/application/vanilla/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "lib": ["DOM", "ES2020"], 5 | "module": "ESNext", 6 | "jsx": "react-jsx", 7 | "strict": true, 8 | "noEmit": true, 9 | "skipLibCheck": true, 10 | "isolatedModules": true, 11 | "resolveJsonModule": true, 12 | "moduleResolution": "bundler", 13 | "useDefineForClassFields": true, 14 | "allowImportingTsExtensions": true, 15 | "paths": { 16 | "*": ["./@mf-types/*"] 17 | } 18 | }, 19 | "include": ["src"], 20 | "ts-node": { 21 | "compilerOptions": { 22 | "module": "CommonJS" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /templates/server/nestjs-auth/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "declaration": true, 5 | "removeComments": true, 6 | "emitDecoratorMetadata": true, 7 | "experimentalDecorators": true, 8 | "allowSyntheticDefaultImports": true, 9 | "target": "es2017", 10 | "sourceMap": true, 11 | "outDir": "./dist", 12 | "baseUrl": "./", 13 | "incremental": true, 14 | "skipLibCheck": true, 15 | "strictNullChecks": false, 16 | "noImplicitAny": false, 17 | "strictBindCallApply": false, 18 | "forceConsistentCasingInFileNames": false, 19 | "noFallthroughCasesInSwitch": false 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /templates/server/nestjs-todo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "declaration": true, 5 | "removeComments": true, 6 | "emitDecoratorMetadata": true, 7 | "experimentalDecorators": true, 8 | "allowSyntheticDefaultImports": true, 9 | "target": "es2017", 10 | "sourceMap": true, 11 | "outDir": "./dist", 12 | "baseUrl": "./", 13 | "incremental": true, 14 | "skipLibCheck": true, 15 | "strictNullChecks": false, 16 | "noImplicitAny": false, 17 | "strictBindCallApply": false, 18 | "forceConsistentCasingInFileNames": false, 19 | "noFallthroughCasesInSwitch": false 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /templates/server/nestjs-auth/src/auth/jwt.strategy.ts: -------------------------------------------------------------------------------- 1 | import { ExtractJwt, Strategy } from 'passport-jwt'; 2 | import { PassportStrategy } from '@nestjs/passport'; 3 | import { Injectable } from '@nestjs/common'; 4 | 5 | import { jwtConstants } from './constants'; 6 | 7 | @Injectable() 8 | export class JwtStrategy extends PassportStrategy(Strategy) { 9 | constructor() { 10 | super({ 11 | jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), 12 | ignoreExpiration: false, 13 | secretOrKey: jwtConstants.secret, 14 | }); 15 | } 16 | 17 | async validate(payload: any) { 18 | return { userId: payload.sub, username: payload.username }; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /templates/application/preact/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "lib": ["DOM", "ES2020"], 5 | "module": "ESNext", 6 | "jsx": "react-jsx", 7 | "jsxImportSource": "preact", 8 | "strict": true, 9 | "noEmit": true, 10 | "skipLibCheck": true, 11 | "isolatedModules": true, 12 | "resolveJsonModule": true, 13 | "moduleResolution": "bundler", 14 | "useDefineForClassFields": true, 15 | "allowImportingTsExtensions": true, 16 | "paths": { 17 | "*": ["./@mf-types/*"] 18 | } 19 | }, 20 | "include": ["src"], 21 | "ts-node": { 22 | "compilerOptions": { 23 | "module": "CommonJS" 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /templates/application/solid-js/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "lib": ["DOM", "ES2020"], 5 | "module": "ESNext", 6 | "jsx": "react-jsx", 7 | "jsxImportSource": "preact", 8 | "strict": true, 9 | "noEmit": true, 10 | "skipLibCheck": true, 11 | "isolatedModules": true, 12 | "resolveJsonModule": true, 13 | "moduleResolution": "bundler", 14 | "useDefineForClassFields": true, 15 | "allowImportingTsExtensions": true, 16 | "paths": { 17 | "*": ["./@mf-types/*"] 18 | } 19 | }, 20 | "include": ["src"], 21 | "ts-node": { 22 | "compilerOptions": { 23 | "module": "CommonJS" 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /templates/server/nestjs-auth/src/auth/local.strategy.ts: -------------------------------------------------------------------------------- 1 | import { Strategy } from 'passport-local'; 2 | import { PassportStrategy } from '@nestjs/passport'; 3 | import { Injectable, UnauthorizedException } from '@nestjs/common'; 4 | import { AuthService } from './auth.service'; 5 | 6 | @Injectable() 7 | export class LocalStrategy extends PassportStrategy(Strategy) { 8 | constructor(private authService: AuthService) { 9 | super(); 10 | } 11 | 12 | async validate(username: string, password: string): Promise { 13 | const user = await this.authService.validateUser(username, password); 14 | if (!user) { 15 | throw new UnauthorizedException(); 16 | } 17 | return user; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /templates/server/graphql-apollo/src/index.ts: -------------------------------------------------------------------------------- 1 | import { ApolloServer, gql } from "apollo-server"; 2 | 3 | const typeDefs = gql` 4 | type Book { 5 | title: String 6 | author: String 7 | } 8 | 9 | type Query { 10 | books: [Book] 11 | } 12 | `; 13 | 14 | const books = [ 15 | { 16 | title: "The Awakening", 17 | author: "Kate Chopin", 18 | }, 19 | { 20 | title: "City of Glass", 21 | author: "Paul Auster", 22 | }, 23 | ]; 24 | 25 | const resolvers = { 26 | Query: { 27 | books: () => books, 28 | }, 29 | }; 30 | 31 | const server = new ApolloServer({ typeDefs, resolvers }); 32 | 33 | server.listen({ port: {{PORT}} }).then(({ url }) => { 34 | console.log(`🚀 {{NAME}} ready at ${url}`); 35 | }); 36 | -------------------------------------------------------------------------------- /templates/server/graphql-subscriptions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{NAME}}", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "start": "ts-node src/index.ts", 8 | "dev": "tsnd --respawn src/index.ts", 9 | "build": "tsc", 10 | "serve": "node dist/index.js" 11 | }, 12 | "dependencies": { 13 | "@graphql-tools/schema": "^7.1.5", 14 | "apollo-server-express": "3.1.2", 15 | "express": "^4.17.1", 16 | "graphql": "^15.5.1", 17 | "graphql-subscriptions": "^1.2.1", 18 | "subscriptions-transport-ws": "^0.9.19" 19 | }, 20 | "devDependencies": { 21 | "ts-node": "^10.4.0", 22 | "ts-node-dev": "^1.1.8", 23 | "typescript": "^4.4.4" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /templates/application/lit-html/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{NAME}}", 3 | "version": "0.0.1", 4 | "scripts": { 5 | "build": "NODE_ENV=production rspack build", 6 | "build:dev": "NODE_ENV=development rspack build", 7 | "build:start": "cd dist && rspack serve", 8 | "start": "NODE_ENV=development rspack serve" 9 | }, 10 | "devDependencies": { 11 | "@rspack/cli": "~1.2.0", 12 | "@rspack/core": "~1.2.0", 13 | "autoprefixer": "^10.1.0", 14 | "css-loader": "^7.1.2", 15 | "postcss": "^8.2.1", 16 | "postcss-loader": "^8.0.0", 17 | "ts-node": "^10.9.2", 18 | "typescript": "^5.7.3" 19 | }, 20 | "dependencies": { 21 | "@module-federation/enhanced": "^0.8.9", 22 | "lit-html": "^2.0.1" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /templates/server/nestjs-auth/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | parserOptions: { 4 | project: 'tsconfig.json', 5 | sourceType: 'module', 6 | }, 7 | plugins: ['@typescript-eslint/eslint-plugin'], 8 | extends: [ 9 | 'plugin:@typescript-eslint/recommended', 10 | 'plugin:prettier/recommended', 11 | ], 12 | root: true, 13 | env: { 14 | node: true, 15 | jest: true, 16 | }, 17 | ignorePatterns: ['.eslintrc.js'], 18 | rules: { 19 | '@typescript-eslint/interface-name-prefix': 'off', 20 | '@typescript-eslint/explicit-function-return-type': 'off', 21 | '@typescript-eslint/explicit-module-boundary-types': 'off', 22 | '@typescript-eslint/no-explicit-any': 'off', 23 | }, 24 | }; 25 | -------------------------------------------------------------------------------- /templates/server/nestjs-todo/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | parserOptions: { 4 | project: 'tsconfig.json', 5 | sourceType: 'module', 6 | }, 7 | plugins: ['@typescript-eslint/eslint-plugin'], 8 | extends: [ 9 | 'plugin:@typescript-eslint/recommended', 10 | 'plugin:prettier/recommended', 11 | ], 12 | root: true, 13 | env: { 14 | node: true, 15 | jest: true, 16 | }, 17 | ignorePatterns: ['.eslintrc.js'], 18 | rules: { 19 | '@typescript-eslint/interface-name-prefix': 'off', 20 | '@typescript-eslint/explicit-function-return-type': 'off', 21 | '@typescript-eslint/explicit-module-boundary-types': 'off', 22 | '@typescript-eslint/no-explicit-any': 'off', 23 | }, 24 | }; 25 | -------------------------------------------------------------------------------- /templates/application/vanilla/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{NAME}}", 3 | "version": "0.0.1", 4 | "scripts": { 5 | "build": "NODE_ENV=production rspack build", 6 | "build:dev": "NODE_ENV=development rspack build", 7 | "build:start": "cd dist && rspack serve", 8 | "start": "NODE_ENV=development rspack serve" 9 | }, 10 | "devDependencies": { 11 | "@rspack/cli": "~1.2.0", 12 | "@rspack/core": "~1.2.0", 13 | "@rspack/plugin-react-refresh": "~1.0.1", 14 | "autoprefixer": "^10.1.0", 15 | "css-loader": "^7.1.2", 16 | "postcss": "^8.2.1", 17 | "postcss-loader": "^8.0.0", 18 | "ts-node": "^10.9.2", 19 | "typescript": "^5.7.3" 20 | }, 21 | "dependencies": { 22 | "@module-federation/enhanced": "^0.8.9" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /templates/server/nestjs-auth/test/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { INestApplication } from '@nestjs/common'; 3 | import * as request from 'supertest'; 4 | import { AppModule } from './../src/app.module'; 5 | 6 | describe('AppController (e2e)', () => { 7 | let app: INestApplication; 8 | 9 | beforeEach(async () => { 10 | const moduleFixture: TestingModule = await Test.createTestingModule({ 11 | imports: [AppModule], 12 | }).compile(); 13 | 14 | app = moduleFixture.createNestApplication(); 15 | await app.init(); 16 | }); 17 | 18 | it('/ (GET)', () => { 19 | return request(app.getHttpServer()) 20 | .get('/') 21 | .expect(200) 22 | .expect('Hello World!'); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /templates/server/nestjs-todo/test/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { INestApplication } from '@nestjs/common'; 3 | import * as request from 'supertest'; 4 | import { AppModule } from './../src/app.module'; 5 | 6 | describe('AppController (e2e)', () => { 7 | let app: INestApplication; 8 | 9 | beforeEach(async () => { 10 | const moduleFixture: TestingModule = await Test.createTestingModule({ 11 | imports: [AppModule], 12 | }).compile(); 13 | 14 | app = moduleFixture.createNestApplication(); 15 | await app.init(); 16 | }); 17 | 18 | it('/ (GET)', () => { 19 | return request(app.getHttpServer()) 20 | .get('/') 21 | .expect(200) 22 | .expect('Hello World!'); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /templates/server/nestjs-auth/src/auth/auth.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { PassportModule } from '@nestjs/passport'; 3 | import { JwtModule } from '@nestjs/jwt'; 4 | 5 | import { AuthService } from './auth.service'; 6 | import { LocalStrategy } from './local.strategy'; 7 | import { JwtStrategy } from './jwt.strategy'; 8 | import { UsersModule } from '../users/users.module'; 9 | import { jwtConstants } from './constants'; 10 | 11 | @Module({ 12 | imports: [ 13 | UsersModule, 14 | PassportModule, 15 | JwtModule.register({ 16 | secret: jwtConstants.secret, 17 | signOptions: { expiresIn: '24h' }, 18 | }), 19 | ], 20 | providers: [AuthService, LocalStrategy, JwtStrategy], 21 | exports: [AuthService], 22 | }) 23 | export class AuthModule {} 24 | -------------------------------------------------------------------------------- /templates/server/graphql-nexus/src/index.ts: -------------------------------------------------------------------------------- 1 | import { ApolloServer } from "apollo-server"; 2 | import { queryType, stringArg, makeSchema } from "nexus"; 3 | import * as path from "path"; 4 | 5 | const Query = queryType({ 6 | definition(t) { 7 | t.string("hello", { 8 | args: { name: stringArg() }, 9 | resolve: (parent, { name }) => `Hello ${name || "World"}!`, 10 | }); 11 | }, 12 | }); 13 | 14 | const schema = makeSchema({ 15 | types: [Query], 16 | outputs: { 17 | schema: path.join(__dirname, "/generated/schema.graphql"), 18 | typegen: path.join(__dirname, "/generated/typings.ts"), 19 | }, 20 | }); 21 | 22 | const server = new ApolloServer({ schema }); 23 | 24 | server.listen({ port: {{PORT}} }).then(({ url }) => { 25 | console.log(`🚀 {{NAME}} ready at ${url}`); 26 | }); 27 | -------------------------------------------------------------------------------- /templates/application/svelte/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{NAME}}", 3 | "version": "0.0.1", 4 | "scripts": { 5 | "build": "NODE_ENV=production rspack build", 6 | "build:dev": "NODE_ENV=development rspack build", 7 | "build:start": "cd dist && rspack serve", 8 | "start": "NODE_ENV=development rspack serve" 9 | }, 10 | "devDependencies": { 11 | "@rspack/cli": "~1.2.0", 12 | "@rspack/core": "~1.2.0", 13 | "autoprefixer": "^10.1.0", 14 | "css-loader": "^7.1.2", 15 | "postcss": "^8.2.1", 16 | "postcss-loader": "^8.0.0", 17 | "svelte-loader": "^3.1.9", 18 | "svelte-preprocess": "^5.1.3", 19 | "ts-node": "^10.9.2", 20 | "typescript": "^5.7.3" 21 | }, 22 | "dependencies": { 23 | "@module-federation/enhanced": "^0.8.9", 24 | "svelte": "^4.2.9" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /templates/server/nestjs-auth/src/app.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { ServeStaticModule } from '@nestjs/serve-static'; 3 | import { join } from 'path'; 4 | 5 | import { AuthorizedModule } from './modules/authorized/authorized.module'; 6 | import { UnauthorizedModule } from './modules/unauthorized/unauthorized.module'; 7 | import { AppController } from './app.controller'; 8 | import { AuthModule } from './auth/auth.module'; 9 | import { UsersService } from './users/users.service'; 10 | 11 | @Module({ 12 | controllers: [AppController], 13 | providers: [UsersService], 14 | imports: [ 15 | ServeStaticModule.forRoot({ 16 | rootPath: join(__dirname, '..', 'public'), 17 | }), 18 | AuthorizedModule, 19 | UnauthorizedModule, 20 | AuthModule, 21 | ], 22 | }) 23 | export class AppModule {} 24 | -------------------------------------------------------------------------------- /templates/application/preact/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{NAME}}", 3 | "version": "0.0.1", 4 | "scripts": { 5 | "build": "NODE_ENV=production rspack build", 6 | "build:dev": "NODE_ENV=development rspack build", 7 | "build:start": "cd dist && rspack serve", 8 | "start": "NODE_ENV=development rspack serve" 9 | }, 10 | "devDependencies": { 11 | "@rspack/cli": "~1.2.0", 12 | "@rspack/core": "~1.2.0", 13 | "@rspack/plugin-react-refresh": "~1.0.1", 14 | "autoprefixer": "^10.1.0", 15 | "css-loader": "^7.1.2", 16 | "postcss": "^8.2.1", 17 | "postcss-loader": "^8.0.0", 18 | "react-refresh": "^0.14.0", 19 | "ts-node": "^10.9.2", 20 | "typescript": "^5.7.3" 21 | }, 22 | "dependencies": { 23 | "@module-federation/enhanced": "^0.8.9", 24 | "preact": "^10.5.14", 25 | "preact-jsx-runtime": "^1.2.0" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /templates/server/nestjs-auth/src/auth/auth.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { JwtService } from '@nestjs/jwt'; 3 | 4 | import { UsersService } from '../users/users.service'; 5 | 6 | @Injectable() 7 | export class AuthService { 8 | constructor( 9 | private usersService: UsersService, 10 | private jwtService: JwtService, 11 | ) {} 12 | 13 | async validateUser(username: string, pass: string): Promise { 14 | const user = await this.usersService.findOne(username); 15 | if (user && user.password === pass) { 16 | const { password, ...result } = user; 17 | return result; 18 | } 19 | return null; 20 | } 21 | 22 | async login(user: any) { 23 | const payload = { username: user.username, sub: user.userId }; 24 | return { 25 | access_token: this.jwtService.sign(payload), 26 | }; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /templates/application/vue3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{NAME}}", 3 | "version": "0.0.1", 4 | "scripts": { 5 | "build": "NODE_ENV=production rspack build", 6 | "build:dev": "NODE_ENV=development rspack build", 7 | "build:start": "cd dist && rspack serve", 8 | "start": "NODE_ENV=development rspack serve" 9 | }, 10 | "devDependencies": { 11 | "@babel/preset-env": "^7.23.8", 12 | "@babel/preset-typescript": "^7.23.3", 13 | "@rspack/cli": "~1.2.0", 14 | "@rspack/core": "~1.2.0", 15 | "autoprefixer": "^10.1.0", 16 | "css-loader": "^7.1.2", 17 | "postcss": "^8.2.1", 18 | "postcss-loader": "^8.0.0", 19 | "ts-node": "^10.9.2", 20 | "typescript": "^5.7.3", 21 | "vue-loader": "^16.8.1", 22 | "vue-template-compiler": "^2.6.14" 23 | }, 24 | "dependencies": { 25 | "@module-federation/enhanced": "^0.8.9", 26 | "vue": "^3.2.19" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /templates/application/react-18/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{NAME}}", 3 | "version": "0.0.1", 4 | "scripts": { 5 | "build": "NODE_ENV=production rspack build", 6 | "build:dev": "NODE_ENV=development rspack build", 7 | "build:start": "cd dist && rspack serve", 8 | "start": "NODE_ENV=development rspack serve" 9 | }, 10 | "devDependencies": { 11 | "@rspack/cli": "~1.2.0", 12 | "@rspack/core": "~1.2.0", 13 | "@rspack/plugin-react-refresh": "~1.0.1", 14 | "@types/react": "^18.2.0", 15 | "@types/react-dom": "^18.2.0", 16 | "autoprefixer": "^10.1.0", 17 | "css-loader": "^7.1.2", 18 | "postcss": "^8.2.1", 19 | "postcss-loader": "^8.0.0", 20 | "react-refresh": "^0.14.0", 21 | "ts-node": "^10.9.2", 22 | "typescript": "^5.7.3" 23 | }, 24 | "dependencies": { 25 | "@module-federation/enhanced": "^0.8.9", 26 | "react": "^18.2.0", 27 | "react-dom": "^18.2.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /templates/application/react-19/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{NAME}}", 3 | "version": "0.0.1", 4 | "scripts": { 5 | "build": "NODE_ENV=production rspack build", 6 | "build:dev": "NODE_ENV=development rspack build", 7 | "build:start": "cd dist && rspack serve", 8 | "start": "NODE_ENV=development rspack serve" 9 | }, 10 | "devDependencies": { 11 | "@rspack/cli": "~1.2.0", 12 | "@rspack/core": "~1.2.0", 13 | "@rspack/plugin-react-refresh": "~1.0.1", 14 | "@types/react": "^19.0.0", 15 | "@types/react-dom": "^19.0.0", 16 | "autoprefixer": "^10.1.0", 17 | "css-loader": "^7.1.2", 18 | "postcss": "^8.2.1", 19 | "postcss-loader": "^8.0.0", 20 | "react-refresh": "^0.14.0", 21 | "ts-node": "^10.9.2", 22 | "typescript": "^5.7.3" 23 | }, 24 | "dependencies": { 25 | "@module-federation/enhanced": "^0.8.9", 26 | "react": "^19.0.0", 27 | "react-dom": "^19.0.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /templates/application/solid-js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{NAME}}", 3 | "version": "0.0.1", 4 | "scripts": { 5 | "build": "NODE_ENV=production rspack build", 6 | "build:dev": "NODE_ENV=development rspack build", 7 | "build:start": "cd dist && rspack serve", 8 | "start": "NODE_ENV=development rspack serve" 9 | }, 10 | "devDependencies": { 11 | "@rspack/cli": "~1.2.0", 12 | "@rspack/core": "~1.2.0", 13 | "@babel/plugin-transform-runtime": "^7.23.7", 14 | "@babel/preset-env": "^7.23.8", 15 | "@babel/preset-typescript": "^7.23.3", 16 | "autoprefixer": "^10.1.0", 17 | "babel-loader": "^9.1.3", 18 | "babel-preset-solid": "^1.8.9", 19 | "css-loader": "^7.1.2", 20 | "postcss": "^8.2.1", 21 | "postcss-loader": "^8.0.0", 22 | "solid-refresh": "^0.6.3", 23 | "ts-node": "^10.9.2", 24 | "typescript": "^5.7.3" 25 | }, 26 | "dependencies": { 27 | "@module-federation/enhanced": "^0.8.9", 28 | "solid-js": "^1.8.11" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Jack Herrington 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-mf-app", 3 | "version": "2.0.3", 4 | "description": "Create Module Federation apps", 5 | "main": "src/index.js", 6 | "bin": "bin/create-mf-app.js", 7 | "scripts": { 8 | "start": "tsc && node bin/create-mf-app.js", 9 | "build": "tsc", 10 | "lint": "eslint --fix", 11 | "prepare": "husky install", 12 | "test": "vitest run", 13 | "test:watch": "vitest watch" 14 | }, 15 | "author": "Jack Herrington", 16 | "license": "MIT", 17 | "dependencies": { 18 | "@clack/prompts": "^0.9.1", 19 | "commander": "^13.1.0", 20 | "ejs": "^3.1.10", 21 | "glob": "^11.0.1" 22 | }, 23 | "devDependencies": { 24 | "@types/ejs": "^3.1.5", 25 | "@types/glob": "^8.1.0", 26 | "@types/node": "^22.13.0", 27 | "@typescript-eslint/eslint-plugin": "^7.7.0", 28 | "@typescript-eslint/parser": "^7.7.0", 29 | "eslint": "^9.19.0", 30 | "globals": "^15.14.0", 31 | "husky": "^7.0.4", 32 | "prettier": "^3.4.2", 33 | "ts-node": "^10.9.2", 34 | "typescript": "^4.5.3", 35 | "typescript-eslint": "^8.22.0", 36 | "vitest": "^1.4.0" 37 | }, 38 | "packageManager": "pnpm@9.1.4" 39 | } 40 | -------------------------------------------------------------------------------- /templates/server/nestjs-auth/README.md: -------------------------------------------------------------------------------- 1 | Static files are served out of the public directory. 2 | 3 | ``` 4 | $ curl http://localhost:{{PORT}}/placeholder.txt 5 | $ # result -> Put your static files in this directory and then delete this file. 6 | ``` 7 | 8 | You can have un-authorized routes. 9 | 10 | ``` 11 | $ curl http://localhost:{{PORT}}/unauthorized 12 | $ # result -> true 13 | ``` 14 | 15 | Trying authorized routes without a JWT will result in a 401. 16 | 17 | ``` 18 | $ curl http://localhost:{{PORT}}/authorized 19 | $ # result -> {"statusCode":401,"message":"Unauthorized"} 20 | ``` 21 | 22 | Use the `/auth/login` route to login. 23 | 24 | ``` 25 | $ # POST /auth/login 26 | $ curl -X POST http://localhost:{{PORT}}/auth/login -d '{"username": "maria", "password": "123"}' -H "Content-Type: application/json" 27 | $ # result -> {"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2Vybm... } 28 | ``` 29 | 30 | Send the JWT to authorized routes using the `Authorization` header and prefixing the JWT with `Bearer `. 31 | 32 | ``` 33 | $ # GET /profile using access_token returned from previous step as bearer code 34 | $ curl http://localhost:{{PORT}}/authorized -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2Vybm..." 35 | $ # result -> {"userId":2} 36 | ``` 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # create-mf-app 2 | 3 | [![npm version](https://badge.fury.io/js/create-mf-app.svg)](https://badge.fury.io/js/create-mf-app) [![npm version](https://img.shields.io/npm/dm/create-mf-app.svg)](https://badge.fury.io/js/create-mf-app) 4 | 5 | Creates a Module Federation application, API server, or library based on one of multiple different templates. 6 | 7 | ## Usage 8 | 9 | ```shell 10 | npx create-mf-app 11 | ``` 12 | 13 | These projects are not production complete. They are designed as lightweight projects that can be used to quickly prototype a new feature or library. 14 | 15 | ## CLI Usage 16 | 17 | Without any arguments, the CLI will prompt you for the information required to create the project. 18 | 19 | ```shell 20 | npx create-mf-app@latest 21 | ``` 22 | 23 | You can also get help for the CLI for the options available. 24 | 25 | ```shell 26 | npx create-mf-app@latest --help 27 | ``` 28 | 29 | You can create an application using CLI options: 30 | 31 | ```shell 32 | npx create-mf-app@latest --name my-remote --port 8080 --css Tailwind --template react-19 33 | ``` 34 | 35 | Shorthand versions of each option are also available: 36 | 37 | ```shell 38 | npx create-mf-app@latest -n my-remote -p 8080 -c Tailwind -t react-19 39 | ``` 40 | 41 | ## Programmatic Usage 42 | 43 | ```js 44 | const { buildProject } = require("create-mf-app"); 45 | 46 | buildProject({ 47 | type: "Application", 48 | name: "my-remote", 49 | port: "8080", 50 | framework: "react-19", 51 | css: "Tailwind", 52 | }); 53 | ``` 54 | -------------------------------------------------------------------------------- /templates/server/nestjs-todo/src/modules/todos/todo.controller.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Controller, 3 | Get, 4 | Post, 5 | Put, 6 | Delete, 7 | Body, 8 | Param, 9 | HttpCode, 10 | } from '@nestjs/common'; 11 | 12 | interface Todo { 13 | id: number; 14 | text: string; 15 | active: boolean; 16 | done: boolean; 17 | } 18 | 19 | let todos: Todo[] = [ 20 | 'NestJS', 21 | 'GraphQL', 22 | 'Apollo', 23 | 'TypeScript', 24 | 'React', 25 | 'Redux', 26 | 'React Query', 27 | 'Angular', 28 | 'Vue', 29 | 'D3', 30 | 'Svelte', 31 | 'SolidJS', 32 | 'NextJS', 33 | 'AWS', 34 | ].map((text, index) => ({ 35 | id: index + 1, 36 | text: `Learn ${text}`, 37 | active: true, 38 | done: false, 39 | })); 40 | 41 | @Controller('todos') 42 | export class TodosController { 43 | constructor() {} 44 | 45 | @Get() 46 | async index(): Promise { 47 | return todos.filter(({ active }) => active); 48 | } 49 | 50 | @Get(':id') 51 | async show(@Param('id') id: string): Promise { 52 | return todos.find((todo) => todo.id === parseInt(id)); 53 | } 54 | 55 | @Post() 56 | async create(@Body() { text }: { text: string }): Promise { 57 | const todo = { 58 | id: todos.length + 1, 59 | text, 60 | active: true, 61 | done: false, 62 | }; 63 | todos.push(todo); 64 | return todo; 65 | } 66 | 67 | @Put(':id') 68 | async update(@Param('id') id: string, @Body() data: Todo): Promise { 69 | todos = todos.map((todo) => 70 | todo.id === parseInt(id) ? { ...todo, ...data } : todo, 71 | ); 72 | 73 | return data; 74 | } 75 | 76 | @Delete(':id') 77 | @HttpCode(204) 78 | async destroy(@Param('id') id: string): Promise { 79 | todos = todos.map((todo) => 80 | todo.id === parseInt(id) ? { ...todo, active: false } : todo, 81 | ); 82 | return parseInt(id); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /templates/server/graphql-subscriptions/src/index.ts: -------------------------------------------------------------------------------- 1 | import { createServer } from "http"; 2 | import express from "express"; 3 | import { execute, subscribe } from "graphql"; 4 | import { ApolloServer, gql } from "apollo-server-express"; 5 | import { PubSub } from "graphql-subscriptions"; 6 | import { SubscriptionServer } from "subscriptions-transport-ws"; 7 | import { makeExecutableSchema } from "@graphql-tools/schema"; 8 | 9 | (async () => { 10 | const PORT = {{PORT}}; 11 | const pubsub = new PubSub(); 12 | const app = express(); 13 | const httpServer = createServer(app); 14 | 15 | // Schema definition 16 | const typeDefs = gql` 17 | type Query { 18 | currentNumber: Int 19 | } 20 | 21 | type Subscription { 22 | numberIncremented: Int 23 | } 24 | `; 25 | 26 | // Resolver map 27 | const resolvers = { 28 | Query: { 29 | currentNumber() { 30 | return currentNumber; 31 | }, 32 | }, 33 | Subscription: { 34 | numberIncremented: { 35 | subscribe: () => pubsub.asyncIterator(["NUMBER_INCREMENTED"]), 36 | }, 37 | }, 38 | }; 39 | 40 | const schema = makeExecutableSchema({ typeDefs, resolvers }); 41 | 42 | const server = new ApolloServer({ 43 | schema, 44 | }); 45 | await server.start(); 46 | server.applyMiddleware({ app }); 47 | 48 | SubscriptionServer.create( 49 | { schema, execute, subscribe }, 50 | { server: httpServer, path: server.graphqlPath } 51 | ); 52 | 53 | httpServer.listen(PORT, () => { 54 | console.log( 55 | `🚀 {{NAME}} Query endpoint ready at http://localhost:${PORT}${server.graphqlPath}` 56 | ); 57 | console.log( 58 | `🚀 {{NAME}} Subscription endpoint ready at ws://localhost:${PORT}${server.graphqlPath}` 59 | ); 60 | }); 61 | 62 | let currentNumber = 0; 63 | function incrementNumber() { 64 | currentNumber++; 65 | pubsub.publish("NUMBER_INCREMENTED", { numberIncremented: currentNumber }); 66 | setTimeout(incrementNumber, 1000); 67 | } 68 | // Start incrementing 69 | incrementNumber(); 70 | })(); 71 | -------------------------------------------------------------------------------- /templates/application/solid-js/rspack.config.ts.ejs: -------------------------------------------------------------------------------- 1 | import * as path from "node:path"; 2 | import { defineConfig } from "@rspack/cli"; 3 | import { rspack } from "@rspack/core"; 4 | import { ModuleFederationPlugin } from "@module-federation/enhanced/rspack"; 5 | 6 | import { mfConfig } from "./module-federation.config"; 7 | 8 | const isDev = process.env.NODE_ENV === "development"; 9 | 10 | // Target browsers, see: https://github.com/browserslist/browserslist 11 | const targets = ["chrome >= 87", "edge >= 88", "firefox >= 78", "safari >= 14"]; 12 | 13 | export default defineConfig({ 14 | context: __dirname, 15 | entry: { 16 | main: "./src/index.ts", 17 | }, 18 | resolve: { 19 | extensions: ["...", ".ts", ".tsx", ".jsx"], 20 | }, 21 | 22 | devServer: { 23 | port: <%= PORT %>, 24 | historyApiFallback: true, 25 | watchFiles: [path.resolve(__dirname, "src")], 26 | }, 27 | output: { 28 | // You need to set a unique value that is not equal to other applications 29 | uniqueName: "<%= SAFE_NAME %>", 30 | // publicPath must be configured if using manifest 31 | publicPath: "http://localhost:<%= PORT %>/", 32 | }, 33 | 34 | experiments: { 35 | css: true, 36 | }, 37 | 38 | module: { 39 | rules: [ 40 | { 41 | test: /\.svg$/, 42 | type: "asset", 43 | }, 44 | { 45 | test: /\.css$/, 46 | use: ["postcss-loader"], 47 | type: "css", 48 | }, 49 | { 50 | test: /\.jsx|\.tsx$/, 51 | use: [ 52 | { 53 | loader: 'babel-loader', 54 | options: { 55 | presets: [['solid']], 56 | plugins: ['solid-refresh/babel'], 57 | }, 58 | }, 59 | ], 60 | }, 61 | ], 62 | }, 63 | plugins: [ 64 | new rspack.HtmlRspackPlugin({ 65 | template: "./index.html", 66 | }), 67 | new ModuleFederationPlugin(mfConfig), 68 | ].filter(Boolean), 69 | optimization: { 70 | minimizer: [ 71 | new rspack.SwcJsMinimizerRspackPlugin(), 72 | new rspack.LightningCssMinimizerRspackPlugin({ 73 | minimizerOptions: { targets }, 74 | }), 75 | ], 76 | }, 77 | }); 78 | -------------------------------------------------------------------------------- /templates/application/lit-html/rspack.config.ts.ejs: -------------------------------------------------------------------------------- 1 | import * as path from "node:path"; 2 | import { defineConfig } from "@rspack/cli"; 3 | import { rspack } from "@rspack/core"; 4 | import { ModuleFederationPlugin } from "@module-federation/enhanced/rspack"; 5 | 6 | import { mfConfig } from "./module-federation.config"; 7 | 8 | // Target browsers, see: https://github.com/browserslist/browserslist 9 | const targets = ["chrome >= 87", "edge >= 88", "firefox >= 78", "safari >= 14"]; 10 | 11 | export default defineConfig({ 12 | context: __dirname, 13 | entry: { 14 | main: "./src/index.ts", 15 | }, 16 | resolve: { 17 | extensions: ["...", ".ts", ".tsx", ".jsx"], 18 | }, 19 | 20 | devServer: { 21 | port: <%= PORT %>, 22 | historyApiFallback: true, 23 | watchFiles: [path.resolve(__dirname, "src")], 24 | }, 25 | output: { 26 | // You need to set a unique value that is not equal to other applications 27 | uniqueName: "<%= SAFE_NAME %>", 28 | // publicPath must be configured if using manifest 29 | publicPath: "http://localhost:<%= PORT %>/", 30 | }, 31 | 32 | experiments: { 33 | css: true, 34 | }, 35 | 36 | module: { 37 | rules: [ 38 | { 39 | test: /\.svg$/, 40 | type: "asset", 41 | }, 42 | { 43 | test: /\.css$/, 44 | use: ["postcss-loader"], 45 | type: "css", 46 | }, 47 | { 48 | test: /\.(jsx?|tsx?)$/, 49 | use: [ 50 | { 51 | loader: "builtin:swc-loader", 52 | options: { 53 | jsc: { 54 | parser: { 55 | syntax: "typescript", 56 | tsx: true, 57 | }, 58 | }, 59 | env: { targets }, 60 | }, 61 | }, 62 | ], 63 | }, 64 | ], 65 | }, 66 | plugins: [ 67 | new rspack.HtmlRspackPlugin({ 68 | template: "./index.html", 69 | }), 70 | new ModuleFederationPlugin(mfConfig), 71 | ].filter(Boolean), 72 | optimization: { 73 | minimizer: [ 74 | new rspack.SwcJsMinimizerRspackPlugin(), 75 | new rspack.LightningCssMinimizerRspackPlugin({ 76 | minimizerOptions: { targets }, 77 | }), 78 | ], 79 | }, 80 | }); 81 | -------------------------------------------------------------------------------- /templates/application/vanilla/rspack.config.ts.ejs: -------------------------------------------------------------------------------- 1 | import * as path from "node:path"; 2 | import { defineConfig } from "@rspack/cli"; 3 | import { rspack } from "@rspack/core"; 4 | import { ModuleFederationPlugin } from "@module-federation/enhanced/rspack"; 5 | 6 | import { mfConfig } from "./module-federation.config"; 7 | 8 | const isDev = process.env.NODE_ENV === "development"; 9 | 10 | // Target browsers, see: https://github.com/browserslist/browserslist 11 | const targets = ["chrome >= 87", "edge >= 88", "firefox >= 78", "safari >= 14"]; 12 | 13 | export default defineConfig({ 14 | context: __dirname, 15 | entry: { 16 | main: "./src/index.ts", 17 | }, 18 | resolve: { 19 | extensions: ["...", ".ts", ".tsx", ".jsx"], 20 | }, 21 | 22 | devServer: { 23 | port: <%= PORT %>, 24 | historyApiFallback: true, 25 | watchFiles: [path.resolve(__dirname, "src")], 26 | }, 27 | 28 | output: { 29 | // You need to set a unique value that is not equal to other applications 30 | uniqueName: "<%= SAFE_NAME %>", 31 | // publicPath must be configured if using manifest 32 | publicPath: "http://localhost:<%= PORT %>/", 33 | }, 34 | 35 | experiments: { 36 | css: true, 37 | }, 38 | 39 | module: { 40 | rules: [ 41 | { 42 | test: /\.svg$/, 43 | type: "asset", 44 | }, 45 | { 46 | test: /\.css$/, 47 | use: ["postcss-loader"], 48 | type: "css", 49 | }, 50 | { 51 | test: /\.(jsx?|tsx?)$/, 52 | use: [ 53 | { 54 | loader: "builtin:swc-loader", 55 | options: { 56 | jsc: { 57 | parser: { 58 | syntax: "typescript", 59 | tsx: true, 60 | }, 61 | }, 62 | env: { targets }, 63 | }, 64 | }, 65 | ], 66 | }, 67 | ], 68 | }, 69 | plugins: [ 70 | new rspack.HtmlRspackPlugin({ 71 | template: "./index.html", 72 | }), 73 | new ModuleFederationPlugin(mfConfig), 74 | ].filter(Boolean), 75 | optimization: { 76 | minimizer: [ 77 | new rspack.SwcJsMinimizerRspackPlugin(), 78 | new rspack.LightningCssMinimizerRspackPlugin({ 79 | minimizerOptions: { targets }, 80 | }), 81 | ], 82 | }, 83 | }); 84 | -------------------------------------------------------------------------------- /templates/server/nestjs-todo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{NAME}}", 3 | "version": "1.0.0", 4 | "description": "", 5 | "author": "", 6 | "private": true, 7 | "license": "UNLICENSED", 8 | "scripts": { 9 | "prebuild": "rimraf dist", 10 | "build": "nest build", 11 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", 12 | "start": "nest start", 13 | "start:dev": "nest start --watch", 14 | "start:debug": "nest start --debug --watch", 15 | "start:prod": "node dist/main", 16 | "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", 17 | "test": "jest", 18 | "test:watch": "jest --watch", 19 | "test:cov": "jest --coverage", 20 | "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", 21 | "test:e2e": "jest --config ./test/jest-e2e.json" 22 | }, 23 | "dependencies": { 24 | "@nestjs/common": "^8.0.0", 25 | "@nestjs/core": "^8.0.0", 26 | "@nestjs/platform-express": "^8.0.0", 27 | "class-validator": "^0.13.1", 28 | "reflect-metadata": "^0.1.13", 29 | "rimraf": "^3.0.2", 30 | "rxjs": "^7.2.0" 31 | }, 32 | "devDependencies": { 33 | "@nestjs/cli": "^8.0.0", 34 | "@nestjs/schematics": "^8.0.0", 35 | "@nestjs/testing": "^8.0.0", 36 | "@types/express": "^4.17.13", 37 | "@types/jest": "^27.0.1", 38 | "@types/node": "^16.0.0", 39 | "@types/supertest": "^2.0.11", 40 | "@typescript-eslint/eslint-plugin": "^4.28.2", 41 | "@typescript-eslint/parser": "^4.28.2", 42 | "eslint": "^7.30.0", 43 | "eslint-config-prettier": "^8.3.0", 44 | "eslint-plugin-prettier": "^3.4.0", 45 | "jest": "^27.0.6", 46 | "prettier": "^2.3.2", 47 | "supertest": "^6.1.3", 48 | "ts-jest": "^27.0.3", 49 | "ts-loader": "^9.2.3", 50 | "ts-node": "^10.0.0", 51 | "tsconfig-paths": "^3.10.1", 52 | "typescript": "^4.3.5" 53 | }, 54 | "jest": { 55 | "moduleFileExtensions": [ 56 | "js", 57 | "json", 58 | "ts" 59 | ], 60 | "rootDir": "src", 61 | "testRegex": ".*\\.spec\\.ts$", 62 | "transform": { 63 | "^.+\\.(t|j)s$": "ts-jest" 64 | }, 65 | "collectCoverageFrom": [ 66 | "**/*.(t|j)s" 67 | ], 68 | "coverageDirectory": "../coverage", 69 | "testEnvironment": "node" 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /templates/application/preact/gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # Snowpack dependency directory (https://snowpack.dev/) 45 | web_modules/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | .parcel-cache 78 | 79 | # Next.js build output 80 | .next 81 | out 82 | 83 | # Nuxt.js build / generate output 84 | .nuxt 85 | dist 86 | 87 | # Gatsby files 88 | .cache/ 89 | # Comment in the public line in if your project uses Gatsby and not Next.js 90 | # https://nextjs.org/blog/next-9-1#public-directory-support 91 | # public 92 | 93 | # vuepress build output 94 | .vuepress/dist 95 | 96 | # Serverless directories 97 | .serverless/ 98 | 99 | # FuseBox cache 100 | .fusebox/ 101 | 102 | # DynamoDB Local files 103 | .dynamodb/ 104 | 105 | # TernJS port file 106 | .tern-port 107 | 108 | # Stores VSCode versions used for testing VSCode extensions 109 | .vscode-test 110 | 111 | # yarn v2 112 | .yarn/cache 113 | .yarn/unplugged 114 | .yarn/build-state.yml 115 | .yarn/install-state.gz 116 | .pnp.* 117 | -------------------------------------------------------------------------------- /templates/application/svelte/gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # Snowpack dependency directory (https://snowpack.dev/) 45 | web_modules/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | .parcel-cache 78 | 79 | # Next.js build output 80 | .next 81 | out 82 | 83 | # Nuxt.js build / generate output 84 | .nuxt 85 | dist 86 | 87 | # Gatsby files 88 | .cache/ 89 | # Comment in the public line in if your project uses Gatsby and not Next.js 90 | # https://nextjs.org/blog/next-9-1#public-directory-support 91 | # public 92 | 93 | # vuepress build output 94 | .vuepress/dist 95 | 96 | # Serverless directories 97 | .serverless/ 98 | 99 | # FuseBox cache 100 | .fusebox/ 101 | 102 | # DynamoDB Local files 103 | .dynamodb/ 104 | 105 | # TernJS port file 106 | .tern-port 107 | 108 | # Stores VSCode versions used for testing VSCode extensions 109 | .vscode-test 110 | 111 | # yarn v2 112 | .yarn/cache 113 | .yarn/unplugged 114 | .yarn/build-state.yml 115 | .yarn/install-state.gz 116 | .pnp.* 117 | -------------------------------------------------------------------------------- /templates/application/vue3/gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # Snowpack dependency directory (https://snowpack.dev/) 45 | web_modules/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | .parcel-cache 78 | 79 | # Next.js build output 80 | .next 81 | out 82 | 83 | # Nuxt.js build / generate output 84 | .nuxt 85 | dist 86 | 87 | # Gatsby files 88 | .cache/ 89 | # Comment in the public line in if your project uses Gatsby and not Next.js 90 | # https://nextjs.org/blog/next-9-1#public-directory-support 91 | # public 92 | 93 | # vuepress build output 94 | .vuepress/dist 95 | 96 | # Serverless directories 97 | .serverless/ 98 | 99 | # FuseBox cache 100 | .fusebox/ 101 | 102 | # DynamoDB Local files 103 | .dynamodb/ 104 | 105 | # TernJS port file 106 | .tern-port 107 | 108 | # Stores VSCode versions used for testing VSCode extensions 109 | .vscode-test 110 | 111 | # yarn v2 112 | .yarn/cache 113 | .yarn/unplugged 114 | .yarn/build-state.yml 115 | .yarn/install-state.gz 116 | .pnp.* 117 | -------------------------------------------------------------------------------- /templates/application/lit-html/gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # Snowpack dependency directory (https://snowpack.dev/) 45 | web_modules/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | .parcel-cache 78 | 79 | # Next.js build output 80 | .next 81 | out 82 | 83 | # Nuxt.js build / generate output 84 | .nuxt 85 | dist 86 | 87 | # Gatsby files 88 | .cache/ 89 | # Comment in the public line in if your project uses Gatsby and not Next.js 90 | # https://nextjs.org/blog/next-9-1#public-directory-support 91 | # public 92 | 93 | # vuepress build output 94 | .vuepress/dist 95 | 96 | # Serverless directories 97 | .serverless/ 98 | 99 | # FuseBox cache 100 | .fusebox/ 101 | 102 | # DynamoDB Local files 103 | .dynamodb/ 104 | 105 | # TernJS port file 106 | .tern-port 107 | 108 | # Stores VSCode versions used for testing VSCode extensions 109 | .vscode-test 110 | 111 | # yarn v2 112 | .yarn/cache 113 | .yarn/unplugged 114 | .yarn/build-state.yml 115 | .yarn/install-state.gz 116 | .pnp.* 117 | -------------------------------------------------------------------------------- /templates/application/react-18/gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # Snowpack dependency directory (https://snowpack.dev/) 45 | web_modules/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | .parcel-cache 78 | 79 | # Next.js build output 80 | .next 81 | out 82 | 83 | # Nuxt.js build / generate output 84 | .nuxt 85 | dist 86 | 87 | # Gatsby files 88 | .cache/ 89 | # Comment in the public line in if your project uses Gatsby and not Next.js 90 | # https://nextjs.org/blog/next-9-1#public-directory-support 91 | # public 92 | 93 | # vuepress build output 94 | .vuepress/dist 95 | 96 | # Serverless directories 97 | .serverless/ 98 | 99 | # FuseBox cache 100 | .fusebox/ 101 | 102 | # DynamoDB Local files 103 | .dynamodb/ 104 | 105 | # TernJS port file 106 | .tern-port 107 | 108 | # Stores VSCode versions used for testing VSCode extensions 109 | .vscode-test 110 | 111 | # yarn v2 112 | .yarn/cache 113 | .yarn/unplugged 114 | .yarn/build-state.yml 115 | .yarn/install-state.gz 116 | .pnp.* 117 | -------------------------------------------------------------------------------- /templates/application/react-19/gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # Snowpack dependency directory (https://snowpack.dev/) 45 | web_modules/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | .parcel-cache 78 | 79 | # Next.js build output 80 | .next 81 | out 82 | 83 | # Nuxt.js build / generate output 84 | .nuxt 85 | dist 86 | 87 | # Gatsby files 88 | .cache/ 89 | # Comment in the public line in if your project uses Gatsby and not Next.js 90 | # https://nextjs.org/blog/next-9-1#public-directory-support 91 | # public 92 | 93 | # vuepress build output 94 | .vuepress/dist 95 | 96 | # Serverless directories 97 | .serverless/ 98 | 99 | # FuseBox cache 100 | .fusebox/ 101 | 102 | # DynamoDB Local files 103 | .dynamodb/ 104 | 105 | # TernJS port file 106 | .tern-port 107 | 108 | # Stores VSCode versions used for testing VSCode extensions 109 | .vscode-test 110 | 111 | # yarn v2 112 | .yarn/cache 113 | .yarn/unplugged 114 | .yarn/build-state.yml 115 | .yarn/install-state.gz 116 | .pnp.* 117 | -------------------------------------------------------------------------------- /templates/application/solid-js/gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # Snowpack dependency directory (https://snowpack.dev/) 45 | web_modules/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | .parcel-cache 78 | 79 | # Next.js build output 80 | .next 81 | out 82 | 83 | # Nuxt.js build / generate output 84 | .nuxt 85 | dist 86 | 87 | # Gatsby files 88 | .cache/ 89 | # Comment in the public line in if your project uses Gatsby and not Next.js 90 | # https://nextjs.org/blog/next-9-1#public-directory-support 91 | # public 92 | 93 | # vuepress build output 94 | .vuepress/dist 95 | 96 | # Serverless directories 97 | .serverless/ 98 | 99 | # FuseBox cache 100 | .fusebox/ 101 | 102 | # DynamoDB Local files 103 | .dynamodb/ 104 | 105 | # TernJS port file 106 | .tern-port 107 | 108 | # Stores VSCode versions used for testing VSCode extensions 109 | .vscode-test 110 | 111 | # yarn v2 112 | .yarn/cache 113 | .yarn/unplugged 114 | .yarn/build-state.yml 115 | .yarn/install-state.gz 116 | .pnp.* 117 | -------------------------------------------------------------------------------- /templates/application/vanilla/gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # Snowpack dependency directory (https://snowpack.dev/) 45 | web_modules/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | .parcel-cache 78 | 79 | # Next.js build output 80 | .next 81 | out 82 | 83 | # Nuxt.js build / generate output 84 | .nuxt 85 | dist 86 | 87 | # Gatsby files 88 | .cache/ 89 | # Comment in the public line in if your project uses Gatsby and not Next.js 90 | # https://nextjs.org/blog/next-9-1#public-directory-support 91 | # public 92 | 93 | # vuepress build output 94 | .vuepress/dist 95 | 96 | # Serverless directories 97 | .serverless/ 98 | 99 | # FuseBox cache 100 | .fusebox/ 101 | 102 | # DynamoDB Local files 103 | .dynamodb/ 104 | 105 | # TernJS port file 106 | .tern-port 107 | 108 | # Stores VSCode versions used for testing VSCode extensions 109 | .vscode-test 110 | 111 | # yarn v2 112 | .yarn/cache 113 | .yarn/unplugged 114 | .yarn/build-state.yml 115 | .yarn/install-state.gz 116 | .pnp.* 117 | -------------------------------------------------------------------------------- /templates/library/typescript/gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .pnpm-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | *.lcov 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # Snowpack dependency directory (https://snowpack.dev/) 46 | web_modules/ 47 | 48 | # TypeScript cache 49 | *.tsbuildinfo 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Microbundle cache 58 | .rpt2_cache/ 59 | .rts2_cache_cjs/ 60 | .rts2_cache_es/ 61 | .rts2_cache_umd/ 62 | 63 | # Optional REPL history 64 | .node_repl_history 65 | 66 | # Output of 'npm pack' 67 | *.tgz 68 | 69 | # Yarn Integrity file 70 | .yarn-integrity 71 | 72 | # dotenv environment variables file 73 | .env 74 | .env.test 75 | .env.production 76 | 77 | # parcel-bundler cache (https://parceljs.org/) 78 | .cache 79 | .parcel-cache 80 | 81 | # Next.js build output 82 | .next 83 | out 84 | 85 | # Nuxt.js build / generate output 86 | .nuxt 87 | dist 88 | 89 | # Gatsby files 90 | .cache/ 91 | # Comment in the public line in if your project uses Gatsby and not Next.js 92 | # https://nextjs.org/blog/next-9-1#public-directory-support 93 | # public 94 | 95 | # vuepress build output 96 | .vuepress/dist 97 | 98 | # Serverless directories 99 | .serverless/ 100 | 101 | # FuseBox cache 102 | .fusebox/ 103 | 104 | # DynamoDB Local files 105 | .dynamodb/ 106 | 107 | # TernJS port file 108 | .tern-port 109 | 110 | # Stores VSCode versions used for testing VSCode extensions 111 | .vscode-test 112 | 113 | # yarn v2 114 | .yarn/cache 115 | .yarn/unplugged 116 | .yarn/build-state.yml 117 | .yarn/install-state.gz 118 | .pnp.* -------------------------------------------------------------------------------- /templates/application/vue3/rspack.config.ts.ejs: -------------------------------------------------------------------------------- 1 | import * as path from "node:path"; 2 | import { defineConfig } from "@rspack/cli"; 3 | import { rspack } from "@rspack/core"; 4 | import { ModuleFederationPlugin } from "@module-federation/enhanced/rspack"; 5 | import { VueLoaderPlugin } from "vue-loader"; 6 | 7 | import { mfConfig } from "./module-federation.config"; 8 | 9 | const isDev = process.env.NODE_ENV === "development"; 10 | 11 | // Target browsers, see: https://github.com/browserslist/browserslist 12 | const targets = ["chrome >= 87", "edge >= 88", "firefox >= 78", "safari >= 14"]; 13 | 14 | export default defineConfig({ 15 | context: __dirname, 16 | entry: { 17 | main: "./src/index.ts", 18 | }, 19 | resolve: { 20 | extensions: ["...", ".ts", ".tsx", ".jsx"], 21 | }, 22 | 23 | devServer: { 24 | port: <%= PORT %>, 25 | historyApiFallback: true, 26 | watchFiles: [path.resolve(__dirname, "src")], 27 | }, 28 | 29 | output: { 30 | // You need to set a unique value that is not equal to other applications 31 | uniqueName: "<%= SAFE_NAME %>", 32 | // publicPath must be configured if using manifest 33 | publicPath: "http://localhost:<%= PORT %>/", 34 | }, 35 | 36 | experiments: { 37 | css: true, 38 | }, 39 | 40 | module: { 41 | rules: [ 42 | { 43 | test: /\.vue$/, 44 | loader: "vue-loader", 45 | options: { 46 | experimentalInlineMatchResource: true, 47 | }, 48 | }, 49 | { 50 | test: /\.css$/, 51 | use: ["postcss-loader"], 52 | type: "css", 53 | }, 54 | { 55 | test: /\.svg$/, 56 | type: "asset", 57 | }, 58 | { 59 | test: /\.(jsx?|tsx?)$/, 60 | use: [ 61 | { 62 | loader: "builtin:swc-loader", 63 | options: { 64 | jsc: { 65 | parser: { 66 | syntax: "typescript", 67 | tsx: true, 68 | }, 69 | }, 70 | env: { targets }, 71 | }, 72 | }, 73 | ], 74 | }, 75 | ], 76 | }, 77 | plugins: [ 78 | new VueLoaderPlugin(), 79 | new rspack.HtmlRspackPlugin({ 80 | template: "./index.html", 81 | }), 82 | new ModuleFederationPlugin(mfConfig), 83 | ].filter(Boolean), 84 | optimization: { 85 | minimizer: [ 86 | new rspack.SwcJsMinimizerRspackPlugin(), 87 | new rspack.LightningCssMinimizerRspackPlugin({ 88 | minimizerOptions: { targets }, 89 | }), 90 | ], 91 | }, 92 | }); 93 | -------------------------------------------------------------------------------- /templates/server/nestjs-auth/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{{NAME}}", 3 | "version": "1.0.0", 4 | "description": "", 5 | "author": "", 6 | "private": true, 7 | "license": "UNLICENSED", 8 | "scripts": { 9 | "prebuild": "rimraf dist", 10 | "build": "nest build", 11 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", 12 | "start": "nest start", 13 | "start:dev": "nest start --watch", 14 | "start:debug": "nest start --debug --watch", 15 | "start:prod": "node dist/main", 16 | "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", 17 | "test": "jest", 18 | "test:watch": "jest --watch", 19 | "test:cov": "jest --coverage", 20 | "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", 21 | "test:e2e": "jest --config ./test/jest-e2e.json" 22 | }, 23 | "dependencies": { 24 | "@nestjs/common": "^8.0.0", 25 | "@nestjs/core": "^8.0.0", 26 | "@nestjs/jwt": "^8.0.0", 27 | "@nestjs/passport": "^8.0.1", 28 | "@nestjs/platform-express": "^8.0.0", 29 | "@nestjs/serve-static": "^2.2.2", 30 | "class-validator": "^0.13.1", 31 | "jsonwebtoken": "^8.5.1", 32 | "passport": "^0.5.0", 33 | "passport-jwt": "^4.0.0", 34 | "passport-local": "^1.0.0", 35 | "reflect-metadata": "^0.1.13", 36 | "rimraf": "^3.0.2", 37 | "rxjs": "^7.2.0" 38 | }, 39 | "devDependencies": { 40 | "@nestjs/cli": "^8.0.0", 41 | "@nestjs/schematics": "^8.0.0", 42 | "@nestjs/testing": "^8.0.0", 43 | "@types/express": "^4.17.13", 44 | "@types/jest": "^27.0.1", 45 | "@types/node": "^16.0.0", 46 | "@types/passport-jwt": "^3.0.6", 47 | "@types/passport-local": "^1.0.34", 48 | "@types/supertest": "^2.0.11", 49 | "@typescript-eslint/eslint-plugin": "^4.28.2", 50 | "@typescript-eslint/parser": "^4.28.2", 51 | "eslint": "^7.30.0", 52 | "eslint-config-prettier": "^8.3.0", 53 | "eslint-plugin-prettier": "^3.4.0", 54 | "jest": "^27.0.6", 55 | "prettier": "^2.3.2", 56 | "supertest": "^6.1.3", 57 | "ts-jest": "^27.0.3", 58 | "ts-loader": "^9.2.3", 59 | "ts-node": "^10.0.0", 60 | "tsconfig-paths": "^3.10.1", 61 | "typescript": "^4.3.5" 62 | }, 63 | "jest": { 64 | "moduleFileExtensions": [ 65 | "js", 66 | "json", 67 | "ts" 68 | ], 69 | "rootDir": "src", 70 | "testRegex": ".*\\.spec\\.ts$", 71 | "transform": { 72 | "^.+\\.(t|j)s$": "ts-jest" 73 | }, 74 | "collectCoverageFrom": [ 75 | "**/*.(t|j)s" 76 | ], 77 | "coverageDirectory": "../coverage", 78 | "testEnvironment": "node" 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /templates/application/preact/rspack.config.ts.ejs: -------------------------------------------------------------------------------- 1 | import * as path from "node:path"; 2 | import { defineConfig } from "@rspack/cli"; 3 | import { rspack } from "@rspack/core"; 4 | import * as RefreshPlugin from "@rspack/plugin-react-refresh"; 5 | import { ModuleFederationPlugin } from "@module-federation/enhanced/rspack"; 6 | 7 | import { mfConfig } from "./module-federation.config"; 8 | 9 | const isDev = process.env.NODE_ENV === "development"; 10 | 11 | // Target browsers, see: https://github.com/browserslist/browserslist 12 | const targets = ["chrome >= 87", "edge >= 88", "firefox >= 78", "safari >= 14"]; 13 | 14 | export default defineConfig({ 15 | context: __dirname, 16 | entry: { 17 | main: "./src/index.ts", 18 | }, 19 | resolve: { 20 | extensions: ["...", ".ts", ".tsx", ".jsx"], 21 | alias: { 22 | react: "preact/compat", 23 | "react-dom": "preact/compat" 24 | } 25 | }, 26 | 27 | devServer: { 28 | port: <%= PORT %>, 29 | historyApiFallback: true, 30 | watchFiles: [path.resolve(__dirname, "src")], 31 | }, 32 | output: { 33 | // You need to set a unique value that is not equal to other applications 34 | uniqueName: "<%= SAFE_NAME %>", 35 | // publicPath must be configured if using manifest 36 | publicPath: "http://localhost:<%= PORT %>/", 37 | }, 38 | 39 | experiments: { 40 | css: true, 41 | }, 42 | 43 | module: { 44 | rules: [ 45 | { 46 | test: /\.svg$/, 47 | type: "asset", 48 | }, 49 | { 50 | test: /\.css$/, 51 | use: ["postcss-loader"], 52 | type: "css", 53 | }, 54 | { 55 | test: /\.(jsx?|tsx?)$/, 56 | use: [ 57 | { 58 | loader: "builtin:swc-loader", 59 | options: { 60 | jsc: { 61 | parser: { 62 | syntax: "typescript", 63 | tsx: true, 64 | }, 65 | transform: { 66 | react: { 67 | runtime: "automatic", 68 | development: isDev, 69 | refresh: isDev, 70 | }, 71 | }, 72 | }, 73 | env: { targets }, 74 | }, 75 | }, 76 | ], 77 | }, 78 | ], 79 | }, 80 | plugins: [ 81 | new rspack.HtmlRspackPlugin({ 82 | template: "./index.html", 83 | }), 84 | new ModuleFederationPlugin(mfConfig), 85 | isDev ? new RefreshPlugin() : null, 86 | ].filter(Boolean), 87 | optimization: { 88 | minimizer: [ 89 | new rspack.SwcJsMinimizerRspackPlugin(), 90 | new rspack.LightningCssMinimizerRspackPlugin({ 91 | minimizerOptions: { targets }, 92 | }), 93 | ], 94 | }, 95 | }); 96 | -------------------------------------------------------------------------------- /templates/application/react-18/rspack.config.ts.ejs: -------------------------------------------------------------------------------- 1 | import * as path from "node:path"; 2 | import { defineConfig } from "@rspack/cli"; 3 | import { rspack } from "@rspack/core"; 4 | import * as RefreshPlugin from "@rspack/plugin-react-refresh"; 5 | import { ModuleFederationPlugin } from "@module-federation/enhanced/rspack"; 6 | <% if (WITH_ZEPHYR) { %>import { withZephyr } from "zephyr-rspack-plugin";<% } %> 7 | 8 | import { mfConfig } from "./module-federation.config"; 9 | 10 | const isDev = process.env.NODE_ENV === "development"; 11 | 12 | // Target browsers, see: https://github.com/browserslist/browserslist 13 | const targets = ["chrome >= 87", "edge >= 88", "firefox >= 78", "safari >= 14"]; 14 | 15 | <% if (WITH_ZEPHYR) { %>export default withZephyr()({<% } else { %>export default defineConfig({<% } %> 16 | context: __dirname, 17 | entry: { 18 | main: "./src/index.ts", 19 | }, 20 | resolve: { 21 | extensions: ["...", ".ts", ".tsx", ".jsx"], 22 | }, 23 | 24 | devServer: { 25 | port: <%= PORT %>, 26 | historyApiFallback: true, 27 | watchFiles: [path.resolve(__dirname, "src")], 28 | }, 29 | output: { 30 | // You need to set a unique value that is not equal to other applications 31 | uniqueName: "<%= SAFE_NAME %>", 32 | // publicPath must be configured if using manifest 33 | publicPath: "http://localhost:<%= PORT %>/", 34 | }, 35 | 36 | experiments: { 37 | css: true, 38 | }, 39 | 40 | module: { 41 | rules: [ 42 | { 43 | test: /\.svg$/, 44 | type: "asset", 45 | }, 46 | { 47 | test: /\.css$/, 48 | use: ["postcss-loader"], 49 | type: "css", 50 | }, 51 | { 52 | test: /\.(jsx?|tsx?)$/, 53 | use: [ 54 | { 55 | loader: "builtin:swc-loader", 56 | options: { 57 | jsc: { 58 | parser: { 59 | syntax: "typescript", 60 | tsx: true, 61 | }, 62 | transform: { 63 | react: { 64 | runtime: "automatic", 65 | development: isDev, 66 | refresh: isDev, 67 | }, 68 | }, 69 | }, 70 | env: { targets }, 71 | }, 72 | }, 73 | ], 74 | }, 75 | ], 76 | }, 77 | plugins: [ 78 | new rspack.HtmlRspackPlugin({ 79 | template: "./index.html", 80 | }), 81 | new ModuleFederationPlugin(mfConfig), 82 | isDev ? new RefreshPlugin() : null, 83 | ].filter(Boolean), 84 | optimization: { 85 | minimizer: [ 86 | new rspack.SwcJsMinimizerRspackPlugin(), 87 | new rspack.LightningCssMinimizerRspackPlugin({ 88 | minimizerOptions: { targets }, 89 | }), 90 | ], 91 | }, 92 | }); 93 | -------------------------------------------------------------------------------- /templates/application/react-19/rspack.config.ts.ejs: -------------------------------------------------------------------------------- 1 | import * as path from "node:path"; 2 | import { defineConfig } from "@rspack/cli"; 3 | import { rspack } from "@rspack/core"; 4 | import * as RefreshPlugin from "@rspack/plugin-react-refresh"; 5 | import { ModuleFederationPlugin } from "@module-federation/enhanced/rspack"; 6 | <% if (WITH_ZEPHYR) { %>import { withZephyr } from "zephyr-rspack-plugin";<% } %> 7 | 8 | import { mfConfig } from "./module-federation.config"; 9 | 10 | const isDev = process.env.NODE_ENV === "development"; 11 | 12 | // Target browsers, see: https://github.com/browserslist/browserslist 13 | const targets = ["chrome >= 87", "edge >= 88", "firefox >= 78", "safari >= 14"]; 14 | 15 | <% if (WITH_ZEPHYR) { %>export default withZephyr()({<% } else { %>export default defineConfig({<% } %> 16 | context: __dirname, 17 | entry: { 18 | main: "./src/index.ts", 19 | }, 20 | resolve: { 21 | extensions: ["...", ".ts", ".tsx", ".jsx"], 22 | }, 23 | 24 | devServer: { 25 | port: <%= PORT %>, 26 | historyApiFallback: true, 27 | watchFiles: [path.resolve(__dirname, "src")], 28 | }, 29 | output: { 30 | // You need to set a unique value that is not equal to other applications 31 | uniqueName: "<%= SAFE_NAME %>", 32 | // publicPath must be configured if using manifest 33 | publicPath: "http://localhost:<%= PORT %>/", 34 | }, 35 | 36 | experiments: { 37 | css: true, 38 | }, 39 | 40 | module: { 41 | rules: [ 42 | { 43 | test: /\.svg$/, 44 | type: "asset", 45 | }, 46 | { 47 | test: /\.css$/, 48 | use: ["postcss-loader"], 49 | type: "css", 50 | }, 51 | { 52 | test: /\.(jsx?|tsx?)$/, 53 | use: [ 54 | { 55 | loader: "builtin:swc-loader", 56 | options: { 57 | jsc: { 58 | parser: { 59 | syntax: "typescript", 60 | tsx: true, 61 | }, 62 | transform: { 63 | react: { 64 | runtime: "automatic", 65 | development: isDev, 66 | refresh: isDev, 67 | }, 68 | }, 69 | }, 70 | env: { targets }, 71 | }, 72 | }, 73 | ], 74 | }, 75 | ], 76 | }, 77 | plugins: [ 78 | new rspack.HtmlRspackPlugin({ 79 | template: "./index.html", 80 | }), 81 | new ModuleFederationPlugin(mfConfig), 82 | isDev ? new RefreshPlugin() : null, 83 | ].filter(Boolean), 84 | optimization: { 85 | minimizer: [ 86 | new rspack.SwcJsMinimizerRspackPlugin(), 87 | new rspack.LightningCssMinimizerRspackPlugin({ 88 | minimizerOptions: { targets }, 89 | }), 90 | ], 91 | }, 92 | }); 93 | -------------------------------------------------------------------------------- /templates/application/svelte/rspack.config.ts.ejs: -------------------------------------------------------------------------------- 1 | import * as path from "node:path"; 2 | import { defineConfig } from "@rspack/cli"; 3 | import { rspack } from "@rspack/core"; 4 | import { ModuleFederationPlugin } from "@module-federation/enhanced/rspack"; 5 | 6 | const sveltePreprocess = require('svelte-preprocess'); 7 | 8 | import { mfConfig } from "./module-federation.config"; 9 | 10 | const isDev = process.env.NODE_ENV === "development"; 11 | 12 | // Target browsers, see: https://github.com/browserslist/browserslist 13 | const targets = ["chrome >= 87", "edge >= 88", "firefox >= 78", "safari >= 14"]; 14 | 15 | export default defineConfig({ 16 | context: __dirname, 17 | entry: { 18 | main: "./src/index.ts", 19 | }, 20 | resolve: { 21 | extensions: ["...", ".ts", ".tsx", ".jsx"], 22 | }, 23 | 24 | devServer: { 25 | port: <%= PORT %>, 26 | historyApiFallback: true, 27 | watchFiles: [path.resolve(__dirname, "src")], 28 | }, 29 | output: { 30 | // You need to set a unique value that is not equal to other applications 31 | uniqueName: "<%= SAFE_NAME %>", 32 | // publicPath must be configured if using manifest 33 | publicPath: "http://localhost:<%= PORT %>/", 34 | }, 35 | 36 | experiments: { 37 | css: true, 38 | }, 39 | 40 | module: { 41 | rules: [ 42 | { 43 | test: /\.svg$/, 44 | type: "asset", 45 | }, 46 | { 47 | test: /\.css$/, 48 | use: ["postcss-loader"], 49 | type: "css", 50 | }, 51 | { 52 | test: /\.(jsx?|tsx?)$/, 53 | use: [ 54 | { 55 | loader: "builtin:swc-loader", 56 | options: { 57 | jsc: { 58 | parser: { 59 | syntax: "typescript", 60 | tsx: true, 61 | }, 62 | }, 63 | env: { targets }, 64 | }, 65 | }, 66 | ], 67 | }, 68 | { 69 | test: /\.svelte$/, 70 | use: [ 71 | { 72 | loader: 'svelte-loader', 73 | options: { 74 | compilerOptions: { 75 | dev: isDev, 76 | }, 77 | 78 | emitCss: !isDev, 79 | hotReload: isDev, 80 | preprocess: sveltePreprocess({ sourceMap: isDev, postcss: true }), 81 | }, 82 | }, 83 | ], 84 | }, 85 | ], 86 | }, 87 | plugins: [ 88 | new rspack.HtmlRspackPlugin({ 89 | template: "./index.html", 90 | }), 91 | new ModuleFederationPlugin(mfConfig), 92 | ].filter(Boolean), 93 | optimization: { 94 | minimizer: [ 95 | new rspack.SwcJsMinimizerRspackPlugin(), 96 | new rspack.LightningCssMinimizerRspackPlugin({ 97 | minimizerOptions: { targets }, 98 | }), 99 | ], 100 | }, 101 | }); 102 | -------------------------------------------------------------------------------- /src/__tests__/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect, afterEach } from "vitest"; 2 | import fs from "fs"; 3 | import path from "path"; 4 | import { buildProject } from "../index"; 5 | 6 | describe("Project Generation", () => { 7 | const testDir = "test-project"; 8 | 9 | afterEach(() => { 10 | if (fs.existsSync(testDir)) { 11 | fs.rmSync(testDir, { recursive: true }); 12 | } 13 | }); 14 | 15 | describe("Application Projects", () => { 16 | const frameworks = [ 17 | "react-18", 18 | "react-19", 19 | "vue3", 20 | "svelte", 21 | "preact", 22 | "lit-html", 23 | "solid-js", 24 | "vanilla", 25 | ]; 26 | 27 | frameworks.forEach((framework) => { 28 | it(`should generate ${framework} application correctly`, async () => { 29 | await buildProject({ 30 | name: testDir, 31 | framework, 32 | type: "Application", 33 | css: "CSS", 34 | withZephyr: 'no', 35 | }); 36 | 37 | expect(fs.existsSync(testDir)).toBe(true); 38 | expect(fs.existsSync(path.join(testDir, "package.json"))).toBe(true); 39 | expect(fs.existsSync(path.join(testDir, "src"))).toBe(true); 40 | }); 41 | }); 42 | }); 43 | 44 | describe("Library Projects", () => { 45 | it("should generate TypeScript library correctly", async () => { 46 | await buildProject({ 47 | name: testDir, 48 | framework: "typescript", 49 | type: "Library", 50 | css: "CSS", 51 | withZephyr: "no", 52 | }); 53 | 54 | expect(fs.existsSync(testDir)).toBe(true); 55 | expect(fs.existsSync(path.join(testDir, "package.json"))).toBe(true); 56 | expect(fs.existsSync(path.join(testDir, "src"))).toBe(true); 57 | }); 58 | }); 59 | 60 | describe("API Projects", () => { 61 | const frameworks = [ 62 | "express", 63 | "nestjs-auth", 64 | "nestjs-todo", 65 | "graphql-apollo", 66 | "graphql-nexus", 67 | "graphql-subscriptions", 68 | ]; 69 | 70 | frameworks.forEach((framework) => { 71 | it(`should generate ${framework} API correctly`, async () => { 72 | await buildProject({ 73 | name: testDir, 74 | framework, 75 | type: "API", 76 | css: "CSS", 77 | withZephyr: 'no', 78 | }); 79 | 80 | expect(fs.existsSync(testDir)).toBe(true); 81 | expect(fs.existsSync(path.join(testDir, "package.json"))).toBe(true); 82 | // expect(fs.existsSync(path.join(testDir, 'src'))).toBe(true); 83 | }); 84 | }); 85 | }); 86 | 87 | describe("Tailwind Integration", () => { 88 | it("should have correct Tailwind setup", async () => { 89 | await buildProject({ 90 | name: testDir, 91 | framework: "react-18", 92 | type: "Application", 93 | css: "Tailwind", 94 | withZephyr: 'no', 95 | }); 96 | 97 | const indexCssPath = path.join(testDir, "src/index.css"); 98 | const packageJsonPath = path.join(testDir, "package.json"); 99 | 100 | // Verify index.css exists and has correct content 101 | expect(fs.existsSync(indexCssPath)).toBe(true); 102 | const indexCssContent = fs.readFileSync(indexCssPath, "utf-8"); 103 | expect(indexCssContent.trim()).toBe('@import "tailwindcss";'); 104 | 105 | // Verify package.json has correct Tailwind dependencies 106 | const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8")); 107 | expect(packageJson.devDependencies["@tailwindcss/postcss"]).toBe( 108 | "^4.0.3" 109 | ); 110 | expect(packageJson.devDependencies["tailwindcss"]).toBe("^4.0.3"); 111 | }); 112 | }); 113 | }); 114 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import fs from "node:fs"; 2 | import path from "node:path"; 3 | import { glob } from "glob"; 4 | import ejs from "ejs"; 5 | 6 | export type Project = { 7 | framework?: string; 8 | css?: "CSS" | "Tailwind"; 9 | withZephyr: boolean; 10 | port?: number; 11 | name: string; 12 | type: "Application" | "Library" | "API"; 13 | }; 14 | 15 | type Profiler = { 16 | NAME: string; 17 | FRAMEWORK: string | undefined; 18 | SAFE_NAME: string; 19 | PORT?: number; 20 | CSS?: "Tailwind" | "Empty CSS"; 21 | WITH_ZEPHYR: boolean; 22 | CONTAINER?: string; 23 | }; 24 | 25 | const templateFile = (fileName: string, replacements: Profiler) => { 26 | let fileContent = fs.readFileSync(fileName, "utf8").toString(); 27 | 28 | let outputFileName = fileName; 29 | // Allow for EJS templates if there is logic required to process the template 30 | if (fileName.endsWith(".ejs")) { 31 | fs.unlinkSync(fileName); 32 | outputFileName = fileName.replace(".ejs", ""); 33 | fileContent = ejs.render(fileContent, replacements); 34 | } else { 35 | fileContent = Object.entries(replacements).reduce((acc, [key, value]) => { 36 | return acc.replace( 37 | new RegExp(`({{${key}}}|{{ ${key} }})`, "g"), 38 | value?.toString() ?? "" 39 | ); 40 | }, fileContent); 41 | } 42 | 43 | fs.writeFileSync(outputFileName, fileContent); 44 | }; 45 | 46 | // required for npm publish 47 | const renameGitignore = (projectName: string) => { 48 | if (fs.existsSync(path.normalize(`${projectName}/gitignore`))) { 49 | fs.renameSync( 50 | path.normalize(`${projectName}/gitignore`), 51 | path.normalize(`${projectName}/.gitignore`) 52 | ); 53 | } 54 | }; 55 | 56 | const buildProfiler = ({ 57 | type, 58 | framework, 59 | name, 60 | css, 61 | port, 62 | withZephyr, 63 | }: Project) => { 64 | const profiler: Profiler = { 65 | NAME: name, 66 | FRAMEWORK: framework, 67 | SAFE_NAME: name.replace(/-/g, "_").trim(), 68 | WITH_ZEPHYR: withZephyr, 69 | }; 70 | 71 | if (type === "API" || type === "Application") { 72 | profiler.PORT = port; 73 | } 74 | 75 | if (type === "Application") { 76 | const isTailwind = css === "Tailwind"; 77 | profiler.CONTAINER = isTailwind 78 | ? "mt-10 text-3xl mx-auto max-w-6xl" 79 | : "container"; 80 | profiler.CSS = isTailwind ? "Tailwind" : "Empty CSS"; 81 | } 82 | return profiler; 83 | }; 84 | 85 | // I for the life of me, could not get ncp to copy the directory fast enough to 86 | // get the template replacements handled properly. 87 | // So I made this hand rolled function to do it 88 | const copyDirSync = (sourceDir: string, targetDir: string) => { 89 | if (!fs.existsSync(targetDir)) { 90 | fs.mkdirSync(targetDir, { recursive: true }); 91 | } 92 | 93 | const files = fs.readdirSync(sourceDir); 94 | 95 | files.forEach((file) => { 96 | const sourcePath = path.join(sourceDir, file); 97 | const targetPath = path.join(targetDir, file); 98 | 99 | const stats = fs.statSync(sourcePath); 100 | 101 | if (stats.isDirectory()) { 102 | copyDirSync(sourcePath, targetPath); 103 | } else { 104 | fs.copyFileSync(sourcePath, targetPath); 105 | } 106 | }); 107 | }; 108 | 109 | export const buildProject = async (project: Project) => { 110 | const { name, framework, type, withZephyr } = project; 111 | const tempDir = type.toLowerCase(); 112 | const profiler = buildProfiler(project); 113 | 114 | if (type === "Application") { 115 | copyDirSync( 116 | path.join(__dirname, `../templates/${tempDir}/${framework}`), 117 | name 118 | ); 119 | 120 | const pkg = fs.readFileSync(path.join(name, "package.json"), "utf8"); 121 | const packageJSON = JSON.parse(pkg); 122 | packageJSON.devDependencies = packageJSON.devDependencies || {}; 123 | 124 | if (project.css === "Tailwind") { 125 | await copyDirSync( 126 | path.join(__dirname, "../templates/application-extras/tailwind"), 127 | name 128 | ); 129 | packageJSON.devDependencies["@tailwindcss/postcss"] = "^4.0.3"; 130 | packageJSON.devDependencies["tailwindcss"] = "^4.0.3"; 131 | } 132 | 133 | if (withZephyr) { 134 | packageJSON.dependencies["zephyr-rspack-plugin"] = "^0.0.50"; 135 | } 136 | 137 | await fs.writeFileSync( 138 | path.join(name, "package.json"), 139 | JSON.stringify(packageJSON, null, 2) 140 | ); 141 | } 142 | if (type === "Library") { 143 | await copyDirSync( 144 | path.join(__dirname, `../templates/${tempDir}/typescript`), 145 | name 146 | ); 147 | } 148 | if (type === "API") { 149 | await copyDirSync( 150 | path.join(__dirname, `../templates/server/${framework}`), 151 | name 152 | ); 153 | } 154 | 155 | renameGitignore(name); 156 | 157 | const files = glob.sync(`${name}/**/*`); 158 | for (const file of files) { 159 | if (fs.lstatSync(file).isFile()) { 160 | templateFile(file, profiler); 161 | } 162 | } 163 | }; 164 | -------------------------------------------------------------------------------- /bin/create-mf-app.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import { 3 | intro, 4 | outro, 5 | text, 6 | isCancel, 7 | cancel, 8 | select, 9 | spinner, 10 | } from "@clack/prompts"; 11 | import fs from "node:fs"; 12 | import path from "node:path"; 13 | import { program } from "commander"; 14 | 15 | import { buildProject, Project } from "../src"; 16 | 17 | const applicationTemplates = fs 18 | .readdirSync(path.join(__dirname, "../templates/application")) 19 | .sort(); 20 | 21 | const serverTemplates = fs 22 | .readdirSync(path.join(__dirname, "../templates/server")) 23 | .sort(); 24 | 25 | const templates = [ 26 | ...applicationTemplates.map((t) => ({ 27 | framework: t, 28 | type: "Application", 29 | })), 30 | ...serverTemplates.map((t) => ({ 31 | framework: t, 32 | type: "Server", 33 | })), 34 | { 35 | framework: "library", 36 | type: "Library", 37 | }, 38 | ]; 39 | 40 | program 41 | .option("-n, --name ", "The name of the project") 42 | .option( 43 | "-t, --template