@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,114 @@
1
+ import type { App, Plugin } from 'vue'
2
+ import type { TerminologyOptions, TermsBundle } from './types.js'
3
+ import { makeTermHelpers } from './terms.js'
4
+ import { inject, ref } from 'vue'
5
+
6
+ const termsBundle: TermsBundle = {}
7
+ let termHelpers: ReturnType<typeof makeTermHelpers> | null = null
8
+ const termsVersion = ref(0)
9
+
10
+ function ensureTermHelpers(): ReturnType<typeof makeTermHelpers> {
11
+ if (termHelpers !== null) {
12
+ return termHelpers
13
+ }
14
+
15
+ termHelpers = makeTermHelpers(termsBundle)
16
+ return termHelpers
17
+ }
18
+
19
+ function applyTermsBundle(bundle: TermsBundle): void {
20
+ const existingKeys = Object.keys(termsBundle)
21
+ for (const key of existingKeys) {
22
+ delete termsBundle[key]
23
+ }
24
+
25
+ Object.assign(termsBundle, bundle)
26
+ termHelpers = makeTermHelpers(termsBundle)
27
+ termsVersion.value += 1
28
+ }
29
+
30
+ function touchTermsVersion(): void {
31
+ void termsVersion.value
32
+ }
33
+
34
+ function installTerminologyProviders(app: App): void {
35
+ const termProxy: ReturnType<typeof makeTermHelpers>['term'] = (key, opts) => {
36
+ touchTermsVersion()
37
+ return ensureTermHelpers().term(key, opts)
38
+ }
39
+
40
+ const segmentProxy: ReturnType<typeof makeTermHelpers>['segment'] = (key) => {
41
+ touchTermsVersion()
42
+ return ensureTermHelpers().segment(key)
43
+ }
44
+
45
+ app.config.globalProperties.$term = termProxy
46
+ app.config.globalProperties.$segment = segmentProxy
47
+ app.provide('terms:term', termProxy)
48
+ app.provide('terms:segment', segmentProxy)
49
+ app.provide('terms:bundle', termsBundle)
50
+ }
51
+
52
+ export const TerminologyPlugin: Plugin = {
53
+ async install(app: App, opts?: Partial<TerminologyOptions>) {
54
+ const brand = opts?.brand ?? 'default'
55
+ const locale = opts?.locale ?? 'en'
56
+ let url = opts?.bundleUrl ?? `/brands/${brand}.${locale}.json`
57
+ installTerminologyProviders(app)
58
+
59
+ const runtimeOrigin = typeof window !== 'undefined' ? window.location.origin : ''
60
+ const apiBase = (opts?.apiBaseUrl ?? runtimeOrigin).replace(/\/$/, '')
61
+ const canUseApiFallback = apiBase.length > 0 && url.startsWith('/')
62
+
63
+ try {
64
+ let response = await fetch(url, { cache: 'no-cache' })
65
+
66
+ if (canUseApiFallback && (!response.ok || response.headers.get('content-type')?.includes('text/html'))) {
67
+ // Fall back to the backend origin when the frontend dev server does not serve the brand bundle.
68
+ url = `${apiBase}${url}`
69
+ response = await fetch(url, {
70
+ credentials: 'include',
71
+ headers: { Accept: 'application/json' }
72
+ })
73
+ }
74
+
75
+ if (!response.ok) {
76
+ throw new Error(`HTTP ${response.status}: Failed to load terminology bundle from ${url}`)
77
+ }
78
+
79
+ const contentType = response.headers.get('content-type')
80
+ if (!contentType?.includes('application/json')) {
81
+ throw new Error(`Invalid content-type: ${contentType ?? 'unknown'}. Expected JSON from ${url}`)
82
+ }
83
+
84
+ const data = await response.json()
85
+ applyTermsBundle(data.terms ?? data)
86
+ } catch {
87
+ applyTermsBundle({})
88
+ }
89
+ }
90
+ }
91
+
92
+ /** Composition API helper to access terminology in setup(). */
93
+ export function useTerms(): {
94
+ term: ReturnType<typeof makeTermHelpers>['term']
95
+ segment: ReturnType<typeof makeTermHelpers>['segment']
96
+ } {
97
+ const term = inject<ReturnType<typeof makeTermHelpers>['term']>('terms:term')
98
+ const segment = inject<ReturnType<typeof makeTermHelpers>['segment']>('terms:segment')
99
+
100
+ if (!term || !segment) {
101
+ const fallback = makeTermHelpers({})
102
+ return { term: fallback.term, segment: fallback.segment }
103
+ }
104
+
105
+ return { term, segment }
106
+ }
107
+
108
+ /** Get term helpers outside of a Vue component context (e.g. router). */
109
+ export function getTermHelpers(): ReturnType<typeof makeTermHelpers> {
110
+ if (!termHelpers) {
111
+ return makeTermHelpers({})
112
+ }
113
+ return termHelpers
114
+ }
@@ -0,0 +1,104 @@
1
+ import type { TermForms, TermsBundle } from './types.js'
2
+
3
+ type TermCase = 'title' | 'upper' | 'lower'
4
+ type TermForm = 'noun' | 'relation_noun' | 'verb' | 'verb_past' | 'verb_ing'
5
+ type NonNounTermForm = Exclude<TermForm, 'noun' | 'relation_noun'>
6
+
7
+ export interface TermOptions {
8
+ form?: TermForm
9
+ count?: number
10
+ ui?: string
11
+ case?: TermCase
12
+ }
13
+
14
+ export function makeTermHelpers(bundle: TermsBundle): {
15
+ term: (key: string, opts?: TermOptions) => string
16
+ segment: (key: string) => string
17
+ } {
18
+ const emptyNode: TermForms = {}
19
+
20
+ const fallbackLabel = (key: string): string => {
21
+ const lastSegment = key.split('.').pop()
22
+ return (lastSegment ?? key).replace(/[_-]/g, ' ')
23
+ }
24
+
25
+ const getNode = (key: string): TermForms => bundle[key] ?? emptyNode
26
+
27
+ const plural = (one?: string, other?: string, count?: number): string | undefined => {
28
+ const fallback = one ?? other
29
+ if (fallback === undefined) {
30
+ return undefined
31
+ }
32
+
33
+ if (count == null) {
34
+ return fallback
35
+ }
36
+
37
+ return count === 1 ? (one ?? fallback) : (other ?? fallback)
38
+ }
39
+
40
+ const applyCase = (value: string, casing?: TermCase): string => {
41
+ if (!value) {
42
+ return value
43
+ }
44
+
45
+ switch (casing) {
46
+ case 'upper':
47
+ return value.toUpperCase()
48
+ case 'lower':
49
+ return value.toLowerCase()
50
+ case 'title':
51
+ return value.replace(/\b\w/g, (match) => match.toUpperCase())
52
+ default:
53
+ return value
54
+ }
55
+ }
56
+
57
+ const getFormValue = (node: TermForms, form: NonNounTermForm): string | undefined => {
58
+ switch (form) {
59
+ case 'verb':
60
+ return node.verb
61
+ case 'verb_past':
62
+ return node.verb_past
63
+ case 'verb_ing':
64
+ return node.verb_ing
65
+ default:
66
+ return undefined
67
+ }
68
+ }
69
+
70
+ const term = (key: string, opts: TermOptions = {}): string => {
71
+ const node = getNode(key)
72
+
73
+ if (opts.ui) {
74
+ return applyCase(node.ui?.[opts.ui] ?? fallbackLabel(key), opts.case)
75
+ }
76
+
77
+ const form: TermForm = opts.form ?? 'noun'
78
+ if (form === 'noun') {
79
+ const out = plural(node.noun?.one, node.noun?.other, opts.count) ?? fallbackLabel(key)
80
+ return applyCase(out, opts.case)
81
+ }
82
+
83
+ if (form === 'relation_noun') {
84
+ const out = plural(node.relation_noun?.one, node.relation_noun?.other, opts.count) ?? fallbackLabel(key)
85
+ return applyCase(out, opts.case)
86
+ }
87
+
88
+ const raw = getFormValue(node, form) ?? fallbackLabel(key)
89
+ return applyCase(raw, opts.case)
90
+ }
91
+
92
+ const segment = (key: string): string => {
93
+ const node = getNode(key)
94
+
95
+ if (node.url_segment) {
96
+ return node.url_segment
97
+ }
98
+
99
+ const base = node.noun?.other ?? node.noun?.one ?? fallbackLabel(key)
100
+ return base.toLowerCase().replace(/\s+/g, '-')
101
+ }
102
+
103
+ return { term, segment }
104
+ }
@@ -0,0 +1,28 @@
1
+ export interface TermForms {
2
+ noun?: { one?: string; other?: string }
3
+ relation_noun?: { one?: string; other?: string }
4
+ verb?: string
5
+ verb_past?: string
6
+ verb_ing?: string
7
+ url_segment?: string
8
+ ui?: Record<string, string>
9
+ }
10
+
11
+ export type TermsBundle = Record<string, TermForms>
12
+
13
+ export interface TerminologyOptions {
14
+ brand: string
15
+ locale: string
16
+ /** Override the bundle URL (default: `/brands/${brand}.${locale}.json`). */
17
+ bundleUrl?: string
18
+ /** API base URL for fallback fetching in development. */
19
+ apiBaseUrl?: string
20
+ onVersionMismatch?: (serverVersion: string) => void
21
+ }
22
+
23
+ declare module 'vue' {
24
+ interface ComponentCustomProperties {
25
+ $term: (key: string, opts?: Record<string, unknown>) => string
26
+ $segment: (key: string) => string
27
+ }
28
+ }