create-skweb 1.1.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 (74) hide show
  1. package/.turbo/turbo-build.log +17 -0
  2. package/.turbo/turbo-check.log +4 -0
  3. package/.turbo/turbo-lint.log +4 -0
  4. package/.turbo/turbo-test.log +65 -0
  5. package/CHANGELOG.md +7 -0
  6. package/dist/cli.d.ts +3 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +199 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/index.cjs +115 -0
  11. package/dist/index.cjs.map +1 -0
  12. package/dist/index.d.ts +12 -0
  13. package/dist/index.d.ts.map +1 -0
  14. package/dist/index.js +102 -0
  15. package/dist/index.js.map +1 -0
  16. package/package.json +54 -0
  17. package/rollup.config.mjs +71 -0
  18. package/src/cli.ts +118 -0
  19. package/src/index.ts +122 -0
  20. package/templates/cjs/ecosystem.config.js +32 -0
  21. package/templates/cjs/eslint.config.js +25 -0
  22. package/templates/cjs/package.json +46 -0
  23. package/templates/cjs/src/app.js +91 -0
  24. package/templates/cjs/src/commands/migrate.js +35 -0
  25. package/templates/cjs/src/commands/seed.js +58 -0
  26. package/templates/cjs/src/controllers/hello.js +33 -0
  27. package/templates/cjs/src/controllers/user.js +101 -0
  28. package/templates/cjs/src/cronActions/cleanup.js +12 -0
  29. package/templates/cjs/src/cronWorker.js +85 -0
  30. package/templates/cjs/src/index.js +7 -0
  31. package/templates/cjs/src/models/SysUser.js +38 -0
  32. package/templates/cjs/src/seeds/SysUser.json +1 -0
  33. package/templates/cjs/src/services/database.js +15 -0
  34. package/templates/cjs/src/utils/config.js +65 -0
  35. package/templates/cjs/src/utils/logger.js +53 -0
  36. package/templates/cjs/test/index.js +13 -0
  37. package/templates/mjs/ecosystem.config.js +32 -0
  38. package/templates/mjs/eslint.config.js +25 -0
  39. package/templates/mjs/package.json +46 -0
  40. package/templates/mjs/src/app.js +97 -0
  41. package/templates/mjs/src/commands/migrate.js +38 -0
  42. package/templates/mjs/src/commands/seed.js +63 -0
  43. package/templates/mjs/src/controllers/hello.js +33 -0
  44. package/templates/mjs/src/controllers/user.js +101 -0
  45. package/templates/mjs/src/cronActions/cleanup.js +9 -0
  46. package/templates/mjs/src/cronWorker.js +91 -0
  47. package/templates/mjs/src/index.js +8 -0
  48. package/templates/mjs/src/models/SysUser.js +40 -0
  49. package/templates/mjs/src/seeds/SysUser.json +1 -0
  50. package/templates/mjs/src/services/database.js +16 -0
  51. package/templates/mjs/src/utils/config.js +63 -0
  52. package/templates/mjs/src/utils/logger.js +52 -0
  53. package/templates/mjs/test/index.mjs +13 -0
  54. package/templates/ts/ecosystem.config.js +36 -0
  55. package/templates/ts/eslint.config.js +17 -0
  56. package/templates/ts/package.json +57 -0
  57. package/templates/ts/rollup.config.mjs +39 -0
  58. package/templates/ts/src/app.ts +96 -0
  59. package/templates/ts/src/commands/migrate.ts +38 -0
  60. package/templates/ts/src/commands/seed.ts +63 -0
  61. package/templates/ts/src/controllers/hello.ts +33 -0
  62. package/templates/ts/src/controllers/user.ts +101 -0
  63. package/templates/ts/src/cronActions/cleanup.ts +10 -0
  64. package/templates/ts/src/cronWorker.ts +90 -0
  65. package/templates/ts/src/index.ts +8 -0
  66. package/templates/ts/src/models/SysUser.ts +49 -0
  67. package/templates/ts/src/seeds/SysUser.json +1 -0
  68. package/templates/ts/src/services/database.ts +16 -0
  69. package/templates/ts/src/utils/config.ts +68 -0
  70. package/templates/ts/src/utils/logger.ts +63 -0
  71. package/templates/ts/test/index.mjs +13 -0
  72. package/templates/ts/tsconfig.json +20 -0
  73. package/test/index.mjs +137 -0
  74. package/tsconfig.json +22 -0
