@intelligo-dev/core 1.0.0-beta.3 → 1.0.0-beta.6

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 (43) hide show
  1. package/README.md +45 -0
  2. package/dist/conversations/service.d.ts +3 -4
  3. package/dist/conversations/service.d.ts.map +1 -1
  4. package/dist/conversations/service.js +3 -4
  5. package/dist/conversations/service.js.map +1 -1
  6. package/dist/db/schema/agents.js +4 -4
  7. package/dist/db/schema/agents.js.map +1 -1
  8. package/dist/db/schema/ai.d.ts +7 -8
  9. package/dist/db/schema/ai.d.ts.map +1 -1
  10. package/dist/db/schema/ai.js +13 -14
  11. package/dist/db/schema/ai.js.map +1 -1
  12. package/dist/db/schema/rag.d.ts +3 -4
  13. package/dist/db/schema/rag.d.ts.map +1 -1
  14. package/dist/db/schema/rag.js +3 -4
  15. package/dist/db/schema/rag.js.map +1 -1
  16. package/dist/db/schema/usage.js +2 -2
  17. package/dist/documents/classifier.d.ts +3 -2
  18. package/dist/documents/classifier.d.ts.map +1 -1
  19. package/dist/documents/classifier.js +16 -7
  20. package/dist/documents/classifier.js.map +1 -1
  21. package/dist/identity/service.d.ts +8 -8
  22. package/dist/identity/service.js +8 -8
  23. package/dist/index.d.ts +0 -1
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +5 -1
  26. package/dist/index.js.map +1 -1
  27. package/dist/money.d.ts +112 -0
  28. package/dist/money.d.ts.map +1 -0
  29. package/dist/money.js +217 -0
  30. package/dist/money.js.map +1 -0
  31. package/dist/prompt.d.ts +46 -0
  32. package/dist/prompt.d.ts.map +1 -0
  33. package/dist/prompt.js +116 -0
  34. package/dist/prompt.js.map +1 -0
  35. package/dist/registry.d.ts +61 -0
  36. package/dist/registry.d.ts.map +1 -0
  37. package/dist/registry.js +92 -0
  38. package/dist/registry.js.map +1 -0
  39. package/dist/request-context.d.ts +66 -0
  40. package/dist/request-context.d.ts.map +1 -0
  41. package/dist/request-context.js +99 -0
  42. package/dist/request-context.js.map +1 -0
  43. package/package.json +38 -9
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Registries that survive a bundler duplicating the module they live in.
3
+ *
4
+ * A framework registry is a `Map` at module scope: the composition root
5
+ * writes to it once at startup and every later reader reads through it.
6
+ * That holds exactly as long as there is one instance of the module.
7
+ * Next.js does not guarantee that — its server build splits code into
8
+ * several bundles, and a package imported from two of them can be
9
+ * instantiated twice. The composition root then writes to one copy and
10
+ * a page reads the other.
11
+ *
12
+ * The failure is quiet, which is what makes it expensive. The first
13
+ * product to hit it saw `"No billing product configured"` logged by a
14
+ * page that rendered perfectly well: quota state came back null,
15
+ * feature checks fell through to their closed defaults, and nothing
16
+ * threw. Its workaround was a `server-only` side-effect module that
17
+ * every server file had to import, plus an architecture test naming the
18
+ * ten functions that read a registry — ADR-0005 forbids exactly that
19
+ * kind of import-side-effect registration, so the product had to
20
+ * violate the rule inside files the framework had shipped it.
21
+ *
22
+ * Keying the storage off `Symbol.for()` moves the map out of the module
23
+ * and into the realm's global symbol registry, which the bundler cannot
24
+ * duplicate. Every copy of the module then finds the same map, and the
25
+ * composition root can go back to running once.
26
+ *
27
+ * The limit, stated honestly: `globalThis` is per process. Node and
28
+ * Edge runtimes are separate processes and each still needs the
29
+ * composition root to run. This fixes duplicate modules, not duplicate
30
+ * runtimes.
31
+ */
32
+ const seen = new Set();
33
+ /**
34
+ * A `Map` shared by every copy of the module that asks for the same
35
+ * key.
36
+ *
37
+ * Use it wherever a registry is written by the composition root and
38
+ * read by request-time code:
39
+ *
40
+ * const plans = createRegistry<PlanMap>("billing/plans");
41
+ *
42
+ * `key` is namespaced into the global symbol registry, so it needs to
43
+ * be unique across the framework — `"<package>/<registry>"` is the
44
+ * convention. The value type is not checked across copies: two modules
45
+ * that disagree about `T` for one key is a programming error this
46
+ * cannot catch, which is why the keys live next to their registries
47
+ * rather than in a shared list someone could reuse by accident.
48
+ */
49
+ export function createRegistry(key) {
50
+ const symbol = Symbol.for(`@intelligo-dev/registry/${key}`);
51
+ const globals = globalThis;
52
+ const existing = globals[symbol];
53
+ if (existing) {
54
+ // A second copy of the module reaching the same slot is the
55
+ // condition this function exists to survive — it is not an error,
56
+ // and the map it returns is the right one. It is worth saying once
57
+ // per key, because it also means every *other* module-scope value
58
+ // in that file is duplicated too, and the next one to matter will
59
+ // not announce itself.
60
+ if (existing.origin !== import.meta.url && !seen.has(key)) {
61
+ seen.add(key);
62
+ console.warn(`[intelligo] registry "${key}" is being read from a second module ` +
63
+ `instance (${import.meta.url}, first seen from ${existing.origin}). ` +
64
+ `The registry itself is shared, so this is safe — but any other ` +
65
+ `module-scope state in that file is now duplicated.`);
66
+ }
67
+ return existing.map;
68
+ }
69
+ const map = new Map();
70
+ globals[symbol] = { map, origin: import.meta.url };
71
+ return map;
72
+ }
73
+ /**
74
+ * A single shared value, for the registries that are not maps.
75
+ *
76
+ * `defaultProductSlug` is the one that motivated this: a `let` at
77
+ * module scope has exactly the duplication problem a `Map` does, and
78
+ * it is the value whose absence produces "No billing product
79
+ * configured".
80
+ */
81
+ export function createRegistryRef(key, initial) {
82
+ const box = createRegistry(`ref/${key}`);
83
+ if (!box.has("value"))
84
+ box.set("value", initial);
85
+ return {
86
+ get: () => box.get("value"),
87
+ set: (value) => {
88
+ box.set("value", value);
89
+ },
90
+ };
91
+ }
92
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AASH,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;AAE/B;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,cAAc,CAAI,GAAW;IAC3C,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,2BAA2B,GAAG,EAAE,CAAC,CAAC;IAC5D,MAAM,OAAO,GAAG,UAA4D,CAAC;IAE7E,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,QAAQ,EAAE,CAAC;QACb,4DAA4D;QAC5D,kEAAkE;QAClE,mEAAmE;QACnE,kEAAkE;QAClE,kEAAkE;QAClE,uBAAuB;QACvB,IAAI,QAAQ,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1D,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACd,OAAO,CAAC,IAAI,CACV,yBAAyB,GAAG,uCAAuC;gBACjE,aAAa,MAAM,CAAC,IAAI,CAAC,GAAG,qBAAqB,QAAQ,CAAC,MAAM,KAAK;gBACrE,iEAAiE;gBACjE,oDAAoD,CACvD,CAAC;QACJ,CAAC;QACD,OAAO,QAAQ,CAAC,GAAG,CAAC;IACtB,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,GAAG,EAAa,CAAC;IACjC,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;IACnD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAC/B,GAAW,EACX,OAAU;IAEV,MAAM,GAAG,GAAG,cAAc,CAAI,OAAO,GAAG,EAAE,CAAC,CAAC;IAC5C,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC;QAAE,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACjD,OAAO;QACL,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAM;QAChC,GAAG,EAAE,CAAC,KAAQ,EAAE,EAAE;YAChB,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC1B,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Where request-scoped context comes from.
3
+ *
4
+ * `@intelligo-dev/auth` needs the incoming request's headers to resolve
5
+ * a session, and it got them by importing `next/headers` directly in
6
+ * five files. That made a package whose subject is authentication —
7
+ * not rendering — unusable outside Next: a queue worker that wants to
8
+ * check a session, a Hono API, a product on another framework, a test
9
+ * that is not running inside a request. ADR-0005 named the fix in its
10
+ * consequences; this is it.
11
+ *
12
+ * The framework asks for headers through `getRequestHeaders()`. The
13
+ * application says where they come from, once, from its composition
14
+ * root:
15
+ *
16
+ * import { setRequestContextSource } from "@intelligo-dev/core/request-context";
17
+ * import { nextRequestContext } from "@intelligo-dev/next";
18
+ *
19
+ * setRequestContextSource(nextRequestContext);
20
+ *
21
+ * `@intelligo-dev/next` is the only package in the framework that
22
+ * imports `next/*`, and an architecture test keeps it that way. This
23
+ * module imports nothing but `./registry`, so the contract is reachable
24
+ * from any runtime the adapter is not.
25
+ *
26
+ * Nothing self-registers. An unbound source throws where the headers
27
+ * are needed, naming the two lines that fix it — the alternative is a
28
+ * framework that guesses at the request, which is how a session gets
29
+ * read from the wrong one.
30
+ */
31
+ /**
32
+ * Produces the current request's headers.
33
+ *
34
+ * Async because Next's accessor is, and sync sources satisfy it too —
35
+ * `getRequestHeaders` awaits either.
36
+ */
37
+ export type RequestContextSource = () => Headers | Promise<Headers>;
38
+ export declare class RequestContextUnavailableError extends Error {
39
+ readonly code = "request_context_unavailable";
40
+ constructor();
41
+ }
42
+ export declare function setRequestContextSource(next: RequestContextSource): void;
43
+ /** Forget the bound source. For tests composing a fresh root. */
44
+ export declare function clearRequestContextSource(): void;
45
+ export declare function hasRequestContextSource(): boolean;
46
+ /**
47
+ * The current request's headers.
48
+ *
49
+ * @throws {RequestContextUnavailableError} when nothing is bound.
50
+ */
51
+ export declare function getRequestHeaders(): Promise<Headers>;
52
+ /**
53
+ * Run `fn` with these headers, whatever the ambient source says.
54
+ *
55
+ * For the callers that have a request but are not inside the
56
+ * framework's request scope: a background job replaying a webhook, a
57
+ * script acting as a user, an integration test that wants a real
58
+ * session without a server. Restores the previous value afterwards, so
59
+ * nesting behaves.
60
+ *
61
+ * Not `AsyncLocalStorage`: the value is set and restored around one
62
+ * awaited call, and ALS would make the package require a Node built-in
63
+ * that Edge runtimes only partly provide.
64
+ */
65
+ export declare function withRequestHeaders<T>(headers: Headers, fn: () => Promise<T> | T): Promise<T>;
66
+ //# sourceMappingURL=request-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../src/request-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAIH;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpE,qBAAa,8BAA+B,SAAQ,KAAK;IACvD,QAAQ,CAAC,IAAI,iCAAiC;;CAU/C;AAmBD,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,oBAAoB,GAAG,IAAI,CAExE;AAED,iEAAiE;AACjE,wBAAgB,yBAAyB,IAAI,IAAI,CAGhD;AAED,wBAAgB,uBAAuB,IAAI,OAAO,CAEjD;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO1D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,kBAAkB,CAAC,CAAC,EACxC,OAAO,EAAE,OAAO,EAChB,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,GACvB,OAAO,CAAC,CAAC,CAAC,CAQZ"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Where request-scoped context comes from.
3
+ *
4
+ * `@intelligo-dev/auth` needs the incoming request's headers to resolve
5
+ * a session, and it got them by importing `next/headers` directly in
6
+ * five files. That made a package whose subject is authentication —
7
+ * not rendering — unusable outside Next: a queue worker that wants to
8
+ * check a session, a Hono API, a product on another framework, a test
9
+ * that is not running inside a request. ADR-0005 named the fix in its
10
+ * consequences; this is it.
11
+ *
12
+ * The framework asks for headers through `getRequestHeaders()`. The
13
+ * application says where they come from, once, from its composition
14
+ * root:
15
+ *
16
+ * import { setRequestContextSource } from "@intelligo-dev/core/request-context";
17
+ * import { nextRequestContext } from "@intelligo-dev/next";
18
+ *
19
+ * setRequestContextSource(nextRequestContext);
20
+ *
21
+ * `@intelligo-dev/next` is the only package in the framework that
22
+ * imports `next/*`, and an architecture test keeps it that way. This
23
+ * module imports nothing but `./registry`, so the contract is reachable
24
+ * from any runtime the adapter is not.
25
+ *
26
+ * Nothing self-registers. An unbound source throws where the headers
27
+ * are needed, naming the two lines that fix it — the alternative is a
28
+ * framework that guesses at the request, which is how a session gets
29
+ * read from the wrong one.
30
+ */
31
+ import { createRegistryRef } from "./registry.js";
32
+ export class RequestContextUnavailableError extends Error {
33
+ constructor() {
34
+ super("No request context source is bound. Call setRequestContextSource() " +
35
+ "from your composition root — `nextRequestContext` from " +
36
+ "@intelligo-dev/next in a Next.js app — or wrap the call in " +
37
+ "withRequestHeaders() outside a request.");
38
+ this.code = "request_context_unavailable";
39
+ this.name = "RequestContextUnavailableError";
40
+ }
41
+ }
42
+ /**
43
+ * Held in the cross-instance registry rather than a module variable
44
+ * for the same reason every other framework registry is: a bundler
45
+ * that duplicates this module would otherwise give the composition
46
+ * root one copy and the request path another.
47
+ */
48
+ const source = createRegistryRef("core/request-context-source", undefined);
49
+ /** Explicitly bound headers, for a call that is not inside a request. */
50
+ const override = createRegistryRef("core/request-headers-override", undefined);
51
+ export function setRequestContextSource(next) {
52
+ source.set(next);
53
+ }
54
+ /** Forget the bound source. For tests composing a fresh root. */
55
+ export function clearRequestContextSource() {
56
+ source.set(undefined);
57
+ override.set(undefined);
58
+ }
59
+ export function hasRequestContextSource() {
60
+ return source.get() !== undefined || override.get() !== undefined;
61
+ }
62
+ /**
63
+ * The current request's headers.
64
+ *
65
+ * @throws {RequestContextUnavailableError} when nothing is bound.
66
+ */
67
+ export async function getRequestHeaders() {
68
+ const explicit = override.get();
69
+ if (explicit)
70
+ return explicit;
71
+ const resolve = source.get();
72
+ if (!resolve)
73
+ throw new RequestContextUnavailableError();
74
+ return await resolve();
75
+ }
76
+ /**
77
+ * Run `fn` with these headers, whatever the ambient source says.
78
+ *
79
+ * For the callers that have a request but are not inside the
80
+ * framework's request scope: a background job replaying a webhook, a
81
+ * script acting as a user, an integration test that wants a real
82
+ * session without a server. Restores the previous value afterwards, so
83
+ * nesting behaves.
84
+ *
85
+ * Not `AsyncLocalStorage`: the value is set and restored around one
86
+ * awaited call, and ALS would make the package require a Node built-in
87
+ * that Edge runtimes only partly provide.
88
+ */
89
+ export async function withRequestHeaders(headers, fn) {
90
+ const previous = override.get();
91
+ override.set(headers);
92
+ try {
93
+ return await fn();
94
+ }
95
+ finally {
96
+ override.set(previous);
97
+ }
98
+ }
99
+ //# sourceMappingURL=request-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-context.js","sourceRoot":"","sources":["../src/request-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAU/C,MAAM,OAAO,8BAA+B,SAAQ,KAAK;IAEvD;QACE,KAAK,CACH,qEAAqE;YACnE,yDAAyD;YACzD,6DAA6D;YAC7D,yCAAyC,CAC5C,CAAC;QAPK,SAAI,GAAG,6BAA6B,CAAC;QAQ5C,IAAI,CAAC,IAAI,GAAG,gCAAgC,CAAC;IAC/C,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,MAAM,GAAG,iBAAiB,CAC9B,6BAA6B,EAC7B,SAAS,CACV,CAAC;AAEF,yEAAyE;AACzE,MAAM,QAAQ,GAAG,iBAAiB,CAChC,+BAA+B,EAC/B,SAAS,CACV,CAAC;AAEF,MAAM,UAAU,uBAAuB,CAAC,IAA0B;IAChE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACnB,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,yBAAyB;IACvC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACtB,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,uBAAuB;IACrC,OAAO,MAAM,CAAC,GAAG,EAAE,KAAK,SAAS,IAAI,QAAQ,CAAC,GAAG,EAAE,KAAK,SAAS,CAAC;AACpE,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC;IAChC,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9B,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,8BAA8B,EAAE,CAAC;IACzD,OAAO,MAAM,OAAO,EAAE,CAAC;AACzB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAgB,EAChB,EAAwB;IAExB,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC;IAChC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,EAAE,CAAC;IACpB,CAAC;YAAS,CAAC;QACT,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intelligo-dev/core",
3
- "version": "1.0.0-beta.3",
3
+ "version": "1.0.0-beta.6",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -49,6 +49,22 @@
49
49
  "types": "./dist/env.d.ts",
