@sundaysf/cli-v2 0.0.3 → 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.
- package/README.md +178 -178
- package/dist/README.md +178 -178
- package/dist/bin/generators/class.js.map +1 -1
- package/dist/bin/generators/postman.js.map +1 -1
- package/dist/bin/index.js.map +1 -1
- package/dist/templates/backend/.claude/agents/knex-table-implementer.md +113 -0
- package/dist/templates/backend/.env.example +13 -13
- package/dist/templates/backend/.prettierignore +2 -2
- package/dist/templates/backend/Dockerfile +14 -14
- package/dist/templates/backend/README.md +18 -18
- package/dist/templates/backend/src/app.ts +34 -34
- package/dist/templates/backend/src/common/utils/environment.resolver.ts +3 -3
- package/dist/templates/backend/src/common/utils/version.resolver.ts +4 -4
- package/dist/templates/backend/src/controllers/health/health.controller.ts +23 -23
- package/dist/templates/backend/src/routes/health/health.router.ts +16 -16
- package/dist/templates/backend/src/routes/index.ts +57 -57
- package/dist/templates/backend/src/server.ts +16 -16
- package/dist/templates/backend/src/types.d.ts +10 -10
- package/dist/templates/backend-db-sql/.env.example +13 -13
- package/dist/templates/backend-db-sql/.prettierignore +2 -2
- package/dist/templates/backend-db-sql/Dockerfile +17 -17
- package/dist/templates/backend-db-sql/README.md +34 -34
- package/dist/templates/backend-db-sql/db/knexfile.ts +34 -33
- package/dist/templates/backend-db-sql/db/migrations/001_create_sundays_package_version.ts +12 -12
- package/dist/templates/backend-db-sql/db/seeds/001_sundays_package_version_seed.ts +10 -10
- package/dist/templates/backend-db-sql/db/src/KnexConnection.ts +74 -74
- package/dist/templates/backend-db-sql/db/src/d.types.ts +18 -18
- package/dist/templates/backend-db-sql/db/src/dao/sundays-package-version/sundays-package-version.dao.ts +71 -71
- package/dist/templates/backend-db-sql/db/src/index.ts +9 -9
- package/dist/templates/backend-db-sql/db/src/interfaces/sundays-package-version/sundays-package-version.interfaces.ts +6 -6
- package/dist/templates/backend-db-sql/db/tsconfig.json +16 -16
- package/dist/templates/backend-db-sql/src/app.ts +34 -34
- package/dist/templates/backend-db-sql/src/common/utils/environment.resolver.ts +3 -3
- package/dist/templates/backend-db-sql/src/common/utils/version.resolver.ts +4 -4
- package/dist/templates/backend-db-sql/src/controllers/health/health.controller.ts +23 -23
- package/dist/templates/backend-db-sql/src/routes/health/health.router.ts +16 -16
- package/dist/templates/backend-db-sql/src/routes/index.ts +57 -57
- package/dist/templates/backend-db-sql/src/server.ts +18 -18
- package/dist/templates/backend-db-sql/src/types.d.ts +10 -10
- package/dist/templates/db-sql/.claude/agents/sundays-backend-builder.md +70 -0
- package/dist/templates/db-sql/knexfile.ts +33 -33
- package/dist/templates/db-sql/migrations/001_create_sundays_package_version.ts +12 -12
- package/dist/templates/db-sql/seeds/001_sundays_package_version_seed.ts +10 -10
- package/dist/templates/db-sql/src/KnexConnection.ts +74 -74
- package/dist/templates/db-sql/src/d.types.ts +18 -18
- package/dist/templates/db-sql/src/dao/sundays-package-version/sundays-package-version.dao.ts +71 -71
- package/dist/templates/db-sql/src/index.ts +9 -9
- package/dist/templates/db-sql/src/interfaces/sundays-package-version/sundays-package-version.interfaces.ts +6 -6
- package/dist/templates/db-sql/tsconfig.json +16 -16
- package/dist/templates/module/.claude/agents/knex-table-implementer.md +113 -0
- package/dist/templates/module/.claude/agents/sundays-backend-builder.md +70 -0
- package/dist/templates/module/.claude/settings.local.json +10 -0
- package/dist/templates/module/CLAUDE.md +158 -158
- package/dist/templates/module/tsconfig.json +19 -19
- package/package.json +1 -1
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
# Sundays Framework Project
|
|
2
|
-
|
|
3
|
-
This directory contains the starter backend with embedded database module generated by the CLI.
|
|
4
|
-
|
|
5
|
-
## Quick start
|
|
6
|
-
|
|
7
|
-
1. Install dependencies:
|
|
8
|
-
```
|
|
9
|
-
npm install
|
|
10
|
-
```
|
|
11
|
-
2. Copy `.env.example` to `.env` and set your environment variables (especially the `SQL_*` database variables).
|
|
12
|
-
3. Run database migrations:
|
|
13
|
-
```
|
|
14
|
-
npm run migrate:deploy
|
|
15
|
-
```
|
|
16
|
-
4. Start the development server:
|
|
17
|
-
```
|
|
18
|
-
npm run start:dev
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
The server will run on the port specified in your `.env` file.
|
|
22
|
-
|
|
23
|
-
## Database module
|
|
24
|
-
|
|
25
|
-
The `db/` directory contains an independently publishable Knex.js database module. It can be used as part of this backend or published separately as an npm package.
|
|
26
|
-
|
|
27
|
-
### Database commands
|
|
28
|
-
|
|
29
|
-
- `npm run migrate:create` - Create a new migration
|
|
30
|
-
- `npm run migrate:deploy` - Run pending migrations
|
|
31
|
-
- `npm run seed:create` - Create a new seed file
|
|
32
|
-
- `npm run seed:run` - Run seed files
|
|
33
|
-
- `npm run db:build` - Compile the database module
|
|
34
|
-
- `npm run db:publish` - Publish the database module to npm
|
|
1
|
+
# Sundays Framework Project
|
|
2
|
+
|
|
3
|
+
This directory contains the starter backend with embedded database module generated by the CLI.
|
|
4
|
+
|
|
5
|
+
## Quick start
|
|
6
|
+
|
|
7
|
+
1. Install dependencies:
|
|
8
|
+
```
|
|
9
|
+
npm install
|
|
10
|
+
```
|
|
11
|
+
2. Copy `.env.example` to `.env` and set your environment variables (especially the `SQL_*` database variables).
|
|
12
|
+
3. Run database migrations:
|
|
13
|
+
```
|
|
14
|
+
npm run migrate:deploy
|
|
15
|
+
```
|
|
16
|
+
4. Start the development server:
|
|
17
|
+
```
|
|
18
|
+
npm run start:dev
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The server will run on the port specified in your `.env` file.
|
|
22
|
+
|
|
23
|
+
## Database module
|
|
24
|
+
|
|
25
|
+
The `db/` directory contains an independently publishable Knex.js database module. It can be used as part of this backend or published separately as an npm package.
|
|
26
|
+
|
|
27
|
+
### Database commands
|
|
28
|
+
|
|
29
|
+
- `npm run migrate:create` - Create a new migration
|
|
30
|
+
- `npm run migrate:deploy` - Run pending migrations
|
|
31
|
+
- `npm run seed:create` - Create a new seed file
|
|
32
|
+
- `npm run seed:run` - Run seed files
|
|
33
|
+
- `npm run db:build` - Compile the database module
|
|
34
|
+
- `npm run db:publish` - Publish the database module to npm
|
|
@@ -1,33 +1,34 @@
|
|
|
1
|
-
import type { Knex } from "knex";
|
|
2
|
-
import
|
|
3
|
-
dotenv
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
1
|
+
import type { Knex } from "knex";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import dotenv from "dotenv";
|
|
4
|
+
dotenv.config({ path: path.resolve(__dirname, "..", ".env") });
|
|
5
|
+
|
|
6
|
+
const isLocalhost = process.env.SQL_HOST === 'localhost' || process.env.SQL_HOST === '127.0.0.1';
|
|
7
|
+
const rejectUnauthorized = process.env.SQL_REJECT_UNAUTHORIZED !== 'false';
|
|
8
|
+
|
|
9
|
+
const sharedConfig: Knex.Config = {
|
|
10
|
+
client: "postgresql",
|
|
11
|
+
connection: {
|
|
12
|
+
database: process.env.SQL_DB_NAME,
|
|
13
|
+
user: process.env.SQL_USER,
|
|
14
|
+
password: process.env.SQL_PASSWORD,
|
|
15
|
+
host: process.env.SQL_HOST,
|
|
16
|
+
port: process.env.SQL_PORT ? +process.env.SQL_PORT : 5432,
|
|
17
|
+
ssl: isLocalhost ? false : { rejectUnauthorized },
|
|
18
|
+
},
|
|
19
|
+
pool: {
|
|
20
|
+
min: 2,
|
|
21
|
+
max: 10,
|
|
22
|
+
},
|
|
23
|
+
migrations: {
|
|
24
|
+
tableName: "knex_migrations",
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const config: { [key: string]: Knex.Config } = {
|
|
29
|
+
development: sharedConfig,
|
|
30
|
+
staging: sharedConfig,
|
|
31
|
+
production: sharedConfig,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default config;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import type { Knex } from "knex";
|
|
2
|
-
|
|
3
|
-
export async function up(knex: Knex): Promise<void> {
|
|
4
|
-
await knex.schema.createTable("sundays_package_version", (table) => {
|
|
5
|
-
table.increments("id").primary();
|
|
6
|
-
table.string("versionName").notNullable();
|
|
7
|
-
table.timestamps(true, true); // created_at, updated_at
|
|
8
|
-
});
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export async function down(knex: Knex): Promise<void> {
|
|
12
|
-
await knex.schema.dropTableIfExists("sundays_package_version");
|
|
1
|
+
import type { Knex } from "knex";
|
|
2
|
+
|
|
3
|
+
export async function up(knex: Knex): Promise<void> {
|
|
4
|
+
await knex.schema.createTable("sundays_package_version", (table) => {
|
|
5
|
+
table.increments("id").primary();
|
|
6
|
+
table.string("versionName").notNullable();
|
|
7
|
+
table.timestamps(true, true); // created_at, updated_at
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function down(knex: Knex): Promise<void> {
|
|
12
|
+
await knex.schema.dropTableIfExists("sundays_package_version");
|
|
13
13
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { Knex } from "knex";
|
|
2
|
-
|
|
3
|
-
export async function seed(knex: Knex): Promise<void> {
|
|
4
|
-
// Deletes ALL existing entries
|
|
5
|
-
await knex("sundays_package_version").del();
|
|
6
|
-
|
|
7
|
-
// Inserts seed entries
|
|
8
|
-
await knex("sundays_package_version").insert([
|
|
9
|
-
{ versionName: "1.0.0" }
|
|
10
|
-
]);
|
|
1
|
+
import { Knex } from "knex";
|
|
2
|
+
|
|
3
|
+
export async function seed(knex: Knex): Promise<void> {
|
|
4
|
+
// Deletes ALL existing entries
|
|
5
|
+
await knex("sundays_package_version").del();
|
|
6
|
+
|
|
7
|
+
// Inserts seed entries
|
|
8
|
+
await knex("sundays_package_version").insert([
|
|
9
|
+
{ versionName: "1.0.0" }
|
|
10
|
+
]);
|
|
11
11
|
}
|
|
@@ -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
|
};
|