@callimacus/thamyr-react 4.3.4

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.
@@ -0,0 +1,110 @@
1
+ /*!
2
+ * Copyright © 2025–2026 Solomei AI SRL. All rights reserved.
3
+ *
4
+ * Proprietary software, licensed for use by Callimacus customers only.
5
+ * See LICENSE.md for the full terms.
6
+ *
7
+ */
8
+ import { UseMutationOptions, UseQueryOptions, DataTag } from '@tanstack/react-query';
9
+ import { CallimacusApi } from '@callimacus/thamyr-core';
10
+
11
+ /**
12
+ TanStack Query bridge for the generated API surface.
13
+
14
+ One generic adapter instead of per-endpoint factories: options are typed
15
+ straight off the generated {@link CallimacusApi}, so every namespace and
16
+ method — including ones added by future contract releases — is covered with
17
+ zero per-operation code. The query function goes through {@link thamyrApi},
18
+ so queries fired before `useInitThamyr()` completes wait for initialization
19
+ instead of erroring.
20
+
21
+ This bridge is hand-written only because hey-api's generated
22
+ `@tanstack/react-query` factories do not compose with the SDK's
23
+ `paramsStructure: 'flat'` (https://github.com/hey-api/hey-api/issues/3191).
24
+ When that is fixed upstream, enable the plugin in openapi-ts.config.ts and
25
+ replace this module's internals with re-exports of the generated factories —
26
+ the `/query` subpath keeps consumers unchanged.
27
+
28
+ Opt-in subpath: requires the `@tanstack/react-query` peer and a
29
+ `QueryClientProvider`.
30
+
31
+ @example
32
+ ```tsx
33
+ import {useQuery, useMutation} from '@tanstack/react-query';
34
+ import {thamyrQueryOptions, thamyrMutationOptions} from '@callimacus/thamyr-react/query';
35
+
36
+ function HomePage({language}: {language: string}) {
37
+ // Refetches automatically when `language` changes (it is part of the key).
38
+ const {data, error} = useQuery(thamyrQueryOptions('content', 'getPage', {language, id: 'home'}));
39
+ }
40
+
41
+ function ShareButton({storyId}: {storyId: string}) {
42
+ const share = useMutation(thamyrMutationOptions('stories', 'share'));
43
+ return <button onClick={() => share.mutate({id: storyId})}>Share</button>;
44
+ }
45
+ ```
46
+
47
+ @packageDocumentation
48
+ */
49
+
50
+ type AnyApiMethod = (parameters: never, options?: never) => Promise<{
51
+ data?: unknown;
52
+ }>;
53
+ /**
54
+ A namespace of the generated client: `'content' | 'stories' | …`.
55
+ */
56
+ type ApiNamespace = keyof CallimacusApi & string;
57
+ /**
58
+ The method names of one generated namespace.
59
+ */
60
+ type ApiMethod<Namespace extends ApiNamespace> = {
61
+ [M in keyof CallimacusApi[Namespace] & string]: CallimacusApi[Namespace][M] extends AnyApiMethod ? M : never;
62
+ }[keyof CallimacusApi[Namespace] & string];
63
+ type MethodOf<Namespace extends ApiNamespace, Method extends ApiMethod<Namespace>> = Extract<CallimacusApi[Namespace][Method], AnyApiMethod>;
64
+ /**
65
+ The flat parameters object a generated method takes, or `void` for
66
+ parameterless reads (e.g. `cart.getCart`), whose single slot is the
67
+ request-options bag — offering that bag as "parameters" would put caller
68
+ options into the query key and swallow the bridge's own request options.
69
+ */
70
+ type ApiParameters<Namespace extends ApiNamespace, Method extends ApiMethod<Namespace>> = Parameters<MethodOf<Namespace, Method>> extends {
71
+ length: 0 | 1;
72
+ } ? void : Parameters<MethodOf<Namespace, Method>>[0];
73
+ /**
74
+ The unwrapped success payload a generated method resolves.
75
+ */
76
+ type ApiData<Namespace extends ApiNamespace, Method extends ApiMethod<Namespace>> = Awaited<ReturnType<MethodOf<Namespace, Method>>> extends {
77
+ data?: infer Data;
78
+ } ? Exclude<Data, undefined> : never;
79
+ /**
80
+ The key of a bridge query: `['thamyr', namespace, method, parameters]`.
81
+ */
82
+ type ThamyrQueryKey<Namespace extends ApiNamespace, Method extends ApiMethod<Namespace>> = readonly ['thamyr', Namespace, Method, ApiParameters<Namespace, Method>];
83
+ type ThamyrQueryOptions<Namespace extends ApiNamespace, Method extends ApiMethod<Namespace>> = UseQueryOptions<ApiData<Namespace, Method>, Error, ApiData<Namespace, Method>, ThamyrQueryKey<Namespace, Method>> & {
84
+ queryKey: DataTag<ThamyrQueryKey<Namespace, Method>, ApiData<Namespace, Method>, Error>;
85
+ };
86
+ /**
87
+ Query options for a generated read (`useQuery`, `prefetchQuery`,
88
+ `ensureQueryData`, …). The key is `['thamyr', namespace, method, parameters]`,
89
+ so parameter changes — a new language, a different id — refetch automatically.
90
+
91
+ @example
92
+ ```tsx
93
+ const {data: homePage} = useQuery(thamyrQueryOptions('content', 'getPage', {language, id: 'home'}));
94
+ ```
95
+ */
96
+ declare function thamyrQueryOptions<const Namespace extends ApiNamespace, const Method extends ApiMethod<Namespace>>(namespace: Namespace, method: Method, parameters: ApiParameters<Namespace, Method>): ThamyrQueryOptions<Namespace, Method>;
97
+ /**
98
+ Mutation options for a generated write (`useMutation`). The mutation
99
+ variables are the method's parameters object.
100
+
101
+ @example
102
+ ```tsx
103
+ const share = useMutation(thamyrMutationOptions('stories', 'share'));
104
+ share.mutate({id: storyId});
105
+ ```
106
+ */
107
+ declare function thamyrMutationOptions<const Namespace extends ApiNamespace, const Method extends ApiMethod<Namespace>>(namespace: Namespace, method: Method): UseMutationOptions<ApiData<Namespace, Method>, Error, ApiParameters<Namespace, Method>>;
108
+
109
+ export { thamyrMutationOptions, thamyrQueryOptions };
110
+ export type { ApiData, ApiMethod, ApiNamespace, ApiParameters, ThamyrQueryKey };
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "@callimacus/thamyr-react",
3
+ "version": "4.3.4",
4
+ "private": false,
5
+ "description": "React package for Thamyr",
6
+ "license": "SEE LICENSE IN LICENSE.md",
7
+ "homepage": "https://docs.callimacus.ai/thamyr-sdk/react/1-overview",
8
+ "main": "dist/esm/index.js",
9
+ "module": "dist/esm/index.js",
10
+ "types": "dist/types/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "import": "./dist/esm/index.js",
14
+ "types": "./dist/types/index.d.ts"
15
+ },
16
+ "./query": {
17
+ "import": "./dist/esm/query.js",
18
+ "types": "./dist/types/query.d.ts"
19
+ }
20
+ },
21
+ "files": [
22
+ "dist",
23
+ "CHANGELOG.md",
24
+ "CHANGELOG.core.md",
25
+ "MIGRATION.md"
26
+ ],
27
+ "type": "module",
28
+ "publishConfig": {
29
+ "access": "public",
30
+ "registry": "https://registry.npmjs.org",
31
+ "@callimacus:registry": "https://registry.npmjs.org"
32
+ },
33
+ "scripts": {
34
+ "prepack": "cp ../../MIGRATION.md ./MIGRATION.md && cp ../core/CHANGELOG.md ./CHANGELOG.core.md",
35
+ "build": "rollup -c",
36
+ "dev": "rollup -c -w",
37
+ "clean": "rm -rf dist",
38
+ "test": "vitest run",
39
+ "lint": "eslint src"
40
+ },
41
+ "dependencies": {
42
+ "@callimacus/thamyr": "^4.3.4",
43
+ "@callimacus/thamyr-core": "^4.3.4",
44
+ "zustand": "^5.0.15"
45
+ },
46
+ "peerDependencies": {
47
+ "react": ">=18",
48
+ "@tanstack/react-query": "^5"
49
+ },
50
+ "devDependencies": {
51
+ "@eslint-react/eslint-plugin": "^5.20.8",
52
+ "@testing-library/react": "^16.3.3",
53
+ "@types/react": "^19.3.0",
54
+ "@types/react-dom": "^19.3.0",
55
+ "eslint-config-xo": "^4.0.1",
56
+ "eslint-plugin-react-hooks": "^7.1.1",
57
+ "jsdom": "^30.1.1",
58
+ "react": "^19.3.0",
59
+ "react-dom": "^19.3.0",
60
+ "vitest": "^5.0.2",
61
+ "@tanstack/react-query": "^5.104.0"
62
+ },
63
+ "gitHead": "fafba2c8ca0586f95b1d03c5eede356a53b00886",
64
+ "peerDependenciesMeta": {
65
+ "@tanstack/react-query": {
66
+ "optional": true
67
+ }
68
+ }
69
+ }