@zeitvu97/cms-sdk 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 (274) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +478 -0
  3. package/dist/chunks/_shared-48T7q0V3.js +26 -0
  4. package/dist/chunks/_shared-48T7q0V3.js.map +1 -0
  5. package/dist/chunks/auth.constant-DO7ZmsKg.js +68 -0
  6. package/dist/chunks/auth.constant-DO7ZmsKg.js.map +1 -0
  7. package/dist/chunks/mt5Retcode-DlZLQOLA.js +178 -0
  8. package/dist/chunks/mt5Retcode-DlZLQOLA.js.map +1 -0
  9. package/dist/chunks/storage.constant--64BDSPW.js +44 -0
  10. package/dist/chunks/storage.constant--64BDSPW.js.map +1 -0
  11. package/dist/common/constants/auth.constant.d.ts +54 -0
  12. package/dist/common/constants/auth.constant.d.ts.map +1 -0
  13. package/dist/common/constants/bars.constant.d.ts +15 -0
  14. package/dist/common/constants/bars.constant.d.ts.map +1 -0
  15. package/dist/common/constants/content-types.constant.d.ts +29 -0
  16. package/dist/common/constants/content-types.constant.d.ts.map +1 -0
  17. package/dist/common/constants/content.constant.d.ts +114 -0
  18. package/dist/common/constants/content.constant.d.ts.map +1 -0
  19. package/dist/common/constants/executions.constant.d.ts +56 -0
  20. package/dist/common/constants/executions.constant.d.ts.map +1 -0
  21. package/dist/common/constants/gov.constant.d.ts +118 -0
  22. package/dist/common/constants/gov.constant.d.ts.map +1 -0
  23. package/dist/common/constants/history.constant.d.ts +108 -0
  24. package/dist/common/constants/history.constant.d.ts.map +1 -0
  25. package/dist/common/constants/http.constant.d.ts +46 -0
  26. package/dist/common/constants/http.constant.d.ts.map +1 -0
  27. package/dist/common/constants/index.d.ts +16 -0
  28. package/dist/common/constants/index.d.ts.map +1 -0
  29. package/dist/common/constants/kalshi.constant.d.ts +35 -0
  30. package/dist/common/constants/kalshi.constant.d.ts.map +1 -0
  31. package/dist/common/constants/llm.constant.d.ts +37 -0
  32. package/dist/common/constants/llm.constant.d.ts.map +1 -0
  33. package/dist/common/constants/mt5-action.constant.d.ts +131 -0
  34. package/dist/common/constants/mt5-action.constant.d.ts.map +1 -0
  35. package/dist/common/constants/mt5.constant.d.ts +254 -0
  36. package/dist/common/constants/mt5.constant.d.ts.map +1 -0
  37. package/dist/common/constants/notifications.constant.d.ts +45 -0
  38. package/dist/common/constants/notifications.constant.d.ts.map +1 -0
  39. package/dist/common/constants/people.constant.d.ts +269 -0
  40. package/dist/common/constants/people.constant.d.ts.map +1 -0
  41. package/dist/common/constants/rules.constant.d.ts +14 -0
  42. package/dist/common/constants/rules.constant.d.ts.map +1 -0
  43. package/dist/common/constants/settings.constant.d.ts +17 -0
  44. package/dist/common/constants/settings.constant.d.ts.map +1 -0
  45. package/dist/common/constants/sort.constant.d.ts +14 -0
  46. package/dist/common/constants/sort.constant.d.ts.map +1 -0
  47. package/dist/common/constants/storage.constant.d.ts +74 -0
  48. package/dist/common/constants/storage.constant.d.ts.map +1 -0
  49. package/dist/common/helpers/format.d.ts +7 -0
  50. package/dist/common/helpers/format.d.ts.map +1 -0
  51. package/dist/common/helpers/format.js +20 -0
  52. package/dist/common/helpers/format.js.map +1 -0
  53. package/dist/common/helpers/mt5Retcode.d.ts +18 -0
  54. package/dist/common/helpers/mt5Retcode.d.ts.map +1 -0
  55. package/dist/common/helpers/mt5Retcode.js +2 -0
  56. package/dist/common/helpers/mt5Retcode.js.map +1 -0
  57. package/dist/common/utils/case.d.ts +12 -0
  58. package/dist/common/utils/case.d.ts.map +1 -0
  59. package/dist/common/utils/clone.d.ts +9 -0
  60. package/dist/common/utils/clone.d.ts.map +1 -0
  61. package/dist/composables/cbsStateKey.d.ts +27 -0
  62. package/dist/composables/cbsStateKey.d.ts.map +1 -0
  63. package/dist/core/createApi.d.ts +69 -0
  64. package/dist/core/createApi.d.ts.map +1 -0
  65. package/dist/core/createCmsSDK.d.ts +19 -0
  66. package/dist/core/createCmsSDK.d.ts.map +1 -0
  67. package/dist/core/credentials/TokenManager.d.ts +38 -0
  68. package/dist/core/credentials/TokenManager.d.ts.map +1 -0
  69. package/dist/core/credentials/credential.type.d.ts +16 -0
  70. package/dist/core/credentials/credential.type.d.ts.map +1 -0
  71. package/dist/core/credentials/resolveStorage.d.ts +6 -0
  72. package/dist/core/credentials/resolveStorage.d.ts.map +1 -0
  73. package/dist/core/credentials/storages/cookieStorage.d.ts +18 -0
  74. package/dist/core/credentials/storages/cookieStorage.d.ts.map +1 -0
  75. package/dist/core/credentials/storages/localStorageAdapter.d.ts +8 -0
  76. package/dist/core/credentials/storages/localStorageAdapter.d.ts.map +1 -0
  77. package/dist/core/credentials/storages/memoryStorage.d.ts +7 -0
  78. package/dist/core/credentials/storages/memoryStorage.d.ts.map +1 -0
  79. package/dist/core/errors.d.ts +26 -0
  80. package/dist/core/errors.d.ts.map +1 -0
  81. package/dist/core/sdk.type.d.ts +115 -0
  82. package/dist/core/sdk.type.d.ts.map +1 -0
  83. package/dist/core/ws/createEaeraWebSocket.d.ts +21 -0
  84. package/dist/core/ws/createEaeraWebSocket.d.ts.map +1 -0
  85. package/dist/core/ws/index.d.ts +4 -0
  86. package/dist/core/ws/index.d.ts.map +1 -0
  87. package/dist/core/ws/ws.constants.d.ts +246 -0
  88. package/dist/core/ws/ws.constants.d.ts.map +1 -0
  89. package/dist/core/ws/ws.events.d.ts +264 -0
  90. package/dist/core/ws/ws.events.d.ts.map +1 -0
  91. package/dist/core/ws/ws.type.d.ts +225 -0
  92. package/dist/core/ws/ws.type.d.ts.map +1 -0
  93. package/dist/index.d.ts +130 -0
  94. package/dist/index.d.ts.map +1 -0
  95. package/dist/index.js +8416 -0
  96. package/dist/index.js.map +1 -0
  97. package/dist/nuxt.d.ts +49 -0
  98. package/dist/nuxt.d.ts.map +1 -0
  99. package/dist/nuxt.js +47 -0
  100. package/dist/nuxt.js.map +1 -0
  101. package/dist/runtime/plugin.d.ts +6 -0
  102. package/dist/runtime/plugin.js +188 -0
  103. package/dist/runtime/plugin.js.map +1 -0
  104. package/dist/server/auth/cbs-callback.post.js +42 -0
  105. package/dist/server/auth/cbs-callback.post.js.map +1 -0
  106. package/dist/server/auth/cbs-start.post.js +34 -0
  107. package/dist/server/auth/cbs-start.post.js.map +1 -0
  108. package/dist/server/auth/idp-callback.get.js +52 -0
  109. package/dist/server/auth/idp-callback.get.js.map +1 -0
  110. package/dist/server/auth/idp-link.post.js +38 -0
  111. package/dist/server/auth/idp-link.post.js.map +1 -0
  112. package/dist/server/auth/idp-login.get.js +42 -0
  113. package/dist/server/auth/idp-login.get.js.map +1 -0
  114. package/dist/server/auth/idp-unlink.delete.js +38 -0
  115. package/dist/server/auth/idp-unlink.delete.js.map +1 -0
  116. package/dist/server/auth/login.post.js +42 -0
  117. package/dist/server/auth/login.post.js.map +1 -0
  118. package/dist/server/auth/logout.post.js +31 -0
  119. package/dist/server/auth/logout.post.js.map +1 -0
  120. package/dist/server/auth/refresh.post.js +46 -0
  121. package/dist/server/auth/refresh.post.js.map +1 -0
  122. package/dist/server/clear-token.delete.js +12 -0
  123. package/dist/server/clear-token.delete.js.map +1 -0
  124. package/dist/server/persist.post.js +31 -0
  125. package/dist/server/persist.post.js.map +1 -0
  126. package/dist/server/set-token.post.js +27 -0
  127. package/dist/server/set-token.post.js.map +1 -0
  128. package/dist/services/auth/auth.type.d.ts +66 -0
  129. package/dist/services/auth/auth.type.d.ts.map +1 -0
  130. package/dist/services/auth/index.d.ts +127 -0
  131. package/dist/services/auth/index.d.ts.map +1 -0
  132. package/dist/services/auth/mock.d.ts +13 -0
  133. package/dist/services/auth/mock.d.ts.map +1 -0
  134. package/dist/services/bars/bars.type.d.ts +78 -0
  135. package/dist/services/bars/bars.type.d.ts.map +1 -0
  136. package/dist/services/bars/index.d.ts +24 -0
  137. package/dist/services/bars/index.d.ts.map +1 -0
  138. package/dist/services/bars/mock.d.ts +23 -0
  139. package/dist/services/bars/mock.d.ts.map +1 -0
  140. package/dist/services/content/content.type.d.ts +832 -0
  141. package/dist/services/content/content.type.d.ts.map +1 -0
  142. package/dist/services/content/filter.d.ts +46 -0
  143. package/dist/services/content/filter.d.ts.map +1 -0
  144. package/dist/services/content/index.d.ts +35 -0
  145. package/dist/services/content/index.d.ts.map +1 -0
  146. package/dist/services/content/mock.d.ts +16 -0
  147. package/dist/services/content/mock.d.ts.map +1 -0
  148. package/dist/services/content-types/content-types.type.d.ts +70 -0
  149. package/dist/services/content-types/content-types.type.d.ts.map +1 -0
  150. package/dist/services/content-types/index.d.ts +18 -0
  151. package/dist/services/content-types/index.d.ts.map +1 -0
  152. package/dist/services/content-types/mock.d.ts +15 -0
  153. package/dist/services/content-types/mock.d.ts.map +1 -0
  154. package/dist/services/executions/executions.type.d.ts +67 -0
  155. package/dist/services/executions/executions.type.d.ts.map +1 -0
  156. package/dist/services/executions/index.d.ts +30 -0
  157. package/dist/services/executions/index.d.ts.map +1 -0
  158. package/dist/services/executions/mock.d.ts +29 -0
  159. package/dist/services/executions/mock.d.ts.map +1 -0
  160. package/dist/services/gov/gov.type.d.ts +740 -0
  161. package/dist/services/gov/gov.type.d.ts.map +1 -0
  162. package/dist/services/gov/index.d.ts +84 -0
  163. package/dist/services/gov/index.d.ts.map +1 -0
  164. package/dist/services/history/history.type.d.ts +167 -0
  165. package/dist/services/history/history.type.d.ts.map +1 -0
  166. package/dist/services/history/index.d.ts +38 -0
  167. package/dist/services/history/index.d.ts.map +1 -0
  168. package/dist/services/history/mock.d.ts +21 -0
  169. package/dist/services/history/mock.d.ts.map +1 -0
  170. package/dist/services/kalshi/index.d.ts +19 -0
  171. package/dist/services/kalshi/index.d.ts.map +1 -0
  172. package/dist/services/kalshi/kalshi.type.d.ts +99 -0
  173. package/dist/services/kalshi/kalshi.type.d.ts.map +1 -0
  174. package/dist/services/kalshi/mock.d.ts +5 -0
  175. package/dist/services/kalshi/mock.d.ts.map +1 -0
  176. package/dist/services/llm/index.d.ts +38 -0
  177. package/dist/services/llm/index.d.ts.map +1 -0
  178. package/dist/services/llm/llm.type.d.ts +106 -0
  179. package/dist/services/llm/llm.type.d.ts.map +1 -0
  180. package/dist/services/notifications/index.d.ts +38 -0
  181. package/dist/services/notifications/index.d.ts.map +1 -0
  182. package/dist/services/notifications/mock.d.ts +39 -0
  183. package/dist/services/notifications/mock.d.ts.map +1 -0
  184. package/dist/services/notifications/notifications.type.d.ts +75 -0
  185. package/dist/services/notifications/notifications.type.d.ts.map +1 -0
  186. package/dist/services/people/_invoke.d.ts +26 -0
  187. package/dist/services/people/_invoke.d.ts.map +1 -0
  188. package/dist/services/people/copilot/index.d.ts +132 -0
  189. package/dist/services/people/copilot/index.d.ts.map +1 -0
  190. package/dist/services/people/identity/actions.d.ts +116 -0
  191. package/dist/services/people/identity/actions.d.ts.map +1 -0
  192. package/dist/services/people/identity/ct.types.d.ts +133 -0
  193. package/dist/services/people/identity/ct.types.d.ts.map +1 -0
  194. package/dist/services/people/identity/index.d.ts +14 -0
  195. package/dist/services/people/identity/index.d.ts.map +1 -0
  196. package/dist/services/people/identity/projections.d.ts +63 -0
  197. package/dist/services/people/identity/projections.d.ts.map +1 -0
  198. package/dist/services/people/index.d.ts +31 -0
  199. package/dist/services/people/index.d.ts.map +1 -0
  200. package/dist/services/people/legal/actions.d.ts +161 -0
  201. package/dist/services/people/legal/actions.d.ts.map +1 -0
  202. package/dist/services/people/legal/ct.types.d.ts +186 -0
  203. package/dist/services/people/legal/ct.types.d.ts.map +1 -0
  204. package/dist/services/people/legal/index.d.ts +15 -0
  205. package/dist/services/people/legal/index.d.ts.map +1 -0
  206. package/dist/services/people/packops/index.d.ts +70 -0
  207. package/dist/services/people/packops/index.d.ts.map +1 -0
  208. package/dist/services/people/packops/packops.type.d.ts +183 -0
  209. package/dist/services/people/packops/packops.type.d.ts.map +1 -0
  210. package/dist/services/people/perms/actions.d.ts +214 -0
  211. package/dist/services/people/perms/actions.d.ts.map +1 -0
  212. package/dist/services/people/perms/ct.types.d.ts +140 -0
  213. package/dist/services/people/perms/ct.types.d.ts.map +1 -0
  214. package/dist/services/people/perms/index.d.ts +14 -0
  215. package/dist/services/people/perms/index.d.ts.map +1 -0
  216. package/dist/services/people/perms/projections.d.ts +47 -0
  217. package/dist/services/people/perms/projections.d.ts.map +1 -0
  218. package/dist/services/people/process/actions.d.ts +154 -0
  219. package/dist/services/people/process/actions.d.ts.map +1 -0
  220. package/dist/services/people/process/ct.types.d.ts +304 -0
  221. package/dist/services/people/process/ct.types.d.ts.map +1 -0
  222. package/dist/services/people/process/index.d.ts +12 -0
  223. package/dist/services/people/process/index.d.ts.map +1 -0
  224. package/dist/services/people/shared.types.d.ts +36 -0
  225. package/dist/services/people/shared.types.d.ts.map +1 -0
  226. package/dist/services/rules/conditions.d.ts +264 -0
  227. package/dist/services/rules/conditions.d.ts.map +1 -0
  228. package/dist/services/rules/index.d.ts +49 -0
  229. package/dist/services/rules/index.d.ts.map +1 -0
  230. package/dist/services/rules/llm-rule.constant.d.ts +84 -0
  231. package/dist/services/rules/llm-rule.constant.d.ts.map +1 -0
  232. package/dist/services/rules/mock.d.ts +20 -0
  233. package/dist/services/rules/mock.d.ts.map +1 -0
  234. package/dist/services/rules/rules.type.d.ts +262 -0
  235. package/dist/services/rules/rules.type.d.ts.map +1 -0
  236. package/dist/services/rules/triggers.d.ts +140 -0
  237. package/dist/services/rules/triggers.d.ts.map +1 -0
  238. package/dist/services/settings/index.d.ts +36 -0
  239. package/dist/services/settings/index.d.ts.map +1 -0
  240. package/dist/services/settings/mock.d.ts +14 -0
  241. package/dist/services/settings/mock.d.ts.map +1 -0
  242. package/dist/services/settings/settings.type.d.ts +39 -0
  243. package/dist/services/settings/settings.type.d.ts.map +1 -0
  244. package/dist/stores/auth.d.ts +192 -0
  245. package/dist/stores/auth.d.ts.map +1 -0
  246. package/dist/stores/bars.d.ts +288 -0
  247. package/dist/stores/bars.d.ts.map +1 -0
  248. package/dist/stores/content.d.ts +4101 -0
  249. package/dist/stores/content.d.ts.map +1 -0
  250. package/dist/stores/executions.d.ts +249 -0
  251. package/dist/stores/executions.d.ts.map +1 -0
  252. package/dist/stores/gov.d.ts +238 -0
  253. package/dist/stores/gov.d.ts.map +1 -0
  254. package/dist/stores/history.d.ts +833 -0
  255. package/dist/stores/history.d.ts.map +1 -0
  256. package/dist/stores/index.d.ts +15 -0
  257. package/dist/stores/index.d.ts.map +1 -0
  258. package/dist/stores/kalshi.d.ts +728 -0
  259. package/dist/stores/kalshi.d.ts.map +1 -0
  260. package/dist/stores/llm-providers.d.ts +97 -0
  261. package/dist/stores/llm-providers.d.ts.map +1 -0
  262. package/dist/stores/llm.d.ts +102 -0
  263. package/dist/stores/llm.d.ts.map +1 -0
  264. package/dist/stores/people.d.ts +596 -0
  265. package/dist/stores/people.d.ts.map +1 -0
  266. package/dist/stores/persist.d.ts +58 -0
  267. package/dist/stores/persist.d.ts.map +1 -0
  268. package/dist/stores/rules.d.ts +485 -0
  269. package/dist/stores/rules.d.ts.map +1 -0
  270. package/dist/stores/settings.d.ts +36 -0
  271. package/dist/stores/settings.d.ts.map +1 -0
  272. package/dist/stores/ws.d.ts +66 -0
  273. package/dist/stores/ws.d.ts.map +1 -0
  274. package/package.json +90 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 viettienlv97
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,478 @@
1
+ # @zeitvu97/cms-sdk
2
+
3
+ Data-access layer for EAERA CMS, built for **Nuxt 3** consumers.
4
+
5
+ - **HTTP**: [`ofetch`](https://github.com/unjs/ofetch) (same engine as Nuxt `$fetch`) — retry, timeout, typed responses, casing opt-in.
6
+ - **State**: [Pinia](https://pinia.vuejs.org/) + a **built-in cookie-based persistence plugin** (per-state, optional `httpOnly`) — no `pinia-plugin-persistedstate` dependency.
7
+ - **Auth**: single-source-of-truth `TokenManager` with pluggable storage adapters (memory / localStorage / cookie / httpOnly-bridge).
8
+ - **Multi-backend**: one `createCmsSDK()` facade can target multiple endpoints (CMS, report, …) sharing one token + hooks.
9
+ - **Domains**: `auth` · `content` · `rules` · `executions` · `settings` — five typed services + five Pinia stores.
10
+ - **Explicit imports**: nothing is auto-imported. You import exactly what you use.
11
+
12
+ > The auth service mirrors the **confirmed** CMS backend surface (login / logout / OAuth refresh only). The content/rules/executions/settings domains ship with a **mock mode** so the SDK is usable before the backend is fully wired; flip `mock: false` once the endpoints exist.
13
+
14
+ ## Requirements
15
+
16
+ | Dep | Version |
17
+ |---|---|
18
+ | Node | `>= 20` (dev repo pins `22` via `.nvmrc`) |
19
+ | Nuxt | `^3.0.0 \|\| ^4.0.0` (if using the Nuxt module) |
20
+ | Vue | `^3.5.0` (peer) |
21
+ | Pinia | `^3.0.4` (peer) |
22
+
23
+ ## Install
24
+
25
+ ```bash
26
+ pnpm add @zeitvu97/cms-sdk
27
+ # Peer deps (usually already present in a Nuxt app):
28
+ # pnpm add pinia vue
29
+ ```
30
+
31
+ > Persistence is **built into the SDK module** (cookie-based, per-state, optional `httpOnly`). No extra package or module is required.
32
+
33
+ ## Quick start (Nuxt 3)
34
+
35
+ Register the module and point it at your runtime config:
36
+
37
+ ```ts
38
+ // nuxt.config.ts
39
+ export default defineNuxtConfig({
40
+ modules: [
41
+ '@pinia/nuxt',
42
+ '@zeitvu97/cms-sdk/nuxt',
43
+ ],
44
+ runtimeConfig: {
45
+ public: {
46
+ cmsUrl: process.env.CMS_URL ?? 'https://cms.example.com',
47
+ reportUrl: process.env.REPORT_URL,
48
+ clientId: process.env.CMS_CLIENT_ID ?? 'web',
49
+ },
50
+ },
51
+ cmsSdk: {
52
+ // Each value is a KEY NAME in runtimeConfig.public (not the URL itself).
53
+ endpoints: { cms: 'cmsUrl', report: 'reportUrl' },
54
+ clientId: 'clientId', // runtimeConfig.public key holding the client id
55
+ mock: process.env.NODE_ENV !== 'production',
56
+ },
57
+ })
58
+ ```
59
+
60
+ > The module forces `'memory'` storage for `TokenManager` internally — the httpOnly cookie `cms_access_token` (managed by the module's `/api/cms/*` routes) is the real token persistence. The `storage` option only matters for standalone `createCmsSDK()`.
61
+
62
+ The module exposes `useNuxtApp().$cms`. Stores are **imported explicitly**:
63
+
64
+ ```vue
65
+ <script setup lang="ts">
66
+ import { useContentStore, CONTENT_TYPE } from '@zeitvu97/cms-sdk'
67
+
68
+ const { $cms } = useNuxtApp()
69
+ const content = useContentStore() // Pinia store; SDK attached by the module
70
+
71
+ await content.fetchByType(CONTENT_TYPE.MT5_ACCOUNT, { perPage: 50 })
72
+ </script>
73
+
74
+ <template>
75
+ <div v-for="acc in content.mt5Accounts" :key="acc.uuid">
76
+ {{ acc.data.login }} — {{ acc.data.group }} (leverage 1:{{ acc.data.leverage }})
77
+ </div>
78
+ </template>
79
+ ```
80
+
81
+ ## Imperative usage (no Nuxt module)
82
+
83
+ ```ts
84
+ import { createPinia } from 'pinia'
85
+ import { createCmsSDK } from '@zeitvu97/cms-sdk'
86
+
87
+ const sdk = createCmsSDK({
88
+ endpoints: { cms: 'https://cms.example.com' },
89
+ clientId: 'web',
90
+ credentials: { storage: 'localStorage' },
91
+ mock: true,
92
+ })
93
+
94
+ const accounts = await sdk.content.list<Mt5Account>({ type: 'Mt5Account', perPage: 50 })
95
+ const rule = await sdk.rules.detail('abc-uuid')
96
+ ```
97
+
98
+ To use the Pinia stores outside Nuxt, install Pinia + the built-in persistence plugin and attach the SDK. (Pinia 3.x defers `pinia.use` plugins until the pinia is installed on an app, so `app.use(pinia)` is required. httpOnly state is **not** available standalone — use a non-httpOnly storage such as `localStorage`.)
99
+
100
+ ```ts
101
+ import { createApp } from 'vue'
102
+ import { createPinia } from 'pinia'
103
+ import { createPersistPlugin, useContentStore } from '@zeitvu97/cms-sdk'
104
+
105
+ const pinia = createPinia()
106
+ createApp({}).use(pinia)
107
+ pinia.use(createPersistPlugin({ storage: localStorage, ssr: false }))
108
+
109
+ const content = useContentStore(pinia)
110
+ content.setSdk(sdk)
111
+ await content.fetchByType('Mt5Account')
112
+ ```
113
+
114
+ ---
115
+
116
+ ## API reference
117
+
118
+ ### `createCmsSDK(options)` → `ICmsSDK`
119
+
120
+ | Option | Type | Default | Description |
121
+ |---|---|---|---|
122
+ | `endpoints` | `{ cms: string; report?: string; poolTrading?: string; [k]: string }` | — | **Required.** Backend URLs; each becomes a `$Fetch` in `sdk.apis`. |
123
+ | `clientId` | `string` | — | Sent as `X-Client-Id` header. |
124
+ | `credentials` | `ICredentialsConfig` | `{ storage: 'cookie' }` | Token storage + header config (see below). |
125
+ | `device` | `{ deviceId?, deviceIp? }` | — | Static or function values sent as `DeviceID` / `DeviceIP`. |
126
+ | `timeout` | `number` | `30000` | Request timeout (ms). |
127
+ | `retry` | `number` | `2` | Retries on `408/425/429/5xx`. |
128
+ | `mock` | `boolean` | `false` | Return fake data instead of hitting the backend. |
129
+ | `responseCasing` | `'camel' \| 'snake'` | `'camel'` | Asks the backend for a casing via `x-response-casing`. |
130
+ | `requestCasing` | `'camel' \| 'snake'` | `'camel'` | Declares request-body casing via `x-request-casing`. |
131
+ | `onError` | `(e: CmsError) => void` | — | Global error callback (after normalisation). |
132
+ | `onUnauthorized` | `(e: CmsError) => void` | — | Called on `401` (e.g. force logout). |
133
+ | `onToken` | `(token: string \| null) => void \| Promise<void>` | — | Hook fired whenever the access token changes (refresh, 401). |
134
+ | `refresh` | `() => Promise<string \| null>` | — | Silent refresh on 401 (Nuxt module wires this to `/api/cms/refresh`). |
135
+ | `authRoute` | `$Fetch` | — | `$Fetch` used for token-lifecycle flows so the httpOnly cookie is set atomically. |
136
+
137
+ **Returns** `ICmsSDK`:
138
+
139
+ | Member | Type | Description |
140
+ |---|---|---|
141
+ | `apis` | `Record<string, $Fetch>` | One typed fetcher per endpoint (e.g. `sdk.apis.cms`, `sdk.apis.report`). |
142
+ | `tokenManager` | `TokenManager` | Single source of truth for the access token. |
143
+ | `auth` | `IAuthService` | Auth domain service (login / logout / token). |
144
+ | `content` | `IContentService` | Content CRUD + actions. |
145
+ | `rules` | `IRulesService` | Content-rule CRUD. |
146
+ | `executions` | `IExecutionsService` | Read-only execution feed. |
147
+ | `settings` | `ISettingsService` | Dashboard settings (monitored groups). |
148
+ | `addRequestMiddleware(target, mw)` | `() => void` | Register a runtime request hook (`'all'` or an endpoint name); returns an unsubscribe. |
149
+ | `setMock(enabled)` | `(b) => void` | Toggle mock mode at runtime. |
150
+ | `syncToken(token)` | `(t: string \| null) => Promise<void>` | Set/clear token (login/restore/logout). |
151
+
152
+ ### `sdk.auth` — Auth service
153
+
154
+ | Method | Params | Returns | Notes |
155
+ |---|---|---|---|
156
+ | `login` | `payload: ILoginPayload, userAgent?` | `IAuthRouteResponse` | `POST /api/auth/login` (or `/api/cms/login` via proxy). |
157
+ | `logout` | — | `unknown` | `POST /api/auth/logout`. |
158
+ | `token` | — | `ITokenResponse` | OAuth refresh (`POST /api/oauth/token`); returns the new access token in the body. |
159
+
160
+ > When a `routeApi` (Nuxt module) is configured, all three flows route through the `/api/cms/*` proxies so httpOnly cookies are set / cleared / rotated atomically.
161
+
162
+ ### `sdk.content` — Content service
163
+
164
+ Generic CMS content CRUD over the **singular** `/api/v1/content` namespace; type-specific reads use `query: { type }`.
165
+
166
+ | Method | Params | Returns | Notes |
167
+ |---|---|---|---|
168
+ | `list` | `query?: ContentQuery` | `ContentListResponse<ContentItem<T>>` | Paginated (1-based `page`/`perPage`), filterable by `type`/`status`/`packId`. |
169
+ | `detail` | `uuid: string` | `ContentItem<T>` | Throws on miss. |
170
+ | `create` | `payload: ContentCreatePayload<T>` | `ContentItem<T>` | POST. |
171
+ | `update` | `uuid, payload: ContentUpdatePayload<T>` | `ContentItem<T>` | PUT (data/slug). |
172
+ | `remove` | `uuid: string` | `void` | Soft-delete. |
173
+ | `listActions` | `uuid: string` | `ContentAction[]` | CT actions available on the item. |
174
+ | `invokeAction` | `uuid, actionName, payload?` | `ActionResponse` | Run a CT action (e.g. `change_group`, `change_leverage`). |
175
+
176
+ ```ts
177
+ const { items } = await sdk.content.list<Mt5Account>({ type: 'Mt5Account', perPage: 50 })
178
+
179
+ await sdk.content.invokeAction(acc.uuid, 'change_leverage', {
180
+ params: { newLeverage: 100 },
181
+ intentionId: crypto.randomUUID(),
182
+ })
183
+ ```
184
+
185
+ ### `sdk.rules` — Rules service
186
+
187
+ Content-rule CRUD over `/api/v1/rules`. A rule binds a **trigger** → **condition** → **execution**.
188
+
189
+ | Method | Params | Returns | Notes |
190
+ |---|---|---|---|
191
+ | `list` | `query?: RuleListQuery` | `ContentRuleListResponse` | No pagination (`total === items.length`). |
192
+ | `detail` | `uuid: string` | `ContentRule` | Full rule. |
193
+ | `create` | `payload: RuleCreatePayload` | `ContentRule` | POST (flat payload). |
194
+ | `update` | `uuid, payload: RuleUpdatePayload` | `ContentRule` | PUT. |
195
+ | `remove` | `uuid: string` | `void` | Deactivate. |
196
+
197
+ The SDK ships **rule-builder helpers** so the dashboard authors valid triggers + actions (see `services/rules/triggers.ts` + `conditions.ts`):
198
+
199
+ ```ts
200
+ import {
201
+ buildSignalTrigger, buildCronTrigger, CRON_PRESETS,
202
+ CONDITION_FIELDS, CONDITION_OPERATORS,
203
+ ACTION_KINDS, LEVERAGE_OPTIONS,
204
+ } from '@zeitvu97/cms-sdk'
205
+
206
+ await sdk.rules.create({
207
+ name: 'High drawdown → move group',
208
+ contentType: 'Mt5Account',
209
+ trigger: buildSignalTrigger(), // signal over the metric stream
210
+ conditionType: 'expression',
211
+ conditionExpr: 'account_metric_by_deal.relative_balance_drawdown > 0.30',
212
+ executionType: 'action',
213
+ executionParams: { actionName: 'change_group', params: { newGroup: 'live\\restricted' } },
214
+ })
215
+ ```
216
+
217
+ ### `sdk.executions` — Executions service (read-only)
218
+
219
+ Backs the detection feed + the action-history table. No remediation write endpoint — operator remediation goes through `content.invokeAction`.
220
+
221
+ | Method | Params | Returns | Notes |
222
+ |---|---|---|---|
223
+ | `list` | `params?: ExecutionListParams` | `ExecutionListResponse` | `GET /api/v1/executions`, or `GET /api/v1/rules/content/{contentId}/executions` when `contentId` is set. |
224
+ | `detail` | `uuid: string` | `ContentExecution` | Single execution row. |
225
+
226
+ ### `sdk.settings` — Settings service
227
+
228
+ | Method | Params | Returns | Notes |
229
+ |---|---|---|---|
230
+ | `getMonitoredGroups` | — | `Promise<string[]>` | Reads `setting.dashboard.monitored_groups`. |
231
+ | `setMonitoredGroups` | `groups: string[]` | `Promise<string[]>` | Writes the setting. |
232
+
233
+ ### Types
234
+
235
+ Each domain exports its DTOs (`ContentItem<T>`, `Mt5Account`, `ContentRule`, `ContentExecution`, …) plus the helper types (`ConditionField`, `ActionKindDef`, `CronPreset`, `TriggerMode`, `LeverageOption`, …). The mt5 pack registers **9 content types** via `CONTENT_TYPE` (`Mt5Server`, `Mt5Account`, `Mt5SyncState`, `ReportDefinition`, `LlmPrompt`, `LlmConversation`, `KalshiServer`, `KalshiEvent`, `KalshiFuture`). See `types-and-constants.md` in the docs hub for the full catalog.
236
+
237
+ ### Helpers
238
+
239
+ ```ts
240
+ import { formatPrice, computeSpread, categoryLabel } from '@zeitvu97/cms-sdk'
241
+
242
+ formatPrice(1.0876, 5) // '1.08760'
243
+ computeSpread(1.0875, 1.0876) // 0.0001
244
+ categoryLabel('fx') // 'Forex'
245
+ ```
246
+
247
+ ---
248
+
249
+ ## Pinia stores
250
+
251
+ All stores must be **imported explicitly**. The Nuxt module attaches the SDK automatically; elsewhere call `setSdk(sdk)` once.
252
+
253
+ ### `useAuthStore` — `cms-auth`
254
+
255
+ | | |
256
+ |---|---|
257
+ | **State** | `authUser`, `employee`, `allowRoutes`, `accessToken` (reactive mirror of the token) |
258
+ | **Getters** | `isLoggedIn` → `!!accessToken`; `routeList` → parsed route permissions |
259
+ | **Actions** | `setSdk(sdk)`, `login`, `refreshToken`, `logout` |
260
+ | **Persist** | `fields: { authUser: { httpOnly: true } }` → cookie `cms-persist-auth.authUser` (httpOnly, server-written via `/api/cms-sdk/persist`) |
261
+
262
+ > `accessToken` is a **reactive mirror** of `TokenManager.currentToken`; it is intentionally **NOT** persisted by Pinia. The durable copy lives in the httpOnly cookie (managed by the Nuxt module), and the mirror is restored from that cookie on SSR.
263
+
264
+ > `allowRoutes` is **derived** from `authUser.allowRoutes` via a watcher, so the menu stays in sync with the persisted user profile on hydrate.
265
+
266
+ ### `useContentStore` — `cms-content`
267
+
268
+ Holds **9 typed slices** (one per mt5-pack CT) and exposes **7 generic actions** that delegate 1:1 to the `content` service.
269
+
270
+ | | |
271
+ |---|---|
272
+ | **State** | `mt5Servers`, `mt5Accounts`, `mt5SyncStates`, `reportDefinitions`, `llmPrompts`, `llmConversations`, `kalshiServers`, `kalshiEvents`, `kalshiFutures`, `isLoading`, `loadError`, `lastQueryByType` |
273
+ | **Getters** | `isEmpty`, `groups` (distinct `Mt5Server.data.name`), `getByType(typeName)`, `getActionsForType(typeName)`, `knownTypes` |
274
+ | **Actions** | `setSdk`, `fetchByType(typeName, query?)`, `fetchOne(uuid)`, `create`, `update`, `remove`, `fetchActions(uuid)`, `invokeAction(uuid, actionName, payload?)` |
275
+ | **Persist** | `pick: ['lastQueryByType']` → cookie `cms-content-v1.lastQueryByType` (non-httpOnly) |
276
+
277
+ > Mutations (`create`/`update`/`remove`/`invokeAction`) do **not** auto-refetch the affected slice — call `fetchByType(typeName)` again if you need it refreshed.
278
+
279
+ ### `useRulesStore` — `cms-rules`
280
+
281
+ | | |
282
+ |---|---|
283
+ | **State** | `items`, `total`, `isLoading`, `loadError`, `lastQuery`, `selectedRule` |
284
+ | **Getters** | `isEmpty`, `activeRules` |
285
+ | **Actions** | `setSdk`, `fetch(query?)`, `select(uuid)`, `create`, `update`, `toggle(uuid, active)`, `remove` |
286
+ | **Persist** | `pick: ['lastQuery']` → cookie `cms-rules-v1.lastQuery` (non-httpOnly) |
287
+
288
+ ### `useExecutionsStore` — `cms-executions`
289
+
290
+ | | |
291
+ |---|---|
292
+ | **State** | `items`, `total`, `isLoading`, `loadError`, `lastParams` |
293
+ | **Getters** | `isEmpty` |
294
+ | **Actions** | `setSdk`, `list(params?)` (read-only) |
295
+ | **Persist** | `pick: ['lastParams']` → cookie `cms-executions-v1.lastParams` (non-httpOnly) |
296
+
297
+ ### `useSettingsStore` — `cms-settings`
298
+
299
+ | | |
300
+ |---|---|
301
+ | **State** | `monitoredGroups`, `isLoading`, `loadError` |
302
+ | **Getters** | `isEmpty` |
303
+ | **Actions** | `setSdk`, `fetchGroups()`, `addGroup(group)`, `removeGroup(group)` (optimistic + rollback) |
304
+ | **Persist** | `pick: ['monitoredGroups']` → cookie `cms-settings-v1.monitoredGroups` (non-httpOnly) |
305
+
306
+ ---
307
+
308
+ ## Authentication & token flow
309
+
310
+ > **Primary call path: Pinia store actions.** Call `useAuthStore()` actions from your app — they own the SDK and the reactive state. `$cms.*` (services / raw `$Fetch`) is an escape hatch.
311
+
312
+ The durable token copy lives in an **httpOnly cookie** (`cms_access_token`) managed by the Nuxt module; a parallel `cms_refresh_token` cookie backs silent refresh. `TokenManager` is the in-memory source for request headers; `useAuthStore.accessToken` is a reactive mirror (restored from the cookie on SSR, **never** persisted to localStorage).
313
+
314
+ ### How it flows (Nuxt module)
315
+
316
+ ```
317
+ login → useAuthStore.login() → /api/cms/login (server route)
318
+ → backend POST /api/auth/login → token in response BODY (accessToken)
319
+ → route sets httpOnly cookies cms_access_token + cms_refresh_token (atomic)
320
+ → returns { ..., token } → client mirrors token in memory
321
+ logout → useAuthStore.logout() → /api/cms/logout
322
+ → backend POST /api/auth/logout (Bearer from cookie) + both cookies cleared
323
+ refresh → on 401, createApi calls /api/cms/refresh once
324
+ → backend /api/oauth/token (grant_type=refresh_token, reads cms_refresh_token cookie)
325
+ → rotates both cookies, replays the request; on failure clears session + onUnauthorized
326
+ sliding → rotated token in response header → onToken → /api/cms/set-token (cookie refreshed, no drift)
327
+ data → useContentStore.fetchByType() / useRulesStore.fetch() → direct client→backend
328
+ → onRequest injects Authorization from TokenManager
329
+ F5 → SSR reads httpOnly token cookie → restores TokenManager + accessToken mirror;
330
+ persist plugin hydrates authUser (cms-persist-auth.authUser) from its cookie
331
+ 401 → onResponseError → onToken(null) → /api/cms/clear-token + onUnauthorized fired
332
+ ```
333
+
334
+ ### Server routes registered by the module
335
+
336
+ | Route | Purpose |
337
+ |---|---|
338
+ | `POST /api/cms/login` | login → backend `/api/auth/login`, sets httpOnly `cms_access_token` + `cms_refresh_token` from body, returns `{ ..., token }` |
339
+ | `POST /api/cms/logout` | logout (backend `POST /api/auth/logout` + clears both cookies) |
340
+ | `POST /api/cms/refresh` | silent refresh — reads httpOnly `cms_refresh_token` → backend `/api/oauth/token` (`grant_type=refresh_token`), rotates both cookies, returns new access token |
341
+ | `POST /api/cms/set-token` | sync cookie on sliding-refresh / external token restore |
342
+ | `DELETE /api/cms/clear-token` | clear cookie on 401 |
343
+ | `POST /api/cms-sdk/persist` | set/clear an **allowlisted** httpOnly persist cookie (internal persistence plugin) |
344
+
345
+ These are thin proxies (raw `ofetch`, no SDK instance) — they read `device_id`/`device_ip`/`user-agent` from the request, call the backend, and set/clear the httpOnly cookie.
346
+
347
+ ### `TokenManager`
348
+
349
+ ```ts
350
+ sdk.tokenManager.get() // string | null
351
+ sdk.tokenManager.has() // boolean
352
+ sdk.tokenManager.set(t) // store + onRefreshed hook
353
+ sdk.tokenManager.clear()
354
+ sdk.tokenManager.getHeader() // `${prefix}${token}` ready for a header
355
+ sdk.tokenManager.swapStorage(storage) // upgrade storage at runtime
356
+ ```
357
+
358
+ ### `sdk.syncToken(token)`
359
+
360
+ Used by login (via the route body `token`) / external SSO / 401. When an `onToken` hook is configured (the Nuxt module wires one), `syncToken` awaits it (sets memory + syncs the httpOnly cookie); otherwise it falls back to `TokenManager.set/clear`.
361
+
362
+ ```ts
363
+ await sdk.syncToken('jwt-from-external-sso') // set
364
+ await sdk.syncToken(null) // clear
365
+ ```
366
+
367
+ ### Credentials storage (TokenManager backend)
368
+
369
+ The Nuxt module forces **`'memory'`** for TokenManager (the httpOnly cookie is the real persistence). For standalone `createCmsSDK()` you can choose:
370
+
371
+ | `storage` | Backend | Use when |
372
+ |---|---|---|
373
+ | `'memory'` | in-process variable | SSR-safe; token lost on reload |
374
+ | `'localStorage'` | browser localStorage | SPA, acceptable XSS exposure |
375
+ | `'cookie'` | browser cookie (`document.cookie`) | SPA only — **client-side**; absent during SSR |
376
+
377
+ ### Requirements (Nuxt)
378
+
379
+ - The SDK registers its **built-in cookie-based persistence plugin** automatically via the Nuxt module — **no `pinia-plugin-persistedstate` (or any extra module) is needed**. Persistence is per-state: sensitive state (`authUser`) uses an **httpOnly cookie** written through `/api/cms-sdk/persist`, while UI prefs (`lastQueryByType`, `lastQuery`, `lastParams`, `monitoredGroups`) use **non-httpOnly cookies** written directly on the client. Both are SSR-readable (instant on F5).
380
+ - The httpOnly cookie is **not readable by JS**; client-side calls rely on the store mirror restored from the SSR payload.
381
+
382
+ > Cookie defaults for the httpOnly cookie: `Secure`, `SameSite=Lax`, `Path=/`, `Max-Age=30 days`, `httpOnly: true` (see `COOKIE_DEFAULTS`).
383
+
384
+ > **Cookie size limit:** cookies are ~4 KB. If your JWT exceeds this, the set-token/login route will fail; consider smaller tokens.
385
+
386
+ ---
387
+
388
+ ## Error handling
389
+
390
+ Every failed request is normalised to a `CmsError` and passed to `onError` (and `onUnauthorized` on 401). You may also `try/catch` locally.
391
+
392
+ ```ts
393
+ import { CmsError } from '@zeitvu97/cms-sdk'
394
+
395
+ try {
396
+ await sdk.content.detail('missing-uuid')
397
+ } catch (e) {
398
+ const err = e as CmsError
399
+ err.message // string
400
+ err.statusCode // number (0 = network)
401
+ err.code // string
402
+ err.fieldErrors // Record<string,string> | undefined (422)
403
+ err.requestId // from x-request-id header
404
+ err.isUnauthorized // 401
405
+ err.isValidation // 422
406
+ err.isNetwork // statusCode === 0
407
+ }
408
+ ```
409
+
410
+ ---
411
+
412
+ ## Runtime request middlewares
413
+
414
+ Register a custom request hook at runtime (the "dynamic interceptor" escape hatch). `target` is `'all'` or an endpoint name (`'cms'`, `'report'`, …). Returns an unsubscribe.
415
+
416
+ ```ts
417
+ const off = sdk.addRequestMiddleware('all', (options, ctx) => {
418
+ options.headers.set('X-Experiment', 'variant-b')
419
+ })
420
+ // later
421
+ off()
422
+ ```
423
+
424
+ ---
425
+
426
+ ## Mock mode
427
+
428
+ While the backend is under development, `mock: true` makes every domain service resolve from a local fake dataset and never touch the network.
429
+
430
+ ```ts
431
+ const sdk = createCmsSDK({ endpoints: { cms: 'http://x' }, mock: true })
432
+
433
+ await sdk.content.list({ type: 'Mt5Account' }) // fake data
434
+ sdk.setMock(false) // switch to real backend at runtime
435
+ ```
436
+
437
+ ---
438
+
439
+ ## Project structure
440
+
441
+ ```
442
+ src/
443
+ ├── core/ # Stable foundation
444
+ │ ├── createCmsSDK.ts # Facade entry point (builds everything)
445
+ │ ├── createApi.ts # ofetch factory + auth/refresh/error hooks
446
+ │ ├── errors.ts # CmsError (normalised error shape)
447
+ │ ├── sdk.type.ts # Core public types (ICmsSDK, ICmsSDKOptions, …)
448
+ │ └── credentials/ # TokenManager + storage adapters
449
+ ├── services/ # 5 domain services (stateless, call $Fetch)
450
+ │ ├── auth/ # login / logout / OAuth refresh (confirmed BE)
451
+ │ ├── content/ # CRUD + actions over /api/v1/content
452
+ │ ├── rules/ # rule CRUD + trigger/condition builders
453
+ │ ├── executions/ # read-only execution feed
454
+ │ └── settings/ # monitored groups
455
+ ├── stores/ # 5 Pinia setup stores + persistence plugin
456
+ ├── server/ # h3 handlers (auth proxies + token/persist)
457
+ ├── common/
458
+ │ ├── constants/ # UPPER_SNAKE const objects (no hardcoding)
459
+ │ ├── helpers/ # formatPrice / computeSpread / categoryLabel
460
+ │ └── utils/ # SDK-internal utilities (clone, casing)
461
+ ├── nuxt.ts # Nuxt module (registers $cms + stores + persistence)
462
+ └── index.ts # Public barrel exports
463
+ ```
464
+
465
+ Layering rule: `stores` → `services` → `core` (createApi/TokenManager) → `common` (constants/helpers/utils). Nothing reaches upward.
466
+
467
+ ## Development
468
+
469
+ ```bash
470
+ pnpm install
471
+ pnpm test # vitest
472
+ pnpm typecheck # tsc --noEmit
473
+ pnpm build # vite build → dist/
474
+ ```
475
+
476
+ ## License
477
+
478
+ MIT — see [LICENSE](./LICENSE).
@@ -0,0 +1,26 @@
1
+ import { a as COOKIE_DEFAULTS } from './storage.constant--64BDSPW.js';
2
+ import { useRuntimeConfig } from '#imports';
3
+
4
+ const TOKEN_COOKIE_OPTIONS = {
5
+ httpOnly: COOKIE_DEFAULTS.HTTP_ONLY,
6
+ secure: COOKIE_DEFAULTS.SECURE,
7
+ sameSite: COOKIE_DEFAULTS.SAME_SITE.toLowerCase(),
8
+ path: COOKIE_DEFAULTS.PATH,
9
+ maxAge: COOKIE_DEFAULTS.MAX_AGE_SECONDS
10
+ };
11
+ function readSdkConfig(event) {
12
+ const config = useRuntimeConfig(event);
13
+ const pub = config?.public ?? {};
14
+ const opts = pub.cmsSdkOptions ?? {};
15
+ const cmsUrl = pub[opts.endpoints?.cms ?? "cmsUrl"];
16
+ const clientId = pub[opts.clientId ?? "clientId"];
17
+ return {
18
+ cmsUrl,
19
+ clientId,
20
+ requestCasing: opts.requestCasing,
21
+ responseCasing: opts.responseCasing
22
+ };
23
+ }
24
+
25
+ export { TOKEN_COOKIE_OPTIONS as T, readSdkConfig as r };
26
+ //# sourceMappingURL=_shared-48T7q0V3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_shared-48T7q0V3.js","sources":["../../src/server/auth/_shared.ts"],"sourcesContent":["import {\n COOKIE_DEFAULTS,\n REFRESH_TOKEN_STORAGE_KEY,\n TOKEN_STORAGE_KEY,\n} from '../../common/constants/storage.constant';\nimport type { RequestCasing, ResponseCasing } from '../../common/constants/http.constant';\nimport { useRuntimeConfig } from '#imports';\n\n/** Cookie options for the httpOnly access-token cookie (server-side set). */\nexport const TOKEN_COOKIE_OPTIONS = {\n httpOnly: COOKIE_DEFAULTS.HTTP_ONLY,\n secure: COOKIE_DEFAULTS.SECURE,\n sameSite: COOKIE_DEFAULTS.SAME_SITE.toLowerCase() as 'lax',\n path: COOKIE_DEFAULTS.PATH,\n maxAge: COOKIE_DEFAULTS.MAX_AGE_SECONDS,\n};\n\nexport { TOKEN_STORAGE_KEY, REFRESH_TOKEN_STORAGE_KEY };\n\n/**\n * Resolve the CMS backend URL + client id from the module options the Nuxt\n * module stored on `runtimeConfig.public.cmsSdkOptions` (mirrors the plugin\n * resolution). Runs inside the consumer's Nitro server where `useRuntimeConfig`\n * is auto-imported.\n */\nexport function readSdkConfig(event: unknown): {\n cmsUrl: string;\n clientId: string;\n requestCasing?: RequestCasing;\n responseCasing?: ResponseCasing;\n} {\n const config = useRuntimeConfig(event) as { public?: Record<string, any> } | undefined;\n const pub = (config?.public ?? {}) as Record<string, any>;\n const opts = (pub.cmsSdkOptions ?? {}) as {\n endpoints?: Record<string, string>;\n clientId?: string;\n requestCasing?: RequestCasing;\n responseCasing?: ResponseCasing;\n };\n const cmsUrl = pub[opts.endpoints?.cms ?? 'cmsUrl'];\n const clientId = pub[opts.clientId ?? 'clientId'];\n return {\n cmsUrl,\n clientId,\n requestCasing: opts.requestCasing,\n responseCasing: opts.responseCasing,\n };\n}\n"],"names":[],"mappings":";;;AASO,MAAM,oBAAA,GAAuB;AAAA,EAClC,UAAU,eAAA,CAAgB,SAAA;AAAA,EAC1B,QAAQ,eAAA,CAAgB,MAAA;AAAA,EACxB,QAAA,EAAU,eAAA,CAAgB,SAAA,CAAU,WAAA,EAAY;AAAA,EAChD,MAAM,eAAA,CAAgB,IAAA;AAAA,EACtB,QAAQ,eAAA,CAAgB;AAC1B;AAUO,SAAS,cAAc,KAAA,EAK5B;AACA,EAAA,MAAM,MAAA,GAAS,iBAAiB,KAAK,CAAA;AACrC,EAAA,MAAM,GAAA,GAAO,MAAA,EAAQ,MAAA,IAAU,EAAC;AAChC,EAAA,MAAM,IAAA,GAAQ,GAAA,CAAI,aAAA,IAAiB,EAAC;AAMpC,EAAA,MAAM,MAAA,GAAS,GAAA,CAAI,IAAA,CAAK,SAAA,EAAW,OAAO,QAAQ,CAAA;AAClD,EAAA,MAAM,QAAA,GAAW,GAAA,CAAI,IAAA,CAAK,QAAA,IAAY,UAAU,CAAA;AAChD,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,QAAA;AAAA,IACA,eAAe,IAAA,CAAK,aAAA;AAAA,IACpB,gBAAgB,IAAA,CAAK;AAAA,GACvB;AACF;;;;"}
@@ -0,0 +1,68 @@
1
+ const HTTP_HEADER = {
2
+ AUTHORIZATION: "Authorization",
3
+ DEVICE_ID: "DeviceID",
4
+ DEVICE_IP: "DeviceIP",
5
+ CLIENT_ID: "X-Client-Id",
6
+ USER_AGENT: "user-agent",
7
+ REQUEST_ID: "x-request-id",
8
+ /**
9
+ * Backend response-casing selector. Default backend casing is camelCase
10
+ * (omit the header); send `snake` to receive snake_case bodies.
11
+ */
12
+ RESPONSE_CASING: "x-response-casing",
13
+ /**
14
+ * Backend request-casing selector. Default is camelCase (omit the header);
15
+ * send `snake` to declare a snake_case request body.
16
+ */
17
+ REQUEST_CASING: "x-request-casing"
18
+ };
19
+ const RESPONSE_CASING_VALUE = {
20
+ SNAKE: "snake"
21
+ };
22
+ const SERIALIZATION_FORMAT = {
23
+ JSON: "json",
24
+ YAML: "yaml"
25
+ };
26
+ const HTTP_DEFAULTS = {
27
+ TIMEOUT_MS: 3e4,
28
+ RETRY: 0
29
+ };
30
+ const HTTP_RETRY_STATUS_CODES = [408, 425, 429, 500, 502, 503, 504];
31
+
32
+ const AUTH_ENDPOINT = {
33
+ LOGIN: "/api/auth/login",
34
+ LOGOUT: "/api/auth/logout",
35
+ REFRESH: "/api/oauth/token",
36
+ /** User registry (GET /api/auth/users) — list of the CMS auth users. */
37
+ USERS: "/api/auth/users",
38
+ /** "Login with CBS" — init (PKCE verifier + state stay server-side). */
39
+ CBS_START: "/api/v1/auth/oauth/cbs/start",
40
+ /** "Login with CBS" — complete (exchange code → CMS session JWT). */
41
+ CBS_CALLBACK: "/api/v1/auth/oauth/cbs/callback",
42
+ /** IdP SSO — init (`GET /api/auth/{provider}/login?redirect_uri=…`). */
43
+ idpLogin: (provider) => `/api/auth/${provider}/login`,
44
+ /** IdP SSO — callback (`GET /api/auth/{provider}/callback?code&state&redirect_uri`). */
45
+ idpCallback: (provider) => `/api/auth/${provider}/callback`,
46
+ /** IdP SSO — link an already-authenticated user to the provider (needs Bearer). */
47
+ idpLink: (provider) => `/api/auth/${provider}/link`,
48
+ /** IdP SSO — unlink the provider from the current user (needs Bearer). */
49
+ idpUnlink: (provider) => `/api/auth/${provider}/unlink`
50
+ };
51
+ const AUTH_PROXY_PATH = {
52
+ LOGIN: "/login",
53
+ LOGOUT: "/logout",
54
+ REFRESH: "/refresh",
55
+ CBS_START: "/cbs-start",
56
+ CBS_CALLBACK: "/cbs-callback",
57
+ /** IdP SSO — init (query: `provider`, `redirect_uri`). */
58
+ IDP_LOGIN: "/idp-login",
59
+ /** IdP SSO — callback (query: `provider`, `code`, `state`, `redirect_uri`). */
60
+ IDP_CALLBACK: "/idp-callback",
61
+ /** IdP SSO — link (body: `{ provider }`; forwards the token cookie as Bearer). */
62
+ IDP_LINK: "/idp-link",
63
+ /** IdP SSO — unlink (query: `provider`; forwards the token cookie as Bearer). */
64
+ IDP_UNLINK: "/idp-unlink"
65
+ };
66
+
67
+ export { AUTH_PROXY_PATH as A, HTTP_DEFAULTS as H, RESPONSE_CASING_VALUE as R, SERIALIZATION_FORMAT as S, HTTP_RETRY_STATUS_CODES as a, HTTP_HEADER as b, AUTH_ENDPOINT as c };
68
+ //# sourceMappingURL=auth.constant-DO7ZmsKg.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.constant-DO7ZmsKg.js","sources":["../../src/common/constants/http.constant.ts","../../src/common/constants/auth.constant.ts"],"sourcesContent":["/**\n * HTTP-layer constants shared by the core `createApi` factory.\n */\n\n/** Canonical request/response header names used across the SDK. */\nexport const HTTP_HEADER = {\n AUTHORIZATION: 'Authorization',\n DEVICE_ID: 'DeviceID',\n DEVICE_IP: 'DeviceIP',\n CLIENT_ID: 'X-Client-Id',\n USER_AGENT: 'user-agent',\n REQUEST_ID: 'x-request-id',\n /**\n * Backend response-casing selector. Default backend casing is camelCase\n * (omit the header); send `snake` to receive snake_case bodies.\n */\n RESPONSE_CASING: 'x-response-casing',\n /**\n * Backend request-casing selector. Default is camelCase (omit the header);\n * send `snake` to declare a snake_case request body.\n */\n REQUEST_CASING: 'x-request-casing',\n} as const;\n\n/** Supported response-casing values. camelCase is the backend default. */\nexport const RESPONSE_CASING_VALUE = {\n CAMEL: 'camel',\n SNAKE: 'snake',\n} as const;\nexport type ResponseCasing = (typeof RESPONSE_CASING_VALUE)[keyof typeof RESPONSE_CASING_VALUE];\nexport type RequestCasing = ResponseCasing;\n\n/**\n * Serialization format discriminator. Accepted by content / rules /\n * lenses list endpoints via `?format=json|yaml`.\n */\nexport const SERIALIZATION_FORMAT = {\n JSON: 'json',\n YAML: 'yaml',\n} as const;\nexport type SerializationFormat = (typeof SERIALIZATION_FORMAT)[keyof typeof SERIALIZATION_FORMAT];\n\n/** Default per-request tuning (overridable via `createCmsSDK` options). */\nexport const HTTP_DEFAULTS = {\n TIMEOUT_MS: 30000,\n RETRY: 0,\n} as const;\n\n/** Status codes eligible for automatic retry (transient failures). */\nexport const HTTP_RETRY_STATUS_CODES = [408, 425, 429, 500, 502, 503, 504] as const;\n","/**\n * Auth backend endpoints.\n *\n * The CMS backend exposes exactly three auth endpoints:\n * - LOGIN (POST /api/auth/login) — confirmed against the real backend\n * - LOGOUT (POST /api/auth/logout) — confirmed (real backend logout is POST)\n * - REFRESH (POST /api/oauth/token) — confirmed — OAuth token endpoint;\n * grant_type=refresh_token\n *\n * Path params are appended at call sites.\n */\nexport const AUTH_ENDPOINT = {\n LOGIN: '/api/auth/login',\n LOGOUT: '/api/auth/logout',\n REFRESH: '/api/oauth/token',\n /** User registry (GET /api/auth/users) — list of the CMS auth users. */\n USERS: '/api/auth/users',\n /** \"Login with CBS\" — init (PKCE verifier + state stay server-side). */\n CBS_START: '/api/v1/auth/oauth/cbs/start',\n /** \"Login with CBS\" — complete (exchange code → CMS session JWT). */\n CBS_CALLBACK: '/api/v1/auth/oauth/cbs/callback',\n /** IdP SSO — init (`GET /api/auth/{provider}/login?redirect_uri=…`). */\n idpLogin: (provider: string): string => `/api/auth/${provider}/login`,\n /** IdP SSO — callback (`GET /api/auth/{provider}/callback?code&state&redirect_uri`). */\n idpCallback: (provider: string): string => `/api/auth/${provider}/callback`,\n /** IdP SSO — link an already-authenticated user to the provider (needs Bearer). */\n idpLink: (provider: string): string => `/api/auth/${provider}/link`,\n /** IdP SSO — unlink the provider from the current user (needs Bearer). */\n idpUnlink: (provider: string): string => `/api/auth/${provider}/unlink`,\n} as const;\n\n/**\n * Client→proxy route paths for token-lifecycle flows.\n *\n * When the Nuxt module is in use, login/logout/token route through the\n * app-origin server proxies (`/api/cms/*`) so the httpOnly cookies are\n * set/cleared/rotated atomically. These are the paths the auth service calls\n * on its `routeApi` (whose baseURL is `/api/cms`).\n */\nexport const AUTH_PROXY_PATH = {\n LOGIN: '/login',\n LOGOUT: '/logout',\n REFRESH: '/refresh',\n CBS_START: '/cbs-start',\n CBS_CALLBACK: '/cbs-callback',\n /** IdP SSO — init (query: `provider`, `redirect_uri`). */\n IDP_LOGIN: '/idp-login',\n /** IdP SSO — callback (query: `provider`, `code`, `state`, `redirect_uri`). */\n IDP_CALLBACK: '/idp-callback',\n /** IdP SSO — link (body: `{ provider }`; forwards the token cookie as Bearer). */\n IDP_LINK: '/idp-link',\n /** IdP SSO — unlink (query: `provider`; forwards the token cookie as Bearer). */\n IDP_UNLINK: '/idp-unlink',\n} as const;\n"],"names":[],"mappings":"AAKO,MAAM,WAAA,GAAc;AAAA,EACzB,aAAA,EAAe,eAAA;AAAA,EACf,SAAA,EAAW,UAAA;AAAA,EACX,SAAA,EAAW,UAAA;AAAA,EACX,SAAA,EAAW,aAAA;AAAA,EACX,UAAA,EAAY,YAAA;AAAA,EACZ,UAAA,EAAY,cAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKZ,eAAA,EAAiB,mBAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKjB,cAAA,EAAgB;AAClB;AAGO,MAAM,qBAAA,GAAwB;AAAA,EAEnC,KAAA,EAAO;AACT;AAQO,MAAM,oBAAA,GAAuB;AAAA,EAClC,IAAA,EAAM,MAAA;AAAA,EACN,IAAA,EAAM;AACR;AAIO,MAAM,aAAA,GAAgB;AAAA,EAC3B,UAAA,EAAY,GAAA;AAAA,EACZ,KAAA,EAAO;AACT;AAGO,MAAM,uBAAA,GAA0B,CAAC,GAAA,EAAK,GAAA,EAAK,KAAK,GAAA,EAAK,GAAA,EAAK,KAAK,GAAG;;ACtClE,MAAM,aAAA,GAAgB;AAAA,EAC3B,KAAA,EAAO,iBAAA;AAAA,EACP,MAAA,EAAQ,kBAAA;AAAA,EACR,OAAA,EAAS,kBAAA;AAAA;AAAA,EAET,KAAA,EAAO,iBAAA;AAAA;AAAA,EAEP,SAAA,EAAW,8BAAA;AAAA;AAAA,EAEX,YAAA,EAAc,iCAAA;AAAA;AAAA,EAEd,QAAA,EAAU,CAAC,QAAA,KAA6B,CAAA,UAAA,EAAa,QAAQ,CAAA,MAAA,CAAA;AAAA;AAAA,EAE7D,WAAA,EAAa,CAAC,QAAA,KAA6B,CAAA,UAAA,EAAa,QAAQ,CAAA,SAAA,CAAA;AAAA;AAAA,EAEhE,OAAA,EAAS,CAAC,QAAA,KAA6B,CAAA,UAAA,EAAa,QAAQ,CAAA,KAAA,CAAA;AAAA;AAAA,EAE5D,SAAA,EAAW,CAAC,QAAA,KAA6B,CAAA,UAAA,EAAa,QAAQ,CAAA,OAAA;AAChE;AAUO,MAAM,eAAA,GAAkB;AAAA,EAC7B,KAAA,EAAO,QAAA;AAAA,EACP,MAAA,EAAQ,SAAA;AAAA,EACR,OAAA,EAAS,UAAA;AAAA,EACT,SAAA,EAAW,YAAA;AAAA,EACX,YAAA,EAAc,eAAA;AAAA;AAAA,EAEd,SAAA,EAAW,YAAA;AAAA;AAAA,EAEX,YAAA,EAAc,eAAA;AAAA;AAAA,EAEd,QAAA,EAAU,WAAA;AAAA;AAAA,EAEV,UAAA,EAAY;AACd;;;;"}