@krak-stack/registry 0.1.13 → 0.1.15

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 (44) hide show
  1. package/README.md +19 -0
  2. package/dist/components/ui/app-brand.d.ts +18 -13
  3. package/dist/components/ui/app-brand.js +48 -15
  4. package/dist/components/ui/code-block.js +10 -6
  5. package/dist/components/ui/copy-button.d.ts +1 -1
  6. package/dist/components/ui/copy-button.js +1 -1
  7. package/dist/components/ui/data-table.d.ts +1 -1
  8. package/dist/components/ui/data-table.js +21 -20
  9. package/dist/components/ui/effect-form.js +7 -6
  10. package/dist/components/ui/file-picker.js +2 -1
  11. package/dist/components/ui/form.js +17 -15
  12. package/dist/components/ui/google-map.d.ts +6 -10
  13. package/dist/components/ui/google-map.js +19 -14
  14. package/dist/components/ui/locale-switcher.js +7 -1
  15. package/dist/components/ui/sidebar-layout.js +19 -21
  16. package/dist/components/ui/theme-switcher.js +1 -1
  17. package/dist/lib/docs-core.js +165 -109
  18. package/dist/lib/documentation-toolkit.d.ts +1 -1
  19. package/dist/lib/documentation-toolkit.js +41 -40
  20. package/dist/lib/httpapi-cli.d.ts +6 -6
  21. package/dist/lib/httpapi-cli.js +83 -48
  22. package/dist/lib/httpapi-client.d.ts +11 -2
  23. package/dist/lib/httpapi-client.js +29 -9
  24. package/dist/lib/httpapi-helpers.d.ts +15 -21
  25. package/dist/lib/httpapi-helpers.js +38 -26
  26. package/dist/lib/httpapi-mcp.js +81 -50
  27. package/dist/lib/httpapi-toolkit.d.ts +3 -2
  28. package/dist/lib/httpapi-toolkit.js +101 -65
  29. package/dist/lib/seo.js +29 -17
  30. package/dist/oxlint/anti-slop/index.js +1592 -0
  31. package/dist/services/agent/client/atom.d.ts +7 -7
  32. package/dist/services/agent/client/index.js +100 -62
  33. package/dist/services/agent/index.d.ts +71 -71
  34. package/dist/services/agent/index.js +38 -19
  35. package/dist/services/notification/channels/index.d.ts +11 -9
  36. package/dist/services/notification/channels/ses/index.d.ts +6 -6
  37. package/dist/services/notification/channels/ses/index.js +15 -11
  38. package/dist/services/notification/client/index.js +3 -2
  39. package/dist/services/notification/client/notification-menu.d.ts +9 -9
  40. package/dist/services/notification/index.d.ts +7 -6
  41. package/dist/services/notification/public.js +3 -2
  42. package/dist/services/s3/index.d.ts +2 -16
  43. package/dist/services/s3/index.js +12 -9
  44. package/package.json +7 -1
