@laconius/core 0.1.0

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 (90) hide show
  1. package/LICENSE +73 -0
  2. package/README.md +31 -0
  3. package/lib/module/auth.js +182 -0
  4. package/lib/module/auth.js.map +1 -0
  5. package/lib/module/client.js +99 -0
  6. package/lib/module/client.js.map +1 -0
  7. package/lib/module/config.js +72 -0
  8. package/lib/module/config.js.map +1 -0
  9. package/lib/module/converters.js +31 -0
  10. package/lib/module/converters.js.map +1 -0
  11. package/lib/module/create-config.js +36 -0
  12. package/lib/module/create-config.js.map +1 -0
  13. package/lib/module/endpoints.js +89 -0
  14. package/lib/module/endpoints.js.map +1 -0
  15. package/lib/module/errors.js +76 -0
  16. package/lib/module/errors.js.map +1 -0
  17. package/lib/module/i18n.js +84 -0
  18. package/lib/module/i18n.js.map +1 -0
  19. package/lib/module/index.js +18 -0
  20. package/lib/module/index.js.map +1 -0
  21. package/lib/module/media.js +182 -0
  22. package/lib/module/media.js.map +1 -0
  23. package/lib/module/models.js +2 -0
  24. package/lib/module/models.js.map +1 -0
  25. package/lib/module/package.json +1 -0
  26. package/lib/module/provider.js +182 -0
  27. package/lib/module/provider.js.map +1 -0
  28. package/lib/module/runtime.js +43 -0
  29. package/lib/module/runtime.js.map +1 -0
  30. package/lib/module/single-flight.js +23 -0
  31. package/lib/module/single-flight.js.map +1 -0
  32. package/lib/module/site-context.js +74 -0
  33. package/lib/module/site-context.js.map +1 -0
  34. package/lib/module/stores.js +66 -0
  35. package/lib/module/stores.js.map +1 -0
  36. package/lib/module/translations.js +42 -0
  37. package/lib/module/translations.js.map +1 -0
  38. package/lib/typescript/package.json +1 -0
  39. package/lib/typescript/src/auth.d.ts +31 -0
  40. package/lib/typescript/src/auth.d.ts.map +1 -0
  41. package/lib/typescript/src/client.d.ts +31 -0
  42. package/lib/typescript/src/client.d.ts.map +1 -0
  43. package/lib/typescript/src/config.d.ts +150 -0
  44. package/lib/typescript/src/config.d.ts.map +1 -0
  45. package/lib/typescript/src/converters.d.ts +17 -0
  46. package/lib/typescript/src/converters.d.ts.map +1 -0
  47. package/lib/typescript/src/create-config.d.ts +11 -0
  48. package/lib/typescript/src/create-config.d.ts.map +1 -0
  49. package/lib/typescript/src/endpoints.d.ts +36 -0
  50. package/lib/typescript/src/endpoints.d.ts.map +1 -0
  51. package/lib/typescript/src/errors.d.ts +43 -0
  52. package/lib/typescript/src/errors.d.ts.map +1 -0
  53. package/lib/typescript/src/i18n.d.ts +20 -0
  54. package/lib/typescript/src/i18n.d.ts.map +1 -0
  55. package/lib/typescript/src/index.d.ts +17 -0
  56. package/lib/typescript/src/index.d.ts.map +1 -0
  57. package/lib/typescript/src/media.d.ts +81 -0
  58. package/lib/typescript/src/media.d.ts.map +1 -0
  59. package/lib/typescript/src/models.d.ts +327 -0
  60. package/lib/typescript/src/models.d.ts.map +1 -0
  61. package/lib/typescript/src/provider.d.ts +37 -0
  62. package/lib/typescript/src/provider.d.ts.map +1 -0
  63. package/lib/typescript/src/runtime.d.ts +26 -0
  64. package/lib/typescript/src/runtime.d.ts.map +1 -0
  65. package/lib/typescript/src/single-flight.d.ts +7 -0
  66. package/lib/typescript/src/single-flight.d.ts.map +1 -0
  67. package/lib/typescript/src/site-context.d.ts +28 -0
  68. package/lib/typescript/src/site-context.d.ts.map +1 -0
  69. package/lib/typescript/src/stores.d.ts +54 -0
  70. package/lib/typescript/src/stores.d.ts.map +1 -0
  71. package/lib/typescript/src/translations.d.ts +40 -0
  72. package/lib/typescript/src/translations.d.ts.map +1 -0
  73. package/package.json +77 -0
  74. package/src/auth.ts +223 -0
  75. package/src/client.ts +133 -0
  76. package/src/config.ts +191 -0
  77. package/src/converters.ts +47 -0
  78. package/src/create-config.ts +29 -0
  79. package/src/endpoints.ts +133 -0
  80. package/src/errors.ts +104 -0
  81. package/src/i18n.ts +108 -0
  82. package/src/index.ts +123 -0
  83. package/src/media.ts +209 -0
  84. package/src/models.ts +384 -0
  85. package/src/provider.tsx +229 -0
  86. package/src/runtime.ts +57 -0
  87. package/src/single-flight.ts +23 -0
  88. package/src/site-context.ts +77 -0
  89. package/src/stores.ts +94 -0
  90. package/src/translations.ts +40 -0
