@sundaysf/cli-v2 0.0.4 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +178 -178
  2. package/dist/README.md +178 -178
  3. package/dist/bin/generators/class.js.map +1 -1
  4. package/dist/bin/generators/postman.js.map +1 -1
  5. package/dist/bin/index.js.map +1 -1
  6. package/dist/templates/backend/.env.example +13 -13
  7. package/dist/templates/backend/.prettierignore +2 -2
  8. package/dist/templates/backend/Dockerfile +14 -14
  9. package/dist/templates/backend/README.md +18 -18
  10. package/dist/templates/backend/src/app.ts +34 -34
  11. package/dist/templates/backend/src/common/utils/environment.resolver.ts +3 -3
  12. package/dist/templates/backend/src/common/utils/version.resolver.ts +4 -4
  13. package/dist/templates/backend/src/controllers/health/health.controller.ts +23 -23
  14. package/dist/templates/backend/src/routes/health/health.router.ts +16 -16
  15. package/dist/templates/backend/src/routes/index.ts +57 -57
  16. package/dist/templates/backend/src/server.ts +16 -16
  17. package/dist/templates/backend/src/types.d.ts +10 -10
  18. package/dist/templates/backend-db-sql/.env.example +13 -13
  19. package/dist/templates/backend-db-sql/.prettierignore +2 -2
  20. package/dist/templates/backend-db-sql/Dockerfile +17 -17
  21. package/dist/templates/backend-db-sql/README.md +34 -34
  22. package/dist/templates/backend-db-sql/db/knexfile.ts +34 -33
  23. package/dist/templates/backend-db-sql/db/migrations/001_create_sundays_package_version.ts +12 -12
  24. package/dist/templates/backend-db-sql/db/seeds/001_sundays_package_version_seed.ts +10 -10
  25. package/dist/templates/backend-db-sql/db/src/KnexConnection.ts +74 -74
  26. package/dist/templates/backend-db-sql/db/src/d.types.ts +18 -18
  27. package/dist/templates/backend-db-sql/db/src/dao/sundays-package-version/sundays-package-version.dao.ts +71 -71
  28. package/dist/templates/backend-db-sql/db/src/index.ts +9 -9
  29. package/dist/templates/backend-db-sql/db/src/interfaces/sundays-package-version/sundays-package-version.interfaces.ts +6 -6
  30. package/dist/templates/backend-db-sql/db/tsconfig.json +16 -16
  31. package/dist/templates/backend-db-sql/src/app.ts +34 -34
  32. package/dist/templates/backend-db-sql/src/common/utils/environment.resolver.ts +3 -3
  33. package/dist/templates/backend-db-sql/src/common/utils/version.resolver.ts +4 -4
  34. package/dist/templates/backend-db-sql/src/controllers/health/health.controller.ts +23 -23
  35. package/dist/templates/backend-db-sql/src/routes/health/health.router.ts +16 -16
  36. package/dist/templates/backend-db-sql/src/routes/index.ts +57 -57
  37. package/dist/templates/backend-db-sql/src/server.ts +18 -18
  38. package/dist/templates/backend-db-sql/src/types.d.ts +10 -10
  39. package/dist/templates/db-sql/knexfile.ts +33 -33
  40. package/dist/templates/db-sql/migrations/001_create_sundays_package_version.ts +12 -12
  41. package/dist/templates/db-sql/seeds/001_sundays_package_version_seed.ts +10 -10
  42. package/dist/templates/db-sql/src/KnexConnection.ts +74 -74
  43. package/dist/templates/db-sql/src/d.types.ts +18 -18
  44. package/dist/templates/db-sql/src/dao/sundays-package-version/sundays-package-version.dao.ts +71 -71
  45. package/dist/templates/db-sql/src/index.ts +9 -9
  46. package/dist/templates/db-sql/src/interfaces/sundays-package-version/sundays-package-version.interfaces.ts +6 -6
  47. package/dist/templates/db-sql/tsconfig.json +16 -16
  48. package/dist/templates/module/CLAUDE.md +158 -158
  49. package/dist/templates/module/tsconfig.json +19 -19
  50. package/package.json +1 -1
