@aifabrix/builder 2.0.0 → 2.0.2
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 +6 -2
- package/bin/aifabrix.js +9 -3
- package/jest.config.integration.js +30 -0
- package/lib/app-config.js +157 -0
- package/lib/app-deploy.js +233 -82
- package/lib/app-dockerfile.js +112 -0
- package/lib/app-prompts.js +244 -0
- package/lib/app-push.js +172 -0
- package/lib/app-run.js +334 -133
- package/lib/app.js +208 -274
- package/lib/audit-logger.js +2 -0
- package/lib/build.js +209 -98
- package/lib/cli.js +76 -86
- package/lib/commands/app.js +414 -0
- package/lib/commands/login.js +304 -0
- package/lib/config.js +78 -0
- package/lib/deployer.js +225 -81
- package/lib/env-reader.js +45 -30
- package/lib/generator.js +308 -191
- package/lib/github-generator.js +67 -7
- package/lib/infra.js +156 -61
- package/lib/push.js +105 -10
- package/lib/schema/application-schema.json +30 -2
- package/lib/schema/infrastructure-schema.json +589 -0
- package/lib/secrets.js +229 -24
- package/lib/template-validator.js +205 -0
- package/lib/templates.js +305 -170
- package/lib/utils/api.js +329 -0
- package/lib/utils/cli-utils.js +97 -0
- package/lib/utils/dockerfile-utils.js +131 -0
- package/lib/utils/environment-checker.js +125 -0
- package/lib/utils/error-formatter.js +61 -0
- package/lib/utils/health-check.js +187 -0
- package/lib/utils/logger.js +53 -0
- package/lib/utils/template-helpers.js +223 -0
- package/lib/utils/variable-transformer.js +271 -0
- package/lib/validator.js +27 -112
- package/package.json +13 -10
- package/templates/README.md +75 -3
- package/templates/applications/keycloak/Dockerfile +36 -0
- package/templates/applications/keycloak/env.template +32 -0
- package/templates/applications/keycloak/rbac.yaml +37 -0
- package/templates/applications/keycloak/variables.yaml +56 -0
- package/templates/applications/miso-controller/Dockerfile +125 -0
- package/templates/applications/miso-controller/env.template +129 -0
- package/templates/applications/miso-controller/rbac.yaml +168 -0
- package/templates/applications/miso-controller/variables.yaml +56 -0
- package/templates/github/release.yaml.hbs +5 -26
- package/templates/github/steps/npm.hbs +24 -0
- package/templates/infra/compose.yaml +6 -6
- package/templates/python/docker-compose.hbs +19 -12
- package/templates/python/main.py +80 -0
- package/templates/python/requirements.txt +4 -0
- package/templates/typescript/Dockerfile.hbs +2 -2
- package/templates/typescript/docker-compose.hbs +19 -12
- package/templates/typescript/index.ts +116 -0
- package/templates/typescript/package.json +26 -0
- package/templates/typescript/tsconfig.json +24 -0
|
@@ -8,11 +8,12 @@ services:
|
|
|
8
8
|
{{app.key}}:
|
|
9
9
|
image: {{image.name}}:{{image.tag}}
|
|
10
10
|
container_name: aifabrix-{{app.key}}
|
|
11
|
-
env_file:
|
|
11
|
+
env_file:
|
|
12
|
+
- {{envFile}}
|
|
12
13
|
ports:
|
|
13
14
|
- "{{build.localPort}}:{{port}}"
|
|
14
15
|
networks:
|
|
15
|
-
-
|
|
16
|
+
- infra_aifabrix-network
|
|
16
17
|
{{#if requiresStorage}}
|
|
17
18
|
volumes:
|
|
18
19
|
- "{{mountVolume}}:/mnt/data"
|
|
@@ -39,31 +40,37 @@ services:
|
|
|
39
40
|
- ${ADMIN_SECRETS_PATH}
|
|
40
41
|
environment:
|
|
41
42
|
POSTGRES_DB: postgres
|
|
43
|
+
PGHOST: postgres
|
|
44
|
+
PGPORT: "5432"
|
|
45
|
+
PGUSER: pgadmin
|
|
42
46
|
networks:
|
|
43
|
-
-
|
|
47
|
+
- infra_aifabrix-network
|
|
44
48
|
command: >
|
|
45
49
|
sh -c "
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
psql -d postgres -c 'GRANT ALL PRIVILEGES ON DATABASE {{app.key}} TO {{app.key}}_user;' &&
|
|
50
|
-
psql -d {{app.key}} -c 'ALTER SCHEMA public OWNER TO {{app.key}}_user;' &&
|
|
51
|
-
psql -d {{app.key}} -c 'GRANT ALL ON SCHEMA public TO {{app.key}}_user;' &&
|
|
50
|
+
export PGHOST=postgres PGPORT=5432 PGUSER=pgadmin &&
|
|
51
|
+
export PGPASSWORD="${POSTGRES_PASSWORD}" &&
|
|
52
|
+
{{#if databases}}
|
|
52
53
|
{{#each databases}}
|
|
53
|
-
{{#unless @first}}
|
|
54
54
|
echo 'Creating {{name}} database and user...' &&
|
|
55
55
|
psql -d postgres -c 'CREATE DATABASE {{name}};' || echo '{{name}} database exists' &&
|
|
56
56
|
psql -d postgres -c \"CREATE USER {{name}}_user WITH PASSWORD '{{name}}_pass123';\" || echo '{{name}}_user exists' &&
|
|
57
57
|
psql -d postgres -c 'GRANT ALL PRIVILEGES ON DATABASE {{name}} TO {{name}}_user;' &&
|
|
58
58
|
psql -d {{name}} -c 'ALTER SCHEMA public OWNER TO {{name}}_user;' &&
|
|
59
59
|
psql -d {{name}} -c 'GRANT ALL ON SCHEMA public TO {{name}}_user;' &&
|
|
60
|
-
{{/unless}}
|
|
61
60
|
{{/each}}
|
|
61
|
+
{{else}}
|
|
62
|
+
echo 'Creating {{app.key}} database and user...' &&
|
|
63
|
+
psql -d postgres -c 'CREATE DATABASE {{app.key}};' || echo '{{app.key}} database exists' &&
|
|
64
|
+
psql -d postgres -c \"CREATE USER {{app.key}}_user WITH PASSWORD '{{app.key}}_pass123';\" || echo '{{app.key}}_user exists' &&
|
|
65
|
+
psql -d postgres -c 'GRANT ALL PRIVILEGES ON DATABASE {{app.key}} TO {{app.key}}_user;' &&
|
|
66
|
+
psql -d {{app.key}} -c 'ALTER SCHEMA public OWNER TO {{app.key}}_user;' &&
|
|
67
|
+
psql -d {{app.key}} -c 'GRANT ALL ON SCHEMA public TO {{app.key}}_user;' &&
|
|
68
|
+
{{/if}}
|
|
62
69
|
echo 'Database initialization complete!'
|
|
63
70
|
"
|
|
64
71
|
restart: "no"
|
|
65
72
|
{{/if}}
|
|
66
73
|
|
|
67
74
|
networks:
|
|
68
|
-
|
|
75
|
+
infra_aifabrix-network:
|
|
69
76
|
external: true
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
from flask import Flask, jsonify
|
|
4
|
+
|
|
5
|
+
app = Flask(__name__)
|
|
6
|
+
PORT = int(os.environ.get('PORT', 3000))
|
|
7
|
+
|
|
8
|
+
def check_database():
|
|
9
|
+
"""Check database connection"""
|
|
10
|
+
database_url = os.environ.get('DATABASE_URL')
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
import psycopg2
|
|
14
|
+
|
|
15
|
+
# If DATABASE_URL is set, use it
|
|
16
|
+
if database_url:
|
|
17
|
+
from urllib.parse import urlparse
|
|
18
|
+
# Parse DATABASE_URL (format: postgresql://user:password@host:port/database)
|
|
19
|
+
parsed = urlparse(database_url)
|
|
20
|
+
|
|
21
|
+
conn = psycopg2.connect(
|
|
22
|
+
host=parsed.hostname or os.environ.get('DATABASE_HOST', 'postgres'),
|
|
23
|
+
port=parsed.port or int(os.environ.get('DATABASE_PORT', 5432)),
|
|
24
|
+
database=parsed.path[1:] if parsed.path else os.environ.get('DATABASE_NAME', 'postgres'),
|
|
25
|
+
user=parsed.username or os.environ.get('DATABASE_USER', 'pgadmin'),
|
|
26
|
+
password=parsed.password or os.environ.get('DATABASE_PASSWORD', 'admin123')
|
|
27
|
+
)
|
|
28
|
+
else:
|
|
29
|
+
# Fallback to individual environment variables
|
|
30
|
+
conn = psycopg2.connect(
|
|
31
|
+
host=os.environ.get('DATABASE_HOST', os.environ.get('DB_HOST', 'postgres')),
|
|
32
|
+
port=int(os.environ.get('DATABASE_PORT', os.environ.get('DB_PORT', 5432))),
|
|
33
|
+
database=os.environ.get('DATABASE_NAME', os.environ.get('DB_NAME', 'postgres')),
|
|
34
|
+
user=os.environ.get('DATABASE_USER', os.environ.get('DB_USER', 'pgadmin')),
|
|
35
|
+
password=os.environ.get('DATABASE_PASSWORD', os.environ.get('DB_PASSWORD', 'admin123'))
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
conn.close()
|
|
39
|
+
return True
|
|
40
|
+
except ImportError:
|
|
41
|
+
return 'psycopg2 not installed'
|
|
42
|
+
except Exception as e:
|
|
43
|
+
return str(e)
|
|
44
|
+
|
|
45
|
+
@app.route('/health', methods=['GET'])
|
|
46
|
+
def health():
|
|
47
|
+
"""Health check endpoint with database connectivity check"""
|
|
48
|
+
health_status = {
|
|
49
|
+
'status': 'ok',
|
|
50
|
+
'timestamp': datetime.utcnow().isoformat() + 'Z'
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
# Check database connection if database is configured (DATABASE_URL or individual vars)
|
|
54
|
+
database_url = os.environ.get('DATABASE_URL')
|
|
55
|
+
database_host = os.environ.get('DATABASE_HOST') or os.environ.get('DB_HOST')
|
|
56
|
+
database_name = os.environ.get('DATABASE_NAME') or os.environ.get('DB_NAME')
|
|
57
|
+
|
|
58
|
+
# Only check database if database is configured
|
|
59
|
+
if database_url or database_host or database_name:
|
|
60
|
+
db_check = check_database()
|
|
61
|
+
if db_check is True:
|
|
62
|
+
health_status['database'] = 'connected'
|
|
63
|
+
else:
|
|
64
|
+
health_status['database'] = 'error'
|
|
65
|
+
health_status['database_error'] = str(db_check)
|
|
66
|
+
return jsonify(health_status), 503
|
|
67
|
+
|
|
68
|
+
return jsonify(health_status), 200
|
|
69
|
+
|
|
70
|
+
@app.route('/', methods=['GET'])
|
|
71
|
+
def root():
|
|
72
|
+
"""Root endpoint"""
|
|
73
|
+
return jsonify({
|
|
74
|
+
'message': 'AI Fabrix Application',
|
|
75
|
+
'version': '1.0.0'
|
|
76
|
+
}), 200
|
|
77
|
+
|
|
78
|
+
if __name__ == '__main__':
|
|
79
|
+
app.run(host='0.0.0.0', port=PORT, debug=False)
|
|
80
|
+
|
|
@@ -16,8 +16,8 @@ RUN apk add --no-cache \
|
|
|
16
16
|
# Copy package files first for better layer caching
|
|
17
17
|
COPY package*.json ./
|
|
18
18
|
|
|
19
|
-
# Install dependencies
|
|
20
|
-
RUN npm
|
|
19
|
+
# Install dependencies (including devDependencies for ts-node)
|
|
20
|
+
RUN npm install && npm cache clean --force
|
|
21
21
|
|
|
22
22
|
# Copy application code
|
|
23
23
|
COPY . .
|
|
@@ -8,11 +8,12 @@ services:
|
|
|
8
8
|
{{app.key}}:
|
|
9
9
|
image: {{image.name}}:{{image.tag}}
|
|
10
10
|
container_name: aifabrix-{{app.key}}
|
|
11
|
-
env_file:
|
|
11
|
+
env_file:
|
|
12
|
+
- {{envFile}}
|
|
12
13
|
ports:
|
|
13
14
|
- "{{build.localPort}}:{{port}}"
|
|
14
15
|
networks:
|
|
15
|
-
-
|
|
16
|
+
- infra_aifabrix-network
|
|
16
17
|
{{#if requiresStorage}}
|
|
17
18
|
volumes:
|
|
18
19
|
- "{{mountVolume}}:/mnt/data"
|
|
@@ -39,31 +40,37 @@ services:
|
|
|
39
40
|
- ${ADMIN_SECRETS_PATH}
|
|
40
41
|
environment:
|
|
41
42
|
POSTGRES_DB: postgres
|
|
43
|
+
PGHOST: postgres
|
|
44
|
+
PGPORT: "5432"
|
|
45
|
+
PGUSER: pgadmin
|
|
42
46
|
networks:
|
|
43
|
-
-
|
|
47
|
+
- infra_aifabrix-network
|
|
44
48
|
command: >
|
|
45
49
|
sh -c "
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
psql -d postgres -c 'GRANT ALL PRIVILEGES ON DATABASE {{app.key}} TO {{app.key}}_user;' &&
|
|
50
|
-
psql -d {{app.key}} -c 'ALTER SCHEMA public OWNER TO {{app.key}}_user;' &&
|
|
51
|
-
psql -d {{app.key}} -c 'GRANT ALL ON SCHEMA public TO {{app.key}}_user;' &&
|
|
50
|
+
export PGHOST=postgres PGPORT=5432 PGUSER=pgadmin &&
|
|
51
|
+
export PGPASSWORD="${POSTGRES_PASSWORD}" &&
|
|
52
|
+
{{#if databases}}
|
|
52
53
|
{{#each databases}}
|
|
53
|
-
{{#unless @first}}
|
|
54
54
|
echo 'Creating {{name}} database and user...' &&
|
|
55
55
|
psql -d postgres -c 'CREATE DATABASE {{name}};' || echo '{{name}} database exists' &&
|
|
56
56
|
psql -d postgres -c \"CREATE USER {{name}}_user WITH PASSWORD '{{name}}_pass123';\" || echo '{{name}}_user exists' &&
|
|
57
57
|
psql -d postgres -c 'GRANT ALL PRIVILEGES ON DATABASE {{name}} TO {{name}}_user;' &&
|
|
58
58
|
psql -d {{name}} -c 'ALTER SCHEMA public OWNER TO {{name}}_user;' &&
|
|
59
59
|
psql -d {{name}} -c 'GRANT ALL ON SCHEMA public TO {{name}}_user;' &&
|
|
60
|
-
{{/unless}}
|
|
61
60
|
{{/each}}
|
|
61
|
+
{{else}}
|
|
62
|
+
echo 'Creating {{app.key}} database and user...' &&
|
|
63
|
+
psql -d postgres -c 'CREATE DATABASE {{app.key}};' || echo '{{app.key}} database exists' &&
|
|
64
|
+
psql -d postgres -c \"CREATE USER {{app.key}}_user WITH PASSWORD '{{app.key}}_pass123';\" || echo '{{app.key}}_user exists' &&
|
|
65
|
+
psql -d postgres -c 'GRANT ALL PRIVILEGES ON DATABASE {{app.key}} TO {{app.key}}_user;' &&
|
|
66
|
+
psql -d {{app.key}} -c 'ALTER SCHEMA public OWNER TO {{app.key}}_user;' &&
|
|
67
|
+
psql -d {{app.key}} -c 'GRANT ALL ON SCHEMA public TO {{app.key}}_user;' &&
|
|
68
|
+
{{/if}}
|
|
62
69
|
echo 'Database initialization complete!'
|
|
63
70
|
"
|
|
64
71
|
restart: "no"
|
|
65
72
|
{{/if}}
|
|
66
73
|
|
|
67
74
|
networks:
|
|
68
|
-
|
|
75
|
+
infra_aifabrix-network:
|
|
69
76
|
external: true
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import { Pool } from 'pg';
|
|
3
|
+
import { Request, Response } from 'express';
|
|
4
|
+
|
|
5
|
+
const app = express();
|
|
6
|
+
const PORT = process.env.PORT || 3000;
|
|
7
|
+
|
|
8
|
+
app.use(express.json());
|
|
9
|
+
|
|
10
|
+
// Database connection pool
|
|
11
|
+
let dbPool: Pool | null = null;
|
|
12
|
+
|
|
13
|
+
function initDatabase() {
|
|
14
|
+
const databaseUrl = process.env.DATABASE_URL;
|
|
15
|
+
if (!databaseUrl) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
dbPool = new Pool({
|
|
21
|
+
connectionString: databaseUrl,
|
|
22
|
+
connectionTimeoutMillis: 5000,
|
|
23
|
+
});
|
|
24
|
+
return dbPool;
|
|
25
|
+
} catch (error) {
|
|
26
|
+
console.error('Failed to initialize database pool:', error);
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function checkDatabase(): Promise<{ connected: boolean; error?: string }> {
|
|
32
|
+
// If DATABASE_URL is not set, try to connect using individual environment variables
|
|
33
|
+
if (!dbPool && process.env.DATABASE_URL) {
|
|
34
|
+
// DATABASE_URL was set but pool initialization failed
|
|
35
|
+
return { connected: false, error: 'Database pool not initialized' };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// If no DATABASE_URL, try to create connection from individual vars
|
|
39
|
+
if (!dbPool) {
|
|
40
|
+
const host = process.env.DATABASE_HOST || process.env.DB_HOST || 'postgres';
|
|
41
|
+
const port = parseInt(process.env.DATABASE_PORT || process.env.DB_PORT || '5432', 10);
|
|
42
|
+
const database = process.env.DATABASE_NAME || process.env.DB_NAME || 'postgres';
|
|
43
|
+
const user = process.env.DATABASE_USER || process.env.DB_USER || 'pgadmin';
|
|
44
|
+
const password = process.env.DATABASE_PASSWORD || process.env.DB_PASSWORD || 'admin123';
|
|
45
|
+
|
|
46
|
+
if (!host && !database) {
|
|
47
|
+
return { connected: false, error: 'Database not configured' };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
const tempPool = new Pool({
|
|
52
|
+
host,
|
|
53
|
+
port,
|
|
54
|
+
database,
|
|
55
|
+
user,
|
|
56
|
+
password,
|
|
57
|
+
connectionTimeoutMillis: 5000,
|
|
58
|
+
});
|
|
59
|
+
const client = await tempPool.connect();
|
|
60
|
+
await client.query('SELECT 1');
|
|
61
|
+
client.release();
|
|
62
|
+
await tempPool.end();
|
|
63
|
+
return { connected: true };
|
|
64
|
+
} catch (error: any) {
|
|
65
|
+
return { connected: false, error: error.message || 'Database connection failed' };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
const client = await dbPool.connect();
|
|
71
|
+
await client.query('SELECT 1');
|
|
72
|
+
client.release();
|
|
73
|
+
return { connected: true };
|
|
74
|
+
} catch (error: any) {
|
|
75
|
+
return { connected: false, error: error.message || 'Database connection failed' };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Initialize database on startup
|
|
80
|
+
initDatabase();
|
|
81
|
+
|
|
82
|
+
// Health check endpoint with database connectivity check
|
|
83
|
+
app.get('/health', async (req: Request, res: Response) => {
|
|
84
|
+
const healthStatus: any = {
|
|
85
|
+
status: 'ok',
|
|
86
|
+
timestamp: new Date().toISOString()
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// Check database connection if database is configured (DATABASE_URL or individual vars)
|
|
90
|
+
const databaseUrl = process.env.DATABASE_URL;
|
|
91
|
+
const databaseHost = process.env.DATABASE_HOST || process.env.DB_HOST;
|
|
92
|
+
const databaseName = process.env.DATABASE_NAME || process.env.DB_NAME;
|
|
93
|
+
|
|
94
|
+
// Only check database if database is configured
|
|
95
|
+
if (databaseUrl || databaseHost || databaseName) {
|
|
96
|
+
const dbCheck = await checkDatabase();
|
|
97
|
+
if (dbCheck.connected) {
|
|
98
|
+
healthStatus.database = 'connected';
|
|
99
|
+
} else {
|
|
100
|
+
healthStatus.database = 'error';
|
|
101
|
+
healthStatus.database_error = dbCheck.error;
|
|
102
|
+
return res.status(503).json(healthStatus);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
res.status(200).json(healthStatus);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Root endpoint
|
|
110
|
+
app.get('/', (req: Request, res: Response) => {
|
|
111
|
+
res.json({ message: 'AI Fabrix Application', version: '1.0.0' });
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
app.listen(PORT, () => {
|
|
115
|
+
console.log(`Server running on port ${PORT}`);
|
|
116
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "aifabrix-app",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "AI Fabrix application",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "ts-node --transpile-only index.ts",
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"dev": "ts-node --transpile-only index.ts"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"express": "^4.18.2",
|
|
13
|
+
"pg": "^8.11.3"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@types/express": "^4.17.21",
|
|
17
|
+
"@types/node": "^20.10.0",
|
|
18
|
+
"@types/pg": "^8.10.9",
|
|
19
|
+
"ts-node": "^10.9.2",
|
|
20
|
+
"typescript": "^5.3.3"
|
|
21
|
+
},
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=18.0.0"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"lib": ["ES2020"],
|
|
6
|
+
"outDir": "./dist",
|
|
7
|
+
"rootDir": "./",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"moduleResolution": "node",
|
|
14
|
+
"types": ["node"]
|
|
15
|
+
},
|
|
16
|
+
"ts-node": {
|
|
17
|
+
"transpileOnly": true,
|
|
18
|
+
"compilerOptions": {
|
|
19
|
+
"module": "commonjs"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"include": ["*.ts"],
|
|
23
|
+
"exclude": ["node_modules", "dist"]
|
|
24
|
+
}
|