@coffer-org/cli 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/coffer.mjs ADDED
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * coffer — портативний рантайм Coffer. Запускається з теки ІНСТАНСУ (де data/).
4
+ * Резолвить @coffer-org/server + @coffer-org/web через require.resolve, тож один
5
+ * бінарник обслуговує будь-який інстанс (monorepo або `npm install @coffer-org/meta`).
6
+ *
7
+ * coffer start — ПРОДАКШН: один процес. Сервер віддає API + prebuilt web
8
+ * (+ /vendor) на одному порту (PORT, типово 7023). Web НЕ білдиться.
9
+ *
10
+ * Розробка (monorepo): `npm run dev` (Vite dev + tsx watch), не через цей CLI.
11
+ */
12
+ import { spawn } from 'node:child_process';
13
+ import { existsSync } from 'node:fs';
14
+ import { join } from 'node:path';
15
+ import { resolveRuntime } from './runtime.mjs';
16
+
17
+ const cmd = process.argv[2];
18
+
19
+ function usage(code = 0) {
20
+ console.log(
21
+ 'coffer — особиста дата-платформа\n\n' +
22
+ 'Використання:\n' +
23
+ ' coffer start продакшн: один процес (API + prebuilt web), порт PORT (типово 7023)\n',
24
+ );
25
+ process.exit(code);
26
+ }
27
+
28
+ if (cmd !== 'start') {
29
+ usage(cmd ? 1 : 0);
30
+ }
31
+
32
+ const { serverEntry, runner, webDist } = resolveRuntime(import.meta.url);
33
+ if (!existsSync(join(webDist, 'index.html'))) {
34
+ console.error(
35
+ `[coffer] не знайдено зібраний web: ${join(webDist, 'index.html')}\n` +
36
+ '[coffer] @coffer-org/web має бути встановлений з prebuilt dist (npm install @coffer-org/meta).',
37
+ );
38
+ process.exit(1);
39
+ }
40
+
41
+ const port = process.env.PORT ?? '7023';
42
+ console.log(`[coffer] start: API + web на http://localhost:${port}`);
43
+
44
+ const child = spawn(runner, [serverEntry], {
45
+ stdio: 'inherit',
46
+ env: { ...process.env, WEB_DIST: webDist },
47
+ });
48
+ child.on('error', (e) => {
49
+ console.error(`[coffer] не вдалося запустити ${runner}: ${e.message}`);
50
+ process.exit(1);
51
+ });
52
+
53
+ function shutdown(code = 0) {
54
+ child.kill('SIGTERM');
55
+ process.exit(code);
56
+ }
57
+ child.on('exit', (c) => process.exit(c ?? 0));
58
+ process.on('SIGINT', () => shutdown(0));
59
+ process.on('SIGTERM', () => shutdown(0));
@@ -0,0 +1,6 @@
1
+ export function pickRunner(serverEntry: string): 'tsx' | 'node';
2
+ export function resolveRuntime(fromUrl: string): {
3
+ serverEntry: string;
4
+ runner: 'tsx' | 'node';
5
+ webDist: string;
6
+ };
@@ -0,0 +1,21 @@
1
+ import { createRequire } from 'node:module';
2
+ import { dirname, join } from 'node:path';
3
+
4
+ /** Choose how to run a resolved server entry: tsx for TS source (monorepo),
5
+ * node for a compiled .js (published install). Input is always
6
+ * @coffer-org/server's resolved entry (index.ts | index.js), so the regex covers
7
+ * .ts/.mts/.cts to harden against a future exports change. */
8
+ export function pickRunner(serverEntry) {
9
+ return /\.[cm]?ts$/.test(serverEntry) ? 'tsx' : 'node';
10
+ }
11
+
12
+ /** Resolve the runtime layout from the CLI's location: the @coffer-org/server
13
+ * entry to spawn and the @coffer-org/web dist dir to serve. Works in both the
14
+ * monorepo (exports→src .ts) and a published install (distExports→dist .js). */
15
+ export function resolveRuntime(fromUrl) {
16
+ const require = createRequire(fromUrl);
17
+ const serverEntry = require.resolve('@coffer-org/server');
18
+ const webPkg = require.resolve('@coffer-org/web/package.json');
19
+ const webDist = join(dirname(webPkg), 'dist');
20
+ return { serverEntry, runner: pickRunner(serverEntry), webDist };
21
+ }
@@ -0,0 +1,11 @@
1
+ import { test } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { pickRunner } from './runtime.mjs';
4
+
5
+ test('pickRunner uses tsx for a .ts entry (monorepo/source)', () => {
6
+ assert.equal(pickRunner('/repo/packages/server/src/index.ts'), 'tsx');
7
+ });
8
+
9
+ test('pickRunner uses node for a .js entry (published dist)', () => {
10
+ assert.equal(pickRunner('/app/node_modules/@coffer-org/server/dist/index.js'), 'node');
11
+ });
package/package.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "@coffer-org/cli",
3
+ "version": "1.1.0",
4
+ "type": "module",
5
+ "files": [
6
+ "bin"
7
+ ],
8
+ "bin": {
9
+ "coffer": "./bin/coffer.mjs"
10
+ },
11
+ "dependencies": {
12
+ "@coffer-org/server": "1.1.0",
13
+ "@coffer-org/web": "1.1.0"
14
+ }
15
+ }