@timber-js/app 0.2.0-alpha.101 → 0.2.0-alpha.102
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/dist/_chunks/{actions-BsfxK6yu.js → actions-n9qTlpmY.js} +7 -10
- package/dist/_chunks/actions-n9qTlpmY.js.map +1 -0
- package/dist/_chunks/{build-output-helper-DXnW0qjz.js → build-output-helper-5TK2Emwp.js} +1 -1
- package/dist/_chunks/{build-output-helper-DXnW0qjz.js.map → build-output-helper-5TK2Emwp.js.map} +1 -1
- package/dist/_chunks/{define-k32T6NL2.js → define-Btmz9B20.js} +3 -3
- package/dist/_chunks/{define-k32T6NL2.js.map → define-Btmz9B20.js.map} +1 -1
- package/dist/_chunks/{define-B-Q_UMOD.js → define-Dn98bPbb.js} +3 -3
- package/dist/_chunks/{define-B-Q_UMOD.js.map → define-Dn98bPbb.js.map} +1 -1
- package/dist/_chunks/{format-Bcn-Iv1x.js → format-CYBGxKtc.js} +1 -1
- package/dist/_chunks/{format-Bcn-Iv1x.js.map → format-CYBGxKtc.js.map} +1 -1
- package/dist/_chunks/{handler-store-B-lqaGyh.js → handler-store-B_df5Npe.js} +1 -1
- package/dist/_chunks/{handler-store-B-lqaGyh.js.map → handler-store-B_df5Npe.js.map} +1 -1
- package/dist/_chunks/{logger-0m8MsKdc.js → logger-DDmK5skc.js} +2 -2
- package/dist/_chunks/{logger-0m8MsKdc.js.map → logger-DDmK5skc.js.map} +1 -1
- package/dist/_chunks/merge-search-params-Cm_KIWDX.js +41 -0
- package/dist/_chunks/merge-search-params-Cm_KIWDX.js.map +1 -0
- package/dist/_chunks/{metadata-routes-BU684ls2.js → metadata-routes-Cjmvi3rQ.js} +1 -1
- package/dist/_chunks/{metadata-routes-BU684ls2.js.map → metadata-routes-Cjmvi3rQ.js.map} +1 -1
- package/dist/_chunks/{navigation-root-yx917rG0.js → navigation-root-2ypaZQDx.js} +2 -2
- package/dist/_chunks/{navigation-root-yx917rG0.js.map → navigation-root-2ypaZQDx.js.map} +1 -1
- package/dist/_chunks/{registry-I2ss-lvy.js → registry-DB93kT5c.js} +1 -1
- package/dist/_chunks/{registry-I2ss-lvy.js.map → registry-DB93kT5c.js.map} +1 -1
- package/dist/_chunks/{router-ref-h3-UaCQv.js → router-ref-TkUdmqtM.js} +2 -2
- package/dist/_chunks/{router-ref-h3-UaCQv.js.map → router-ref-TkUdmqtM.js.map} +1 -1
- package/dist/_chunks/{schema-bridge-Cxu4l-7p.js → schema-bridge-C3xl_vfb.js} +1 -1
- package/dist/_chunks/{schema-bridge-Cxu4l-7p.js.map → schema-bridge-C3xl_vfb.js.map} +1 -1
- package/dist/_chunks/{segment-classify-BjfuctV2.js → segment-classify-CnfLLvir.js} +1 -1
- package/dist/_chunks/{segment-classify-BjfuctV2.js.map → segment-classify-CnfLLvir.js.map} +1 -1
- package/dist/_chunks/{segment-context-Dx_OizxD.js → segment-context-Dc-GbSTe.js} +1 -1
- package/dist/_chunks/{segment-context-Dx_OizxD.js.map → segment-context-Dc-GbSTe.js.map} +1 -1
- package/dist/_chunks/{ssr-data-B4CdH7rE.js → ssr-data-DzuI0bIV.js} +1 -1
- package/dist/_chunks/{ssr-data-B4CdH7rE.js.map → ssr-data-DzuI0bIV.js.map} +1 -1
- package/dist/_chunks/{stale-reload-Bab885FO.js → stale-reload-D6FlD3xn.js} +1 -1
- package/dist/_chunks/{stale-reload-Bab885FO.js.map → stale-reload-D6FlD3xn.js.map} +1 -1
- package/dist/_chunks/{tracing-C8V-YGsP.js → tracing-DvKLzCFa.js} +1 -1
- package/dist/_chunks/{tracing-C8V-YGsP.js.map → tracing-DvKLzCFa.js.map} +1 -1
- package/dist/_chunks/{use-query-states-B2XTqxDR.js → use-query-states-B-cLl8mx.js} +2 -2
- package/dist/_chunks/{use-query-states-B2XTqxDR.js.map → use-query-states-B-cLl8mx.js.map} +1 -1
- package/dist/_chunks/{use-segment-params-DlsOX1YS.js → use-segment-params-07V1TIxL.js} +3 -3
- package/dist/_chunks/{use-segment-params-DlsOX1YS.js.map → use-segment-params-07V1TIxL.js.map} +1 -1
- package/dist/_chunks/{merge-search-params-BphMdht_.js → validation-DfyuMoK2.js} +2 -40
- package/dist/_chunks/validation-DfyuMoK2.js.map +1 -0
- package/dist/_chunks/{walkers-Tg0Alwcg.js → walkers-DQn5NNrf.js} +4 -4
- package/dist/_chunks/{walkers-Tg0Alwcg.js.map → walkers-DQn5NNrf.js.map} +1 -1
- package/dist/_chunks/{warnings-Cg47l5sk.js → warnings-B30wpfaS.js} +2 -2
- package/dist/_chunks/{warnings-Cg47l5sk.js.map → warnings-B30wpfaS.js.map} +1 -1
- package/dist/adapters/cloudflare.js +1 -1
- package/dist/adapters/nitro.js +1 -1
- package/dist/cache/index.js +3 -3
- package/dist/client/error-boundary.js +2 -2
- package/dist/client/index.js +10 -117
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal.js +7 -7
- package/dist/client/use-cookie.d.ts +4 -0
- package/dist/client/use-cookie.d.ts.map +1 -1
- package/dist/codec.js +1 -1
- package/dist/cookies/define-cookie.d.ts +5 -45
- package/dist/cookies/define-cookie.d.ts.map +1 -1
- package/dist/cookies/index.js +252 -1
- package/dist/cookies/index.js.map +1 -1
- package/dist/index.js +36 -6
- package/dist/index.js.map +1 -1
- package/dist/routing/index.js +2 -2
- package/dist/search-params/index.js +3 -3
- package/dist/segment-params/index.js +1 -1
- package/dist/server/index.js +3 -3
- package/dist/server/internal.js +7 -7
- package/dist/server/request-context.d.ts.map +1 -1
- package/package.json +7 -6
- package/src/cli.ts +0 -0
- package/src/client/index.ts +0 -9
- package/src/client/use-cookie.ts +2 -2
- package/src/cookies/define-cookie.ts +100 -166
- package/src/server/request-context.ts +1 -8
- package/LICENSE +0 -8
- package/dist/_chunks/actions-BsfxK6yu.js.map +0 -1
- package/dist/_chunks/chunk-Cfpv9whK.js +0 -32
- package/dist/_chunks/define-cookie-BjpIt4UC.js +0 -194
- package/dist/_chunks/define-cookie-BjpIt4UC.js.map +0 -1
- package/dist/_chunks/merge-search-params-BphMdht_.js.map +0 -1
package/dist/routing/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { i as INTERCEPTION_MARKERS, n as classifyUrlSegment, r as DEFAULT_PAGE_EXTENSIONS, t as classifySegment } from "../_chunks/segment-classify-
|
|
2
|
-
import { i as scanRoutes, n as collectInterceptionRewrites, r as generateRouteMap, t as collectLeafRoutes } from "../_chunks/walkers-
|
|
1
|
+
import { i as INTERCEPTION_MARKERS, n as classifyUrlSegment, r as DEFAULT_PAGE_EXTENSIONS, t as classifySegment } from "../_chunks/segment-classify-CnfLLvir.js";
|
|
2
|
+
import { i as scanRoutes, n as collectInterceptionRewrites, r as generateRouteMap, t as collectLeafRoutes } from "../_chunks/walkers-DQn5NNrf.js";
|
|
3
3
|
export { DEFAULT_PAGE_EXTENSIONS, INTERCEPTION_MARKERS, classifySegment, classifyUrlSegment, collectInterceptionRewrites, collectLeafRoutes, generateRouteMap, scanRoutes };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { n as registerSearchParams, t as getSearchParamsDefinition } from "../_chunks/registry-
|
|
2
|
-
import { i as isStandardSchema, n as fromSchema, r as isCodec } from "../_chunks/schema-bridge-
|
|
3
|
-
import { n as defineSearchParams } from "../_chunks/define-
|
|
1
|
+
import { n as registerSearchParams, t as getSearchParamsDefinition } from "../_chunks/registry-DB93kT5c.js";
|
|
2
|
+
import { i as isStandardSchema, n as fromSchema, r as isCodec } from "../_chunks/schema-bridge-C3xl_vfb.js";
|
|
3
|
+
import { n as defineSearchParams } from "../_chunks/define-Dn98bPbb.js";
|
|
4
4
|
//#region src/search-params/wrappers.ts
|
|
5
5
|
/**
|
|
6
6
|
* Wrap a nullable codec with a default value. When the inner codec returns
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { r as defineSegmentParams } from "../_chunks/define-
|
|
1
|
+
import { r as defineSegmentParams } from "../_chunks/define-Btmz9B20.js";
|
|
2
2
|
export { defineSegmentParams };
|
package/dist/server/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { a as getSpanId, d as withSpan, o as getTraceId, p as formFlashAls, t as addSpanEvent, v as isDebug, y as isDevMode } from "../_chunks/tracing-
|
|
2
|
-
import { t as formatSize } from "../_chunks/format-
|
|
3
|
-
import { E as getCookieJar, a as revalidateTag, b as getSegmentParams, c as DenySignal, f as deny, h as waitUntil, i as revalidatePath, l as RedirectSignal, m as redirectExternal, p as redirect, s as parseFormData, u as RedirectType, v as getHeaders } from "../_chunks/actions-
|
|
1
|
+
import { a as getSpanId, d as withSpan, o as getTraceId, p as formFlashAls, t as addSpanEvent, v as isDebug, y as isDevMode } from "../_chunks/tracing-DvKLzCFa.js";
|
|
2
|
+
import { t as formatSize } from "../_chunks/format-CYBGxKtc.js";
|
|
3
|
+
import { E as getCookieJar, a as revalidateTag, b as getSegmentParams, c as DenySignal, f as deny, h as waitUntil, i as revalidatePath, l as RedirectSignal, m as redirectExternal, p as redirect, s as parseFormData, u as RedirectType, v as getHeaders } from "../_chunks/actions-n9qTlpmY.js";
|
|
4
4
|
//#region src/server/sensitive-fields.ts
|
|
5
5
|
/**
|
|
6
6
|
* Sensitive field stripping — removes password/token/CVV-style fields
|
package/dist/server/internal.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { c as replaceTraceId, d as withSpan, f as earlyHintsSenderAls, g as timingAls, i as getOtelTraceId, l as runWithTraceId, m as requestContextAls, o as getTraceId, r as generateTraceId, u as setSpanAttribute, v as isDebug } from "../_chunks/tracing-
|
|
2
|
-
import { a as warnRedirectInSuspense, c as warnSuspenseWrappingChildren, i as warnRedirectInAccess, n as setViteServer, o as warnSlowSlotWithoutSuspense, r as warnDenyInSuspense, s as warnStaticRequestApi, t as WarningId } from "../_chunks/warnings-
|
|
3
|
-
import { n as classifyUrlSegment } from "../_chunks/segment-classify-
|
|
4
|
-
import { i as getMetadataRouteServePath, n as classifyMetadataRoute, r as getMetadataRouteAutoLink, t as METADATA_ROUTE_CONVENTIONS } from "../_chunks/metadata-routes-
|
|
5
|
-
import { a as logProxyError, c as logRequestReceived, d as logSwrRefetchFailed, f as logWaitUntilRejected, h as swallow, i as logMiddlewareShortCircuit, l as logRouteError, m as setLogger, n as logCacheMiss, o as logRenderError, p as logWaitUntilUnsupported, r as logMiddlewareError, s as logRequestCompleted, t as getLogger, u as logSlowRequest } from "../_chunks/logger-
|
|
6
|
-
import { C as setMutableCookieContext, D as getSetCookieHeaders, S as runWithRequestContext, T as getCookie, _ as getHeader, b as getSegmentParams, c as DenySignal, d as RenderError, g as applyRequestHeaderOverlay, l as RedirectSignal, n as executeAction, o as coerce, r as isRscActionRequest, t as buildNoJsResponse, w as setSegmentParams, x as markResponseFlushed, y as getSearchParams } from "../_chunks/actions-
|
|
1
|
+
import { c as replaceTraceId, d as withSpan, f as earlyHintsSenderAls, g as timingAls, i as getOtelTraceId, l as runWithTraceId, m as requestContextAls, o as getTraceId, r as generateTraceId, u as setSpanAttribute, v as isDebug } from "../_chunks/tracing-DvKLzCFa.js";
|
|
2
|
+
import { a as warnRedirectInSuspense, c as warnSuspenseWrappingChildren, i as warnRedirectInAccess, n as setViteServer, o as warnSlowSlotWithoutSuspense, r as warnDenyInSuspense, s as warnStaticRequestApi, t as WarningId } from "../_chunks/warnings-B30wpfaS.js";
|
|
3
|
+
import { n as classifyUrlSegment } from "../_chunks/segment-classify-CnfLLvir.js";
|
|
4
|
+
import { i as getMetadataRouteServePath, n as classifyMetadataRoute, r as getMetadataRouteAutoLink, t as METADATA_ROUTE_CONVENTIONS } from "../_chunks/metadata-routes-Cjmvi3rQ.js";
|
|
5
|
+
import { a as logProxyError, c as logRequestReceived, d as logSwrRefetchFailed, f as logWaitUntilRejected, h as swallow, i as logMiddlewareShortCircuit, l as logRouteError, m as setLogger, n as logCacheMiss, o as logRenderError, p as logWaitUntilUnsupported, r as logMiddlewareError, s as logRequestCompleted, t as getLogger, u as logSlowRequest } from "../_chunks/logger-DDmK5skc.js";
|
|
6
|
+
import { C as setMutableCookieContext, D as getSetCookieHeaders, S as runWithRequestContext, T as getCookie, _ as getHeader, b as getSegmentParams, c as DenySignal, d as RenderError, g as applyRequestHeaderOverlay, l as RedirectSignal, n as executeAction, o as coerce, r as isRscActionRequest, t as buildNoJsResponse, w as setSegmentParams, x as markResponseFlushed, y as getSearchParams } from "../_chunks/actions-n9qTlpmY.js";
|
|
7
7
|
import "../client/error-boundary.js";
|
|
8
|
-
import "../_chunks/segment-context-
|
|
8
|
+
import "../_chunks/segment-context-Dc-GbSTe.js";
|
|
9
9
|
import { readFile } from "node:fs/promises";
|
|
10
10
|
import { createElement } from "react";
|
|
11
11
|
//#region src/server/server-timing.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../../src/server/request-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,iBAAiB,EAA4B,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../../src/server/request-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,iBAAiB,EAA4B,MAAM,mBAAmB,CAAC;AAMhF,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAQ7B;;;;;GAKG;AACH,wBAAgB,UAAU,IAAI,eAAe,CAS5C;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG1D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,IAAI,eAAe,CASjD;AAaD;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAepE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,IAAI,CAMhF;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAG/C;AAID;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,IAAI,CAChC,OAAO,EACP,KAAK,GAAG,KAAK,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,MAAM,CAAC,QAAQ,CACnF,CAAC;AAIF;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAmBrE;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAK9D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAK1C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmBhE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@timber-js/app",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.102",
|
|
4
4
|
"description": "Vite-native React framework built for Servers and Serverless Platforms — correct HTTP semantics, real status codes, pages that work without JavaScript",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cloudflare-workers",
|
|
@@ -110,6 +110,11 @@
|
|
|
110
110
|
"publishConfig": {
|
|
111
111
|
"access": "public"
|
|
112
112
|
},
|
|
113
|
+
"scripts": {
|
|
114
|
+
"build": "vite build --config vite.lib.config.ts && tsc --emitDeclarationOnly --project tsconfig.json --outDir dist",
|
|
115
|
+
"typecheck": "tsgo --noEmit",
|
|
116
|
+
"prepublishOnly": "pnpm run build"
|
|
117
|
+
},
|
|
113
118
|
"dependencies": {
|
|
114
119
|
"@opentelemetry/api": "^1.9.1",
|
|
115
120
|
"@opentelemetry/context-async-hooks": "^2.6.1",
|
|
@@ -153,9 +158,5 @@
|
|
|
153
158
|
},
|
|
154
159
|
"engines": {
|
|
155
160
|
"node": ">=22.12.0"
|
|
156
|
-
},
|
|
157
|
-
"scripts": {
|
|
158
|
-
"build": "vite build --config vite.lib.config.ts && tsc --emitDeclarationOnly --project tsconfig.json --outDir dist",
|
|
159
|
-
"typecheck": "tsgo --noEmit"
|
|
160
161
|
}
|
|
161
|
-
}
|
|
162
|
+
}
|
package/src/cli.ts
CHANGED
|
File without changes
|
package/src/client/index.ts
CHANGED
|
@@ -83,15 +83,6 @@ export { useSegmentParams } from './use-segment-params';
|
|
|
83
83
|
// Types still exported for advanced use.
|
|
84
84
|
export type { ClientCookieOptions, CookieSetter } from './use-cookie';
|
|
85
85
|
|
|
86
|
-
// Register the client cookie module with defineCookie's lazy reference.
|
|
87
|
-
// This runs at module load time in the client/SSR environment, wiring up
|
|
88
|
-
// the useCookie hook without a top-level import in define-cookie.ts.
|
|
89
|
-
import * as _useCookieMod from './use-cookie.js';
|
|
90
|
-
import { _registerUseCookieModule, _registerFromSchema } from '../cookies/define-cookie.js';
|
|
91
|
-
import { fromSchema } from '../schema-bridge.js';
|
|
92
|
-
_registerUseCookieModule(_useCookieMod);
|
|
93
|
-
_registerFromSchema(fromSchema);
|
|
94
|
-
|
|
95
86
|
// Register the client useSegmentParams hook with defineSegmentParams.
|
|
96
87
|
import { useSegmentParams as _useSegmentParams } from './use-segment-params.js';
|
|
97
88
|
import { _registerUseSegmentParams } from '../segment-params/define.js';
|
package/src/client/use-cookie.ts
CHANGED
|
@@ -39,7 +39,7 @@ type Listener = () => void;
|
|
|
39
39
|
const listeners = new Map<string, Set<Listener>>();
|
|
40
40
|
|
|
41
41
|
/** Parse a cookie name from document.cookie. */
|
|
42
|
-
function getCookieValue(name: string): string | undefined {
|
|
42
|
+
export function getCookieValue(name: string): string | undefined {
|
|
43
43
|
if (typeof document === 'undefined') return undefined;
|
|
44
44
|
const match = document.cookie.match(
|
|
45
45
|
new RegExp('(?:^|;\\s*)' + name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '\\s*=\\s*([^;]*)')
|
|
@@ -48,7 +48,7 @@ function getCookieValue(name: string): string | undefined {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
/** Serialize options into a cookie string suffix. */
|
|
51
|
-
function serializeOptions(options?: ClientCookieOptions): string {
|
|
51
|
+
export function serializeOptions(options?: ClientCookieOptions): string {
|
|
52
52
|
if (!options) return '; Path=/; SameSite=Lax';
|
|
53
53
|
const parts: string[] = [];
|
|
54
54
|
parts.push(`Path=${options.path ?? '/'}`);
|
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
* with sync .get(), .set(), .delete() isomorphic methods (server + client)
|
|
6
6
|
* and a .useCookie() client hook.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* Environment detection is call-time: on the server, getCookieJar() is
|
|
9
|
+
* used directly (ALS-backed). On the client, document.cookie helpers
|
|
10
|
+
* and the useCookie hook are used. No registration pattern — imports
|
|
11
|
+
* resolve via the shims plugin (client bundle gets a stub for
|
|
12
|
+
* @timber-js/app/server).
|
|
12
13
|
*
|
|
13
14
|
* Standard Schema objects (Zod, Valibot, ArkType) are auto-detected in
|
|
14
15
|
* the codec option — no explicit fromSchema() wrapper needed.
|
|
@@ -71,119 +72,76 @@ export interface CookieDefinition<T> extends ServerOnlyCookieDefinition<T> {
|
|
|
71
72
|
useCookie(): [T, (value: T) => void, () => void];
|
|
72
73
|
}
|
|
73
74
|
|
|
74
|
-
// ───
|
|
75
|
+
// ─── Direct Imports (no registration) ─────────────────────────────────────
|
|
75
76
|
//
|
|
76
|
-
// Server
|
|
77
|
-
//
|
|
78
|
-
//
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/** Client-side cookie impl: reads/writes document.cookie via useCookie hook. */
|
|
90
|
-
export interface ClientCookieImpl {
|
|
91
|
-
useCookie(
|
|
92
|
-
name: string,
|
|
93
|
-
options?: ClientCookieOptions
|
|
94
|
-
): [string | undefined, (value: string, options?: ClientCookieOptions) => void, () => void];
|
|
95
|
-
getCookieValue(name: string): string | undefined;
|
|
96
|
-
setCookieValue(name: string, value: string, options?: ClientCookieOptions): void;
|
|
97
|
-
deleteCookieValue(name: string, options?: ClientCookieOptions): void;
|
|
98
|
-
}
|
|
77
|
+
// Server: getCookieJar is imported from @timber-js/app/server. In the client
|
|
78
|
+
// bundle, the shims plugin replaces @timber-js/app/server with a stub module
|
|
79
|
+
// where getCookieJar throws on call. We detect the environment at call time
|
|
80
|
+
// by trying getCookieJar() — if it throws the stub error, we fall through
|
|
81
|
+
// to the client path.
|
|
82
|
+
//
|
|
83
|
+
// Client: useCookie, getCookieValue, notifyCookieChange
|
|
84
|
+
// are imported from use-cookie.ts. These are safe in all environments (no
|
|
85
|
+
// node:async_hooks dependency).
|
|
86
|
+
//
|
|
87
|
+
// Schema: fromSchema is a pure function — safe in all environments.
|
|
99
88
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
89
|
+
import { getCookieJar } from '@timber-js/app/server';
|
|
90
|
+
import { fromSchema } from '../schema-bridge.js';
|
|
91
|
+
import {
|
|
92
|
+
useCookie as useRawCookie,
|
|
93
|
+
notifyCookieChange,
|
|
94
|
+
getCookieValue,
|
|
95
|
+
} from '../client/use-cookie.js';
|
|
103
96
|
|
|
104
|
-
|
|
105
|
-
* Register the server-side cookie implementation.
|
|
106
|
-
* Called by server entry at module load time.
|
|
107
|
-
* @internal
|
|
108
|
-
*/
|
|
109
|
-
export function _registerServerCookieImpl(impl: ServerCookieImpl): void {
|
|
110
|
-
_serverImpl = impl;
|
|
111
|
-
}
|
|
97
|
+
// ─── Environment Detection ────────────────────────────────────────────────
|
|
112
98
|
|
|
113
99
|
/**
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
100
|
+
* Try to get the server cookie jar. Returns null if we're in the client
|
|
101
|
+
* environment (stub throws) or if there's no request context.
|
|
102
|
+
*
|
|
103
|
+
* On the server, getCookieJar() throws "outside of a request context" if
|
|
104
|
+
* called without an ALS store — this is a real error and is re-thrown.
|
|
105
|
+
* The client stub throws a different message — that's caught and returns null.
|
|
117
106
|
*/
|
|
118
|
-
|
|
119
|
-
|
|
107
|
+
function tryGetServerCookieJar(): ReturnType<typeof getCookieJar> | null {
|
|
108
|
+
try {
|
|
109
|
+
return getCookieJar();
|
|
110
|
+
} catch (e) {
|
|
111
|
+
// Server-side "no request context" error — re-throw as a real bug.
|
|
112
|
+
if (e instanceof Error && e.message.includes('outside of a request context')) {
|
|
113
|
+
throw e;
|
|
114
|
+
}
|
|
115
|
+
// Client stub error or other — fall through to client path.
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
120
118
|
}
|
|
121
119
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
)
|
|
130
|
-
|
|
120
|
+
// ─── Client Cookie Helpers ────────────────────────────────────────────────
|
|
121
|
+
|
|
122
|
+
/** Write a cookie via document.cookie and notify useCookie subscribers. */
|
|
123
|
+
function setClientCookie(name: string, value: string, options?: ClientCookieOptions): void {
|
|
124
|
+
const parts: string[] = [`${name}=${encodeURIComponent(value)}`];
|
|
125
|
+
const path = options?.path ?? '/';
|
|
126
|
+
parts.push(`Path=${path}`);
|
|
127
|
+
if (options?.domain) parts.push(`Domain=${options.domain}`);
|
|
128
|
+
if (options?.maxAge !== undefined) parts.push(`Max-Age=${options.maxAge}`);
|
|
129
|
+
if (options?.expires) parts.push(`Expires=${options.expires.toUTCString()}`);
|
|
130
|
+
const sameSite = options?.sameSite ?? 'lax';
|
|
131
|
+
parts.push(`SameSite=${sameSite.charAt(0).toUpperCase()}${sameSite.slice(1)}`);
|
|
132
|
+
if (options?.secure) parts.push('Secure');
|
|
133
|
+
document.cookie = parts.join('; ');
|
|
134
|
+
notifyCookieChange(name);
|
|
131
135
|
}
|
|
132
136
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
);
|
|
142
|
-
}
|
|
143
|
-
return _useCookieModule;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Register the client cookie module. Called by the client entry to wire
|
|
148
|
-
* up the lazy reference without a top-level import.
|
|
149
|
-
*
|
|
150
|
-
* @internal — framework use only
|
|
151
|
-
*/
|
|
152
|
-
export function _registerUseCookieModule(mod: typeof import('../client/use-cookie.js')): void {
|
|
153
|
-
_useCookieModule = mod;
|
|
154
|
-
// Also register the client impl from the module
|
|
155
|
-
_clientImpl = {
|
|
156
|
-
useCookie: mod.useCookie,
|
|
157
|
-
getCookieValue: (name: string) => {
|
|
158
|
-
if (typeof document === 'undefined') return undefined;
|
|
159
|
-
const match = document.cookie.match(
|
|
160
|
-
new RegExp('(?:^|;\\s*)' + name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '\\s*=\\s*([^;]*)')
|
|
161
|
-
);
|
|
162
|
-
return match ? decodeURIComponent(match[1]) : undefined;
|
|
163
|
-
},
|
|
164
|
-
setCookieValue: (name: string, value: string, options?: ClientCookieOptions) => {
|
|
165
|
-
const parts: string[] = [`${name}=${encodeURIComponent(value)}`];
|
|
166
|
-
const path = options?.path ?? '/';
|
|
167
|
-
parts.push(`Path=${path}`);
|
|
168
|
-
if (options?.domain) parts.push(`Domain=${options.domain}`);
|
|
169
|
-
if (options?.maxAge !== undefined) parts.push(`Max-Age=${options.maxAge}`);
|
|
170
|
-
if (options?.expires) parts.push(`Expires=${options.expires.toUTCString()}`);
|
|
171
|
-
const sameSite = options?.sameSite ?? 'lax';
|
|
172
|
-
parts.push(`SameSite=${sameSite.charAt(0).toUpperCase()}${sameSite.slice(1)}`);
|
|
173
|
-
if (options?.secure) parts.push('Secure');
|
|
174
|
-
document.cookie = parts.join('; ');
|
|
175
|
-
// Notify useCookie subscribers so mounted hooks re-render
|
|
176
|
-
mod.notifyCookieChange(name);
|
|
177
|
-
},
|
|
178
|
-
deleteCookieValue: (name: string, options?: ClientCookieOptions) => {
|
|
179
|
-
const path = options?.path ?? '/';
|
|
180
|
-
const domain = options?.domain;
|
|
181
|
-
let cookieStr = `${name}=; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Path=${path}`;
|
|
182
|
-
if (domain) cookieStr += `; Domain=${domain}`;
|
|
183
|
-
document.cookie = cookieStr;
|
|
184
|
-
mod.notifyCookieChange(name);
|
|
185
|
-
},
|
|
186
|
-
};
|
|
137
|
+
/** Delete a cookie via document.cookie and notify useCookie subscribers. */
|
|
138
|
+
function deleteClientCookie(name: string, options?: ClientCookieOptions): void {
|
|
139
|
+
const path = options?.path ?? '/';
|
|
140
|
+
const domain = options?.domain;
|
|
141
|
+
let cookieStr = `${name}=; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Path=${path}`;
|
|
142
|
+
if (domain) cookieStr += `; Domain=${domain}`;
|
|
143
|
+
document.cookie = cookieStr;
|
|
144
|
+
notifyCookieChange(name);
|
|
187
145
|
}
|
|
188
146
|
|
|
189
147
|
// ─── Standard Schema Auto-Detection ───────────────────────────────────────
|
|
@@ -199,14 +157,7 @@ function resolveCodec<T>(codecOrSchema: CookieCodec<T> | StandardSchemaV1<T>): C
|
|
|
199
157
|
|
|
200
158
|
// Auto-detect Standard Schema
|
|
201
159
|
if (typeof codecOrSchema === 'object' && codecOrSchema !== null && '~standard' in codecOrSchema) {
|
|
202
|
-
|
|
203
|
-
throw new Error(
|
|
204
|
-
'[timber] defineCookie: Standard Schema auto-detection requires @timber-js/app/server or ' +
|
|
205
|
-
'@timber-js/app/client to be loaded. Pass an explicit Codec<T> with parse/serialize methods, ' +
|
|
206
|
-
'or ensure the framework entry module is imported.'
|
|
207
|
-
);
|
|
208
|
-
}
|
|
209
|
-
return _fromSchemaFn(codecOrSchema as StandardSchemaV1<unknown>) as CookieCodec<T>;
|
|
160
|
+
return fromSchema(codecOrSchema as StandardSchemaV1<unknown>) as CookieCodec<T>;
|
|
210
161
|
}
|
|
211
162
|
|
|
212
163
|
throw new Error(
|
|
@@ -266,88 +217,73 @@ export function defineCookie<T, HttpOnly extends boolean = true>(
|
|
|
266
217
|
};
|
|
267
218
|
}
|
|
268
219
|
|
|
269
|
-
function assertNotHttpOnlyClient(method: string): void {
|
|
270
|
-
if (isHttpOnly && !_serverImpl) {
|
|
271
|
-
throw new Error(
|
|
272
|
-
`[timber] defineCookie('${name}').${method}() cannot be used with httpOnly cookies — ` +
|
|
273
|
-
`the browser cannot access them. Set httpOnly: false to enable client access.`
|
|
274
|
-
);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
|
|
278
220
|
const base: ServerOnlyCookieDefinition<T> = {
|
|
279
221
|
name,
|
|
280
222
|
options: resolvedOptions,
|
|
281
223
|
codec,
|
|
282
224
|
|
|
283
225
|
get(): T {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
return codec.parse(raw);
|
|
226
|
+
const serverJar = tryGetServerCookieJar();
|
|
227
|
+
if (serverJar) {
|
|
228
|
+
return codec.parse(serverJar.get(name));
|
|
288
229
|
}
|
|
289
230
|
// Client path
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
231
|
+
if (isHttpOnly) {
|
|
232
|
+
throw new Error(
|
|
233
|
+
`[timber] defineCookie('${name}').get() cannot be used with httpOnly cookies — ` +
|
|
234
|
+
`the browser cannot access them. Set httpOnly: false to enable client access.`
|
|
235
|
+
);
|
|
294
236
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
'Ensure @timber-js/app/server or @timber-js/app/client is imported.'
|
|
298
|
-
);
|
|
237
|
+
const raw = getCookieValue(name);
|
|
238
|
+
return codec.parse(raw);
|
|
299
239
|
},
|
|
300
240
|
|
|
301
241
|
set(value: T): void {
|
|
302
|
-
|
|
303
|
-
|
|
242
|
+
const serverJar = tryGetServerCookieJar();
|
|
243
|
+
if (serverJar) {
|
|
304
244
|
const serialized = codec.serialize(value);
|
|
305
245
|
if (serialized === null) {
|
|
306
|
-
|
|
246
|
+
serverJar.delete(name, {
|
|
307
247
|
path: resolvedOptions.path,
|
|
308
248
|
domain: resolvedOptions.domain,
|
|
309
249
|
});
|
|
310
250
|
} else {
|
|
311
|
-
|
|
251
|
+
serverJar.set(name, serialized, resolvedOptions);
|
|
312
252
|
}
|
|
313
253
|
return;
|
|
314
254
|
}
|
|
315
255
|
// Client path
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
256
|
+
if (isHttpOnly) {
|
|
257
|
+
throw new Error(
|
|
258
|
+
`[timber] defineCookie('${name}').set() cannot be used with httpOnly cookies — ` +
|
|
259
|
+
`the browser cannot access them. Set httpOnly: false to enable client access.`
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
const serialized = codec.serialize(value);
|
|
263
|
+
if (serialized === null) {
|
|
264
|
+
deleteClientCookie(name, getClientOpts());
|
|
265
|
+
} else {
|
|
266
|
+
setClientCookie(name, serialized, getClientOpts());
|
|
325
267
|
}
|
|
326
|
-
throw new Error(
|
|
327
|
-
`[timber] defineCookie('${name}').set() — no environment registered. ` +
|
|
328
|
-
'Ensure @timber-js/app/server or @timber-js/app/client is imported.'
|
|
329
|
-
);
|
|
330
268
|
},
|
|
331
269
|
|
|
332
270
|
delete(): void {
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
271
|
+
const serverJar = tryGetServerCookieJar();
|
|
272
|
+
if (serverJar) {
|
|
273
|
+
serverJar.delete(name, {
|
|
336
274
|
path: resolvedOptions.path,
|
|
337
275
|
domain: resolvedOptions.domain,
|
|
338
276
|
});
|
|
339
277
|
return;
|
|
340
278
|
}
|
|
341
279
|
// Client path
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
280
|
+
if (isHttpOnly) {
|
|
281
|
+
throw new Error(
|
|
282
|
+
`[timber] defineCookie('${name}').delete() cannot be used with httpOnly cookies — ` +
|
|
283
|
+
`the browser cannot access them. Set httpOnly: false to enable client access.`
|
|
284
|
+
);
|
|
346
285
|
}
|
|
347
|
-
|
|
348
|
-
`[timber] defineCookie('${name}').delete() — no environment registered. ` +
|
|
349
|
-
'Ensure @timber-js/app/server or @timber-js/app/client is imported.'
|
|
350
|
-
);
|
|
286
|
+
deleteClientCookie(name, getClientOpts());
|
|
351
287
|
},
|
|
352
288
|
};
|
|
353
289
|
|
|
@@ -360,8 +296,6 @@ export function defineCookie<T, HttpOnly extends boolean = true>(
|
|
|
360
296
|
...base,
|
|
361
297
|
|
|
362
298
|
useCookie(): [T, (value: T) => void, () => void] {
|
|
363
|
-
const { useCookie: useRawCookie } = getUseCookieModule();
|
|
364
|
-
|
|
365
299
|
const clientOpts = getClientOpts();
|
|
366
300
|
const [raw, setRaw, deleteRaw] = useRawCookie(name, clientOpts);
|
|
367
301
|
const parsed = codec.parse(raw);
|
|
@@ -17,9 +17,7 @@
|
|
|
17
17
|
import { requestContextAls, type RequestContextStore } from './als-registry.js';
|
|
18
18
|
import { _setGetSearchParamsFn } from '../search-params/define.js';
|
|
19
19
|
import { _setGetSegmentParamsFn } from '../segment-params/define.js';
|
|
20
|
-
import { consumeSeededCookies
|
|
21
|
-
import { _registerServerCookieImpl, _registerFromSchema } from '../cookies/define-cookie.js';
|
|
22
|
-
import { fromSchema } from '../schema-bridge.js';
|
|
20
|
+
import { consumeSeededCookies } from './cookie-context.js';
|
|
23
21
|
|
|
24
22
|
// Re-export the ALS for framework-internal consumers that need direct access.
|
|
25
23
|
export { requestContextAls };
|
|
@@ -87,11 +85,6 @@ _setGetSearchParamsFn(getSearchParams);
|
|
|
87
85
|
// Same pattern as search params — dynamic imports lose ALS context. See TIM-523.
|
|
88
86
|
_setGetSegmentParamsFn(getSegmentParams);
|
|
89
87
|
|
|
90
|
-
// Eagerly register the server cookie impl with defineCookie so
|
|
91
|
-
// .get()/.set()/.delete() are sync without dynamic imports.
|
|
92
|
-
_registerServerCookieImpl({ getCookieJar });
|
|
93
|
-
_registerFromSchema(fromSchema);
|
|
94
|
-
|
|
95
88
|
/**
|
|
96
89
|
* Returns the current request's coerced segment params.
|
|
97
90
|
*
|
package/LICENSE
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
DONTFUCKINGUSE LICENSE
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 Daniel Saewitz
|
|
4
|
-
|
|
5
|
-
This software may not be used, copied, modified, merged, published,
|
|
6
|
-
distributed, sublicensed, or sold by anyone other than the copyright holder.
|
|
7
|
-
|
|
8
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
|