@tulipes/cli 0.1.1 → 0.2.0-rc.1
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 +10 -7
- package/dist/agent.d.ts +12 -0
- package/dist/agent.js +29 -0
- package/dist/agent.js.map +1 -0
- package/dist/app-core.d.ts +8 -6
- package/dist/app-core.js +23 -14
- package/dist/app-core.js.map +1 -1
- package/dist/bin.js +3 -3
- package/dist/bin.js.map +1 -1
- package/dist/config-check.d.ts +8 -0
- package/dist/config-check.js +43 -0
- package/dist/config-check.js.map +1 -0
- package/dist/config-import.d.ts +20 -0
- package/dist/config-import.js +133 -0
- package/dist/config-import.js.map +1 -0
- package/dist/dev.d.ts +4 -4
- package/dist/dev.js +7 -10
- package/dist/dev.js.map +1 -1
- package/dist/init.d.ts +6 -11
- package/dist/init.js +11 -6422
- package/dist/init.js.map +1 -1
- package/dist/inspection.d.ts +9 -8
- package/dist/inspection.js +10 -11
- package/dist/inspection.js.map +1 -1
- package/dist/main.js +82 -11
- package/dist/main.js.map +1 -1
- package/dist/migrate.d.ts +30 -0
- package/dist/migrate.js +772 -0
- package/dist/migrate.js.map +1 -0
- package/dist/new-module.js +84 -43
- package/dist/new-module.js.map +1 -1
- package/dist/routes.d.ts +3 -5
- package/dist/routes.js +4 -6
- package/dist/routes.js.map +1 -1
- package/dist/spec.d.ts +2 -5
- package/dist/spec.js +13 -6
- package/dist/spec.js.map +1 -1
- package/dist/sync.d.ts +3 -11
- package/dist/sync.js +81 -20
- package/dist/sync.js.map +1 -1
- package/dist/template.d.ts +58 -0
- package/dist/template.js +244 -0
- package/dist/template.js.map +1 -0
- package/dist/update.js +4 -4
- package/package.json +17 -16
- package/templates/AGENTS.md +68 -31
- package/templates/CLAUDE.md +5 -4
- package/templates/app/.envs/.env.development +18 -0
- package/templates/app/.envs/.env.production +19 -0
- package/templates/app/.envs/.env.staging +19 -0
- package/templates/app/README.md +327 -0
- package/templates/app/app.ts +3 -0
- package/templates/app/config/app.config.ts +73 -0
- package/templates/app/docs/agent-manifest.json +724 -0
- package/templates/app/ecosystem.config.cjs +60 -0
- package/templates/app/modules/agent/controllers/agent.controllers.ts +31 -0
- package/templates/app/modules/agent/i18n/en.json +5 -0
- package/templates/app/modules/agent/i18n/fr.json +5 -0
- package/templates/app/modules/agent/module.acl.ts +14 -0
- package/templates/app/modules/agent/package.json +21 -0
- package/templates/app/modules/agent/routes/agent.routes.ts +29 -0
- package/templates/app/modules/agent/schemas/agent.schemas.ts +9 -0
- package/templates/app/modules/auth/bootstrap/credentials.bootstrap.ts +26 -0
- package/templates/app/modules/auth/bootstrap/seed-admin.bootstrap.ts +44 -0
- package/templates/app/modules/auth/controllers/auth.controllers.ts +312 -0
- package/templates/app/modules/auth/helpers/access-check.ts +42 -0
- package/templates/app/modules/auth/helpers/auth.ts +48 -0
- package/templates/app/modules/auth/helpers/documents.ts +57 -0
- package/templates/app/modules/auth/helpers/passport.ts +180 -0
- package/templates/app/modules/auth/helpers/passwords.ts +58 -0
- package/templates/app/modules/auth/helpers/session-cache.ts +67 -0
- package/templates/app/modules/auth/helpers/tokens.ts +329 -0
- package/templates/app/modules/auth/i18n/en.json +19 -0
- package/templates/app/modules/auth/i18n/fr.json +19 -0
- package/templates/app/modules/auth/lib/index.ts +12 -0
- package/templates/app/modules/auth/models/credential.model.ts +31 -0
- package/templates/app/modules/auth/models/revoked-token.model.ts +20 -0
- package/templates/app/modules/auth/models/session.model.ts +42 -0
- package/templates/app/modules/auth/module.acl.ts +41 -0
- package/templates/app/modules/auth/module.config.ts +30 -0
- package/templates/app/modules/auth/package.json +61 -0
- package/templates/app/modules/auth/routes/auth.routes.ts +94 -0
- package/templates/app/modules/auth/schemas/auth.schemas.ts +37 -0
- package/templates/app/modules/auth/tests/auth.test.ts +1079 -0
- package/templates/app/modules/config/controllers/config.controllers.ts +89 -0
- package/templates/app/modules/config/helpers/audit.ts +41 -0
- package/templates/app/modules/config/helpers/describe.ts +72 -0
- package/templates/app/modules/config/i18n/en.json +6 -0
- package/templates/app/modules/config/i18n/fr.json +6 -0
- package/templates/app/modules/config/models/config-audit.model.ts +26 -0
- package/templates/app/modules/config/module.acl.ts +12 -0
- package/templates/app/modules/config/package.json +23 -0
- package/templates/app/modules/config/routes/config.routes.ts +37 -0
- package/templates/app/modules/config/schemas/config.schemas.ts +13 -0
- package/templates/app/modules/config/tests/config.test.ts +126 -0
- package/templates/app/modules/core/bootstrap/cache.bootstrap.ts +12 -0
- package/templates/app/modules/core/helpers/cache/index.ts +60 -0
- package/templates/app/modules/core/helpers/cache/memory-cache.ts +53 -0
- package/templates/app/modules/core/helpers/cache/redis-cache.ts +68 -0
- package/templates/app/modules/core/helpers/cache/types.ts +37 -0
- package/templates/app/modules/core/helpers/lazy.ts +13 -0
- package/templates/app/modules/core/helpers/logger/index.ts +115 -0
- package/templates/app/modules/core/helpers/mongoose/index.ts +27 -0
- package/templates/app/modules/core/helpers/mongoose/plugins/base.plugin.ts +14 -0
- package/templates/app/modules/core/helpers/mongoose/plugins/soft-delete.plugin.ts +124 -0
- package/templates/app/modules/core/helpers/mongoose/plugins/timestamps.plugin.ts +13 -0
- package/templates/app/modules/core/helpers/mongoose/plugins/types.ts +45 -0
- package/templates/app/modules/core/helpers/mongoose/register.ts +20 -0
- package/templates/app/modules/core/lib/index.ts +34 -0
- package/templates/app/modules/core/module.config.ts +24 -0
- package/templates/app/modules/core/package.json +80 -0
- package/templates/app/modules/core/routes/core.routes.ts +24 -0
- package/templates/app/modules/core/tests/core.test.ts +19 -0
- package/templates/app/modules/hello/agent/hello.agent.ts +33 -0
- package/templates/app/modules/hello/bootstrap/seed-greetings.bootstrap.ts +27 -0
- package/templates/app/modules/hello/controllers/greetings.controllers.ts +43 -0
- package/templates/app/modules/hello/controllers/hello.controllers.ts +50 -0
- package/templates/app/modules/hello/helpers/greeting.ts +8 -0
- package/templates/app/modules/hello/i18n/en.json +8 -0
- package/templates/app/modules/hello/i18n/fr.json +8 -0
- package/templates/app/modules/hello/models/greeting.model.ts +24 -0
- package/templates/app/modules/hello/module.acl.ts +16 -0
- package/templates/app/modules/hello/module.config.ts +14 -0
- package/templates/app/modules/hello/package.json +24 -0
- package/templates/app/modules/hello/queues/hello.queues.ts +38 -0
- package/templates/app/modules/hello/routes/greetings.routes.ts +25 -0
- package/templates/app/modules/hello/routes/hello.routes.ts +44 -0
- package/templates/app/modules/hello/sockets/hello.sockets.ts +21 -0
- package/templates/app/modules/hello/tests/hello.test.ts +19 -0
- package/templates/app/modules/security/bootstrap/rate-limit.bootstrap.ts +8 -0
- package/templates/app/modules/security/helpers/hardening.ts +65 -0
- package/templates/app/modules/security/helpers/proxy.ts +16 -0
- package/templates/app/modules/security/helpers/rate-limit.ts +150 -0
- package/templates/app/modules/security/module.config.ts +59 -0
- package/templates/app/modules/security/package.json +26 -0
- package/templates/app/modules/security/routes/security.routes.ts +42 -0
- package/templates/app/modules/security/tests/security.test.ts +174 -0
- package/templates/app/modules/settings/bootstrap/log-streams.bootstrap.ts +12 -0
- package/templates/app/modules/settings/controllers/settings.controllers.ts +58 -0
- package/templates/app/modules/settings/helpers/access-lease.ts +99 -0
- package/templates/app/modules/settings/helpers/log-stream.ts +272 -0
- package/templates/app/modules/settings/helpers/log-tail.ts +253 -0
- package/templates/app/modules/settings/i18n/en.json +3 -0
- package/templates/app/modules/settings/i18n/fr.json +3 -0
- package/templates/app/modules/settings/module.acl.ts +12 -0
- package/templates/app/modules/settings/package.json +21 -0
- package/templates/app/modules/settings/routes/settings.routes.ts +33 -0
- package/templates/app/modules/settings/schemas/settings.schemas.ts +8 -0
- package/templates/app/modules/settings/tests/settings.test.ts +409 -0
- package/templates/app/modules/users/controllers/users.controllers.ts +113 -0
- package/templates/app/modules/users/i18n/en.json +14 -0
- package/templates/app/modules/users/i18n/fr.json +14 -0
- package/templates/app/modules/users/models/user.model.ts +18 -0
- package/templates/app/modules/users/module.acl.ts +10 -0
- package/templates/app/modules/users/module.config.ts +11 -0
- package/templates/app/modules/users/package.json +24 -0
- package/templates/app/modules/users/queues/users.queues.ts +31 -0
- package/templates/app/modules/users/routes/users.routes.ts +60 -0
- package/templates/app/modules/users/schemas/users.schemas.ts +30 -0
- package/templates/app/modules/users/sockets/users.sockets.ts +18 -0
- package/templates/app/nginx/development.conf +44 -0
- package/templates/app/nginx/production.conf +75 -0
- package/templates/app/nginx/staging.conf +51 -0
- package/templates/app/package.json +58 -0
- package/templates/app/scripts/count-greetings.ts +29 -0
- package/templates/app/scripts/deploy-nginx.ts +143 -0
- package/templates/app/scripts/list-users.ts +34 -0
- package/templates/app/tests/app.test.ts +28 -0
- package/templates/app/tests/support.ts +36 -0
- package/templates/app/tsconfig.json +28 -0
- package/templates/app/vitest.config.ts +6 -0
- package/templates/app/worker.ts +6 -0
- package/templates/claude/skills/tulipes-agent-tool/SKILL.md +83 -0
- package/templates/claude/skills/tulipes-boot-errors/SKILL.md +11 -5
- package/templates/claude/skills/tulipes-config/SKILL.md +74 -0
- package/templates/claude/skills/tulipes-endpoint/SKILL.md +38 -25
- package/templates/claude/skills/tulipes-env-variable/SKILL.md +54 -26
- package/templates/claude/skills/tulipes-model/SKILL.md +11 -4
- package/templates/claude/skills/tulipes-module/SKILL.md +11 -10
- package/templates/claude/skills/tulipes-queue/SKILL.md +20 -6
- package/templates/claude/skills/tulipes-settings/SKILL.md +49 -100
- package/templates/claude/skills/tulipes-spec/SKILL.md +10 -12
- package/templates/minimal/README.md +21 -0
- package/templates/minimal/app.ts +3 -0
- package/templates/minimal/config/app.config.ts +16 -0
- package/templates/minimal/modules/agent/module.acl.ts +3 -0
- package/templates/minimal/modules/agent/package.json +14 -0
- package/templates/minimal/modules/agent/routes/agent.routes.ts +20 -0
- package/templates/minimal/modules/core/module.acl.ts +4 -0
- package/templates/minimal/modules/core/package.json +21 -0
- package/templates/minimal/modules/hello/i18n/en.json +3 -0
- package/templates/minimal/modules/hello/module.acl.ts +2 -0
- package/templates/minimal/modules/hello/package.json +11 -0
- package/templates/minimal/modules/hello/routes/health.routes.ts +9 -0
- package/templates/minimal/modules/hello/routes/hello.routes.ts +10 -0
- package/templates/minimal/modules/security/package.json +15 -0
- package/templates/minimal/modules/security/routes/security.routes.ts +8 -0
- package/templates/minimal/package.json +38 -0
- package/templates/minimal/tests/app.test.ts +52 -0
- package/templates/minimal/tsconfig.json +22 -0
- package/templates/minimal/vitest.config.ts +5 -0
- package/templates/overlays/no-queues/ecosystem.config.cjs +52 -0
- package/templates/overlays/no-queues/modules/hello/controllers/greetings.controllers.ts +41 -0
- package/templates/overlays/no-queues/modules/users/controllers/users.controllers.ts +107 -0
- package/templates/versions.json +11 -0
- package/dist/minimal.d.ts +0 -2
- package/dist/minimal.js +0 -2200
- package/dist/minimal.js.map +0 -1
- /package/templates/{browser-auth.md → app/docs/browser-auth.md} +0 -0
package/README.md
CHANGED
|
@@ -16,21 +16,24 @@ loader it carries.
|
|
|
16
16
|
```sh
|
|
17
17
|
npm install -g @tulipes/cli@next
|
|
18
18
|
tulipes init my-api # minimal preset; --preset production for the full app
|
|
19
|
-
cd my-api &&
|
|
19
|
+
cd my-api && pnpm install && pnpm dev
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
Generated apps also list `@tulipes/cli` in `devDependencies`, so `
|
|
23
|
-
`
|
|
22
|
+
Generated apps also list `@tulipes/cli` in `devDependencies`, so `pnpm dev`,
|
|
23
|
+
`pnpm sync`, `pnpm spec` and `pnpm tulipes new module <name>` work without a
|
|
24
24
|
global install and always match the app.
|
|
25
25
|
|
|
26
26
|
| Command | What it does |
|
|
27
27
|
|---|---|
|
|
28
28
|
| `tulipes init [dir] [--minimal \| --preset minimal \| --preset production] [--no-queues] [--no-sockets]` | scaffold an application; no services. The two opt-outs apply to the production preset and leave that provider, its files, dependencies and worker process out |
|
|
29
|
-
| `tulipes dev [entry]` | regenerate types, then run
|
|
30
|
-
| `tulipes sync` | regenerate `types/
|
|
29
|
+
| `tulipes dev [entry]` | regenerate types, then run the entrypoint with `node --watch` |
|
|
30
|
+
| `tulipes sync` | regenerate `types/tulipes.d.ts` and `.env.example` |
|
|
31
31
|
| `tulipes env:check` | validate the environment without booting |
|
|
32
|
-
| `tulipes routes
|
|
33
|
-
| `tulipes spec [--
|
|
32
|
+
| `tulipes routes` | list declared endpoints, through inspection |
|
|
33
|
+
| `tulipes spec [--openapi file] [--postman file] [--url base]` | generate documents through inspection (needs `@tulipes/spec` in the app) |
|
|
34
|
+
| `tulipes agent manifest [--out file] [--role role]` | every tool the app exposes to agents, as JSON, through inspection |
|
|
35
|
+
| `tulipes migrate 0.11` | rewrite an app generated on 0.10 to the 0.11 layout and contracts; every judgement it cannot make is a `TODO 0.11:` |
|
|
36
|
+
| `tulipes config:import [--env APP_ENV] [--from file] [--dry-run]` | after a migration, carry the env file's values for variables that became settings into the store |
|
|
34
37
|
| `tulipes new module <name> [--model\|--no-model] [--queues\|--no-queues] [--sockets\|--no-sockets]` | scaffold a module for the providers the app declares |
|
|
35
38
|
| `tulipes update` | upgrade the global CLI and, inside an app, its core and CLI ranges |
|
|
36
39
|
| `tulipes -v` | print the CLI version, its bundled core, and the app's core when they differ |
|
package/dist/agent.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `tulipes agent manifest` — every tool the app exposes to agents, from
|
|
3
|
+
* the same inspection boot as `tulipes routes`: route tools from the RAIs
|
|
4
|
+
* with method, path and input schema, actions from `agent/*.agent.ts`.
|
|
5
|
+
* No service, secret or `.env` is needed. `--role` narrows it to what one
|
|
6
|
+
* role may call, which is what the HTTP transport serves that role.
|
|
7
|
+
*/
|
|
8
|
+
export interface AgentManifestOptions {
|
|
9
|
+
out?: string;
|
|
10
|
+
role?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function runAgentManifest(rootDir: string, options: AgentManifestOptions): Promise<void>;
|
package/dist/agent.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
|
+
import { inspectApp } from "./inspection.js";
|
|
4
|
+
export async function runAgentManifest(rootDir, options) {
|
|
5
|
+
const handle = await inspectApp(rootDir);
|
|
6
|
+
try {
|
|
7
|
+
const registry = handle.ctx.agent;
|
|
8
|
+
const manifest = registry.manifest(options.role);
|
|
9
|
+
const json = `${JSON.stringify(manifest, null, 2)}\n`;
|
|
10
|
+
if (options.out) {
|
|
11
|
+
const path = resolve(options.out);
|
|
12
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
13
|
+
writeFileSync(path, json);
|
|
14
|
+
console.log(`wrote ${options.out}: ${manifest.tools.length} tool(s) across ${manifest.modules.length} module(s)`);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
process.stdout.write(json);
|
|
18
|
+
}
|
|
19
|
+
if (registry.warnings.length > 0) {
|
|
20
|
+
console.error(`\n${registry.warnings.length} schema(s) could not be described:`);
|
|
21
|
+
for (const warning of registry.warnings)
|
|
22
|
+
console.error(` ! ${warning}`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
finally {
|
|
26
|
+
await handle.shutdown();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAc7C,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAAe,EAAE,OAA6B;IACnF,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;IAEzC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,KAAM,CAAC;QACnC,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACjD,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;QAEtD,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;YAChB,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAClC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9C,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,SAAS,OAAO,CAAC,GAAG,KAAK,QAAQ,CAAC,KAAK,CAAC,MAAM,mBAAmB,QAAQ,CAAC,OAAO,CAAC,MAAM,YAAY,CAAC,CAAC;QACpH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;QAED,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjC,OAAO,CAAC,KAAK,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,MAAM,oCAAoC,CAAC,CAAC;YACjF,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,QAAQ;gBAAE,OAAO,CAAC,KAAK,CAAC,OAAO,OAAO,EAAE,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;IAC1B,CAAC;AACH,CAAC"}
|
package/dist/app-core.d.ts
CHANGED
|
@@ -23,11 +23,13 @@ export declare function importFromApp<T>(rootDir: string, specifier: string): Pr
|
|
|
23
23
|
*/
|
|
24
24
|
export declare function appBoot(rootDir: string): Promise<BootFn>;
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
26
|
+
* An app's modules are TypeScript and the CLI imports them as they are:
|
|
27
|
+
* Node strips the types natively (every supported Node does), so there is
|
|
28
|
+
* no loader to register. What this checks is that the node running the
|
|
29
|
+
* CLI is one of those — a node too old to strip types would fail later,
|
|
30
|
+
* on the first module file, with a syntax error that says nothing about
|
|
31
|
+
* the cause.
|
|
32
32
|
*/
|
|
33
|
+
export declare function requireNativeTypeScript(): void;
|
|
34
|
+
/** @deprecated Since 0.11 nothing is registered; kept for callers written against 0.10. */
|
|
33
35
|
export declare function registerTypeScript(): Promise<void>;
|
package/dist/app-core.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
1
9
|
import { createRequire } from "node:module";
|
|
2
10
|
import { join } from "node:path";
|
|
3
11
|
import { pathToFileURL } from "node:url";
|
|
@@ -16,7 +24,7 @@ export async function importFromApp(rootDir, specifier) {
|
|
|
16
24
|
// whatever directory the CLI itself was installed into.
|
|
17
25
|
const requireFromApp = createRequire(join(rootDir, "package.json"));
|
|
18
26
|
const entry = requireFromApp.resolve(specifier);
|
|
19
|
-
return (await import(pathToFileURL(entry).href));
|
|
27
|
+
return (await import(__rewriteRelativeImportExtension(pathToFileURL(entry).href)));
|
|
20
28
|
}
|
|
21
29
|
catch {
|
|
22
30
|
return undefined;
|
|
@@ -39,20 +47,21 @@ export async function appBoot(rootDir) {
|
|
|
39
47
|
return module?.boot ?? bundledBoot;
|
|
40
48
|
}
|
|
41
49
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
50
|
+
* An app's modules are TypeScript and the CLI imports them as they are:
|
|
51
|
+
* Node strips the types natively (every supported Node does), so there is
|
|
52
|
+
* no loader to register. What this checks is that the node running the
|
|
53
|
+
* CLI is one of those — a node too old to strip types would fail later,
|
|
54
|
+
* on the first module file, with a syntax error that says nothing about
|
|
55
|
+
* the cause.
|
|
48
56
|
*/
|
|
49
|
-
export
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
catch {
|
|
55
|
-
// No tsx available: a compiled app still boots fine without it.
|
|
57
|
+
export function requireNativeTypeScript() {
|
|
58
|
+
const features = process.features;
|
|
59
|
+
if (!features.typescript) {
|
|
60
|
+
throw new Error(`Node ${process.versions.node} cannot run TypeScript natively — Tulipes apps need Node 24 (or 22.18+)`);
|
|
56
61
|
}
|
|
57
62
|
}
|
|
63
|
+
/** @deprecated Since 0.11 nothing is registered; kept for callers written against 0.10. */
|
|
64
|
+
export async function registerTypeScript() {
|
|
65
|
+
requireNativeTypeScript();
|
|
66
|
+
}
|
|
58
67
|
//# sourceMappingURL=app-core.js.map
|
package/dist/app-core.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-core.js","sourceRoot":"","sources":["../src/app-core.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,IAAI,IAAI,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAKzD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAI,OAAe,EAAE,SAAiB;IACvE,IAAI,CAAC;QACH,sEAAsE;QACtE,wDAAwD;QACxD,MAAM,cAAc,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC;QACpE,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAChD,OAAO,CAAC,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"app-core.js","sourceRoot":"","sources":["../src/app-core.ts"],"names":[],"mappings":";;;;;;;;AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,IAAI,IAAI,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAKzD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAI,OAAe,EAAE,SAAiB;IACvE,IAAI,CAAC;QACH,sEAAsE;QACtE,wDAAwD;QACxD,MAAM,cAAc,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC;QACpE,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAChD,OAAO,CAAC,MAAM,MAAM,kCAAC,aAAa,CAAC,KAAK,CAAC,CAAC,IAAI,EAAC,CAAM,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,OAAe;IAC3C,MAAM,MAAM,GAAG,MAAM,aAAa,CAAoB,OAAO,EAAE,oBAAoB,CAAC,CAAC;IACrF,OAAO,MAAM,EAAE,IAAI,IAAI,WAAW,CAAC;AACrC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB;IACrC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAA2C,CAAC;IACrE,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,QAAQ,OAAO,CAAC,QAAQ,CAAC,IAAI,yEAAyE,CAAC,CAAC;IAC1H,CAAC;AACH,CAAC;AAED,2FAA2F;AAC3F,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,uBAAuB,EAAE,CAAC;AAC5B,CAAC"}
|
package/dist/bin.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// Published bin entry — compiled to dist/bin.js. The dev workspace
|
|
3
|
-
//
|
|
4
|
-
// swaps
|
|
2
|
+
// Published bin entry — compiled to dist/bin.js. The dev workspace runs
|
|
3
|
+
// this source through node's native type stripping instead; publishConfig.bin
|
|
4
|
+
// swaps the compiled one in at pack time.
|
|
5
5
|
import { main } from "./main.js";
|
|
6
6
|
await main(process.argv.slice(2));
|
|
7
7
|
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,wEAAwE;AACxE,
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,wEAAwE;AACxE,8EAA8E;AAC9E,0CAA0C;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `tulipes config:check` — boot in script mode, which loads every settings
|
|
3
|
+
* namespace from the store the app declares (or core's file store) and
|
|
4
|
+
* refuses invalid stored values the way a serving process would; then
|
|
5
|
+
* print what each module runs with and exit. A deploy preflight for the
|
|
6
|
+
* settings store, the way `env:check` is one for the environment.
|
|
7
|
+
*/
|
|
8
|
+
export declare function runConfigCheck(rootDir: string): Promise<void>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { TulipesBootError } from "@tulipes/core/errors";
|
|
2
|
+
import { appBoot, requireNativeTypeScript } from "./app-core.js";
|
|
3
|
+
/**
|
|
4
|
+
* `tulipes config:check` — boot in script mode, which loads every settings
|
|
5
|
+
* namespace from the store the app declares (or core's file store) and
|
|
6
|
+
* refuses invalid stored values the way a serving process would; then
|
|
7
|
+
* print what each module runs with and exit. A deploy preflight for the
|
|
8
|
+
* settings store, the way `env:check` is one for the environment.
|
|
9
|
+
*/
|
|
10
|
+
export async function runConfigCheck(rootDir) {
|
|
11
|
+
requireNativeTypeScript();
|
|
12
|
+
const boot = await appBoot(rootDir);
|
|
13
|
+
let handle;
|
|
14
|
+
try {
|
|
15
|
+
handle = await boot({ rootDir, mode: "script", handleSignals: false });
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
if (error instanceof TulipesBootError) {
|
|
19
|
+
console.error(error.message);
|
|
20
|
+
process.exitCode = 1;
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
throw error;
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const { settings } = handle.ctx;
|
|
27
|
+
const namespaces = settings.namespaces();
|
|
28
|
+
console.log(`APP_ENV=${handle.env.appEnv} — ${namespaces.length} settings namespace(s) in ${settings.status().label}:`);
|
|
29
|
+
for (const namespace of namespaces) {
|
|
30
|
+
const description = settings.describe(namespace);
|
|
31
|
+
const { version, updated_at, updated_by } = description.stored;
|
|
32
|
+
console.log(` ✔ ${namespace} v${version} ${updated_at} by ${updated_by.label ?? updated_by.id}`);
|
|
33
|
+
for (const [field, value] of Object.entries(description.values)) {
|
|
34
|
+
const pending = description.pendingRestart.includes(field) ? " (restart pending)" : "";
|
|
35
|
+
console.log(` ${field} = ${JSON.stringify(value)}${pending}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
await handle.shutdown();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=config-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-check.js","sourceRoot":"","sources":["../src/config-check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,OAAO,EAAE,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAEjE;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAe;IAClD,uBAAuB,EAAE,CAAC;IAC1B,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IACpC,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC;IACzE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,gBAAgB,EAAE,CAAC;YACtC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC7B,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;IACD,IAAI,CAAC;QACH,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC;QAChC,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,EAAE,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,CAAC,GAAG,CAAC,MAAM,MAAM,UAAU,CAAC,MAAM,6BAA6B,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC;QACxH,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,MAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YACjD,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC;YAC/D,OAAO,CAAC,GAAG,CAAC,OAAO,SAAS,MAAM,OAAO,KAAK,UAAU,QAAQ,UAAU,CAAC,KAAK,IAAI,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;YACrG,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;gBAChE,MAAM,OAAO,GAAG,WAAW,CAAC,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,CAAC;gBACxF,OAAO,CAAC,GAAG,CAAC,SAAS,KAAK,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,OAAO,EAAE,CAAC,CAAC;YACrE,CAAC;QACH,CAAC;IACH,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;IAC1B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `tulipes config:import` — after `tulipes migrate 0.11`, carry the values a
|
|
3
|
+
* deployment kept in `.envs/.env.<APP_ENV>` for variables that became
|
|
4
|
+
* settings into the settings store, so the upgraded app boots with what
|
|
5
|
+
* it ran with. The mapping is `config/migration-0.11.json`, written by the
|
|
6
|
+
* migration; the values are validated by each module's schema before they
|
|
7
|
+
* are written, and written with the store's own versioning — through the
|
|
8
|
+
* file store the app uses by default, or the Mongo store it declares.
|
|
9
|
+
*/
|
|
10
|
+
export interface ConfigImportOptions {
|
|
11
|
+
/** APP_ENV to read and write for; default the process's APP_ENV or "development". */
|
|
12
|
+
env?: string;
|
|
13
|
+
/** An env file to read instead of `.envs/.env.<env>`. */
|
|
14
|
+
from?: string;
|
|
15
|
+
/** Print what would be written and write nothing. */
|
|
16
|
+
dryRun?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare function runConfigImport(rootDir: string, options?: ConfigImportOptions): Promise<void>;
|
|
19
|
+
/** `KEY=value` lines, quotes and inline comments removed — what dotenv reads, without dotenv. */
|
|
20
|
+
export declare function parseEnv(text: string): Record<string, string>;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
9
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
10
|
+
import { join, resolve } from "node:path";
|
|
11
|
+
import { pathToFileURL } from "node:url";
|
|
12
|
+
import { importFromApp } from "./app-core.js";
|
|
13
|
+
export async function runConfigImport(rootDir, options = {}) {
|
|
14
|
+
const appEnv = options.env ?? process.env.APP_ENV ?? "development";
|
|
15
|
+
const mappingFile = join(rootDir, "config", "migration-0.11.json");
|
|
16
|
+
if (!existsSync(mappingFile)) {
|
|
17
|
+
console.error("config/migration-0.11.json not found — run `tulipes migrate 0.11` first; it records which variables became settings");
|
|
18
|
+
process.exitCode = 2;
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const mapping = JSON.parse(readFileSync(mappingFile, "utf8"));
|
|
22
|
+
const envFile = options.from ? resolve(options.from) : join(rootDir, ".envs", `.env.${appEnv}`);
|
|
23
|
+
const values = existsSync(envFile) ? parseEnv(readFileSync(envFile, "utf8")) : {};
|
|
24
|
+
const read = (name) => process.env[name] ?? values[name];
|
|
25
|
+
if (!existsSync(envFile))
|
|
26
|
+
console.warn(`${envFile} does not exist; only process.env is read`);
|
|
27
|
+
const core = await importFromApp(rootDir, "@tulipes/core/config");
|
|
28
|
+
if (!core) {
|
|
29
|
+
console.error("@tulipes/core is not installed in this app — pnpm install first");
|
|
30
|
+
process.exitCode = 2;
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const store = await openStore(rootDir, appEnv, read, core);
|
|
34
|
+
if (!store)
|
|
35
|
+
return;
|
|
36
|
+
console.log(`store: ${store.status().label}`);
|
|
37
|
+
let written = 0;
|
|
38
|
+
try {
|
|
39
|
+
for (const [namespace, fields] of Object.entries(mapping.settings)) {
|
|
40
|
+
const configFile = join(rootDir, "modules", namespace, "module.config.ts");
|
|
41
|
+
const exported = (await import(__rewriteRelativeImportExtension(pathToFileURL(configFile).href)));
|
|
42
|
+
if (!exported.default || !core.isConfigDeclaration(exported.default)) {
|
|
43
|
+
console.error(` ${namespace}: module.config.ts does not export defineConfig({ … }); skipped`);
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
const patch = {};
|
|
47
|
+
const sources = [];
|
|
48
|
+
for (const [setting, { variable, type }] of Object.entries(fields)) {
|
|
49
|
+
const raw = read(variable);
|
|
50
|
+
if (raw === undefined)
|
|
51
|
+
continue;
|
|
52
|
+
patch[setting] = coerce(raw, type);
|
|
53
|
+
sources.push(`${setting} ← ${variable}`);
|
|
54
|
+
}
|
|
55
|
+
if (sources.length === 0) {
|
|
56
|
+
console.log(` ${namespace}: nothing set for ${Object.values(fields).map((field) => field.variable).join(", ")}; the schema defaults stay`);
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
const stored = await store.load(namespace);
|
|
60
|
+
const candidate = { ...stored?.values, ...patch };
|
|
61
|
+
const parsed = exported.default.schema.safeParse(candidate);
|
|
62
|
+
if (!parsed.success) {
|
|
63
|
+
console.error(` ${namespace}: refused by the schema — ${parsed.error?.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join("; ")}`);
|
|
64
|
+
process.exitCode = 1;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
console.log(` ${namespace}: ${sources.join(", ")}${options.dryRun ? " (dry run)" : ""}`);
|
|
68
|
+
if (options.dryRun)
|
|
69
|
+
continue;
|
|
70
|
+
await store.save(namespace, parsed.data, stored?.version ?? 0, { id: "config:import", label: `from ${envFile}` });
|
|
71
|
+
written++;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
await store.dispose?.();
|
|
76
|
+
}
|
|
77
|
+
console.log(`${written} namespace(s) written for APP_ENV=${appEnv}` + (written ? "; the variables can leave the env file now" : ""));
|
|
78
|
+
}
|
|
79
|
+
async function openStore(rootDir, appEnv, read, core) {
|
|
80
|
+
const pkg = JSON.parse(readFileSync(join(rootDir, "package.json"), "utf8"));
|
|
81
|
+
const declared = pkg.tulipes?.providers?.settings;
|
|
82
|
+
if (!declared)
|
|
83
|
+
return new core.FileSettingsStore(rootDir, appEnv);
|
|
84
|
+
if (!declared.startsWith("@tulipes/mongoose")) {
|
|
85
|
+
console.error(`the app declares settings provider "${declared}", which this command cannot write to — set the values through the console once the app runs`);
|
|
86
|
+
process.exitCode = 2;
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
const uri = read("MONGO_URI");
|
|
90
|
+
if (!uri) {
|
|
91
|
+
console.error("MONGO_URI is not set in the env file or the process; the Mongo settings store needs it");
|
|
92
|
+
process.exitCode = 2;
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
const mongoose = await importFromApp(rootDir, "mongoose");
|
|
96
|
+
const provider = await importFromApp(rootDir, "@tulipes/mongoose");
|
|
97
|
+
if (!mongoose || !provider) {
|
|
98
|
+
console.error("mongoose and @tulipes/mongoose must be installed in the app");
|
|
99
|
+
process.exitCode = 2;
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
const connection = mongoose.createConnection(uri, { serverSelectionTimeoutMS: 5_000 });
|
|
103
|
+
await connection.asPromise();
|
|
104
|
+
const store = new provider.MongoSettingsStore(connection);
|
|
105
|
+
const dispose = store.dispose?.bind(store);
|
|
106
|
+
store.dispose = async () => { await dispose?.(); await connection.close(); };
|
|
107
|
+
return store;
|
|
108
|
+
}
|
|
109
|
+
function coerce(raw, type) {
|
|
110
|
+
switch (type) {
|
|
111
|
+
case "number": return Number(raw);
|
|
112
|
+
case "boolean": return /^(1|true|yes|on)$/i.test(raw.trim());
|
|
113
|
+
default: return raw;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/** `KEY=value` lines, quotes and inline comments removed — what dotenv reads, without dotenv. */
|
|
117
|
+
export function parseEnv(text) {
|
|
118
|
+
const values = {};
|
|
119
|
+
for (const line of text.split("\n")) {
|
|
120
|
+
const match = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/.exec(line);
|
|
121
|
+
if (!match)
|
|
122
|
+
continue;
|
|
123
|
+
let value = match[2].trim();
|
|
124
|
+
const quoted = /^(["'])((?:(?!\1).)*)\1/.exec(value);
|
|
125
|
+
if (quoted)
|
|
126
|
+
value = quoted[2];
|
|
127
|
+
else
|
|
128
|
+
value = value.replace(/\s+#.*$/, "");
|
|
129
|
+
values[match[1]] = value;
|
|
130
|
+
}
|
|
131
|
+
return values;
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=config-import.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-import.js","sourceRoot":"","sources":["../src/config-import.ts"],"names":[],"mappings":"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"}
|
package/dist/dev.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `tulipes dev [entry]` — sync first (generated types must never be stale
|
|
3
|
-
* when the dev server starts), then
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* when the dev server starts), then run the entrypoint with node itself in
|
|
4
|
+
* watch mode. Node strips the types natively, so there is no loader to
|
|
5
|
+
* resolve and nothing to transpile: what runs in development is what PM2
|
|
6
|
+
* runs in production.
|
|
7
7
|
*/
|
|
8
8
|
export declare function runDev(rootDir: string, entry: string): Promise<void>;
|
package/dist/dev.js
CHANGED
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
-
import { createRequire } from "node:module";
|
|
3
|
-
import { dirname, join } from "node:path";
|
|
4
2
|
import { runSync } from "./sync.js";
|
|
3
|
+
import { requireNativeTypeScript } from "./app-core.js";
|
|
5
4
|
/**
|
|
6
5
|
* `tulipes dev [entry]` — sync first (generated types must never be stale
|
|
7
|
-
* when the dev server starts), then
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* when the dev server starts), then run the entrypoint with node itself in
|
|
7
|
+
* watch mode. Node strips the types natively, so there is no loader to
|
|
8
|
+
* resolve and nothing to transpile: what runs in development is what PM2
|
|
9
|
+
* runs in production.
|
|
11
10
|
*/
|
|
12
11
|
export async function runDev(rootDir, entry) {
|
|
12
|
+
requireNativeTypeScript();
|
|
13
13
|
await runSync(rootDir);
|
|
14
|
-
const
|
|
15
|
-
const tsxPackage = require.resolve("tsx/package.json");
|
|
16
|
-
const tsxCli = join(dirname(tsxPackage), "dist", "cli.mjs");
|
|
17
|
-
const child = spawn(process.execPath, [tsxCli, "watch", "--clear-screen=false", entry], { cwd: rootDir, stdio: "inherit" });
|
|
14
|
+
const child = spawn(process.execPath, ["--watch", "--watch-preserve-output", entry], { cwd: rootDir, stdio: "inherit" });
|
|
18
15
|
child.on("exit", (code) => {
|
|
19
16
|
process.exitCode = code ?? 0;
|
|
20
17
|
});
|
package/dist/dev.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../src/dev.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../src/dev.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAExD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,OAAe,EAAE,KAAa;IACzD,uBAAuB,EAAE,CAAC;IAC1B,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAEvB,MAAM,KAAK,GAAG,KAAK,CACjB,OAAO,CAAC,QAAQ,EAChB,CAAC,SAAS,EAAE,yBAAyB,EAAE,KAAK,CAAC,EAC7C,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CACnC,CAAC;IACF,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;QACxB,OAAO,CAAC,QAAQ,GAAG,IAAI,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/init.d.ts
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `tulipes init [dir]` — scaffold a complete application
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* a queue with its processor, and a socket namespace.
|
|
9
|
-
*
|
|
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.
|
|
2
|
+
* `tulipes init [dir]` — scaffold a complete application from a template
|
|
3
|
+
* tree. The production preset is the reference application the framework
|
|
4
|
+
* is developed against, copied verbatim and transformed only in the ways
|
|
5
|
+
* `template.ts` lists; the minimal preset is a three-module API with no
|
|
6
|
+
* infrastructure. Neither is rendered from strings, so what this command
|
|
7
|
+
* writes and what the repository tests are the same files.
|
|
13
8
|
*/
|
|
14
9
|
export type InitPreset = "minimal" | "production";
|
|
15
10
|
/**
|