@tulipes/core 0.1.4 → 0.1.6
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 +14 -13
- package/dist/boot/boot.d.ts +3 -3
- package/dist/boot/boot.js +12 -9
- package/dist/boot/boot.js.map +1 -1
- package/dist/boot/contracts.d.ts +2 -2
- package/dist/cli/init.d.ts +8 -15
- package/dist/cli/init.js +156 -195
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/main.js +17 -10
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/package-info.d.ts +8 -0
- package/dist/cli/package-info.js +17 -0
- package/dist/cli/package-info.js.map +1 -0
- package/dist/cli/update.d.ts +10 -0
- package/dist/cli/update.js +143 -0
- package/dist/cli/update.js.map +1 -0
- package/dist/queues/queue-manager.d.ts +1 -1
- package/dist/queues/queue-manager.js +1 -1
- package/dist/sockets/load-sockets.d.ts +2 -2
- package/dist/sockets/load-sockets.js +1 -1
- package/dist/sockets/socket-manager.d.ts +1 -1
- package/dist/sockets/socket-manager.js +1 -1
- package/package.json +1 -1
- package/templates/CLAUDE.md +2 -1
- package/templates/claude/skills/tulipes-queue/SKILL.md +2 -2
- package/templates/claude/skills/tulipes-socket/SKILL.md +4 -4
package/README.md
CHANGED
|
@@ -8,11 +8,11 @@ Tulipes exists so you never rewrite Express boilerplate again. You write **modul
|
|
|
8
8
|
// app.ts — the whole entrypoint
|
|
9
9
|
import { boot } from "@tulipes/core/boot";
|
|
10
10
|
|
|
11
|
-
await boot({ rootDir: import.meta.dirname, mode: "
|
|
11
|
+
await boot({ rootDir: import.meta.dirname, mode: "backend" });
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
```
|
|
15
|
-
▲ my-api development ·
|
|
15
|
+
▲ my-api development · backend mode
|
|
16
16
|
|
|
17
17
|
➜ Server http://localhost:4000 ● listening
|
|
18
18
|
➜ Database mongodb://127.0.0.1:27017/my-api ● connected
|
|
@@ -29,7 +29,7 @@ await boot({ rootDir: import.meta.dirname, mode: "web" });
|
|
|
29
29
|
|
|
30
30
|
- **Modules, not layers.** A feature lives in one folder: its routes, models, config, permissions, background jobs, and env contract. Delete the folder, the feature is gone.
|
|
31
31
|
- **Fail-closed everywhere.** Missing env vars, dependency cycles, duplicate ACL grants, colliding queue names — all crash the boot with a full report. Reading an undeclared variable or model throws at the call site. Unknown roles deny. Unrouted requests 404. Unexpected errors never leak internals outside development.
|
|
32
|
-
- **One process, two modes.** The same codebase boots as a `
|
|
32
|
+
- **One process, two modes.** The same codebase boots as a `backend` server or a queue-consuming `worker` — same modules, same config, forked at the last pipeline phase.
|
|
33
33
|
- **Types generated, not hand-written.** `tulipes sync` reads your modules and emits a `config.d.ts` that types every env variable and every config namespace — enum variables become literal unions, config shapes are inferred from your factories' return types.
|
|
34
34
|
- **The framework stays out of your request path.** Core mounts *no* middleware. Your sys-tier modules own the pipeline head; core only guarantees the tail (404 + terminal error handler).
|
|
35
35
|
|
|
@@ -49,7 +49,7 @@ yarn add @tulipes/core
|
|
|
49
49
|
|
|
50
50
|
```
|
|
51
51
|
my-api/
|
|
52
|
-
├── app.ts # boot({ mode: "
|
|
52
|
+
├── app.ts # boot({ mode: "backend" })
|
|
53
53
|
├── worker.ts # boot({ mode: "worker" })
|
|
54
54
|
├── config/
|
|
55
55
|
│ └── app.config.ts # optional: seeds global config before any module
|
|
@@ -148,7 +148,7 @@ ctx.Environment.get("TYPO_NAME"); // throws: never declared by any modul
|
|
|
148
148
|
6. Database connect Mongoose → model store → bootstrap tasks
|
|
149
149
|
7. Queues every *.queues.ts registers in BOTH modes
|
|
150
150
|
8. ── mode fork ──
|
|
151
|
-
|
|
151
|
+
backend module routers (load order) → 404 → error handler → listen
|
|
152
152
|
worker start a BullMQ worker per registered processor
|
|
153
153
|
9. onReady hooks in load order → startup banner
|
|
154
154
|
shutdown SIGTERM/SIGINT → onShutdown hooks in REVERSE order →
|
|
@@ -168,8 +168,8 @@ interface Ctx {
|
|
|
168
168
|
acl?: Acl; // after phase 5
|
|
169
169
|
models?: ModelStore; // after phase 6
|
|
170
170
|
queues?: QueueManager; // after phase 7
|
|
171
|
-
sockets?: SocketManager; //
|
|
172
|
-
app?: Express; //
|
|
171
|
+
sockets?: SocketManager; // backend only
|
|
172
|
+
app?: Express; // backend only
|
|
173
173
|
}
|
|
174
174
|
```
|
|
175
175
|
|
|
@@ -247,19 +247,20 @@ router.get("/users/:id", async (req) => {
|
|
|
247
247
|
## The CLI
|
|
248
248
|
|
|
249
249
|
```
|
|
250
|
-
tulipes init [dir] scaffold a new application
|
|
251
|
-
tulipes init [dir] --full ...plus models, bootstrap tasks and queues (needs mongo + redis)
|
|
250
|
+
tulipes init [dir] scaffold a new application (needs mongo + redis)
|
|
252
251
|
tulipes sync regenerate types/config.d.ts and .env.example
|
|
253
252
|
tulipes env:check validate env against every meta contract — CI gate, exit 1 on failure
|
|
254
253
|
tulipes new module <name> scaffold a module (scope auto-detected from siblings)
|
|
254
|
+
tulipes update upgrade @tulipes/core to the latest release, everywhere
|
|
255
|
+
tulipes -v print the installed core version
|
|
255
256
|
tulipes dev [entry] sync, then run the entry under tsx watch
|
|
256
257
|
```
|
|
257
258
|
|
|
258
259
|
The scaffolded `modules/hello` is a worked example of every module
|
|
259
260
|
contract — config factory with lifecycle hooks, ACL grants, routes with
|
|
260
|
-
`HttpError` and permission checks, a controller, a pure helper,
|
|
261
|
-
|
|
262
|
-
|
|
261
|
+
`HttpError` and permission checks, a controller, a pure helper, a model,
|
|
262
|
+
an idempotent bootstrap task, a queue with its processor, and a socket
|
|
263
|
+
namespace. The generated app expects mongo and redis to be running.
|
|
263
264
|
|
|
264
265
|
### Built for AI-assisted work
|
|
265
266
|
|
|
@@ -297,4 +298,4 @@ Express 5 · Mongoose 8 · BullMQ 5 · ioredis 5 · Socket.IO 4 · Zod. Delibera
|
|
|
297
298
|
|
|
298
299
|
## Well-known variables
|
|
299
300
|
|
|
300
|
-
Core reads three variable names when present (declare them in your sys core module): `PORT` (
|
|
301
|
+
Core reads three variable names when present (declare them in your sys core module): `PORT` (backend listen port, default 3000), `MONGO_URI` (required if any module ships models), `REDIS_URL` (required if any module ships queues). No models and no `MONGO_URI` is a valid database-less app; models without `MONGO_URI` is a boot refusal.
|
package/dist/boot/boot.d.ts
CHANGED
|
@@ -3,12 +3,12 @@ import type { Connection } from "mongoose";
|
|
|
3
3
|
import { type Express } from "express";
|
|
4
4
|
import { Environment, type AppEnv } from "../env/environment.js";
|
|
5
5
|
import type { Ctx } from "./contracts.js";
|
|
6
|
-
export declare const processModes: readonly ["
|
|
6
|
+
export declare const processModes: readonly ["backend", "worker"];
|
|
7
7
|
export type ProcessMode = (typeof processModes)[number];
|
|
8
8
|
export interface BootOptions {
|
|
9
9
|
/** App root — the directory containing `modules/` and `.envs/`. */
|
|
10
10
|
rootDir: string;
|
|
11
|
-
/** Defaults to process.env.PROCESS_MODE, then "
|
|
11
|
+
/** Defaults to process.env.PROCESS_MODE, then "backend". */
|
|
12
12
|
mode?: ProcessMode;
|
|
13
13
|
appEnv?: AppEnv;
|
|
14
14
|
/** Skip SIGTERM/SIGINT wiring — for tests that manage shutdown themselves. */
|
|
@@ -26,7 +26,7 @@ export interface BootHandle {
|
|
|
26
26
|
/**
|
|
27
27
|
* The whole run workflow, in the order the POC pins down:
|
|
28
28
|
* environment → module graph → exploration → global config → (acl, db —
|
|
29
|
-
* future steps) → mode fork (
|
|
29
|
+
* future steps) → mode fork (backend | worker) → onReady. Each phase crashes
|
|
30
30
|
* with its aggregate report before the next begins.
|
|
31
31
|
*/
|
|
32
32
|
export declare function boot(options: BootOptions): Promise<BootHandle>;
|
package/dist/boot/boot.js
CHANGED
|
@@ -15,11 +15,11 @@ import { errorHandler, notFoundHandler } from "../http/error-handler.js";
|
|
|
15
15
|
import { loadAppConfigSeed } from "./app-files.js";
|
|
16
16
|
import { printStartupBanner } from "./banner.js";
|
|
17
17
|
import { importFile } from "./import-file.js";
|
|
18
|
-
export const processModes = ["
|
|
18
|
+
export const processModes = ["backend", "worker"];
|
|
19
19
|
/**
|
|
20
20
|
* The whole run workflow, in the order the POC pins down:
|
|
21
21
|
* environment → module graph → exploration → global config → (acl, db —
|
|
22
|
-
* future steps) → mode fork (
|
|
22
|
+
* future steps) → mode fork (backend | worker) → onReady. Each phase crashes
|
|
23
23
|
* with its aggregate report before the next begins.
|
|
24
24
|
*/
|
|
25
25
|
export async function boot(options) {
|
|
@@ -64,8 +64,8 @@ export async function boot(options) {
|
|
|
64
64
|
const queueReport = new BootReport();
|
|
65
65
|
await initQueues(explored, ctx, queueReport);
|
|
66
66
|
queueReport.throwIfAny("queues");
|
|
67
|
-
if (mode === "
|
|
68
|
-
await
|
|
67
|
+
if (mode === "backend") {
|
|
68
|
+
await startBackend(handle, explored);
|
|
69
69
|
}
|
|
70
70
|
else {
|
|
71
71
|
const workerReport = new BootReport();
|
|
@@ -104,14 +104,17 @@ export async function boot(options) {
|
|
|
104
104
|
return handle;
|
|
105
105
|
}
|
|
106
106
|
function resolveMode(override) {
|
|
107
|
-
const raw = override ?? process.env.PROCESS_MODE ?? "
|
|
107
|
+
const raw = override ?? process.env.PROCESS_MODE ?? "backend";
|
|
108
108
|
if (!processModes.includes(raw)) {
|
|
109
|
-
|
|
109
|
+
// "web" was this mode's name before 0.1.5; name the replacement rather
|
|
110
|
+
// than leaving an upgrader to guess from the valid-values list.
|
|
111
|
+
const hint = raw === "web" ? ' — "web" was renamed to "backend"' : "";
|
|
112
|
+
throw new Error(`PROCESS_MODE "${raw}" is invalid — expected one of: ${processModes.join(", ")}${hint}`);
|
|
110
113
|
}
|
|
111
114
|
return raw;
|
|
112
115
|
}
|
|
113
116
|
/**
|
|
114
|
-
* Phases
|
|
117
|
+
* Phases 9b–11b: express, module routes, http server.
|
|
115
118
|
*
|
|
116
119
|
* The request pipeline, in order:
|
|
117
120
|
* 1. every module router (load order — sys modules first, so their
|
|
@@ -128,7 +131,7 @@ function resolveMode(override) {
|
|
|
128
131
|
* escapes unrouted or unhandled. @tulipes/core/http ships only that tail's
|
|
129
132
|
* building blocks (HttpError, notFoundHandler, errorHandler).
|
|
130
133
|
*/
|
|
131
|
-
async function
|
|
134
|
+
async function startBackend(handle, explored) {
|
|
132
135
|
const app = express();
|
|
133
136
|
handle.app = app;
|
|
134
137
|
handle.ctx.app = app;
|
|
@@ -171,7 +174,7 @@ async function startWeb(handle, explored) {
|
|
|
171
174
|
: 3000;
|
|
172
175
|
const server = createServer(app);
|
|
173
176
|
handle.server = server;
|
|
174
|
-
// Phase
|
|
177
|
+
// Phase 11b — sockets attach before listen() so no client can connect
|
|
175
178
|
// to a namespace that isn't wired yet.
|
|
176
179
|
const socketReport = new BootReport();
|
|
177
180
|
await initSockets(explored, handle.ctx, server, socketReport);
|
package/dist/boot/boot.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boot.js","sourceRoot":"","sources":["../../src/boot/boot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAe,MAAM,WAAW,CAAC;AAEtD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,OAAO,EAAE,EAAgB,MAAM,SAAS,CAAC;AAEhD,OAAO,EAAE,WAAW,EAAe,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAoB,MAAM,wBAAwB,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"boot.js","sourceRoot":"","sources":["../../src/boot/boot.ts"],"names":[],"mappings":"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"}
|
package/dist/boot/contracts.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import type { SocketManager } from "../sockets/socket-manager.js";
|
|
|
8
8
|
/**
|
|
9
9
|
* The context object threaded through every module-authored function.
|
|
10
10
|
* Later-phase members only exist once their phase has run: config factories
|
|
11
|
-
* (phase 6) see neither `acl` (phase 7) nor `app` (
|
|
11
|
+
* (phase 6) see neither `acl` (phase 7) nor `app` (backend branch, phase 9).
|
|
12
12
|
*/
|
|
13
13
|
export interface Ctx {
|
|
14
14
|
Environment: Environment;
|
|
@@ -40,7 +40,7 @@ export interface ModuleLifecycle {
|
|
|
40
40
|
onShutdown?: LifecycleHook;
|
|
41
41
|
}
|
|
42
42
|
/**
|
|
43
|
-
* Default export of `routes/*.routes.ts` (
|
|
43
|
+
* Default export of `routes/*.routes.ts` (backend branch only). May mount
|
|
44
44
|
* directly on `ctx.app`, or return a Router for core to `app.use()` —
|
|
45
45
|
* returning one is the recommended style.
|
|
46
46
|
*/
|
package/dist/cli/init.d.ts
CHANGED
|
@@ -1,21 +1,14 @@
|
|
|
1
|
-
export interface InitOptions {
|
|
2
|
-
/** Also scaffold the contracts that need mongo and redis. */
|
|
3
|
-
full?: boolean;
|
|
4
|
-
}
|
|
5
1
|
/**
|
|
6
|
-
* `tulipes init [dir]
|
|
2
|
+
* `tulipes init [dir]` — scaffold a complete application.
|
|
7
3
|
*
|
|
8
4
|
* Three modules ship: core (sys 0 — env contract, roles, request ids),
|
|
9
5
|
* security (sys 10 — helmet, cors, logging, body parsing) and hello, a
|
|
10
|
-
* worked example of
|
|
6
|
+
* worked example of EVERY module contract: config with lifecycle hooks,
|
|
7
|
+
* ACL grants, routes, a controller, a helper, a model, a bootstrap task,
|
|
8
|
+
* a queue with its processor, and a socket namespace.
|
|
11
9
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* always succeeds on a bare machine.
|
|
16
|
-
*
|
|
17
|
-
* `--full` adds the contracts that cannot work without infrastructure —
|
|
18
|
-
* models, bootstrap tasks and queues — along with the variables they
|
|
19
|
-
* require. That app needs mongo and redis running to boot.
|
|
10
|
+
* The generated app therefore needs mongo and redis running — models and
|
|
11
|
+
* queues cannot work without them, and the boot refuses rather than
|
|
12
|
+
* degrading quietly.
|
|
20
13
|
*/
|
|
21
|
-
export declare function runInit(rootDir: string, target?: string
|
|
14
|
+
export declare function runInit(rootDir: string, target?: string): Promise<void>;
|
package/dist/cli/init.js
CHANGED
|
@@ -1,33 +1,29 @@
|
|
|
1
1
|
import { cpSync, existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { basename, dirname, join, resolve } from "node:path";
|
|
3
|
-
import {
|
|
3
|
+
import { coreVersion, packageRoot } from "./package-info.js";
|
|
4
4
|
/**
|
|
5
|
-
* `tulipes init [dir]
|
|
5
|
+
* `tulipes init [dir]` — scaffold a complete application.
|
|
6
6
|
*
|
|
7
7
|
* Three modules ship: core (sys 0 — env contract, roles, request ids),
|
|
8
8
|
* security (sys 10 — helmet, cors, logging, body parsing) and hello, a
|
|
9
|
-
* worked example of
|
|
9
|
+
* worked example of EVERY module contract: config with lifecycle hooks,
|
|
10
|
+
* ACL grants, routes, a controller, a helper, a model, a bootstrap task,
|
|
11
|
+
* a queue with its processor, and a socket namespace.
|
|
10
12
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* always succeeds on a bare machine.
|
|
15
|
-
*
|
|
16
|
-
* `--full` adds the contracts that cannot work without infrastructure —
|
|
17
|
-
* models, bootstrap tasks and queues — along with the variables they
|
|
18
|
-
* require. That app needs mongo and redis running to boot.
|
|
13
|
+
* The generated app therefore needs mongo and redis running — models and
|
|
14
|
+
* queues cannot work without them, and the boot refuses rather than
|
|
15
|
+
* degrading quietly.
|
|
19
16
|
*/
|
|
20
|
-
export async function runInit(rootDir, target
|
|
17
|
+
export async function runInit(rootDir, target) {
|
|
21
18
|
const dir = resolve(rootDir, target ?? ".");
|
|
22
19
|
const name = sanitizeName(basename(dir));
|
|
23
|
-
const full = options.full ?? false;
|
|
24
20
|
if (existsSync(dir) && readdirSync(dir).some((entry) => entry !== ".git")) {
|
|
25
21
|
console.error(`refusing to init: ${dir} is not empty`);
|
|
26
22
|
process.exitCode = 1;
|
|
27
23
|
return;
|
|
28
24
|
}
|
|
29
|
-
const
|
|
30
|
-
const files = renderProject(name,
|
|
25
|
+
const version = coreVersion();
|
|
26
|
+
const files = renderProject(name, version);
|
|
31
27
|
for (const [relPath, content] of files) {
|
|
32
28
|
const filePath = join(dir, relPath);
|
|
33
29
|
mkdirSync(dirname(filePath), { recursive: true });
|
|
@@ -46,23 +42,11 @@ export async function runInit(rootDir, target, options = {}) {
|
|
|
46
42
|
"",
|
|
47
43
|
" → http://localhost:3000/hello",
|
|
48
44
|
"",
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
45
|
+
"Needs mongo and redis running — see MONGO_URI / REDIS_URL in",
|
|
46
|
+
".envs/.env.development. Run `yarn worker` in a second terminal to",
|
|
47
|
+
"consume queued jobs.",
|
|
52
48
|
].filter((line) => line !== undefined).join("\n"));
|
|
53
49
|
}
|
|
54
|
-
/**
|
|
55
|
-
* The version of the core running this CLI. Resolved relative to this file
|
|
56
|
-
* (src/cli or dist/cli — both sit two levels below the package root) since
|
|
57
|
-
* the exports map deliberately doesn't expose package.json.
|
|
58
|
-
*/
|
|
59
|
-
function ownVersion() {
|
|
60
|
-
const pkg = JSON.parse(readFileSync(join(packageRoot(), "package.json"), "utf8"));
|
|
61
|
-
return pkg.version;
|
|
62
|
-
}
|
|
63
|
-
function packageRoot() {
|
|
64
|
-
return join(dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
65
|
-
}
|
|
66
50
|
/**
|
|
67
51
|
* Instructions for AI coding agents working in the generated app: an
|
|
68
52
|
* always-loaded CLAUDE.md plus task-scoped skills. They ship as real
|
|
@@ -95,7 +79,7 @@ function sanitizeName(raw) {
|
|
|
95
79
|
return name || "tulipes-app";
|
|
96
80
|
}
|
|
97
81
|
const json = (value) => JSON.stringify(value, null, 2) + "\n";
|
|
98
|
-
function renderProject(name, coreVersion
|
|
82
|
+
function renderProject(name, coreVersion) {
|
|
99
83
|
const core = `^${coreVersion}`;
|
|
100
84
|
const files = [
|
|
101
85
|
["package.json", json({
|
|
@@ -167,7 +151,7 @@ function renderProject(name, coreVersion, full) {
|
|
|
167
151
|
["app.ts", [
|
|
168
152
|
`import { boot } from "@tulipes/core/boot";`,
|
|
169
153
|
``,
|
|
170
|
-
`await boot({ rootDir: import.meta.dirname, mode: "
|
|
154
|
+
`await boot({ rootDir: import.meta.dirname, mode: "backend" });`,
|
|
171
155
|
``,
|
|
172
156
|
].join("\n")],
|
|
173
157
|
["worker.ts", [
|
|
@@ -346,13 +330,9 @@ function renderProject(name, coreVersion, full) {
|
|
|
346
330
|
`# none; "*" allows any but forbids credentials.`,
|
|
347
331
|
`CORS_ORIGINS=http://localhost:5173`,
|
|
348
332
|
``,
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
`REDIS_URL=redis://127.0.0.1:6379`,
|
|
353
|
-
``,
|
|
354
|
-
]
|
|
355
|
-
: []),
|
|
333
|
+
`MONGO_URI=mongodb://127.0.0.1:27017/${name}`,
|
|
334
|
+
`REDIS_URL=redis://127.0.0.1:6379`,
|
|
335
|
+
``,
|
|
356
336
|
].join("\n")],
|
|
357
337
|
// ── modules/core — sys tier, priority 0: the very first router ─────────
|
|
358
338
|
["modules/core/package.json", json({
|
|
@@ -369,29 +349,25 @@ function renderProject(name, coreVersion, full) {
|
|
|
369
349
|
name: "PORT",
|
|
370
350
|
type: "number",
|
|
371
351
|
group: "http",
|
|
372
|
-
description: "HTTP port the
|
|
352
|
+
description: "HTTP port the backend process listens on",
|
|
373
353
|
default: 3000,
|
|
374
354
|
},
|
|
375
355
|
// Infra connection strings live in the sys core module because every
|
|
376
356
|
// feature shares them — one owner per variable, no duplicates.
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
description: "Redis connection string (queues, cache)",
|
|
392
|
-
},
|
|
393
|
-
]
|
|
394
|
-
: []),
|
|
357
|
+
{
|
|
358
|
+
name: "MONGO_URI",
|
|
359
|
+
type: "url",
|
|
360
|
+
group: "database",
|
|
361
|
+
required: true,
|
|
362
|
+
description: "MongoDB connection string",
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
name: "REDIS_URL",
|
|
366
|
+
type: "url",
|
|
367
|
+
group: "redis",
|
|
368
|
+
required: true,
|
|
369
|
+
description: "Redis connection string (queues, cache)",
|
|
370
|
+
},
|
|
395
371
|
],
|
|
396
372
|
})],
|
|
397
373
|
["modules/core/module.acl.ts", [
|
|
@@ -617,7 +593,7 @@ function renderProject(name, coreVersion, full) {
|
|
|
617
593
|
dependencies: {
|
|
618
594
|
"@tulipes/core": core,
|
|
619
595
|
express: "^5",
|
|
620
|
-
|
|
596
|
+
mongoose: "^8",
|
|
621
597
|
},
|
|
622
598
|
})],
|
|
623
599
|
["modules/hello/meta.variables.json", json({
|
|
@@ -756,7 +732,7 @@ function renderProject(name, coreVersion, full) {
|
|
|
756
732
|
`import type { SocketRegistry } from "@tulipes/core/sockets";`,
|
|
757
733
|
``,
|
|
758
734
|
`/**`,
|
|
759
|
-
` *
|
|
735
|
+
` * Backend mode only. A namespace is claimed by exactly one module; emit`,
|
|
760
736
|
` * from anywhere with \`ctx.sockets!.of("/hello")\`.`,
|
|
761
737
|
` *`,
|
|
762
738
|
` * Try it: wscat -c ws://localhost:3000/hello`,
|
|
@@ -776,119 +752,117 @@ function renderProject(name, coreVersion, full) {
|
|
|
776
752
|
``,
|
|
777
753
|
].join("\n")],
|
|
778
754
|
];
|
|
779
|
-
// ──
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
].join("\n")]);
|
|
891
|
-
}
|
|
755
|
+
// ── the contracts that need a database or redis ────────────────────────
|
|
756
|
+
files.push(["modules/hello/models/greeting.model.ts", [
|
|
757
|
+
`import { Schema } from "mongoose";`,
|
|
758
|
+
`import type { ModelDef } from "@tulipes/core/db";`,
|
|
759
|
+
``,
|
|
760
|
+
`/**`,
|
|
761
|
+
` * A model file is a DECLARATION, never a registration: the framework`,
|
|
762
|
+
` * compiles the schema on its own connection and puts it in the model`,
|
|
763
|
+
` * store. Never call mongoose.model() yourself.`,
|
|
764
|
+
` *`,
|
|
765
|
+
` * Read it anywhere the context reaches: models!.get("Greeting").`,
|
|
766
|
+
` */`,
|
|
767
|
+
`const greetingSchema = new Schema(`,
|
|
768
|
+
` {`,
|
|
769
|
+
` name: { type: String, required: true, unique: true, lowercase: true, trim: true },`,
|
|
770
|
+
` message: { type: String, required: true },`,
|
|
771
|
+
` timesUsed: { type: Number, default: 0, min: 0 },`,
|
|
772
|
+
` },`,
|
|
773
|
+
` { timestamps: true },`,
|
|
774
|
+
`);`,
|
|
775
|
+
``,
|
|
776
|
+
`export default { name: "Greeting", schema: greetingSchema } satisfies ModelDef;`,
|
|
777
|
+
``,
|
|
778
|
+
].join("\n")], ["modules/hello/bootstrap/seed-greetings.bootstrap.ts", [
|
|
779
|
+
`import type { Ctx } from "@tulipes/core/boot";`,
|
|
780
|
+
``,
|
|
781
|
+
`/**`,
|
|
782
|
+
` * Runs after models are registered and before the server accepts`,
|
|
783
|
+
` * traffic — the place for indexes, seed rows and defaults.`,
|
|
784
|
+
` *`,
|
|
785
|
+
` * MUST be idempotent: it runs on every boot of every process, backend and`,
|
|
786
|
+
` * worker alike. Upsert; never blind-insert.`,
|
|
787
|
+
` */`,
|
|
788
|
+
`export default async function seedGreetings({ models }: Ctx): Promise<void> {`,
|
|
789
|
+
` const Greeting = models!.get("Greeting");`,
|
|
790
|
+
``,
|
|
791
|
+
` await Greeting.updateOne(`,
|
|
792
|
+
` { name: "world" },`,
|
|
793
|
+
` { $setOnInsert: { name: "world", message: "Hello, world!" } },`,
|
|
794
|
+
` { upsert: true },`,
|
|
795
|
+
` );`,
|
|
796
|
+
`}`,
|
|
797
|
+
``,
|
|
798
|
+
].join("\n")], ["modules/hello/queues/hello.queues.ts", [
|
|
799
|
+
`import type { Ctx } from "@tulipes/core/boot";`,
|
|
800
|
+
`import type { QueueRegistry } from "@tulipes/core/queues";`,
|
|
801
|
+
``,
|
|
802
|
+
`/**`,
|
|
803
|
+
` * ONE file describes both sides. The backend process registers the queue`,
|
|
804
|
+
` * so routes can produce into it; \`yarn worker\` turns the processor`,
|
|
805
|
+
` * into a live consumer. Never duplicate the definition.`,
|
|
806
|
+
` *`,
|
|
807
|
+
` * Queue names use "." — BullMQ reserves ":" as its redis separator.`,
|
|
808
|
+
` */`,
|
|
809
|
+
`export default function helloQueues({ models }: Ctx, queues: QueueRegistry): void {`,
|
|
810
|
+
` queues.define("hello.count-greeting");`,
|
|
811
|
+
``,
|
|
812
|
+
` queues.process("hello.count-greeting", async (job) => {`,
|
|
813
|
+
` // Jobs retry, so processors must be idempotent-safe. Pass ids in`,
|
|
814
|
+
` // job.data and re-read state here rather than shipping documents.`,
|
|
815
|
+
` const { name } = job.data as { name: string };`,
|
|
816
|
+
` await models!.get("Greeting").updateOne({ name }, { $inc: { timesUsed: 1 } });`,
|
|
817
|
+
` return { counted: name };`,
|
|
818
|
+
` });`,
|
|
819
|
+
`}`,
|
|
820
|
+
``,
|
|
821
|
+
].join("\n")], ["modules/hello/routes/greetings.routes.ts", [
|
|
822
|
+
`import { Router } from "express";`,
|
|
823
|
+
`import type { Ctx } from "@tulipes/core/boot";`,
|
|
824
|
+
`import { HttpError } from "@tulipes/core/http";`,
|
|
825
|
+
``,
|
|
826
|
+
`/**`,
|
|
827
|
+
` * A module may ship several routes files; each is discovered and`,
|
|
828
|
+
` * mounted independently. This one shows the database and the queue.`,
|
|
829
|
+
` */`,
|
|
830
|
+
`export default function greetingsRoutes({ config, models, queues }: Ctx): Router {`,
|
|
831
|
+
` const router = Router();`,
|
|
832
|
+
` const base = String(config.api?.prefix ?? "");`,
|
|
833
|
+
``,
|
|
834
|
+
` router.get(\`\${base}/greetings\`, async (req, res) => {`,
|
|
835
|
+
` // Pagination bounds are app-wide, so every list endpoint clamps`,
|
|
836
|
+
` // the same way and no caller can ask for the whole table.`,
|
|
837
|
+
` const { defaultLimit = 20, maxLimit = 100 } = config.pagination ?? {};`,
|
|
838
|
+
` const asked = Number(req.query.limit ?? defaultLimit);`,
|
|
839
|
+
` const limit = Math.min(Number.isFinite(asked) ? asked : defaultLimit, maxLimit);`,
|
|
840
|
+
``,
|
|
841
|
+
` const greetings = await models!`,
|
|
842
|
+
` .get("Greeting")`,
|
|
843
|
+
` .find()`,
|
|
844
|
+
` .select("name message timesUsed -_id")`,
|
|
845
|
+
` .limit(limit)`,
|
|
846
|
+
` .lean();`,
|
|
847
|
+
``,
|
|
848
|
+
` res.json({ count: greetings.length, limit, greetings });`,
|
|
849
|
+
` });`,
|
|
850
|
+
``,
|
|
851
|
+
` router.post(\`\${base}/greetings/:name/use\`, async (req, res) => {`,
|
|
852
|
+
` const { name } = req.params;`,
|
|
853
|
+
` const greeting = await models!.get("Greeting").findOne({ name }).lean();`,
|
|
854
|
+
` if (!greeting) throw new HttpError(404, \`no greeting named "\${name}"\`);`,
|
|
855
|
+
``,
|
|
856
|
+
` // Slow or retryable work belongs in a job, not in the request.`,
|
|
857
|
+
` // Run \`yarn worker\` in another terminal to see it processed.`,
|
|
858
|
+
` await queues!.add("hello.count-greeting", "count", { name });`,
|
|
859
|
+
` res.status(202).json({ name, queued: true });`,
|
|
860
|
+
` });`,
|
|
861
|
+
``,
|
|
862
|
+
` return router;`,
|
|
863
|
+
`}`,
|
|
864
|
+
``,
|
|
865
|
+
].join("\n")]);
|
|
892
866
|
files.push(["README.md", [
|
|
893
867
|
`# ${name}`,
|
|
894
868
|
``,
|
|
@@ -899,22 +873,12 @@ function renderProject(name, coreVersion, full) {
|
|
|
899
873
|
"```sh",
|
|
900
874
|
`corepack enable # once per machine — activates the pinned yarn 4`,
|
|
901
875
|
`yarn install`,
|
|
902
|
-
`yarn dev # boot the
|
|
876
|
+
`yarn dev # boot the backend process → http://localhost:3000/hello`,
|
|
903
877
|
"```",
|
|
904
878
|
``,
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
`in \`.envs/.env.development\`. Run \`yarn worker\` in a second`,
|
|
909
|
-
`terminal to consume queued jobs.`,
|
|
910
|
-
]
|
|
911
|
-
: [
|
|
912
|
-
`Boots with no database and no redis: the pipeline skips engines no`,
|
|
913
|
-
`module asks for. When your first model lands, declare \`MONGO_URI\``,
|
|
914
|
-
`(type \`url\`, required) in \`modules/core/meta.variables.json\` and`,
|
|
915
|
-
`set it in \`.envs/.env.development\`; same with \`REDIS_URL\` for`,
|
|
916
|
-
`queues. \`tulipes init --full\` scaffolds all of that up front.`,
|
|
917
|
-
]),
|
|
879
|
+
`Needs mongo and redis running — see \`MONGO_URI\` and \`REDIS_URL\` in`,
|
|
880
|
+
`\`.envs/.env.development\`. Run \`yarn worker\` in a second terminal to`,
|
|
881
|
+
`consume queued jobs.`,
|
|
918
882
|
``,
|
|
919
883
|
`## The hello module`,
|
|
920
884
|
``,
|
|
@@ -930,23 +894,20 @@ function renderProject(name, coreVersion, full) {
|
|
|
930
894
|
`| \`controllers/\` | the work; imported by routes, never scanned |`,
|
|
931
895
|
`| \`helpers/\` | pure logic, no framework |`,
|
|
932
896
|
`| \`sockets/*.sockets.ts\` | a claimed Socket.IO namespace |`,
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
`| \`bootstrap/*.bootstrap.ts\` | idempotent seeding, before traffic |`,
|
|
937
|
-
`| \`queues/*.queues.ts\` | a job definition and its processor |`,
|
|
938
|
-
]
|
|
939
|
-
: []),
|
|
897
|
+
`| \`models/*.model.ts\` | a schema declaration for the model store |`,
|
|
898
|
+
`| \`bootstrap/*.bootstrap.ts\` | idempotent seeding, before traffic |`,
|
|
899
|
+
`| \`queues/*.queues.ts\` | a job definition and its processor |`,
|
|
940
900
|
``,
|
|
941
901
|
`## Daily commands`,
|
|
942
902
|
``,
|
|
943
903
|
`| command | does |`,
|
|
944
904
|
`|---|---|`,
|
|
945
|
-
`| \`yarn dev\` | regenerate types, run
|
|
905
|
+
`| \`yarn dev\` | regenerate types, run backend process under tsx watch |`,
|
|
946
906
|
`| \`yarn worker\` | run the queue-consumer process (needs a queue first) |`,
|
|
947
907
|
`| \`yarn sync\` | regenerate \`types/config.d.ts\` + \`.env.example\` |`,
|
|
948
908
|
`| \`yarn check\` | validate env against every module contract — CI gate |`,
|
|
949
909
|
`| \`yarn tulipes new module <name>\` | scaffold a module |`,
|
|
910
|
+
`| \`yarn tulipes update\` | upgrade the framework everywhere it is declared |`,
|
|
950
911
|
``,
|
|
951
912
|
].join("\n")]);
|
|
952
913
|
return files;
|
package/dist/cli/init.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/main.js
CHANGED
|
@@ -3,34 +3,36 @@ import { runSync } from "./sync.js";
|
|
|
3
3
|
import { runEnvCheck } from "./env-check.js";
|
|
4
4
|
import { runNewModule } from "./new-module.js";
|
|
5
5
|
import { runDev } from "./dev.js";
|
|
6
|
+
import { runUpdate } from "./update.js";
|
|
7
|
+
import { coreVersion } from "./package-info.js";
|
|
6
8
|
/**
|
|
7
|
-
* The `tulipes` CLI. Deliberately dependency-free argument handling —
|
|
8
|
-
* commands don't justify a parser library.
|
|
9
|
+
* The `tulipes` CLI. Deliberately dependency-free argument handling — a
|
|
10
|
+
* handful of commands don't justify a parser library.
|
|
9
11
|
* All commands operate on the app in the current working directory.
|
|
10
12
|
*/
|
|
11
13
|
const HELP = `tulipes — module-based express framework
|
|
12
14
|
|
|
13
15
|
Usage:
|
|
14
|
-
tulipes init [dir] scaffold a new application (
|
|
15
|
-
tulipes
|
|
16
|
+
tulipes init [dir] scaffold a new application (needs mongo + redis)
|
|
17
|
+
tulipes dev [entry] run with tsx in watch mode (default entry: app.ts), sync first
|
|
16
18
|
tulipes sync regenerate types/config.d.ts and .env.example
|
|
17
19
|
tulipes env:check validate env against every meta.variables.json (CI-friendly)
|
|
18
20
|
tulipes new module <name> scaffold a module under ./modules
|
|
19
|
-
tulipes
|
|
21
|
+
tulipes update upgrade @tulipes/core to the latest release, everywhere
|
|
22
|
+
tulipes -v print the installed core version
|
|
20
23
|
`;
|
|
21
24
|
export async function main(argv) {
|
|
22
25
|
const [command, ...rest] = argv;
|
|
23
26
|
const rootDir = process.cwd();
|
|
24
27
|
switch (command) {
|
|
25
|
-
case "init":
|
|
26
|
-
|
|
27
|
-
const target = rest.find((arg) => !arg.startsWith("-"));
|
|
28
|
-
return runInit(rootDir, target, { full });
|
|
29
|
-
}
|
|
28
|
+
case "init":
|
|
29
|
+
return runInit(rootDir, rest[0]);
|
|
30
30
|
case "sync":
|
|
31
31
|
return runSync(rootDir);
|
|
32
32
|
case "env:check":
|
|
33
33
|
return runEnvCheck(rootDir);
|
|
34
|
+
case "update":
|
|
35
|
+
return runUpdate(rootDir);
|
|
34
36
|
case "new":
|
|
35
37
|
if (rest[0] !== "module" || !rest[1]) {
|
|
36
38
|
console.error('Usage: tulipes new module <name>');
|
|
@@ -40,6 +42,11 @@ export async function main(argv) {
|
|
|
40
42
|
return runNewModule(rootDir, rest[1]);
|
|
41
43
|
case "dev":
|
|
42
44
|
return runDev(rootDir, rest[0] ?? "app.ts");
|
|
45
|
+
case "-v":
|
|
46
|
+
case "--version":
|
|
47
|
+
case "version":
|
|
48
|
+
console.log(coreVersion());
|
|
49
|
+
return;
|
|
43
50
|
case undefined:
|
|
44
51
|
case "help":
|
|
45
52
|
case "--help":
|
package/dist/cli/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD;;;;GAIG;AACH,MAAM,IAAI,GAAG;;;;;;;;;;CAUZ,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,IAAuB;IAChD,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAChC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE9B,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,MAAM;YACT,OAAO,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACnC,KAAK,MAAM;YACT,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC;QAC1B,KAAK,WAAW;YACd,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC;QAC9B,KAAK,QAAQ;YACX,OAAO,SAAS,CAAC,OAAO,CAAC,CAAC;QAC5B,KAAK,KAAK;YACR,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrC,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;gBAClD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;gBACrB,OAAO;YACT,CAAC;YACD,OAAO,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACxC,KAAK,KAAK;YACR,OAAO,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC;QAC9C,KAAK,IAAI,CAAC;QACV,KAAK,WAAW,CAAC;QACjB,KAAK,SAAS;YACZ,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;YAC3B,OAAO;QACT,KAAK,SAAS,CAAC;QACf,KAAK,MAAM,CAAC;QACZ,KAAK,QAAQ;YACX,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAClB,OAAO;QACT;YACE,OAAO,CAAC,KAAK,CAAC,oBAAoB,OAAO,QAAQ,IAAI,EAAE,CAAC,CAAC;YACzD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACzB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The installed core's own package root. Resolved relative to this file —
|
|
3
|
+
* src/cli and dist/cli both sit two levels below it — because the exports
|
|
4
|
+
* map deliberately does not expose package.json.
|
|
5
|
+
*/
|
|
6
|
+
export declare function packageRoot(): string;
|
|
7
|
+
/** Version of the @tulipes/core running this CLI. */
|
|
8
|
+
export declare function coreVersion(): string;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
/**
|
|
5
|
+
* The installed core's own package root. Resolved relative to this file —
|
|
6
|
+
* src/cli and dist/cli both sit two levels below it — because the exports
|
|
7
|
+
* map deliberately does not expose package.json.
|
|
8
|
+
*/
|
|
9
|
+
export function packageRoot() {
|
|
10
|
+
return join(dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
11
|
+
}
|
|
12
|
+
/** Version of the @tulipes/core running this CLI. */
|
|
13
|
+
export function coreVersion() {
|
|
14
|
+
const pkg = JSON.parse(readFileSync(join(packageRoot(), "package.json"), "utf8"));
|
|
15
|
+
return pkg.version;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=package-info.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-info.js","sourceRoot":"","sources":["../../src/cli/package-info.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC;;;;GAIG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACnE,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,WAAW;IACzB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAE/E,CAAC;IACF,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `tulipes update` — move the app to the latest published core.
|
|
3
|
+
*
|
|
4
|
+
* The framework is depended on in more than one place: the app root and
|
|
5
|
+
* every module, since modules are workspace packages that declare their
|
|
6
|
+
* own dependencies. Bumping them by hand is the tedium this removes —
|
|
7
|
+
* and a module left behind on an older range is exactly the kind of
|
|
8
|
+
* split-version install that produces baffling type errors.
|
|
9
|
+
*/
|
|
10
|
+
export declare function runUpdate(rootDir: string): Promise<void>;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { existsSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { join, relative } from "node:path";
|
|
4
|
+
import { coreVersion } from "./package-info.js";
|
|
5
|
+
const PACKAGE = "@tulipes/core";
|
|
6
|
+
const REGISTRY = "https://registry.npmjs.org";
|
|
7
|
+
/**
|
|
8
|
+
* `tulipes update` — move the app to the latest published core.
|
|
9
|
+
*
|
|
10
|
+
* The framework is depended on in more than one place: the app root and
|
|
11
|
+
* every module, since modules are workspace packages that declare their
|
|
12
|
+
* own dependencies. Bumping them by hand is the tedium this removes —
|
|
13
|
+
* and a module left behind on an older range is exactly the kind of
|
|
14
|
+
* split-version install that produces baffling type errors.
|
|
15
|
+
*/
|
|
16
|
+
export async function runUpdate(rootDir) {
|
|
17
|
+
const current = coreVersion();
|
|
18
|
+
let latest;
|
|
19
|
+
try {
|
|
20
|
+
latest = await fetchLatest();
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
console.error(`could not reach the npm registry: ${error.message}`);
|
|
24
|
+
process.exitCode = 1;
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const manifests = findManifests(rootDir);
|
|
28
|
+
if (manifests.length === 0) {
|
|
29
|
+
console.error(`no package.json in ${rootDir} depends on ${PACKAGE} — run this from an app root`);
|
|
30
|
+
process.exitCode = 1;
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const range = `^${latest}`;
|
|
34
|
+
const changed = manifests.filter(({ path }) => rewrite(path, range));
|
|
35
|
+
if (changed.length === 0) {
|
|
36
|
+
console.log(`already on ${PACKAGE}@${range} (installed ${current}, latest ${latest})`);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
for (const { path } of changed) {
|
|
40
|
+
console.log(` update ${relative(rootDir, path) || "package.json"} → ${range}`);
|
|
41
|
+
}
|
|
42
|
+
console.log(`\n${PACKAGE}: ${current} → ${latest}\n`);
|
|
43
|
+
await install(rootDir);
|
|
44
|
+
}
|
|
45
|
+
async function fetchLatest() {
|
|
46
|
+
// The scoped name has to be encoded for the registry's document route.
|
|
47
|
+
const response = await fetch(`${REGISTRY}/${PACKAGE.replace("/", "%2f")}/latest`);
|
|
48
|
+
if (!response.ok) {
|
|
49
|
+
throw new Error(`registry responded ${response.status}`);
|
|
50
|
+
}
|
|
51
|
+
const body = (await response.json());
|
|
52
|
+
if (typeof body.version !== "string") {
|
|
53
|
+
throw new Error("registry returned no version");
|
|
54
|
+
}
|
|
55
|
+
return body.version;
|
|
56
|
+
}
|
|
57
|
+
/** The app root plus every module — anywhere the framework is depended on. */
|
|
58
|
+
function findManifests(rootDir) {
|
|
59
|
+
const candidates = [join(rootDir, "package.json")];
|
|
60
|
+
const modulesDir = join(rootDir, "modules");
|
|
61
|
+
try {
|
|
62
|
+
for (const entry of readdirSync(modulesDir, { withFileTypes: true })) {
|
|
63
|
+
if (entry.isDirectory()) {
|
|
64
|
+
candidates.push(join(modulesDir, entry.name, "package.json"));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// No modules directory: still a valid target if the root depends on core.
|
|
70
|
+
}
|
|
71
|
+
return candidates
|
|
72
|
+
.filter((path) => existsSync(path) && dependsOnCore(path))
|
|
73
|
+
.map((path) => ({ path }));
|
|
74
|
+
}
|
|
75
|
+
function dependsOnCore(path) {
|
|
76
|
+
try {
|
|
77
|
+
const manifest = JSON.parse(readFileSync(path, "utf8"));
|
|
78
|
+
return Boolean(manifest.dependencies?.[PACKAGE] ?? manifest.devDependencies?.[PACKAGE]);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/** Returns true when the file actually changed. */
|
|
85
|
+
function rewrite(path, range) {
|
|
86
|
+
const raw = readFileSync(path, "utf8");
|
|
87
|
+
const manifest = JSON.parse(raw);
|
|
88
|
+
let touched = false;
|
|
89
|
+
for (const field of ["dependencies", "devDependencies"]) {
|
|
90
|
+
const deps = manifest[field];
|
|
91
|
+
if (deps?.[PACKAGE] !== undefined && deps[PACKAGE] !== range) {
|
|
92
|
+
deps[PACKAGE] = range;
|
|
93
|
+
touched = true;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (!touched)
|
|
97
|
+
return false;
|
|
98
|
+
writeFileSync(path, JSON.stringify(manifest, null, 2) + "\n");
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Rewriting manifests without installing would leave the app claiming a
|
|
103
|
+
* version it does not have, so the install is part of the command rather
|
|
104
|
+
* than a step to remember.
|
|
105
|
+
*/
|
|
106
|
+
async function install(rootDir) {
|
|
107
|
+
const manager = detectManager(rootDir);
|
|
108
|
+
console.log(`running ${manager} install…\n`);
|
|
109
|
+
const code = await new Promise((resolve) => {
|
|
110
|
+
const child = spawn(manager, ["install"], { cwd: rootDir, stdio: "inherit" });
|
|
111
|
+
child.on("error", () => resolve(-1));
|
|
112
|
+
child.on("exit", (status) => resolve(status ?? 1));
|
|
113
|
+
});
|
|
114
|
+
if (code === -1) {
|
|
115
|
+
console.error(`\ncould not run "${manager}" — manifests are updated, install manually`);
|
|
116
|
+
process.exitCode = 1;
|
|
117
|
+
}
|
|
118
|
+
else if (code !== 0) {
|
|
119
|
+
process.exitCode = code;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function detectManager(rootDir) {
|
|
123
|
+
if (existsSync(join(rootDir, "yarn.lock")))
|
|
124
|
+
return "yarn";
|
|
125
|
+
if (existsSync(join(rootDir, "pnpm-lock.yaml")))
|
|
126
|
+
return "pnpm";
|
|
127
|
+
if (existsSync(join(rootDir, "package-lock.json")))
|
|
128
|
+
return "npm";
|
|
129
|
+
// No lockfile yet (a fresh scaffold): fall back to the pinned manager.
|
|
130
|
+
try {
|
|
131
|
+
const manifest = JSON.parse(readFileSync(join(rootDir, "package.json"), "utf8"));
|
|
132
|
+
const pinned = manifest.packageManager ?? "";
|
|
133
|
+
if (pinned.startsWith("pnpm"))
|
|
134
|
+
return "pnpm";
|
|
135
|
+
if (pinned.startsWith("npm"))
|
|
136
|
+
return "npm";
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
// fall through
|
|
140
|
+
}
|
|
141
|
+
return "yarn";
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/cli/update.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,7 @@ import { BootReport } from "../errors/boot-error.js";
|
|
|
5
5
|
* run in BOTH modes — definitions and processors are always registered — and
|
|
6
6
|
* the mode decides what happens with them:
|
|
7
7
|
*
|
|
8
|
-
*
|
|
8
|
+
* backend → queues produce; processors are registered but never started
|
|
9
9
|
* worker → `startWorkers()` turns every registered processor into a
|
|
10
10
|
* consuming BullMQ Worker
|
|
11
11
|
*
|
|
@@ -6,7 +6,7 @@ import { BootReport } from "../errors/boot-error.js";
|
|
|
6
6
|
* run in BOTH modes — definitions and processors are always registered — and
|
|
7
7
|
* the mode decides what happens with them:
|
|
8
8
|
*
|
|
9
|
-
*
|
|
9
|
+
* backend → queues produce; processors are registered but never started
|
|
10
10
|
* worker → `startWorkers()` turns every registered processor into a
|
|
11
11
|
* consuming BullMQ Worker
|
|
12
12
|
*
|
|
@@ -3,10 +3,10 @@ import { BootReport } from "../errors/boot-error.js";
|
|
|
3
3
|
import type { Ctx } from "../boot/contracts.js";
|
|
4
4
|
import type { ModuleFiles } from "../modules/explorer.js";
|
|
5
5
|
import { SocketManager, type SocketRegistry } from "./socket-manager.js";
|
|
6
|
-
/** Default export of `sockets/*.sockets.ts` (
|
|
6
|
+
/** Default export of `sockets/*.sockets.ts` (backend branch only). */
|
|
7
7
|
export type SocketsFn = (ctx: Ctx, sockets: SocketRegistry) => void | Promise<void>;
|
|
8
8
|
/**
|
|
9
|
-
* Phase
|
|
9
|
+
* Phase 11b: attach Socket.IO to the http server and run every
|
|
10
10
|
* `*.sockets.ts` in load order. No socket files → no Socket.IO server at
|
|
11
11
|
* all; websockets are opt-in per app, not a standing cost.
|
|
12
12
|
*/
|
|
@@ -2,7 +2,7 @@ import { BootReport } from "../errors/boot-error.js";
|
|
|
2
2
|
import { importFile } from "../boot/import-file.js";
|
|
3
3
|
import { SocketManager } from "./socket-manager.js";
|
|
4
4
|
/**
|
|
5
|
-
* Phase
|
|
5
|
+
* Phase 11b: attach Socket.IO to the http server and run every
|
|
6
6
|
* `*.sockets.ts` in load order. No socket files → no Socket.IO server at
|
|
7
7
|
* all; websockets are opt-in per app, not a standing cost.
|
|
8
8
|
*/
|
|
@@ -2,7 +2,7 @@ import type { Server as HttpServer } from "node:http";
|
|
|
2
2
|
import { Server, type Namespace, type ServerOptions } from "socket.io";
|
|
3
3
|
import { BootReport } from "../errors/boot-error.js";
|
|
4
4
|
/**
|
|
5
|
-
* Wraps the process-wide Socket.IO server (
|
|
5
|
+
* Wraps the process-wide Socket.IO server (backend branch only, phase 11b).
|
|
6
6
|
*
|
|
7
7
|
* Namespaces are the socket-side equivalent of route prefixes, and get the
|
|
8
8
|
* same ownership rule as everything else in Tulipes: a module claims its
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Server } from "socket.io";
|
|
2
2
|
import { BootReport } from "../errors/boot-error.js";
|
|
3
3
|
/**
|
|
4
|
-
* Wraps the process-wide Socket.IO server (
|
|
4
|
+
* Wraps the process-wide Socket.IO server (backend branch only, phase 11b).
|
|
5
5
|
*
|
|
6
6
|
* Namespaces are the socket-side equivalent of route prefixes, and get the
|
|
7
7
|
* same ownership rule as everything else in Tulipes: a module claims its
|
package/package.json
CHANGED
package/templates/CLAUDE.md
CHANGED
|
@@ -56,12 +56,13 @@ queues → routes. If code needs something another module provides, declare
|
|
|
56
56
|
|
|
57
57
|
| Command | Use |
|
|
58
58
|
|---|---|
|
|
59
|
-
| `yarn dev` | run the
|
|
59
|
+
| `yarn dev` | run the backend process (regenerates types first) |
|
|
60
60
|
| `yarn worker` | run the queue-consumer process |
|
|
61
61
|
| `yarn sync` | regenerate `types/config.d.ts` + `.env.example` |
|
|
62
62
|
| `yarn check` | validate the environment without booting |
|
|
63
63
|
| `yarn typecheck` | typecheck the whole app |
|
|
64
64
|
| `yarn tulipes new module <name>` | scaffold a module |
|
|
65
|
+
| `yarn tulipes update` | upgrade the framework in the root and every module |
|
|
65
66
|
|
|
66
67
|
## Verifying your work
|
|
67
68
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: tulipes-queue
|
|
3
|
-
description: Use when adding background work to a Tulipes app — emails, webhooks, exports, scheduled retries — or when a request handler is doing something slow. Covers the queues contract, producing jobs, and the
|
|
3
|
+
description: Use when adding background work to a Tulipes app — emails, webhooks, exports, scheduled retries — or when a request handler is doing something slow. Covers the queues contract, producing jobs, and the backend/worker process split.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Adding a background job
|
|
7
7
|
|
|
8
8
|
One file declares both sides of a queue, and the process mode decides what
|
|
9
|
-
happens with it: the **
|
|
9
|
+
happens with it: the **backend** process registers the queue so routes can
|
|
10
10
|
produce into it; the **worker** process turns the processor into a live
|
|
11
11
|
consumer. Never duplicate the definition.
|
|
12
12
|
|
|
@@ -27,7 +27,7 @@ export default function billingSockets({ config }: Ctx, sockets: SocketRegistry)
|
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
Emit from anywhere with the context — a route, a bootstrap task, a queue
|
|
30
|
-
processor in the
|
|
30
|
+
processor in the backend process:
|
|
31
31
|
|
|
32
32
|
```ts
|
|
33
33
|
ctx.sockets!.of("/billing").to(`invoice:${id}`).emit("invoice:paid", payload);
|
|
@@ -40,16 +40,16 @@ ctx.sockets!.of("/billing").to(`invoice:${id}`).emit("invoice:paid", payload);
|
|
|
40
40
|
- `sockets.of()` throws on a namespace nobody claimed. Socket.IO's raw
|
|
41
41
|
`io.of()` would silently create it and emit into the void — use the
|
|
42
42
|
framework accessor so typos surface.
|
|
43
|
-
- Sockets exist in **
|
|
43
|
+
- Sockets exist in **backend mode only**. `ctx.sockets` is undefined in the
|
|
44
44
|
worker process, so a queue processor cannot emit directly — publish to
|
|
45
|
-
Redis, or have the
|
|
45
|
+
Redis, or have the backend process subscribe.
|
|
46
46
|
- Namespace names are lowercase kebab-case with a leading slash.
|
|
47
47
|
|
|
48
48
|
## Gotchas
|
|
49
49
|
|
|
50
50
|
- Authenticate in namespace middleware (`nsp.use(...)`), not per event —
|
|
51
51
|
the framework's HTTP pipeline does not run for socket connections.
|
|
52
|
-
- Scaling past one
|
|
52
|
+
- Scaling past one backend process needs the Socket.IO Redis adapter;
|
|
53
53
|
otherwise an emit only reaches clients connected to that instance.
|
|
54
54
|
- Socket handlers run outside the request pipeline: no `HttpError`, no
|
|
55
55
|
request logging. Handle failures explicitly and emit an error event.
|