@codingfactory/socialkit-vue 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 (56) hide show
  1. package/dist/composables/useAuth.d.ts +27 -0
  2. package/dist/composables/useAuth.d.ts.map +1 -0
  3. package/dist/composables/useAuth.js +137 -0
  4. package/dist/composables/useAuth.js.map +1 -0
  5. package/dist/index.d.ts +25 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +16 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/plugins/terminology/index.d.ts +11 -0
  10. package/dist/plugins/terminology/index.d.ts.map +1 -0
  11. package/dist/plugins/terminology/index.js +91 -0
  12. package/dist/plugins/terminology/index.js.map +1 -0
  13. package/dist/plugins/terminology/terms.d.ts +15 -0
  14. package/dist/plugins/terminology/terms.d.ts.map +1 -0
  15. package/dist/plugins/terminology/terms.js +72 -0
  16. package/dist/plugins/terminology/terms.js.map +1 -0
  17. package/dist/plugins/terminology/types.d.ts +32 -0
  18. package/dist/plugins/terminology/types.d.ts.map +1 -0
  19. package/dist/plugins/terminology/types.js +2 -0
  20. package/dist/plugins/terminology/types.js.map +1 -0
  21. package/dist/services/api.d.ts +50 -0
  22. package/dist/services/api.d.ts.map +1 -0
  23. package/dist/services/api.js +305 -0
  24. package/dist/services/api.js.map +1 -0
  25. package/dist/services/auth.d.ts +127 -0
  26. package/dist/services/auth.d.ts.map +1 -0
  27. package/dist/services/auth.js +562 -0
  28. package/dist/services/auth.js.map +1 -0
  29. package/dist/stores/auth.d.ts +174 -0
  30. package/dist/stores/auth.d.ts.map +1 -0
  31. package/dist/stores/auth.js +262 -0
  32. package/dist/stores/auth.js.map +1 -0
  33. package/dist/types/api.d.ts +52 -0
  34. package/dist/types/api.d.ts.map +1 -0
  35. package/dist/types/api.js +7 -0
  36. package/dist/types/api.js.map +1 -0
  37. package/dist/types/user.d.ts +42 -0
  38. package/dist/types/user.d.ts.map +1 -0
  39. package/dist/types/user.js +45 -0
  40. package/dist/types/user.js.map +1 -0
  41. package/dist/utils/tokenStorage.d.ts +41 -0
  42. package/dist/utils/tokenStorage.d.ts.map +1 -0
  43. package/dist/utils/tokenStorage.js +300 -0
  44. package/dist/utils/tokenStorage.js.map +1 -0
  45. package/package.json +40 -0
  46. package/src/composables/useAuth.ts +164 -0
  47. package/src/index.ts +118 -0
  48. package/src/plugins/terminology/index.ts +114 -0
  49. package/src/plugins/terminology/terms.ts +104 -0
  50. package/src/plugins/terminology/types.ts +28 -0
  51. package/src/services/api.ts +472 -0
  52. package/src/services/auth.ts +874 -0
  53. package/src/stores/auth.ts +400 -0
  54. package/src/types/api.ts +56 -0
  55. package/src/types/user.ts +94 -0
  56. package/src/utils/tokenStorage.ts +394 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenStorage.d.ts","sourceRoot":"","sources":["../../src/utils/tokenStorage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,2DAA2D;AAC3D,MAAM,WAAW,kBAAkB;IACjC,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,uFAAuF;IACvF,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC3B,mEAAmE;IACnE,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC7B,0FAA0F;IAC1F,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,sCAAsC;AACtC,MAAM,WAAW,YAAY;IAC3B,QAAQ,IAAI,MAAM,GAAG,IAAI,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,WAAW,IAAI,IAAI,CAAA;IACnB,QAAQ,IAAI,OAAO,CAAA;IACnB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAA;IAChD,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAA;IACxD,eAAe,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IACzC,oBAAoB,CAAC,0BAA0B,EAAE,OAAO,GAAG,OAAO,CAAA;CACnE;AAyID;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAiB7E;AAED,kDAAkD;AAClD,wBAAgB,kBAAkB,CAAC,MAAM,GAAE,kBAAuB,GAAG,YAAY,CAoMhF"}