@@ -0,0 +1,182 @@
1
+ "use strict";
2
+
3
+ import { QueryClient, QueryClientProvider, focusManager, onlineManager, useQueryClient } from '@tanstack/react-query';
4
+ import * as Network from 'expo-network';
5
+ import { createContext, useContext, useEffect, useMemo, useState, useSyncExternalStore } from 'react';
6
+ import { AppState } from 'react-native';
7
+ import { createAuthClient } from "./auth.js";
8
+ import { createHttpClient } from "./client.js";
9
+ import { createConverterRegistry } from "./converters.js";
10
+ import { LaconiusHttpError } from "./errors.js";
11
+ import { createTranslator } from "./i18n.js";
12
+ import { setActiveRuntime } from "./runtime.js";
13
+ import { resolveCurrency, resolveLanguage, useSessionStore, useSiteContextStore } from "./stores.js";
14
+ import { jsx as _jsx } from "react/jsx-runtime";
15
+ const LaconiusContext = /*#__PURE__*/createContext(undefined);
16
+
17
+ /**
18
+ * Fails loud at mount: without a backend the app does not exist, and failing at request forty
19
+ * only hides the cause. Individual unconfigured endpoints degrade through `isConfigured()`.
20
+ */
21
+ function assertValidConfig(config) {
22
+ const missing = [];
23
+ if (!config.backend?.occ?.baseUrl) missing.push('backend.occ.baseUrl');
24
+ if (!config.backend?.occ?.baseSite) missing.push('backend.occ.baseSite');
25
+ if (config.auth) {
26
+ for (const key of ['clientId', 'redirectUri', 'authServerUrl']) {
27
+ if (!config.auth[key]) missing.push(`auth.${key}`);
28
+ }
29
+ }
30
+ if (missing.length > 0) {
31
+ throw new Error(`[laconius] Incomplete configuration: ${missing.join(', ')} ${missing.length === 1 ? 'is' : 'are'} required.`);
32
+ }
33
+ }
34
+
35
+ /** Retry policy of chapter 09, overridable through `queryClient.setQueryDefaults`. */
36
+ export function createDefaultQueryClient() {
37
+ return new QueryClient({
38
+ defaultOptions: {
39
+ queries: {
40
+ staleTime: 5 * 60_000,
41
+ gcTime: 30 * 60_000,
42
+ retry: (failureCount, error) => {
43
+ if (error instanceof LaconiusHttpError) {
44
+ // 401 is not retried here: the client already refreshes once and retries once.
45
+ if (error.status >= 400 && error.status < 500) return false;
46
+ }
47
+ return failureCount < 2;
48
+ },
49
+ retryDelay: attempt => Math.min(1000 * 2 ** attempt, 30_000)
50
+ },
51
+ // A retried `POST /entries` can double an order line.
52
+ mutations: {
53
+ retry: false
54
+ }
55
+ }
56
+ });
57
+ }
58
+ export function LaconiusProvider({
59
+ config,
60
+ children,
61
+ fallback = null
62
+ }) {
63
+ const runtime = useMemo(() => {
64
+ assertValidConfig(config);
65
+ const auth = createAuthClient(config);
66
+ const runtime = {
67
+ config,
68
+ auth,
69
+ client: createHttpClient(config, auth),
70
+ converters: createConverterRegistry(config)
71
+ };
72
+ setActiveRuntime(runtime);
73
+ return runtime;
74
+ }, [config]);
75
+ useEffect(() => () => setActiveRuntime(undefined), []);
76
+ const queryClient = useMemo(() => config.query?.queryClient ?? createDefaultQueryClient(), [config.query?.queryClient]);
77
+ useEffect(() => {
78
+ if (config.query?.wireOnlineManager === false) return;
79
+ return onlineManager.setEventListener(setOnline => {
80
+ const subscription = Network.addNetworkStateListener(state => {
81
+ setOnline(state.isInternetReachable ?? state.isConnected ?? true);
82
+ });
83
+ return () => subscription.remove();
84
+ });
85
+ }, [config.query?.wireOnlineManager]);
86
+ useEffect(() => {
87
+ if (config.query?.wireFocusManager === false) return;
88
+ const subscription = AppState.addEventListener('change', status => focusManager.setFocused(status === 'active'));
89
+ return () => subscription.remove();
90
+ }, [config.query?.wireFocusManager]);
91
+
92
+ // Cold start: exchange the stored refresh token once, before the first authenticated call.
93
+ const [hydrated, setHydrated] = useState(false);
94
+ useEffect(() => {
95
+ let cancelled = false;
96
+ runtime.auth.hydrate().catch(error => config.onError?.(error, {})).finally(() => {
97
+ if (!cancelled) setHydrated(true);
98
+ });
99
+ return () => {
100
+ cancelled = true;
101
+ };
102
+ }, [runtime, config]);
103
+ return /*#__PURE__*/_jsx(LaconiusContext.Provider, {
104
+ value: runtime,
105
+ children: /*#__PURE__*/_jsx(QueryClientProvider, {
106
+ client: queryClient,
107
+ children: hydrated ? children : fallback
108
+ })
109
+ });
110
+ }
111
+ export function useLaconius() {
112
+ const runtime = useContext(LaconiusContext);
113
+ if (!runtime) {
114
+ throw new Error('[laconius] useLaconius must be used inside <LaconiusProvider>.');
115
+ }
116
+ return runtime;
117
+ }
118
+ export const useLaconiusConfig = () => useLaconius().config;
119
+
120
+ /** Re-renders on a language change, so a switch retranslates and refetches in one move. */
121
+ export function useTranslation() {
122
+ const {
123
+ config
124
+ } = useLaconius();
125
+ // Subscribed for the re-render; the value itself comes from `resolveLanguage`, which is where
126
+ // a stored value that the config no longer offers is dropped.
127
+ const language = useSiteContextStore(state => state.language);
128
+ return useMemo(() => createTranslator({
129
+ translations: config.i18n?.translations,
130
+ language: resolveLanguage(config) ?? 'en',
131
+ fallbackLanguage: config.i18n?.fallbackLanguage,
132
+ translate: config.i18n?.translate
133
+ }), [config, language]);
134
+ }
135
+ export function useSiteContext() {
136
+ const {
137
+ config
138
+ } = useLaconius();
139
+ // Subscriptions, not values: reading the store directly here would show a currency the client
140
+ // is no longer sending, because `resolveCurrency` drops one the config no longer offers.
141
+ useSiteContextStore(state => state.language);
142
+ useSiteContextStore(state => state.currency);
143
+ const setLanguage = useSiteContextStore(state => state.setLanguage);
144
+ const setCurrency = useSiteContextStore(state => state.setCurrency);
145
+ return {
146
+ language: resolveLanguage(config),
147
+ currency: resolveCurrency(config),
148
+ languages: config.context.languages,
149
+ currencies: config.context.currencies,
150
+ baseSite: config.backend.occ.baseSite,
151
+ setLanguage,
152
+ setCurrency
153
+ };
154
+ }
155
+
156
+ /** `true` while the session store holds an access token. */
157
+ export function useIsLoggedIn() {
158
+ return useSessionStore(state => Boolean(state.accessToken));
159
+ }
160
+
161
+ /** The app owns offline UI; the provider only wires `onlineManager`. */
162
+ export function useIsOnline() {
163
+ return useSyncExternalStore(onChange => onlineManager.subscribe(onChange), () => onlineManager.isOnline(), () => true);
164
+ }
165
+
166
+ /**
167
+ * Revoke, clear, and drop Laconius' queries — never `queryClient.clear()`, which would wipe the
168
+ * app's own. Site context and recently-viewed deliberately survive.
169
+ */
170
+ export function useLogout() {
171
+ const {
172
+ auth
173
+ } = useLaconius();
174
+ const queryClient = useQueryClient();
175
+ return async () => {
176
+ await auth.logout();
177
+ queryClient.removeQueries({
178
+ queryKey: ['laconius']
179
+ });
180
+ };
181
+ }
182
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["QueryClient","QueryClientProvider","focusManager","onlineManager","useQueryClient","Network","createContext","useContext","useEffect","useMemo","useState","useSyncExternalStore","AppState","createAuthClient","createHttpClient","createConverterRegistry","LaconiusHttpError","createTranslator","setActiveRuntime","resolveCurrency","resolveLanguage","useSessionStore","useSiteContextStore","jsx","_jsx","LaconiusContext","undefined","assertValidConfig","config","missing","backend","occ","baseUrl","push","baseSite","auth","key","length","Error","join","createDefaultQueryClient","defaultOptions","queries","staleTime","gcTime","retry","failureCount","error","status","retryDelay","attempt","Math","min","mutations","LaconiusProvider","children","fallback","runtime","client","converters","queryClient","query","wireOnlineManager","setEventListener","setOnline","subscription","addNetworkStateListener","state","isInternetReachable","isConnected","remove","wireFocusManager","addEventListener","setFocused","hydrated","setHydrated","cancelled","hydrate","catch","onError","finally","Provider","value","useLaconius","useLaconiusConfig","useTranslation","language","translations","i18n","fallbackLanguage","translate","useSiteContext","currency","setLanguage","setCurrency","languages","context","currencies","useIsLoggedIn","Boolean","accessToken","useIsOnline","onChange","subscribe","isOnline","useLogout","logout","removeQueries","queryKey"],"sourceRoot":"../../src","sources":["provider.tsx"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+
3
+ import { resolveCurrency, resolveLanguage } from "./stores.js";
4
+
5
+ /** Everything a query factory needs without a React context to read it from. */
6
+
7
+ let active;
8
+
9
+ /** Set by `LaconiusProvider` during render, so factories work before any effect runs. */
10
+ export function setActiveRuntime(runtime) {
11
+ active = runtime;
12
+ }
13
+
14
+ /**
15
+ * The runtime, for `queryOptions` factories used outside React (`prefetchQuery`,
16
+ * `ensureQueryData`).
17
+ */
18
+ export function getRuntime() {
19
+ if (!active) {
20
+ throw new Error('[laconius] No LaconiusProvider is mounted. Wrap your app in <LaconiusProvider config={…}>.');
21
+ }
22
+ return active;
23
+ }
24
+
25
+ /**
26
+ * `['laconius', <feature>, { site, lang, curr, user }, ...args]`.
27
+ *
28
+ * The context object is in every key, including product: customer-group pricing depends on the
29
+ * user. The `'laconius'` prefix is what makes `removeQueries(['laconius'])` safe.
30
+ */
31
+ export function laconiusQueryKey(feature, ...args) {
32
+ const {
33
+ config,
34
+ auth
35
+ } = getRuntime();
36
+ return ['laconius', feature, {
37
+ site: config.backend.occ.baseSite,
38
+ lang: resolveLanguage(config),
39
+ curr: resolveCurrency(config),
40
+ user: auth.getUserId()
41
+ }, ...args];
42
+ }
43
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["resolveCurrency","resolveLanguage","active","setActiveRuntime","runtime","getRuntime","Error","laconiusQueryKey","feature","args","config","auth","site","backend","occ","baseSite","lang","curr","user","getUserId"],"sourceRoot":"../../src","sources":["runtime.ts"],"mappings":";;AAIA,SAASA,eAAe,EAAEC,eAAe,QAAQ,aAAU;;AAE3D;;AAQA,IAAIC,MAAmC;;AAEvC;AACA,OAAO,SAASC,gBAAgBA,CAACC,OAAoC,EAAQ;EAC3EF,MAAM,GAAGE,OAAO;AAClB;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASC,UAAUA,CAAA,EAAoB;EAC5C,IAAI,CAACH,MAAM,EAAE;IACX,MAAM,IAAII,KAAK,CACb,4FACF,CAAC;EACH;EACA,OAAOJ,MAAM;AACf;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASK,gBAAgBA,CAC9BC,OAAe,EACf,GAAGC,IAAe,EACP;EACX,MAAM;IAAEC,MAAM;IAAEC;EAAK,CAAC,GAAGN,UAAU,CAAC,CAAC;EACrC,OAAO,CACL,UAAU,EACVG,OAAO,EACP;IACEI,IAAI,EAAEF,MAAM,CAACG,OAAO,CAACC,GAAG,CAACC,QAAQ;IACjCC,IAAI,EAAEf,eAAe,CAACS,MAAM,CAAC;IAC7BO,IAAI,EAAEjB,eAAe,CAACU,MAAM,CAAC;IAC7BQ,IAAI,EAAEP,IAAI,CAACQ,SAAS,CAAC;EACvB,CAAC,EACD,GAAGV,IAAI,CACR;AACH","ignoreList":[]}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Collapses concurrent calls onto one in-flight promise: N 401s cause one refresh.
5
+ *
6
+ * The next call after settlement starts a fresh one.
7
+ */
8
+ export function singleFlight(fn) {
9
+ let inFlight;
10
+ return () => {
11
+ if (!inFlight) {
12
+ const promise = fn();
13
+ inFlight = promise;
14
+ promise.finally(() => {
15
+ if (inFlight === promise) inFlight = undefined;
16
+ }).catch(() => {
17
+ // The caller owns the rejection; this chain exists only to clear the slot.
18
+ });
19
+ }
20
+ return inFlight;
21
+ };
22
+ }
23
+ //# sourceMappingURL=single-flight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["singleFlight","fn","inFlight","promise","finally","undefined","catch"],"sourceRoot":"../../src","sources":["single-flight.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASA,YAAYA,CAAIC,EAAoB,EAAoB;EACtE,IAAIC,QAAgC;EAEpC,OAAO,MAAM;IACX,IAAI,CAACA,QAAQ,EAAE;MACb,MAAMC,OAAO,GAAGF,EAAE,CAAC,CAAC;MACpBC,QAAQ,GAAGC,OAAO;MAClBA,OAAO,CACJC,OAAO,CAAC,MAAM;QACb,IAAIF,QAAQ,KAAKC,OAAO,EAAED,QAAQ,GAAGG,SAAS;MAChD,CAAC,CAAC,CACDC,KAAK,CAAC,MAAM;QACX;MAAA,CACD,CAAC;IACN;IACA,OAAOJ,QAAQ;EACjB,CAAC;AACH","ignoreList":[]}
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+
3
+ import { queryOptions, useQuery } from '@tanstack/react-query';
4
+ import { getRuntime, laconiusQueryKey } from "./runtime.js";
5
+
6
+ /**
7
+ * Adapters are plain objects of functions, so overriding one call is a spread and replacing the
8
+ * whole object is the route to a non-OCC backend.
9
+ */
10
+
11
+ export const defaultSiteContextAdapter = {
12
+ async loadBaseSites({
13
+ client,
14
+ converters
15
+ }) {
16
+ const response = await client.request({
17
+ endpoint: 'baseSites'
18
+ });
19
+ return converters.convertAll(response?.baseSites, 'baseSite');
20
+ },
21
+ async loadLanguages({
22
+ client,
23
+ converters
24
+ }) {
25
+ const response = await client.request({
26
+ endpoint: 'languages'
27
+ });
28
+ return converters.convertAll(response?.languages, 'language');
29
+ },
30
+ async loadCurrencies({
31
+ client,
32
+ converters
33
+ }) {
34
+ const response = await client.request({
35
+ endpoint: 'currencies'
36
+ });
37
+ return converters.convertAll(response?.currencies, 'currency');
38
+ }
39
+ };
40
+ function adapter(runtime) {
41
+ return {
42
+ ...defaultSiteContextAdapter,
43
+ ...runtime.config.backend.adapters?.siteContext
44
+ };
45
+ }
46
+
47
+ /** `queryOptions` factories, for `prefetchQuery` / `useSuspenseQuery` without forking Laconius. */
48
+ export const siteContextQueries = {
49
+ baseSites: () => queryOptions({
50
+ queryKey: laconiusQueryKey('siteContext', 'baseSites'),
51
+ queryFn: () => {
52
+ const runtime = getRuntime();
53
+ return adapter(runtime).loadBaseSites(runtime);
54
+ }
55
+ }),
56
+ languages: () => queryOptions({
57
+ queryKey: laconiusQueryKey('siteContext', 'languages'),
58
+ queryFn: () => {
59
+ const runtime = getRuntime();
60
+ return adapter(runtime).loadLanguages(runtime);
61
+ }
62
+ }),
63
+ currencies: () => queryOptions({
64
+ queryKey: laconiusQueryKey('siteContext', 'currencies'),
65
+ queryFn: () => {
66
+ const runtime = getRuntime();
67
+ return adapter(runtime).loadCurrencies(runtime);
68
+ }
69
+ })
70
+ };
71
+ export const useBaseSites = () => useQuery(siteContextQueries.baseSites());
72
+ export const useLanguages = () => useQuery(siteContextQueries.languages());
73
+ export const useCurrencies = () => useQuery(siteContextQueries.currencies());
74
+ //# sourceMappingURL=site-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["queryOptions","useQuery","getRuntime","laconiusQueryKey","defaultSiteContextAdapter","loadBaseSites","client","converters","response","request","endpoint","convertAll","baseSites","loadLanguages","languages","loadCurrencies","currencies","adapter","runtime","config","backend","adapters","siteContext","siteContextQueries","queryKey","queryFn","useBaseSites","useLanguages","useCurrencies"],"sourceRoot":"../../src","sources":["site-context.ts"],"mappings":";;AAAA,SAASA,YAAY,EAAEC,QAAQ,QAAQ,uBAAuB;AAG9D,SAASC,UAAU,EAAEC,gBAAgB,QAAQ,cAAW;;AAGxD;AACA;AACA;AACA;;AASA,OAAO,MAAMC,yBAA6C,GAAG;EAC3D,MAAMC,aAAaA,CAAC;IAAEC,MAAM;IAAEC;EAAW,CAAC,EAAE;IAC1C,MAAMC,QAAQ,GAAG,MAAMF,MAAM,CAACG,OAAO,CAAwB;MAC3DC,QAAQ,EAAE;IACZ,CAAC,CAAC;IACF,OAAOH,UAAU,CAACI,UAAU,CAAoBH,QAAQ,EAAEI,SAAS,EAAE,UAAU,CAAC;EAClF,CAAC;EACD,MAAMC,aAAaA,CAAC;IAAEP,MAAM;IAAEC;EAAW,CAAC,EAAE;IAC1C,MAAMC,QAAQ,GAAG,MAAMF,MAAM,CAACG,OAAO,CAAwB;MAC3DC,QAAQ,EAAE;IACZ,CAAC,CAAC;IACF,OAAOH,UAAU,CAACI,UAAU,CAAoBH,QAAQ,EAAEM,SAAS,EAAE,UAAU,CAAC;EAClF,CAAC;EACD,MAAMC,cAAcA,CAAC;IAAET,MAAM;IAAEC;EAAW,CAAC,EAAE;IAC3C,MAAMC,QAAQ,GAAG,MAAMF,MAAM,CAACG,OAAO,CAAwB;MAC3DC,QAAQ,EAAE;IACZ,CAAC,CAAC;IACF,OAAOH,UAAU,CAACI,UAAU,CAAoBH,QAAQ,EAAEQ,UAAU,EAAE,UAAU,CAAC;EACnF;AACF,CAAC;AAED,SAASC,OAAOA,CAACC,OAAwB,EAAsB;EAC7D,OAAO;IACL,GAAGd,yBAAyB;IAC5B,GAAGc,OAAO,CAACC,MAAM,CAACC,OAAO,CAACC,QAAQ,EAAEC;EACtC,CAAC;AACH;;AAEA;AACA,OAAO,MAAMC,kBAAkB,GAAG;EAChCX,SAAS,EAAEA,CAAA,KACTZ,YAAY,CAAC;IACXwB,QAAQ,EAAErB,gBAAgB,CAAC,aAAa,EAAE,WAAW,CAAC;IACtDsB,OAAO,EAAEA,CAAA,KAAM;MACb,MAAMP,OAAO,GAAGhB,UAAU,CAAC,CAAC;MAC5B,OAAOe,OAAO,CAACC,OAAO,CAAC,CAACb,aAAa,CAACa,OAAO,CAAC;IAChD;EACF,CAAC,CAAC;EACJJ,SAAS,EAAEA,CAAA,KACTd,YAAY,CAAC;IACXwB,QAAQ,EAAErB,gBAAgB,CAAC,aAAa,EAAE,WAAW,CAAC;IACtDsB,OAAO,EAAEA,CAAA,KAAM;MACb,MAAMP,OAAO,GAAGhB,UAAU,CAAC,CAAC;MAC5B,OAAOe,OAAO,CAACC,OAAO,CAAC,CAACL,aAAa,CAACK,OAAO,CAAC;IAChD;EACF,CAAC,CAAC;EACJF,UAAU,EAAEA,CAAA,KACVhB,YAAY,CAAC;IACXwB,QAAQ,EAAErB,gBAAgB,CAAC,aAAa,EAAE,YAAY,CAAC;IACvDsB,OAAO,EAAEA,CAAA,KAAM;MACb,MAAMP,OAAO,GAAGhB,UAAU,CAAC,CAAC;MAC5B,OAAOe,OAAO,CAACC,OAAO,CAAC,CAACH,cAAc,CAACG,OAAO,CAAC;IACjD;EACF,CAAC;AACL,CAAC;AAED,OAAO,MAAMQ,YAAY,GAAGA,CAAA,KAAMzB,QAAQ,CAACsB,kBAAkB,CAACX,SAAS,CAAC,CAAC,CAAC;AAC1E,OAAO,MAAMe,YAAY,GAAGA,CAAA,KAAM1B,QAAQ,CAACsB,kBAAkB,CAACT,SAAS,CAAC,CAAC,CAAC;AAC1E,OAAO,MAAMc,aAAa,GAAGA,CAAA,KAAM3B,QAAQ,CAACsB,kBAAkB,CAACP,UAAU,CAAC,CAAC,CAAC","ignoreList":[]}
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+
3
+ import AsyncStorage from 'expo-sqlite/kv-store';
4
+ import { create } from 'zustand';
5
+ import { createJSONStorage, persist } from 'zustand/middleware';
6
+ /** Not persisted: [ADR-0003](docs/adr/0003-refresh-token-in-the-keychain.md). */
7
+ export const useSessionStore = create(set => ({
8
+ setSession: ({
9
+ accessToken,
10
+ refreshToken,
11
+ expiresAt
12
+ }) => set({
13
+ accessToken,
14
+ refreshToken,
15
+ expiresAt
16
+ }),
17
+ clearSession: () => set({
18
+ accessToken: undefined,
19
+ refreshToken: undefined,
20
+ expiresAt: undefined
21
+ })
22
+ }));
23
+
24
+ /** Derived, never stored. Spartacus needs a `UserIdService`; Zustand does not. */
25
+ export function selectUserId(state) {
26
+ return state.accessToken ? 'current' : 'anonymous';
27
+ }
28
+ /**
29
+ * Base site is immutable config; language and currency are runtime state. Both are part of every
30
+ * query key and drive translation lookup, so a switch retranslates and refetches in one move.
31
+ */
32
+ export const useSiteContextStore = create()(persist(set => ({
33
+ setLanguage: language => set({
34
+ language
35
+ }),
36
+ setCurrency: currency => set({
37
+ currency
38
+ })
39
+ }), {
40
+ name: 'laconius.siteContext',
41
+ storage: createJSONStorage(() => AsyncStorage),
42
+ partialize: state => ({
43
+ language: state.language,
44
+ currency: state.currency
45
+ })
46
+ }));
47
+
48
+ /**
49
+ * A persisted value outlives the config that produced it: drop the base store's last currency and
50
+ * the app restores it on every cold start, and every OCC call answers `UnsupportedCurrencyError`
51
+ * with no way back. So a stored value counts only while the config still offers it.
52
+ */
53
+ function stored(value, allowed) {
54
+ return value !== undefined && allowed.includes(value) ? value : undefined;
55
+ }
56
+
57
+ /** Active language, falling back to config: the store starts empty until the app picks one. */
58
+ export function resolveLanguage(config) {
59
+ return stored(useSiteContextStore.getState().language, config.context.languages) ?? config.context.defaultLanguage ?? config.context.languages[0];
60
+ }
61
+
62
+ /** Active currency, falling back to config. */
63
+ export function resolveCurrency(config) {
64
+ return stored(useSiteContextStore.getState().currency, config.context.currencies) ?? config.context.defaultCurrency ?? config.context.currencies[0];
65
+ }
66
+ //# sourceMappingURL=stores.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["AsyncStorage","create","createJSONStorage","persist","useSessionStore","set","setSession","accessToken","refreshToken","expiresAt","clearSession","undefined","selectUserId","state","useSiteContextStore","setLanguage","language","setCurrency","currency","name","storage","partialize","stored","value","allowed","includes","resolveLanguage","config","getState","context","languages","defaultLanguage","resolveCurrency","currencies","defaultCurrency"],"sourceRoot":"../../src","sources":["stores.ts"],"mappings":";;AAAA,OAAOA,YAAY,MAAM,sBAAsB;AAC/C,SAASC,MAAM,QAAQ,SAAS;AAChC,SAASC,iBAAiB,EAAEC,OAAO,QAAQ,oBAAoB;AAe/D;AACA,OAAO,MAAMC,eAAe,GAAGH,MAAM,CAAgBI,GAAG,KAAM;EAC5DC,UAAU,EAAEA,CAAC;IAAEC,WAAW;IAAEC,YAAY;IAAEC;EAAU,CAAC,KACnDJ,GAAG,CAAC;IAAEE,WAAW;IAAEC,YAAY;IAAEC;EAAU,CAAC,CAAC;EAC/CC,YAAY,EAAEA,CAAA,KACZL,GAAG,CAAC;IACFE,WAAW,EAAEI,SAAS;IACtBH,YAAY,EAAEG,SAAS;IACvBF,SAAS,EAAEE;EACb,CAAC;AACL,CAAC,CAAC,CAAC;;AAEH;AACA,OAAO,SAASC,YAAYA,CAACC,KAE5B,EAA2B;EAC1B,OAAOA,KAAK,CAACN,WAAW,GAAG,SAAS,GAAG,WAAW;AACpD;AASA;AACA;AACA;AACA;AACA,OAAO,MAAMO,mBAAmB,GAAGb,MAAM,CAAmB,CAAC,CAC3DE,OAAO,CACJE,GAAG,KAAM;EACRU,WAAW,EAAGC,QAAQ,IAAKX,GAAG,CAAC;IAAEW;EAAS,CAAC,CAAC;EAC5CC,WAAW,EAAGC,QAAQ,IAAKb,GAAG,CAAC;IAAEa;EAAS,CAAC;AAC7C,CAAC,CAAC,EACF;EACEC,IAAI,EAAE,sBAAsB;EAC5BC,OAAO,EAAElB,iBAAiB,CAAC,MAAMF,YAAY,CAAC;EAC9CqB,UAAU,EAAGR,KAAK,KAAM;IACtBG,QAAQ,EAAEH,KAAK,CAACG,QAAQ;IACxBE,QAAQ,EAAEL,KAAK,CAACK;EAClB,CAAC;AACH,CACF,CACF,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA,SAASI,MAAMA,CAACC,KAAyB,EAAEC,OAAiB,EAAsB;EAChF,OAAOD,KAAK,KAAKZ,SAAS,IAAIa,OAAO,CAACC,QAAQ,CAACF,KAAK,CAAC,GAAGA,KAAK,GAAGZ,SAAS;AAC3E;;AAEA;AACA,OAAO,SAASe,eAAeA,CAACC,MAE/B,EAAsB;EACrB,OACEL,MAAM,CAACR,mBAAmB,CAACc,QAAQ,CAAC,CAAC,CAACZ,QAAQ,EAAEW,MAAM,CAACE,OAAO,CAACC,SAAS,CAAC,IACzEH,MAAM,CAACE,OAAO,CAACE,eAAe,IAC9BJ,MAAM,CAACE,OAAO,CAACC,SAAS,CAAC,CAAC,CAAC;AAE/B;;AAEA;AACA,OAAO,SAASE,eAAeA,CAACL,MAE/B,EAAsB;EACrB,OACEL,MAAM,CAACR,mBAAmB,CAACc,QAAQ,CAAC,CAAC,CAACV,QAAQ,EAAES,MAAM,CAACE,OAAO,CAACI,UAAU,CAAC,IAC1EN,MAAM,CAACE,OAAO,CAACK,eAAe,IAC9BP,MAAM,CAACE,OAAO,CAACI,UAAU,CAAC,CAAC,CAAC;AAEhC","ignoreList":[]}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * English error strings, ported from Spartacus'
5
+ * `core-libs/assets/src/translations/en/common.json` (`httpHandlers.*`), minus the checkout and
6
+ * payment validation keys. Other languages are the app's: Spartacus ships 17 under
7
+ * `core-libs/assets/src/translations/<lang>/` and is Apache-2.0.
8
+ */
9
+ export const defaultCoreTranslations = {
10
+ en: {
11
+ common: {
12
+ retry: 'Retry',
13
+ cancel: 'Cancel',
14
+ close: 'Close',
15
+ loading: 'Loading…'
16
+ },
17
+ errors: {
18
+ http: {
19
+ badRequest: 'The request could not be processed. Please check your input.',
20
+ unauthorized: 'Your session has expired. Please login again.',
21
+ forbidden: 'You are not authorized to perform this action. Please contact your administrator if you think this is a mistake.',
22
+ notFound: 'Item not found.',
23
+ conflict: 'Already exists.',
24
+ serverError: 'A server error occurred. Please try again later.',
25
+ offline: 'No connection. Please check your network and try again.',
26
+ unknown: 'An unknown error occurred.'
27
+ },
28
+ occ: {
29
+ InsufficientStockError: 'Not enough stock for this product.',
30
+ CartError: 'Cart errors occurred.',
31
+ CartEntryError: 'This cart entry could not be updated.',
32
+ UnknownIdentifierError: 'Item not found.',
33
+ CMSItemNotFoundError: 'This page is not available.',
34
+ ValidationError: 'Some of the information entered is not valid.',
35
+ DuplicateUidError: 'An account with this email address already exists.',
36
+ PasswordMismatchError: 'Old password incorrect.',
37
+ InvalidTokenError: 'Invalid code provided.'
38
+ }
39
+ }
40
+ }
41
+ };
42
+ //# sourceMappingURL=translations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["defaultCoreTranslations","en","common","retry","cancel","close","loading","errors","http","badRequest","unauthorized","forbidden","notFound","conflict","serverError","offline","unknown","occ","InsufficientStockError","CartError","CartEntryError","UnknownIdentifierError","CMSItemNotFoundError","ValidationError","DuplicateUidError","PasswordMismatchError","InvalidTokenError"],"sourceRoot":"../../src","sources":["translations.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMA,uBAAuB,GAAG;EACrCC,EAAE,EAAE;IACFC,MAAM,EAAE;MACNC,KAAK,EAAE,OAAO;MACdC,MAAM,EAAE,QAAQ;MAChBC,KAAK,EAAE,OAAO;MACdC,OAAO,EAAE;IACX,CAAC;IACDC,MAAM,EAAE;MACNC,IAAI,EAAE;QACJC,UAAU,EAAE,8DAA8D;QAC1EC,YAAY,EAAE,+CAA+C;QAC7DC,SAAS,EACP,kHAAkH;QACpHC,QAAQ,EAAE,iBAAiB;QAC3BC,QAAQ,EAAE,iBAAiB;QAC3BC,WAAW,EAAE,kDAAkD;QAC/DC,OAAO,EAAE,yDAAyD;QAClEC,OAAO,EAAE;MACX,CAAC;MACDC,GAAG,EAAE;QACHC,sBAAsB,EAAE,oCAAoC;QAC5DC,SAAS,EAAE,uBAAuB;QAClCC,cAAc,EAAE,uCAAuC;QACvDC,sBAAsB,EAAE,iBAAiB;QACzCC,oBAAoB,EAAE,6BAA6B;QACnDC,eAAe,EAAE,+CAA+C;QAChEC,iBAAiB,EAAE,oDAAoD;QACvEC,qBAAqB,EAAE,yBAAyB;QAChDC,iBAAiB,EAAE;MACrB;IACF;EACF;AACF,CAAC","ignoreList":[]}
@@ -0,0 +1 @@
1
+ {"type":"module"}
@@ -0,0 +1,31 @@
1
+ import * as AuthSession from 'expo-auth-session';
2
+ import type { LaconiusConfig } from './config.js';
3
+ /** Refresh-token storage failed. Treated as "no stored session", never as a crash. */
4
+ export declare class SecureStorageError extends Error {
5
+ constructor(operation: string, cause: unknown);
6
+ }
7
+ export type TokenSet = {
8
+ accessToken: string;
9
+ refreshToken?: string;
10
+ /** Epoch milliseconds. */
11
+ expiresAt?: number;
12
+ };
13
+ /**
14
+ * Built from config, never from the server's discovery document: that document is wrong about
15
+ * its own server (it never advertises `none` for token endpoint auth, which demonstrably works).
16
+ */
17
+ export declare function createDiscovery(authServerUrl: string): AuthSession.DiscoveryDocument;
18
+ export type AuthClient = {
19
+ /** Authorization Code + PKCE. Returns the token set, or `undefined` when the user cancelled. */
20
+ login: () => Promise<TokenSet | undefined>;
21
+ logout: () => Promise<void>;
22
+ /** Single-flight: concurrent callers share one token request. */
23
+ refresh: () => Promise<TokenSet | undefined>;
24
+ /** Cold start: read the stored refresh token and exchange it once. */
25
+ hydrate: () => Promise<TokenSet | undefined>;
26
+ /** Refreshes proactively when the access token is within 60s of expiry. */
27
+ getAccessToken: () => Promise<string | undefined>;
28
+ getUserId: () => string;
29
+ };
30
+ export declare function createAuthClient(config: LaconiusConfig): AuthClient;
31
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAC;AAGjD,OAAO,KAAK,EAAsB,cAAc,EAAE,MAAM,aAAU,CAAC;AAMnE,sFAAsF;AACtF,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAK9C;AAED,MAAM,MAAM,QAAQ,GAAG;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,aAAa,EAAE,MAAM,GACpB,WAAW,CAAC,iBAAiB,CAO/B;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,gGAAgG;IAChG,KAAK,EAAE,MAAM,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC;IAC3C,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,iEAAiE;IACjE,OAAO,EAAE,MAAM,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC;IAC7C,sEAAsE;IACtE,OAAO,EAAE,MAAM,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC;IAC7C,2EAA2E;IAC3E,cAAc,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAClD,SAAS,EAAE,MAAM,MAAM,CAAC;CACzB,CAAC;AAIF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,cAAc,GAAG,UAAU,CAuKnE"}
@@ -0,0 +1,31 @@
1
+ import type { AuthClient } from './auth.js';
2
+ import type { LaconiusConfig } from './config.js';
3
+ import { type EndpointResolver } from './endpoints.js';
4
+ export type LaconiusRequest = {
5
+ /** Endpoint key, resolved through `backend.occ.endpoints`. */
6
+ endpoint: string;
7
+ scope?: string;
8
+ method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
9
+ urlParams?: Record<string, string | number>;
10
+ queryParams?: Record<string, string | number | boolean | undefined>;
11
+ /** Sent as JSON. */
12
+ body?: unknown;
13
+ /** Sent as `application/x-www-form-urlencoded` (OCC wants this for product reviews). */
14
+ form?: Record<string, string>;
15
+ headers?: Record<string, string>;
16
+ /** Skip the `Authorization` header even when a session exists. */
17
+ anonymous?: boolean;
18
+ signal?: AbortSignal;
19
+ };
20
+ export type LaconiusHttpClient = {
21
+ request<T>(options: LaconiusRequest): Promise<T>;
22
+ endpoints: EndpointResolver;
23
+ };
24
+ /**
25
+ * Lives outside React so refresh and session reads work from anywhere.
26
+ *
27
+ * `lang` and `curr` are appended here rather than by adapters — the same division Spartacus
28
+ * draws with an interceptor.
29
+ */
30
+ export declare function createHttpClient(config: LaconiusConfig, auth: AuthClient): LaconiusHttpClient;
31
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAQ,CAAC;AACzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAU,CAAC;AAC/C,OAAO,EAA0B,KAAK,gBAAgB,EAAE,MAAM,gBAAa,CAAC;AAO5E,MAAM,MAAM,eAAe,GAAG;IAC5B,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;IACpE,oBAAoB;IACpB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,wFAAwF;IACxF,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,kEAAkE;IAClE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACjD,SAAS,EAAE,gBAAgB,CAAC;CAC7B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE,UAAU,GACf,kBAAkB,CAiFpB"}