package/README.md CHANGED
@@ -79,3 +79,22 @@ bunx shadcn@latest add @krak-stack/data-table
79
79
  ```
80
80
 
81
81
  Project-specific configuration and scaffolding remain available through shadcn.
82
+
83
+ ## Oxlint Plugin
84
+
85
+ Projects that prefer centrally versioned rules can load the compiled anti-slop
86
+ plugin directly from the package:
87
+
88
+ ```json
89
+ {
90
+ "jsPlugins": [
91
+ {
92
+ "name": "anti-slop",
93
+ "specifier": "@krak-stack/registry/oxlint/anti-slop"
94
+ }
95
+ ]
96
+ }
97
+ ```
98
+
99
+ Use `@krak-stack/lint-format` instead when the project should receive editable,
100
+ vendored rule source under `tools/oxlint/anti-slop`.
@@ -1,26 +1,31 @@
1
1
  import { type LinkProps } from "@tanstack/react-router";
2
2
  import type { ComponentProps } from "react";
3
3
  import type { LucideIcon } from "lucide-react";
4
- type AppBrandBaseProps = {
4
+ type AppBrandContentProps = {
5
5
  label: string;
6
6
  subtitle: string;
7
7
  className?: string;
8
8
  variant?: "default" | "sidebar";
9
- } & ((Omit<LinkProps, "className" | "children"> & {
10
- to?: LinkProps["to"];
11
- }) | (ComponentProps<"a"> & {
12
- href: string;
13
- to?: never;
14
- }) | (ComponentProps<"div"> & {
15
- to: null;
16
- href?: never;
17
- }));
18
- type AppBrandProps = AppBrandBaseProps & ({
9
+ };
10
+ type AppBrandVisualProps = {
19
11
  icon: LucideIcon;
20
12
  imageSrc?: string;
21
13
  } | {
22
14
  imageSrc: string;
23
15
  icon?: LucideIcon;
24
- });
25
- export declare function AppBrand({ className, label, subtitle, icon: Icon, imageSrc, href, to, variant, ...props }: AppBrandProps): import("react").JSX.Element;
16
+ };
17
+ type AppBrandLinkProps = AppBrandContentProps & AppBrandVisualProps & Omit<LinkProps, "children" | "className" | "href" | "to"> & {
18
+ href?: never;
19
+ to?: Exclude<LinkProps["to"], null>;
20
+ };
21
+ type AppBrandAnchorProps = AppBrandContentProps & AppBrandVisualProps & Omit<ComponentProps<"a">, "children" | "className"> & {
22
+ href: string;
23
+ to?: never;
24
+ };
25
+ type AppBrandStaticProps = AppBrandContentProps & AppBrandVisualProps & Omit<ComponentProps<"div">, "children" | "className"> & {
26
+ href?: never;
27
+ to: null;
28
+ };
29
+ type AppBrandProps = AppBrandLinkProps | AppBrandAnchorProps | AppBrandStaticProps;
30
+ export declare function AppBrand(brandProps: AppBrandProps): import("react").JSX.Element;
26
31
  export {};
@@ -1,17 +1,17 @@
1
1
  // ../../src/components/ui/app-brand.tsx
2
2
  import { Link } from "@tanstack/react-router";
3
3
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
4
- function AppBrand({
5
- className,
6
- label,
7
- subtitle,
8
- icon: Icon,
9
- imageSrc,
10
- href,
11
- to,
12
- variant = "default",
13
- ...props
14
- }) {
4
+ var isStaticBrand = (props) => props.to === null;
5
+ var isAnchorBrand = (props) => props.href !== undefined;
6
+ function AppBrand(brandProps) {
7
+ const {
8
+ className,
9
+ label,
10
+ subtitle,
11
+ icon: Icon,
12
+ imageSrc,
13
+ variant = "default"
14
+ } = brandProps;
15
15
  const iconClassName = variant === "sidebar" ? "bg-sidebar-primary" : "bg-primary";
16
16
  const iconColor = variant === "sidebar" ? "var(--sidebar-primary-foreground)" : "var(--primary-foreground)";
17
17
  const contentClassName = variant === "sidebar" ? "group-data-[collapsible=icon]:hidden" : undefined;
@@ -51,21 +51,54 @@ function AppBrand({
51
51
  variant === "sidebar" ? "p-2 group-data-[collapsible=icon]:justify-center group-data-[collapsible=icon]:p-0" : "",
52
52
  className
53
53
  ].filter(Boolean).join(" ");
54
- if (to === null) {
54
+ if (isStaticBrand(brandProps)) {
55
+ const {
56
+ className: _className2,
57
+ label: _label2,
58
+ subtitle: _subtitle2,
59
+ icon: _icon2,
60
+ imageSrc: _imageSrc2,
61
+ variant: _variant2,
62
+ to: _to,
63
+ href: _href2,
64
+ ...props2
65
+ } = brandProps;
55
66
  return /* @__PURE__ */ jsx("div", {
56
67
  className: brandClassName,
57
- ...props,
68
+ ...props2,
58
69
  children: content
59
70
  });
60
71
  }
61
- if (href) {
72
+ if (isAnchorBrand(brandProps)) {
73
+ const {
74
+ className: _className2,
75
+ label: _label2,
76
+ subtitle: _subtitle2,
77
+ icon: _icon2,
78
+ imageSrc: _imageSrc2,
79
+ variant: _variant2,
80
+ to: _to,
81
+ href,
82
+ ...props2
83
+ } = brandProps;
62
84
  return /* @__PURE__ */ jsx("a", {
63
85
  className: brandClassName,
64
86
  href,
65
- ...props,
87
+ ...props2,
66
88
  children: content
67
89
  });
68
90
  }
91
+ const {
92
+ className: _className,
93
+ label: _label,
94
+ subtitle: _subtitle,
95
+ icon: _icon,
96
+ imageSrc: _imageSrc,
97
+ variant: _variant,
98
+ href: _href,
99
+ to,
100
+ ...props
101
+ } = brandProps;
69
102
  return /* @__PURE__ */ jsx(Link, {
70
103
  to: to ?? "/",
71
104
  className: brandClassName,
@@ -95,7 +95,7 @@ function CopyButton({
95
95
  onCopied?.();
96
96
  } catch (error) {
97
97
  setCopyState("failed");
98
- onCopyError?.(error);
98
+ onCopyError?.(error instanceof Error ? error : new Error("Copy failed", { cause: error }));
99
99
  }
100
100
  resetCopyState();
101
101
  };
@@ -168,6 +168,14 @@ function CodeBlock({
168
168
  active = false;
169
169
  };
170
170
  }, [code, highlighter, language]);
171
+ const copyMessages = {};
172
+ if (messages?.copy !== undefined)
173
+ copyMessages.copy = messages.copy;
174
+ if (messages?.copied !== undefined)
175
+ copyMessages.copied = messages.copied;
176
+ if (messages?.copyFailed !== undefined) {
177
+ copyMessages.copyFailed = messages.copyFailed;
178
+ }
171
179
  return /* @__PURE__ */ jsxs2("div", {
172
180
  className: "overflow-hidden rounded-md border",
173
181
  children: [
@@ -182,11 +190,7 @@ function CodeBlock({
182
190
  value: code,
183
191
  valueDescription: `${language.toLowerCase()} code`,
184
192
  variant: "secondary",
185
- messages: {
186
- ...messages?.copy === undefined ? {} : { copy: messages.copy },
187
- ...messages?.copied === undefined ? {} : { copied: messages.copied },
188
- ...messages?.copyFailed === undefined ? {} : { copyFailed: messages.copyFailed }
189
- }
193
+ messages: copyMessages
190
194
  })
191
195
  ]
192
196
  }),
@@ -11,7 +11,7 @@ type CopyButtonProps = Omit<ComponentProps<typeof Button>, "children" | "onClick
11
11
  copyVariant?: "default" | "sm" | "large";
12
12
  messages?: CopyButtonMessages;
13
13
  onCopied?: () => void;
14
- onCopyError?: (error: unknown) => void;
14
+ onCopyError?: (error: Error) => void;
15
15
  resetDelay?: number;
16
16
  };
17
17
  export declare function CopyButton({ value, valueDescription, copyVariant, messages, onCopied, onCopyError, resetDelay, disabled, size, "aria-label": ariaLabel, ...props }: CopyButtonProps): import("react").JSX.Element;
@@ -95,7 +95,7 @@ function CopyButton({
95
95
  onCopied?.();
96
96
  } catch (error) {
97
97
  setCopyState("failed");
98
- onCopyError?.(error);
98
+ onCopyError?.(error instanceof Error ? error : new Error("Copy failed", { cause: error }));
99
99
  }
100
100
  resetCopyState();
101
101
  };
@@ -350,7 +350,7 @@ export declare const DataTableRowActions: <TData>({ actions, contentClassName, r
350
350
  export declare const getHeaderNames: <TData extends RowData>(headers: DataTableHeader<TData, unknown>[]) => string[];
351
351
  export type CsvValue = string | number | boolean | null | undefined;
352
352
  export declare const downloadCsv: (headers: CsvValue[], data: CsvValue[][], fileName?: string) => void;
353
- export declare const downloadJson: (data: unknown, fileName?: string) => void;
353
+ export declare const downloadJson: <Data>(data: Data, fileName?: string) => void;
354
354
  export declare function DataTable<TData extends RowData>({ columns, data, state, search: controlledSearch, onSearchChange, searchState, emptyLabel, messages, exportFileName, isLoading: legacyIsLoading, onRefresh, onRowClick, from, routeFrom, grouping, gallery, rowActions: legacyRowActions, reordering, serverPagination, features, }: DataTableProps<TData>): import("react").JSX.Element;
355
355
  interface DataTablePaginationProps<TData extends RowData> {
356
356
  messages?: DataTableMessageOverrides;
@@ -1859,6 +1859,7 @@ var DEFAULT_COLUMN_MIN_SIZE = 128;
1859
1859
  var DEFAULT_COLUMN_SIZE = 224;
1860
1860
  var DEFAULT_COLUMN_MAX_SIZE = 640;
1861
1861
  var COLUMN_RESIZE_STEP = 8;
1862
+ var dataTableColumnMeta = {};
1862
1863
  var dataTableFeatures = tableFeatures({
1863
1864
  columnFilteringFeature,
1864
1865
  columnResizingFeature,
@@ -1871,7 +1872,7 @@ var dataTableFeatures = tableFeatures({
1871
1872
  filteredRowModel: createFilteredRowModel(),
1872
1873
  paginatedRowModel: createPaginatedRowModel(),
1873
1874
  sortedRowModel: createSortedRowModel(),
1874
- columnMeta: {}
1875
+ columnMeta: dataTableColumnMeta
1875
1876
  });
1876
1877
  var {
1877
1878
  createAppColumnHelper: createDataTableColumnHelper,
@@ -2007,7 +2008,7 @@ var snapDragOverlayVerticalCenterToCursor = ({
2007
2008
  overlayNodeRect,
2008
2009
  transform
2009
2010
  }) => {
2010
- if (typeof MouseEvent === "undefined" || !(activatorEvent instanceof MouseEvent) || !activeNodeRect || !overlayNodeRect) {
2011
+ if (!globalThis.window || !(activatorEvent instanceof globalThis.window.MouseEvent) || !activeNodeRect || !overlayNodeRect) {
2011
2012
  return transform;
2012
2013
  }
2013
2014
  return {
@@ -2609,24 +2610,24 @@ var DataTableGalleryCard = ({
2609
2610
  });
2610
2611
  };
2611
2612
  var extractTextFromElement = (element) => {
2612
- if (typeof element === "string")
2613
+ if (Schema2.is(Schema2.String)(element))
2613
2614
  return element;
2614
- if (typeof element === "number")
2615
+ if (Schema2.is(Schema2.Number)(element))
2615
2616
  return String(element);
2616
2617
  if (!isValidElement(element)) {
2617
2618
  return null;
2618
2619
  }
2619
2620
  const { props } = element;
2620
- if (typeof props.title === "string")
2621
+ if (Schema2.is(Schema2.String)(props.title))
2621
2622
  return props.title;
2622
2623
  return extractTextFromElement(props.children);
2623
2624
  };
2624
2625
  var getColumnLabels = (table) => new Map(table.getFlatHeaders().map((header) => [header.column.id, getHeaderName(header)]));
2625
2626
  var getHeaderName = (header) => {
2626
2627
  const columnDef = header.column.columnDef;
2627
- if (typeof columnDef.header === "function") {
2628
+ if (columnDef.header instanceof Function) {
2628
2629
  const headerContext = columnDef.header(header.getContext());
2629
- if (typeof headerContext === "string") {
2630
+ if (Schema2.is(Schema2.String)(headerContext)) {
2630
2631
  return headerContext;
2631
2632
  }
2632
2633
  return extractTextFromElement(headerContext) ?? header.id;
@@ -2929,7 +2930,7 @@ function DataTable({
2929
2930
  const showExport = exportFeature !== false;
2930
2931
  const columnVisibilityFeature2 = features?.columnVisibility ?? true;
2931
2932
  const showColumnVisibility = columnVisibilityFeature2 !== false;
2932
- const defaultColumnVisibility = typeof columnVisibilityFeature2 === "object" ? columnVisibilityFeature2.default : undefined;
2933
+ const defaultColumnVisibility = Schema2.is(Schema2.Struct({ default: ColumnVisibilitySchema }))(columnVisibilityFeature2) ? columnVisibilityFeature2.default : undefined;
2933
2934
  const showGallery = !!galleryConfig;
2934
2935
  const showSorting = features?.sorting ?? true;
2935
2936
  const selectionFeature = features?.selection === false ? undefined : features?.selection;
@@ -2964,10 +2965,10 @@ function DataTable({
2964
2965
  }));
2965
2966
  const tableStorageId = useMemo(() => {
2966
2967
  const columnIds = columns.map((column, index) => {
2967
- if ("id" in column && typeof column.id === "string") {
2968
+ if ("id" in column && Schema2.is(Schema2.String)(column.id)) {
2968
2969
  return column.id;
2969
2970
  }
2970
- if ("accessorKey" in column && typeof column.accessorKey === "string") {
2971
+ if ("accessorKey" in column && Schema2.is(Schema2.String)(column.accessorKey)) {
2971
2972
  return column.accessorKey;
2972
2973
  }
2973
2974
  return String(index);
@@ -3029,14 +3030,14 @@ function DataTable({
3029
3030
  data,
3030
3031
  columns,
3031
3032
  onColumnSizingChange: (updater) => {
3032
- const nextColumnSizing = typeof updater === "function" ? updater(columnSizing) : updater;
3033
+ const nextColumnSizing = updater instanceof Function ? updater(columnSizing) : updater;
3033
3034
  setColumnSizing(nextColumnSizing);
3034
3035
  },
3035
3036
  ...selectionFeature ? { getRowId: selectionFeature.getRowId } : reordering ? { getRowId: reordering.getRowId } : {},
3036
3037
  enableRowSelection: selectionFeature?.isRowSelectable ? (row) => selectionFeature.isRowSelectable?.(row.original) ?? true : selectable,
3037
3038
  enableMultiRowSelection: selectable,
3038
3039
  onPaginationChange: (updater) => {
3039
- const newPagination = typeof updater === "function" ? updater(pagination) : updater;
3040
+ const newPagination = updater instanceof Function ? updater(pagination) : updater;
3040
3041
  if (pagination.pageIndex === newPagination.pageIndex && pagination.pageSize === newPagination.pageSize) {
3041
3042
  return;
3042
3043
  }
@@ -3047,7 +3048,7 @@ function DataTable({
3047
3048
  }));
3048
3049
  },
3049
3050
  onSortingChange: (updater) => {
3050
- const newSorting = typeof updater === "function" ? updater([...sorting]) : updater;
3051
+ const newSorting = updater instanceof Function ? updater([...sorting]) : updater;
3051
3052
  if (sorting.length === newSorting.length && sorting.every((sortState, i) => sortState.id === newSorting[i]?.id && sortState.desc === newSorting[i]?.desc)) {
3052
3053
  return;
3053
3054
  }
@@ -3062,7 +3063,7 @@ function DataTable({
3062
3063
  }));
3063
3064
  },
3064
3065
  onGlobalFilterChange: (updater) => {
3065
- const newGlobalFilter = typeof updater === "function" ? updater(globalFilter) : updater;
3066
+ const newGlobalFilter = updater instanceof Function ? updater(globalFilter) : updater;
3066
3067
  if (globalFilter === newGlobalFilter) {
3067
3068
  return;
3068
3069
  }
@@ -3072,17 +3073,17 @@ function DataTable({
3072
3073
  globalFilter: newGlobalFilter
3073
3074
  }), { replace: true });
3074
3075
  },
3075
- ...isServerMode ? { manualSorting: true } : {},
3076
- ...isServerMode ? { manualFiltering: true } : {},
3076
+ manualSorting: isServerMode || undefined,
3077
+ manualFiltering: isServerMode || undefined,
3077
3078
  ...paginationFeature !== false && paginationFeature.mode === "server" ? { manualPagination: true, rowCount: paginationFeature.rowCount } : paginationFeature === false ? { manualPagination: true } : {},
3078
3079
  autoResetPageIndex: false,
3079
3080
  onColumnVisibilityChange: (updater) => {
3080
- const nextColumnVisibility = typeof updater === "function" ? updater(columnVisibility) : updater;
3081
+ const nextColumnVisibility = updater instanceof Function ? updater(columnVisibility) : updater;
3081
3082
  setColumnVisibility(nextColumnVisibility);
3082
3083
  },
3083
3084
  onRowSelectionChange: (updater) => {
3084
3085
  setRowSelection((current) => {
3085
- const next = typeof updater === "function" ? updater(current) : updater;
3086
+ const next = updater instanceof Function ? updater(current) : updater;
3086
3087
  selectionFeature?.onSelectionChange?.(data.filter((row) => next[selectionFeature.getRowId(row)]));
3087
3088
  return next;
3088
3089
  });
@@ -3563,7 +3564,7 @@ function DataTableViewOptions({
3563
3564
  table
3564
3565
  }) {
3565
3566
  const columnLabels = getColumnLabels(table);
3566
- const columns = table.getAllColumns().filter((column) => typeof column.accessorFn !== "undefined" && column.getCanHide());
3567
+ const columns = table.getAllColumns().filter((column) => column.accessorFn !== undefined && column.getCanHide());
3567
3568
  if (columns.length === 0) {
3568
3569
  return null;
3569
3570
  }
@@ -3700,7 +3701,7 @@ function DataTableListSummary({
3700
3701
  visibleCount = 3
3701
3702
  }) {
3702
3703
  const labels2 = dataTableMessages();
3703
- const normalizedItems = items.map((item) => typeof item === "string" ? { label: item } : item);
3704
+ const normalizedItems = items.map((item) => Schema2.is(Schema2.String)(item) ? { label: item } : item);
3704
3705
  const visibleItems = normalizedItems.slice(0, visibleCount);
3705
3706
  const visibleLabels = visibleItems.map(({ label }) => label).join(", ");
3706
3707
  const remaining = Math.max(totalCount - visibleItems.length, 0);
@@ -1,7 +1,7 @@
1
1
  // ../../src/components/ui/effect-form.tsx
2
2
  import { useAtomSet, useAtomValue } from "@effect/atom-react";
3
3
  import { Block } from "@tanstack/react-router";
4
- import { Cause, Option, Schema } from "effect";
4
+ import { Cause, Option, Schema as Schema2 } from "effect";
5
5
  import { AsyncResult } from "effect/unstable/reactivity";
6
6
  import { Languages, Loader2, Plus, Trash } from "lucide-react";
7
7
 
@@ -175,6 +175,7 @@ import {
175
175
  useState
176
176
  } from "react";
177
177
  import { CloudUpload, FileIcon, FileUp, RefreshCw, Trash2 } from "lucide-react";
178
+ import { Schema } from "effect";
178
179
 
179
180
  // ../../src/components/ui/attachment.tsx
180
181
  import { mergeProps } from "@base-ui/react/merge-props";
@@ -1029,7 +1030,7 @@ var FilePicker = ({
1029
1030
  }),
1030
1031
  canClear ? /* @__PURE__ */ jsx5(AttachmentAction, {
1031
1032
  type: "button",
1032
- "aria-label": `${labels.deleteFile} ${typeof title === "string" ? title : ""}`,
1033
+ "aria-label": `${labels.deleteFile} ${Schema.is(Schema.String)(title) ? title : ""}`,
1033
1034
  onClick: clear,
1034
1035
  children: /* @__PURE__ */ jsx5(Trash2, {})
1035
1036
  }) : null
@@ -1768,7 +1769,7 @@ var ErrorMessage = ({ text }) => /* @__PURE__ */ jsx14("em", {
1768
1769
  var SubmitError = ({
1769
1770
  result
1770
1771
  }) => {
1771
- const message = AsyncResult.isFailure(result) ? Schema.isSchemaError(Cause.squash(result.cause)) ? undefined : getCauseErrorMessage(result.cause) : undefined;
1772
+ const message = AsyncResult.isFailure(result) ? Schema2.isSchemaError(Cause.squash(result.cause)) ? undefined : getCauseErrorMessage(result.cause) : undefined;
1772
1773
  return message ? /* @__PURE__ */ jsx14(ErrorMessage, {
1773
1774
  text: message
1774
1775
  }) : null;
@@ -2154,7 +2155,7 @@ var SearchableSelectField = ({
2154
2155
  const { selectedItems, mergedItems } = getSearchableSelectItems(field.value, props.initialItems ?? [], props.items);
2155
2156
  const invalid = Option.isSome(field.error);
2156
2157
  const labels = virtualizedComboboxMessages(props.messages);
2157
- const ariaLabel = typeof props.label === "string" ? props.label : labels.search;
2158
+ const ariaLabel = Schema2.is(Schema2.String)(props.label) ? props.label : labels.search;
2158
2159
  return /* @__PURE__ */ jsxs6(Field, {
2159
2160
  className: "min-w-0",
2160
2161
  "data-invalid": invalid,
@@ -2194,7 +2195,7 @@ var SingleSearchableSelectField = ({
2194
2195
  const { selectedItems, mergedItems } = getSearchableSelectItems(field.value ? [field.value] : [], props.initialItems ?? [], props.items);
2195
2196
  const invalid = Option.isSome(field.error);
2196
2197
  const labels = virtualizedComboboxMessages(props.messages);
2197
- const ariaLabel = typeof props.label === "string" ? props.label : labels.search;
2198
+ const ariaLabel = Schema2.is(Schema2.String)(props.label) ? props.label : labels.search;
2198
2199
  return /* @__PURE__ */ jsxs6(Field, {
2199
2200
  className: "min-w-0",
2200
2201
  "data-invalid": invalid,
@@ -2382,7 +2383,7 @@ var RevertButton = ({
2382
2383
  })
2383
2384
  });
2384
2385
  var ImageField = ({ field, props }) => {
2385
- const imageUrl = typeof field.value === "string" ? field.value : undefined;
2386
+ const imageUrl = Schema2.is(Schema2.String)(field.value) ? field.value : undefined;
2386
2387
  const invalid = Option.isSome(field.error);
2387
2388
  return /* @__PURE__ */ jsxs6(Field, {
2388
2389
  "data-invalid": invalid,
@@ -6,6 +6,7 @@ import {
6
6
  useState
7
7
  } from "react";
8
8
  import { CloudUpload, FileIcon, FileUp, RefreshCw, Trash2 } from "lucide-react";
9
+ import { Schema } from "effect";
9
10
 
10
11
  // ../../src/components/ui/attachment.tsx
11
12
  import { mergeProps } from "@base-ui/react/merge-props";
@@ -912,7 +913,7 @@ var FilePicker = ({
912
913
  }),
913
914
  canClear ? /* @__PURE__ */ jsx4(AttachmentAction, {
914
915
  type: "button",
915
- "aria-label": `${labels.deleteFile} ${typeof title === "string" ? title : ""}`,
916
+ "aria-label": `${labels.deleteFile} ${Schema.is(Schema.String)(title) ? title : ""}`,
916
917
  onClick: clear,
917
918
  children: /* @__PURE__ */ jsx4(Trash2, {})
918
919
  }) : null
@@ -137,6 +137,7 @@ import {
137
137
  useStore
138
138
  } from "@tanstack/react-form";
139
139
  import { Block } from "@tanstack/react-router";
140
+ import { Option, Schema as Schema2 } from "effect";
140
141
  import { Loader2, Plus, Trash, Languages } from "lucide-react";
141
142
 
142
143
  // ../../src/components/ui/alert-dialog.tsx
@@ -332,6 +333,7 @@ import {
332
333
  useState
333
334
  } from "react";
334
335
  import { CloudUpload, FileIcon, FileUp, RefreshCw, Trash2 } from "lucide-react";
336
+ import { Schema } from "effect";
335
337
 
336
338
  // ../../src/components/ui/attachment.tsx
337
339
  import { mergeProps } from "@base-ui/react/merge-props";
@@ -1174,7 +1176,7 @@ var FilePicker = ({
1174
1176
  }),
1175
1177
  canClear ? /* @__PURE__ */ jsx7(AttachmentAction, {
1176
1178
  type: "button",
1177
- "aria-label": `${labels.deleteFile} ${typeof title === "string" ? title : ""}`,
1179
+ "aria-label": `${labels.deleteFile} ${Schema.is(Schema.String)(title) ? title : ""}`,
1178
1180
  onClick: clear,
1179
1181
  children: /* @__PURE__ */ jsx7(Trash2, {})
1180
1182
  }) : null
@@ -2125,7 +2127,7 @@ var SearchableSelectField = ({
2125
2127
  const field = useFieldContext();
2126
2128
  const labels = virtualizedComboboxMessages(props.messages);
2127
2129
  const invalid = !field.state.meta.isValid;
2128
- const ariaLabel = typeof label === "string" ? label : labels.search;
2130
+ const ariaLabel = Schema2.is(Schema2.String)(label) ? label : labels.search;
2129
2131
  const controlProps = {
2130
2132
  ...props,
2131
2133
  ariaLabel,
@@ -2205,7 +2207,13 @@ var ImageField = ({
2205
2207
  const labels = formMessages(messages4);
2206
2208
  const field = useFieldContext();
2207
2209
  const invalid = !field.state.meta.isValid;
2208
- const imageUrl = typeof field.state.value === "string" ? field.state.value : undefined;
2210
+ const imageUrl = Schema2.is(Schema2.String)(field.state.value) ? field.state.value : undefined;
2211
+ const image = {
2212
+ alt: label,
2213
+ height: size.height,
2214
+ width: size.width,
2215
+ src: imageUrl
2216
+ };
2209
2217
  return /* @__PURE__ */ jsxs6(Field, {
2210
2218
  "data-invalid": invalid,
2211
2219
  children: [
@@ -2218,12 +2226,7 @@ var ImageField = ({
2218
2226
  canClear: Boolean(field.state.value),
2219
2227
  ...field.state.value instanceof File ? { file: field.state.value } : {},
2220
2228
  id: field.name,
2221
- image: {
2222
- alt: label,
2223
- height: size.height,
2224
- ...imageUrl ? { src: imageUrl } : {},
2225
- width: size.width
2226
- },
2229
+ image,
2227
2230
  invalid,
2228
2231
  messages: { accepts: labels.accepts, deleteFile: labels.delete },
2229
2232
  name: field.name,
@@ -2303,14 +2306,13 @@ var SubmitButton = ({
2303
2306
  })
2304
2307
  });
2305
2308
  };
2309
+ var FormErrorValue = Schema2.Struct({
2310
+ form: Schema2.optional(Schema2.Unknown)
2311
+ }).annotate({ identifier: "FormErrorValue" });
2306
2312
  var getFormErrorText = (error) => {
2307
- if (!error)
2313
+ if (error == null)
2308
2314
  return;
2309
- if (typeof error === "object" && "form" in error) {
2310
- const formError = error.form;
2311
- return formError ? String(formError) : undefined;
2312
- }
2313
- return String(error);
2315
+ return Schema2.decodeUnknownOption(FormErrorValue)(error).pipe(Option.flatMap((value) => Option.fromNullishOr(value.form)), Option.map(String), Option.getOrElse(() => String(error)));
2314
2316
  };
2315
2317
  var FormError = () => {
2316
2318
  const form = useFormContext();
@@ -35,6 +35,7 @@ export type GoogleMapProps = {
35
35
  maxZoom?: number | undefined;
36
36
  className?: string | undefined;
37
37
  messages?: Partial<GoogleMapMessages> | undefined;
38
+ locale?: string | undefined;
38
39
  };
39
40
  type GoogleMapOptions = {
40
41
  center: GoogleMapPoint;
@@ -73,7 +74,8 @@ type GoogleCircleInstance = {
73
74
  type GoogleMapsEventListener = {
74
75
  remove: () => void;
75
76
  };
76
- type GoogleMapsApi = {
77
+ type GoogleMapsEventTarget = GoogleMapInstance | GoogleMarkerInstance | GoogleCircleInstance;
78
+ export type GoogleMapsApi = {
77
79
  maps: {
78
80
  Map: new (element: HTMLElement, options: GoogleMapOptions) => GoogleMapInstance;
79
81
  Marker: new (options: {
@@ -88,16 +90,10 @@ type GoogleMapsApi = {
88
90
  radius: number;
89
91
  }) => GoogleCircleInstance;
90
92
  event: {
91
- addListener: (instance: object, eventName: string, handler: () => void) => GoogleMapsEventListener;
92
- clearInstanceListeners: (instance: object) => void;
93
+ addListener: (instance: GoogleMapsEventTarget, eventName: string, handler: () => void) => GoogleMapsEventListener;
94
+ clearInstanceListeners: (instance: GoogleMapsEventTarget) => void;
93
95
  };
94
96
  };
95
97
  };
96
- declare global {
97
- interface Window {
98
- google?: GoogleMapsApi | undefined;
99
- __krakStackGoogleMapsInit?: (() => void) | undefined;
100
- }
101
- }
102
- export declare function GoogleMap({ apiKey, center, zoom, marker, radius, interactive, zoomControls, minZoom, maxZoom, className, messages: messageOverrides, }: GoogleMapProps): import("react").JSX.Element;
98
+ export declare function GoogleMap({ apiKey, center, zoom, marker, radius, interactive, zoomControls, minZoom, maxZoom, className, messages: messageOverrides, locale, }: GoogleMapProps): import("react").JSX.Element;
103
99
  export {};
@@ -1,6 +1,7 @@
1
1
  // ../../src/components/ui/google-map.tsx
2
2
  import { Minus, Plus } from "lucide-react";
3
3
  import { useEffect, useEffectEvent, useRef, useState } from "react";
4
+ import { Schema } from "effect";
4
5
 
5
6
  // ../../src/lib/utils.ts
6
7
  import { clsx } from "clsx";
@@ -472,28 +473,30 @@ var defaultMessages = {
472
473
  zoomOut: "Zoom arrière"
473
474
  }
474
475
  };
475
- var googleMapMessages = (overrides) => ({
476
- ...getLocale().startsWith("fr") ? defaultMessages.fr : defaultMessages.en,
476
+ var googleMapMessages = (locale, overrides) => ({
477
+ ...locale.startsWith("fr") ? defaultMessages.fr : defaultMessages.en,
477
478
  ...overrides
478
479
  });
479
480
  var isGoogleMapsReady = (api) => Boolean(api?.maps.Map && api.maps.Marker && api.maps.Circle && api.maps.event);
480
481
  var loadGoogleMaps = (apiKey) => {
481
- if (typeof window === "undefined" || typeof document === "undefined") {
482
+ if (!globalThis.window || !globalThis.document) {
482
483
  return Promise.reject(new Error("Google Maps requires a browser."));
483
484
  }
484
- if (isGoogleMapsReady(window.google))
485
- return Promise.resolve(window.google);
485
+ const browserWindow = window;
486
+ if (isGoogleMapsReady(browserWindow.google)) {
487
+ return Promise.resolve(browserWindow.google);
488
+ }
486
489
  if (googleMapsPromise)
487
490
  return googleMapsPromise;
488
491
  googleMapsPromise = new Promise((resolve, reject) => {
489
492
  const resolveApi = () => {
490
- if (isGoogleMapsReady(window.google))
491
- resolve(window.google);
492
- else
493
+ if (isGoogleMapsReady(browserWindow.google)) {
494
+ resolve(browserWindow.google);
495
+ } else
493
496
  reject(new Error("Google Maps failed to initialize."));
494
497
  };
495
498
  const rejectLoad = () => reject(new Error("Google Maps failed to load."));
496
- window[googleMapsCallbackName] = resolveApi;
499
+ browserWindow.__krakStackGoogleMapsInit = resolveApi;
497
500
  const existingScript = document.getElementById(googleMapsScriptId);
498
501
  if (existingScript) {
499
502
  existingScript.addEventListener("error", rejectLoad, { once: true });
@@ -508,7 +511,7 @@ var loadGoogleMaps = (apiKey) => {
508
511
  document.head.append(script);
509
512
  }).catch((error) => {
510
513
  googleMapsPromise = undefined;
511
- window[googleMapsCallbackName] = undefined;
514
+ browserWindow.__krakStackGoogleMapsInit = undefined;
512
515
  document.getElementById(googleMapsScriptId)?.remove();
513
516
  throw error;
514
517
  });
@@ -542,7 +545,8 @@ function GoogleMap({
542
545
  minZoom = 3,
543
546
  maxZoom = 20,
544
547
  className,
545
- messages: messageOverrides
548
+ messages: messageOverrides,
549
+ locale = getLocale()
546
550
  }) {
547
551
  const mapElementRef = useRef(null);
548
552
  const apiRef = useRef(null);
@@ -556,9 +560,10 @@ function GoogleMap({
556
560
  const initialZoom = clampZoom(zoom, normalizedMinZoom, normalizedMaxZoom);
557
561
  const [loadState, setLoadState] = useState(normalizedApiKey ? "loading" : "missing-key");
558
562
  const [currentZoom, setCurrentZoom] = useState(initialZoom);
559
- const labels = googleMapMessages(messageOverrides);
560
- const markerEnabled = marker === true || typeof marker === "object";
561
- const markerIcon = typeof marker === "object" ? marker.icon : undefined;
563
+ const labels = googleMapMessages(locale, messageOverrides);
564
+ const markerOptions = Schema.is(Schema.Struct({ icon: Schema.optional(Schema.String) }))(marker) ? marker : undefined;
565
+ const markerEnabled = marker === true || markerOptions !== undefined;
566
+ const markerIcon = markerOptions?.icon;
562
567
  const centerLat = center.lat;
563
568
  const centerLng = center.lng;
564
569
  const radiusMeters = radius?.radiusMeters;