@@ -0,0 +1,300 @@
1
+ /**
2
+ * Token storage utility for SocialKit-powered frontends.
3
+ *
4
+ * Tokens are cached in memory and persisted to a configurable browser storage
5
+ * backend. Use `createTokenStorage()` to get a configured instance.
6
+ */
7
+ import axios from 'axios';
8
+ const DEFAULT_STORAGE_KEY = 'auth_token';
9
+ const DEFAULT_REFRESH_ENDPOINTS = ['/v1/auth/refresh-token'];
10
+ const DEFAULT_ANONYMOUS_ENDPOINTS = [
11
+ '/sanctum/csrf-cookie',
12
+ '/v1/auth/login',
13
+ '/v1/auth/register',
14
+ '/v1/auth/forgot-password',
15
+ '/v1/auth/reset-password'
16
+ ];
17
+ function normalizeStoredToken(stored) {
18
+ if (typeof stored === 'string' && stored.length > 0) {
19
+ return stored;
20
+ }
21
+ return undefined;
22
+ }
23
+ function getBrowserStorage(kind) {
24
+ if (typeof window === 'undefined') {
25
+ return null;
26
+ }
27
+ try {
28
+ return kind === 'local' ? window.localStorage : window.sessionStorage;
29
+ }
30
+ catch {
31
+ return null;
32
+ }
33
+ }
34
+ function resolveStoragePair(shareSessions) {
35
+ if (shareSessions) {
36
+ return {
37
+ primary: getBrowserStorage('local'),
38
+ secondary: getBrowserStorage('session')
39
+ };
40
+ }
41
+ return {
42
+ primary: getBrowserStorage('session'),
43
+ secondary: getBrowserStorage('local')
44
+ };
45
+ }
46
+ function readStorageToken(storage, storageKey) {
47
+ if (storage === null) {
48
+ return undefined;
49
+ }
50
+ try {
51
+ const stored = storage.getItem(storageKey);
52
+ return normalizeStoredToken(stored);
53
+ }
54
+ catch {
55
+ return undefined;
56
+ }
57
+ }
58
+ function writeStorageToken(storage, storageKey, token) {
59
+ if (storage === null) {
60
+ return;
61
+ }
62
+ try {
63
+ storage.setItem(storageKey, token);
64
+ }
65
+ catch {
66
+ // Storage full or unavailable — token still works for this session via memory.
67
+ }
68
+ }
69
+ function removeStorageToken(storage, storageKey) {
70
+ if (storage === null) {
71
+ return;
72
+ }
73
+ try {
74
+ storage.removeItem(storageKey);
75
+ }
76
+ catch {
77
+ // Storage unavailable — ignore.
78
+ }
79
+ }
80
+ function isObjectRecord(value) {
81
+ return typeof value === 'object' && value !== null;
82
+ }
83
+ function extractAuthorizationHeaderValue(requestAuthHeaderOrHeaders) {
84
+ if (typeof requestAuthHeaderOrHeaders === 'string') {
85
+ return requestAuthHeaderOrHeaders;
86
+ }
87
+ if (!isObjectRecord(requestAuthHeaderOrHeaders)) {
88
+ return null;
89
+ }
90
+ const maybeGet = requestAuthHeaderOrHeaders.get;
91
+ if (typeof maybeGet === 'function') {
92
+ const uppercaseValue = maybeGet.call(requestAuthHeaderOrHeaders, 'Authorization');
93
+ if (typeof uppercaseValue === 'string' && uppercaseValue.length > 0) {
94
+ return uppercaseValue;
95
+ }
96
+ const lowercaseValue = maybeGet.call(requestAuthHeaderOrHeaders, 'authorization');
97
+ if (typeof lowercaseValue === 'string' && lowercaseValue.length > 0) {
98
+ return lowercaseValue;
99
+ }
100
+ }
101
+ const directUppercase = requestAuthHeaderOrHeaders.Authorization;
102
+ if (typeof directUppercase === 'string' && directUppercase.length > 0) {
103
+ return directUppercase;
104
+ }
105
+ const directLowercase = requestAuthHeaderOrHeaders.authorization;
106
+ if (typeof directLowercase === 'string' && directLowercase.length > 0) {
107
+ return directLowercase;
108
+ }
109
+ for (const [key, value] of Object.entries(requestAuthHeaderOrHeaders)) {
110
+ if (key.toLowerCase() !== 'authorization') {
111
+ continue;
112
+ }
113
+ if (typeof value === 'string' && value.length > 0) {
114
+ return value;
115
+ }
116
+ }
117
+ return null;
118
+ }
119
+ /**
120
+ * Extract a token string from various API response shapes.
121
+ *
122
+ * Handles:
123
+ * - `{ token: string }`
124
+ * - `{ data: { token: string } }`
125
+ */
126
+ export function extractTokenFromResponse(payload) {
127
+ if (!payload || typeof payload !== 'object') {
128
+ return undefined;
129
+ }
130
+ if ('token' in payload) {
131
+ const token = payload.token;
132
+ if (typeof token === 'string' && token.length > 0) {
133
+ return token;
134
+ }
135
+ }
136
+ if ('data' in payload) {
137
+ return extractTokenFromResponse(payload.data);
138
+ }
139
+ return undefined;
140
+ }
141
+ /** Create a configured token storage instance. */
142
+ export function createTokenStorage(config = {}) {
143
+ const storageKey = config.storageKey ?? DEFAULT_STORAGE_KEY;
144
+ const refreshEndpoints = config.refreshEndpoints ?? DEFAULT_REFRESH_ENDPOINTS;
145
+ const anonymousEndpoints = config.anonymousEndpoints ?? DEFAULT_ANONYMOUS_ENDPOINTS;
146
+ const apiBaseUrl = config.apiBaseUrl ?? '/api';
147
+ const shareSessions = config.shareSessions ?? false;
148
+ const storagePair = resolveStoragePair(shareSessions);
149
+ let inMemoryToken;
150
+ let refreshPromise = null;
151
+ function readPersistedToken() {
152
+ const primaryToken = readStorageToken(storagePair.primary, storageKey);
153
+ const secondaryToken = readStorageToken(storagePair.secondary, storageKey);
154
+ if (secondaryToken !== undefined) {
155
+ if (primaryToken === undefined) {
156
+ writeStorageToken(storagePair.primary, storageKey, secondaryToken);
157
+ }
158
+ removeStorageToken(storagePair.secondary, storageKey);
159
+ }
160
+ return primaryToken ?? secondaryToken;
161
+ }
162
+ function persistToken(token) {
163
+ writeStorageToken(storagePair.primary, storageKey, token);
164
+ removeStorageToken(storagePair.secondary, storageKey);
165
+ }
166
+ function clearPersistedTokens() {
167
+ removeStorageToken(getBrowserStorage('local'), storageKey);
168
+ removeStorageToken(getBrowserStorage('session'), storageKey);
169
+ }
170
+ function syncInMemoryTokenFromStorage() {
171
+ inMemoryToken = readPersistedToken();
172
+ }
173
+ inMemoryToken = readPersistedToken();
174
+ if (typeof window !== 'undefined') {
175
+ window.addEventListener('storage', (event) => {
176
+ const localStorageRef = getBrowserStorage('local');
177
+ const sessionStorageRef = getBrowserStorage('session');
178
+ if (event.storageArea &&
179
+ event.storageArea !== localStorageRef &&
180
+ event.storageArea !== sessionStorageRef) {
181
+ return;
182
+ }
183
+ if (event.key === storageKey) {
184
+ inMemoryToken = normalizeStoredToken(event.newValue);
185
+ if (inMemoryToken === undefined) {
186
+ clearPersistedTokens();
187
+ }
188
+ return;
189
+ }
190
+ if (event.key !== null) {
191
+ return;
192
+ }
193
+ syncInMemoryTokenFromStorage();
194
+ });
195
+ }
196
+ const refreshClient = axios.create({
197
+ baseURL: apiBaseUrl,
198
+ timeout: 30000,
199
+ headers: {
200
+ 'Content-Type': 'application/json',
201
+ Accept: 'application/json'
202
+ },
203
+ withCredentials: false
204
+ });
205
+ function getToken() {
206
+ if (inMemoryToken !== undefined) {
207
+ return inMemoryToken;
208
+ }
209
+ const persistedToken = readPersistedToken();
210
+ if (persistedToken !== undefined) {
211
+ inMemoryToken = persistedToken;
212
+ return persistedToken;
213
+ }
214
+ return null;
215
+ }
216
+ function setToken(token) {
217
+ inMemoryToken = token;
218
+ persistToken(token);
219
+ }
220
+ function removeToken() {
221
+ inMemoryToken = undefined;
222
+ clearPersistedTokens();
223
+ }
224
+ function hasToken() {
225
+ return getToken() !== null;
226
+ }
227
+ function shouldSkipAuth(url) {
228
+ if (!url) {
229
+ return false;
230
+ }
231
+ return anonymousEndpoints.some((endpoint) => url.includes(endpoint));
232
+ }
233
+ function isRefreshTokenEndpoint(url) {
234
+ if (!url) {
235
+ return false;
236
+ }
237
+ return refreshEndpoints.some((endpoint) => url.includes(endpoint));
238
+ }
239
+ async function requestTokenRefresh() {
240
+ const existingToken = getToken();
241
+ if (!existingToken) {
242
+ return null;
243
+ }
244
+ for (const endpoint of refreshEndpoints) {
245
+ try {
246
+ const response = await refreshClient.post(endpoint, {}, {
247
+ headers: {
248
+ Authorization: `Bearer ${existingToken}`
249
+ }
250
+ });
251
+ const refreshedToken = extractTokenFromResponse(response.data);
252
+ if (refreshedToken) {
253
+ setToken(refreshedToken);
254
+ return refreshedToken;
255
+ }
256
+ }
257
+ catch {
258
+ // Try the next known refresh endpoint.
259
+ }
260
+ }
261
+ const latestPersistedToken = readPersistedToken();
262
+ if (latestPersistedToken && latestPersistedToken !== existingToken) {
263
+ inMemoryToken = latestPersistedToken;
264
+ return latestPersistedToken;
265
+ }
266
+ return null;
267
+ }
268
+ async function tryRefreshToken() {
269
+ if (refreshPromise) {
270
+ return refreshPromise;
271
+ }
272
+ refreshPromise = requestTokenRefresh();
273
+ try {
274
+ return await refreshPromise;
275
+ }
276
+ finally {
277
+ refreshPromise = null;
278
+ }
279
+ }
280
+ function wasTokenRotatedSince(requestAuthHeaderOrHeaders) {
281
+ const requestAuthHeader = extractAuthorizationHeaderValue(requestAuthHeaderOrHeaders);
282
+ if (requestAuthHeader === null || !requestAuthHeader.startsWith('Bearer ')) {
283
+ return false;
284
+ }
285
+ const requestToken = requestAuthHeader.slice(7);
286
+ const currentToken = getToken();
287
+ return requestToken.length > 0 && currentToken !== null && currentToken !== requestToken;
288
+ }
289
+ return {
290
+ getToken,
291
+ setToken,
292
+ removeToken,
293
+ hasToken,
294
+ shouldSkipAuth,
295
+ isRefreshTokenEndpoint,
296
+ tryRefreshToken,
297
+ wasTokenRotatedSince
298
+ };
299
+ }
300
+ //# sourceMappingURL=tokenStorage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenStorage.js","sourceRoot":"","sources":["../../src/utils/tokenStorage.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@codingfactory/socialkit-vue",
3
+ "version": "0.1.0",
4
+ "description": "Shared Vue 3 utilities for SocialKit-powered frontends",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "src"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsc",
21
+ "dev": "tsc --watch",
22
+ "typecheck": "tsc --noEmit",
23
+ "prepublishOnly": "npm run build"
24
+ },
25
+ "peerDependencies": {
26
+ "axios": "^1.6.0",
27
+ "pinia": "^3.0.0",
28
+ "vue": "^3.4.0",
29
+ "vue-router": "^4.3.0"
30
+ },
31
+ "devDependencies": {
32
+ "axios": "^1.7.0",
33
+ "pinia": "^3.0.0",
34
+ "typescript": "~5.7.0",
35
+ "vue": "^3.5.0",
36
+ "vue-router": "^4.5.0"
37
+ },
38
+ "license": "UNLICENSED",
39
+ "private": false
40
+ }
@@ -0,0 +1,164 @@
1
+ /**
2
+ * Composable for common auth operations.
3
+ *
4
+ * This is a thin convenience wrapper that adds local loading/error state
5
+ * on top of an auth service instance.
6
+ */
7
+
8
+ import { ref, computed, type Ref, type ComputedRef } from 'vue'
9
+ import type { AuthServiceInstance, RegisterData, ResetPasswordData } from '../services/auth.js'
10
+ import type { User } from '../types/user.js'
11
+
12
+ function isAxiosError(error: unknown): error is {
13
+ response?: {
14
+ status?: number
15
+ data?: {
16
+ message?: string
17
+ errors?: Record<string, string[]>
18
+ }
19
+ }
20
+ } {
21
+ return error !== null && typeof error === 'object' && 'response' in error
22
+ }
23
+
24
+ function extractForgotPasswordValidationMessage(error: unknown): string | null {
25
+ if (!isAxiosError(error) || error.response?.status !== 422) {
26
+ return null
27
+ }
28
+
29
+ const emailErrors = error.response.data?.errors?.email
30
+ const usernameErrors = error.response.data?.errors?.username
31
+ const identifierErrors = error.response.data?.errors?.identifier
32
+
33
+ return emailErrors?.[0] ?? usernameErrors?.[0] ?? identifierErrors?.[0] ?? null
34
+ }
35
+
36
+ export interface UseAuthReturn {
37
+ user: ComputedRef<User | null>
38
+ loading: Ref<boolean>
39
+ error: Ref<string | null>
40
+ login(credential: string, password: string): Promise<unknown>
41
+ register(data: RegisterData): Promise<unknown>
42
+ logout(): Promise<void>
43
+ forgotPassword(email: string): Promise<unknown>
44
+ resetPassword(data: ResetPasswordData): Promise<unknown>
45
+ }
46
+
47
+ /**
48
+ * Create the useAuth composable bound to a specific auth service and user ref.
49
+ *
50
+ * Call `makeUseAuth()` once during app bootstrap, then use the returned
51
+ * composable in your components.
52
+ */
53
+ export function makeUseAuth(
54
+ authService: AuthServiceInstance,
55
+ currentUser: Ref<User | null>
56
+ ): () => UseAuthReturn {
57
+ return function useAuth(): UseAuthReturn {
58
+ const loading = ref(false)
59
+ const error = ref<string | null>(null)
60
+
61
+ const user = computed(() => currentUser.value)
62
+
63
+ const login = async (credential: string, password: string): Promise<unknown> => {
64
+ loading.value = true
65
+ error.value = null
66
+
67
+ try {
68
+ const response = await authService.login(credential, password)
69
+ return response
70
+ } catch (err) {
71
+ if (isAxiosError(err)) {
72
+ error.value = err.response?.data?.message ?? 'Login failed'
73
+ } else {
74
+ error.value = 'Login failed'
75
+ }
76
+ throw err
77
+ } finally {
78
+ loading.value = false
79
+ }
80
+ }
81
+
82
+ const register = async (data: RegisterData): Promise<unknown> => {
83
+ loading.value = true
84
+ error.value = null
85
+
86
+ try {
87
+ const response = await authService.register(data)
88
+ return response
89
+ } catch (err) {
90
+ if (isAxiosError(err)) {
91
+ error.value = err.response?.data?.message ?? 'Registration failed'
92
+ } else {
93
+ error.value = 'Registration failed'
94
+ }
95
+ throw err
96
+ } finally {
97
+ loading.value = false
98
+ }
99
+ }
100
+
101
+ const logout = async (): Promise<void> => {
102
+ loading.value = true
103
+
104
+ try {
105
+ await authService.logout()
106
+ } finally {
107
+ loading.value = false
108
+ }
109
+ }
110
+
111
+ const forgotPassword = async (email: string): Promise<unknown> => {
112
+ loading.value = true
113
+ error.value = null
114
+
115
+ try {
116
+ const response = await authService.forgotPassword(email)
117
+ error.value = null
118
+ return response
119
+ } catch (err) {
120
+ const validationMessage = extractForgotPasswordValidationMessage(err)
121
+ if (validationMessage !== null) {
122
+ error.value = validationMessage
123
+ } else if (isAxiosError(err)) {
124
+ error.value = err.response?.data?.message ?? 'Failed to send reset link'
125
+ } else {
126
+ error.value = 'Failed to send reset link'
127
+ }
128
+ throw err
129
+ } finally {
130
+ loading.value = false
131
+ }
132
+ }
133
+
134
+ const resetPassword = async (data: ResetPasswordData): Promise<unknown> => {
135
+ loading.value = true
136
+ error.value = null
137
+
138
+ try {
139
+ const response = await authService.resetPassword(data)
140
+ return response
141
+ } catch (err) {
142
+ if (isAxiosError(err)) {
143
+ error.value = err.response?.data?.message ?? 'Password reset failed'
144
+ } else {
145
+ error.value = 'Password reset failed'
146
+ }
147
+ throw err
148
+ } finally {
149
+ loading.value = false
150
+ }
151
+ }
152
+
153
+ return {
154
+ user,
155
+ loading,
156
+ error,
157
+ login,
158
+ register,
159
+ logout,
160
+ forgotPassword,
161
+ resetPassword
162
+ }
163
+ }
164
+ }
package/src/index.ts ADDED
@@ -0,0 +1,118 @@
1
+ /**
2
+ * @socialkit/vue — Shared Vue 3 utilities for SocialKit-powered frontends.
3
+ *
4
+ * This package provides configurable building blocks (token storage, API service,
5
+ * auth service, auth store, terminology plugin) that each site frontend
6
+ * instantiates with its own configuration.
7
+ */
8
+
9
+ // ── Types ────────────────────────────────────────────────────────────────────
10
+ export type {
11
+ ApiResponse,
12
+ PaginatedResponse,
13
+ ApiError,
14
+ UploadProgressEvent,
15
+ RequestConfig
16
+ } from './types/api.js'
17
+
18
+ export type {
19
+ User,
20
+ IdentityUser
21
+ } from './types/user.js'
22
+
23
+ export {
24
+ isUser,
25
+ isIdentityUser,
26
+ identityUserToUser
27
+ } from './types/user.js'
28
+
29
+ // ── Token Storage ────────────────────────────────────────────────────────────
30
+ export type {
31
+ TokenStorageConfig,
32
+ TokenStorage
33
+ } from './utils/tokenStorage.js'
34
+
35
+ export {
36
+ createTokenStorage,
37
+ extractTokenFromResponse
38
+ } from './utils/tokenStorage.js'
39
+
40
+ // ── API Service ──────────────────────────────────────────────────────────────
41
+ export type {
42
+ ApiServiceConfig,
43
+ ApiService
44
+ } from './services/api.js'
45
+
46
+ export {
47
+ createApiService
48
+ } from './services/api.js'
49
+
50
+ // ── Auth Service ─────────────────────────────────────────────────────────────
51
+ export type {
52
+ AuthServiceConfig,
53
+ AuthServiceInstance,
54
+ AuthenticatedLoginResponse,
55
+ AuthenticatedRegisterResponse,
56
+ AuthLoginResult,
57
+ ConfiguredTokenAuthClient,
58
+ ExtendedAuthServiceConfig,
59
+ ExtendedAuthServiceInstance,
60
+ RegisterData,
61
+ RegisterResponse,
62
+ ResetPasswordData,
63
+ LoginResponse,
64
+ TokenAuthClientConfig,
65
+ TwoFactorChallengeResponse,
66
+ VerificationRequiredRegisterResponse
67
+ } from './services/auth.js'
68
+
69
+ export {
70
+ configureTokenAuthClient,
71
+ createAuthService,
72
+ createExtendedAuthService
73
+ } from './services/auth.js'
74
+
75
+ // ── Auth Store ───────────────────────────────────────────────────────────────
76
+ export type {
77
+ AuthStoreConfig,
78
+ AuthStoreActions,
79
+ AuthStoreExtension,
80
+ AuthStoreExtensionContext,
81
+ AuthStoreGetters,
82
+ AuthStoreStateRefs,
83
+ AuthStoreReturn
84
+ } from './stores/auth.js'
85
+
86
+ export {
87
+ createAuthStoreDefinition
88
+ } from './stores/auth.js'
89
+
90
+ // ── Auth Composable ──────────────────────────────────────────────────────────
91
+ export type {
92
+ UseAuthReturn
93
+ } from './composables/useAuth.js'
94
+
95
+ export {
96
+ makeUseAuth
97
+ } from './composables/useAuth.js'
98
+
99
+ // ── Terminology Plugin ───────────────────────────────────────────────────────
100
+ export type {
101
+ TermForms,
102
+ TermsBundle,
103
+ TerminologyOptions
104
+ } from './plugins/terminology/types.js'
105
+
106
+ export type {
107
+ TermOptions
108
+ } from './plugins/terminology/terms.js'
109
+
110
+ export {
111
+ makeTermHelpers
112
+ } from './plugins/terminology/terms.js'
113
+
114
+ export {
115
+ TerminologyPlugin,
116
+ useTerms,
117
+ getTermHelpers
118
+ } from './plugins/terminology/index.js'