50
50
  "default": "./dist/env.js"
51
51
  },
52
+ "./registry": {
53
+ "types": "./dist/registry.d.ts",
54
+ "default": "./dist/registry.js"
55
+ },
56
+ "./money": {
57
+ "types": "./dist/money.d.ts",
58
+ "default": "./dist/money.js"
59
+ },
60
+ "./request-context": {
61
+ "types": "./dist/request-context.d.ts",
62
+ "default": "./dist/request-context.js"
63
+ },
64
+ "./prompt": {
65
+ "types": "./dist/prompt.d.ts",
66
+ "default": "./dist/prompt.js"
67
+ },
52
68
  "./logger": {
53
69
  "types": "./dist/logger.d.ts",
54
70
  "import": "./dist/logger.js",
@@ -59,16 +75,14 @@
59
75
  "@neondatabase/serverless": "^0.10.4",
60
76
  "@react-email/components": "^1.0.7",
61
77
  "dotenv": "^16.4.7",
62
- "drizzle-orm": "^0.45.1",
63
78
  "pg": "^8.18.0",
64
79
  "pino": "^10.3.1",
65
- "react": "^19.0.0",
66
- "resend": "^6.9.1",
67
- "server-only": "^0.0.1",
68
- "zod": "^3.24.1"
80
+ "resend": "^6.9.1"
69
81
  },
