@yca-software/yca-react-core 0.0.1

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 (87) hide show
  1. package/README.md +129 -0
  2. package/dist/admin/index.d.ts +10 -0
  3. package/dist/admin/index.js +3 -0
  4. package/dist/admin/index.js.map +1 -0
  5. package/dist/admin-BVYdWtEy.d.ts +3 -0
  6. package/dist/api/index.d.ts +68 -0
  7. package/dist/api/index.js +3 -0
  8. package/dist/api/index.js.map +1 -0
  9. package/dist/auth/index.d.ts +49 -0
  10. package/dist/auth/index.js +3 -0
  11. package/dist/auth/index.js.map +1 -0
  12. package/dist/chunk-2HJO2ICF.js +339 -0
  13. package/dist/chunk-2HJO2ICF.js.map +1 -0
  14. package/dist/chunk-3AYG73DK.js +174 -0
  15. package/dist/chunk-3AYG73DK.js.map +1 -0
  16. package/dist/chunk-3SCZ4Z6P.js +26 -0
  17. package/dist/chunk-3SCZ4Z6P.js.map +1 -0
  18. package/dist/chunk-3ZLODBRJ.js +21 -0
  19. package/dist/chunk-3ZLODBRJ.js.map +1 -0
  20. package/dist/chunk-6LO5O4G6.js +224 -0
  21. package/dist/chunk-6LO5O4G6.js.map +1 -0
  22. package/dist/chunk-APZVW5SW.js +75 -0
  23. package/dist/chunk-APZVW5SW.js.map +1 -0
  24. package/dist/chunk-EVZBADFR.js +583 -0
  25. package/dist/chunk-EVZBADFR.js.map +1 -0
  26. package/dist/chunk-GXWVFQCK.js +52 -0
  27. package/dist/chunk-GXWVFQCK.js.map +1 -0
  28. package/dist/chunk-KG4JVAKS.js +13 -0
  29. package/dist/chunk-KG4JVAKS.js.map +1 -0
  30. package/dist/chunk-KZH56VPP.js +183 -0
  31. package/dist/chunk-KZH56VPP.js.map +1 -0
  32. package/dist/chunk-LP7Q75C6.js +96 -0
  33. package/dist/chunk-LP7Q75C6.js.map +1 -0
  34. package/dist/chunk-NL4NAHXG.js +3 -0
  35. package/dist/chunk-NL4NAHXG.js.map +1 -0
  36. package/dist/chunk-PLSNCPEC.js +2507 -0
  37. package/dist/chunk-PLSNCPEC.js.map +1 -0
  38. package/dist/chunk-QFKVPVFC.js +1391 -0
  39. package/dist/chunk-QFKVPVFC.js.map +1 -0
  40. package/dist/chunk-TSXUUD64.js +64 -0
  41. package/dist/chunk-TSXUUD64.js.map +1 -0
  42. package/dist/chunk-UCJ76BEC.js +32 -0
  43. package/dist/chunk-UCJ76BEC.js.map +1 -0
  44. package/dist/chunk-WFTIYYII.js +3 -0
  45. package/dist/chunk-WFTIYYII.js.map +1 -0
  46. package/dist/components/forms/index.d.ts +101 -0
  47. package/dist/components/forms/index.js +7 -0
  48. package/dist/components/forms/index.js.map +1 -0
  49. package/dist/components/marketing/index.d.ts +473 -0
  50. package/dist/components/marketing/index.js +5 -0
  51. package/dist/components/marketing/index.js.map +1 -0
  52. package/dist/components/spa/index.d.ts +275 -0
  53. package/dist/components/spa/index.js +8 -0
  54. package/dist/components/spa/index.js.map +1 -0
  55. package/dist/components/ui/index.d.ts +420 -0
  56. package/dist/components/ui/index.js +6 -0
  57. package/dist/components/ui/index.js.map +1 -0
  58. package/dist/constants/index.d.ts +2 -0
  59. package/dist/constants/index.js +4 -0
  60. package/dist/constants/index.js.map +1 -0
  61. package/dist/cookies-ZS_QYOR7.d.ts +8 -0
  62. package/dist/dateRangePickerTranslations-B99F2WQA.d.ts +9 -0
  63. package/dist/errors/index.d.ts +48 -0
  64. package/dist/errors/index.js +3 -0
  65. package/dist/errors/index.js.map +1 -0
  66. package/dist/forms-VpLvEFob.d.ts +18 -0
  67. package/dist/hooks/index.d.ts +18 -0
  68. package/dist/hooks/index.js +4 -0
  69. package/dist/hooks/index.js.map +1 -0
  70. package/dist/index.d.ts +42 -0
  71. package/dist/index.js +19 -0
  72. package/dist/index.js.map +1 -0
  73. package/dist/lib/index.d.ts +49 -0
  74. package/dist/lib/index.js +7 -0
  75. package/dist/lib/index.js.map +1 -0
  76. package/dist/pagination-CFqoqiAG.d.ts +10 -0
  77. package/dist/radix-overlays-BlCr-uem.d.ts +10 -0
  78. package/dist/styles.css +9 -0
  79. package/dist/theme/marketing.css +750 -0
  80. package/dist/theme/tokens.css +115 -0
  81. package/dist/types/index.d.ts +2 -0
  82. package/dist/types/index.js +3 -0
  83. package/dist/types/index.js.map +1 -0
  84. package/dist/types-BuNHOJ1h.d.ts +58 -0
  85. package/dist/types-CN73TWSY.d.ts +51 -0
  86. package/dist/useAdminListPage-C4ZTTllP.d.ts +26 -0
  87. package/package.json +152 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/forms/description-field/index.tsx","../src/components/forms/email-field/index.tsx","../src/components/forms/expires-at-field/index.tsx","../src/components/forms/first-name-field/index.tsx","../src/components/forms/last-name-field/index.tsx","../src/components/forms/name-field/index.tsx","../src/components/forms/password-field/index.tsx","../src/components/forms/permissions-field/index.tsx","../src/components/forms/role-select-field/index.tsx"],"names":["jsx","jsxs"],"mappings":"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","file":"chunk-2HJO2ICF.js","sourcesContent":["import type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport { FormControl, FormField, FormItem, FormLabel, FormMessage, Textarea } from '../../ui';\n\ntype DescriptionFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n placeholder?: string;\n className?: string;\n disabled?: boolean;\n};\n\nexport function DescriptionField<T extends FieldValues>({\n control,\n name,\n label,\n placeholder,\n className,\n disabled,\n}: DescriptionFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => (\n <FormItem className={className}>\n <FormLabel>{label}</FormLabel>\n <FormControl>\n <Textarea placeholder={placeholder} disabled={disabled} {...field} />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n );\n}\n","import type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport { FormControl, FormField, FormItem, FormLabel, FormMessage, Input } from '../../ui';\n\ntype EmailFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n placeholder?: string;\n description?: string;\n autoComplete?: 'email' | 'username';\n className?: string;\n};\n\nexport function EmailField<T extends FieldValues>({\n control,\n name,\n label,\n placeholder,\n description,\n autoComplete = 'email',\n className,\n}: EmailFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => (\n <FormItem className={className}>\n <FormLabel>{label}</FormLabel>\n {description && <p className=\"text-sm text-muted-foreground mt-0.5\">{description}</p>}\n <FormControl>\n <Input type=\"email\" placeholder={placeholder} autoComplete={autoComplete} {...field} />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n );\n}\n","import type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport { FormField, FormItem, FormLabel, FormMessage, Select } from '../../ui';\n\ntype ExpiresAtOption = {\n value: string;\n label: string;\n};\n\ntype ExpiresAtFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n placeholder?: string;\n ariaLabel?: string;\n options: ExpiresAtOption[];\n};\n\nexport function ExpiresAtField<T extends FieldValues>({\n control,\n name,\n label,\n placeholder,\n ariaLabel,\n options,\n}: ExpiresAtFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => (\n <FormItem>\n <FormLabel>{label}</FormLabel>\n <Select\n value={(field.value as string) ?? ''}\n onValueChange={(next) => {\n field.onChange(next);\n }}\n options={options}\n placeholder={placeholder}\n aria-label={ariaLabel ?? label}\n />\n <FormMessage />\n </FormItem>\n )}\n />\n );\n}\n","import type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport { FormControl, FormField, FormItem, FormLabel, FormMessage, Input } from '../../ui';\n\ntype FirstNameFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n placeholder?: string;\n className?: string;\n};\n\nexport function FirstNameField<T extends FieldValues>({\n control,\n name,\n label,\n placeholder,\n className,\n}: FirstNameFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => (\n <FormItem className={className}>\n <FormLabel>{label}</FormLabel>\n <FormControl>\n <Input placeholder={placeholder} autoComplete=\"given-name\" {...field} />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n );\n}\n","import type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport { FormControl, FormField, FormItem, FormLabel, FormMessage, Input } from '../../ui';\n\ntype LastNameFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n placeholder?: string;\n className?: string;\n};\n\nexport function LastNameField<T extends FieldValues>({\n control,\n name,\n label,\n placeholder,\n className,\n}: LastNameFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => (\n <FormItem className={className}>\n <FormLabel>{label}</FormLabel>\n <FormControl>\n <Input placeholder={placeholder} autoComplete=\"family-name\" {...field} />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n );\n}\n","import type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport { FormControl, FormField, FormItem, FormLabel, FormMessage, Input } from '../../ui';\n\ntype NameFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n placeholder?: string;\n className?: string;\n disabled?: boolean;\n};\n\nexport function NameField<T extends FieldValues>({\n control,\n name,\n label,\n placeholder,\n className,\n disabled,\n}: NameFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => (\n <FormItem className={className}>\n <FormLabel>{label}</FormLabel>\n <FormControl>\n <Input placeholder={placeholder} disabled={disabled} autoComplete=\"off\" {...field} />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n );\n}\n","import type { ReactNode } from 'react';\nimport type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport { FormControl, FormField, FormItem, FormLabel, FormMessage, Input } from '../../ui';\n\ntype PasswordFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n placeholder?: string;\n autoComplete?: 'current-password' | 'new-password';\n /** Optional node to show on the right of the label (e.g. \"Forgot password?\" link) */\n rightLabel?: ReactNode;\n className?: string;\n};\n\nexport function PasswordField<T extends FieldValues>({\n control,\n name,\n label,\n placeholder,\n autoComplete = 'current-password',\n rightLabel,\n className,\n}: PasswordFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => (\n <FormItem className={className}>\n <div className=\"flex items-center justify-between\">\n <FormLabel>{label}</FormLabel>\n {rightLabel}\n </div>\n <FormControl>\n <Input\n type=\"password\"\n placeholder={placeholder}\n autoComplete={autoComplete}\n {...field}\n />\n </FormControl>\n <FormMessage />\n </FormItem>\n )}\n />\n );\n}\n","import { Info } from 'lucide-react';\nimport type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport type { PermissionGroup, PermissionOption } from '../../../types';\nimport { Checkbox, FormField, FormItem, FormLabel, FormMessage, Tooltip } from '../../ui';\n\nexport type {\n PermissionAction,\n PermissionGroup,\n PermissionOption,\n} from '../../../types';\n\ntype PermissionsFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n groups: PermissionGroup[];\n t: (key: string) => string;\n disabled?: boolean;\n};\n\nexport function PermissionsField<T extends FieldValues>({\n control,\n name,\n label,\n groups,\n t,\n disabled = false,\n}: PermissionsFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => {\n const selected = (field.value as string[]) ?? [];\n\n const togglePermission = (key: string, group: PermissionOption[]) => {\n const readKey = getReadKeyForGroup(group);\n const opt = group.find((p) => p.key === key);\n if (!opt) return;\n\n const next = selected.includes(key)\n ? selected.filter((k) => k !== key)\n : [...selected, key];\n\n if (opt.action === 'write' || opt.action === 'delete') {\n if (next.includes(key) && readKey && !next.includes(readKey)) {\n next.push(readKey);\n }\n }\n if (opt.action === 'delete') {\n const writeKey = getWriteKeyForGroup(group);\n if (next.includes(key) && writeKey && !next.includes(writeKey)) {\n next.push(writeKey);\n }\n }\n\n field.onChange(next);\n };\n\n return (\n <FormItem>\n <FormLabel>{label}</FormLabel>\n <div className=\"space-y-4\">\n {groups.map((group) => {\n const readKey = getReadKeyForGroup(group.permissions);\n const writeKey = getWriteKeyForGroup(group.permissions);\n const readDisabled = readKey\n ? hasWriteOrDelete(group.permissions, selected)\n : false;\n const writeDisabled = writeKey ? hasDelete(group.permissions, selected) : false;\n const readChecked =\n readKey !== null && (selected.includes(readKey) || readDisabled);\n const writeChecked =\n writeKey !== null && (selected.includes(writeKey) || writeDisabled);\n\n return (\n <div key={group.contextKey} className=\"space-y-2\">\n <div className=\"flex items-center gap-1.5\">\n <p className=\"text-sm font-medium\">{t(group.labelKey)}</p>\n <Tooltip content={t(group.descriptionKey)} side=\"top\" align=\"start\">\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:text-foreground cursor-help inline-flex rounded p-0.5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n aria-label={t(group.descriptionKey)}\n >\n <Info className=\"size-3.5\" aria-hidden />\n </button>\n </Tooltip>\n </div>\n <div className=\"flex flex-wrap gap-4 pl-2\">\n {group.permissions.map((perm) => {\n const isRead = perm.action === 'read';\n const isWrite = perm.action === 'write';\n const checked = isRead\n ? readChecked\n : isWrite\n ? writeChecked\n : selected.includes(perm.key);\n const permissionDisabled =\n (isRead && readDisabled) || (isWrite && writeDisabled);\n const globallyDisabled = disabled || permissionDisabled;\n\n return (\n <div key={perm.key} className=\"flex items-center space-x-2\">\n <Checkbox\n id={perm.key}\n checked={isRead ? readChecked : checked}\n disabled={globallyDisabled}\n onCheckedChange={() =>\n !globallyDisabled && togglePermission(perm.key, group.permissions)\n }\n />\n <label\n htmlFor={perm.key}\n className=\"text-sm font-normal leading-none cursor-pointer peer-disabled:opacity-70\"\n >\n {t(perm.labelKey)}\n </label>\n </div>\n );\n })}\n </div>\n </div>\n );\n })}\n </div>\n <FormMessage />\n </FormItem>\n );\n }}\n />\n );\n}\n\nfunction getReadKeyForGroup(permissions: PermissionOption[]): string | null {\n const readOpt = permissions.find((p) => p.action === 'read');\n return readOpt?.key ?? null;\n}\n\nfunction getWriteKeyForGroup(permissions: PermissionOption[]): string | null {\n const writeOpt = permissions.find((p) => p.action === 'write');\n return writeOpt?.key ?? null;\n}\n\nfunction hasWriteOrDelete(permissions: PermissionOption[], selected: string[]): boolean {\n return permissions.some(\n (p) => (p.action === 'write' || p.action === 'delete') && selected.includes(p.key),\n );\n}\n\nfunction hasDelete(permissions: PermissionOption[], selected: string[]): boolean {\n return permissions.some((p) => p.action === 'delete' && selected.includes(p.key));\n}\n","import { ChevronDown } from 'lucide-react';\nimport type { Control, FieldPath, FieldValues } from 'react-hook-form';\nimport { cn } from '../../../lib/utils';\nimport type { RoleOption } from '../../../types';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n FormControl,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '../../ui';\n\nexport type { RoleOption } from '../../../types';\n\ntype RoleSelectFieldProps<T extends FieldValues> = {\n control: Control<T>;\n name: FieldPath<T>;\n label: string;\n options: RoleOption[];\n className?: string;\n};\n\nexport function RoleSelectField<T extends FieldValues>({\n control,\n name,\n label,\n options,\n className,\n}: RoleSelectFieldProps<T>) {\n return (\n <FormField\n control={control}\n name={name}\n render={({ field }) => {\n const selectedOption = options.find((opt) => opt.value === field.value);\n const displayValue = selectedOption?.label ?? label;\n\n return (\n <FormItem className={className}>\n <FormLabel>{label}</FormLabel>\n <FormControl>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n role=\"combobox\"\n aria-label={label}\n onBlur={field.onBlur}\n className={cn(\n 'flex h-9 w-full cursor-pointer items-center justify-between rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-xs outline-none transition-colors',\n 'hover:bg-accent/50 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n 'disabled:pointer-events-none disabled:opacity-50',\n 'aria-invalid:ring-destructive/20 aria-invalid:border-destructive',\n !field.value && 'text-muted-foreground',\n )}\n >\n <span className=\"min-w-0 truncate text-left\">{displayValue}</span>\n <ChevronDown className=\"ml-2 h-4 w-4 shrink-0 text-muted-foreground\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n align=\"start\"\n sideOffset={0}\n className={cn('min-w-(--radix-dropdown-menu-trigger-width) z-101')}\n >\n {options.map((opt) => (\n <DropdownMenuItem key={opt.value} onClick={() => field.onChange(opt.value)}>\n {opt.label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n </FormControl>\n <FormMessage />\n </FormItem>\n );\n }}\n />\n );\n}\n"]}
@@ -0,0 +1,174 @@
1
+ import { controlFocus, controlInvalid, cn, surfaceCard, controlBase } from './chunk-GXWVFQCK.js';
2
+ import { jsx } from 'react/jsx-runtime';
3
+ import { Slot } from '@radix-ui/react-slot';
4
+ import { cva } from 'class-variance-authority';
5
+
6
+ function Card({ className, ...props }) {
7
+ return /* @__PURE__ */ jsx(
8
+ "div",
9
+ {
10
+ "data-slot": "card",
11
+ className: cn(surfaceCard, "flex flex-col gap-6 px-6 py-6", className),
12
+ ...props
13
+ }
14
+ );
15
+ }
16
+ function CardHeader({ className, ...props }) {
17
+ return /* @__PURE__ */ jsx(
18
+ "div",
19
+ {
20
+ "data-slot": "card-header",
21
+ className: cn(
22
+ "@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-0",
23
+ "has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:border-border/40 [.border-b]:pb-6",
24
+ className
25
+ ),
26
+ ...props
27
+ }
28
+ );
29
+ }
30
+ function CardTitle({ className, ...props }) {
31
+ return /* @__PURE__ */ jsx(
32
+ "div",
33
+ {
34
+ "data-slot": "card-title",
35
+ className: cn("font-semibold leading-none tracking-tight", className),
36
+ ...props
37
+ }
38
+ );
39
+ }
40
+ function CardDescription({ className, ...props }) {
41
+ return /* @__PURE__ */ jsx(
42
+ "div",
43
+ {
44
+ "data-slot": "card-description",
45
+ className: cn(
46
+ "text-muted-foreground text-sm overflow-hidden [display:-webkit-box] [-webkit-line-clamp:2] [-webkit-box-orient:vertical]",
47
+ className
48
+ ),
49
+ ...props
50
+ }
51
+ );
52
+ }
53
+ function CardAction({ className, ...props }) {
54
+ return /* @__PURE__ */ jsx(
55
+ "div",
56
+ {
57
+ "data-slot": "card-action",
58
+ className: cn("col-start-2 row-span-2 row-start-1 self-start justify-self-end", className),
59
+ ...props
60
+ }
61
+ );
62
+ }
63
+ function CardContent({ className, ...props }) {
64
+ return /* @__PURE__ */ jsx("div", { "data-slot": "card-content", className: cn("px-0", className), ...props });
65
+ }
66
+ function CardFooter({ className, ...props }) {
67
+ return /* @__PURE__ */ jsx(
68
+ "div",
69
+ {
70
+ "data-slot": "card-footer",
71
+ className: cn(
72
+ "flex items-center px-0 [.border-t]:border-border/40 [.border-t]:pt-6",
73
+ className
74
+ ),
75
+ ...props
76
+ }
77
+ );
78
+ }
79
+ var buttonVariants = cva(
80
+ [
81
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg text-sm font-medium",
82
+ "transition-all cursor-pointer shrink-0",
83
+ "disabled:pointer-events-none disabled:opacity-50",
84
+ "[&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0",
85
+ controlFocus,
86
+ controlInvalid
87
+ ],
88
+ {
89
+ variants: {
90
+ variant: {
91
+ default: "bg-primary text-primary-foreground shadow-[var(--shadow-surface)] hover:bg-primary/90",
92
+ destructive: "bg-destructive text-destructive-foreground shadow-[var(--shadow-surface)] hover:bg-destructive/90 focus-visible:ring-destructive/25 dark:bg-destructive/75",
93
+ outline: "border border-border/50 bg-background shadow-[var(--shadow-surface)] hover:bg-accent hover:text-accent-foreground dark:bg-muted/20",
94
+ secondary: "bg-secondary text-secondary-foreground shadow-[var(--shadow-surface)] hover:bg-secondary/85",
95
+ ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
96
+ link: "text-primary underline-offset-4 hover:underline"
97
+ },
98
+ size: {
99
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
100
+ sm: "h-8 gap-1.5 px-3 has-[>svg]:px-2.5",
101
+ lg: "h-10 px-6 has-[>svg]:px-4",
102
+ icon: "size-9",
103
+ "icon-sm": "size-8",
104
+ "icon-lg": "size-10"
105
+ }
106
+ },
107
+ defaultVariants: {
108
+ variant: "default",
109
+ size: "default"
110
+ }
111
+ }
112
+ );
113
+ function Button({
114
+ className,
115
+ variant = "default",
116
+ size = "default",
117
+ asChild = false,
118
+ ...props
119
+ }) {
120
+ const Comp = asChild ? Slot : "button";
121
+ return /* @__PURE__ */ jsx(
122
+ Comp,
123
+ {
124
+ "data-slot": "button",
125
+ "data-variant": variant,
126
+ "data-size": size,
127
+ className: cn(buttonVariants({ variant, size, className })),
128
+ ...props
129
+ }
130
+ );
131
+ }
132
+ var numberInputClassName = "[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none";
133
+ function shouldSelectAllNumberInputOnFocus(value) {
134
+ const trimmed = value.trim();
135
+ if (trimmed === "" || trimmed === "-" || trimmed === ".") {
136
+ return true;
137
+ }
138
+ const parsed = Number(trimmed);
139
+ return !Number.isNaN(parsed) && parsed === 0;
140
+ }
141
+ function Input({ className, type, onFocus, ...props }) {
142
+ const handleFocus = (event) => {
143
+ if (type === "number" && shouldSelectAllNumberInputOnFocus(event.currentTarget.value)) {
144
+ event.currentTarget.select();
145
+ }
146
+ onFocus?.(event);
147
+ };
148
+ return /* @__PURE__ */ jsx(
149
+ "input",
150
+ {
151
+ type,
152
+ onFocus: handleFocus,
153
+ "data-slot": "input",
154
+ className: cn(
155
+ controlBase,
156
+ controlFocus,
157
+ controlInvalid,
158
+ "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground",
159
+ "h-9 w-full min-w-0 px-3 py-1 text-base md:text-sm",
160
+ "file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium",
161
+ "disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-100",
162
+ "disabled:bg-muted/50 disabled:text-muted-foreground disabled:border-border/40",
163
+ "dark:disabled:bg-muted/25",
164
+ type === "number" && numberInputClassName,
165
+ className
166
+ ),
167
+ ...props
168
+ }
169
+ );
170
+ }
171
+
172
+ export { Button, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Input, buttonVariants };
173
+ //# sourceMappingURL=chunk-3AYG73DK.js.map
174
+ //# sourceMappingURL=chunk-3AYG73DK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ui/card/index.tsx","../src/components/ui/button/index.tsx","../src/components/ui/input/index.tsx"],"names":["jsx"],"mappings":"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","file":"chunk-3AYG73DK.js","sourcesContent":["import type * as React from 'react';\n\nimport { surfaceCard } from '../../../lib/surfaces';\nimport { cn } from '../../../lib/utils';\n\n/** Elevated content container. Compose with CardHeader, CardContent, etc. */\nfunction Card({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card\"\n className={cn(surfaceCard, 'flex flex-col gap-6 px-6 py-6', className)}\n {...props}\n />\n );\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-header\"\n className={cn(\n '@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-0',\n 'has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:border-border/40 [.border-b]:pb-6',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-title\"\n className={cn('font-semibold leading-none tracking-tight', className)}\n {...props}\n />\n );\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-description\"\n className={cn(\n 'text-muted-foreground text-sm overflow-hidden [display:-webkit-box] [-webkit-line-clamp:2] [-webkit-box-orient:vertical]',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-action\"\n className={cn('col-start-2 row-span-2 row-start-1 self-start justify-self-end', className)}\n {...props}\n />\n );\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"card-content\" className={cn('px-0', className)} {...props} />;\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-footer\"\n className={cn(\n 'flex items-center px-0 [.border-t]:border-border/40 [.border-t]:pt-6',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle };\n","import { Slot } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type * as React from 'react';\n\nimport { controlFocus, controlInvalid } from '../../../lib/surfaces';\nimport { cn } from '../../../lib/utils';\n\nconst buttonVariants = cva(\n [\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg text-sm font-medium',\n 'transition-all cursor-pointer shrink-0',\n 'disabled:pointer-events-none disabled:opacity-50',\n \"[&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0\",\n controlFocus,\n controlInvalid,\n ],\n {\n variants: {\n variant: {\n default:\n 'bg-primary text-primary-foreground shadow-[var(--shadow-surface)] hover:bg-primary/90',\n destructive:\n 'bg-destructive text-destructive-foreground shadow-[var(--shadow-surface)] hover:bg-destructive/90 focus-visible:ring-destructive/25 dark:bg-destructive/75',\n outline:\n 'border border-border/50 bg-background shadow-[var(--shadow-surface)] hover:bg-accent hover:text-accent-foreground dark:bg-muted/20',\n secondary:\n 'bg-secondary text-secondary-foreground shadow-[var(--shadow-surface)] hover:bg-secondary/85',\n ghost: 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-9 px-4 py-2 has-[>svg]:px-3',\n sm: 'h-8 gap-1.5 px-3 has-[>svg]:px-2.5',\n lg: 'h-10 px-6 has-[>svg]:px-4',\n icon: 'size-9',\n 'icon-sm': 'size-8',\n 'icon-lg': 'size-10',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\ntype ButtonProps = React.ComponentProps<'button'> &\n VariantProps<typeof buttonVariants> & {\n /** Render as a child element (e.g. `<a>`) while keeping button styles. */\n asChild?: boolean;\n };\n\n/** Primary action control. See Storybook **UI/Button** for variants. */\nfunction Button({\n className,\n variant = 'default',\n size = 'default',\n asChild = false,\n ...props\n}: ButtonProps) {\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n data-slot=\"button\"\n data-variant={variant}\n data-size={size}\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n );\n}\n\nexport { Button, buttonVariants };\n","import type * as React from 'react';\n\nimport { controlBase, controlFocus, controlInvalid } from '../../../lib/surfaces';\nimport { cn } from '../../../lib/utils';\n\nconst numberInputClassName =\n '[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none';\n\nfunction shouldSelectAllNumberInputOnFocus(value: string): boolean {\n const trimmed = value.trim();\n if (trimmed === '' || trimmed === '-' || trimmed === '.') {\n return true;\n }\n const parsed = Number(trimmed);\n return !Number.isNaN(parsed) && parsed === 0;\n}\n\n/** Text field styled with theme tokens. See Storybook **UI/Input**. */\nfunction Input({ className, type, onFocus, ...props }: React.ComponentProps<'input'>) {\n const handleFocus = (event: React.FocusEvent<HTMLInputElement>) => {\n if (type === 'number' && shouldSelectAllNumberInputOnFocus(event.currentTarget.value)) {\n event.currentTarget.select();\n }\n onFocus?.(event);\n };\n\n return (\n <input\n type={type}\n onFocus={handleFocus}\n data-slot=\"input\"\n className={cn(\n controlBase,\n controlFocus,\n controlInvalid,\n 'file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground',\n 'h-9 w-full min-w-0 px-3 py-1 text-base md:text-sm',\n 'file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium',\n 'disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-100',\n 'disabled:bg-muted/50 disabled:text-muted-foreground disabled:border-border/40',\n 'dark:disabled:bg-muted/25',\n type === 'number' && numberInputClassName,\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Input };\n"]}
@@ -0,0 +1,26 @@
1
+ // src/lib/pagination.ts
2
+ function readItems(page) {
3
+ if (!page || typeof page !== "object") return [];
4
+ const record = page;
5
+ const raw = record.items ?? record.Items;
6
+ if (!Array.isArray(raw)) return [];
7
+ return raw.filter((item) => item != null);
8
+ }
9
+ function flattenPaginatedItems(pages) {
10
+ if (!pages?.length) return [];
11
+ return pages.flatMap((page) => readItems(page));
12
+ }
13
+ function normalizePaginatedList(raw) {
14
+ if (!raw || typeof raw !== "object") {
15
+ return { items: [], hasNext: false };
16
+ }
17
+ const record = raw;
18
+ return {
19
+ items: readItems(raw),
20
+ hasNext: Boolean(record.hasNext ?? record.HasNext)
21
+ };
22
+ }
23
+
24
+ export { flattenPaginatedItems, normalizePaginatedList };
25
+ //# sourceMappingURL=chunk-3SCZ4Z6P.js.map
26
+ //# sourceMappingURL=chunk-3SCZ4Z6P.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/pagination.ts"],"names":[],"mappings":";AAMA,SAAS,UAAa,IAAA,EAAoB;AACxC,EAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,SAAiB,EAAC;AAC/C,EAAA,MAAM,MAAA,GAAS,IAAA;AACf,EAAA,MAAM,GAAA,GAAM,MAAA,CAAO,KAAA,IAAS,MAAA,CAAO,KAAA;AACnC,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,SAAU,EAAC;AACjC,EAAA,OAAO,GAAA,CAAI,MAAA,CAAO,CAAC,IAAA,KAAoB,QAAQ,IAAI,CAAA;AACrD;AAGO,SAAS,sBAAyB,KAAA,EAA4C;AACnF,EAAA,IAAI,CAAC,KAAA,EAAO,MAAA,EAAQ,OAAO,EAAC;AAC5B,EAAA,OAAO,MAAM,OAAA,CAAQ,CAAC,IAAA,KAAS,SAAA,CAAa,IAAI,CAAC,CAAA;AACnD;AAEO,SAAS,uBAA0B,GAAA,EAAgC;AACxE,EAAA,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,QAAA,EAAU;AACnC,IAAA,OAAO,EAAE,KAAA,EAAO,EAAC,EAAG,SAAS,KAAA,EAAM;AAAA,EACrC;AACA,EAAA,MAAM,MAAA,GAAS,GAAA;AACf,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,UAAa,GAAG,CAAA;AAAA,IACvB,OAAA,EAAS,OAAA,CAAQ,MAAA,CAAO,OAAA,IAAW,OAAO,OAAO;AAAA,GACnD;AACF","file":"chunk-3SCZ4Z6P.js","sourcesContent":["/** Paginated list shape from go-api (`pagination.PaginatedListResponse`). */\nexport interface PaginatedList<T> {\n items: T[];\n hasNext: boolean;\n}\n\nfunction readItems<T>(page: unknown): T[] {\n if (!page || typeof page !== 'object') return [];\n const record = page as Record<string, unknown>;\n const raw = record.items ?? record.Items;\n if (!Array.isArray(raw)) return [];\n return raw.filter((item): item is T => item != null);\n}\n\n/** Flatten infinite-query pages and drop null/invalid entries. */\nexport function flattenPaginatedItems<T>(pages: PaginatedList<T>[] | undefined): T[] {\n if (!pages?.length) return [];\n return pages.flatMap((page) => readItems<T>(page));\n}\n\nexport function normalizePaginatedList<T>(raw: unknown): PaginatedList<T> {\n if (!raw || typeof raw !== 'object') {\n return { items: [], hasNext: false };\n }\n const record = raw as Record<string, unknown>;\n return {\n items: readItems<T>(raw),\n hasNext: Boolean(record.hasNext ?? record.HasNext),\n };\n}\n"]}
@@ -0,0 +1,21 @@
1
+ // src/admin/getAdminDetailErrorKind.ts
2
+ function getAdminDetailErrorKind(options) {
3
+ const { isLoading, isError, hasData, status } = options;
4
+ if (isLoading || hasData) {
5
+ return void 0;
6
+ }
7
+ if (status === 403) {
8
+ return "forbidden";
9
+ }
10
+ if (status === 404 || !isError && !hasData) {
11
+ return "notFound";
12
+ }
13
+ if (isError) {
14
+ return "load";
15
+ }
16
+ return "notFound";
17
+ }
18
+
19
+ export { getAdminDetailErrorKind };
20
+ //# sourceMappingURL=chunk-3ZLODBRJ.js.map
21
+ //# sourceMappingURL=chunk-3ZLODBRJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/admin/getAdminDetailErrorKind.ts"],"names":[],"mappings":";AAEO,SAAS,wBAAwB,OAAA,EAKH;AACnC,EAAA,MAAM,EAAE,SAAA,EAAW,OAAA,EAAS,OAAA,EAAS,QAAO,GAAI,OAAA;AAEhD,EAAA,IAAI,aAAa,OAAA,EAAS;AACxB,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,IAAI,WAAW,GAAA,EAAK;AAClB,IAAA,OAAO,WAAA;AAAA,EACT;AAEA,EAAA,IAAI,MAAA,KAAW,GAAA,IAAQ,CAAC,OAAA,IAAW,CAAC,OAAA,EAAU;AAC5C,IAAA,OAAO,UAAA;AAAA,EACT;AAEA,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,OAAO,UAAA;AACT","file":"chunk-3ZLODBRJ.js","sourcesContent":["import type { AdminDetailErrorKind } from '../types/admin';\n\nexport function getAdminDetailErrorKind(options: {\n isLoading: boolean;\n isError: boolean;\n hasData: boolean;\n status?: number;\n}): AdminDetailErrorKind | undefined {\n const { isLoading, isError, hasData, status } = options;\n\n if (isLoading || hasData) {\n return undefined;\n }\n\n if (status === 403) {\n return 'forbidden';\n }\n\n if (status === 404 || (!isError && !hasData)) {\n return 'notFound';\n }\n\n if (isError) {\n return 'load';\n }\n\n return 'notFound';\n}\n"]}
@@ -0,0 +1,224 @@
1
+ import { createContext, useMemo, useContext, useCallback } from 'react';
2
+ import { jsx } from 'react/jsx-runtime';
3
+
4
+ // src/api/ApiClientContext.tsx
5
+
6
+ // src/api/request.ts
7
+ var DEFAULT_REFRESH_ENDPOINT = "auth/refresh";
8
+ var DEFAULT_REFRESH_EXCLUDED_PREFIXES = ["auth/"];
9
+ function createDefaultRefreshRequest({
10
+ endpoint = DEFAULT_REFRESH_ENDPOINT,
11
+ excludedRetryPrefixes = DEFAULT_REFRESH_EXCLUDED_PREFIXES
12
+ } = {}) {
13
+ return {
14
+ endpoint,
15
+ method: "POST",
16
+ buildBody: ({ refreshToken }) => refreshToken ? { refreshToken } : {},
17
+ parseAccessToken: (data) => {
18
+ if (data && typeof data === "object" && "accessToken" in data) {
19
+ const token = data.accessToken;
20
+ return typeof token === "string" ? token : null;
21
+ }
22
+ return null;
23
+ },
24
+ excludedRetryPrefixes
25
+ };
26
+ }
27
+ function buildRequestUrl(baseURL, endpoint) {
28
+ const base = baseURL.replace(/\/$/, "");
29
+ const path = endpoint.replace(/^\//, "");
30
+ return `${base}/${path}`;
31
+ }
32
+ function getRequestHeaders(accessToken, options) {
33
+ const headers = {};
34
+ if (!options?.multipart) {
35
+ headers["Content-Type"] = "application/json";
36
+ }
37
+ if (accessToken) {
38
+ headers.Authorization = `Bearer ${accessToken}`;
39
+ }
40
+ if (options?.acceptLanguage) {
41
+ headers["Accept-Language"] = options.acceptLanguage;
42
+ }
43
+ return headers;
44
+ }
45
+ function getRequestOptions(config, token, acceptLanguage) {
46
+ const init = {
47
+ method: config.method,
48
+ headers: getRequestHeaders(token, {
49
+ multipart: config.multipart,
50
+ acceptLanguage
51
+ }),
52
+ body: config.multipart ? config.body : config.body != null ? JSON.stringify(config.body) : void 0
53
+ };
54
+ if (config.credentials) {
55
+ init.credentials = config.credentials;
56
+ }
57
+ return init;
58
+ }
59
+ async function performAccessTokenRefresh(params) {
60
+ const refreshToken = params.useCookieCredentials ? null : params.getRefreshToken();
61
+ if (!params.useCookieCredentials && !refreshToken) {
62
+ params.onFailure();
63
+ throw { error: new Error("missing refresh token"), status: 401 };
64
+ }
65
+ const bodyContext = {
66
+ refreshToken,
67
+ useCookieCredentials: params.useCookieCredentials
68
+ };
69
+ const requestConfig = {
70
+ endpoint: params.request.endpoint,
71
+ method: params.request.method,
72
+ body: params.request.buildBody(bodyContext),
73
+ credentials: params.useCookieCredentials ? "include" : params.request.credentials
74
+ };
75
+ const response = await fetch(
76
+ buildRequestUrl(params.baseURL, requestConfig.endpoint),
77
+ getRequestOptions(requestConfig, null, params.acceptLanguage)
78
+ );
79
+ const responseText = await response.text();
80
+ let data = null;
81
+ if (responseText) {
82
+ try {
83
+ data = JSON.parse(responseText);
84
+ } catch {
85
+ params.onFailure();
86
+ throw { error: new Error("invalid refresh response"), status: 401 };
87
+ }
88
+ }
89
+ const accessToken = params.request.parseAccessToken(data);
90
+ if (!response.ok || !accessToken) {
91
+ params.onFailure();
92
+ throw { error: new Error("failed to refresh access token"), status: 401 };
93
+ }
94
+ params.setAccessToken(accessToken);
95
+ return accessToken;
96
+ }
97
+ async function executeConfiguredRefresh(config) {
98
+ const refresh = config.refresh;
99
+ if (!refresh) {
100
+ throw new Error("refresh is not configured");
101
+ }
102
+ refresh.onStart?.();
103
+ try {
104
+ return await performAccessTokenRefresh({
105
+ baseURL: config.baseURL,
106
+ getRefreshToken: config.getRefreshToken,
107
+ request: refresh.request,
108
+ useCookieCredentials: refresh.cookieCredentialsEnabled(),
109
+ setAccessToken: refresh.setAccessToken,
110
+ onFailure: refresh.onFailure,
111
+ acceptLanguage: config.getAcceptLanguage?.()
112
+ });
113
+ } finally {
114
+ refresh.onEnd?.();
115
+ }
116
+ }
117
+
118
+ // src/api/responseHandler.ts
119
+ function shouldRetryWithRefresh(status, endpoint, isRetry, refreshToken, refresh) {
120
+ if (status !== 401 || !refreshToken || !refresh || !endpoint || isRetry) {
121
+ return false;
122
+ }
123
+ const normalized = endpoint.replace(/^\//, "");
124
+ return !refresh.request.excludedRetryPrefixes.some(
125
+ (prefix) => normalized.startsWith(prefix.replace(/^\//, ""))
126
+ );
127
+ }
128
+ function createResponseHandler(config) {
129
+ const { baseURL, getRefreshToken, refresh } = config;
130
+ async function handleResponse(response, options) {
131
+ const responseText = await response.text();
132
+ let data;
133
+ if (responseText) {
134
+ try {
135
+ data = JSON.parse(responseText);
136
+ } catch {
137
+ data = responseText;
138
+ }
139
+ }
140
+ if (!response.ok) {
141
+ const refreshToken = getRefreshToken();
142
+ if (shouldRetryWithRefresh(
143
+ response.status,
144
+ options?.config?.endpoint,
145
+ options?.isRetry,
146
+ refreshToken,
147
+ refresh
148
+ ) && options?.config) {
149
+ const newToken = await executeConfiguredRefresh(config);
150
+ const retryResponse = await fetch(
151
+ buildRequestUrl(baseURL, options.config.endpoint),
152
+ getRequestOptions(options.config, newToken, config.getAcceptLanguage?.())
153
+ );
154
+ return handleResponse(retryResponse, { ...options, isRetry: true });
155
+ }
156
+ throw {
157
+ error: data,
158
+ status: response.status,
159
+ retry: response.status >= 500
160
+ };
161
+ }
162
+ return data;
163
+ }
164
+ return handleResponse;
165
+ }
166
+ var ApiClientContext = createContext(null);
167
+ function ApiClientProvider({
168
+ baseURL,
169
+ config,
170
+ children
171
+ }) {
172
+ const value = useMemo(() => ({ ...config, baseURL }), [baseURL, config]);
173
+ return /* @__PURE__ */ jsx(ApiClientContext.Provider, { value, children });
174
+ }
175
+ function useApiClientConfig() {
176
+ const ctx = useContext(ApiClientContext);
177
+ if (!ctx) {
178
+ throw new Error("useApiClientConfig must be used within ApiClientProvider");
179
+ }
180
+ return ctx;
181
+ }
182
+ function useAPI() {
183
+ const config = useApiClientConfig();
184
+ const responseHandler = useMemo(() => createResponseHandler(config), [config]);
185
+ return useCallback(
186
+ (requestConfig) => {
187
+ const accessToken = config.getAccessToken();
188
+ return fetch(
189
+ buildRequestUrl(config.baseURL, requestConfig.endpoint),
190
+ getRequestOptions(requestConfig, accessToken, config.getAcceptLanguage?.())
191
+ ).then((response) => responseHandler(response, { config: requestConfig }));
192
+ },
193
+ [config, responseHandler]
194
+ );
195
+ }
196
+ function createApiProvider(useOptions) {
197
+ return function ApiProvider({ children }) {
198
+ const options = useOptions();
199
+ const apiConfig = useMemo(
200
+ () => ({
201
+ getAccessToken: options.getAccessToken,
202
+ getRefreshToken: options.getRefreshToken,
203
+ getAcceptLanguage: options.getAcceptLanguage,
204
+ refresh: {
205
+ request: createDefaultRefreshRequest({
206
+ endpoint: options.refreshEndpoint,
207
+ excludedRetryPrefixes: options.refreshExcludedPrefixes
208
+ }),
209
+ cookieCredentialsEnabled: options.cookieCredentialsEnabled,
210
+ setAccessToken: options.setAccessToken,
211
+ onFailure: options.onRefreshFailure,
212
+ onStart: options.onRefreshStart,
213
+ onEnd: options.onRefreshEnd
214
+ }
215
+ }),
216
+ [options]
217
+ );
218
+ return /* @__PURE__ */ jsx(ApiClientProvider, { baseURL: options.baseURL, config: apiConfig, children });
219
+ };
220
+ }
221
+
222
+ export { ApiClientProvider, DEFAULT_REFRESH_ENDPOINT, DEFAULT_REFRESH_EXCLUDED_PREFIXES, buildRequestUrl, createApiProvider, createDefaultRefreshRequest, createResponseHandler, executeConfiguredRefresh, getRequestHeaders, getRequestOptions, performAccessTokenRefresh, useAPI, useApiClientConfig };
223
+ //# sourceMappingURL=chunk-6LO5O4G6.js.map
224
+ //# sourceMappingURL=chunk-6LO5O4G6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/api/request.ts","../src/api/responseHandler.ts","../src/api/ApiClientContext.tsx","../src/api/createApiProvider.tsx"],"names":["useMemo","jsx"],"mappings":"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","file":"chunk-6LO5O4G6.js","sourcesContent":["import type {\n ApiClientConfig,\n RefreshBodyContext,\n RefreshRequestConfig,\n RequestConfig,\n} from './types';\n\nexport const DEFAULT_REFRESH_ENDPOINT = 'auth/refresh';\nexport const DEFAULT_REFRESH_EXCLUDED_PREFIXES = ['auth/'];\n\nexport interface DefaultRefreshRequestOptions {\n endpoint?: string;\n excludedRetryPrefixes?: string[];\n}\n\nexport function createDefaultRefreshRequest({\n endpoint = DEFAULT_REFRESH_ENDPOINT,\n excludedRetryPrefixes = DEFAULT_REFRESH_EXCLUDED_PREFIXES,\n}: DefaultRefreshRequestOptions = {}): RefreshRequestConfig {\n return {\n endpoint,\n method: 'POST',\n buildBody: ({ refreshToken }: RefreshBodyContext) => (refreshToken ? { refreshToken } : {}),\n parseAccessToken: (data: unknown) => {\n if (data && typeof data === 'object' && 'accessToken' in data) {\n const token = (data as { accessToken: unknown }).accessToken;\n return typeof token === 'string' ? token : null;\n }\n return null;\n },\n excludedRetryPrefixes,\n };\n}\n\nexport function buildRequestUrl(baseURL: string, endpoint: string): string {\n const base = baseURL.replace(/\\/$/, '');\n const path = endpoint.replace(/^\\//, '');\n return `${base}/${path}`;\n}\n\nexport function getRequestHeaders(\n accessToken: string | null,\n options?: { multipart?: boolean; acceptLanguage?: string },\n): HeadersInit {\n const headers: HeadersInit = {};\n if (!options?.multipart) {\n headers['Content-Type'] = 'application/json';\n }\n if (accessToken) {\n headers.Authorization = `Bearer ${accessToken}`;\n }\n if (options?.acceptLanguage) {\n headers['Accept-Language'] = options.acceptLanguage;\n }\n return headers;\n}\n\nexport function getRequestOptions(\n config: RequestConfig,\n token: string | null,\n acceptLanguage?: string,\n): RequestInit {\n const init: RequestInit = {\n method: config.method,\n headers: getRequestHeaders(token, {\n multipart: config.multipart,\n acceptLanguage,\n }),\n body: config.multipart\n ? (config.body as BodyInit)\n : config.body != null\n ? JSON.stringify(config.body)\n : undefined,\n };\n if (config.credentials) {\n init.credentials = config.credentials;\n }\n return init;\n}\n\nexport async function performAccessTokenRefresh(params: {\n baseURL: string;\n getRefreshToken: () => string | null;\n request: RefreshRequestConfig;\n useCookieCredentials: boolean;\n setAccessToken: (token: string) => void;\n onFailure: () => void;\n acceptLanguage?: string;\n}): Promise<string> {\n const refreshToken = params.useCookieCredentials ? null : params.getRefreshToken();\n if (!params.useCookieCredentials && !refreshToken) {\n params.onFailure();\n throw { error: new Error('missing refresh token'), status: 401 };\n }\n\n const bodyContext: RefreshBodyContext = {\n refreshToken,\n useCookieCredentials: params.useCookieCredentials,\n };\n\n const requestConfig: RequestConfig = {\n endpoint: params.request.endpoint,\n method: params.request.method,\n body: params.request.buildBody(bodyContext),\n credentials: params.useCookieCredentials ? 'include' : params.request.credentials,\n };\n\n const response = await fetch(\n buildRequestUrl(params.baseURL, requestConfig.endpoint),\n getRequestOptions(requestConfig, null, params.acceptLanguage),\n );\n const responseText = await response.text();\n\n let data: unknown = null;\n if (responseText) {\n try {\n data = JSON.parse(responseText);\n } catch {\n params.onFailure();\n throw { error: new Error('invalid refresh response'), status: 401 };\n }\n }\n\n const accessToken = params.request.parseAccessToken(data);\n if (!response.ok || !accessToken) {\n params.onFailure();\n throw { error: new Error('failed to refresh access token'), status: 401 };\n }\n\n params.setAccessToken(accessToken);\n return accessToken;\n}\n\nexport async function executeConfiguredRefresh(config: ApiClientConfig): Promise<string> {\n const refresh = config.refresh;\n if (!refresh) {\n throw new Error('refresh is not configured');\n }\n\n refresh.onStart?.();\n try {\n return await performAccessTokenRefresh({\n baseURL: config.baseURL,\n getRefreshToken: config.getRefreshToken,\n request: refresh.request,\n useCookieCredentials: refresh.cookieCredentialsEnabled(),\n setAccessToken: refresh.setAccessToken,\n onFailure: refresh.onFailure,\n acceptLanguage: config.getAcceptLanguage?.(),\n });\n } finally {\n refresh.onEnd?.();\n }\n}\n","import { buildRequestUrl, executeConfiguredRefresh, getRequestOptions } from './request';\nimport type { ApiClientConfig, ApiErrorBody, RequestConfig, RequestError } from './types';\n\nfunction shouldRetryWithRefresh(\n status: number,\n endpoint: string | undefined,\n isRetry: boolean | undefined,\n refreshToken: string | null | undefined,\n refresh: ApiClientConfig['refresh'],\n): boolean {\n if (status !== 401 || !refreshToken || !refresh || !endpoint || isRetry) {\n return false;\n }\n const normalized = endpoint.replace(/^\\//, '');\n return !refresh.request.excludedRetryPrefixes.some((prefix) =>\n normalized.startsWith(prefix.replace(/^\\//, '')),\n );\n}\n\nexport function createResponseHandler(config: ApiClientConfig) {\n const { baseURL, getRefreshToken, refresh } = config;\n\n async function handleResponse(\n response: Response,\n options?: { config?: RequestConfig; isRetry?: boolean },\n ): Promise<unknown> {\n const responseText = await response.text();\n let data: unknown;\n if (responseText) {\n try {\n data = JSON.parse(responseText);\n } catch {\n data = responseText;\n }\n }\n\n if (!response.ok) {\n const refreshToken = getRefreshToken();\n if (\n shouldRetryWithRefresh(\n response.status,\n options?.config?.endpoint,\n options?.isRetry,\n refreshToken,\n refresh,\n ) &&\n options?.config\n ) {\n const newToken = await executeConfiguredRefresh(config);\n const retryResponse = await fetch(\n buildRequestUrl(baseURL, options.config.endpoint),\n getRequestOptions(options.config, newToken, config.getAcceptLanguage?.()),\n );\n return handleResponse(retryResponse, { ...options, isRetry: true });\n }\n\n throw {\n error: data as ApiErrorBody,\n status: response.status,\n retry: response.status >= 500,\n } satisfies RequestError;\n }\n\n return data;\n }\n\n return handleResponse;\n}\n","import { createContext, type ReactNode, useCallback, useContext, useMemo } from 'react';\nimport { buildRequestUrl, getRequestOptions } from './request';\nimport { createResponseHandler } from './responseHandler';\nimport type { ApiClientConfig, ApiClientProviderConfig, FetchFn, RequestConfig } from './types';\n\nconst ApiClientContext = createContext<ApiClientConfig | null>(null);\n\nexport function ApiClientProvider({\n baseURL,\n config,\n children,\n}: {\n baseURL: string;\n config: ApiClientProviderConfig;\n children: ReactNode;\n}) {\n const value = useMemo<ApiClientConfig>(() => ({ ...config, baseURL }), [baseURL, config]);\n\n return <ApiClientContext.Provider value={value}>{children}</ApiClientContext.Provider>;\n}\n\nexport function useApiClientConfig(): ApiClientConfig {\n const ctx = useContext(ApiClientContext);\n if (!ctx) {\n throw new Error('useApiClientConfig must be used within ApiClientProvider');\n }\n return ctx;\n}\n\nexport function useAPI(): FetchFn {\n const config = useApiClientConfig();\n const responseHandler = useMemo(() => createResponseHandler(config), [config]);\n\n return useCallback(\n (requestConfig: RequestConfig) => {\n const accessToken = config.getAccessToken();\n return fetch(\n buildRequestUrl(config.baseURL, requestConfig.endpoint),\n getRequestOptions(requestConfig, accessToken, config.getAcceptLanguage?.()),\n ).then((response) => responseHandler(response, { config: requestConfig }));\n },\n [config, responseHandler],\n );\n}\n","import { type ReactNode, useMemo } from 'react';\n\nimport { ApiClientProvider } from './ApiClientContext';\nimport { createDefaultRefreshRequest } from './request';\nimport type { ApiClientProviderConfig } from './types';\n\nexport interface CreateApiProviderOptions {\n baseURL: string;\n getAccessToken: () => string | null;\n getRefreshToken: () => string | null;\n /** When true, refresh uses HttpOnly cookie credentials instead of body token. */\n cookieCredentialsEnabled: () => boolean;\n setAccessToken: (token: string) => void;\n onRefreshFailure: () => void;\n getAcceptLanguage?: () => string;\n onRefreshStart?: () => void;\n onRefreshEnd?: () => void;\n /** Refresh endpoint path relative to baseURL. Defaults to `auth/refresh`. */\n refreshEndpoint?: string;\n /** Paths that must not trigger automatic refresh retry on 401. Defaults to `['auth/']`. */\n refreshExcludedPrefixes?: string[];\n}\n\n/**\n * Factory for app `ApiProvider` components. Pass a hook that returns wiring options\n * (cookies, i18n, zustand). Memoize that return value with `useMemo` so the API\n * client context is not rebuilt on every parent render.\n */\nexport function createApiProvider(useOptions: () => CreateApiProviderOptions) {\n return function ApiProvider({ children }: { children: ReactNode }) {\n const options = useOptions();\n\n const apiConfig = useMemo<ApiClientProviderConfig>(\n () => ({\n getAccessToken: options.getAccessToken,\n getRefreshToken: options.getRefreshToken,\n getAcceptLanguage: options.getAcceptLanguage,\n refresh: {\n request: createDefaultRefreshRequest({\n endpoint: options.refreshEndpoint,\n excludedRetryPrefixes: options.refreshExcludedPrefixes,\n }),\n cookieCredentialsEnabled: options.cookieCredentialsEnabled,\n setAccessToken: options.setAccessToken,\n onFailure: options.onRefreshFailure,\n onStart: options.onRefreshStart,\n onEnd: options.onRefreshEnd,\n },\n }),\n [options],\n );\n\n return (\n <ApiClientProvider baseURL={options.baseURL} config={apiConfig}>\n {children}\n </ApiClientProvider>\n );\n };\n}\n"]}