@@ -1,74 +1,74 @@
1
- import { knex, Knex } from 'knex';
2
-
3
- class KnexManager {
4
- private static knexInstance: Knex<any, unknown[]> | null = null;
5
-
6
- /**
7
- * Open a new connection. Reuse the already existing one if there's any.
8
- */
9
- static async connect(
10
- config?: Knex.Config,
11
- connections?: number
12
- ): Promise<Knex<any, unknown[]>> {
13
- if (!KnexManager.knexInstance) {
14
- const isLocalhost = process.env.SQL_HOST === 'localhost' || process.env.SQL_HOST === '127.0.0.1';
15
- const rejectUnauthorized = process.env.SQL_REJECT_UNAUTHORIZED !== 'false';
16
- const defaultConfig = {
17
- client: 'pg',
18
- connection: {
19
- host: process.env.SQL_HOST,
20
- user: process.env.SQL_USER,
21
- password: process.env.SQL_PASSWORD,
22
- database: process.env.SQL_DB_NAME,
23
- port: Number(process.env.SQL_PORT) || 5432,
24
- ssl: isLocalhost ? false : { rejectUnauthorized },
25
- },
26
- pool: {
27
- min: 1,
28
- max: connections || 15,
29
- idleTimeoutMillis: 20000,
30
- acquireTimeoutMillis: 30000,
31
- },
32
- migrations: {
33
- tableName: 'knex_migrations',
34
- },
35
- };
36
- KnexManager.knexInstance = knex(config || defaultConfig);
37
- try {
38
- await KnexManager.knexInstance.raw('SELECT 1');
39
- console.info(`Knex connection established`);
40
- } catch (error) {
41
- console.error(`Failed to establish Knex connection:`, error);
42
- KnexManager.knexInstance = null;
43
- throw error;
44
- }
45
- }
46
-
47
- return KnexManager.knexInstance;
48
- }
49
-
50
- /**
51
- * Returns the active connection.
52
- */
53
- static getConnection(): Knex<any, unknown[]> {
54
- if (!KnexManager.knexInstance) {
55
- throw new Error(
56
- 'Knex connection has not been established. Call connect() first.'
57
- );
58
- }
59
- return KnexManager.knexInstance;
60
- }
61
-
62
- /**
63
- * Closes the connection and destroys the instance.
64
- */
65
- static async disconnect(): Promise<void> {
66
- if (KnexManager.knexInstance) {
67
- await KnexManager.knexInstance.destroy();
68
- KnexManager.knexInstance = null;
69
- console.info(`Knex connection closed`);
70
- }
71
- }
72
- }
73
-
74
- export default KnexManager;
1
+ import { knex, Knex } from 'knex';
2
+
3
+ class KnexManager {
4
+ private static knexInstance: Knex<any, unknown[]> | null = null;
5
+
6
+ /**
7
+ * Open a new connection. Reuse the already existing one if there's any.
8
+ */
9
+ static async connect(
10
+ config?: Knex.Config,
11
+ connections?: number
12
+ ): Promise<Knex<any, unknown[]>> {
13
+ if (!KnexManager.knexInstance) {
14
+ const isLocalhost = process.env.SQL_HOST === 'localhost' || process.env.SQL_HOST === '127.0.0.1';
15
+ const rejectUnauthorized = process.env.SQL_REJECT_UNAUTHORIZED !== 'false';
16
+ const defaultConfig = {
17
+ client: 'pg',
18
+ connection: {
19
+ host: process.env.SQL_HOST,
20
+ user: process.env.SQL_USER,
21
+ password: process.env.SQL_PASSWORD,
22
+ database: process.env.SQL_DB_NAME,
23
+ port: Number(process.env.SQL_PORT) || 5432,
24
+ ssl: isLocalhost ? false : { rejectUnauthorized },
25
+ },
26
+ pool: {
27
+ min: 1,
28
+ max: connections || 15,
29
+ idleTimeoutMillis: 20000,
30
+ acquireTimeoutMillis: 30000,
31
+ },
32
+ migrations: {
33
+ tableName: 'knex_migrations',
34
+ },
35
+ };
36
+ KnexManager.knexInstance = knex(config || defaultConfig);
37
+ try {
38
+ await KnexManager.knexInstance.raw('SELECT 1');
39
+ console.info(`Knex connection established`);
40
+ } catch (error) {
41
+ console.error(`Failed to establish Knex connection:`, error);
42
+ KnexManager.knexInstance = null;
43
+ throw error;
44
+ }
45
+ }
46
+
47
+ return KnexManager.knexInstance;
48
+ }
49
+
50
+ /**
51
+ * Returns the active connection.
52
+ */
53
+ static getConnection(): Knex<any, unknown[]> {
54
+ if (!KnexManager.knexInstance) {
55
+ throw new Error(
56
+ 'Knex connection has not been established. Call connect() first.'
57
+ );
58
+ }
59
+ return KnexManager.knexInstance;
60
+ }
61
+
62
+ /**
63
+ * Closes the connection and destroys the instance.
64
+ */
65
+ static async disconnect(): Promise<void> {
66
+ if (KnexManager.knexInstance) {
67
+ await KnexManager.knexInstance.destroy();
68
+ KnexManager.knexInstance = null;
69
+ console.info(`Knex connection closed`);
70
+ }
71
+ }
72
+ }
73
+
74
+ export default KnexManager;
@@ -1,18 +1,18 @@
1
- export interface IBaseDAO<T> {
2
- create(item: T): Promise<T>;
3
- getById(id: number): Promise<T | null>;
4
- getByUuid(uuid: string): Promise<T | null>;
5
- update(id: number, item: Partial<T>): Promise<T | null>;
6
- delete(id: number): Promise<boolean>;
7
- getAll(page: number, limit: number): Promise<IDataPaginator<T>>;
8
- }
9
-
10
- export interface IDataPaginator<T> {
11
- success: boolean;
12
- data: T[];
13
- page: number;
14
- limit: number;
15
- count: number;
16
- totalCount: number;
17
- totalPages: number;
18
- }
1
+ export interface IBaseDAO<T> {
2
+ create(item: T): Promise<T>;
3
+ getById(id: number): Promise<T | null>;
4
+ getByUuid(uuid: string): Promise<T | null>;
5
+ update(id: number, item: Partial<T>): Promise<T | null>;
6
+ delete(id: number): Promise<boolean>;
7
+ getAll(page: number, limit: number): Promise<IDataPaginator<T>>;
8
+ }
9
+
10
+ export interface IDataPaginator<T> {
11
+ success: boolean;
12
+ data: T[];
13
+ page: number;
14
+ limit: number;
15
+ count: number;
16
+ totalCount: number;
17
+ totalPages: number;
18
+ }
@@ -1,71 +1,71 @@
1
- import { Knex } from "knex";
2
- import { IBaseDAO, IDataPaginator } from "../../d.types";
3
- import { ISundaysPackageVersion } from "../../interfaces/sundays-package-version/sundays-package-version.interfaces";
4
- import KnexManager from "../../KnexConnection";
5
-
6
- export class SundaysPackageVersionDAO implements IBaseDAO<ISundaysPackageVersion> {
7
- private _knex: Knex<any, unknown[]> = KnexManager.getConnection();
8
-
9
- async create(item: ISundaysPackageVersion): Promise<ISundaysPackageVersion> {
10
- const [created] = await this._knex("sundays_package_version").insert(item).returning("*");
11
- return created;
12
- }
13
-
14
- async getById(id: number): Promise<ISundaysPackageVersion | null> {
15
- const result = await this._knex("sundays_package_version")
16
- .select("*")
17
- .where("id", id)
18
- .first();
19
- return result || null;
20
- }
21
-
22
- async getByUuid(uuid: string): Promise<ISundaysPackageVersion | null> {
23
- const result = await this._knex("sundays_package_version")
24
- .select("*")
25
- .where("uuid", uuid)
26
- .first();
27
- return result || null;
28
- }
29
-
30
- async update(id: number, item: Partial<ISundaysPackageVersion>): Promise<ISundaysPackageVersion | null> {
31
- const [updated] = await this._knex("sundays_package_version")
32
- .where({ id })
33
- .update(item)
34
- .returning("*");
35
- return updated || null;
36
- }
37
-
38
- async delete(id: number): Promise<boolean> {
39
- const result = await this._knex("sundays_package_version").where({ id }).del();
40
- return result > 0;
41
- }
42
-
43
- async getAll(page: number, limit: number): Promise<IDataPaginator<ISundaysPackageVersion>> {
44
- const safeLimit = Math.max(limit, 1);
45
- const offset = (page - 1) * safeLimit;
46
-
47
- const query = this._knex("sundays_package_version").select("*");
48
-
49
- const [countResult] = await query.clone().clearSelect().count("* as count");
50
- const totalCount = +countResult.count;
51
- const data = await query.clone().limit(safeLimit).offset(offset).orderBy("id", "desc");
52
-
53
- return {
54
- success: true,
55
- data,
56
- page,
57
- limit: safeLimit,
58
- count: data.length,
59
- totalCount,
60
- totalPages: Math.ceil(totalCount / safeLimit),
61
- };
62
- }
63
-
64
- async getLatestVersion(): Promise<ISundaysPackageVersion | null> {
65
- const result = await this._knex("sundays_package_version")
66
- .select("*")
67
- .orderBy("id", "desc")
68
- .first();
69
- return result || null;
70
- }
71
- }
1
+ import { Knex } from "knex";
2
+ import { IBaseDAO, IDataPaginator } from "../../d.types";
3
+ import { ISundaysPackageVersion } from "../../interfaces/sundays-package-version/sundays-package-version.interfaces";
4
+ import KnexManager from "../../KnexConnection";
5
+
6
+ export class SundaysPackageVersionDAO implements IBaseDAO<ISundaysPackageVersion> {
7
+ private _knex: Knex<any, unknown[]> = KnexManager.getConnection();
8
+
9
+ async create(item: ISundaysPackageVersion): Promise<ISundaysPackageVersion> {
10
+ const [created] = await this._knex("sundays_package_version").insert(item).returning("*");
11
+ return created;
12
+ }
13
+
14
+ async getById(id: number): Promise<ISundaysPackageVersion | null> {
15
+ const result = await this._knex("sundays_package_version")
16
+ .select("*")
17
+ .where("id", id)
18
+ .first();
19
+ return result || null;
20
+ }
21
+
22
+ async getByUuid(uuid: string): Promise<ISundaysPackageVersion | null> {
23
+ const result = await this._knex("sundays_package_version")
24
+ .select("*")
25
+ .where("uuid", uuid)
26
+ .first();
27
+ return result || null;
28
+ }
29
+
30
+ async update(id: number, item: Partial<ISundaysPackageVersion>): Promise<ISundaysPackageVersion | null> {
31
+ const [updated] = await this._knex("sundays_package_version")
32
+ .where({ id })
33
+ .update(item)
34
+ .returning("*");
35
+ return updated || null;
36
+ }
37
+
38
+ async delete(id: number): Promise<boolean> {
39
+ const result = await this._knex("sundays_package_version").where({ id }).del();
40
+ return result > 0;
41
+ }
42
+
43
+ async getAll(page: number, limit: number): Promise<IDataPaginator<ISundaysPackageVersion>> {
44
+ const safeLimit = Math.max(limit, 1);
45
+ const offset = (page - 1) * safeLimit;
46
+
47
+ const query = this._knex("sundays_package_version").select("*");
48
+
49
+ const [countResult] = await query.clone().clearSelect().count("* as count");
50
+ const totalCount = +countResult.count;
51
+ const data = await query.clone().limit(safeLimit).offset(offset).orderBy("id", "desc");
52
+
53
+ return {
54
+ success: true,
55
+ data,
56
+ page,
57
+ limit: safeLimit,
58
+ count: data.length,
59
+ totalCount,
60
+ totalPages: Math.ceil(totalCount / safeLimit),
61
+ };
62
+ }
63
+
64
+ async getLatestVersion(): Promise<ISundaysPackageVersion | null> {
65
+ const result = await this._knex("sundays_package_version")
66
+ .select("*")
67
+ .orderBy("id", "desc")
68
+ .first();
69
+ return result || null;
70
+ }
71
+ }
@@ -1,9 +1,9 @@
1
- // DAOs
2
- export { SundaysPackageVersionDAO } from "./dao/sundays-package-version/sundays-package-version.dao";
3
-
4
- // Interfaces
5
- export { IDataPaginator } from "./d.types";
6
- export { ISundaysPackageVersion } from "./interfaces/sundays-package-version/sundays-package-version.interfaces";
7
-
8
- import KnexManager from './KnexConnection';
9
- export { KnexManager };
1
+ // DAOs
2
+ export { SundaysPackageVersionDAO } from "./dao/sundays-package-version/sundays-package-version.dao";
3
+
4
+ // Interfaces
5
+ export { IDataPaginator } from "./d.types";
6
+ export { ISundaysPackageVersion } from "./interfaces/sundays-package-version/sundays-package-version.interfaces";
7
+
8
+ import KnexManager from './KnexConnection';
9
+ export { KnexManager };
@@ -1,6 +1,6 @@
1
- export interface ISundaysPackageVersion {
2
- id: number;
3
- versionName: string;
4
- createdAt: string;
5
- updatedAt: string;
6
- }
1
+ export interface ISundaysPackageVersion {
2
+ id: number;
3
+ versionName: string;
4
+ createdAt: string;
5
+ updatedAt: string;
6
+ }
@@ -1,16 +1,16 @@
1
- {
2
- "compilerOptions": {
3
- "module": "CommonJS",
4
- "target": "ES2022",
5
- "sourceMap": true,
6
- "esModuleInterop": true,
7
- "strict": true,
8
- "declaration": true,
9
- "rootDir": "./src",
10
- "outDir": "./dist",
11
- "skipLibCheck": true,
12
- "forceConsistentCasingInFileNames": true
13
- },
14
- "include": ["src/**/*"],
15
- "exclude": ["node_modules", "dist"]
16
- }
1
+ {
2
+ "compilerOptions": {
3
+ "module": "CommonJS",
4
+ "target": "ES2022",
5
+ "sourceMap": true,
6
+ "esModuleInterop": true,
7
+ "strict": true,
8
+ "declaration": true,
9
+ "rootDir": "./src",
10
+ "outDir": "./dist",
11
+ "skipLibCheck": true,
12
+ "forceConsistentCasingInFileNames": true
13
+ },
14
+ "include": ["src/**/*"],
15
+ "exclude": ["node_modules", "dist"]
16
+ }
@@ -1,35 +1,35 @@
1
- import dotenv from 'dotenv';
2
- import express, { type Express } from 'express';
3
- import logger from 'morgan';
4
- import cors from 'cors';
5
- import { IndexRouter } from './routes/index';
6
- import { errorMiddleware } from './middlewares/error/error.middleware';
7
- import { getAllowedOrigins } from './common/config/origins/origins.config';
8
- dotenv.config();
9
-
10
- const app: Express = express();
11
-
12
- app.use(
13
- logger('tiny', {
14
- skip: (req, _res) => {
15
- return req.originalUrl.startsWith('/api/health');
16
- },
17
- })
18
- );
19
-
20
- app.use(
21
- cors({
22
- origin: getAllowedOrigins(),
23
- credentials: true,
24
- allowedHeaders: ['Content-Type', 'Authorization'],
25
- })
26
- );
27
-
28
- app.use(express.urlencoded({ extended: true }));
29
- app.use(express.json());
30
-
31
- app.use('/api', new IndexRouter().router);
32
-
33
- app.use(errorMiddleware);
34
-
1
+ import dotenv from 'dotenv';
2
+ import express, { type Express } from 'express';
3
+ import logger from 'morgan';
4
+ import cors from 'cors';
5
+ import { IndexRouter } from './routes/index';
6
+ import { errorMiddleware } from './middlewares/error/error.middleware';
7
+ import { getAllowedOrigins } from './common/config/origins/origins.config';
8
+ dotenv.config();
9
+
10
+ const app: Express = express();
11
+
12
+ app.use(
13
+ logger('tiny', {
14
+ skip: (req, _res) => {
15
+ return req.originalUrl.startsWith('/api/health');
16
+ },
17
+ })
18
+ );
19
+
20
+ app.use(
21
+ cors({
22
+ origin: getAllowedOrigins(),
23
+ credentials: true,
24
+ allowedHeaders: ['Content-Type', 'Authorization'],
25
+ })
26
+ );
27
+
28
+ app.use(express.urlencoded({ extended: true }));
29
+ app.use(express.json());
30
+
31
+ app.use('/api', new IndexRouter().router);
32
+
33
+ app.use(errorMiddleware);
34
+
35
35
  export default app;
