@zintrust/core 0.1.17 → 0.1.19
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 -0
- package/package.json +10 -1
- package/public/index.html +1 -1
- package/routes/api.d.ts +7 -0
- package/routes/api.d.ts.map +1 -0
- package/routes/api.js +91 -0
- package/routes/broadcast.d.ts +9 -0
- package/routes/broadcast.d.ts.map +1 -0
- package/routes/broadcast.js +27 -0
- package/routes/health.d.ts +7 -0
- package/routes/health.d.ts.map +1 -0
- package/routes/health.js +127 -0
- package/routes/storage.d.ts +4 -0
- package/routes/storage.d.ts.map +1 -0
- package/routes/storage.js +35 -0
- package/src/boot/Application.js +1 -1
- package/src/boot/bootstrap.js +1 -1
- package/src/cli/CLI.d.ts.map +1 -1
- package/src/cli/CLI.js +2 -0
- package/src/cli/PromptHelper.d.ts.map +1 -1
- package/src/cli/PromptHelper.js +5 -4
- package/src/cli/commands/NewCommand.d.ts +1 -1
- package/src/cli/commands/NewCommand.d.ts.map +1 -1
- package/src/cli/commands/NewCommand.js +27 -10
- package/src/cli/commands/SimulateCommand.js +1 -1
- package/src/cli/commands/StartCommand.d.ts.map +1 -1
- package/src/cli/commands/StartCommand.js +90 -3
- package/src/cli/commands/UpgradeCommand.d.ts +16 -0
- package/src/cli/commands/UpgradeCommand.d.ts.map +1 -0
- package/src/cli/commands/UpgradeCommand.js +107 -0
- package/src/cli/commands/runner/index.d.ts +3 -0
- package/src/cli/commands/runner/index.d.ts.map +1 -0
- package/src/cli/commands/runner/index.js +139 -0
- package/src/cli/config/ConfigSchema.js +1 -1
- package/src/cli/env/EnvFileBackfill.d.ts +10 -0
- package/src/cli/env/EnvFileBackfill.d.ts.map +1 -0
- package/src/cli/env/EnvFileBackfill.js +64 -0
- package/src/cli/scaffolding/ProjectScaffolder.d.ts.map +1 -1
- package/src/cli/scaffolding/ProjectScaffolder.js +53 -23
- package/src/cli/utils/DistPackager.d.ts.map +1 -1
- package/src/cli/utils/DistPackager.js +8 -0
- package/src/config/broadcast.js +1 -1
- package/src/config/database.d.ts +6 -0
- package/src/config/database.d.ts.map +1 -1
- package/src/config/database.js +7 -1
- package/src/config/index.d.ts +7 -1
- package/src/config/index.d.ts.map +1 -1
- package/src/config/middleware.d.ts +2 -1
- package/src/config/middleware.d.ts.map +1 -1
- package/src/config/middleware.js +47 -11
- package/src/config/notification.js +1 -1
- package/src/config/storage.js +1 -1
- package/src/config/type.d.ts +7 -1
- package/src/config/type.d.ts.map +1 -1
- package/src/index.d.ts +1 -0
- package/src/index.d.ts.map +1 -1
- package/src/middleware/RateLimiter.d.ts +35 -0
- package/src/middleware/RateLimiter.d.ts.map +1 -1
- package/src/middleware/RateLimiter.js +213 -16
- package/src/node.d.ts +1 -1
- package/src/node.d.ts.map +1 -1
- package/src/node.js +4 -1
- package/src/orm/DatabaseRuntimeRegistration.d.ts.map +1 -1
- package/src/orm/DatabaseRuntimeRegistration.js +4 -0
- package/src/orm/QueryBuilder.d.ts.map +1 -1
- package/src/orm/QueryBuilder.js +7 -3
- package/src/orm/adapters/SQLiteAdapter.d.ts.map +1 -1
- package/src/orm/adapters/SQLiteAdapter.js +5 -1
- package/src/routes/api.d.ts +2 -0
- package/src/routes/api.d.ts.map +1 -0
- package/src/routes/api.js +1 -0
- package/src/routes/broadcast.d.ts +2 -0
- package/src/routes/broadcast.d.ts.map +1 -0
- package/src/routes/broadcast.js +1 -0
- package/src/routes/health.d.ts +2 -0
- package/src/routes/health.d.ts.map +1 -0
- package/src/routes/health.js +1 -0
- package/src/routes/storage.d.ts +2 -0
- package/src/routes/storage.d.ts.map +1 -0
- package/src/routes/storage.js +1 -0
- package/src/runtime/RuntimeAdapter.d.ts.map +1 -1
- package/src/runtime/RuntimeAdapter.js +20 -1
- package/src/runtime/adapters/DenoAdapter.js +2 -2
- package/src/scripts/TemplateImportsCheck.js +7 -7
- package/src/scripts/TemplateSync.js +6 -0
- package/src/start.d.ts +21 -0
- package/src/start.d.ts.map +1 -0
- package/src/start.js +60 -0
- package/src/templates/features/Queue.ts.tpl +2 -3
- package/src/templates/project/basic/.env.example.tpl +1 -1
- package/src/templates/project/basic/app/Controllers/UserController.ts.tpl +2 -4
- package/src/templates/project/basic/app/Middleware/ProfilerMiddleware.ts.tpl +1 -3
- package/src/templates/project/basic/app/Middleware/index.ts.tpl +3 -8
- package/src/templates/project/basic/app/Models/Post.ts.tpl +2 -3
- package/src/templates/project/basic/app/Models/User.ts.tpl +1 -1
- package/src/templates/project/basic/config/FileLogWriter.ts.tpl +1 -1
- package/src/templates/project/basic/config/SecretsManager.ts.tpl +2 -2
- package/src/templates/project/basic/config/StartupConfigValidator.ts.tpl +2 -2
- package/src/templates/project/basic/config/app.ts.tpl +3 -3
- package/src/templates/project/basic/config/broadcast.ts.tpl +4 -5
- package/src/templates/project/basic/config/cache.ts.tpl +2 -3
- package/src/templates/project/basic/config/cloudflare.ts.tpl +1 -1
- package/src/templates/project/basic/config/database.ts.tpl +9 -3
- package/src/templates/project/basic/config/env.ts.tpl +1 -1
- package/src/templates/project/basic/config/features.ts.tpl +2 -2
- package/src/templates/project/basic/config/index.ts.tpl +38 -20
- package/src/templates/project/basic/config/logger.ts.tpl +5 -381
- package/src/templates/project/basic/config/logging/HttpLogger.ts.tpl +1 -1
- package/src/templates/project/basic/config/logging/KvLogger.ts.tpl +2 -2
- package/src/templates/project/basic/config/logging/SlackLogger.ts.tpl +1 -1
- package/src/templates/project/basic/config/mail.ts.tpl +2 -3
- package/src/templates/project/basic/config/microservices.ts.tpl +1 -1
- package/src/templates/project/basic/config/middleware.ts.tpl +40 -13
- package/src/templates/project/basic/config/notification.ts.tpl +3 -4
- package/src/templates/project/basic/config/queue.ts.tpl +2 -2
- package/src/templates/project/basic/config/security.ts.tpl +3 -3
- package/src/templates/project/basic/config/startup.ts.tpl +1 -1
- package/src/templates/project/basic/config/storage.ts.tpl +3 -4
- package/src/templates/project/basic/config/type.ts.tpl +12 -2
- package/src/templates/project/basic/package.json.tpl +1 -1
- package/src/templates/project/basic/routes/api.ts.tpl +4 -4
- package/src/templates/project/basic/routes/health.ts.tpl +1 -6
- package/src/templates/project/basic/src/index.ts.tpl +7 -80
- package/src/templates/project/basic/tsconfig.json.tpl +0 -2
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { BaseCommand } from '../BaseCommand.js';
|
|
2
|
+
import { DENO_RUNNER_SOURCE, LAMBDA_RUNNER_SOURCE } from '../commands/runner/index.js';
|
|
2
3
|
import { EnvFileLoader } from '../utils/EnvFileLoader.js';
|
|
3
4
|
import { SpawnUtil } from '../utils/spawn.js';
|
|
4
5
|
import { resolveNpmPath } from '../../common/index.js';
|
|
5
6
|
import { ErrorFactory } from '../../exceptions/ZintrustError.js';
|
|
6
|
-
import { existsSync, readFileSync } from '../../node-singletons/fs.js';
|
|
7
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from '../../node-singletons/fs.js';
|
|
7
8
|
import * as path from '../../node-singletons/path.js';
|
|
8
9
|
const isValidModeInput = (value) => value === 'development' ||
|
|
9
10
|
value === 'dev' ||
|
|
@@ -59,6 +60,22 @@ const resolveRuntime = (options) => {
|
|
|
59
60
|
const raw = typeof options.runtime === 'string' ? options.runtime.trim() : '';
|
|
60
61
|
return raw === '' ? undefined : raw;
|
|
61
62
|
};
|
|
63
|
+
const resolveStartVariant = (options) => {
|
|
64
|
+
const wantWrangler = options.wrangler === true || options.wg === true;
|
|
65
|
+
const wantDeno = options.deno === true;
|
|
66
|
+
const wantLambda = options.lambda === true;
|
|
67
|
+
const enabled = [wantWrangler, wantDeno, wantLambda].filter(Boolean).length;
|
|
68
|
+
if (enabled > 1) {
|
|
69
|
+
throw ErrorFactory.createCliError('Error: Choose only one of --wrangler/--wg, --deno, or --lambda.');
|
|
70
|
+
}
|
|
71
|
+
if (wantWrangler)
|
|
72
|
+
return 'wrangler';
|
|
73
|
+
if (wantDeno)
|
|
74
|
+
return 'deno';
|
|
75
|
+
if (wantLambda)
|
|
76
|
+
return 'lambda';
|
|
77
|
+
return 'node';
|
|
78
|
+
};
|
|
62
79
|
const hasFlag = (flag) => process.argv.includes(flag);
|
|
63
80
|
const resolveWatchPreference = (options, mode) => {
|
|
64
81
|
const hasWatch = hasFlag('--watch');
|
|
@@ -104,6 +121,10 @@ const findWranglerConfig = (cwd) => {
|
|
|
104
121
|
return undefined;
|
|
105
122
|
};
|
|
106
123
|
const resolveWranglerEntry = (cwd) => {
|
|
124
|
+
const indexEntry = path.join(cwd, 'src/index.ts');
|
|
125
|
+
if (existsSync(indexEntry))
|
|
126
|
+
return 'src/index.ts';
|
|
127
|
+
// Legacy fallback
|
|
107
128
|
const entry = path.join(cwd, 'src/functions/cloudflare.ts');
|
|
108
129
|
return existsSync(entry) ? 'src/functions/cloudflare.ts' : undefined;
|
|
109
130
|
};
|
|
@@ -167,6 +188,55 @@ const executeWranglerStart = async (cmd, cwd, port, runtime) => {
|
|
|
167
188
|
const exitCode = await SpawnUtil.spawnAndWait({ command: 'wrangler', args: wranglerArgs });
|
|
168
189
|
process.exit(exitCode);
|
|
169
190
|
};
|
|
191
|
+
const ensureTmpRunnerFile = (cwd, filename, content) => {
|
|
192
|
+
const tmpDir = path.join(cwd, 'tmp');
|
|
193
|
+
try {
|
|
194
|
+
mkdirSync(tmpDir, { recursive: true });
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
throw ErrorFactory.createTryCatchError('Failed to create tmp directory', error);
|
|
198
|
+
}
|
|
199
|
+
const fullPath = path.join(tmpDir, filename);
|
|
200
|
+
try {
|
|
201
|
+
writeFileSync(fullPath, content, 'utf-8');
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
throw ErrorFactory.createTryCatchError('Failed to write start runner', error);
|
|
205
|
+
}
|
|
206
|
+
return fullPath;
|
|
207
|
+
};
|
|
208
|
+
const executeDenoStart = async (cmd, cwd, mode, watchEnabled, _port, runtime) => {
|
|
209
|
+
if (runtime !== undefined) {
|
|
210
|
+
throw ErrorFactory.createCliError('Error: --runtime cannot be used with --deno.');
|
|
211
|
+
}
|
|
212
|
+
if (mode === 'testing') {
|
|
213
|
+
throw ErrorFactory.createCliError('Error: Cannot start server in testing mode. Use development or production.');
|
|
214
|
+
}
|
|
215
|
+
const denoRunner = ensureTmpRunnerFile(cwd, 'zin-start-deno.ts', DENO_RUNNER_SOURCE);
|
|
216
|
+
const args = [];
|
|
217
|
+
if (mode === 'development' && watchEnabled)
|
|
218
|
+
args.push('watch');
|
|
219
|
+
args.push(denoRunner);
|
|
220
|
+
cmd.info('Starting in Deno adapter mode...');
|
|
221
|
+
const exitCode = await SpawnUtil.spawnAndWait({ command: 'tsx', args });
|
|
222
|
+
process.exit(exitCode);
|
|
223
|
+
};
|
|
224
|
+
const executeLambdaStart = async (cmd, cwd, mode, watchEnabled, _port, runtime) => {
|
|
225
|
+
if (runtime !== undefined) {
|
|
226
|
+
throw ErrorFactory.createCliError('Error: --runtime cannot be used with --lambda.');
|
|
227
|
+
}
|
|
228
|
+
if (mode === 'testing') {
|
|
229
|
+
throw ErrorFactory.createCliError('Error: Cannot start server in testing mode. Use development or production.');
|
|
230
|
+
}
|
|
231
|
+
const lambdaRunner = ensureTmpRunnerFile(cwd, 'zin-start-lambda.ts', LAMBDA_RUNNER_SOURCE);
|
|
232
|
+
const args = [];
|
|
233
|
+
if (mode === 'development' && watchEnabled)
|
|
234
|
+
args.push('watch');
|
|
235
|
+
args.push(lambdaRunner);
|
|
236
|
+
cmd.info('Starting in Lambda adapter mode...');
|
|
237
|
+
const exitCode = await SpawnUtil.spawnAndWait({ command: 'tsx', args });
|
|
238
|
+
process.exit(exitCode);
|
|
239
|
+
};
|
|
170
240
|
const executeNodeStart = async (cmd, cwd, mode, watchEnabled) => {
|
|
171
241
|
if (mode === 'testing') {
|
|
172
242
|
throw ErrorFactory.createCliError('Error: Cannot start server in testing mode. Use --force to override (not supported).');
|
|
@@ -196,12 +266,26 @@ const executeStart = async (options, cmd) => {
|
|
|
196
266
|
const mode = resolveMode(options);
|
|
197
267
|
const port = resolvePort(options);
|
|
198
268
|
const runtime = resolveRuntime(options);
|
|
199
|
-
|
|
200
|
-
|
|
269
|
+
const variant = resolveStartVariant(options);
|
|
270
|
+
let effectiveRuntime = runtime;
|
|
271
|
+
if (variant === 'deno')
|
|
272
|
+
effectiveRuntime = 'deno';
|
|
273
|
+
if (variant === 'lambda')
|
|
274
|
+
effectiveRuntime = 'lambda';
|
|
275
|
+
EnvFileLoader.applyCliOverrides({ nodeEnv: mode, port, runtime: effectiveRuntime });
|
|
276
|
+
if (variant === 'wrangler') {
|
|
201
277
|
await executeWranglerStart(cmd, cwd, port, runtime);
|
|
202
278
|
return;
|
|
203
279
|
}
|
|
204
280
|
const watchEnabled = resolveWatchPreference(options, mode);
|
|
281
|
+
if (variant === 'deno') {
|
|
282
|
+
await executeDenoStart(cmd, cwd, mode, watchEnabled, port, runtime);
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
if (variant === 'lambda') {
|
|
286
|
+
await executeLambdaStart(cmd, cwd, mode, watchEnabled, port, runtime);
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
205
289
|
await executeNodeStart(cmd, cwd, mode, watchEnabled);
|
|
206
290
|
};
|
|
207
291
|
export const StartCommand = Object.freeze({
|
|
@@ -210,6 +294,9 @@ export const StartCommand = Object.freeze({
|
|
|
210
294
|
command.alias('s');
|
|
211
295
|
command
|
|
212
296
|
.option('-w, --wrangler', 'Start with Wrangler dev mode (Cloudflare Workers)')
|
|
297
|
+
.option('--wg', 'Alias for --wrangler')
|
|
298
|
+
.option('--deno', 'Start a local server using the Deno runtime adapter')
|
|
299
|
+
.option('--lambda', 'Start a local server using the AWS Lambda runtime adapter')
|
|
213
300
|
.option('--watch', 'Force watch mode (Node only)')
|
|
214
301
|
.option('--no-watch', 'Disable watch mode (Node only)')
|
|
215
302
|
.option('--mode <development|production|testing>', 'Override app mode')
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Upgrade Command
|
|
3
|
+
*
|
|
4
|
+
* Goal: help existing Zintrust projects adopt new safe defaults without forcing
|
|
5
|
+
* a full re-scaffold.
|
|
6
|
+
*
|
|
7
|
+
* Current scope (minimal/safe):
|
|
8
|
+
* - Backfill required .env defaults (HOST, PORT, LOG_LEVEL) when missing or blank.
|
|
9
|
+
* - Never overwrite a non-empty user value.
|
|
10
|
+
*/
|
|
11
|
+
import { type IBaseCommand } from '../BaseCommand';
|
|
12
|
+
export declare const UpgradeCommand: Readonly<{
|
|
13
|
+
create(): IBaseCommand;
|
|
14
|
+
}>;
|
|
15
|
+
export default UpgradeCommand;
|
|
16
|
+
//# sourceMappingURL=UpgradeCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UpgradeCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/UpgradeCommand.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAoFvF,eAAO,MAAM,cAAc;cACf,YAAY;EA6BtB,CAAC;AAEH,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Upgrade Command
|
|
3
|
+
*
|
|
4
|
+
* Goal: help existing Zintrust projects adopt new safe defaults without forcing
|
|
5
|
+
* a full re-scaffold.
|
|
6
|
+
*
|
|
7
|
+
* Current scope (minimal/safe):
|
|
8
|
+
* - Backfill required .env defaults (HOST, PORT, LOG_LEVEL) when missing or blank.
|
|
9
|
+
* - Never overwrite a non-empty user value.
|
|
10
|
+
*/
|
|
11
|
+
import { BaseCommand } from '../BaseCommand.js';
|
|
12
|
+
import { ErrorHandler } from '../ErrorHandler.js';
|
|
13
|
+
import { EnvFileBackfill } from '../env/EnvFileBackfill.js';
|
|
14
|
+
import { mkdirSync, readFileSync, unlinkSync, writeFileSync } from '../../node-singletons/fs.js';
|
|
15
|
+
import * as path from '../../node-singletons/path.js';
|
|
16
|
+
const ensureEnvFileExists = (envPath) => {
|
|
17
|
+
const dir = path.dirname(envPath);
|
|
18
|
+
mkdirSync(dir, { recursive: true });
|
|
19
|
+
try {
|
|
20
|
+
readFileSync(envPath, 'utf8');
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
writeFileSync(envPath, '\n', 'utf8');
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
const resolveCwd = (cwd) => {
|
|
27
|
+
if (typeof cwd === 'string' && cwd.trim() !== '')
|
|
28
|
+
return cwd;
|
|
29
|
+
return process.cwd();
|
|
30
|
+
};
|
|
31
|
+
const getEnvDefaults = () => Object.freeze({
|
|
32
|
+
HOST: 'localhost',
|
|
33
|
+
PORT: '7777',
|
|
34
|
+
LOG_LEVEL: 'debug',
|
|
35
|
+
});
|
|
36
|
+
const envFileExists = (envPath) => {
|
|
37
|
+
try {
|
|
38
|
+
readFileSync(envPath, 'utf8');
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
const formatBackfillSummary = (result) => {
|
|
46
|
+
const filled = result.filledKeys.join(', ') || '(none)';
|
|
47
|
+
const appended = result.appendedKeys.join(', ') || '(none)';
|
|
48
|
+
return `filled=${filled}; appended=${appended}`;
|
|
49
|
+
};
|
|
50
|
+
const runDryRun = (envPath, defaults) => {
|
|
51
|
+
const exists = envFileExists(envPath);
|
|
52
|
+
if (exists === false) {
|
|
53
|
+
ErrorHandler.info(`[dry-run] Would create ${envPath}`);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const raw = readFileSync(envPath, 'utf8');
|
|
57
|
+
const tmpPath = `${envPath}.zin-upgrade.tmp`;
|
|
58
|
+
writeFileSync(tmpPath, raw, 'utf8');
|
|
59
|
+
try {
|
|
60
|
+
const result = EnvFileBackfill.backfillEnvDefaults(tmpPath, defaults);
|
|
61
|
+
if (result.changed === false) {
|
|
62
|
+
ErrorHandler.success('No changes needed.');
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
ErrorHandler.info(`[dry-run] Would backfill .env: ${formatBackfillSummary(result)}`);
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
try {
|
|
69
|
+
unlinkSync(tmpPath);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// ignore
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
const runUpgrade = (envPath, defaults) => {
|
|
77
|
+
ensureEnvFileExists(envPath);
|
|
78
|
+
return EnvFileBackfill.backfillEnvDefaults(envPath, defaults);
|
|
79
|
+
};
|
|
80
|
+
export const UpgradeCommand = Object.freeze({
|
|
81
|
+
create() {
|
|
82
|
+
return BaseCommand.create({
|
|
83
|
+
name: 'upgrade',
|
|
84
|
+
description: 'Upgrade an existing Zintrust project in-place (safe, non-destructive)',
|
|
85
|
+
addOptions: (command) => {
|
|
86
|
+
command.option('--cwd <path>', 'Project directory (default: current working directory)');
|
|
87
|
+
command.option('--dry-run', 'Print planned changes without writing files');
|
|
88
|
+
},
|
|
89
|
+
execute: (options) => {
|
|
90
|
+
const cwd = resolveCwd(options.cwd);
|
|
91
|
+
const envPath = path.resolve(cwd, '.env');
|
|
92
|
+
const defaults = getEnvDefaults();
|
|
93
|
+
if (options.dryRun === true) {
|
|
94
|
+
runDryRun(envPath, defaults);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const result = runUpgrade(envPath, defaults);
|
|
98
|
+
if (result.changed === false) {
|
|
99
|
+
ErrorHandler.success('No changes needed.');
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
ErrorHandler.success(`Upgraded .env: ${formatBackfillSummary(result)}`);
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
export default UpgradeCommand;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/runner/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB,QAwDnB,CAAC;AAEb,eAAO,MAAM,oBAAoB,QAiFrB,CAAC"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
export const DENO_RUNNER_SOURCE = [
|
|
2
|
+
"import http from 'node:http';",
|
|
3
|
+
"import { deno } from '@zintrust/core/start';",
|
|
4
|
+
'',
|
|
5
|
+
"const port = Number.parseInt(process.env.PORT ?? '3000', 10) || 3000;",
|
|
6
|
+
"const host = process.env.HOST ?? 'localhost';",
|
|
7
|
+
'',
|
|
8
|
+
'const readBody = async (req: http.IncomingMessage): Promise<Buffer | undefined> => {',
|
|
9
|
+
" if (req.method === 'GET' || req.method === 'HEAD') return undefined;",
|
|
10
|
+
' const chunks: Buffer[] = [];',
|
|
11
|
+
' for await (const chunk of req) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));',
|
|
12
|
+
' return chunks.length > 0 ? Buffer.concat(chunks) : undefined;',
|
|
13
|
+
'};',
|
|
14
|
+
'',
|
|
15
|
+
'const server = http.createServer(async (req, res) => {',
|
|
16
|
+
' try {',
|
|
17
|
+
" const proto = (req.headers['x-forwarded-proto'] ?? 'http').toString();",
|
|
18
|
+
' const authority = (req.headers.host ?? host).toString();',
|
|
19
|
+
" const url = new URL(req.url ?? '/', proto + '://' + authority);",
|
|
20
|
+
'',
|
|
21
|
+
' const headers = new Headers();',
|
|
22
|
+
' for (const [key, value] of Object.entries(req.headers)) {',
|
|
23
|
+
' if (value === undefined) continue;',
|
|
24
|
+
' if (Array.isArray(value)) {',
|
|
25
|
+
' for (const v of value) headers.append(key, v);',
|
|
26
|
+
' } else {',
|
|
27
|
+
' headers.set(key, String(value));',
|
|
28
|
+
' }',
|
|
29
|
+
' }',
|
|
30
|
+
'',
|
|
31
|
+
' const body = await readBody(req);',
|
|
32
|
+
' const request = new Request(url.toString(), {',
|
|
33
|
+
" method: req.method ?? 'GET',",
|
|
34
|
+
' headers,',
|
|
35
|
+
' body,',
|
|
36
|
+
' });',
|
|
37
|
+
'',
|
|
38
|
+
' const response = await deno(request);',
|
|
39
|
+
'',
|
|
40
|
+
' res.statusCode = response.status;',
|
|
41
|
+
' response.headers.forEach((v, k) => res.setHeader(k, v));',
|
|
42
|
+
'',
|
|
43
|
+
' const ab = await response.arrayBuffer();',
|
|
44
|
+
' res.end(Buffer.from(ab));',
|
|
45
|
+
' } catch (err) {',
|
|
46
|
+
' res.statusCode = 500;',
|
|
47
|
+
" res.setHeader('content-type', 'text/plain');",
|
|
48
|
+
" res.end('Internal Server Error' + (err as Error).message);",
|
|
49
|
+
' }',
|
|
50
|
+
'});',
|
|
51
|
+
'',
|
|
52
|
+
'server.listen(port, host, () => {',
|
|
53
|
+
' // eslint-disable-next-line no-console',
|
|
54
|
+
" console.log('Deno adapter server listening at http://' + host + ':' + port);",
|
|
55
|
+
'});',
|
|
56
|
+
'',
|
|
57
|
+
].join('\n');
|
|
58
|
+
export const LAMBDA_RUNNER_SOURCE = [
|
|
59
|
+
"import http from 'node:http';",
|
|
60
|
+
"import { handler as lambdaHandler } from '@zintrust/core/start';",
|
|
61
|
+
'',
|
|
62
|
+
"const port = Number.parseInt(process.env.PORT ?? '3000', 10) || 3000;",
|
|
63
|
+
"const host = process.env.HOST ?? 'localhost';",
|
|
64
|
+
'',
|
|
65
|
+
'const readBody = async (req: http.IncomingMessage): Promise<string | undefined> => {',
|
|
66
|
+
" if (req.method === 'GET' || req.method === 'HEAD') return undefined;",
|
|
67
|
+
' const chunks: Buffer[] = [];',
|
|
68
|
+
' for await (const chunk of req) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));',
|
|
69
|
+
" return chunks.length > 0 ? Buffer.concat(chunks).toString('utf-8') : undefined;",
|
|
70
|
+
'};',
|
|
71
|
+
'',
|
|
72
|
+
'const server = http.createServer(async (req, res) => {',
|
|
73
|
+
' try {',
|
|
74
|
+
" const proto = (req.headers['x-forwarded-proto'] ?? 'http').toString();",
|
|
75
|
+
' const authority = (req.headers.host ?? host).toString();',
|
|
76
|
+
" const url = new URL(req.url ?? '/', proto + '://' + authority);",
|
|
77
|
+
'',
|
|
78
|
+
' const body = await readBody(req);',
|
|
79
|
+
' const headers: Record<string, string> = {};',
|
|
80
|
+
' for (const [k, v] of Object.entries(req.headers)) {',
|
|
81
|
+
' if (v === undefined) continue;',
|
|
82
|
+
" headers[k] = Array.isArray(v) ? v.join(',') : String(v);",
|
|
83
|
+
' }',
|
|
84
|
+
'',
|
|
85
|
+
' const queryStringParameters: Record<string, string> = {};',
|
|
86
|
+
' url.searchParams.forEach((value, key) => {',
|
|
87
|
+
' if (queryStringParameters[key] === undefined) queryStringParameters[key] = value;',
|
|
88
|
+
' });',
|
|
89
|
+
'',
|
|
90
|
+
' const event = {',
|
|
91
|
+
" version: '2.0',",
|
|
92
|
+
" routeKey: '$default',",
|
|
93
|
+
' rawPath: url.pathname,',
|
|
94
|
+
' rawQueryString: url.searchParams.toString(),',
|
|
95
|
+
' headers,',
|
|
96
|
+
' queryStringParameters,',
|
|
97
|
+
' requestContext: {',
|
|
98
|
+
' http: {',
|
|
99
|
+
" method: req.method ?? 'GET',",
|
|
100
|
+
' path: url.pathname,',
|
|
101
|
+
" sourceIp: (req.socket.remoteAddress ?? '').toString(),",
|
|
102
|
+
' },',
|
|
103
|
+
' },',
|
|
104
|
+
' body: body ?? null,',
|
|
105
|
+
' isBase64Encoded: false,',
|
|
106
|
+
' };',
|
|
107
|
+
'',
|
|
108
|
+
' const result = (await lambdaHandler(event, {})) as {',
|
|
109
|
+
' statusCode?: number;',
|
|
110
|
+
' headers?: Record<string, string | string[]>;',
|
|
111
|
+
' body?: string;',
|
|
112
|
+
' isBase64Encoded?: boolean;',
|
|
113
|
+
' };',
|
|
114
|
+
'',
|
|
115
|
+
' res.statusCode = typeof result.statusCode === "number" ? result.statusCode : 200;',
|
|
116
|
+
' if (result.headers) {',
|
|
117
|
+
' for (const [k, v] of Object.entries(result.headers)) {',
|
|
118
|
+
' res.setHeader(k, v as any);',
|
|
119
|
+
' }',
|
|
120
|
+
' }',
|
|
121
|
+
'',
|
|
122
|
+
' if (result.isBase64Encoded === true && typeof result.body === "string") {',
|
|
123
|
+
" res.end(Buffer.from(result.body, 'base64'));",
|
|
124
|
+
' } else {',
|
|
125
|
+
" res.end(result.body ?? '');",
|
|
126
|
+
' }',
|
|
127
|
+
' } catch {',
|
|
128
|
+
' res.statusCode = 500;',
|
|
129
|
+
" res.setHeader('content-type', 'application/json');",
|
|
130
|
+
" res.end(JSON.stringify({ message: 'Internal Server Error' }));",
|
|
131
|
+
' }',
|
|
132
|
+
'});',
|
|
133
|
+
'',
|
|
134
|
+
'server.listen(port, host, () => {',
|
|
135
|
+
' // eslint-disable-next-line no-console',
|
|
136
|
+
" console.log('Lambda adapter server listening at http://' + host + ':' + port);",
|
|
137
|
+
'});',
|
|
138
|
+
'',
|
|
139
|
+
].join('\n');
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type EnvBackfillResult = {
|
|
2
|
+
changed: boolean;
|
|
3
|
+
filledKeys: string[];
|
|
4
|
+
appendedKeys: string[];
|
|
5
|
+
};
|
|
6
|
+
export declare const EnvFileBackfill: Readonly<{
|
|
7
|
+
stripEnvInlineComment: (value: string) => string;
|
|
8
|
+
backfillEnvDefaults: (envPath: string, defaults: Record<string, string>) => EnvBackfillResult;
|
|
9
|
+
}>;
|
|
10
|
+
//# sourceMappingURL=EnvFileBackfill.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EnvFileBackfill.d.ts","sourceRoot":"","sources":["../../../../src/cli/env/EnvFileBackfill.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AAsEF,eAAO,MAAM,eAAe;mCApEU,MAAM,KAAG,MAAM;mCAqB1C,MAAM,YACL,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAC/B,iBAAiB;EAgDlB,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from '../../node-singletons/fs.js';
|
|
2
|
+
const stripEnvInlineComment = (value) => {
|
|
3
|
+
let inSingle = false;
|
|
4
|
+
let inDouble = false;
|
|
5
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
6
|
+
const ch = value[i];
|
|
7
|
+
if (ch === "'" && !inDouble)
|
|
8
|
+
inSingle = !inSingle;
|
|
9
|
+
if (ch === '"' && !inSingle)
|
|
10
|
+
inDouble = !inDouble;
|
|
11
|
+
if (!inSingle && !inDouble && ch === '#') {
|
|
12
|
+
const prev = value[i - 1];
|
|
13
|
+
if (prev === undefined || prev === ' ' || prev === '\t') {
|
|
14
|
+
return value.slice(0, i).trimEnd();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return value;
|
|
19
|
+
};
|
|
20
|
+
const backfillEnvDefaults = (envPath, defaults) => {
|
|
21
|
+
const raw = readFileSync(envPath, 'utf8');
|
|
22
|
+
const lines = raw.split(/\r?\n/);
|
|
23
|
+
const seen = new Set();
|
|
24
|
+
const filledKeys = [];
|
|
25
|
+
const appendedKeys = [];
|
|
26
|
+
const out = lines.map((line) => {
|
|
27
|
+
const trimmed = line.trim();
|
|
28
|
+
if (trimmed === '' || trimmed.startsWith('#'))
|
|
29
|
+
return line;
|
|
30
|
+
const withoutExport = trimmed.startsWith('export ') ? trimmed.slice('export '.length) : trimmed;
|
|
31
|
+
const eq = withoutExport.indexOf('=');
|
|
32
|
+
if (eq <= 0)
|
|
33
|
+
return line;
|
|
34
|
+
const key = withoutExport.slice(0, eq).trim();
|
|
35
|
+
if (key === '')
|
|
36
|
+
return line;
|
|
37
|
+
if (!Object.hasOwn(defaults, key))
|
|
38
|
+
return line;
|
|
39
|
+
if (seen.has(key))
|
|
40
|
+
return line;
|
|
41
|
+
seen.add(key);
|
|
42
|
+
const rhs = withoutExport.slice(eq + 1);
|
|
43
|
+
const withoutComment = stripEnvInlineComment(rhs);
|
|
44
|
+
const value = withoutComment.trim();
|
|
45
|
+
if (value !== '')
|
|
46
|
+
return line;
|
|
47
|
+
filledKeys.push(key);
|
|
48
|
+
return `${key}=${defaults[key]}`;
|
|
49
|
+
});
|
|
50
|
+
const missingKeys = Object.keys(defaults).filter((k) => !seen.has(k));
|
|
51
|
+
if (missingKeys.length > 0) {
|
|
52
|
+
appendedKeys.push(...missingKeys);
|
|
53
|
+
out.push(...missingKeys.map((k) => `${k}=${defaults[k]}`));
|
|
54
|
+
}
|
|
55
|
+
const changed = filledKeys.length > 0 || appendedKeys.length > 0;
|
|
56
|
+
if (!changed)
|
|
57
|
+
return { changed: false, filledKeys, appendedKeys };
|
|
58
|
+
writeFileSync(envPath, out.join('\n') + (out.at(-1) === '' ? '' : '\n'));
|
|
59
|
+
return { changed: true, filledKeys, appendedKeys };
|
|
60
|
+
};
|
|
61
|
+
export const EnvFileBackfill = Object.freeze({
|
|
62
|
+
stripEnvInlineComment,
|
|
63
|
+
backfillEnvDefaults,
|
|
64
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectScaffolder.d.ts","sourceRoot":"","sources":["../../../../src/cli/scaffolding/ProjectScaffolder.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"ProjectScaffolder.d.ts","sourceRoot":"","sources":["../../../../src/cli/scaffolding/ProjectScaffolder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,cAAc,GAAG,sBAAsB,CAAC;AAEpD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,cAAc,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI,CAAC;IACtD,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,eAAe,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAAC;IACpE,cAAc,IAAI,MAAM,CAAC;IACzB,sBAAsB,IAAI,OAAO,CAAC;IAClC,iBAAiB,IAAI,MAAM,CAAC;IAC5B,WAAW,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,MAAM,CAAC;IACtD,gBAAgB,IAAI,OAAO,CAAC;IAC5B,aAAa,IAAI,OAAO,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;CAC3E;AA0cD,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAEhD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAsBrE;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG;IAChE,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAsBA;AA0ID;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,GAAE,MAAsB,GAAG,kBAAkB,CAsB/F;AAED,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,qBAAqB,CAAC,CAEhC;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;EAM5B,CAAC"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Project Scaffolder - New project generation
|
|
3
3
|
* Handles directory structure and boilerplate file creation
|
|
4
4
|
*/
|
|
5
|
+
import { EnvFileBackfill } from '../env/EnvFileBackfill.js';
|
|
5
6
|
import { Logger } from '../../config/logger.js';
|
|
6
7
|
import { randomBytes } from '../../node-singletons/crypto.js';
|
|
7
8
|
import fs from '../../node-singletons/fs.js';
|
|
@@ -87,7 +88,7 @@ const createProjectConfigFile = (projectPath, variables) => {
|
|
|
87
88
|
connection: variables['database'] ?? 'sqlite',
|
|
88
89
|
},
|
|
89
90
|
server: {
|
|
90
|
-
port: variables['port'] ??
|
|
91
|
+
port: variables['port'] ?? 7777,
|
|
91
92
|
},
|
|
92
93
|
};
|
|
93
94
|
fs.writeFileSync(fullPath, JSON.stringify(config, null, 2));
|
|
@@ -97,18 +98,59 @@ const createProjectConfigFile = (projectPath, variables) => {
|
|
|
97
98
|
return false;
|
|
98
99
|
}
|
|
99
100
|
};
|
|
101
|
+
const buildDatabaseEnvLines = (database) => {
|
|
102
|
+
if (database === 'postgresql' || database === 'postgres') {
|
|
103
|
+
return [
|
|
104
|
+
'DB_HOST=localhost',
|
|
105
|
+
'DB_PORT=5432',
|
|
106
|
+
'DB_DATABASE=zintrust',
|
|
107
|
+
'DB_USERNAME=postgres',
|
|
108
|
+
'DB_PASSWORD=',
|
|
109
|
+
];
|
|
110
|
+
}
|
|
111
|
+
if (database === 'mysql') {
|
|
112
|
+
return [
|
|
113
|
+
'DB_HOST=localhost',
|
|
114
|
+
'DB_PORT=3306',
|
|
115
|
+
'DB_DATABASE=zintrust',
|
|
116
|
+
'DB_USERNAME=root',
|
|
117
|
+
'DB_PASSWORD=',
|
|
118
|
+
];
|
|
119
|
+
}
|
|
120
|
+
if (database === 'sqlite') {
|
|
121
|
+
// Provide both DB_DATABASE (used by the framework) and DB_PATH (common alias)
|
|
122
|
+
return ['DB_DATABASE=./database.sqlite', 'DB_PATH=./database.sqlite'];
|
|
123
|
+
}
|
|
124
|
+
if (database === 'd1-remote' || database === 'd1-proxy') {
|
|
125
|
+
return [
|
|
126
|
+
'# Cloudflare D1 Remote Proxy (HTTPS)',
|
|
127
|
+
'D1_REMOTE_URL=',
|
|
128
|
+
'D1_REMOTE_KEY_ID=',
|
|
129
|
+
'D1_REMOTE_SECRET=',
|
|
130
|
+
'D1_REMOTE_MODE=registry',
|
|
131
|
+
'ZT_PROXY_TIMEOUT_MS=15000',
|
|
132
|
+
];
|
|
133
|
+
}
|
|
134
|
+
return [];
|
|
135
|
+
};
|
|
100
136
|
const createEnvFile = (projectPath, variables) => {
|
|
101
137
|
try {
|
|
102
138
|
if (!fs.existsSync(projectPath)) {
|
|
103
139
|
fs.mkdirSync(projectPath, { recursive: true });
|
|
104
140
|
}
|
|
105
141
|
const fullPath = path.join(projectPath, '.env');
|
|
106
|
-
// If
|
|
142
|
+
// If an .env already exists (e.g., from a template), do not overwrite user values.
|
|
143
|
+
// But we *do* backfill safe defaults for common bootstrap keys when missing/blank.
|
|
107
144
|
if (fs.existsSync(fullPath)) {
|
|
145
|
+
EnvFileBackfill.backfillEnvDefaults(fullPath, {
|
|
146
|
+
HOST: 'localhost',
|
|
147
|
+
PORT: String(Number(variables['port'] ?? 7777)),
|
|
148
|
+
LOG_LEVEL: 'debug',
|
|
149
|
+
});
|
|
108
150
|
return true;
|
|
109
151
|
}
|
|
110
152
|
const name = typeof variables['projectName'] === 'string' ? variables['projectName'] : 'zintrust-app';
|
|
111
|
-
const port = Number(variables['port'] ??
|
|
153
|
+
const port = Number(variables['port'] ?? 7777);
|
|
112
154
|
const database = typeof variables['database'] === 'string' ? variables['database'] : 'sqlite';
|
|
113
155
|
// Generate a secure APP_KEY (32 bytes = 256-bit, base64 encoded)
|
|
114
156
|
const appKeyBytes = randomBytes(32);
|
|
@@ -119,28 +161,12 @@ const createEnvFile = (projectPath, variables) => {
|
|
|
119
161
|
`APP_NAME=${name}`,
|
|
120
162
|
'HOST=localhost',
|
|
121
163
|
`PORT=${port}`,
|
|
122
|
-
`APP_PORT=${port}`,
|
|
123
164
|
'APP_DEBUG=true',
|
|
124
165
|
// Auto-generated secure key for storage signing and encryption
|
|
125
166
|
`APP_KEY=${appKey}`,
|
|
126
167
|
`DB_CONNECTION=${database}`,
|
|
127
168
|
];
|
|
128
|
-
const dbLines = (
|
|
129
|
-
if (database === 'postgresql' || database === 'postgres') {
|
|
130
|
-
return [
|
|
131
|
-
'DB_HOST=localhost',
|
|
132
|
-
'DB_PORT=5432',
|
|
133
|
-
'DB_DATABASE=zintrust',
|
|
134
|
-
'DB_USERNAME=postgres',
|
|
135
|
-
'DB_PASSWORD=',
|
|
136
|
-
];
|
|
137
|
-
}
|
|
138
|
-
if (database === 'sqlite') {
|
|
139
|
-
// Provide both DB_DATABASE (used by the framework) and DB_PATH (common alias)
|
|
140
|
-
return ['DB_DATABASE=./database.sqlite', 'DB_PATH=./database.sqlite'];
|
|
141
|
-
}
|
|
142
|
-
return [];
|
|
143
|
-
})();
|
|
169
|
+
const dbLines = buildDatabaseEnvLines(database);
|
|
144
170
|
const placeholderLines = [
|
|
145
171
|
'',
|
|
146
172
|
'# Logging',
|
|
@@ -162,7 +188,7 @@ const createEnvFile = (projectPath, variables) => {
|
|
|
162
188
|
'',
|
|
163
189
|
'# Microservices',
|
|
164
190
|
'SERVICE_DISCOVERY_ENABLED=false',
|
|
165
|
-
'
|
|
191
|
+
'SERVICE_DISCOVERY_TYPE=filesystem',
|
|
166
192
|
'SERVICE_NAME=',
|
|
167
193
|
'SERVICE_VERSION=1.0.0',
|
|
168
194
|
];
|
|
@@ -245,11 +271,15 @@ const loadTemplateFiles = (templateDir) => {
|
|
|
245
271
|
if (relPath === 'template.json')
|
|
246
272
|
return false;
|
|
247
273
|
const normalized = normalizeRelPath(relPath);
|
|
274
|
+
// Project `.env` is generated by createEnvFile() so it can set defaults and create a secure APP_KEY.
|
|
275
|
+
// Some templates ship `.env.tpl` (which would become `.env`), but that file is intentionally ignored.
|
|
276
|
+
const outputRel = normalizeRelPath(getOutputRelPath(relPath));
|
|
277
|
+
if (outputRel === '.env')
|
|
278
|
+
return false;
|
|
248
279
|
if (!normalized.startsWith('config/'))
|
|
249
280
|
return true;
|
|
250
281
|
// Starter apps should only ship app-level config modules.
|
|
251
282
|
// Core/framework config internals (e.g. config/logging/*) remain core-owned.
|
|
252
|
-
const outputRel = normalizeRelPath(getOutputRelPath(relPath));
|
|
253
283
|
return allowedConfigFiles.has(outputRel);
|
|
254
284
|
};
|
|
255
285
|
const readUtf8FileOrUndefined = (absPath) => {
|
|
@@ -424,7 +454,7 @@ const prepareContext = (state, options) => {
|
|
|
424
454
|
projectSlug: options.name,
|
|
425
455
|
author: options.author ?? 'Your Name',
|
|
426
456
|
description: options.description ?? '',
|
|
427
|
-
port: options.port ??
|
|
457
|
+
port: options.port ?? 7777,
|
|
428
458
|
database: options.database ?? 'sqlite',
|
|
429
459
|
template: state.templateName,
|
|
430
460
|
migrationTimestamp,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DistPackager.d.ts","sourceRoot":"","sources":["../../../../src/cli/utils/DistPackager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"DistPackager.d.ts","sourceRoot":"","sources":["../../../../src/cli/utils/DistPackager.ts"],"names":[],"mappings":"AAoIA,eAAO,MAAM,YAAY;IACvB;;;OAGG;sBACe,MAAM,aAAY,MAAM,GAAmB,IAAI;EAgBjE,CAAC"}
|