@daloyjs/core 1.0.0-rc.2 → 1.0.0-rc.3
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 +7 -1
- package/dist/adapters/vercel.d.ts +8 -10
- package/dist/adapters/vercel.js +0 -2
- package/dist/app.d.ts +19 -0
- package/dist/app.js +51 -4
- package/dist/sbom.cdx.json +9 -9
- package/dist/sbom.spdx.json +5 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -28,6 +28,12 @@ Disclosure](https://img.shields.io/badge/Security-Responsible%20Disclosure-yello
|
|
|
28
28
|
|
|
29
29
|
DaloyJS is maintained in the GitHub organization at <https://github.com/daloyjs>; the canonical framework repository is <https://github.com/daloyjs/daloy>.
|
|
30
30
|
|
|
31
|
+
## Partners
|
|
32
|
+
|
|
33
|
+
<a href="https://snyk.io">
|
|
34
|
+
<img src="https://github.com/user-attachments/assets/da58db43-67cc-45d4-ade5-bdaa7b041465" alt="Snyk's Secure Developer Program" width="160">
|
|
35
|
+
</a>
|
|
36
|
+
|
|
31
37
|
---
|
|
32
38
|
|
|
33
39
|
## Built for the vibe-coding era
|
|
@@ -509,7 +515,7 @@ The core only ever sees `Request → Response`. Adapters live at the edge.
|
|
|
509
515
|
|
|
510
516
|
## Status
|
|
511
517
|
|
|
512
|
-
DaloyJS is at **`1.0.0-rc.
|
|
518
|
+
DaloyJS is at **`1.0.0-rc.3`**, a security-hardening release candidate. Because the framework has no external users yet, this RC makes a few intentional 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, the API follows SemVer with deprecations getting at least one minor cycle. The framework is already in use for production trials.
|
|
513
519
|
|
|
514
520
|
**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
521
|
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Vercel / web-standard handler.
|
|
3
3
|
*
|
|
4
|
-
* Vercel
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* Vercel recommends the Node.js runtime for new functions (it runs on Fluid
|
|
5
|
+
* Compute with full Node APIs) and has deprecated standalone Edge Functions.
|
|
6
|
+
* The runtime is web-standard, but the export shape differs by integration:
|
|
7
|
+
* Node `/api` functions use a default `{ fetch }` object, App Router route
|
|
8
|
+
* handlers use named method exports, and the deprecated Edge runtime expects a
|
|
9
|
+
* bare function export — {@link toWebHandler} — plus `export const runtime =
|
|
10
|
+
* "edge"`.
|
|
9
11
|
*
|
|
10
|
-
* // Vercel Functions (`api/[...path].ts`)
|
|
12
|
+
* // Vercel Functions (`api/[...path].ts`) — recommended
|
|
11
13
|
* import { toFetchHandler } from "@daloyjs/core/vercel";
|
|
12
14
|
* export default toFetchHandler(app);
|
|
13
15
|
*
|
|
@@ -15,8 +17,6 @@
|
|
|
15
17
|
* import { toRouteHandlers } from "@daloyjs/core/vercel";
|
|
16
18
|
* export const { GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD } =
|
|
17
19
|
* toRouteHandlers(app);
|
|
18
|
-
*
|
|
19
|
-
* `toEdgeHandler` is kept as a backward-compatible alias of `toWebHandler`.
|
|
20
20
|
*/
|
|
21
21
|
import type { App } from "../app.js";
|
|
22
22
|
/** Web-standard handler shape used by Vercel Functions, Next.js route handlers, and middleware. */
|
|
@@ -44,8 +44,6 @@ export declare function toWebHandler(app: App): WebHandler;
|
|
|
44
44
|
* @returns A {@link FetchHandler} object suitable as the module's `export default`.
|
|
45
45
|
*/
|
|
46
46
|
export declare function toFetchHandler(app: App): FetchHandler;
|
|
47
|
-
/** Backward-compatible alias for {@link toWebHandler}. */
|
|
48
|
-
export declare const toEdgeHandler: typeof toWebHandler;
|
|
49
47
|
/**
|
|
50
48
|
* Build the `{ GET, POST, ... }` object expected by Next.js App Router
|
|
51
49
|
* `route.ts` files when a DaloyJS app is mounted inside an existing Next app.
|
package/dist/adapters/vercel.js
CHANGED
|
@@ -18,8 +18,6 @@ export function toWebHandler(app) {
|
|
|
18
18
|
export function toFetchHandler(app) {
|
|
19
19
|
return { fetch: toWebHandler(app) };
|
|
20
20
|
}
|
|
21
|
-
/** Backward-compatible alias for {@link toWebHandler}. */
|
|
22
|
-
export const toEdgeHandler = toWebHandler;
|
|
23
21
|
/**
|
|
24
22
|
* Build the `{ GET, POST, ... }` object expected by Next.js App Router
|
|
25
23
|
* `route.ts` files when a DaloyJS app is mounted inside an existing Next app.
|
package/dist/app.d.ts
CHANGED
|
@@ -1401,6 +1401,25 @@ export declare class App<Routes extends readonly RouteDefinition<any, any, any,
|
|
|
1401
1401
|
* });
|
|
1402
1402
|
* ```
|
|
1403
1403
|
*
|
|
1404
|
+
* ### Scoping (Fastify-style encapsulation)
|
|
1405
|
+
*
|
|
1406
|
+
* Decorations are **scoped to the app instance they are declared on**, and
|
|
1407
|
+
* are captured per route at registration time:
|
|
1408
|
+
*
|
|
1409
|
+
* - Calling `decorate()` on the root app makes the value visible to every
|
|
1410
|
+
* route, including routes inside plugins/groups registered *afterwards*
|
|
1411
|
+
* (app-level decorations flow inward).
|
|
1412
|
+
* - Calling `decorate()` on the child app passed to {@link App.register} /
|
|
1413
|
+
* {@link App.group} scopes the value to **that plugin's routes only** — it
|
|
1414
|
+
* does not leak to sibling plugins or back to the root.
|
|
1415
|
+
*
|
|
1416
|
+
* Each route binds to its scope's decorations when it is registered, so
|
|
1417
|
+
* **decorate before registering the routes that consume the value** (the same
|
|
1418
|
+
* ordering Fastify requires). Adding a decoration to a scope that already had
|
|
1419
|
+
* at least one is picked up by that scope's existing routes; but the first
|
|
1420
|
+
* decoration added to a scope *after* its routes were registered will not
|
|
1421
|
+
* reach them.
|
|
1422
|
+
*
|
|
1404
1423
|
* @param key - Property name on `ctx.state`.
|
|
1405
1424
|
* @param value - Value bound to that property on every request.
|
|
1406
1425
|
* @param opts - Pass `{ override: true }` to replace an existing decoration (logged as a warning).
|
package/dist/app.js
CHANGED
|
@@ -1433,7 +1433,22 @@ export class App {
|
|
|
1433
1433
|
...corsOriginAllows,
|
|
1434
1434
|
];
|
|
1435
1435
|
const securityMarkers = securityMarkersFromHooks([globalHookLayer, ...sources]);
|
|
1436
|
-
|
|
1436
|
+
// Capture the decorations of this route's scope at registration time so the
|
|
1437
|
+
// dispatch hot path reads the scope-local bag rather than the root app's.
|
|
1438
|
+
// `this.decorations` is this scope's own bag (the root's, or the child's
|
|
1439
|
+
// copy created in `group()`), so plugin-local decorations never leak to
|
|
1440
|
+
// sibling plugins or the root. `undefined` when empty keeps the per-request
|
|
1441
|
+
// `Object.assign` skipped for the common no-decoration case.
|
|
1442
|
+
const decorations = this.decorationsCount === 0 ? undefined : this.decorations;
|
|
1443
|
+
this.router.add(def.method, fullPath, {
|
|
1444
|
+
def: merged,
|
|
1445
|
+
hooks,
|
|
1446
|
+
mergedHooks,
|
|
1447
|
+
hasFinalizeHook,
|
|
1448
|
+
corsOriginAllows,
|
|
1449
|
+
fullCorsOriginAllows,
|
|
1450
|
+
decorations,
|
|
1451
|
+
}, def.operationId);
|
|
1437
1452
|
// `routes` is statically a readonly tuple so the typed client can infer
|
|
1438
1453
|
// per-route methods; at runtime it is a growable array, so we push through
|
|
1439
1454
|
// a mutable view.
|
|
@@ -1946,7 +1961,15 @@ export class App {
|
|
|
1946
1961
|
child.corsOriginAllows = corsOriginAllowsFromHooks(child.groupHooks);
|
|
1947
1962
|
child.groupTags = [...this.groupTags, ...(config.tags ?? [])];
|
|
1948
1963
|
child.groupAuth = config.auth ?? this.groupAuth;
|
|
1949
|
-
|
|
1964
|
+
// Encapsulate decorations (Fastify-style): the child gets its OWN bag
|
|
1965
|
+
// seeded with a copy of the parent's current decorations. App-level
|
|
1966
|
+
// decorations therefore flow inward, while `child.decorate()` mutates only
|
|
1967
|
+
// this copy — it never leaks back to the parent or sideways to sibling
|
|
1968
|
+
// plugins (each sibling copies the parent bag at its own registration).
|
|
1969
|
+
// Routes snapshot this bag in `route()`; the shared reference used before
|
|
1970
|
+
// made decorators app-global instead of scoped.
|
|
1971
|
+
child.decorations = { ...this.decorations };
|
|
1972
|
+
child.decorationsCount = this.decorationsCount;
|
|
1950
1973
|
child.installedPlugins = this.installedPlugins;
|
|
1951
1974
|
child.closeHooks = this.closeHooks;
|
|
1952
1975
|
child.idleConnectionCloseHooks = this.idleConnectionCloseHooks;
|
|
@@ -2032,6 +2055,25 @@ export class App {
|
|
|
2032
2055
|
* });
|
|
2033
2056
|
* ```
|
|
2034
2057
|
*
|
|
2058
|
+
* ### Scoping (Fastify-style encapsulation)
|
|
2059
|
+
*
|
|
2060
|
+
* Decorations are **scoped to the app instance they are declared on**, and
|
|
2061
|
+
* are captured per route at registration time:
|
|
2062
|
+
*
|
|
2063
|
+
* - Calling `decorate()` on the root app makes the value visible to every
|
|
2064
|
+
* route, including routes inside plugins/groups registered *afterwards*
|
|
2065
|
+
* (app-level decorations flow inward).
|
|
2066
|
+
* - Calling `decorate()` on the child app passed to {@link App.register} /
|
|
2067
|
+
* {@link App.group} scopes the value to **that plugin's routes only** — it
|
|
2068
|
+
* does not leak to sibling plugins or back to the root.
|
|
2069
|
+
*
|
|
2070
|
+
* Each route binds to its scope's decorations when it is registered, so
|
|
2071
|
+
* **decorate before registering the routes that consume the value** (the same
|
|
2072
|
+
* ordering Fastify requires). Adding a decoration to a scope that already had
|
|
2073
|
+
* at least one is picked up by that scope's existing routes; but the first
|
|
2074
|
+
* decoration added to a scope *after* its routes were registered will not
|
|
2075
|
+
* reach them.
|
|
2076
|
+
*
|
|
2035
2077
|
* @param key - Property name on `ctx.state`.
|
|
2036
2078
|
* @param value - Value bound to that property on every request.
|
|
2037
2079
|
* @param opts - Pass `{ override: true }` to replace an existing decoration (logged as a warning).
|
|
@@ -2466,8 +2508,13 @@ export class App {
|
|
|
2466
2508
|
const state = ctx.state;
|
|
2467
2509
|
state.requestId = requestId;
|
|
2468
2510
|
state.log = log;
|
|
2469
|
-
|
|
2470
|
-
|
|
2511
|
+
// Apply the decorations captured for THIS route's scope (see
|
|
2512
|
+
// `CompiledRoute.decorations`) rather than the root app's bag, so a
|
|
2513
|
+
// plugin's decorations reach only that plugin's routes. `undefined` when
|
|
2514
|
+
// the scope had none keeps the common case allocation-free.
|
|
2515
|
+
const routeDecorations = match.handler.decorations;
|
|
2516
|
+
if (routeDecorations !== undefined)
|
|
2517
|
+
Object.assign(state, routeDecorations);
|
|
2471
2518
|
if (allHooks.beforeHandle !== undefined) {
|
|
2472
2519
|
const beforeResult = allHooks.beforeHandle(ctx);
|
|
2473
2520
|
const before = isPromiseLike(beforeResult) ? await beforeResult : beforeResult;
|
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:50e7cfc8-73fe-5f9a-96b0-38df20d401b5",
|
|
5
5
|
"version": 1,
|
|
6
6
|
"metadata": {
|
|
7
|
-
"timestamp": "2026-07-
|
|
7
|
+
"timestamp": "2026-07-09T19:29:34.036Z",
|
|
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.3"
|
|
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.3",
|
|
23
23
|
"name": "@daloyjs/core",
|
|
24
|
-
"version": "1.0.0-rc.
|
|
24
|
+
"version": "1.0.0-rc.3",
|
|
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.3",
|
|
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.3",
|
|
50
50
|
"name": "@daloyjs/core",
|
|
51
|
-
"version": "1.0.0-rc.
|
|
51
|
+
"version": "1.0.0-rc.3",
|
|
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.3",
|
|
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.3",
|
|
6
|
+
"documentNamespace": "https://github.com/daloyjs/daloy/sbom/@daloyjs/core-1.0.0-rc.3-50e7cfc8-73fe-5f9a-96b0-38df20d401b5",
|
|
7
7
|
"creationInfo": {
|
|
8
|
-
"created": "2026-07-
|
|
8
|
+
"created": "2026-07-09T19:29:34.036Z",
|
|
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.3",
|
|
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.3"
|
|
31
31
|
}
|
|
32
32
|
]
|
|
33
33
|
}
|
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.3",
|
|
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": {
|