diff --git a/README.md b/README.md index 59649ad..a2141fb 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Seedling is a project generator for @prokyon libraries. 1. Create file `.npmrc` 2. Paste content to file `@toolkit:registry=https://npm.romanjaros.dev` -3. Use `pnpm dlx @toolkit/seedling --name hello-world --port 90 --monorepo T ./app` +3. Use `pnpm dlx @toolkit/seedling --name hello-world --port 90 ./app` - instead of `./app` use can use curent folder, `.` or `./` 4. Use `pnpm dev` to start @@ -20,10 +20,6 @@ Seedling is a project generator for @prokyon libraries. - define port for application when is deployed - number -### monorepo -- define if generated structure will be for monorepo -- value `T` = `true` or `F` = `false` - ### context - last parameter is folder as destination of generated code - string \ No newline at end of file diff --git a/create.js b/create.js index abef25e..abafdf4 100644 --- a/create.js +++ b/create.js @@ -6,7 +6,6 @@ const argv = require('minimist')(process.argv.slice(2)); // questions const appName = argv.name ?? 'app'; const appPort = argv.port ?? '0'; -const isMonorepo = argv.monorepo === 'T'; const defaultContextDir = './'; const rootDir = __dirname; @@ -14,18 +13,19 @@ const contextDir = `${argv._[0]}/` ?? defaultContextDir; // create app folder const appsDir = `${contextDir}/apps`; -const appDir = isMonorepo ? `${contextDir}/apps/${appName}-fe` : `${contextDir}/`; +const uiDir = `${contextDir}/apps/${appName}-ui`; +const apiDir = `${contextDir}/apps/${appName}-api`; // prepare structure folders -if (!fs.existsSync(appDir)) { +if (!fs.existsSync(uiDir)) { if (!fs.existsSync(contextDir)) { fs.mkdirSync(contextDir); } - if (isMonorepo) { - fs.mkdirSync(appsDir); - } - fs.mkdirSync(appDir); - fs.mkdirSync(`${appDir}/src`); + fs.mkdirSync(appsDir); + fs.mkdirSync(uiDir); + fs.mkdirSync(`${uiDir}/src`); + fs.mkdirSync(apiDir); + fs.mkdirSync(`${apiDir}/src`); } // copy folder content @@ -34,7 +34,11 @@ try { force: true, recursive: true, }); - fs.cpSync(`${rootDir}/source/app/`, appDir, { + fs.cpSync(`${rootDir}/source/ui/`, uiDir, { + force: true, + recursive: true, + }); + fs.cpSync(`${rootDir}/source/api/`, apiDir, { force: true, recursive: true, }); @@ -50,7 +54,8 @@ fs.renameSync(`${contextDir}/npmrc`, `${contextDir}/.npmrc`); fs.renameSync(`${contextDir}/gitignore`, `${contextDir}/.gitignore`); fs.renameSync(`${contextDir}/prettierrc`, `${contextDir}/.prettierrc`); fs.renameSync(`${contextDir}/.tsconfig.json`, `${contextDir}/tsconfig.json`); -fs.renameSync(`${appDir}/.tsconfig.json`, `${appDir}/tsconfig.json`); +fs.renameSync(`${uiDir}/.tsconfig.json`, `${uiDir}/tsconfig.json`); +fs.renameSync(`${apiDir}/.tsconfig.json`, `${apiDir}/tsconfig.json`); // replace in files replaceInFiles.sync({ diff --git a/source/api/.tsconfig.json b/source/api/.tsconfig.json new file mode 100644 index 0000000..d70541b --- /dev/null +++ b/source/api/.tsconfig.json @@ -0,0 +1,42 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "moduleResolution": "node", + "strict": false, + "outDir": "dist", + "rootDir": "./", + "baseUrl": "./", + "resolveJsonModule": true, + "paths": { + "config/*": [ + "./src/config/*" + ], + "database/*": [ + "./src/database/*" + ], + "model/*": [ + "./src/model/*" + ], + "controllers/*": [ + "./src/controllers/*" + ], + "utils/*": [ + "./src/utils/*" + ], + "types/*": [ + "./src/types/*" + ], + "plugins/*": [ + "./src/plugins/*" + ] + } + }, + "include": [ + "./**/*.ts", + "./**/*.tsx", + "./src/**/*.json" + ], + "exclude": [ + "node_modules" + ] +} \ No newline at end of file diff --git a/source/api/nodemon.json b/source/api/nodemon.json new file mode 100644 index 0000000..b98a06d --- /dev/null +++ b/source/api/nodemon.json @@ -0,0 +1,5 @@ +{ + "ignore": [ + "README" + ] +} \ No newline at end of file diff --git a/source/api/package.json b/source/api/package.json new file mode 100644 index 0000000..b4b4877 --- /dev/null +++ b/source/api/package.json @@ -0,0 +1,38 @@ +{ + "name": "$(appName)-api", + "version": "0.1.0", + "description": "", + "author": "Roman Jaroš ", + "license": "ISC", + "scripts": { + "dev": "nodemon --exec ts-node -r tsconfig-paths/register src/index.ts", + "build": "rimraf dist && tsc -p tsconfig.json && tsc-alias -p tsconfig.json" + }, + "devDependencies": { + "@types/hapi": "18.0.10", + "@types/hapi__nes": "11.0.7", + "@types/ramda": "0.28.0", + "@types/validator": "13.11.1", + "copyfiles": "2.4.1", + "nodemon": "3.0.1", + "rimraf": "5.0.1", + "ts-node": "10.9.1", + "tsc-alias": "1.8.7" + }, + "dependencies": { + "@hapi/boom": "10.0.1", + "@hapi/nes": "13.0.1", + "@hapi/hapi": "21.3.2", + "@hapi/inert": "7.1.0", + "@hapi/vision": "7.0.3", + "@prokyon/utils": "1.0.31", + "hapi-swagger": "17.1.0", + "joi": "17.10.1", + "typeorm": "0.3.17", + "sqlite3": "5.1.6" + }, + "peerDependencies": { + "ramda": "0.28.0", + "typescript": "5.2.2" + } +} \ No newline at end of file diff --git a/source/api/src/config/server.json b/source/api/src/config/server.json new file mode 100644 index 0000000..8ea5838 --- /dev/null +++ b/source/api/src/config/server.json @@ -0,0 +1,4 @@ +{ + "host": "localhost", + "port": 3000 +} \ No newline at end of file diff --git a/source/api/src/controllers/hey.ts b/source/api/src/controllers/hey.ts new file mode 100644 index 0000000..38f67b9 --- /dev/null +++ b/source/api/src/controllers/hey.ts @@ -0,0 +1,18 @@ +// @ts-nocheck +import { Request, ResponseToolkit, ServerRoute } from '@hapi/hapi'; + +const routers: ServerRoute[] = [ + { + path: '/hey', + method: 'GET', + options: { + description: 'Are u alive?', + tags: ['api'], + }, + handler: (request: Request, h: ResponseToolkit) => { + return h.response('I am here !').type('html/text').code(200); + }, + }, +]; + +export default routers; diff --git a/source/api/src/database/db.ts b/source/api/src/database/db.ts new file mode 100644 index 0000000..b372672 --- /dev/null +++ b/source/api/src/database/db.ts @@ -0,0 +1,13 @@ +// @ts-nocheck +import { DataSource } from 'typeorm'; + +export const dbConnect = async () => { + const AppDataSource = new DataSource({ + type: 'sqlite', + database: `database.sqlite`, + entities: [], + synchronize: true, + logging: ['query'], + }); + return await AppDataSource.initialize(); +}; diff --git a/source/api/src/index.ts b/source/api/src/index.ts new file mode 100644 index 0000000..35dcbdf --- /dev/null +++ b/source/api/src/index.ts @@ -0,0 +1,51 @@ +// @ts-nocheck +import hapi from '@hapi/hapi'; +import nes from '@hapi/nes'; + +import { host, port } from 'config/server.json'; +import { dbConnect } from 'database/db'; + +import swagger from 'plugins/swagger'; + +const server: hapi.Server = new hapi.Server({ + host: host, + port: port, + debug: { + log: ['error'], + request: ['error'], + }, + routes: { + validate: { + failAction: (request, h, err) => { + throw err; + }, + }, + }, +}); + +const start = async (): Promise => { + await swagger(server); + await server.register(nes); + + // v1 endpoints + await server.register(require('./plugins/controllers'), { routes: { prefix: '/api/v1' } }); + + // connect to database + await dbConnect() + .then(() => { + console.log('Data Source has been initialized!'); + }) + .catch((err) => { + console.error('Error during Data Source initialization', err); + }); + + await server.start(); + console.info(`Server running: ${server.info.uri}`); +}; + +process.on('unhandledRejection', (err) => { + console.info(err); + process.exit(1); +}); + +start(); diff --git a/source/api/src/plugins/controllers.ts b/source/api/src/plugins/controllers.ts new file mode 100644 index 0000000..a2d14ea --- /dev/null +++ b/source/api/src/plugins/controllers.ts @@ -0,0 +1,11 @@ +// @ts-nocheck +import { Server } from '@hapi/hapi'; + +import hey from 'controllers/hey'; + +export const plugin = { + name: 'Controllers', + register: async (server: Server) => { + server.route(hey); + }, +}; diff --git a/source/api/src/plugins/swagger.ts b/source/api/src/plugins/swagger.ts new file mode 100644 index 0000000..beaead3 --- /dev/null +++ b/source/api/src/plugins/swagger.ts @@ -0,0 +1,26 @@ +// @ts-nocheck +import { Server } from '@hapi/hapi'; + +const version = require('../../package.json').version; + +export default async (server: Server) => { + return server.register([ + require('@hapi/inert'), + require('@hapi/vision'), + { + plugin: require('hapi-swagger'), + options: { + info: { + title: 'Many API', + version, + }, + swaggerUI: true, + documentationPage: true, + documentationPath: '/swagger', + pathPrefixSize: 3, + basePath: '/api/v1', + reuseDefinitions: false, + }, + }, + ]); +}; diff --git a/source/app/src/app/assets/public/.gitkeep b/source/api/src/types/.gitkeep similarity index 100% rename from source/app/src/app/assets/public/.gitkeep rename to source/api/src/types/.gitkeep diff --git a/source/api/src/utils/params.ts b/source/api/src/utils/params.ts new file mode 100644 index 0000000..4615106 --- /dev/null +++ b/source/api/src/utils/params.ts @@ -0,0 +1,23 @@ +// @ts-nocheck +import { Request } from '@hapi/hapi'; + +export type RequestParams = Record; + +export const getParam = + (request: Request) => + (name: string): string | null => { + const params: RequestParams = { + ...(request.params as object), + ...(request.payload as object), + ...(request.query as object), + }; + const filteredParams: RequestParams = {} as any; + Object.keys(params).map((key) => { + const value = params[key]; + if (['undefined', 'null'].includes(value as string)) { + filteredParams[key] = null; + } + filteredParams[key] = value; + }); + return filteredParams[name] ?? null; + }; diff --git a/source/shared/.tsconfig.json b/source/shared/.tsconfig.json index cb56d47..8f9d0f0 100644 --- a/source/shared/.tsconfig.json +++ b/source/shared/.tsconfig.json @@ -16,10 +16,6 @@ "es6", "dom" ], - "jsx": "react", - "types": [ - "jest", - ], }, "exclude": [ "./node_modules", diff --git a/source/app/.eslintignore b/source/ui/.eslintignore similarity index 100% rename from source/app/.eslintignore rename to source/ui/.eslintignore diff --git a/source/app/.eslintrc b/source/ui/.eslintrc similarity index 100% rename from source/app/.eslintrc rename to source/ui/.eslintrc diff --git a/source/app/.tsconfig.json b/source/ui/.tsconfig.json similarity index 94% rename from source/app/.tsconfig.json rename to source/ui/.tsconfig.json index fc32b8f..59553b9 100644 --- a/source/app/.tsconfig.json +++ b/source/ui/.tsconfig.json @@ -36,9 +36,10 @@ ] }, "types": [ - "./src/types/yup", - "node" - ], + "node", + "jest", + "./src/types/yup" + ] }, "include": [ "./src/**/*.ts", diff --git a/source/app/README.md b/source/ui/README.md similarity index 100% rename from source/app/README.md rename to source/ui/README.md diff --git a/source/app/config/local/.env b/source/ui/config/local/.env similarity index 100% rename from source/app/config/local/.env rename to source/ui/config/local/.env diff --git a/source/app/config/prod/.env b/source/ui/config/prod/.env similarity index 100% rename from source/app/config/prod/.env rename to source/ui/config/prod/.env diff --git a/source/app/docker/Dockerfile b/source/ui/docker/Dockerfile similarity index 100% rename from source/app/docker/Dockerfile rename to source/ui/docker/Dockerfile diff --git a/source/app/docker/nginx/conf.d/default.conf b/source/ui/docker/nginx/conf.d/default.conf similarity index 100% rename from source/app/docker/nginx/conf.d/default.conf rename to source/ui/docker/nginx/conf.d/default.conf diff --git a/source/app/jest.config.js b/source/ui/jest.config.js similarity index 100% rename from source/app/jest.config.js rename to source/ui/jest.config.js diff --git a/source/app/nightwatch.js b/source/ui/nightwatch.js similarity index 100% rename from source/app/nightwatch.js rename to source/ui/nightwatch.js diff --git a/source/app/openapi-config.ts b/source/ui/openapi-config.ts similarity index 100% rename from source/app/openapi-config.ts rename to source/ui/openapi-config.ts diff --git a/source/app/package.json b/source/ui/package.json similarity index 100% rename from source/app/package.json rename to source/ui/package.json diff --git a/source/app/scripts/webpack-common.js b/source/ui/scripts/webpack-common.js similarity index 100% rename from source/app/scripts/webpack-common.js rename to source/ui/scripts/webpack-common.js diff --git a/source/app/scripts/webpack-dev.js b/source/ui/scripts/webpack-dev.js similarity index 100% rename from source/app/scripts/webpack-dev.js rename to source/ui/scripts/webpack-dev.js diff --git a/source/app/scripts/webpack-prod.js b/source/ui/scripts/webpack-prod.js similarity index 100% rename from source/app/scripts/webpack-prod.js rename to source/ui/scripts/webpack-prod.js diff --git a/source/app/src/api/emptyApi.ts b/source/ui/src/api/emptyApi.ts similarity index 100% rename from source/app/src/api/emptyApi.ts rename to source/ui/src/api/emptyApi.ts diff --git a/source/app/src/app/app.tsx b/source/ui/src/app/app.tsx similarity index 100% rename from source/app/src/app/app.tsx rename to source/ui/src/app/app.tsx diff --git a/source/app/src/app/assets/html/index.ejs b/source/ui/src/app/assets/html/index.ejs similarity index 100% rename from source/app/src/app/assets/html/index.ejs rename to source/ui/src/app/assets/html/index.ejs diff --git a/source/app/src/components/.gitkeep b/source/ui/src/app/assets/public/.gitkeep similarity index 100% rename from source/app/src/components/.gitkeep rename to source/ui/src/app/assets/public/.gitkeep diff --git a/source/app/src/app/routes.ts b/source/ui/src/app/routes.ts similarity index 100% rename from source/app/src/app/routes.ts rename to source/ui/src/app/routes.ts diff --git a/source/app/src/app/store.ts b/source/ui/src/app/store.ts similarity index 100% rename from source/app/src/app/store.ts rename to source/ui/src/app/store.ts diff --git a/source/app/src/constants/.gitkeep b/source/ui/src/components/.gitkeep similarity index 100% rename from source/app/src/constants/.gitkeep rename to source/ui/src/components/.gitkeep diff --git a/source/app/src/features/.gitkeep b/source/ui/src/constants/.gitkeep similarity index 100% rename from source/app/src/features/.gitkeep rename to source/ui/src/constants/.gitkeep diff --git a/source/app/src/hooks/.gitkeep b/source/ui/src/features/.gitkeep similarity index 100% rename from source/app/src/hooks/.gitkeep rename to source/ui/src/features/.gitkeep diff --git a/source/app/src/types/global.ts b/source/ui/src/hooks/.gitkeep similarity index 100% rename from source/app/src/types/global.ts rename to source/ui/src/hooks/.gitkeep diff --git a/source/app/src/index.tsx b/source/ui/src/index.tsx similarity index 100% rename from source/app/src/index.tsx rename to source/ui/src/index.tsx diff --git a/source/app/src/localization/dictionary/csCZ.ts b/source/ui/src/localization/dictionary/csCZ.ts similarity index 100% rename from source/app/src/localization/dictionary/csCZ.ts rename to source/ui/src/localization/dictionary/csCZ.ts diff --git a/source/app/src/localization/locale.ts b/source/ui/src/localization/locale.ts similarity index 100% rename from source/app/src/localization/locale.ts rename to source/ui/src/localization/locale.ts diff --git a/source/app/src/localization/message.ts b/source/ui/src/localization/message.ts similarity index 100% rename from source/app/src/localization/message.ts rename to source/ui/src/localization/message.ts diff --git a/source/app/src/localization/schema.ts b/source/ui/src/localization/schema.ts similarity index 100% rename from source/app/src/localization/schema.ts rename to source/ui/src/localization/schema.ts diff --git a/source/app/src/pages/WelcomePage.tsx b/source/ui/src/pages/WelcomePage.tsx similarity index 100% rename from source/app/src/pages/WelcomePage.tsx rename to source/ui/src/pages/WelcomePage.tsx diff --git a/source/app/src/styles/components/component.js b/source/ui/src/styles/components/component.js similarity index 100% rename from source/app/src/styles/components/component.js rename to source/ui/src/styles/components/component.js diff --git a/source/app/src/styles/global.css b/source/ui/src/styles/global.css similarity index 100% rename from source/app/src/styles/global.css rename to source/ui/src/styles/global.css diff --git a/source/app/src/styles/postcss.config.js b/source/ui/src/styles/postcss.config.js similarity index 100% rename from source/app/src/styles/postcss.config.js rename to source/ui/src/styles/postcss.config.js diff --git a/source/app/src/styles/tailwind.config.js b/source/ui/src/styles/tailwind.config.js similarity index 100% rename from source/app/src/styles/tailwind.config.js rename to source/ui/src/styles/tailwind.config.js diff --git a/source/app/src/styles/theme.js b/source/ui/src/styles/theme.js similarity index 100% rename from source/app/src/styles/theme.js rename to source/ui/src/styles/theme.js diff --git a/source/app/src/styles/variables.css b/source/ui/src/styles/variables.css similarity index 100% rename from source/app/src/styles/variables.css rename to source/ui/src/styles/variables.css diff --git a/source/ui/src/types/global.ts b/source/ui/src/types/global.ts new file mode 100644 index 0000000..e69de29 diff --git a/source/app/src/types/yup.d.ts b/source/ui/src/types/yup.d.ts similarity index 100% rename from source/app/src/types/yup.d.ts rename to source/ui/src/types/yup.d.ts diff --git a/source/app/src/utils/yup.ts b/source/ui/src/utils/yup.ts similarity index 100% rename from source/app/src/utils/yup.ts rename to source/ui/src/utils/yup.ts diff --git a/source/app/tests/nightwatchjs.d.ts b/source/ui/tests/nightwatchjs.d.ts similarity index 100% rename from source/app/tests/nightwatchjs.d.ts rename to source/ui/tests/nightwatchjs.d.ts diff --git a/source/app/tests/tsconfig.json b/source/ui/tests/tsconfig.json similarity index 100% rename from source/app/tests/tsconfig.json rename to source/ui/tests/tsconfig.json