@stacksjs/actions 0.70.88 → 0.70.91
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/dist/action.d.ts +149 -0
- package/dist/action.js +78 -0
- package/dist/actions.d.ts +2 -0
- package/dist/actions.js +2 -0
- package/dist/add.d.ts +6 -0
- package/dist/add.js +20 -0
- package/dist/ai/request-model-access.d.ts +1 -0
- package/dist/ai/request-model-access.js +10 -0
- package/dist/auth/client.d.ts +1 -0
- package/dist/auth/client.js +44 -0
- package/dist/auth/prune.d.ts +1 -0
- package/dist/auth/prune.js +35 -0
- package/dist/auth/setup.d.ts +1 -0
- package/dist/auth/setup.js +322 -0
- package/dist/auth/token.d.ts +1 -0
- package/dist/auth/token.js +10 -0
- package/dist/blog-admin.d.ts +55 -0
- package/dist/blog-admin.js +156 -0
- package/dist/blog.d.ts +30 -0
- package/dist/blog.js +398 -0
- package/dist/build/cli.d.ts +1 -0
- package/dist/build/cli.js +6 -0
- package/dist/build/component-libs.d.ts +1 -0
- package/dist/build/component-libs.js +7 -0
- package/dist/build/core.d.ts +1 -0
- package/dist/build/core.js +55 -0
- package/dist/build/desktop.d.ts +1 -0
- package/dist/build/desktop.js +5 -0
- package/dist/build/docs.d.ts +1 -0
- package/dist/build/docs.js +5 -0
- package/dist/build/frontend-static.d.ts +16 -0
- package/dist/build/frontend-static.js +124 -0
- package/dist/build/server.d.ts +1 -0
- package/dist/build/server.js +6 -0
- package/dist/build/stacks.d.ts +1 -0
- package/dist/build/stacks.js +8 -0
- package/dist/build/views.d.ts +1 -0
- package/dist/build/views.js +11 -0
- package/dist/build.d.ts +9 -0
- package/dist/build.js +64 -0
- package/dist/bump.d.ts +1 -0
- package/dist/bump.js +163 -0
- package/dist/cdn/invalidate-cache.d.ts +1 -0
- package/dist/cdn/invalidate-cache.js +0 -0
- package/dist/changelog.d.ts +9 -0
- package/dist/changelog.js +27 -0
- package/dist/check/ports.d.ts +1 -0
- package/dist/check/ports.js +16 -0
- package/dist/clean.d.ts +1 -0
- package/dist/clean.js +4 -0
- package/dist/commit.d.ts +3 -0
- package/dist/commit.js +12 -0
- package/dist/copy-types.d.ts +1 -0
- package/dist/copy-types.js +10 -0
- package/dist/database/seed.d.ts +1 -0
- package/dist/database/seed.js +26 -0
- package/dist/deploy/create-receipt-rule.d.ts +1 -0
- package/dist/deploy/create-receipt-rule.js +36 -0
- package/dist/deploy/index.d.ts +1 -0
- package/dist/deploy/index.js +1574 -0
- package/dist/dev/api.d.ts +1 -0
- package/dist/dev/api.js +94 -0
- package/dist/dev/components.d.ts +1 -0
- package/dist/dev/components.js +7 -0
- package/dist/dev/dashboard-globals.d.ts +4 -0
- package/dist/dev/dashboard-globals.js +89 -0
- package/dist/dev/dashboard-utils.d.ts +150 -0
- package/dist/dev/dashboard-utils.js +380 -0
- package/dist/dev/dashboard.d.ts +22 -0
- package/dist/dev/dashboard.js +435 -0
- package/dist/dev/desktop.d.ts +1 -0
- package/dist/dev/desktop.js +5 -0
- package/dist/dev/docs.d.ts +1 -0
- package/dist/dev/docs.js +24 -0
- package/dist/dev/index.d.ts +10 -0
- package/dist/dev/index.js +29 -0
- package/dist/dev/migrate-watcher.d.ts +1 -0
- package/dist/dev/migrate-watcher.js +74 -0
- package/dist/dev/system-tray.d.ts +1 -0
- package/dist/dev/system-tray.js +5 -0
- package/dist/dev/views.d.ts +1 -0
- package/dist/dev/views.js +147 -0
- package/dist/discover-packages.d.ts +18 -0
- package/dist/discover-packages.js +32 -0
- package/dist/domains/add.d.ts +1 -0
- package/dist/domains/add.js +61 -0
- package/dist/domains/purchase.d.ts +1 -0
- package/dist/domains/purchase.js +66 -0
- package/dist/domains/remove.d.ts +1 -0
- package/dist/domains/remove.js +24 -0
- package/dist/examples.d.ts +5 -0
- package/dist/examples.js +34 -0
- package/dist/find-projects.d.ts +1 -0
- package/dist/find-projects.js +16 -0
- package/dist/fresh.d.ts +1 -0
- package/dist/fresh.js +17 -0
- package/dist/generate/action-types.d.ts +1 -0
- package/dist/generate/action-types.js +13 -0
- package/dist/generate/component-meta.d.ts +1 -0
- package/dist/generate/component-meta.js +9 -0
- package/dist/generate/custom-cli-file.d.ts +1 -0
- package/dist/generate/custom-cli-file.js +21 -0
- package/dist/generate/env-files.d.ts +1 -0
- package/dist/generate/env-files.js +66 -0
- package/dist/generate/ide-helpers.d.ts +1 -0
- package/dist/generate/ide-helpers.js +8 -0
- package/dist/generate/index.d.ts +36 -0
- package/dist/generate/index.js +158 -0
- package/dist/generate/lib-entries.d.ts +1 -0
- package/dist/generate/lib-entries.js +16 -0
- package/dist/generate/pantry-file.d.ts +1 -0
- package/dist/generate/pantry-file.js +46 -0
- package/dist/generate/symlink-core.d.ts +1 -0
- package/dist/generate/symlink-core.js +2 -0
- package/dist/generate/types.d.ts +1 -0
- package/dist/generate/types.js +3 -0
- package/dist/generate/vscode-custom-data.d.ts +1 -0
- package/dist/generate/vscode-custom-data.js +9 -0
- package/dist/generate/web-types.d.ts +1 -0
- package/dist/generate/web-types.js +0 -0
- package/dist/helpers/component-meta.d.ts +26 -0
- package/dist/helpers/component-meta.js +295 -0
- package/dist/helpers/index.d.ts +4 -0
- package/dist/helpers/index.js +1 -0
- package/dist/helpers/lib-entries.d.ts +12 -0
- package/dist/helpers/lib-entries.js +73 -0
- package/dist/helpers/package-json.d.ts +2 -0
- package/dist/helpers/package-json.js +74 -0
- package/dist/helpers/utils.d.ts +23 -0
- package/dist/helpers/utils.js +105 -0
- package/dist/helpers/vscode-custom-data.d.ts +3 -0
- package/dist/helpers/vscode-custom-data.js +30 -0
- package/dist/index.d.ts +62 -0
- package/dist/index.js +50 -0
- package/dist/key-generate.d.ts +1 -0
- package/dist/key-generate.js +24 -0
- package/dist/lint/fix.d.ts +1 -0
- package/dist/lint/fix.js +4 -0
- package/dist/lint/index.d.ts +1 -0
- package/dist/lint/index.js +4 -0
- package/dist/lint/lint.d.ts +14 -0
- package/dist/lint/lint.js +34 -0
- package/dist/make-command.d.ts +10 -0
- package/dist/make-command.js +95 -0
- package/dist/make-job.d.ts +5 -0
- package/dist/make-job.js +154 -0
- package/dist/make-policy.d.ts +10 -0
- package/dist/make-policy.js +142 -0
- package/dist/make-resource.d.ts +10 -0
- package/dist/make-resource.js +142 -0
- package/dist/make.d.ts +52 -0
- package/dist/make.js +328 -0
- package/dist/migrate/database.d.ts +1 -0
- package/dist/migrate/database.js +16 -0
- package/dist/migrate/fresh.d.ts +1 -0
- package/dist/migrate/fresh.js +31 -0
- package/dist/orm/base.d.ts +1 -0
- package/dist/orm/base.js +0 -0
- package/dist/orm/test.d.ts +1 -0
- package/dist/orm/test.js +0 -0
- package/dist/prepublish.d.ts +1 -0
- package/dist/prepublish.js +16 -0
- package/dist/queue/clear.d.ts +1 -0
- package/dist/queue/clear.js +42 -0
- package/dist/queue/dlq-purge.d.ts +1 -0
- package/dist/queue/dlq-purge.js +28 -0
- package/dist/queue/dlq-retry.d.ts +1 -0
- package/dist/queue/dlq-retry.js +35 -0
- package/dist/queue/dlq.d.ts +1 -0
- package/dist/queue/dlq.js +55 -0
- package/dist/queue/failed.d.ts +1 -0
- package/dist/queue/failed.js +69 -0
- package/dist/queue/flush.d.ts +1 -0
- package/dist/queue/flush.js +49 -0
- package/dist/queue/inspect.d.ts +1 -0
- package/dist/queue/inspect.js +154 -0
- package/dist/queue/list.d.ts +1 -0
- package/dist/queue/list.js +69 -0
- package/dist/queue/monitor.d.ts +1 -0
- package/dist/queue/monitor.js +95 -0
- package/dist/queue/pause.d.ts +1 -0
- package/dist/queue/pause.js +28 -0
- package/dist/queue/quarantine.d.ts +1 -0
- package/dist/queue/quarantine.js +42 -0
- package/dist/queue/resume.d.ts +1 -0
- package/dist/queue/resume.js +27 -0
- package/dist/queue/retry.d.ts +1 -0
- package/dist/queue/retry.js +41 -0
- package/dist/queue/schedule-list.d.ts +1 -0
- package/dist/queue/schedule-list.js +33 -0
- package/dist/queue/schedule.d.ts +1 -0
- package/dist/queue/schedule.js +12 -0
- package/dist/queue/status.d.ts +1 -0
- package/dist/queue/status.js +68 -0
- package/dist/queue/table.d.ts +1 -0
- package/dist/queue/table.js +10 -0
- package/dist/queue/unquarantine.d.ts +1 -0
- package/dist/queue/unquarantine.js +27 -0
- package/dist/queue/work.d.ts +1 -0
- package/dist/queue/work.js +57 -0
- package/dist/release.d.ts +1 -0
- package/dist/release.js +21 -0
- package/dist/route/list.d.ts +1 -0
- package/dist/route/list.js +78 -0
- package/dist/run-action.d.ts +2 -0
- package/dist/run-action.js +1 -0
- package/dist/saas/setup.d.ts +1 -0
- package/dist/saas/setup.js +9 -0
- package/dist/scaffold-crud.d.ts +25 -0
- package/dist/scaffold-crud.js +211 -0
- package/dist/schedule/run.d.ts +1 -0
- package/dist/schedule/run.js +7 -0
- package/dist/search/flush.d.ts +1 -0
- package/dist/search/flush.js +10 -0
- package/dist/search/import.d.ts +1 -0
- package/dist/search/import.js +10 -0
- package/dist/search/settings-list.d.ts +1 -0
- package/dist/search/settings-list.js +10 -0
- package/dist/search/settings.d.ts +1 -0
- package/dist/search/settings.js +9 -0
- package/dist/serve/api.d.ts +1 -0
- package/dist/serve/api.js +35 -0
- package/dist/setup/index.d.ts +1 -0
- package/dist/setup/index.js +1 -0
- package/dist/setup/ssl.d.ts +38 -0
- package/dist/setup/ssl.js +271 -0
- package/dist/stacks.d.ts +4 -0
- package/dist/stacks.js +265 -0
- package/dist/templates.d.ts +28 -0
- package/dist/templates.js +301 -0
- package/dist/test/feature.d.ts +1 -0
- package/dist/test/feature.js +11 -0
- package/dist/test/index.d.ts +1 -0
- package/dist/test/index.js +11 -0
- package/dist/test/ui.d.ts +1 -0
- package/dist/test/ui.js +4 -0
- package/dist/test/unit.d.ts +1 -0
- package/dist/test/unit.js +11 -0
- package/dist/typecheck.d.ts +1 -0
- package/dist/typecheck.js +4 -0
- package/dist/types.d.ts +3 -0
- package/dist/types.js +16 -0
- package/dist/upgrade/binary.d.ts +1 -0
- package/dist/upgrade/binary.js +29 -0
- package/dist/upgrade/bun.d.ts +1 -0
- package/dist/upgrade/bun.js +0 -0
- package/dist/upgrade/dependencies.d.ts +1 -0
- package/dist/upgrade/dependencies.js +0 -0
- package/dist/upgrade/framework-utils.d.ts +150 -0
- package/dist/upgrade/framework-utils.js +193 -0
- package/dist/upgrade/framework.d.ts +1 -0
- package/dist/upgrade/framework.js +310 -0
- package/dist/upgrade/index.d.ts +1 -0
- package/dist/upgrade/index.js +17 -0
- package/dist/upgrade/packages.d.ts +14 -0
- package/dist/upgrade/packages.js +99 -0
- package/dist/upgrade/shell.d.ts +1 -0
- package/dist/upgrade/shell.js +41 -0
- package/dist/upgrade.d.ts +7 -0
- package/dist/upgrade.js +38 -0
- package/package.json +16 -16
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { log } from "@stacksjs/logging";
|
|
3
|
+
import { Job, FailedJob } from "@stacksjs/orm";
|
|
4
|
+
const options = parseArgs(), queueName = options.queue;
|
|
5
|
+
try {
|
|
6
|
+
log.info(`Fetching queue status...
|
|
7
|
+
`);
|
|
8
|
+
const allJobs = queueName ? await Job.where("queue", queueName).get() : await Job.all(), failedJobs = queueName ? await FailedJob.where("queue", queueName).get() : await FailedJob.all(), queueStats = new Map;
|
|
9
|
+
for (const job of allJobs) {
|
|
10
|
+
const queue = job.queue || "default";
|
|
11
|
+
if (!queueStats.has(queue))
|
|
12
|
+
queueStats.set(queue, { pending: 0, processing: 0, delayed: 0 });
|
|
13
|
+
const stats = queueStats.get(queue), now = Math.floor(Date.now() / 1000);
|
|
14
|
+
if (job.reserved_at)
|
|
15
|
+
stats.processing++;
|
|
16
|
+
else if (job.available_at && Number(job.available_at) > now)
|
|
17
|
+
stats.delayed++;
|
|
18
|
+
else
|
|
19
|
+
stats.pending++;
|
|
20
|
+
}
|
|
21
|
+
const failedStats = new Map;
|
|
22
|
+
for (const job of failedJobs) {
|
|
23
|
+
const queue = job.queue || "default";
|
|
24
|
+
failedStats.set(queue, (failedStats.get(queue) || 0) + 1);
|
|
25
|
+
}
|
|
26
|
+
console.log("\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510");
|
|
27
|
+
console.log("\u2502 Queue \u2502 Pending \u2502 Processing \u2502 Delayed \u2502 Failed \u2502");
|
|
28
|
+
console.log("\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524");
|
|
29
|
+
const allQueues = new Set([...queueStats.keys(), ...failedStats.keys()]);
|
|
30
|
+
if (allQueues.size === 0)
|
|
31
|
+
console.log("\u2502 No queues found \u2502");
|
|
32
|
+
else
|
|
33
|
+
for (const queue of allQueues) {
|
|
34
|
+
const stats = queueStats.get(queue) || { pending: 0, processing: 0, delayed: 0 }, failed = failedStats.get(queue) || 0, queueDisplay = queue.substring(0, 48).padEnd(48), pendingDisplay = String(stats.pending).padStart(8), processingDisplay = String(stats.processing).padStart(10), delayedDisplay = String(stats.delayed).padStart(8), failedDisplay = String(failed).padStart(6);
|
|
35
|
+
console.log(`\u2502 ${queueDisplay} \u2502${pendingDisplay} \u2502${processingDisplay} \u2502${delayedDisplay} \u2502${failedDisplay} \u2502`);
|
|
36
|
+
}
|
|
37
|
+
console.log("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
|
|
38
|
+
const totalPending = Array.from(queueStats.values()).reduce((sum, s) => sum + s.pending, 0), totalProcessing = Array.from(queueStats.values()).reduce((sum, s) => sum + s.processing, 0), totalDelayed = Array.from(queueStats.values()).reduce((sum, s) => sum + s.delayed, 0), totalFailed = Array.from(failedStats.values()).reduce((sum, n) => sum + n, 0);
|
|
39
|
+
console.log(`
|
|
40
|
+
Summary:`);
|
|
41
|
+
console.log(` Pending: ${totalPending}`);
|
|
42
|
+
console.log(` Processing: ${totalProcessing}`);
|
|
43
|
+
console.log(` Delayed: ${totalDelayed}`);
|
|
44
|
+
console.log(` Failed: ${totalFailed}`);
|
|
45
|
+
console.log(` Total: ${totalPending + totalProcessing + totalDelayed + totalFailed}`);
|
|
46
|
+
process.exit(0);
|
|
47
|
+
} catch (error) {
|
|
48
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
49
|
+
if (/no such table:\s*(?:jobs|failed_jobs)\b/i.test(message)) {
|
|
50
|
+
process.stdout.write(`Queue tables are not set up yet.
|
|
51
|
+
`);
|
|
52
|
+
process.stdout.write("Run `buddy queue:table` to create the migrations, then `buddy migrate` to apply them.\n");
|
|
53
|
+
process.exit(0);
|
|
54
|
+
}
|
|
55
|
+
log.error("Failed to get queue status", error);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
function parseArgs() {
|
|
59
|
+
const args = {};
|
|
60
|
+
process.argv.forEach((arg) => {
|
|
61
|
+
if (arg.startsWith("--")) {
|
|
62
|
+
const [key, value] = arg.slice(2).split("=");
|
|
63
|
+
if (key && value)
|
|
64
|
+
args[key] = value;
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
return args;
|
|
68
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { createJobsMigration } from "@stacksjs/database";
|
|
3
|
+
import { log } from "@stacksjs/logging";
|
|
4
|
+
const result = await createJobsMigration();
|
|
5
|
+
if (result?.isErr) {
|
|
6
|
+
console.error(result.error);
|
|
7
|
+
log.error("generateMigrations failed", result.error);
|
|
8
|
+
process.exit(1);
|
|
9
|
+
}
|
|
10
|
+
process.exit(0);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { log } from "@stacksjs/logging";
|
|
3
|
+
import { unquarantineJob } from "@stacksjs/queue";
|
|
4
|
+
const options = parseArgs(), jobName = options.name;
|
|
5
|
+
if (!jobName) {
|
|
6
|
+
log.error("Usage: buddy queue:unquarantine --name=<JobName>");
|
|
7
|
+
process.exit(1);
|
|
8
|
+
}
|
|
9
|
+
try {
|
|
10
|
+
await unquarantineJob(jobName);
|
|
11
|
+
log.success(`Lifted quarantine for ${jobName}`);
|
|
12
|
+
process.exit(0);
|
|
13
|
+
} catch (error) {
|
|
14
|
+
log.error("Failed to unquarantine", error);
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
function parseArgs() {
|
|
18
|
+
const args = {};
|
|
19
|
+
process.argv.forEach((arg) => {
|
|
20
|
+
if (arg.startsWith("--")) {
|
|
21
|
+
const [key, value] = arg.slice(2).split("=");
|
|
22
|
+
if (key && value)
|
|
23
|
+
args[key] = value;
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
return args;
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { log } from "@stacksjs/logging";
|
|
3
|
+
import { startProcessor, stopProcessor } from "@stacksjs/queue";
|
|
4
|
+
process.on("unhandledRejection", (reason) => {
|
|
5
|
+
log.error(`Unhandled Rejection in queue worker: ${reason}`);
|
|
6
|
+
});
|
|
7
|
+
process.on("uncaughtException", (error) => {
|
|
8
|
+
log.error(`Uncaught Exception in queue worker: ${error.message}`);
|
|
9
|
+
});
|
|
10
|
+
const SHUTDOWN_GRACE_MS = Number(process.env.STACKS_QUEUE_SHUTDOWN_GRACE_MS) || 1e4;
|
|
11
|
+
let shuttingDown = !1;
|
|
12
|
+
async function gracefulShutdown(signal) {
|
|
13
|
+
if (shuttingDown)
|
|
14
|
+
return;
|
|
15
|
+
shuttingDown = !0;
|
|
16
|
+
log.info(`[queue] Worker received ${signal}, draining in-flight jobs (max ${SHUTDOWN_GRACE_MS / 1000}s)\u2026`);
|
|
17
|
+
setTimeout(() => {
|
|
18
|
+
log.warn("[queue] Drain window exceeded \u2014 forcing worker exit.");
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}, SHUTDOWN_GRACE_MS + 2000).unref();
|
|
21
|
+
try {
|
|
22
|
+
await stopProcessor({ graceMs: SHUTDOWN_GRACE_MS });
|
|
23
|
+
} catch (error) {
|
|
24
|
+
log.error("[queue] Error while draining worker on shutdown:", error);
|
|
25
|
+
}
|
|
26
|
+
process.exit(0);
|
|
27
|
+
}
|
|
28
|
+
process.on("SIGTERM", () => {
|
|
29
|
+
gracefulShutdown("SIGTERM");
|
|
30
|
+
});
|
|
31
|
+
process.on("SIGINT", () => {
|
|
32
|
+
gracefulShutdown("SIGINT");
|
|
33
|
+
});
|
|
34
|
+
const options = parseArgs(), queue = options.queue, concurrency = Number(options.concurrency) || 1;
|
|
35
|
+
log.info(`Starting queue worker with ${concurrency} concurrent worker(s)...`);
|
|
36
|
+
const result = await startProcessor(queue, {
|
|
37
|
+
concurrency
|
|
38
|
+
});
|
|
39
|
+
if (result.isErr) {
|
|
40
|
+
log.error("Failed to start queue worker:", result.error);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
log.success("Queue worker started successfully!");
|
|
44
|
+
await new Promise(() => {});
|
|
45
|
+
function parseArgs() {
|
|
46
|
+
const args = {};
|
|
47
|
+
process.argv.forEach((arg) => {
|
|
48
|
+
if (arg.startsWith("--")) {
|
|
49
|
+
const [key, value] = arg.slice(2).split("=");
|
|
50
|
+
if (key && value)
|
|
51
|
+
args[key] = value;
|
|
52
|
+
else if (key)
|
|
53
|
+
args[key] = "true";
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
return args;
|
|
57
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/release.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { parseOptions } from "@stacksjs/cli";
|
|
2
|
+
import { app } from "@stacksjs/config";
|
|
3
|
+
import { Action } from "@stacksjs/enums";
|
|
4
|
+
import { log } from "@stacksjs/logging";
|
|
5
|
+
import { projectPath } from "@stacksjs/path";
|
|
6
|
+
import { runActions } from ".";
|
|
7
|
+
const raw = parseOptions() ?? {}, passthrough = {};
|
|
8
|
+
for (const [k, v] of Object.entries(raw)) {
|
|
9
|
+
if (k === "--" || k === "_")
|
|
10
|
+
continue;
|
|
11
|
+
passthrough[k] = v;
|
|
12
|
+
}
|
|
13
|
+
const isDryRun = passthrough.dryRun === !0 || passthrough.dryRun === "true", actions = isDryRun ? [Action.GenerateLibraryEntries, Action.Bump] : [Action.GenerateLibraryEntries, Action.LintFix, Action.Bump], result = await runActions(actions, {
|
|
14
|
+
cwd: projectPath(),
|
|
15
|
+
...passthrough
|
|
16
|
+
});
|
|
17
|
+
if (result && result.isErr) {
|
|
18
|
+
log.error(`Release failed: ${result.error?.message ?? String(result.error)}`);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
log.success(`Successfully released ${app.name}`);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { italic, log } from "@stacksjs/cli";
|
|
3
|
+
import { route } from "@stacksjs/router";
|
|
4
|
+
const METHOD_ORDER = ["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"];
|
|
5
|
+
function formatHandler(handler) {
|
|
6
|
+
if (typeof handler === "string")
|
|
7
|
+
return handler;
|
|
8
|
+
if (typeof handler === "function")
|
|
9
|
+
return handler.name ? `[fn ${handler.name}]` : "[fn]";
|
|
10
|
+
return "[handler]";
|
|
11
|
+
}
|
|
12
|
+
function pad(value, width) {
|
|
13
|
+
if (value.length >= width)
|
|
14
|
+
return value;
|
|
15
|
+
return value + " ".repeat(width - value.length);
|
|
16
|
+
}
|
|
17
|
+
function write(line) {
|
|
18
|
+
process.stdout.write(`${line}
|
|
19
|
+
`);
|
|
20
|
+
}
|
|
21
|
+
async function listRoutes() {
|
|
22
|
+
try {
|
|
23
|
+
await route.importRoutes();
|
|
24
|
+
} catch (error) {
|
|
25
|
+
return { isErr: !0, error };
|
|
26
|
+
}
|
|
27
|
+
const registered = route.routes ?? [];
|
|
28
|
+
if (registered.length === 0) {
|
|
29
|
+
write(italic("No routes registered."));
|
|
30
|
+
return {};
|
|
31
|
+
}
|
|
32
|
+
const rows = registered.map((r) => ({
|
|
33
|
+
method: String(r.method || "GET").toUpperCase(),
|
|
34
|
+
uri: String(r.path || r.uri || ""),
|
|
35
|
+
handler: formatHandler(r.handler ?? r.action ?? ""),
|
|
36
|
+
name: String(r.name || ""),
|
|
37
|
+
middleware: Array.isArray(r.middleware) ? r.middleware.join(",") : String(r.middleware || "")
|
|
38
|
+
}));
|
|
39
|
+
rows.sort((a, b) => {
|
|
40
|
+
const ai = METHOD_ORDER.indexOf(a.method), bi = METHOD_ORDER.indexOf(b.method);
|
|
41
|
+
if (ai !== bi)
|
|
42
|
+
return (ai === -1 ? 99 : ai) - (bi === -1 ? 99 : bi);
|
|
43
|
+
return a.uri.localeCompare(b.uri);
|
|
44
|
+
});
|
|
45
|
+
const widths = {
|
|
46
|
+
method: Math.max(6, ...rows.map((r) => r.method.length)),
|
|
47
|
+
uri: Math.max(3, ...rows.map((r) => r.uri.length)),
|
|
48
|
+
handler: Math.max(7, ...rows.map((r) => r.handler.length)),
|
|
49
|
+
name: Math.max(4, ...rows.map((r) => r.name.length))
|
|
50
|
+
}, header = [
|
|
51
|
+
pad("METHOD", widths.method),
|
|
52
|
+
pad("URI", widths.uri),
|
|
53
|
+
pad("HANDLER", widths.handler),
|
|
54
|
+
pad("NAME", widths.name),
|
|
55
|
+
"MIDDLEWARE"
|
|
56
|
+
].join(" ");
|
|
57
|
+
write("");
|
|
58
|
+
write(header);
|
|
59
|
+
write("-".repeat(header.length));
|
|
60
|
+
for (const r of rows)
|
|
61
|
+
write([
|
|
62
|
+
pad(r.method, widths.method),
|
|
63
|
+
pad(r.uri, widths.uri),
|
|
64
|
+
pad(r.handler, widths.handler),
|
|
65
|
+
pad(r.name || "-", widths.name),
|
|
66
|
+
r.middleware || "-"
|
|
67
|
+
].join(" "));
|
|
68
|
+
write("");
|
|
69
|
+
write(italic(`${rows.length} route${rows.length === 1 ? "" : "s"} registered.`));
|
|
70
|
+
return {};
|
|
71
|
+
}
|
|
72
|
+
const result = await listRoutes();
|
|
73
|
+
if (result?.isErr) {
|
|
74
|
+
console.error(result.error);
|
|
75
|
+
log.error("Route lists failed", result.error);
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
process.exit(0);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { runAction } from "./helpers/utils";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { log } from "@stacksjs/logging";
|
|
3
|
+
import { createStripeProduct } from "@stacksjs/payments";
|
|
4
|
+
const result = await createStripeProduct();
|
|
5
|
+
if (result?.isErr) {
|
|
6
|
+
console.error(result.error);
|
|
7
|
+
log.error("generateMigrations failed", result.error);
|
|
8
|
+
process.exit(1);
|
|
9
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { MakeOptions } from '@stacksjs/types';
|
|
2
|
+
export declare function parseFields(input: string | undefined): CrudField[];
|
|
3
|
+
/**
|
|
4
|
+
* Generate a complete CRUD stack for a resource:
|
|
5
|
+
* - app/Models/<Model>.ts (defineModel definition)
|
|
6
|
+
* - database/migrations/<ts>-create-<table>-table.ts
|
|
7
|
+
* - app/Actions/<Model>{Index,Show,Store,Update,Destroy}Action.ts
|
|
8
|
+
*
|
|
9
|
+
* Honors `--dry-run` via the shared `isDryRunActive()` flag, so users
|
|
10
|
+
* can preview every file before committing to disk.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* buddy scaffold:crud Post --fields=title:string,body:text,published:boolean
|
|
14
|
+
*/
|
|
15
|
+
export declare function scaffoldCrud(name: string, options: MakeOptions & { fields?: string }): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Field declaration for CRUD scaffolding. Examples:
|
|
18
|
+
*
|
|
19
|
+
* --fields=title,body
|
|
20
|
+
* --fields=title:string,body:text,published:boolean,views:number
|
|
21
|
+
*/
|
|
22
|
+
export declare interface CrudField {
|
|
23
|
+
name: string
|
|
24
|
+
type: 'string' | 'text' | 'number' | 'boolean' | 'date' | 'json'
|
|
25
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { italic } from "@stacksjs/cli";
|
|
2
|
+
import { log } from "@stacksjs/logging";
|
|
3
|
+
import { path as p } from "@stacksjs/path";
|
|
4
|
+
import { writeTextFile } from "@stacksjs/storage";
|
|
5
|
+
import { isDryRunActive } from "./make";
|
|
6
|
+
const TYPE_ALIASES = {
|
|
7
|
+
str: "string",
|
|
8
|
+
string: "string",
|
|
9
|
+
varchar: "string",
|
|
10
|
+
text: "text",
|
|
11
|
+
longtext: "text",
|
|
12
|
+
int: "number",
|
|
13
|
+
integer: "number",
|
|
14
|
+
number: "number",
|
|
15
|
+
num: "number",
|
|
16
|
+
bool: "boolean",
|
|
17
|
+
boolean: "boolean",
|
|
18
|
+
date: "date",
|
|
19
|
+
datetime: "date",
|
|
20
|
+
json: "json"
|
|
21
|
+
};
|
|
22
|
+
export function parseFields(input) {
|
|
23
|
+
if (!input)
|
|
24
|
+
return [];
|
|
25
|
+
const parts = input.split(",").map((p) => p.trim()).filter(Boolean), out = [];
|
|
26
|
+
for (const part of parts) {
|
|
27
|
+
const [rawName, rawType = "string"] = part.split(":"), name = rawName?.trim();
|
|
28
|
+
if (!name)
|
|
29
|
+
continue;
|
|
30
|
+
const type = TYPE_ALIASES[rawType.trim().toLowerCase()] ?? "string";
|
|
31
|
+
out.push({ name, type });
|
|
32
|
+
}
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
35
|
+
function pluralize(word) {
|
|
36
|
+
if (!word)
|
|
37
|
+
return word;
|
|
38
|
+
const lower = word.toLowerCase();
|
|
39
|
+
if (lower.endsWith("s") || lower.endsWith("x") || lower.endsWith("z") || lower.endsWith("ch") || lower.endsWith("sh"))
|
|
40
|
+
return `${word}es`;
|
|
41
|
+
if (lower.endsWith("y") && !/[aeiou]y$/.test(lower))
|
|
42
|
+
return `${word.slice(0, -1)}ies`;
|
|
43
|
+
return `${word}s`;
|
|
44
|
+
}
|
|
45
|
+
function pascalCase(name) {
|
|
46
|
+
return name.replace(/(^|[-_\s])(\w)/g, (_, __, c) => String(c).toUpperCase());
|
|
47
|
+
}
|
|
48
|
+
function snakeCase(name) {
|
|
49
|
+
return name.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[-\s]+/g, "_").toLowerCase();
|
|
50
|
+
}
|
|
51
|
+
function attributeBlock(fields) {
|
|
52
|
+
if (fields.length === 0)
|
|
53
|
+
return " title: { type: 'string', fillable: true, validation: { rule: schema.string().required() } },";
|
|
54
|
+
return fields.map((f) => {
|
|
55
|
+
const t = f.type, rule = t === "number" ? "schema.number()" : t === "boolean" ? "schema.boolean()" : t === "date" ? "schema.date()" : t === "json" ? "schema.object({})" : "schema.string()", dbType = t === "number" ? "number" : t === "boolean" ? "boolean" : t === "date" ? "date" : t === "json" ? "json" : "string";
|
|
56
|
+
return ` ${f.name}: { type: '${dbType}', fillable: true, validation: { rule: ${rule} } },`;
|
|
57
|
+
}).join(`
|
|
58
|
+
`);
|
|
59
|
+
}
|
|
60
|
+
function migrationColumns(fields) {
|
|
61
|
+
if (fields.length === 0)
|
|
62
|
+
return " .addColumn('title', 'varchar(255)', col => col.notNull())";
|
|
63
|
+
return fields.map((f) => {
|
|
64
|
+
switch (f.type) {
|
|
65
|
+
case "number":
|
|
66
|
+
return ` .addColumn('${f.name}', 'integer')`;
|
|
67
|
+
case "boolean":
|
|
68
|
+
return ` .addColumn('${f.name}', 'boolean', col => col.defaultTo(false))`;
|
|
69
|
+
case "text":
|
|
70
|
+
return ` .addColumn('${f.name}', 'text')`;
|
|
71
|
+
case "date":
|
|
72
|
+
return ` .addColumn('${f.name}', 'timestamp')`;
|
|
73
|
+
case "json":
|
|
74
|
+
return ` .addColumn('${f.name}', 'text')`;
|
|
75
|
+
default:
|
|
76
|
+
return ` .addColumn('${f.name}', 'varchar(255)')`;
|
|
77
|
+
}
|
|
78
|
+
}).join(`
|
|
79
|
+
`);
|
|
80
|
+
}
|
|
81
|
+
function actionStub(name, kind, fields) {
|
|
82
|
+
const Model = pascalCase(name);
|
|
83
|
+
switch (kind) {
|
|
84
|
+
case "Index":
|
|
85
|
+
return `import { Action } from '@stacksjs/actions'
|
|
86
|
+
import ${Model} from '~/app/Models/${Model}'
|
|
87
|
+
|
|
88
|
+
export default new Action({
|
|
89
|
+
name: '${Model}IndexAction',
|
|
90
|
+
description: 'List ${pluralize(Model)}',
|
|
91
|
+
|
|
92
|
+
async handle() {
|
|
93
|
+
return await ${Model}.all()
|
|
94
|
+
},
|
|
95
|
+
})`;
|
|
96
|
+
case "Show":
|
|
97
|
+
return `import { Action } from '@stacksjs/actions'
|
|
98
|
+
import ${Model} from '~/app/Models/${Model}'
|
|
99
|
+
|
|
100
|
+
export default new Action({
|
|
101
|
+
name: '${Model}ShowAction',
|
|
102
|
+
description: 'Show a single ${Model}',
|
|
103
|
+
|
|
104
|
+
async handle(request) {
|
|
105
|
+
const id = Number(request.get('id'))
|
|
106
|
+
return await ${Model}.findOrFail(id)
|
|
107
|
+
},
|
|
108
|
+
})`;
|
|
109
|
+
case "Store": {
|
|
110
|
+
const keys = (fields.length > 0 ? fields : [{ name: "title", type: "string" }]).map((f) => `'${f.name}'`).join(", ");
|
|
111
|
+
return `import { Action } from '@stacksjs/actions'
|
|
112
|
+
import ${Model} from '~/app/Models/${Model}'
|
|
113
|
+
|
|
114
|
+
export default new Action({
|
|
115
|
+
name: '${Model}StoreAction',
|
|
116
|
+
description: 'Create a new ${Model}',
|
|
117
|
+
|
|
118
|
+
async handle(request) {
|
|
119
|
+
const data = request.only([${keys}])
|
|
120
|
+
return await ${Model}.create(data)
|
|
121
|
+
},
|
|
122
|
+
})`;
|
|
123
|
+
}
|
|
124
|
+
case "Update": {
|
|
125
|
+
const keys = (fields.length > 0 ? fields : [{ name: "title", type: "string" }]).map((f) => `'${f.name}'`).join(", ");
|
|
126
|
+
return `import { Action } from '@stacksjs/actions'
|
|
127
|
+
import ${Model} from '~/app/Models/${Model}'
|
|
128
|
+
|
|
129
|
+
export default new Action({
|
|
130
|
+
name: '${Model}UpdateAction',
|
|
131
|
+
description: 'Update an existing ${Model}',
|
|
132
|
+
|
|
133
|
+
async handle(request) {
|
|
134
|
+
const id = Number(request.get('id'))
|
|
135
|
+
const data = request.only([${keys}])
|
|
136
|
+
return await ${Model}.update(id, data)
|
|
137
|
+
},
|
|
138
|
+
})`;
|
|
139
|
+
}
|
|
140
|
+
case "Destroy":
|
|
141
|
+
return `import { Action } from '@stacksjs/actions'
|
|
142
|
+
import ${Model} from '~/app/Models/${Model}'
|
|
143
|
+
|
|
144
|
+
export default new Action({
|
|
145
|
+
name: '${Model}DestroyAction',
|
|
146
|
+
description: 'Delete a ${Model}',
|
|
147
|
+
|
|
148
|
+
async handle(request) {
|
|
149
|
+
const id = Number(request.get('id'))
|
|
150
|
+
const deleted = await ${Model}.delete(id)
|
|
151
|
+
return { deleted }
|
|
152
|
+
},
|
|
153
|
+
})`;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function modelStub(name, fields) {
|
|
157
|
+
return `import { defineModel } from '@stacksjs/orm'
|
|
158
|
+
import { schema } from '@stacksjs/validation'
|
|
159
|
+
|
|
160
|
+
export default defineModel({
|
|
161
|
+
name: '${pascalCase(name)}',
|
|
162
|
+
table: '${pluralize(snakeCase(name))}',
|
|
163
|
+
attributes: {
|
|
164
|
+
${attributeBlock(fields)}
|
|
165
|
+
},
|
|
166
|
+
traits: { useTimestamps: true, useUuid: false },
|
|
167
|
+
} as const)
|
|
168
|
+
`;
|
|
169
|
+
}
|
|
170
|
+
function migrationStub(name, fields) {
|
|
171
|
+
return `import type { Database } from '@stacksjs/database'
|
|
172
|
+
import { sql } from '@stacksjs/database'
|
|
173
|
+
|
|
174
|
+
export async function up(db: Database<any>) {
|
|
175
|
+
await db.schema
|
|
176
|
+
.createTable('${pluralize(snakeCase(name))}')
|
|
177
|
+
.addColumn('id', 'serial', col => col.primaryKey())
|
|
178
|
+
${migrationColumns(fields)}
|
|
179
|
+
.addColumn('created_at', 'timestamp', col => col.notNull().defaultTo(sql.raw('CURRENT_TIMESTAMP')))
|
|
180
|
+
.addColumn('updated_at', 'timestamp')
|
|
181
|
+
.execute()
|
|
182
|
+
}
|
|
183
|
+
`;
|
|
184
|
+
}
|
|
185
|
+
async function writeFile(path, contents) {
|
|
186
|
+
if (isDryRunActive()) {
|
|
187
|
+
const lines = contents.split(`
|
|
188
|
+
`);
|
|
189
|
+
log.info(`[dry-run] would write ${path} (${lines.length} lines)`);
|
|
190
|
+
process.stdout.write(`${lines.slice(0, 60).map((l) => ` ${l}`).join(`
|
|
191
|
+
`)}
|
|
192
|
+
|
|
193
|
+
`);
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
await writeTextFile({ path, data: contents });
|
|
197
|
+
}
|
|
198
|
+
export async function scaffoldCrud(name, options) {
|
|
199
|
+
const Model = pascalCase(name);
|
|
200
|
+
if (!Model)
|
|
201
|
+
throw Error("scaffold:crud requires a non-empty resource name");
|
|
202
|
+
const fields = parseFields(options.fields);
|
|
203
|
+
log.info(`Scaffolding CRUD for ${italic(Model)} (${fields.length || "no"} fields)`);
|
|
204
|
+
await writeFile(p.userModelsPath(`${Model}.ts`), modelStub(Model, fields));
|
|
205
|
+
const migrationName = `${Date.now().toString()}-create-${pluralize(snakeCase(name))}-table.ts`;
|
|
206
|
+
await writeFile(p.userMigrationsPath(migrationName), migrationStub(name, fields));
|
|
207
|
+
for (const kind of ["Index", "Show", "Store", "Update", "Destroy"])
|
|
208
|
+
await writeFile(p.userActionsPath(`${Model}${kind}Action.ts`), actionStub(name, kind, fields));
|
|
209
|
+
log.success(`CRUD scaffold complete: model + migration + 5 actions for ${Model}`);
|
|
210
|
+
log.info(`Next: register \`route.resource('${pluralize(snakeCase(name))}', '${Model}')\` in routes/api.ts`);
|
|
211
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { parseOptions } from "@stacksjs/cli";
|
|
3
|
+
import { log } from "@stacksjs/logging";
|
|
4
|
+
import { flushModelDocuments } from "@stacksjs/search-engine";
|
|
5
|
+
const options = parseOptions(), modelOption = options.model, result = await flushModelDocuments(modelOption);
|
|
6
|
+
if (result?.isErr) {
|
|
7
|
+
console.error(result.error);
|
|
8
|
+
log.error("Flushing search engine failed", result.error);
|
|
9
|
+
}
|
|
10
|
+
process.exit(0);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { parseOptions } from "@stacksjs/cli";
|
|
3
|
+
import { log } from "@stacksjs/logging";
|
|
4
|
+
import { importModelDocuments } from "@stacksjs/search-engine";
|
|
5
|
+
const options = parseOptions(), modelOption = options.model, result = await importModelDocuments(modelOption);
|
|
6
|
+
if (result?.isErr) {
|
|
7
|
+
console.error(result.error);
|
|
8
|
+
log.error("Import to search engine failed", result.error);
|
|
9
|
+
}
|
|
10
|
+
process.exit(0);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { parseOptions } from "@stacksjs/cli";
|
|
3
|
+
import { log } from "@stacksjs/logging";
|
|
4
|
+
import { listIndexSettings } from "@stacksjs/search-engine";
|
|
5
|
+
const options = parseOptions(), modelOption = options.model, result = await listIndexSettings(modelOption);
|
|
6
|
+
if (result?.isErr) {
|
|
7
|
+
console.error(result.error);
|
|
8
|
+
log.error("Listing index settings failed", result.error);
|
|
9
|
+
}
|
|
10
|
+
process.exit(0);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
import { log } from "@stacksjs/logging";
|
|
3
|
+
import { updateIndexSettings } from "@stacksjs/search-engine";
|
|
4
|
+
const result = await updateIndexSettings();
|
|
5
|
+
if (result?.isErr) {
|
|
6
|
+
console.error(result.error);
|
|
7
|
+
log.error("generateMigrations failed", result.error);
|
|
8
|
+
}
|
|
9
|
+
process.exit(0);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import { config } from "@stacksjs/config";
|
|
5
|
+
import { log } from "@stacksjs/logging";
|
|
6
|
+
import { frameworkPath } from "@stacksjs/path";
|
|
7
|
+
import { route } from "@stacksjs/router";
|
|
8
|
+
function resolveDefaultsFile(rel) {
|
|
9
|
+
const vendored = frameworkPath(`defaults/${rel}`);
|
|
10
|
+
if (existsSync(vendored))
|
|
11
|
+
return vendored;
|
|
12
|
+
try {
|
|
13
|
+
const pkgJson = Bun.resolveSync("@stacksjs/defaults/package.json", process.cwd());
|
|
14
|
+
return join(dirname(pkgJson), rel);
|
|
15
|
+
} catch {
|
|
16
|
+
return vendored;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const isProduction = process.env.APP_ENV === "production" || process.env.NODE_ENV === "production", port = Number(process.env.PORT) || config.ports?.api || 3008, hostname = process.env.HOST || (isProduction ? "0.0.0.0" : "127.0.0.1");
|
|
20
|
+
log.info("[Stacks API] Starting server...");
|
|
21
|
+
log.info(`[Stacks API] Environment: ${process.env.APP_ENV || "development"}`);
|
|
22
|
+
const corsMod = await import(resolveDefaultsFile("app/Middleware/Cors.ts")), corsMiddleware = corsMod.default;
|
|
23
|
+
route.use(corsMiddleware.toRouterHandler());
|
|
24
|
+
await route.importRoutes();
|
|
25
|
+
const isDeployed = ["production", "staging", "development"].includes((process.env.APP_ENV || "").toLowerCase()), server = await route.serve({
|
|
26
|
+
port,
|
|
27
|
+
hostname,
|
|
28
|
+
reusePort: isDeployed
|
|
29
|
+
});
|
|
30
|
+
process.on("SIGTERM", () => {
|
|
31
|
+
const graceMs = Number(process.env.SHUTDOWN_GRACE_MS) || 15000;
|
|
32
|
+
setTimeout(() => process.exit(0), graceMs).unref();
|
|
33
|
+
Promise.resolve(server?.stop()).then(() => process.exit(0));
|
|
34
|
+
});
|
|
35
|
+
log.info(`[Stacks API] Server running at http://${hostname}:${port}`);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ssl';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./ssl";
|