@cedarjs/tenancy 7.0.0-canary.3092

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.
Files changed (41) hide show
  1. package/README.md +98 -0
  2. package/dist/auth.d.ts +28 -0
  3. package/dist/auth.d.ts.map +1 -0
  4. package/dist/auth.js +47 -0
  5. package/dist/context.d.ts +121 -0
  6. package/dist/context.d.ts.map +1 -0
  7. package/dist/context.js +84 -0
  8. package/dist/errors.d.ts +10 -0
  9. package/dist/errors.d.ts.map +1 -0
  10. package/dist/errors.js +6 -0
  11. package/dist/index.d.ts +6 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +7 -0
  14. package/dist/prismaExtension.d.ts +89 -0
  15. package/dist/prismaExtension.d.ts.map +1 -0
  16. package/dist/prismaExtension.js +583 -0
  17. package/dist/web/OrgContext.d.ts +8 -0
  18. package/dist/web/OrgContext.d.ts.map +1 -0
  19. package/dist/web/OrgContext.js +7 -0
  20. package/dist/web/OrgScope.d.ts +29 -0
  21. package/dist/web/OrgScope.d.ts.map +1 -0
  22. package/dist/web/OrgScope.js +107 -0
  23. package/dist/web/getMemberships.d.ts +8 -0
  24. package/dist/web/getMemberships.d.ts.map +1 -0
  25. package/dist/web/getMemberships.js +25 -0
  26. package/dist/web/hasOrgRole.d.ts +12 -0
  27. package/dist/web/hasOrgRole.d.ts.map +1 -0
  28. package/dist/web/hasOrgRole.js +16 -0
  29. package/dist/web/index.d.ts +9 -0
  30. package/dist/web/index.d.ts.map +1 -0
  31. package/dist/web/index.js +14 -0
  32. package/dist/web/orgClients.d.ts +27 -0
  33. package/dist/web/orgClients.d.ts.map +1 -0
  34. package/dist/web/orgClients.js +37 -0
  35. package/dist/web/types.d.ts +36 -0
  36. package/dist/web/types.d.ts.map +1 -0
  37. package/dist/web/types.js +0 -0
  38. package/dist/web/useCurrentOrg.d.ts +10 -0
  39. package/dist/web/useCurrentOrg.d.ts.map +1 -0
  40. package/dist/web/useCurrentOrg.js +12 -0
  41. package/package.json +105 -0
