@daloyjs/core 1.0.0-rc.1 → 1.0.0-rc.2
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 +5 -5
- package/bin/daloy.mjs +38 -10
- package/dist/cli.d.ts +5 -2
- package/dist/cli.js +9 -5
- package/dist/sbom.cdx.json +9 -9
- package/dist/sbom.spdx.json +5 -5
- package/dist/types.d.ts +4 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -211,7 +211,7 @@ That single command runs the two scripts:
|
|
|
211
211
|
```jsonc
|
|
212
212
|
// package.json
|
|
213
213
|
"scripts": {
|
|
214
|
-
"gen:openapi": "node
|
|
214
|
+
"gen:openapi": "node scripts/dump-openapi.ts",
|
|
215
215
|
"gen:client": "openapi-ts",
|
|
216
216
|
"gen": "pnpm gen:openapi && pnpm gen:client"
|
|
217
217
|
}
|
|
@@ -339,11 +339,11 @@ const app = createApp({ docs: true });
|
|
|
339
339
|
|
|
340
340
|
| Runtime | Spawned command |
|
|
341
341
|
| ------- | --------------------------------------------------------------- |
|
|
342
|
-
| Node | `node --
|
|
342
|
+
| Node | `node --watch <entry>` |
|
|
343
343
|
| Bun | `bun --hot <entry>` |
|
|
344
344
|
| Deno | `deno run --watch --allow-net --allow-env --allow-read <entry>` |
|
|
345
345
|
|
|
346
|
-
Entry defaults to `src/index.ts`, `src/main.ts`, `src/server.ts`, or `src/app.ts`.
|
|
346
|
+
Entry defaults to `src/index.ts`, `src/main.ts`, `src/server.ts`, or `src/app.ts`. Node.js (>= 22.18) runs TypeScript entries natively via built-in type stripping — no loader needed. Projects that rely on non-erasable syntax (enums, runtime namespaces, parameter properties) or extensionless relative imports can keep using a loader directly, e.g. `node --import tsx --watch <entry>` (and `daloy inspect` falls back to `tsx` automatically when the native load fails and `tsx` is installed).
|
|
347
347
|
|
|
348
348
|
Pass `--runtime <node|bun|deno>` to override runtime detection. This is required when running `daloy dev` from a `package.json` script on Bun or Deno, because the CLI binary's `#!/usr/bin/env node` shebang otherwise forces Node detection. The `bun-basic` template ships `"dev": "daloy dev --runtime bun"` for this reason.
|
|
349
349
|
|
|
@@ -509,7 +509,7 @@ The core only ever sees `Request → Response`. Adapters live at the edge.
|
|
|
509
509
|
|
|
510
510
|
## Status
|
|
511
511
|
|
|
512
|
-
DaloyJS is at **`1.0.0-rc.
|
|
512
|
+
DaloyJS is at **`1.0.0-rc.2`**, a security-hardening release candidate. Because the framework has no external users yet, this RC ships a few intentional breaking changes (see the [CHANGELOG](CHANGELOG.md)) to get the secure-by-default posture right before GA rather than deferring them; the generated OpenAPI contract is unchanged. From `1.0.0` GA onward, breaking changes follow SemVer with deprecations getting at least one minor cycle. The framework is already in use for production trials.
|
|
513
513
|
|
|
514
514
|
**Release quality bar.** Every release ships with **≥90% line + function coverage and ≥90% branch coverage**, strict TypeScript, OpenSSF Scorecard, CodeQL + Opengrep dual SAST, zizmor workflow linting, and npm provenance. Coverage was relaxed from a former 100% gate so complex security work isn't blocked chasing throwaway tests for unreachable defensive branches or tsx source-map phantoms; see [AGENTS.md](AGENTS.md) for the policy.
|
|
515
515
|
|
|
@@ -527,7 +527,7 @@ DaloyJS is at **`1.0.0-rc.1`**, a security-hardening release candidate. Because
|
|
|
527
527
|
### Runtimes and deployment
|
|
528
528
|
|
|
529
529
|
- Adapters for Node (Heroku, Railway, Render, Fly.io), Bun, Deno, Cloudflare Workers, Vercel Node / Edge / Next.js / Netlify Edge, Fastly Compute, and AWS Lambda / Netlify Functions / Lambda Function URLs.
|
|
530
|
-
- `daloy dev` watch loop delegates to the host runtime's native watcher (`node --
|
|
530
|
+
- `daloy dev` watch loop delegates to the host runtime's native watcher (`node --watch`, `bun --hot`, or `deno run --watch`) with a `--runtime` override for cross-runtime `package.json` scripts.
|
|
531
531
|
- `pnpm create daloy` scaffolder with Node, Bun, Deno, Cloudflare Worker, and Vercel templates, plus optional `--with-ci` GitHub Actions / Dependabot / CODEOWNERS / SECURITY.md hardening. The completion summary surfaces official install links (nodejs.org, pnpm.io, bun.sh) for any runtime or package manager your selections need but that is missing from `PATH`, and skips a doomed dependency install when the chosen package manager is absent.
|
|
532
532
|
- Container-first templates: `HEALTHCHECK` to `/readyz`, `STOPSIGNAL SIGTERM`, non-root user, `tini` as PID 1.
|
|
533
533
|
- Generated `deploy.yml` for container templates signs every pushed GHCR image with **Sigstore Cosign** (keyless OIDC) and attaches an **SPDX SBOM attestation** so consumers can `cosign verify` and `cosign verify-attestation --type spdxjson` instead of trusting the registry alone.
|
package/bin/daloy.mjs
CHANGED
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* `daloy` CLI shim. Real logic lives in `dist/cli.js` (`src/cli.ts`).
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* TypeScript entry files are imported directly — Node.js >= 22.18 strips
|
|
6
|
+
* erasable TypeScript syntax natively. If the native load fails (older
|
|
7
|
+
* Node, non-erasable syntax such as enums, or extensionless relative
|
|
8
|
+
* imports) we fall back to registering `tsx` when the consumer project has
|
|
9
|
+
* it installed; otherwise we surface a friendly error.
|
|
8
10
|
*/
|
|
9
11
|
|
|
10
12
|
import { pathToFileURL, fileURLToPath } from "node:url";
|
|
@@ -20,17 +22,33 @@ const PKG = JSON.parse(
|
|
|
20
22
|
|
|
21
23
|
const TS_EXT = /\.(ts|tsx|mts|cts)$/i;
|
|
22
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Error codes that mean the host Node.js could not load a TypeScript file
|
|
27
|
+
* natively — the cases where falling back to a transpiling loader (tsx)
|
|
28
|
+
* can still succeed.
|
|
29
|
+
*/
|
|
30
|
+
const NATIVE_TS_ERROR_CODES = new Set([
|
|
31
|
+
// Type stripping disabled (--no-strip-types) or Node too old.
|
|
32
|
+
"ERR_UNKNOWN_FILE_EXTENSION",
|
|
33
|
+
// Non-erasable syntax: enums, runtime namespaces, parameter properties.
|
|
34
|
+
"ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX",
|
|
35
|
+
// Extensionless relative imports that native stripping refuses to resolve.
|
|
36
|
+
"ERR_MODULE_NOT_FOUND",
|
|
37
|
+
]);
|
|
38
|
+
|
|
23
39
|
let tsxRegistered = false;
|
|
24
|
-
async function
|
|
25
|
-
if (!TS_EXT.test(specifier) || tsxRegistered) return;
|
|
40
|
+
async function registerTsxFallback(specifier, cause) {
|
|
26
41
|
try {
|
|
27
42
|
const api = await import("tsx/esm/api");
|
|
28
43
|
api.register();
|
|
29
44
|
tsxRegistered = true;
|
|
30
45
|
} catch {
|
|
31
46
|
throw new Error(
|
|
32
|
-
`Loading TypeScript entry "${specifier}"
|
|
33
|
-
|
|
47
|
+
`Loading TypeScript entry "${specifier}" failed: ${cause?.message ?? cause}\n` +
|
|
48
|
+
"Node.js runs erasable-only TypeScript natively (>= 22.18). If the entry uses " +
|
|
49
|
+
"non-erasable syntax (enums, runtime namespaces, parameter properties) or " +
|
|
50
|
+
"extensionless relative imports, install tsx (`pnpm add -D tsx`) and re-run.",
|
|
51
|
+
{ cause }
|
|
34
52
|
);
|
|
35
53
|
}
|
|
36
54
|
}
|
|
@@ -40,8 +58,18 @@ async function importEntry(specifier) {
|
|
|
40
58
|
if (!existsSync(abs)) {
|
|
41
59
|
throw new Error(`Entry file not found: ${abs}`);
|
|
42
60
|
}
|
|
43
|
-
|
|
44
|
-
|
|
61
|
+
const href = pathToFileURL(abs).href;
|
|
62
|
+
if (!TS_EXT.test(abs) || tsxRegistered) return import(href);
|
|
63
|
+
try {
|
|
64
|
+
return await import(href);
|
|
65
|
+
} catch (err) {
|
|
66
|
+
if (!NATIVE_TS_ERROR_CODES.has(err?.code)) throw err;
|
|
67
|
+
await registerTsxFallback(abs, err);
|
|
68
|
+
// Cache-bust so the retried load resolves through tsx's hooks instead of
|
|
69
|
+
// the failed native module job. The first attempt failed before
|
|
70
|
+
// evaluation, so no side effects ran twice.
|
|
71
|
+
return import(`${href}?daloy-tsx-fallback=1`);
|
|
72
|
+
}
|
|
45
73
|
}
|
|
46
74
|
|
|
47
75
|
function spawnDev(command, args) {
|
|
@@ -62,7 +90,7 @@ function spawnDev(command, args) {
|
|
|
62
90
|
new Error(
|
|
63
91
|
`\`${command}\` was not found on PATH. ` +
|
|
64
92
|
(command === "node"
|
|
65
|
-
? "
|
|
93
|
+
? "Ensure Node.js is on PATH."
|
|
66
94
|
: `Install ${command} or run daloy dev from the runtime that hosts it.`)
|
|
67
95
|
)
|
|
68
96
|
);
|
package/dist/cli.d.ts
CHANGED
|
@@ -130,8 +130,11 @@ export declare function normalizeEntryArg(entry: string): string;
|
|
|
130
130
|
* runtime and entry file. Pure function so tests can assert exact argv
|
|
131
131
|
* without spawning a child process.
|
|
132
132
|
*
|
|
133
|
-
* - Node: `node --
|
|
134
|
-
*
|
|
133
|
+
* - Node: `node --watch <entry>` (Node >= 22.18 strips TypeScript types
|
|
134
|
+
* natively, so `.ts` entries with erasable-only syntax run without a
|
|
135
|
+
* loader; `.js` entries also work. Projects that need non-erasable
|
|
136
|
+
* syntax — enums, runtime namespaces, parameter properties — should
|
|
137
|
+
* transpile or add a loader such as tsx themselves).
|
|
135
138
|
* - Bun: `bun --hot <entry>` (Bun ships with TS support).
|
|
136
139
|
* - Deno: `deno run --watch --allow-net --allow-env --allow-read <entry>`
|
|
137
140
|
* (the three permissions cover serving HTTP, reading env vars, and
|
package/dist/cli.js
CHANGED
|
@@ -22,8 +22,9 @@ Usage:
|
|
|
22
22
|
Commands:
|
|
23
23
|
inspect [entry] Load an App and print its routes (default command).
|
|
24
24
|
dev [entry] Start the entry file with the host runtime's
|
|
25
|
-
native watch mode (
|
|
26
|
-
Bun, --watch on Deno).
|
|
25
|
+
native watch mode (node --watch on Node, --hot on
|
|
26
|
+
Bun, --watch on Deno). Node runs TypeScript
|
|
27
|
+
entries via its built-in type stripping.
|
|
27
28
|
doctor [entry] Audit a loaded App's secure-by-default posture.
|
|
28
29
|
Exits non-zero on any violation so the
|
|
29
30
|
command can guard container HEALTHCHECK and CI
|
|
@@ -186,8 +187,11 @@ export function normalizeEntryArg(entry) {
|
|
|
186
187
|
* runtime and entry file. Pure function so tests can assert exact argv
|
|
187
188
|
* without spawning a child process.
|
|
188
189
|
*
|
|
189
|
-
* - Node: `node --
|
|
190
|
-
*
|
|
190
|
+
* - Node: `node --watch <entry>` (Node >= 22.18 strips TypeScript types
|
|
191
|
+
* natively, so `.ts` entries with erasable-only syntax run without a
|
|
192
|
+
* loader; `.js` entries also work. Projects that need non-erasable
|
|
193
|
+
* syntax — enums, runtime namespaces, parameter properties — should
|
|
194
|
+
* transpile or add a loader such as tsx themselves).
|
|
191
195
|
* - Bun: `bun --hot <entry>` (Bun ships with TS support).
|
|
192
196
|
* - Deno: `deno run --watch --allow-net --allow-env --allow-read <entry>`
|
|
193
197
|
* (the three permissions cover serving HTTP, reading env vars, and
|
|
@@ -219,7 +223,7 @@ export function buildDevCommand(runtime, entry) {
|
|
|
219
223
|
};
|
|
220
224
|
case "node":
|
|
221
225
|
default:
|
|
222
|
-
return { command: "node", args: ["--
|
|
226
|
+
return { command: "node", args: ["--watch", safe] };
|
|
223
227
|
}
|
|
224
228
|
}
|
|
225
229
|
/**
|
package/dist/sbom.cdx.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"bomFormat": "CycloneDX",
|
|
3
3
|
"specVersion": "1.5",
|
|
4
|
-
"serialNumber": "urn:uuid:
|
|
4
|
+
"serialNumber": "urn:uuid:8448de36-3a72-553d-882f-b5b36bbd1426",
|
|
5
5
|
"version": 1,
|
|
6
6
|
"metadata": {
|
|
7
|
-
"timestamp": "2026-07-
|
|
7
|
+
"timestamp": "2026-07-07T09:24:36.816Z",
|
|
8
8
|
"tools": [
|
|
9
9
|
{
|
|
10
10
|
"vendor": "DaloyJS",
|
|
11
11
|
"name": "daloy-generate-sbom",
|
|
12
|
-
"version": "1.0.0-rc.
|
|
12
|
+
"version": "1.0.0-rc.2"
|
|
13
13
|
}
|
|
14
14
|
],
|
|
15
15
|
"authors": [
|
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
],
|
|
20
20
|
"component": {
|
|
21
21
|
"type": "library",
|
|
22
|
-
"bom-ref": "pkg:npm/@daloyjs/core@1.0.0-rc.
|
|
22
|
+
"bom-ref": "pkg:npm/@daloyjs/core@1.0.0-rc.2",
|
|
23
23
|
"name": "@daloyjs/core",
|
|
24
|
-
"version": "1.0.0-rc.
|
|
24
|
+
"version": "1.0.0-rc.2",
|
|
25
25
|
"description": "DaloyJS is a runtime-portable, contract-first TypeScript web framework with built-in OpenAPI (Hey API), typed client generation, large-scale maintainability, and security-first defaults. Hono-grade portability, Elysia-grade DX, FastAPI-grade docs, Fastify-grade ops — distributed via pnpm.",
|
|
26
|
-
"purl": "pkg:npm/@daloyjs/core@1.0.0-rc.
|
|
26
|
+
"purl": "pkg:npm/@daloyjs/core@1.0.0-rc.2",
|
|
27
27
|
"licenses": [
|
|
28
28
|
{
|
|
29
29
|
"license": {
|
|
@@ -46,9 +46,9 @@
|
|
|
46
46
|
}
|
|
47
47
|
],
|
|
48
48
|
"swid": {
|
|
49
|
-
"tagId": "swidtag--daloyjs-core-1.0.0-rc.
|
|
49
|
+
"tagId": "swidtag--daloyjs-core-1.0.0-rc.2",
|
|
50
50
|
"name": "@daloyjs/core",
|
|
51
|
-
"version": "1.0.0-rc.
|
|
51
|
+
"version": "1.0.0-rc.2",
|
|
52
52
|
"tagVersion": 0,
|
|
53
53
|
"patch": false
|
|
54
54
|
}
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"components": [],
|
|
58
58
|
"dependencies": [
|
|
59
59
|
{
|
|
60
|
-
"ref": "pkg:npm/@daloyjs/core@1.0.0-rc.
|
|
60
|
+
"ref": "pkg:npm/@daloyjs/core@1.0.0-rc.2",
|
|
61
61
|
"dependsOn": []
|
|
62
62
|
}
|
|
63
63
|
]
|
package/dist/sbom.spdx.json
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"spdxVersion": "SPDX-2.3",
|
|
3
3
|
"dataLicense": "CC0-1.0",
|
|
4
4
|
"SPDXID": "SPDXRef-DOCUMENT",
|
|
5
|
-
"name": "@daloyjs/core-1.0.0-rc.
|
|
6
|
-
"documentNamespace": "https://github.com/daloyjs/daloy/sbom/@daloyjs/core-1.0.0-rc.
|
|
5
|
+
"name": "@daloyjs/core-1.0.0-rc.2",
|
|
6
|
+
"documentNamespace": "https://github.com/daloyjs/daloy/sbom/@daloyjs/core-1.0.0-rc.2-8448de36-3a72-553d-882f-b5b36bbd1426",
|
|
7
7
|
"creationInfo": {
|
|
8
|
-
"created": "2026-07-
|
|
8
|
+
"created": "2026-07-07T09:24:36.816Z",
|
|
9
9
|
"creators": [
|
|
10
10
|
"Tool: daloy-generate-sbom",
|
|
11
11
|
"Organization: DaloyJS"
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
{
|
|
17
17
|
"SPDXID": "SPDXRef-Package--daloyjs-core",
|
|
18
18
|
"name": "@daloyjs/core",
|
|
19
|
-
"versionInfo": "1.0.0-rc.
|
|
19
|
+
"versionInfo": "1.0.0-rc.2",
|
|
20
20
|
"downloadLocation": "https://github.com/daloyjs/daloy",
|
|
21
21
|
"filesAnalyzed": false,
|
|
22
22
|
"licenseConcluded": "MIT",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
{
|
|
28
28
|
"referenceCategory": "PACKAGE-MANAGER",
|
|
29
29
|
"referenceType": "purl",
|
|
30
|
-
"referenceLocator": "pkg:npm/@daloyjs/core@1.0.0-rc.
|
|
30
|
+
"referenceLocator": "pkg:npm/@daloyjs/core@1.0.0-rc.2"
|
|
31
31
|
}
|
|
32
32
|
]
|
|
33
33
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -199,7 +199,10 @@ export interface AuthSpec {
|
|
|
199
199
|
*
|
|
200
200
|
* @example
|
|
201
201
|
* ```ts
|
|
202
|
-
* //
|
|
202
|
+
* // Put this in a regular module the compiler always checks (e.g. the
|
|
203
|
+
* // plugin file that calls `app.decorate(...)`). Avoid a separate .d.ts:
|
|
204
|
+
* // `skipLibCheck` skips declaration files, so a broken import there
|
|
205
|
+
* // silently types the state value as `any`.
|
|
203
206
|
* declare module "@daloyjs/core" {
|
|
204
207
|
* interface AppState {
|
|
205
208
|
* user: { id: string; roles: string[] };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@daloyjs/core",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.2",
|
|
4
4
|
"description": "DaloyJS is a runtime-portable, contract-first TypeScript web framework with built-in OpenAPI (Hey API), typed client generation, large-scale maintainability, and security-first defaults. Hono-grade portability, Elysia-grade DX, FastAPI-grade docs, Fastify-grade ops — distributed via pnpm.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|