everything-dev 2.0.0-rc.6 → 2.0.0-rc.8
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 +2 -2
- package/dist/api/auth-middleware.cjs +14 -1
- package/dist/api/auth-middleware.cjs.map +1 -1
- package/dist/api/auth-middleware.d.cts +9 -0
- package/dist/api/auth-middleware.d.mts +9 -0
- package/dist/api/auth-middleware.mjs +14 -1
- package/dist/api/auth-middleware.mjs.map +1 -1
- package/dist/build.cjs +1 -1
- package/dist/build.mjs +1 -1
- package/dist/bundle-cache.cjs +1 -1
- package/dist/bundle-cache.cjs.map +1 -1
- package/dist/bundle-cache.mjs +1 -1
- package/dist/bundle-cache.mjs.map +1 -1
- package/dist/cli/init.cjs +22 -10
- package/dist/cli/init.cjs.map +1 -1
- package/dist/cli/init.mjs +22 -10
- package/dist/cli/init.mjs.map +1 -1
- package/dist/cli.cjs +6 -5
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.mjs +5 -4
- package/dist/cli.mjs.map +1 -1
- package/dist/commands/deploy.cjs +111 -1
- package/dist/commands/deploy.cjs.map +1 -1
- package/dist/commands/deploy.mjs +112 -2
- package/dist/commands/deploy.mjs.map +1 -1
- package/dist/commands/keys.cjs +1 -1
- package/dist/commands/keys.cjs.map +1 -1
- package/dist/commands/keys.mjs +1 -1
- package/dist/commands/keys.mjs.map +1 -1
- package/dist/commands/smoke.cjs +41 -0
- package/dist/commands/smoke.cjs.map +1 -0
- package/dist/commands/smoke.mjs +41 -0
- package/dist/commands/smoke.mjs.map +1 -0
- package/dist/commands/upgrade.cjs +2 -2
- package/dist/commands/upgrade.cjs.map +1 -1
- package/dist/commands/upgrade.mjs +1 -1
- package/dist/commands/upgrade.mjs.map +1 -1
- package/dist/contract.cjs +27 -1
- package/dist/contract.cjs.map +1 -1
- package/dist/contract.d.cts +65 -1
- package/dist/contract.d.mts +65 -1
- package/dist/contract.meta.cjs +14 -2
- package/dist/contract.meta.cjs.map +1 -1
- package/dist/contract.meta.d.cts +24 -2
- package/dist/contract.meta.d.mts +24 -2
- package/dist/contract.meta.mjs +14 -2
- package/dist/contract.meta.mjs.map +1 -1
- package/dist/contract.mjs +26 -2
- package/dist/contract.mjs.map +1 -1
- package/dist/db/core.cjs +22 -4
- package/dist/db/core.cjs.map +1 -1
- package/dist/db/core.mjs +22 -4
- package/dist/db/core.mjs.map +1 -1
- package/dist/dev-log-pipeline.cjs +6 -0
- package/dist/dev-log-pipeline.cjs.map +1 -1
- package/dist/dev-log-pipeline.mjs +6 -0
- package/dist/dev-log-pipeline.mjs.map +1 -1
- package/dist/dev-program.cjs +20 -3
- package/dist/dev-program.cjs.map +1 -1
- package/dist/dev-program.mjs +20 -4
- package/dist/dev-program.mjs.map +1 -1
- package/dist/dev-session.cjs +1 -0
- package/dist/dev-session.cjs.map +1 -1
- package/dist/dev-session.mjs +1 -0
- package/dist/dev-session.mjs.map +1 -1
- package/dist/fastkv.cjs +21 -3
- package/dist/fastkv.cjs.map +1 -1
- package/dist/fastkv.d.cts +14 -1
- package/dist/fastkv.d.mts +14 -1
- package/dist/fastkv.mjs +21 -5
- package/dist/fastkv.mjs.map +1 -1
- package/dist/{mf.cjs → federation.cjs} +6 -13
- package/dist/federation.cjs.map +1 -0
- package/dist/{mf.d.cts → federation.d.cts} +2 -2
- package/dist/{mf.d.mts → federation.d.mts} +2 -2
- package/dist/{mf.mjs → federation.mjs} +6 -13
- package/dist/federation.mjs.map +1 -0
- package/dist/http-client.cjs +84 -57
- package/dist/http-client.cjs.map +1 -1
- package/dist/http-client.mjs +84 -58
- package/dist/http-client.mjs.map +1 -1
- package/dist/image-deploy.cjs +9 -0
- package/dist/image-deploy.cjs.map +1 -1
- package/dist/image-deploy.mjs +9 -1
- package/dist/image-deploy.mjs.map +1 -1
- package/dist/index.cjs +4 -0
- package/dist/index.d.cts +3 -3
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +3 -3
- package/dist/infra/planner.cjs +6 -2
- package/dist/infra/planner.cjs.map +1 -1
- package/dist/infra/planner.mjs +6 -2
- package/dist/infra/planner.mjs.map +1 -1
- package/dist/orchestrator.cjs +39 -35
- package/dist/orchestrator.cjs.map +1 -1
- package/dist/orchestrator.mjs +39 -35
- package/dist/orchestrator.mjs.map +1 -1
- package/dist/plugin.cjs +2 -0
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +24 -0
- package/dist/plugin.d.mts +24 -0
- package/dist/plugin.mjs +2 -0
- package/dist/plugin.mjs.map +1 -1
- package/dist/process-registry.cjs +1 -1
- package/dist/process-registry.mjs +1 -1
- package/dist/publish.cjs +3 -3
- package/dist/publish.cjs.map +1 -1
- package/dist/publish.mjs +4 -4
- package/dist/publish.mjs.map +1 -1
- package/dist/resolver.cjs +293 -0
- package/dist/resolver.cjs.map +1 -0
- package/dist/resolver.d.cts +99 -0
- package/dist/resolver.d.mts +99 -0
- package/dist/resolver.mjs +284 -0
- package/dist/resolver.mjs.map +1 -0
- package/dist/smoke.cjs +262 -0
- package/dist/smoke.cjs.map +1 -0
- package/dist/smoke.mjs +260 -0
- package/dist/smoke.mjs.map +1 -0
- package/dist/ui/auth.d.cts +217 -123
- package/dist/ui/auth.d.mts +217 -123
- package/dist/ui/router-client.cjs +2 -1
- package/dist/ui/router-client.cjs.map +1 -1
- package/dist/ui/router-client.mjs +2 -1
- package/dist/ui/router-client.mjs.map +1 -1
- package/dist/version-manifest-resolve.cjs +3 -3
- package/dist/version-manifest-resolve.cjs.map +1 -1
- package/dist/version-manifest-resolve.mjs +1 -1
- package/dist/version-manifest-resolve.mjs.map +1 -1
- package/dist/workspace.cjs +1 -1
- package/dist/workspace.mjs +1 -1
- package/package.json +18 -18
- package/skills/api-and-auth/SKILL.md +12 -9
- package/skills/api-and-auth/references/middleware.md +38 -0
- package/skills/cli-reference/SKILL.md +22 -6
- package/skills/talk-to-the-app/SKILL.md +32 -5
- package/dist/bundle-fs-resolve.cjs +0 -235
- package/dist/bundle-fs-resolve.cjs.map +0 -1
- package/dist/bundle-fs-resolve.d.cts +0 -82
- package/dist/bundle-fs-resolve.d.mts +0 -82
- package/dist/bundle-fs-resolve.mjs +0 -228
- package/dist/bundle-fs-resolve.mjs.map +0 -1
- package/dist/bundle-path.cjs +0 -48
- package/dist/bundle-path.cjs.map +0 -1
- package/dist/bundle-path.mjs +0 -45
- package/dist/bundle-path.mjs.map +0 -1
- package/dist/mf.cjs.map +0 -1
- package/dist/mf.mjs.map +0 -1
|
@@ -33,7 +33,8 @@ function createRouter(opts) {
|
|
|
33
33
|
cspNonce: opts.context.cspNonce
|
|
34
34
|
}),
|
|
35
35
|
session: opts.context.session,
|
|
36
|
-
locale: opts.context.locale
|
|
36
|
+
locale: opts.context.locale,
|
|
37
|
+
pluginNav: opts.context.pluginNav
|
|
37
38
|
},
|
|
38
39
|
...cspNonce ? { ssr: { nonce: cspNonce } } : {},
|
|
39
40
|
defaultPreload: "intent",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router-client.cjs","names":["createBrowserHistory","createTanStackRouter","createAuthClient","RouterError","dehydrate"],"sources":["../../src/ui/router-client.tsx"],"sourcesContent":["/**\n * Client router factory — creates a TanStack Router with browser history.\n * The app-specific route tree is injected as `defaultRouteTree` (the\n * bundled core-only fallback); the composed tree wins when manifest\n * construction produced one.\n */\n\nimport { dehydrate, hydrate } from \"@tanstack/react-query\";\nimport {\n type AnyRoute,\n createBrowserHistory,\n createRouter as createTanStackRouter,\n} from \"@tanstack/react-router\";\nimport { createAuthClient } from \"./auth\";\nimport { defaultNotFoundComponent, defaultPendingComponent } from \"./router-defaults\";\nimport { RouterError } from \"./router-error\";\nimport type { CreateRouterOptions, RouterContextWithApi } from \"./types\";\n\nexport interface CoreRouterOptions<TApiClient = unknown, TSession = unknown>\n extends CreateRouterOptions<TApiClient, TSession> {\n /** The app's generated route tree — the core-only fallback when no composed tree is passed. */\n defaultRouteTree?: unknown;\n}\n\nexport function createRouter<\n TApiClient = unknown,\n TSession = unknown,\n TRouteTree extends AnyRoute = AnyRoute,\n>(\n opts: CoreRouterOptions<TApiClient, TSession> & {\n context: RouterContextWithApi<TApiClient, TSession> & { authClient?: unknown };\n },\n) {\n const queryClient = opts.context.queryClient;\n const history = opts.history ?? createBrowserHistory();\n const cspNonce = opts.context.cspNonce;\n\n const routeTree = opts.routeTree ?? opts.defaultRouteTree;\n if (!routeTree) {\n throw new Error(\n \"createRouter: no route tree — compose failed and no core-only fallback was constructed\",\n );\n }\n\n const router = createTanStackRouter({\n routeTree: routeTree as TRouteTree,\n history,\n basepath: opts.basepath ?? opts.context.runtimeConfig?.runtime?.runtimeBasePath ?? \"/\",\n context: {\n queryClient,\n runtimeConfig: opts.context.runtimeConfig,\n cspNonce: opts.context.cspNonce,\n apiClient: opts.context.apiClient,\n authClient:\n opts.context.authClient ??\n createAuthClient({\n runtimeConfig: opts.context.runtimeConfig,\n cspNonce: opts.context.cspNonce,\n }),\n session: opts.context.session,\n locale: opts.context.locale,\n },\n ...(cspNonce ? { ssr: { nonce: cspNonce } } : {}),\n defaultPreload: \"intent\",\n scrollRestoration: true,\n defaultStructuralSharing: true,\n defaultPreloadStaleTime: 0,\n defaultPendingMinMs: 0,\n defaultErrorComponent: RouterError,\n defaultNotFoundComponent,\n defaultPendingComponent,\n dehydrate: () => {\n if (typeof window === \"undefined\") {\n return { queryClientState: dehydrate(queryClient) };\n }\n\n return { queryClientState: {} };\n },\n hydrate: (dehydrated: { queryClientState?: unknown }) => {\n if (typeof window !== \"undefined\" && dehydrated?.queryClientState) {\n hydrate(queryClient, dehydrated.queryClientState);\n }\n },\n });\n\n return { router, queryClient };\n}\n"],"mappings":";;;;;;;;;;;;;;AAwBA,SAAgB,aAKd,MAGA;CACA,MAAM,cAAc,KAAK,QAAQ;CACjC,MAAM,UAAU,KAAK,eAAWA,6CAAqB;CACrD,MAAM,WAAW,KAAK,QAAQ;CAE9B,MAAM,YAAY,KAAK,aAAa,KAAK;CACzC,IAAI,CAAC,WACH,MAAM,IAAI,MACR,wFACF;
|
|
1
|
+
{"version":3,"file":"router-client.cjs","names":["createBrowserHistory","createTanStackRouter","createAuthClient","RouterError","dehydrate"],"sources":["../../src/ui/router-client.tsx"],"sourcesContent":["/**\n * Client router factory — creates a TanStack Router with browser history.\n * The app-specific route tree is injected as `defaultRouteTree` (the\n * bundled core-only fallback); the composed tree wins when manifest\n * construction produced one.\n */\n\nimport { dehydrate, hydrate } from \"@tanstack/react-query\";\nimport {\n type AnyRoute,\n createBrowserHistory,\n createRouter as createTanStackRouter,\n} from \"@tanstack/react-router\";\nimport { createAuthClient } from \"./auth\";\nimport { defaultNotFoundComponent, defaultPendingComponent } from \"./router-defaults\";\nimport { RouterError } from \"./router-error\";\nimport type { CreateRouterOptions, RouterContextWithApi } from \"./types\";\n\nexport interface CoreRouterOptions<TApiClient = unknown, TSession = unknown>\n extends CreateRouterOptions<TApiClient, TSession> {\n /** The app's generated route tree — the core-only fallback when no composed tree is passed. */\n defaultRouteTree?: unknown;\n}\n\nexport function createRouter<\n TApiClient = unknown,\n TSession = unknown,\n TRouteTree extends AnyRoute = AnyRoute,\n>(\n opts: CoreRouterOptions<TApiClient, TSession> & {\n context: RouterContextWithApi<TApiClient, TSession> & { authClient?: unknown };\n },\n) {\n const queryClient = opts.context.queryClient;\n const history = opts.history ?? createBrowserHistory();\n const cspNonce = opts.context.cspNonce;\n\n const routeTree = opts.routeTree ?? opts.defaultRouteTree;\n if (!routeTree) {\n throw new Error(\n \"createRouter: no route tree — compose failed and no core-only fallback was constructed\",\n );\n }\n\n const router = createTanStackRouter({\n routeTree: routeTree as TRouteTree,\n history,\n basepath: opts.basepath ?? opts.context.runtimeConfig?.runtime?.runtimeBasePath ?? \"/\",\n context: {\n queryClient,\n runtimeConfig: opts.context.runtimeConfig,\n cspNonce: opts.context.cspNonce,\n apiClient: opts.context.apiClient,\n authClient:\n opts.context.authClient ??\n createAuthClient({\n runtimeConfig: opts.context.runtimeConfig,\n cspNonce: opts.context.cspNonce,\n }),\n session: opts.context.session,\n locale: opts.context.locale,\n pluginNav: opts.context.pluginNav,\n },\n ...(cspNonce ? { ssr: { nonce: cspNonce } } : {}),\n defaultPreload: \"intent\",\n scrollRestoration: true,\n defaultStructuralSharing: true,\n defaultPreloadStaleTime: 0,\n defaultPendingMinMs: 0,\n defaultErrorComponent: RouterError,\n defaultNotFoundComponent,\n defaultPendingComponent,\n dehydrate: () => {\n if (typeof window === \"undefined\") {\n return { queryClientState: dehydrate(queryClient) };\n }\n\n return { queryClientState: {} };\n },\n hydrate: (dehydrated: { queryClientState?: unknown }) => {\n if (typeof window !== \"undefined\" && dehydrated?.queryClientState) {\n hydrate(queryClient, dehydrated.queryClientState);\n }\n },\n });\n\n return { router, queryClient };\n}\n"],"mappings":";;;;;;;;;;;;;;AAwBA,SAAgB,aAKd,MAGA;CACA,MAAM,cAAc,KAAK,QAAQ;CACjC,MAAM,UAAU,KAAK,eAAWA,6CAAqB;CACrD,MAAM,WAAW,KAAK,QAAQ;CAE9B,MAAM,YAAY,KAAK,aAAa,KAAK;CACzC,IAAI,CAAC,WACH,MAAM,IAAI,MACR,wFACF;CA6CF,OAAO;EAAE,YA1CMC,qCAAqB;GACvB;GACX;GACA,UAAU,KAAK,YAAY,KAAK,QAAQ,eAAe,SAAS,mBAAmB;GACnF,SAAS;IACP;IACA,eAAe,KAAK,QAAQ;IAC5B,UAAU,KAAK,QAAQ;IACvB,WAAW,KAAK,QAAQ;IACxB,YACE,KAAK,QAAQ,cACbC,iCAAiB;KACf,eAAe,KAAK,QAAQ;KAC5B,UAAU,KAAK,QAAQ;IACzB,CAAC;IACH,SAAS,KAAK,QAAQ;IACtB,QAAQ,KAAK,QAAQ;IACrB,WAAW,KAAK,QAAQ;GAC1B;GACA,GAAI,WAAW,EAAE,KAAK,EAAE,OAAO,SAAS,EAAE,IAAI,CAAC;GAC/C,gBAAgB;GAChB,mBAAmB;GACnB,0BAA0B;GAC1B,yBAAyB;GACzB,qBAAqB;GACrB,uBAAuBC;GACvB;GACA;GACA,iBAAiB;IACf,IAAI,OAAO,WAAW,aACpB,OAAO,EAAE,sBAAkBC,iCAAU,WAAW,EAAE;IAGpD,OAAO,EAAE,kBAAkB,CAAC,EAAE;GAChC;GACA,UAAU,eAA+C;IACvD,IAAI,OAAO,WAAW,eAAe,YAAY,kBAC/C,mCAAQ,aAAa,WAAW,gBAAgB;GAEpD;EACF,CAEc;EAAG;CAAY;AAC/B"}
|
|
@@ -32,7 +32,8 @@ function createRouter(opts) {
|
|
|
32
32
|
cspNonce: opts.context.cspNonce
|
|
33
33
|
}),
|
|
34
34
|
session: opts.context.session,
|
|
35
|
-
locale: opts.context.locale
|
|
35
|
+
locale: opts.context.locale,
|
|
36
|
+
pluginNav: opts.context.pluginNav
|
|
36
37
|
},
|
|
37
38
|
...cspNonce ? { ssr: { nonce: cspNonce } } : {},
|
|
38
39
|
defaultPreload: "intent",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router-client.mjs","names":["createTanStackRouter"],"sources":["../../src/ui/router-client.tsx"],"sourcesContent":["/**\n * Client router factory — creates a TanStack Router with browser history.\n * The app-specific route tree is injected as `defaultRouteTree` (the\n * bundled core-only fallback); the composed tree wins when manifest\n * construction produced one.\n */\n\nimport { dehydrate, hydrate } from \"@tanstack/react-query\";\nimport {\n type AnyRoute,\n createBrowserHistory,\n createRouter as createTanStackRouter,\n} from \"@tanstack/react-router\";\nimport { createAuthClient } from \"./auth\";\nimport { defaultNotFoundComponent, defaultPendingComponent } from \"./router-defaults\";\nimport { RouterError } from \"./router-error\";\nimport type { CreateRouterOptions, RouterContextWithApi } from \"./types\";\n\nexport interface CoreRouterOptions<TApiClient = unknown, TSession = unknown>\n extends CreateRouterOptions<TApiClient, TSession> {\n /** The app's generated route tree — the core-only fallback when no composed tree is passed. */\n defaultRouteTree?: unknown;\n}\n\nexport function createRouter<\n TApiClient = unknown,\n TSession = unknown,\n TRouteTree extends AnyRoute = AnyRoute,\n>(\n opts: CoreRouterOptions<TApiClient, TSession> & {\n context: RouterContextWithApi<TApiClient, TSession> & { authClient?: unknown };\n },\n) {\n const queryClient = opts.context.queryClient;\n const history = opts.history ?? createBrowserHistory();\n const cspNonce = opts.context.cspNonce;\n\n const routeTree = opts.routeTree ?? opts.defaultRouteTree;\n if (!routeTree) {\n throw new Error(\n \"createRouter: no route tree — compose failed and no core-only fallback was constructed\",\n );\n }\n\n const router = createTanStackRouter({\n routeTree: routeTree as TRouteTree,\n history,\n basepath: opts.basepath ?? opts.context.runtimeConfig?.runtime?.runtimeBasePath ?? \"/\",\n context: {\n queryClient,\n runtimeConfig: opts.context.runtimeConfig,\n cspNonce: opts.context.cspNonce,\n apiClient: opts.context.apiClient,\n authClient:\n opts.context.authClient ??\n createAuthClient({\n runtimeConfig: opts.context.runtimeConfig,\n cspNonce: opts.context.cspNonce,\n }),\n session: opts.context.session,\n locale: opts.context.locale,\n },\n ...(cspNonce ? { ssr: { nonce: cspNonce } } : {}),\n defaultPreload: \"intent\",\n scrollRestoration: true,\n defaultStructuralSharing: true,\n defaultPreloadStaleTime: 0,\n defaultPendingMinMs: 0,\n defaultErrorComponent: RouterError,\n defaultNotFoundComponent,\n defaultPendingComponent,\n dehydrate: () => {\n if (typeof window === \"undefined\") {\n return { queryClientState: dehydrate(queryClient) };\n }\n\n return { queryClientState: {} };\n },\n hydrate: (dehydrated: { queryClientState?: unknown }) => {\n if (typeof window !== \"undefined\" && dehydrated?.queryClientState) {\n hydrate(queryClient, dehydrated.queryClientState);\n }\n },\n });\n\n return { router, queryClient };\n}\n"],"mappings":";;;;;;;;;;;;;AAwBA,SAAgB,aAKd,MAGA;CACA,MAAM,cAAc,KAAK,QAAQ;CACjC,MAAM,UAAU,KAAK,WAAW,qBAAqB;CACrD,MAAM,WAAW,KAAK,QAAQ;CAE9B,MAAM,YAAY,KAAK,aAAa,KAAK;CACzC,IAAI,CAAC,WACH,MAAM,IAAI,MACR,wFACF;
|
|
1
|
+
{"version":3,"file":"router-client.mjs","names":["createTanStackRouter"],"sources":["../../src/ui/router-client.tsx"],"sourcesContent":["/**\n * Client router factory — creates a TanStack Router with browser history.\n * The app-specific route tree is injected as `defaultRouteTree` (the\n * bundled core-only fallback); the composed tree wins when manifest\n * construction produced one.\n */\n\nimport { dehydrate, hydrate } from \"@tanstack/react-query\";\nimport {\n type AnyRoute,\n createBrowserHistory,\n createRouter as createTanStackRouter,\n} from \"@tanstack/react-router\";\nimport { createAuthClient } from \"./auth\";\nimport { defaultNotFoundComponent, defaultPendingComponent } from \"./router-defaults\";\nimport { RouterError } from \"./router-error\";\nimport type { CreateRouterOptions, RouterContextWithApi } from \"./types\";\n\nexport interface CoreRouterOptions<TApiClient = unknown, TSession = unknown>\n extends CreateRouterOptions<TApiClient, TSession> {\n /** The app's generated route tree — the core-only fallback when no composed tree is passed. */\n defaultRouteTree?: unknown;\n}\n\nexport function createRouter<\n TApiClient = unknown,\n TSession = unknown,\n TRouteTree extends AnyRoute = AnyRoute,\n>(\n opts: CoreRouterOptions<TApiClient, TSession> & {\n context: RouterContextWithApi<TApiClient, TSession> & { authClient?: unknown };\n },\n) {\n const queryClient = opts.context.queryClient;\n const history = opts.history ?? createBrowserHistory();\n const cspNonce = opts.context.cspNonce;\n\n const routeTree = opts.routeTree ?? opts.defaultRouteTree;\n if (!routeTree) {\n throw new Error(\n \"createRouter: no route tree — compose failed and no core-only fallback was constructed\",\n );\n }\n\n const router = createTanStackRouter({\n routeTree: routeTree as TRouteTree,\n history,\n basepath: opts.basepath ?? opts.context.runtimeConfig?.runtime?.runtimeBasePath ?? \"/\",\n context: {\n queryClient,\n runtimeConfig: opts.context.runtimeConfig,\n cspNonce: opts.context.cspNonce,\n apiClient: opts.context.apiClient,\n authClient:\n opts.context.authClient ??\n createAuthClient({\n runtimeConfig: opts.context.runtimeConfig,\n cspNonce: opts.context.cspNonce,\n }),\n session: opts.context.session,\n locale: opts.context.locale,\n pluginNav: opts.context.pluginNav,\n },\n ...(cspNonce ? { ssr: { nonce: cspNonce } } : {}),\n defaultPreload: \"intent\",\n scrollRestoration: true,\n defaultStructuralSharing: true,\n defaultPreloadStaleTime: 0,\n defaultPendingMinMs: 0,\n defaultErrorComponent: RouterError,\n defaultNotFoundComponent,\n defaultPendingComponent,\n dehydrate: () => {\n if (typeof window === \"undefined\") {\n return { queryClientState: dehydrate(queryClient) };\n }\n\n return { queryClientState: {} };\n },\n hydrate: (dehydrated: { queryClientState?: unknown }) => {\n if (typeof window !== \"undefined\" && dehydrated?.queryClientState) {\n hydrate(queryClient, dehydrated.queryClientState);\n }\n },\n });\n\n return { router, queryClient };\n}\n"],"mappings":";;;;;;;;;;;;;AAwBA,SAAgB,aAKd,MAGA;CACA,MAAM,cAAc,KAAK,QAAQ;CACjC,MAAM,UAAU,KAAK,WAAW,qBAAqB;CACrD,MAAM,WAAW,KAAK,QAAQ;CAE9B,MAAM,YAAY,KAAK,aAAa,KAAK;CACzC,IAAI,CAAC,WACH,MAAM,IAAI,MACR,wFACF;CA6CF,OAAO;EAAE,QA1CMA,eAAqB;GACvB;GACX;GACA,UAAU,KAAK,YAAY,KAAK,QAAQ,eAAe,SAAS,mBAAmB;GACnF,SAAS;IACP;IACA,eAAe,KAAK,QAAQ;IAC5B,UAAU,KAAK,QAAQ;IACvB,WAAW,KAAK,QAAQ;IACxB,YACE,KAAK,QAAQ,cACb,iBAAiB;KACf,eAAe,KAAK,QAAQ;KAC5B,UAAU,KAAK,QAAQ;IACzB,CAAC;IACH,SAAS,KAAK,QAAQ;IACtB,QAAQ,KAAK,QAAQ;IACrB,WAAW,KAAK,QAAQ;GAC1B;GACA,GAAI,WAAW,EAAE,KAAK,EAAE,OAAO,SAAS,EAAE,IAAI,CAAC;GAC/C,gBAAgB;GAChB,mBAAmB;GACnB,0BAA0B;GAC1B,yBAAyB;GACzB,qBAAqB;GACrB,uBAAuB;GACvB;GACA;GACA,iBAAiB;IACf,IAAI,OAAO,WAAW,aACpB,OAAO,EAAE,kBAAkB,UAAU,WAAW,EAAE;IAGpD,OAAO,EAAE,kBAAkB,CAAC,EAAE;GAChC;GACA,UAAU,eAA+C;IACvD,IAAI,OAAO,WAAW,eAAe,YAAY,kBAC/C,QAAQ,aAAa,WAAW,gBAAgB;GAEpD;EACF,CAEc;EAAG;CAAY;AAC/B"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
|
|
3
|
-
const
|
|
3
|
+
const require_resolver = require('./resolver.cjs');
|
|
4
4
|
let node_fs = require("node:fs");
|
|
5
5
|
let node_path = require("node:path");
|
|
6
6
|
node_path = require_runtime.__toESM(node_path, 1);
|
|
@@ -46,9 +46,9 @@ function slotVersionFromManifest(base, manifest) {
|
|
|
46
46
|
function readStagedSlotVersion(base, pin) {
|
|
47
47
|
const bundleDir = process.env.BOS_BUNDLE_DIR;
|
|
48
48
|
if (!bundleDir) return null;
|
|
49
|
-
const slotDir =
|
|
49
|
+
const slotDir = require_resolver.bundleUrlToStagedPath(base, bundleDir);
|
|
50
50
|
if (!slotDir || !(0, node_fs.existsSync)(slotDir)) return null;
|
|
51
|
-
const pinnedManifestPath =
|
|
51
|
+
const pinnedManifestPath = require_resolver.resolveContained(slotDir, pin.manifest);
|
|
52
52
|
if (!pinnedManifestPath || (0, node_fs.existsSync)(pinnedManifestPath)) return null;
|
|
53
53
|
const versionsDir = node_path.default.join(slotDir, "versions");
|
|
54
54
|
if (!(0, node_fs.existsSync)(versionsDir)) return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version-manifest-resolve.cjs","names":["bundleUrlToStagedPath","existsSync","resolveContained","path","readdirSync","statSync","WorkspaceVersionManifestSchema","readFileSync","createHash"],"sources":["../src/version-manifest-resolve.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport path from \"node:path\";\nimport {\n type WorkspaceVersionManifest,\n WorkspaceVersionManifestSchema,\n} from \"every-plugin/version-manifest\";\nimport { bundleUrlToStagedPath, resolveContained } from \"./
|
|
1
|
+
{"version":3,"file":"version-manifest-resolve.cjs","names":["bundleUrlToStagedPath","existsSync","resolveContained","path","readdirSync","statSync","WorkspaceVersionManifestSchema","readFileSync","createHash"],"sources":["../src/version-manifest-resolve.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport path from \"node:path\";\nimport {\n type WorkspaceVersionManifest,\n WorkspaceVersionManifestSchema,\n} from \"every-plugin/version-manifest\";\nimport { bundleUrlToStagedPath, resolveContained } from \"./resolver\";\n\n/**\n * Version-manifest slot resolution (atomic-deploys 04): a config slot's\n * `pin` ({ manifest, integrity }) resolves to the derived entry-level fields\n * every consumer needs. The cache is keyed by the full pin — the pinned\n * bytes are immutable, so a verified entry is cached for the process\n * lifetime and serves as last-known-good if the origin later fails; a fetch\n * or SRI failure with nothing cached propagates (a boot-time resolution\n * failure fails the deploy, which is the platform's rollback).\n */\n\nexport interface ResolvedSlotVersion {\n /** Absolute URL of the content-hashed container entry. */\n entryUrl: string;\n entryIntegrity: string;\n /** Absolute URL of the hashed browser manifest (mf-manifest), when present. */\n browserManifestUrl?: string;\n /** Absolute URL of the content-hashed SSR entry, when present. */\n ssrEntryUrl?: string;\n ssrIntegrity?: string;\n /** Full per-file digest map of the dist (object path → SRI), when the\n * pinned manifest carries one — the diff base for skip-unchanged uploads. */\n files?: Record<string, string>;\n}\n\nexport interface SlotPin {\n /** versioned manifest filename, relative to the slot's production base */\n manifest: string;\n /** the manifest document's own SRI */\n integrity: string;\n}\n\nconst cache = new Map<string, ResolvedSlotVersion>();\n\nexport function clearSlotVersionCache(): void {\n cache.clear();\n}\n\nfunction fetchText(url: string, fetchImpl: typeof fetch): Promise<string> {\n return fetchImpl(url).then((response) => {\n if (!response.ok) throw new Error(`version manifest fetch failed: ${response.status}`);\n return response.text();\n });\n}\n\nfunction slotVersionFromManifest(\n base: string,\n manifest: WorkspaceVersionManifest,\n): ResolvedSlotVersion {\n const trimmedBase = base.replace(/\\/$/, \"\");\n return {\n entryUrl: `${trimmedBase}/${manifest.entry}`,\n entryIntegrity: manifest.entryIntegrity,\n ...(manifest.browserManifest\n ? { browserManifestUrl: `${trimmedBase}/${manifest.browserManifest.file}` }\n : {}),\n ...(manifest.ssr\n ? {\n ssrEntryUrl: `${trimmedBase}/${manifest.ssr.entry}`,\n ssrIntegrity: manifest.ssr.integrity,\n }\n : {}),\n ...(manifest.files ? { files: manifest.files } : {}),\n };\n}\n\n/**\n * Staged-slot preference (ADR 0020/0021 self-contained tier): when a runtime\n * stages its own namespace under `BOS_BUNDLE_DIR`, a slot resolves from the\n * staged dist's own version manifest instead of the config's pin — pinned\n * manifest bytes that predate the image (deploy lag after a release bump)\n * cannot exist in the staged namespace, so their hashed files would 404 the\n * disk and fall through to the network, where the stale immutable bytes\n * still answer 200 and boot a foreign build. The staged manifest is trusted\n * (staged by the image build itself) and skipped entirely when the slot is\n * absent from the staged namespace or the pinned manifest is present (the\n * normal healthy case, which keeps the pin's SRI check).\n */\nfunction readStagedSlotVersion(base: string, pin: SlotPin): ResolvedSlotVersion | null {\n const bundleDir = process.env.BOS_BUNDLE_DIR;\n if (!bundleDir) return null;\n\n const slotDir = bundleUrlToStagedPath(base, bundleDir);\n if (!slotDir || !existsSync(slotDir)) return null;\n\n const pinnedManifestPath = resolveContained(slotDir, pin.manifest);\n if (!pinnedManifestPath || existsSync(pinnedManifestPath)) return null;\n\n const versionsDir = path.join(slotDir, \"versions\");\n if (!existsSync(versionsDir)) return null;\n const manifests = readdirSync(versionsDir)\n .filter((name) => name.endsWith(\".json\"))\n .map((name) => path.join(versionsDir, name))\n .filter((file) => statSync(file).isFile())\n .sort((a, b) => statSync(b).mtimeMs - statSync(a).mtimeMs || (a < b ? -1 : 1));\n if (manifests.length === 0) return null;\n const manifestPath = manifests[0];\n if (!manifestPath) return null;\n\n try {\n const manifest = WorkspaceVersionManifestSchema.parse(\n JSON.parse(readFileSync(manifestPath, \"utf8\")),\n );\n return slotVersionFromManifest(base, manifest);\n } catch {\n return null;\n }\n}\n\nexport async function resolveSlotVersion(input: {\n base: string;\n pin: SlotPin;\n fetchImpl?: typeof fetch;\n}): Promise<ResolvedSlotVersion> {\n const key = `${input.base}::${input.pin.manifest}::${input.pin.integrity}`;\n // content-addressed: a verified pin is cached for the process lifetime and\n // never refetched — the cache IS the last-known-good\n const cached = cache.get(key);\n if (cached) return cached;\n\n const staged = readStagedSlotVersion(input.base, input.pin);\n if (staged) {\n cache.set(key, staged);\n return staged;\n }\n\n const manifestUrl = `${input.base.replace(/\\/$/, \"\")}/${input.pin.manifest.replace(/^\\//, \"\")}`;\n const body = await fetchText(manifestUrl, input.fetchImpl ?? fetch);\n const computed = `sha384-${createHash(\"sha384\").update(body).digest(\"base64\")}`;\n if (computed !== input.pin.integrity) {\n throw new Error(\n `[SRI] version manifest integrity mismatch for ${manifestUrl}\\n Expected: ${input.pin.integrity}\\n Computed: ${computed}`,\n );\n }\n const manifest: WorkspaceVersionManifest = WorkspaceVersionManifestSchema.parse(JSON.parse(body));\n\n const resolved = slotVersionFromManifest(input.base, manifest);\n cache.set(key, resolved);\n return resolved;\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { bundleUrlToStagedPath, resolveContained } from "./
|
|
1
|
+
import { bundleUrlToStagedPath, resolveContained } from "./resolver.mjs";
|
|
2
2
|
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { createHash } from "node:crypto";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version-manifest-resolve.mjs","names":[],"sources":["../src/version-manifest-resolve.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport path from \"node:path\";\nimport {\n type WorkspaceVersionManifest,\n WorkspaceVersionManifestSchema,\n} from \"every-plugin/version-manifest\";\nimport { bundleUrlToStagedPath, resolveContained } from \"./
|
|
1
|
+
{"version":3,"file":"version-manifest-resolve.mjs","names":[],"sources":["../src/version-manifest-resolve.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport path from \"node:path\";\nimport {\n type WorkspaceVersionManifest,\n WorkspaceVersionManifestSchema,\n} from \"every-plugin/version-manifest\";\nimport { bundleUrlToStagedPath, resolveContained } from \"./resolver\";\n\n/**\n * Version-manifest slot resolution (atomic-deploys 04): a config slot's\n * `pin` ({ manifest, integrity }) resolves to the derived entry-level fields\n * every consumer needs. The cache is keyed by the full pin — the pinned\n * bytes are immutable, so a verified entry is cached for the process\n * lifetime and serves as last-known-good if the origin later fails; a fetch\n * or SRI failure with nothing cached propagates (a boot-time resolution\n * failure fails the deploy, which is the platform's rollback).\n */\n\nexport interface ResolvedSlotVersion {\n /** Absolute URL of the content-hashed container entry. */\n entryUrl: string;\n entryIntegrity: string;\n /** Absolute URL of the hashed browser manifest (mf-manifest), when present. */\n browserManifestUrl?: string;\n /** Absolute URL of the content-hashed SSR entry, when present. */\n ssrEntryUrl?: string;\n ssrIntegrity?: string;\n /** Full per-file digest map of the dist (object path → SRI), when the\n * pinned manifest carries one — the diff base for skip-unchanged uploads. */\n files?: Record<string, string>;\n}\n\nexport interface SlotPin {\n /** versioned manifest filename, relative to the slot's production base */\n manifest: string;\n /** the manifest document's own SRI */\n integrity: string;\n}\n\nconst cache = new Map<string, ResolvedSlotVersion>();\n\nexport function clearSlotVersionCache(): void {\n cache.clear();\n}\n\nfunction fetchText(url: string, fetchImpl: typeof fetch): Promise<string> {\n return fetchImpl(url).then((response) => {\n if (!response.ok) throw new Error(`version manifest fetch failed: ${response.status}`);\n return response.text();\n });\n}\n\nfunction slotVersionFromManifest(\n base: string,\n manifest: WorkspaceVersionManifest,\n): ResolvedSlotVersion {\n const trimmedBase = base.replace(/\\/$/, \"\");\n return {\n entryUrl: `${trimmedBase}/${manifest.entry}`,\n entryIntegrity: manifest.entryIntegrity,\n ...(manifest.browserManifest\n ? { browserManifestUrl: `${trimmedBase}/${manifest.browserManifest.file}` }\n : {}),\n ...(manifest.ssr\n ? {\n ssrEntryUrl: `${trimmedBase}/${manifest.ssr.entry}`,\n ssrIntegrity: manifest.ssr.integrity,\n }\n : {}),\n ...(manifest.files ? { files: manifest.files } : {}),\n };\n}\n\n/**\n * Staged-slot preference (ADR 0020/0021 self-contained tier): when a runtime\n * stages its own namespace under `BOS_BUNDLE_DIR`, a slot resolves from the\n * staged dist's own version manifest instead of the config's pin — pinned\n * manifest bytes that predate the image (deploy lag after a release bump)\n * cannot exist in the staged namespace, so their hashed files would 404 the\n * disk and fall through to the network, where the stale immutable bytes\n * still answer 200 and boot a foreign build. The staged manifest is trusted\n * (staged by the image build itself) and skipped entirely when the slot is\n * absent from the staged namespace or the pinned manifest is present (the\n * normal healthy case, which keeps the pin's SRI check).\n */\nfunction readStagedSlotVersion(base: string, pin: SlotPin): ResolvedSlotVersion | null {\n const bundleDir = process.env.BOS_BUNDLE_DIR;\n if (!bundleDir) return null;\n\n const slotDir = bundleUrlToStagedPath(base, bundleDir);\n if (!slotDir || !existsSync(slotDir)) return null;\n\n const pinnedManifestPath = resolveContained(slotDir, pin.manifest);\n if (!pinnedManifestPath || existsSync(pinnedManifestPath)) return null;\n\n const versionsDir = path.join(slotDir, \"versions\");\n if (!existsSync(versionsDir)) return null;\n const manifests = readdirSync(versionsDir)\n .filter((name) => name.endsWith(\".json\"))\n .map((name) => path.join(versionsDir, name))\n .filter((file) => statSync(file).isFile())\n .sort((a, b) => statSync(b).mtimeMs - statSync(a).mtimeMs || (a < b ? -1 : 1));\n if (manifests.length === 0) return null;\n const manifestPath = manifests[0];\n if (!manifestPath) return null;\n\n try {\n const manifest = WorkspaceVersionManifestSchema.parse(\n JSON.parse(readFileSync(manifestPath, \"utf8\")),\n );\n return slotVersionFromManifest(base, manifest);\n } catch {\n return null;\n }\n}\n\nexport async function resolveSlotVersion(input: {\n base: string;\n pin: SlotPin;\n fetchImpl?: typeof fetch;\n}): Promise<ResolvedSlotVersion> {\n const key = `${input.base}::${input.pin.manifest}::${input.pin.integrity}`;\n // content-addressed: a verified pin is cached for the process lifetime and\n // never refetched — the cache IS the last-known-good\n const cached = cache.get(key);\n if (cached) return cached;\n\n const staged = readStagedSlotVersion(input.base, input.pin);\n if (staged) {\n cache.set(key, staged);\n return staged;\n }\n\n const manifestUrl = `${input.base.replace(/\\/$/, \"\")}/${input.pin.manifest.replace(/^\\//, \"\")}`;\n const body = await fetchText(manifestUrl, input.fetchImpl ?? fetch);\n const computed = `sha384-${createHash(\"sha384\").update(body).digest(\"base64\")}`;\n if (computed !== input.pin.integrity) {\n throw new Error(\n `[SRI] version manifest integrity mismatch for ${manifestUrl}\\n Expected: ${input.pin.integrity}\\n Computed: ${computed}`,\n );\n }\n const manifest: WorkspaceVersionManifest = WorkspaceVersionManifestSchema.parse(JSON.parse(body));\n\n const resolved = slotVersionFromManifest(input.base, manifest);\n cache.set(key, resolved);\n return resolved;\n}\n"],"mappings":"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"}
|
package/dist/workspace.cjs
CHANGED
|
@@ -2,8 +2,8 @@ const require_run = require('./utils/run.cjs');
|
|
|
2
2
|
let node_fs = require("node:fs");
|
|
3
3
|
let node_path = require("node:path");
|
|
4
4
|
let effect = require("effect");
|
|
5
|
-
let yaml = require("yaml");
|
|
6
5
|
let node_fs_promises = require("node:fs/promises");
|
|
6
|
+
let yaml = require("yaml");
|
|
7
7
|
|
|
8
8
|
//#region src/workspace.ts
|
|
9
9
|
var DepsBuildFailure = class extends effect.Data.TaggedError("DepsBuildFailure") {
|
package/dist/workspace.mjs
CHANGED
|
@@ -2,8 +2,8 @@ import { run } from "./utils/run.mjs";
|
|
|
2
2
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
3
3
|
import { dirname, join, resolve } from "node:path";
|
|
4
4
|
import { Data } from "effect";
|
|
5
|
-
import { parse } from "yaml";
|
|
6
5
|
import { readdir, stat } from "node:fs/promises";
|
|
6
|
+
import { parse } from "yaml";
|
|
7
7
|
|
|
8
8
|
//#region src/workspace.ts
|
|
9
9
|
var DepsBuildFailure = class extends Data.TaggedError("DepsBuildFailure") {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "everything-dev",
|
|
3
|
-
"version": "2.0.0-rc.
|
|
3
|
+
"version": "2.0.0-rc.8",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=20.11"
|
|
@@ -54,10 +54,10 @@
|
|
|
54
54
|
"import": "./dist/version-manifest-resolve.mjs",
|
|
55
55
|
"require": "./dist/version-manifest-resolve.cjs"
|
|
56
56
|
},
|
|
57
|
-
"./
|
|
58
|
-
"types": "./dist/
|
|
59
|
-
"import": "./dist/
|
|
60
|
-
"require": "./dist/
|
|
57
|
+
"./resolver": {
|
|
58
|
+
"types": "./dist/resolver.d.mts",
|
|
59
|
+
"import": "./dist/resolver.mjs",
|
|
60
|
+
"require": "./dist/resolver.cjs"
|
|
61
61
|
},
|
|
62
62
|
"./fastkv": {
|
|
63
63
|
"types": "./dist/fastkv.d.mts",
|
|
@@ -69,10 +69,10 @@
|
|
|
69
69
|
"import": "./dist/contract.meta.mjs",
|
|
70
70
|
"require": "./dist/contract.meta.cjs"
|
|
71
71
|
},
|
|
72
|
-
"./
|
|
73
|
-
"types": "./dist/
|
|
74
|
-
"import": "./dist/
|
|
75
|
-
"require": "./dist/
|
|
72
|
+
"./federation": {
|
|
73
|
+
"types": "./dist/federation.d.mts",
|
|
74
|
+
"import": "./dist/federation.mjs",
|
|
75
|
+
"require": "./dist/federation.cjs"
|
|
76
76
|
},
|
|
77
77
|
"./integrity": {
|
|
78
78
|
"types": "./dist/integrity.d.mts",
|
|
@@ -243,7 +243,7 @@
|
|
|
243
243
|
"dotenv": "^17.3.1",
|
|
244
244
|
"effect": "4.0.0-rc.117",
|
|
245
245
|
"@everything-dev/upload-app": "workspace:^",
|
|
246
|
-
"every-plugin": "^3.0.0-rc.
|
|
246
|
+
"every-plugin": "^3.0.0-rc.5",
|
|
247
247
|
"execa": "^9.5.2",
|
|
248
248
|
"glob": "^13.0.6",
|
|
249
249
|
"near-kit": "^0.20.2",
|
|
@@ -253,8 +253,8 @@
|
|
|
253
253
|
"zod": "4.6.5"
|
|
254
254
|
},
|
|
255
255
|
"peerDependencies": {
|
|
256
|
-
"@better-auth/api-key": "1.
|
|
257
|
-
"@better-auth/passkey": "1.
|
|
256
|
+
"@better-auth/api-key": "1.7.7",
|
|
257
|
+
"@better-auth/passkey": "1.7.7",
|
|
258
258
|
"@lingui/core": "5.9.0",
|
|
259
259
|
"@lingui/react": "5.9.0",
|
|
260
260
|
"@orpc/client": "2.0.0-beta.35",
|
|
@@ -262,8 +262,8 @@
|
|
|
262
262
|
"@orpc/tanstack-query": "2.0.0-beta.35",
|
|
263
263
|
"@tanstack/react-query": ">=5.0.0",
|
|
264
264
|
"@tanstack/react-router": ">=1.0.0",
|
|
265
|
-
"better-auth": "1.
|
|
266
|
-
"better-near-auth": "^2.0.0-rc.
|
|
265
|
+
"better-auth": "1.7.7",
|
|
266
|
+
"better-near-auth": "^2.0.0-rc.1",
|
|
267
267
|
"effect": "4.0.0-rc.117",
|
|
268
268
|
"react": "19.2.4",
|
|
269
269
|
"react-dom": "19.2.4",
|
|
@@ -309,8 +309,8 @@
|
|
|
309
309
|
}
|
|
310
310
|
},
|
|
311
311
|
"devDependencies": {
|
|
312
|
-
"@better-auth/api-key": "1.
|
|
313
|
-
"@better-auth/passkey": "1.
|
|
312
|
+
"@better-auth/api-key": "1.7.7",
|
|
313
|
+
"@better-auth/passkey": "1.7.7",
|
|
314
314
|
"@lingui/core": "5.9.0",
|
|
315
315
|
"@lingui/react": "5.9.0",
|
|
316
316
|
"@module-federation/rsbuild-plugin": "^2.9.0",
|
|
@@ -327,8 +327,8 @@
|
|
|
327
327
|
"@tanstack/router-plugin": "1.168.35",
|
|
328
328
|
"@types/node": "^25.0.3",
|
|
329
329
|
"@types/tar": "^7.0.0",
|
|
330
|
-
"better-auth": "1.
|
|
331
|
-
"better-near-auth": "^2.0.0-rc.
|
|
330
|
+
"better-auth": "1.7.7",
|
|
331
|
+
"better-near-auth": "^2.0.0-rc.1",
|
|
332
332
|
"jsdom": "^30.0.1",
|
|
333
333
|
"react": "19.2.4",
|
|
334
334
|
"react-dom": "19.2.4",
|
|
@@ -104,7 +104,7 @@ builder.myRoute.use(requireAuth).handler(async ({ input, context }) => {
|
|
|
104
104
|
});
|
|
105
105
|
```
|
|
106
106
|
|
|
107
|
-
Available: `requireAuth`, `requireAuthOrApiKey`, `requireRole("admin")`, `requireOrganization`, `requireOrgRole("owner")`, `requireApiKey
|
|
107
|
+
Available: `requireAuth`, `requireAuthOrApiKey`, `requireRole("admin")`, `requireOrganization`, `requireOrgRole("owner")`, `requireApiKey`, `requirePermission("resource", "action")` (gates on the caller's effective permissions from the auth plugin's `getContext` — see `references/middleware.md`). Apply via `.use()`:
|
|
108
108
|
|
|
109
109
|
```ts
|
|
110
110
|
builder.authHealth.use(requireAuth).handler(...)
|
|
@@ -204,16 +204,19 @@ initialize: (config, plugins, _tools) =>
|
|
|
204
204
|
})
|
|
205
205
|
```
|
|
206
206
|
|
|
207
|
-
Use `
|
|
207
|
+
Use the host's session middleware for in-process auth checks. The canonical middleware import is `everything-dev/api` (`packages/everything-dev/src/api/auth-middleware.ts:34`). For in-process calls, access the auth client via the injected `context.authClient` in route handlers, or use `useAuthClient()` from `@/app` in the UI.
|
|
208
208
|
|
|
209
|
-
|
|
210
|
-
import { getAuthClient, createAuthMiddleware } from "./lib/auth";
|
|
209
|
+
## Auth on the Client
|
|
211
210
|
|
|
212
|
-
|
|
213
|
-
const session = await authClient.getSession();
|
|
214
|
-
```
|
|
211
|
+
Create the client in `ui/src/lib/auth.ts`:
|
|
215
212
|
|
|
216
|
-
|
|
213
|
+
```ts
|
|
214
|
+
export function createAuthClient(runtimeConfig) {
|
|
215
|
+
return betterAuth.createClient({
|
|
216
|
+
baseURL: runtimeConfig.authBaseUrl,
|
|
217
|
+
plugins: [siwn({ recipients, networkId }), passkey(), organization(), admin(), apiKey(), anonymous(), phone()],
|
|
218
|
+
});
|
|
219
|
+
}
|
|
217
220
|
|
|
218
221
|
## Auth on the Client
|
|
219
222
|
|
|
@@ -428,7 +431,7 @@ The host (`host/src/program.ts`) creates RPC and OpenAPI handlers from each plug
|
|
|
428
431
|
|
|
429
432
|
**"Add an admin-only route."** Contract declares `.errors({ UNAUTHORIZED, FORBIDDEN })`; handler is `.effect(function* ...)` and guards with `return yield* Effect.fail(errors.UNAUTHORIZED({ apiKeyProvided: !!context.apiKey }))` — note all-optional error shapes still need an explicit `data: {}`. For shared middleware shapes, see `packages/everything-dev/src/api/auth-middleware.ts`.
|
|
430
433
|
|
|
431
|
-
**"Call the auth plugin from my route."**
|
|
434
|
+
**"Call the auth plugin from my route."** The host injects `context.authClient` into route handlers via the plugin client. Access it as `context.authClient.getSession()` for in-process calls, or use `useAuthClient()` from `@/app` in the UI. See `packages/everything-dev/src/api/auth-middleware.ts` for the middleware pattern and `context.userId`/`context.user` narrowing with `requireAuth`.
|
|
432
435
|
|
|
433
436
|
**"Wire an SSE route."** Contract: `.output(eventIterator(Schema))`. Handler: async generator that subscribes to the publisher and yields per event, filtering server-side on `pluginId`/query params.
|
|
434
437
|
|
|
@@ -36,3 +36,41 @@ ctx.organization.organization?.metadata?.plan;
|
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
Also available: `OrgMemberAuthenticatedContext<TMeta>` (guarantees `organization.member` is non-null).
|
|
39
|
+
|
|
40
|
+
## `requirePermission(resource, action)`
|
|
41
|
+
|
|
42
|
+
Gates a route on the caller's **effective permissions** — the map the auth plugin's
|
|
43
|
+
`getContext` returns (session principals: the active organization's role grants;
|
|
44
|
+
API-key principals: the key's declared permissions; anonymous: null, denied).
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
const { requirePermission } = createAuthMiddleware(builder);
|
|
48
|
+
|
|
49
|
+
builder.createProposal
|
|
50
|
+
.use(requireAuth)
|
|
51
|
+
.use(requirePermission("proposal", "create"))
|
|
52
|
+
.handler(...);
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Fails `FORBIDDEN` with `data: { requiredPermissions: ["proposal:create"] }` when the
|
|
56
|
+
map lacks the grant.
|
|
57
|
+
|
|
58
|
+
**Team scope.** `getContext`'s `organization.teams` entries carry a per-team
|
|
59
|
+
`permissions` map (the caller's `team_member.role` grants unioned per team). Pass a
|
|
60
|
+
team resolver to gate on the team resolved from the route input:
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
builder.updateTeamTask
|
|
64
|
+
.use(requireAuth)
|
|
65
|
+
.use(requirePermission("team", "update", { scope: "team", teamId: (input) => input.teamId }))
|
|
66
|
+
.handler(...);
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The check reads the caller's grants for that specific team; a team they are not a
|
|
70
|
+
member of (or one lacking the grant) is denied. Scope boundary (ADR 0028): the middleware can only see the
|
|
71
|
+
request context, so it gates *active-organization* permissions; checks against an
|
|
72
|
+
*explicit* organization id from route input (or data-masking checks) stay
|
|
73
|
+
service-side via Better Auth `hasPermission`, which evaluates the same
|
|
74
|
+
config-declared roles. The permission surface itself is config-declared in the auth
|
|
75
|
+
plugin's `siwn.permissions` — the plugin ships no defaults (see
|
|
76
|
+
`docs/adr/0028-config-declared-permissions.md`).
|
|
@@ -9,7 +9,7 @@ metadata:
|
|
|
9
9
|
|
|
10
10
|
# CLI Command Reference
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
19 `bos` commands organised by workflow category.
|
|
13
13
|
|
|
14
14
|
## Development
|
|
15
15
|
|
|
@@ -135,7 +135,7 @@ Output includes installed vs latest versions for each workspace package, whether
|
|
|
135
135
|
|
|
136
136
|
Publish the resolved config to the FastKV on-chain registry. Optionally build and deploy workspaces first.
|
|
137
137
|
|
|
138
|
-
**Flags:** `--deploy` `--dry-run` `--network <mainnet|testnet>` `--private-key <key>` `--env <production|staging>` `--packages <list|all|local>`
|
|
138
|
+
**Flags:** `--deploy` `--dry-run` `--network <mainnet|testnet>` `--private-key <key>` `--wallet` `--env <production|staging>` `--packages <list|all|local>`
|
|
139
139
|
|
|
140
140
|
```bash
|
|
141
141
|
bos publish # publish current config snapshot
|
|
@@ -143,6 +143,7 @@ bos publish --deploy # build all + deploy + publish
|
|
|
143
143
|
bos publish --deploy --packages local # build/deploy only the workspaces owned by this repo (CI default)
|
|
144
144
|
bos publish --dry-run # preview what would be published
|
|
145
145
|
bos publish --network testnet # publish to testnet registry
|
|
146
|
+
bos publish --wallet # gasless: sign in a browser, relayed delegate write — no local key needed
|
|
146
147
|
```
|
|
147
148
|
|
|
148
149
|
→ [`publish-sync`](.) skill for config sections, SRI integrity, rollback, and FastKV troubleshooting.
|
|
@@ -174,16 +175,31 @@ bos deploy --service my-railway # override Railway service name
|
|
|
174
175
|
|
|
175
176
|
→ [`publish-sync`](.) skill and [`super-app`](.) for tenant-aware deploy considerations.
|
|
176
177
|
|
|
178
|
+
### `bos login` / `bos logout`
|
|
179
|
+
|
|
180
|
+
Establish publish/CLI identity without a seed phrase or private key. `bos login` opens a browser (one approval), persists a device-named API key in `.bos/session.json` (gitignored), and works for both the publish path and API access (`x-api-key` on `/api/*`, `/api/rpc/*`, `/api/mcp`).
|
|
181
|
+
|
|
182
|
+
**Flags (login):** `--key` (additionally mint and export a publish-scoped function-call key to `~/.near-credentials`)
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
bos login # browser approval → API key in .bos/session.json
|
|
186
|
+
bos login --key # also export a scoped publish key (near-CLI format)
|
|
187
|
+
bos logout # revoke the API key (best-effort) + delete the handle and exported key
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Sessions/keys expire (90 days by default); re-login is non-destructive. → [`talk-to-the-app`](.) skill for the authentication model and MCP access.
|
|
191
|
+
|
|
177
192
|
### `bos key generate`
|
|
178
193
|
|
|
179
194
|
Generate a publish access key (NEAR function-call key) scoped to the FastKV registry contract.
|
|
180
|
-
If existing publish keys are found on the account, you will be prompted to
|
|
195
|
+
If existing publish keys are found on the account, you will be prompted — the prompt defaults to **keeping** them.
|
|
181
196
|
|
|
182
|
-
**Flags:** `--allowance <amount>` (default: `1NEAR`)
|
|
197
|
+
**Flags:** `--allowance <amount>` (default: `1NEAR`) `--[no-]remove-old-keys` (default: ask on a TTY, keep when non-interactive)
|
|
183
198
|
|
|
184
199
|
```bash
|
|
185
|
-
bos key generate
|
|
186
|
-
bos key generate --allowance 2NEAR
|
|
200
|
+
bos key generate # generate key with default allowance
|
|
201
|
+
bos key generate --allowance 2NEAR # custom allowance
|
|
202
|
+
bos key generate --remove-old-keys # also remove existing publish key(s) without prompting
|
|
187
203
|
```
|
|
188
204
|
|
|
189
205
|
Outputs the public key, private key, and registry contract address. The generated key can only call the set and get methods on the BOS registry contract — it cannot transfer funds or call other contracts.
|
|
@@ -36,19 +36,46 @@ There is no network parameter anywhere — the origin is the choice.
|
|
|
36
36
|
|
|
37
37
|
## Authentication
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
Every API surface — `/api/*` (REST), `/api/rpc/*` (oRPC RPC), and `/api/mcp`
|
|
40
|
+
(MCP) — requires a session or an API key. Anonymous requests get `401` with a
|
|
41
|
+
`WWW-Authenticate` hint (this includes MCP `tools/list`: the tool catalog is
|
|
42
|
+
not disclosed to unauthenticated callers). Use an **API key**:
|
|
43
|
+
|
|
44
|
+
**Path A — create one in the app UI.**
|
|
40
45
|
|
|
41
46
|
1. Sign in with your NEAR wallet (SIWN) at the app.
|
|
42
47
|
2. Navigate to **Settings → API Keys** at `/settings/api-keys`.
|
|
43
48
|
3. Create a new key — the full secret (`api_...`) is shown once, copy it immediately.
|
|
44
|
-
|
|
49
|
+
|
|
50
|
+
**Path B — no UI needed: `bos login`** (for CLI sessions and agents with a
|
|
51
|
+
browser available):
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
bos login
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Opens a browser, you approve once (NEAR SIWN), and the CLI persists a
|
|
58
|
+
device-named API key in `.bos/session.json` (gitignored, 0600). Same key, same
|
|
59
|
+
header — pass it on every request:
|
|
45
60
|
|
|
46
61
|
```
|
|
47
62
|
x-api-key: api_your_key_here
|
|
48
63
|
```
|
|
49
64
|
|
|
50
|
-
|
|
51
|
-
(
|
|
65
|
+
Keys carry optional permissions; a call outside them refuses with 403. Keys
|
|
66
|
+
expire (90 days by default) and are revocable at `/settings/api-keys` —
|
|
67
|
+
re-run `bos login` (or create a fresh key in the UI) when a key dies.
|
|
68
|
+
|
|
69
|
+
**Other credentials:**
|
|
70
|
+
|
|
71
|
+
- `bos login --key` mints a publish-scoped function-call access key
|
|
72
|
+
(`~/.near-credentials`) for the publish path — not an API-key replacement.
|
|
73
|
+
- Device-link session tokens (`POST /device/token` +
|
|
74
|
+
`POST /device-link/claim`, one-time hashed claim) yield a real Better Auth
|
|
75
|
+
session that also passes the gate — cookie transport, no revocation UI.
|
|
76
|
+
For MCP and agent work, prefer the API key.
|
|
77
|
+
- For CI or a browser-less agent: create a key once (UI or `bos login` from a
|
|
78
|
+
machine with a browser) and pass it as `x-api-key` in the pipeline.
|
|
52
79
|
|
|
53
80
|
## MCP
|
|
54
81
|
|
|
@@ -128,7 +155,7 @@ with write permission.
|
|
|
128
155
|
|
|
129
156
|
| status | do |
|
|
130
157
|
|---|---|
|
|
131
|
-
| `401` | no
|
|
158
|
+
| `401` | no key sent, a bad/revoked key, or an anonymous caller — if you have a key, check the `x-api-key` header reached the request; if not, get one (Paths A/B above); MCP `tools/list` is also gated |
|
|
132
159
|
| `403` | the key lacks permission — the owner edits the key's permissions; do not retry unchanged |
|
|
133
160
|
| `404` | wrong surface or path — re-check `/api/spec.json`; plugin RPC mounts are `/api/rpc/<pluginKey>` |
|
|
134
161
|
| `429` | rate limited — wait as the response says, then once more |
|