@@ -0,0 +1,107 @@
1
+ import { Fragment, jsx } from "react/jsx-runtime";
2
+ import React from "react";
3
+ import { ApolloProvider } from "@apollo/client/react";
4
+ import { useNoAuth } from "@cedarjs/auth";
5
+ import { navigate, useLocation, useParams } from "@cedarjs/router";
6
+ import { useCreateApolloClient } from "@cedarjs/web/apollo";
7
+ import { getMemberships } from "./getMemberships.js";
8
+ import { hasOrgRole } from "./hasOrgRole.js";
9
+ import { clearOrgClients, dropOrgClient, getOrgClient } from "./orgClients.js";
10
+ import { OrgContext } from "./OrgContext.js";
11
+ const CEDAR_ORG_HEADER = "cedar-org";
12
+ function membershipRoleMap(memberships) {
13
+ return new Map(memberships.map((m) => [m.organizationId, m.role]));
14
+ }
15
+ function OrgScope({
16
+ orgSlug: orgSlugProp,
17
+ notAMember = null,
18
+ useAuth = useNoAuth,
19
+ onSetOrg,
20
+ children
21
+ }) {
22
+ const params = useParams();
23
+ const location = useLocation();
24
+ const createClient = useCreateApolloClient();
25
+ const { isAuthenticated, currentUser } = useAuth();
26
+ const orgSlug = orgSlugProp ?? params["orgSlug"];
27
+ const memberships = getMemberships(currentUser);
28
+ const userId = typeof currentUser?.["id"] === "string" ? currentUser["id"] : void 0;
29
+ const membershipSignature = memberships.map((m) => `${m.organizationId}:${m.role}`).sort().join(",");
30
+ const lastAuthUserIdRef = React.useRef(userId);
31
+ const lastMembershipsRef = React.useRef(
32
+ membershipRoleMap(memberships)
33
+ );
34
+ const [, forceRenderAfterTeardown] = React.useReducer((c) => c + 1, 0);
35
+ React.useEffect(() => {
36
+ const previousUserId = lastAuthUserIdRef.current;
37
+ const userChanged = previousUserId !== void 0 && previousUserId !== userId;
38
+ if (!isAuthenticated || userChanged) {
39
+ lastAuthUserIdRef.current = userId;
40
+ lastMembershipsRef.current = /* @__PURE__ */ new Map();
41
+ void clearOrgClients();
42
+ forceRenderAfterTeardown();
43
+ return;
44
+ }
45
+ lastAuthUserIdRef.current = userId;
46
+ const nextMemberships = membershipRoleMap(memberships);
47
+ let dropped = false;
48
+ if (userId) {
49
+ for (const [organizationId, role] of lastMembershipsRef.current) {
50
+ const currentRole = nextMemberships.get(organizationId);
51
+ if (currentRole === void 0 || currentRole !== role) {
52
+ void dropOrgClient(userId, organizationId);
53
+ dropped = true;
54
+ }
55
+ }
56
+ }
57
+ lastMembershipsRef.current = nextMemberships;
58
+ if (dropped) {
59
+ forceRenderAfterTeardown();
60
+ }
61
+ }, [isAuthenticated, userId, membershipSignature]);
62
+ const setOrg = React.useCallback(
63
+ (idOrSlug) => {
64
+ if (onSetOrg) {
65
+ onSetOrg(idOrSlug);
66
+ return;
67
+ }
68
+ const currentSlug = params["orgSlug"];
69
+ if (!currentSlug) {
70
+ throw new Error(
71
+ "useCurrentOrg().setOrg has no orgSlug route param to replace and no onSetOrg prop was given to OrgScope"
72
+ );
73
+ }
74
+ const nextPathname = location.pathname.split("/").map((segment) => segment === currentSlug ? idOrSlug : segment).join("/");
75
+ navigate(nextPathname + location.search + location.hash);
76
+ },
77
+ [onSetOrg, params, location.pathname, location.search, location.hash]
78
+ );
79
+ const membership = orgSlug ? memberships.find((m) => m.organization.slug === orgSlug) : void 0;
80
+ if (!membership || !userId) {
81
+ return /* @__PURE__ */ jsx(Fragment, { children: notAMember });
82
+ }
83
+ const org = {
84
+ id: membership.organizationId,
85
+ slug: membership.organization.slug,
86
+ name: membership.organization.name,
87
+ role: membership.role,
88
+ membershipId: membership.id
89
+ };
90
+ const orgClient = getOrgClient({
91
+ userId,
92
+ organizationId: membership.organizationId,
93
+ createClient: () => createClient({
94
+ headers: { [CEDAR_ORG_HEADER]: membership.organizationId }
95
+ })
96
+ });
97
+ const contextValue = {
98
+ org,
99
+ memberships,
100
+ hasOrgRole: (roles, organizationId) => hasOrgRole(memberships, roles, organizationId ?? org.id),
101
+ setOrg
102
+ };
103
+ return /* @__PURE__ */ jsx(ApolloProvider, { client: orgClient, children: /* @__PURE__ */ jsx(OrgContext.Provider, { value: contextValue, children }) });
104
+ }
105
+ export {
106
+ OrgScope
107
+ };
@@ -0,0 +1,8 @@
1
+ import type { OrgMembership } from './types.js';
2
+ /**
3
+ * Reads `currentUser.memberships` defensively, since `currentUser` is
4
+ * `unknown` shape from the app's `useAuth()`. Returns `[]` when it is
5
+ * missing, not an array, or its entries are not memberships.
6
+ */
7
+ export declare function getMemberships(currentUser: unknown): OrgMembership[];
8
+ //# sourceMappingURL=getMemberships.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getMemberships.d.ts","sourceRoot":"","sources":["../../src/web/getMemberships.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AA+B/C;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,OAAO,GAAG,aAAa,EAAE,CAYpE"}
@@ -0,0 +1,25 @@
1
+ function isOrgMembership(value) {
2
+ if (!value || typeof value !== "object") {
3
+ return false;
4
+ }
5
+ const membership = value;
6
+ const organization = membership["organization"];
7
+ if (!organization || typeof organization !== "object") {
8
+ return false;
9
+ }
10
+ const org = organization;
11
+ return typeof membership["id"] === "string" && typeof membership["organizationId"] === "string" && typeof membership["role"] === "string" && typeof org["id"] === "string" && typeof org["slug"] === "string" && typeof org["name"] === "string";
12
+ }
13
+ function getMemberships(currentUser) {
14
+ if (!currentUser || typeof currentUser !== "object") {
15
+ return [];
16
+ }
17
+ const memberships = currentUser["memberships"];
18
+ if (!Array.isArray(memberships)) {
19
+ return [];
20
+ }
21
+ return memberships.filter(isOrgMembership);
22
+ }
23
+ export {
24
+ getMemberships
25
+ };
@@ -0,0 +1,12 @@
1
+ import type { OrgMembership } from './types.js';
2
+ /**
3
+ * Pure role check over a memberships snapshot, with no dependency on auth or
4
+ * context. `useCurrentOrg().hasOrgRole` and the app's own code (checking a
5
+ * membership other than the current organization's) both build on this.
6
+ *
7
+ * Returns `false` when there is no membership in `organizationId`. An empty
8
+ * `roles` list returns `true` when a membership exists, matching
9
+ * `@cedarjs/tenancy`'s server-side `hasOrgRole`.
10
+ */
11
+ export declare function hasOrgRole(memberships: OrgMembership[] | undefined, roles: string | string[], organizationId: string): boolean;
12
+ //# sourceMappingURL=hasOrgRole.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hasOrgRole.d.ts","sourceRoot":"","sources":["../../src/web/hasOrgRole.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACxB,WAAW,EAAE,aAAa,EAAE,GAAG,SAAS,EACxC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,EACxB,cAAc,EAAE,MAAM,GACrB,OAAO,CAgBT"}
@@ -0,0 +1,16 @@
1
+ function hasOrgRole(memberships, roles, organizationId) {
2
+ const membership = memberships?.find(
3
+ (candidate) => candidate.organizationId === organizationId
4
+ );
5
+ if (!membership) {
6
+ return false;
7
+ }
8
+ const roleList = Array.isArray(roles) ? roles : [roles];
9
+ if (roleList.length === 0) {
10
+ return true;
11
+ }
12
+ return roleList.includes(membership.role);
13
+ }
14
+ export {
15
+ hasOrgRole
16
+ };
@@ -0,0 +1,9 @@
1
+ export { getMemberships } from './getMemberships.js';
2
+ export { hasOrgRole } from './hasOrgRole.js';
3
+ export { OrgContext } from './OrgContext.js';
4
+ export type { OrgScopeProps } from './OrgScope.js';
5
+ export { OrgScope } from './OrgScope.js';
6
+ export { clearOrgClients } from './orgClients.js';
7
+ export type { CurrentOrgSummary, OrgContextValue, OrgMembership, } from './types.js';
8
+ export { useCurrentOrg } from './useCurrentOrg.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/web/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,YAAY,EACV,iBAAiB,EACjB,eAAe,EACf,aAAa,GACd,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA"}
@@ -0,0 +1,14 @@
1
+ import { getMemberships } from "./getMemberships.js";
2
+ import { hasOrgRole } from "./hasOrgRole.js";
3
+ import { OrgContext } from "./OrgContext.js";
4
+ import { OrgScope } from "./OrgScope.js";
5
+ import { clearOrgClients } from "./orgClients.js";
6
+ import { useCurrentOrg } from "./useCurrentOrg.js";
7
+ export {
8
+ OrgContext,
9
+ OrgScope,
10
+ clearOrgClients,
11
+ getMemberships,
12
+ hasOrgRole,
13
+ useCurrentOrg
14
+ };
@@ -0,0 +1,27 @@
1
+ import type { ApolloClient } from '@apollo/client';
2
+ export interface GetOrgClientOptions {
3
+ userId: string;
4
+ organizationId: string;
5
+ /** Builds a new client. Only called on a cache miss. */
6
+ createClient: () => ApolloClient;
7
+ }
8
+ /**
9
+ * Returns the Apollo client for one user's membership in one organization,
10
+ * creating and caching it on first use so returning to an organization
11
+ * reuses its client and cache.
12
+ */
13
+ export declare function getOrgClient({ userId, organizationId, createClient, }: GetOrgClientOptions): ApolloClient;
14
+ /**
15
+ * Drops one organization's client, clearing its cache first. Called when a
16
+ * memberships refresh shows the membership gone or its role changed, so
17
+ * data cached under the previous authorization does not outlive it.
18
+ */
19
+ export declare function dropOrgClient(userId: string, organizationId: string): Promise<void>;
20
+ /**
21
+ * Drops every organization client, clearing each cache first. Called when
22
+ * `useAuth().isAuthenticated` turns false or `currentUser.id` changes, so a
23
+ * different user in the same tab is never handed a previous user's client.
24
+ * Also exported for tests and app logout hooks.
25
+ */
26
+ export declare function clearOrgClients(): Promise<void>;
27
+ //# sourceMappingURL=orgClients.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orgClients.d.ts","sourceRoot":"","sources":["../../src/web/orgClients.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAgBlD,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,EAAE,MAAM,CAAA;IACtB,wDAAwD;IACxD,YAAY,EAAE,MAAM,YAAY,CAAA;CACjC;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EAC3B,MAAM,EACN,cAAc,EACd,YAAY,GACb,EAAE,mBAAmB,GAAG,YAAY,CAYpC;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,CAAC,CAUf;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAKrD"}
@@ -0,0 +1,37 @@
1
+ const clients = /* @__PURE__ */ new Map();
2
+ function clientKey(userId, organizationId) {
3
+ return `${userId}:${organizationId}`;
4
+ }
5
+ function getOrgClient({
6
+ userId,
7
+ organizationId,
8
+ createClient
9
+ }) {
10
+ const key = clientKey(userId, organizationId);
11
+ const existing = clients.get(key);
12
+ if (existing) {
13
+ return existing;
14
+ }
15
+ const client = createClient();
16
+ clients.set(key, client);
17
+ return client;
18
+ }
19
+ async function dropOrgClient(userId, organizationId) {
20
+ const key = clientKey(userId, organizationId);
21
+ const client = clients.get(key);
22
+ if (!client) {
23
+ return;
24
+ }
25
+ clients.delete(key);
26
+ await client.clearStore();
27
+ }
28
+ async function clearOrgClients() {
29
+ const clientsToClear = Array.from(clients.values());
30
+ clients.clear();
31
+ await Promise.all(clientsToClear.map((client) => client.clearStore()));
32
+ }
33
+ export {
34
+ clearOrgClients,
35
+ dropOrgClient,
36
+ getOrgClient
37
+ };
@@ -0,0 +1,36 @@
1
+ /**
2
+ * One of the current user's memberships, as `getCurrentUser()` returns them
3
+ * on the API side (see the plan's "Web entry" section): a snapshot taken at
4
+ * authentication, refreshed by `reauthenticate()`.
5
+ */
6
+ export interface OrgMembership {
7
+ id: string;
8
+ organizationId: string;
9
+ role: string;
10
+ organization: {
11
+ id: string;
12
+ slug: string;
13
+ name: string;
14
+ };
15
+ }
16
+ /**
17
+ * The organization `OrgScope` has resolved for the current route, combining
18
+ * the matching membership with the organization it belongs to.
19
+ */
20
+ export interface CurrentOrgSummary {
21
+ id: string;
22
+ slug: string;
23
+ name: string;
24
+ role: string;
25
+ membershipId: string;
26
+ }
27
+ /**
28
+ * The value `OrgContext` carries, read through `useCurrentOrg()`.
29
+ */
30
+ export interface OrgContextValue {
31
+ org: CurrentOrgSummary | undefined;
32
+ memberships: OrgMembership[];
33
+ hasOrgRole(roles: string | string[], organizationId?: string): boolean;
34
+ setOrg(idOrSlug: string): void;
35
+ }
36
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/web/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,cAAc,EAAE,MAAM,CAAA;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE;QACZ,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;KACb,CAAA;CACF;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,MAAM,CAAA;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,iBAAiB,GAAG,SAAS,CAAA;IAClC,WAAW,EAAE,aAAa,EAAE,CAAA;IAC5B,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IACtE,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAC/B"}
File without changes
@@ -0,0 +1,10 @@
1
+ import type { OrgContextValue } from './types.js';
2
+ /**
3
+ * Reads the organization `OrgScope` resolved for the current route: the
4
+ * current organization, the full memberships snapshot, a role check scoped
5
+ * to it, and `setOrg` to switch organizations.
6
+ *
7
+ * Must be called from a component rendered under `OrgScope`.
8
+ */
9
+ export declare function useCurrentOrg(): OrgContextValue;
10
+ //# sourceMappingURL=useCurrentOrg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCurrentOrg.d.ts","sourceRoot":"","sources":["../../src/web/useCurrentOrg.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD;;;;;;GAMG;AACH,wBAAgB,aAAa,IAAI,eAAe,CAQ/C"}
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ import { OrgContext } from "./OrgContext.js";
3
+ function useCurrentOrg() {
4
+ const context = React.useContext(OrgContext);
5
+ if (!context) {
6
+ throw new Error("useCurrentOrg must be used within an OrgScope");
7
+ }
8
+ return context;
9
+ }
10
+ export {
11
+ useCurrentOrg
12
+ };
package/package.json ADDED
@@ -0,0 +1,105 @@
1
+ {
2
+ "name": "@cedarjs/tenancy",
3
+ "version": "7.0.0-canary.3092",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git+https://github.com/cedarjs/cedar.git",
7
+ "directory": "packages/tenancy"
8
+ },
9
+ "license": "MIT",
10
+ "type": "module",
11
+ "exports": {
12
+ ".": {
13
+ "default": {
14
+ "types": "./dist/index.d.ts",
15
+ "default": "./dist/index.js"
16
+ }
17
+ },
18
+ "./web": {
19
+ "default": {
20
+ "types": "./dist/web/index.d.ts",
21
+ "default": "./dist/web/index.js"
22
+ }
23
+ }
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "!dist/**/*.test.d.*"
28
+ ],
29
+ "scripts": {
30
+ "build": "node ./build.mts",
31
+ "build:pack": "yarn pack -o cedarjs-tenancy.tgz",
32
+ "build:types": "tsc --build --verbose ./tsconfig.build.json",
33
+ "check:attw": "yarn cedar-fwtools-attw",
34
+ "check:package": "concurrently npm:check:attw yarn publint",
35
+ "setup:test": "npx prisma db push --accept-data-loss --config ./src/__tests__/prisma.config.ts && npx prisma generate --config ./src/__tests__/prisma.config.ts",
36
+ "test": "vitest run",
37
+ "test:types": "yarn setup:test && tstyche",
38
+ "test:watch": "vitest watch"
39
+ },
40
+ "dependencies": {
41
+ "@cedarjs/api": "7.0.0-canary.3092",
42
+ "@cedarjs/context": "7.0.0-canary.3092",
43
+ "@cedarjs/graphql-server": "7.0.0-canary.3092"
44
+ },
45
+ "devDependencies": {
46
+ "@apollo/client": "4.2.12",
47
+ "@arethetypeswrong/cli": "0.18.5",
48
+ "@cedarjs/auth": "7.0.0-canary.3092",
49
+ "@cedarjs/framework-tools": "7.0.0-canary.3092",
50
+ "@cedarjs/router": "7.0.0-canary.3092",
51
+ "@cedarjs/web": "7.0.0-canary.3092",
52
+ "@prisma/adapter-better-sqlite3": "7.10.0",
53
+ "@prisma/client": "7.10.0",
54
+ "@testing-library/dom": "10.4.1",
55
+ "@testing-library/jest-dom": "6.9.1",
56
+ "@testing-library/react": "16.3.3",
57
+ "@types/aws-lambda": "8.10.162",
58
+ "@types/better-sqlite3": "7.6.13",
59
+ "@types/react": "^19.2.0",
60
+ "@types/react-dom": "^19.2.0",
61
+ "better-sqlite3": "12.11.1",
62
+ "concurrently": "9.2.4",
63
+ "esbuild": "0.28.2",
64
+ "graphql": "16.14.2",
65
+ "jsdom": "27.4.0",
66
+ "prisma": "7.10.0",
67
+ "publint": "0.3.24",
68
+ "react": "19.2.8",
69
+ "react-dom": "19.2.8",
70
+ "tstyche": "5.0.2",
71
+ "typescript": "5.9.3",
72
+ "vitest": "4.1.11",
73
+ "zx": "8.8.5"
74
+ },
75
+ "peerDependencies": {
76
+ "@apollo/client": "4.2.12",
77
+ "@cedarjs/auth": "7.0.0-canary.3092",
78
+ "@cedarjs/router": "7.0.0-canary.3092",
79
+ "@cedarjs/web": "7.0.0-canary.3092",
80
+ "react": "19.2.8"
81
+ },
82
+ "peerDependenciesMeta": {
83
+ "@apollo/client": {
84
+ "optional": true
85
+ },
86
+ "@cedarjs/auth": {
87
+ "optional": true
88
+ },
89
+ "@cedarjs/router": {
90
+ "optional": true
91
+ },
92
+ "@cedarjs/web": {
93
+ "optional": true
94
+ },
95
+ "react": {
96
+ "optional": true
97
+ }
98
+ },
99
+ "engines": {
100
+ "node": ">=24"
101
+ },
102
+ "publishConfig": {
103
+ "access": "public"
104
+ }
105
+ }