70
82
  "peerDependencies": {
71
- "next": "^15.0.0 || ^16.0.0"
83
+ "drizzle-orm": "^0.45.1",
84
+ "react": "^19.0.0",
85
+ "zod": "^3.24.1"
72
86
  },
73
87
  "devDependencies": {
74
88
  "@types/bcryptjs": "^3.0.0",
@@ -76,18 +90,33 @@
76
90
  "@types/react": "^19.0.10",
77
91
  "bcryptjs": "^3.0.3",
78
92
  "drizzle-kit": "^0.31.8",
93
+ "drizzle-orm": "^0.45.1",
79
94
  "next": "^16.0.7",
80
95
  "pino-pretty": "^13.1.3",
96
+ "react": "^19.0.0",
81
97
  "tsx": "^4.21.0",
82
- "typescript": "^5.7.2"
98
+ "typescript": "^5.7.2",
99
+ "zod": "^3.24.1"
83
100
  },
84
101
  "files": [
85
102
  "dist",
86
- "src/db/migrations"
103
+ "src/db/migrations",
104
+ "LICENSE",
105
+ "README.md",
106
+ "!dist/**/*.tsbuildinfo"
87
107
  ],
88
108
  "publishConfig": {
89
109
  "access": "public"
90
110
  },
111
+ "peerDependenciesMeta": {
112
+ "react": {
113
+ "optional": true
114
+ }
115
+ },
116
+ "engines": {
117
+ "node": ">=22"
118
+ },
119
+ "sideEffects": false,
91
120
  "scripts": {
92
121
  "type-check": "tsc --noEmit",
93
122
  "lint": "eslint .",