@@ -0,0 +1,63 @@
1
+ import 'dotenv/config'
2
+
3
+ import path from 'path'
4
+ import { fileURLToPath } from 'url'
5
+ import { Database } from 'skweb-sequelize'
6
+ import logger from '../utils/logger.js'
7
+
8
+ const __filename = fileURLToPath(import.meta.url)
9
+ const __dirname = path.dirname(__filename)
10
+
11
+ async function runSeed() {
12
+ logger.info('[seed] Initializing database with seed data...')
13
+
14
+ const db = new Database({
15
+ host: process.env.DB_HOST || '127.0.0.1',
16
+ port: Number(process.env.DB_PORT) || 3306,
17
+ username: process.env.DB_USER || 'root',
18
+ password: process.env.DB_PASS || '',
19
+ database: process.env.DB_NAME || 'test-project',
20
+ dialect: process.env.DB_DIALECT || 'mysql',
21
+ charset: process.env.DB_CHARSET || 'utf8mb4',
22
+ underscored: true,
23
+ logging: process.env.DEBUG_DB === 'true' ? (msg) => logger.debug(msg) : false
24
+ })
25
+
26
+ await db.loadModelsDir(path.join(__dirname, '..', 'models'))
27
+ db.associateAllModels()
28
+
29
+ const seedsDir = path.join(__dirname, '..', 'seeds')
30
+ const fs = await import('fs/promises')
31
+ let files
32
+ try {
33
+ files = await fs.readdir(seedsDir)
34
+ } catch {
35
+ logger.warn('[seed] No seeds directory found')
36
+ return
37
+ }
38
+
39
+ for (const file of files) {
40
+ if (!file.endsWith('.json')) continue
41
+ const modelName = path.basename(file, '.json')
42
+ const Model = db.sequelize.models[modelName]
43
+ if (!Model) {
44
+ logger.warn(`[seed] Model ${modelName} not found`)
45
+ continue
46
+ }
47
+ const data = JSON.parse(await fs.readFile(path.join(seedsDir, file), 'utf-8'))
48
+ if (Array.isArray(data) && data.length > 0) {
49
+ await Model.bulkCreate(data, { ignoreDuplicates: true })
50
+ logger.info(`[seed] Seeded ${modelName} with ${data.length} records`)
51
+ }
52
+ }
53
+
54
+ logger.info('[seed] Database initialization complete')
55
+ }
56
+
57
+ const isMainModule = import.meta.url === `file://${process.argv[1]}`
58
+ if (isMainModule) {
59
+ runSeed().catch((err) => {
60
+ logger.error('[seed] Fatal error:', err)
61
+ process.exit(1)
62
+ })
63
+ }
@@ -0,0 +1,33 @@
1
+ export default [
2
+ {
3
+ method: 'get',
4
+ path: '/',
5
+ async handler() {
6
+ return {
7
+ message: 'Welcome to SKWeb!',
8
+ version: '1.0.0',
9
+ timestamp: new Date().toISOString()
10
+ }
11
+ }
12
+ },
13
+ {
14
+ method: 'get',
15
+ path: '/health',
16
+ async handler() {
17
+ return {
18
+ status: 'ok',
19
+ timestamp: new Date().toISOString()
20
+ }
21
+ }
22
+ },
23
+ {
24
+ method: 'post',
25
+ path: '/echo',
26
+ async handler(req) {
27
+ return {
28
+ message: 'Echo received',
29
+ data: req.body
30
+ }
31
+ }
32
+ }
33
+ ]
@@ -0,0 +1,101 @@
1
+ import createHttpError from 'http-errors'
2
+ import { db } from '../services/database.js'
3
+
4
+ const { SysUser } = db.sequelize.models
5
+
6
+ export default [
7
+ {
8
+ method: 'get',
9
+ path: '/api/users',
10
+ async handler(req) {
11
+ const { page = 1, limit = 10 } = req.query
12
+ const users = await SysUser.findAndCountAll({
13
+ offset: (Number(page) - 1) * Number(limit),
14
+ limit: Number(limit)
15
+ })
16
+ return {
17
+ list: users.rows,
18
+ total: users.count
19
+ }
20
+ }
21
+ },
22
+ {
23
+ method: 'get',
24
+ path: '/api/users/:id',
25
+ paramsSchema: {
26
+ type: 'object',
27
+ required: ['id'],
28
+ properties: { id: { type: 'integer', minimum: 1 } }
29
+ },
30
+ async handler(req) {
31
+ const { id } = req.validatedParams
32
+ const user = await SysUser.findByPk(id)
33
+ if (!user) {
34
+ throw new createHttpError.NotFound('User not found')
35
+ }
36
+ return user
37
+ }
38
+ },
39
+ {
40
+ method: 'post',
41
+ path: '/api/users',
42
+ bodySchema: {
43
+ type: 'object',
44
+ required: ['username', 'password'],
45
+ properties: {
46
+ username: { type: 'string', minLength: 3 },
47
+ password: { type: 'string', minLength: 6 },
48
+ email: { type: 'string', format: 'email' },
49
+ phone: { type: 'string' }
50
+ }
51
+ },
52
+ async handler(req) {
53
+ return await SysUser.create(req.validatedBody)
54
+ }
55
+ },
56
+ {
57
+ method: 'put',
58
+ path: '/api/users/:id',
59
+ paramsSchema: {
60
+ type: 'object',
61
+ required: ['id'],
62
+ properties: { id: { type: 'integer', minimum: 1 } }
63
+ },
64
+ bodySchema: {
65
+ type: 'object',
66
+ properties: {
67
+ password: { type: 'string', minLength: 6 },
68
+ email: { type: 'string', format: 'email' },
69
+ phone: { type: 'string' },
70
+ status: { type: 'integer' }
71
+ }
72
+ },
73
+ async handler(req) {
74
+ const { id } = req.validatedParams
75
+ const user = await SysUser.findByPk(id)
76
+ if (!user) {
77
+ throw new createHttpError.NotFound('User not found')
78
+ }
79
+ await user.update(req.validatedBody)
80
+ return user
81
+ }
82
+ },
83
+ {
84
+ method: 'delete',
85
+ path: '/api/users/:id',
86
+ paramsSchema: {
87
+ type: 'object',
88
+ required: ['id'],
89
+ properties: { id: { type: 'integer', minimum: 1 } }
90
+ },
91
+ async handler(req) {
92
+ const { id } = req.validatedParams
93
+ const user = await SysUser.findByPk(id)
94
+ if (!user) {
95
+ throw new createHttpError.NotFound('User not found')
96
+ }
97
+ await user.destroy()
98
+ return { message: 'User deleted' }
99
+ }
100
+ }
101
+ ]
@@ -0,0 +1,9 @@
1
+ import logger from '../utils/logger.js'
2
+
3
+ /**
4
+ * 清理任务示例
5
+ */
6
+ export default async function cleanup() {
7
+ logger.info(`[cron] Running cleanup task at ${new Date().toISOString()}`)
8
+ logger.info('[cron] Cleanup task completed')
9
+ }
@@ -0,0 +1,91 @@
1
+ import 'dotenv/config'
2
+
3
+ import path from 'path'
4
+ import { fileURLToPath } from 'url'
5
+ import logger from './utils/logger.js'
6
+ import { checkRequiredEnv } from './utils/config.js'
7
+
8
+ const __filename = fileURLToPath(import.meta.url)
9
+ const __dirname = path.dirname(__filename)
10
+
11
+ async function startCronWorker() {
12
+ logger.info('[cron-worker] Starting cron worker process...')
13
+
14
+ if (!checkRequiredEnv()) {
15
+ logger.error('[cron-worker] Configuration validation failed, exiting...')
16
+ process.exit(1)
17
+ }
18
+
19
+ const { CronFramework } = await import('skweb-framework')
20
+
21
+ const framework = new CronFramework({
22
+ db: {
23
+ host: process.env.DB_HOST || '127.0.0.1',
24
+ port: Number(process.env.DB_PORT) || 3306,
25
+ username: process.env.DB_USER || 'root',
26
+ password: process.env.DB_PASS || '',
27
+ database: process.env.DB_NAME || 'test-project',
28
+ dialect: process.env.DB_DIALECT || 'mysql',
29
+ charset: process.env.DB_CHARSET || 'utf8mb4',
30
+ underscored: true,
31
+ logging: process.env.DEBUG_DB === 'true' ? (msg) => logger.debug(msg) : false
32
+ },
33
+ redis: {
34
+ host: process.env.REDIS_HOST || '127.0.0.1',
35
+ port: Number(process.env.REDIS_PORT) || 6379,
36
+ password: process.env.REDIS_PASSWORD || undefined
37
+ },
38
+ channel: 'cron:task:cmd',
39
+ logger,
40
+ onSaveTask: async (taskData) => {
41
+ const SysCronTask = framework.db?.sequelize?.models.SysCronTask
42
+ if (SysCronTask) {
43
+ await SysCronTask.update(
44
+ { cache: taskData.cache, data: taskData.data },
45
+ { where: { id: taskData.taskId } }
46
+ )
47
+ }
48
+ },
49
+ loadTasks: async () => {
50
+ const SysCronTask = framework.db?.sequelize?.models.SysCronTask
51
+ if (!SysCronTask) return []
52
+ return (await SysCronTask.findAll()).map((t) => ({
53
+ id: String(t.id),
54
+ cronTime: t.cronTime,
55
+ method: t.method
56
+ }))
57
+ }
58
+ })
59
+
60
+ await framework.runPluginBeforeSetup()
61
+ await framework.setupModels(path.join(__dirname, './models'))
62
+ await framework.loadPluginModels()
63
+ await framework.runPluginAfterSetup()
64
+
65
+ await framework.loadCronActions(path.join(__dirname, './cronActions'))
66
+ await framework.startWorker()
67
+ framework.start()
68
+ logger.info('[cron-worker] Cron worker started')
69
+
70
+ process.on('SIGINT', async () => {
71
+ logger.info('[cron-worker] Received SIGINT, shutting down...')
72
+ await framework.stop()
73
+ process.exit(0)
74
+ })
75
+
76
+ process.on('SIGTERM', async () => {
77
+ logger.info('[cron-worker] Received SIGTERM, shutting down...')
78
+ await framework.stop()
79
+ process.exit(0)
80
+ })
81
+ }
82
+
83
+ const isMainModule = import.meta.url === `file://${process.argv[1]}`
84
+ if (isMainModule) {
85
+ startCronWorker().catch((err) => {
86
+ logger.error('[cron-worker] Fatal error:', err)
87
+ process.exit(1)
88
+ })
89
+ }
90
+
91
+ export { startCronWorker }
@@ -0,0 +1,8 @@
1
+ import 'dotenv/config'
2
+
3
+ import { bootstrap } from './app.js'
4
+
5
+ const isMainModule = import.meta.url === `file://${process.argv[1]}`
6
+ if (isMainModule) {
7
+ bootstrap()
8
+ }
@@ -0,0 +1,40 @@
1
+ import { Model, DataTypes } from 'sequelize'
2
+
3
+ export default (sequelize) => {
4
+ class SysUser extends Model {}
5
+
6
+ SysUser.init({
7
+ id: {
8
+ type: DataTypes.INTEGER,
9
+ primaryKey: true,
10
+ autoIncrement: true
11
+ },
12
+ username: {
13
+ type: DataTypes.STRING(50),
14
+ allowNull: false,
15
+ unique: true
16
+ },
17
+ password: {
18
+ type: DataTypes.STRING(255),
19
+ allowNull: false
20
+ },
21
+ email: {
22
+ type: DataTypes.STRING(100)
23
+ },
24
+ phone: {
25
+ type: DataTypes.STRING(20)
26
+ },
27
+ status: {
28
+ type: DataTypes.TINYINT,
29
+ defaultValue: 1
30
+ }
31
+ }, {
32
+ sequelize,
33
+ modelName: 'SysUser',
34
+ tableName: 'sys_users',
35
+ timestamps: true,
36
+ underscored: true
37
+ })
38
+
39
+ return SysUser
40
+ }
@@ -0,0 +1 @@
1
+ [{"id": 1, "username": "admin", "password": "$2b$10$example", "email": "admin@example.com", "phone": "13800138000", "status": 1}]
@@ -0,0 +1,16 @@
1
+ import { Database } from 'skweb-sequelize'
2
+
3
+ const db = new Database({
4
+ host: process.env.DB_HOST || '127.0.0.1',
5
+ port: Number(process.env.DB_PORT) || 3306,
6
+ username: process.env.DB_USER || 'root',
7
+ password: process.env.DB_PASS || '',
8
+ database: process.env.DB_NAME || '{{name}}',
9
+ dialect: process.env.DB_DIALECT || 'mysql',
10
+ charset: process.env.DB_CHARSET || 'utf8mb4',
11
+ underscored: true,
12
+ logging: process.env.DEBUG_DB === 'true'
13
+ })
14
+
15
+ export { db }
16
+ export default db
@@ -0,0 +1,63 @@
1
+ import logger from './logger.js'
2
+
3
+ export function validateConfig() {
4
+ const errors = []
5
+
6
+ if (!process.env.DB_HOST) {
7
+ logger.warn('[config] DB_HOST not set, using default: 127.0.0.1')
8
+ }
9
+ if (!process.env.DB_NAME) {
10
+ logger.warn('[config] DB_NAME not set, using default: test-project')
11
+ }
12
+ if (!process.env.DB_USER) {
13
+ logger.warn('[config] DB_USER not set, using default: root')
14
+ }
15
+
16
+ if (process.env.JWT_SECRET === 'please-change-this-in-production') {
17
+ logger.warn('[config] WARNING: JWT_SECRET is using default value, please change in production!')
18
+ }
19
+
20
+ if (!process.env.REDIS_HOST) {
21
+ logger.warn('[config] REDIS_HOST not set, using default: 127.0.0.1')
22
+ }
23
+
24
+ const port = Number(process.env.PORT)
25
+ if (port && (port < 1 || port > 65535)) {
26
+ errors.push('PORT must be between 1 and 65535')
27
+ }
28
+
29
+ const dbPort = Number(process.env.DB_PORT)
30
+ if (dbPort && (dbPort < 1 || dbPort > 65535)) {
31
+ errors.push('DB_PORT must be between 1 and 65535')
32
+ }
33
+
34
+ const redisPort = Number(process.env.REDIS_PORT)
35
+ if (redisPort && (redisPort < 1 || redisPort > 65535)) {
36
+ errors.push('REDIS_PORT must be between 1 and 65535')
37
+ }
38
+
39
+ return {
40
+ isValid: errors.length === 0,
41
+ errors
42
+ }
43
+ }
44
+
45
+ export function checkRequiredEnv() {
46
+ const result = validateConfig()
47
+
48
+ if (result.errors.length > 0) {
49
+ logger.error('[config] Configuration validation failed:')
50
+ result.errors.forEach((err) => logger.error(` - ${err}`))
51
+ return false
52
+ }
53
+
54
+ if (process.env.NODE_ENV === 'production') {
55
+ if (!process.env.JWT_SECRET || process.env.JWT_SECRET === 'please-change-this-in-production') {
56
+ logger.error('[config] JWT_SECRET must be set in production!')
57
+ return false
58
+ }
59
+ }
60
+
61
+ logger.info('[config] Configuration validation passed')
62
+ return true
63
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Winston 日志配置
3
+ */
4
+ import winston from 'winston'
5
+ import path from 'path'
6
+ import fs from 'fs'
7
+
8
+ const LOG_LEVEL = process.env.LOG_LEVEL || 'info'
9
+ const LOG_DIR = process.env.LOG_DIR || path.join(process.cwd(), 'logs')
10
+ const LOG_CONSOLE = process.env.LOG_CONSOLE !== 'false'
11
+
12
+ if (!fs.existsSync(LOG_DIR)) {
13
+ fs.mkdirSync(LOG_DIR, { recursive: true })
14
+ }
15
+
16
+ const { combine, timestamp, printf, colorize, errors, splat, json } = winston.format
17
+
18
+ const consoleFormat = printf(({ level, message, timestamp: ts, stack }) => {
19
+ return `${ts} [${level}] ${stack || message}`
20
+ })
21
+
22
+ const fileFormat = combine(timestamp(), errors({ stack: true }), splat(), json())
23
+
24
+ export const logger = winston.createLogger({
25
+ level: LOG_LEVEL,
26
+ format: combine(timestamp({ format: 'YYYY-MM-DD HH:mm:ss.SSS' }), errors({ stack: true }), splat()),
27
+ transports: [
28
+ new winston.transports.File({
29
+ filename: path.join(LOG_DIR, 'error.log'),
30
+ level: 'error',
31
+ format: fileFormat,
32
+ maxsize: 10 * 1024 * 1024,
33
+ maxFiles: 10
34
+ }),
35
+ new winston.transports.File({
36
+ filename: path.join(LOG_DIR, 'combined.log'),
37
+ format: fileFormat,
38
+ maxsize: 10 * 1024 * 1024,
39
+ maxFiles: 10
40
+ })
41
+ ]
42
+ })
43
+
44
+ if (LOG_CONSOLE) {
45
+ logger.add(
46
+ new winston.transports.Console({
47
+ format: combine(colorize(), consoleFormat)
48
+ })
49
+ )
50
+ }
51
+
52
+ export default logger
@@ -0,0 +1,13 @@
1
+ import { expect } from 'chai'
2
+
3
+ describe('SKWeb App Tests', function() {
4
+ describe('Basic Tests', function() {
5
+ it('should pass basic test', function() {
6
+ expect(true).to.equal(true)
7
+ })
8
+
9
+ it('should have correct package structure', function() {
10
+ expect('SKWeb').to.be.a('string')
11
+ })
12
+ })
13
+ })
@@ -0,0 +1,36 @@
1
+ module.exports = {
2
+ apps: [
3
+ {
4
+ name: '{{name}}-web',
5
+ script: 'src/index.ts',
6
+ interpreter: 'npx',
7
+ interpreter_args: 'tsx',
8
+ instances: 'max',
9
+ exec_mode: 'cluster',
10
+ env: {
11
+ NODE_ENV: 'production',
12
+ PORT: 3000
13
+ },
14
+ max_memory_restart: '512M',
15
+ error_file: 'logs/web-err.log',
16
+ out_file: 'logs/web-out.log',
17
+ log_date_format: 'YYYY-MM-DD HH:mm:ss Z'
18
+ },
19
+ {
20
+ name: '{{name}}-cron',
21
+ script: 'src/cronWorker.ts',
22
+ interpreter: 'npx',
23
+ interpreter_args: 'tsx',
24
+ instances: 1,
25
+ exec_mode: 'fork',
26
+ autorestart: true,
27
+ env: {
28
+ NODE_ENV: 'production'
29
+ },
30
+ max_memory_restart: '512M',
31
+ error_file: 'logs/cron-err.log',
32
+ out_file: 'logs/cron-out.log',
33
+ log_date_format: 'YYYY-MM-DD HH:mm:ss Z'
34
+ }
35
+ ]
36
+ }
@@ -0,0 +1,17 @@
1
+ import tseslint from 'typescript-eslint'
2
+ import js from '@eslint/js'
3
+
4
+ export default tseslint.config(
5
+ { ignores: ['dist', 'node_modules', 'logs', 'test'] },
6
+ {
7
+ extends: [js.configs.recommended, ...tseslint.configs.recommended],
8
+ languageOptions: {
9
+ ecmaVersion: 2022,
10
+ sourceType: 'module'
11
+ },
12
+ rules: {
13
+ '@typescript-eslint/no-explicit-any': 'warn',
14
+ '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }]
15
+ }
16
+ }
17
+ )
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "{{name}}",
3
+ "version": "1.0.0",
4
+ "description": "{{description}}",
5
+ "type": "module",
6
+ "scripts": {
7
+ "start": "pm2 start ecosystem.config.js",
8
+ "stop": "pm2 stop all",
9
+ "restart": "pm2 restart all",
10
+ "delete": "pm2 delete all",
11
+ "logs": "pm2 logs",
12
+ "web:dev": "npx dotenvx run -- tsx watch src/index.ts",
13
+ "cron:dev": "npx dotenvx run -- tsx watch src/cronWorker.ts",
14
+ "seed": "npx dotenvx run -- tsx src/commands/seed.ts",
15
+ "migrate": "npx dotenvx run -- tsx src/commands/migrate.ts",
16
+ "build": "tsc && rollup -c rollup.config.mjs",
17
+ "build:dev": "rollup -c rollup.config.mjs --environment NODE_ENV:development",
18
+ "lint": "eslint --fix --ext .ts src",
19
+ "check": "tsc --noEmit",
20
+ "test": "npx dotenvx run -- mocha test/**/*.mjs",
21
+ "clean": "rm -rf dist",
22
+ "clean:temp": "rm -rf .rollup.cache"
23
+ },
24
+ "dependencies": {
25
+ "@dotenvx/dotenvx": "^1.71.0",
26
+ "http-errors": "^2.0.0",
27
+ "skweb-express": "^1.0.0",
28
+ "skweb-express-jwt": "^1.0.0",
29
+ "skweb-express-logger": "^1.0.0",
30
+ "skweb-sequelize": "^1.0.0",
31
+ "skweb-redis": "^1.0.0",
32
+ "skweb-cron": "^1.0.0",
33
+ "skweb-framework": "^1.0.0",
34
+ "skweb-plugin": "^1.0.0",
35
+ "skweb-util": "^1.0.0",
36
+ "winston": "^3.17.0",
37
+ "sequelize": "^6.37.7"
38
+ },
39
+ "devDependencies": {
40
+ "@types/node": "^25.0.1",
41
+ "@types/mocha": "^10.0.10",
42
+ "@types/http-errors": "^2.0.4",
43
+ "chai": "^6.2.1",
44
+ "mocha": "^11.7.5",
45
+ "tsx": "^4.22.4",
46
+ "typescript": "^5.9.3",
47
+ "rollup": "^2.79.2",
48
+ "@rollup/plugin-typescript": "^12.3.0",
49
+ "@rollup/plugin-node-resolve": "^16.0.3",
50
+ "@rollup/plugin-commonjs": "^29.0.0",
51
+ "eslint": "^9.39.1",
52
+ "typescript-eslint": "^8.49.0"
53
+ },
54
+ "engines": {
55
+ "node": ">=20.18.1"
56
+ }
57
+ }
@@ -0,0 +1,39 @@
1
+ import resolve from '@rollup/plugin-node-resolve'
2
+ import commonjs from '@rollup/plugin-commonjs'
3
+ import typescript from '@rollup/plugin-typescript'
4
+ import terser from '@rollup/plugin-terser'
5
+
6
+ const isProduction = process.env.NODE_ENV === 'production'
7
+
8
+ export default {
9
+ input: 'src/index.ts',
10
+ output: {
11
+ file: 'dist/index.js',
12
+ format: 'es',
13
+ sourcemap: true
14
+ },
15
+ plugins: [
16
+ resolve(),
17
+ commonjs(),
18
+ typescript({ tsconfig: './tsconfig.json' }),
19
+ isProduction && terser()
20
+ ],
21
+ external: [
22
+ 'skweb-express',
23
+ 'skweb-express-jwt',
24
+ 'skweb-express-logger',
25
+ 'skweb-sequelize',
26
+ 'skweb-redis',
27
+ 'skweb-cron',
28
+ 'skweb-framework',
29
+ 'skweb-plugin',
30
+ 'skweb-util',
31
+ '@dotenvx/dotenvx',
32
+ 'http-errors',
33
+ 'express',
34
+ 'sequelize',
35
+ 'ioredis',
36
+ 'path',
37
+ 'fs'
38
+ ]
39
+ }