@@ -1,4 +1,4 @@
1
- export const getServiceEnvironment = (): string => {
2
- const serEnv: string = process.env.ENVIRONMENT || 'undefined';
3
- return serEnv.charAt(0).toUpperCase() + serEnv.slice(1);
1
+ export const getServiceEnvironment = (): string => {
2
+ const serEnv: string = process.env.ENVIRONMENT || 'undefined';
3
+ return serEnv.charAt(0).toUpperCase() + serEnv.slice(1);
4
4
  };
@@ -1,5 +1,5 @@
1
- const pjson = require('../../../package.json');
2
-
3
- export const getServiceVersion = (): string => {
4
- return pjson['version'];
1
+ const pjson = require('../../../package.json');
2
+
3
+ export const getServiceVersion = (): string => {
4
+ return pjson['version'];
5
5
  };
@@ -1,24 +1,24 @@
1
- import { NextFunction, Request, Response } from 'express';
2
- import { getServiceVersion } from '../../common/utils/version.resolver';
3
- import { getServiceEnvironment } from '../../common/utils/environment.resolver';
4
-
5
- export class HealthController {
6
- public async getHealthStatus(
7
- _req: Request,
8
- res: Response,
9
- next: NextFunction
10
- ): Promise<void> {
11
- try {
12
- const version: string = await getServiceVersion();
13
- const environment: string = await getServiceEnvironment();
14
- res.status(200).json({
15
- success: true,
16
- health: 'Up!',
17
- version,
18
- environment,
19
- });
20
- } catch (err: any) {
21
- next(err);
22
- }
23
- }
1
+ import { NextFunction, Request, Response } from 'express';
2
+ import { getServiceVersion } from '../../common/utils/version.resolver';
3
+ import { getServiceEnvironment } from '../../common/utils/environment.resolver';
4
+
5
+ export class HealthController {
6
+ public async getHealthStatus(
7
+ _req: Request,
8
+ res: Response,
9
+ next: NextFunction
10
+ ): Promise<void> {
11
+ try {
12
+ const version: string = await getServiceVersion();
13
+ const environment: string = await getServiceEnvironment();
14
+ res.status(200).json({
15
+ success: true,
16
+ health: 'Up!',
17
+ version,
18
+ environment,
19
+ });
20
+ } catch (err: any) {
21
+ next(err);
22
+ }
23
+ }
24
24
  }
@@ -1,17 +1,17 @@
1
- import { Router } from 'express';
2
- import { HealthController } from '../../controllers/health/health.controller';
3
-
4
- export class HealthRouter {
5
- public router: Router = Router();
6
- private readonly healthController: HealthController = new HealthController();
7
- constructor() {
8
- this.initRoutes();
9
- }
10
-
11
- private initRoutes(): void {
12
- this.router.get(
13
- '/',
14
- this.healthController.getHealthStatus.bind(this.healthController)
15
- );
16
- }
1
+ import { Router } from 'express';
2
+ import { HealthController } from '../../controllers/health/health.controller';
3
+
4
+ export class HealthRouter {
5
+ public router: Router = Router();
6
+ private readonly healthController: HealthController = new HealthController();
7
+ constructor() {
8
+ this.initRoutes();
9
+ }
10
+
11
+ private initRoutes(): void {
12
+ this.router.get(
13
+ '/',
14
+ this.healthController.getHealthStatus.bind(this.healthController)
15
+ );
16
+ }
17
17
  }