@uninspired/cookie-banner 0.0.12 → 0.0.14

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.
package/README.md CHANGED
@@ -0,0 +1,206 @@
1
+ # Cookie Banner
2
+
3
+ Cookie banner for all Uninspired products. Available as React component or HTML embed script.
4
+
5
+ ## Theming
6
+
7
+ Default theme:
8
+
9
+ ```css
10
+ :root {
11
+ /* Colors */
12
+ /* Base */
13
+ --cb-color-neutral-0: rgb(255, 255, 255);
14
+ --cb-color-neutral-50: rgb(250, 250, 250);
15
+ --cb-color-neutral-100: rgb(245, 245, 245);
16
+ --cb-color-neutral-200: rgb(229, 229, 229);
17
+ --cb-color-neutral-300: rgb(212, 212, 212);
18
+ --cb-color-neutral-400: rgb(163, 163, 163);
19
+ --cb-color-neutral-500: rgb(115, 115, 115);
20
+ --cb-color-neutral-600: rgb(82, 82, 82);
21
+ --cb-color-neutral-700: rgb(64, 64, 64);
22
+ --cb-color-neutral-800: rgb(38, 38, 38);
23
+ --cb-color-neutral-900: rgb(23, 23, 23);
24
+ --cb-color-neutral-950: rgb(10, 10, 10);
25
+
26
+ --cb-color-brand-50: rgb(236, 253, 245);
27
+ --cb-color-brand-100: rgb(209, 250, 229);
28
+ --cb-color-brand-200: rgb(167, 243, 208);
29
+ --cb-color-brand-300: rgb(110, 231, 183);
30
+ --cb-color-brand-400: rgb(52, 211, 153);
31
+ --cb-color-brand-500: rgb(16, 185, 129);
32
+ --cb-color-brand-600: rgb(5, 150, 105);
33
+ --cb-color-brand-700: rgb(4, 120, 87);
34
+ --cb-color-brand-800: rgb(6, 95, 70);
35
+ --cb-color-brand-900: rgb(6, 78, 59);
36
+
37
+ --cb-space-base: 4px;
38
+ --cb-space-xs: calc(var(--cb-space-base) * 1);
39
+ --cb-space-sm: calc(var(--cb-space-base) * 2);
40
+ --cb-space-md: calc(var(--cb-space-base) * 4);
41
+ --cb-space-lg: calc(var(--cb-space-base) * 6);
42
+ --cb-space-xl: calc(var(--cb-space-base) * 12);
43
+
44
+ /* Typography */
45
+ --cb-font-family-body: "Nunito Sans", sans-serif;
46
+ --cb-font-size-body: 14px;
47
+ --cb-font-weight-body-normal: 400;
48
+ --cb-font-weight-body-bold: 500;
49
+ --cb-line-height-body: 20px;
50
+ --cb-letter-spacing-body: 0em;
51
+
52
+ --cb-font-family-caption: "Nunito Sans", sans-serif;
53
+ --cb-font-size-caption: 12px;
54
+ --cb-font-weight-caption-normal: 400;
55
+ --cb-font-weight-caption-bold: 500;
56
+ --cb-line-height-caption: 16px;
57
+ --cb-letter-spacing-caption: 0em;
58
+
59
+ /* Radius */
60
+ --cb-radius-base: 6px;
61
+ --cb-radius-sm: calc(var(--cb-radius-base) * 1);
62
+ --cb-radius-md: calc(var(--cb-radius-base) * 2);
63
+ --cb-radius-lg: calc(var(--cb-radius-base) * 3);
64
+
65
+ /* Shadow */
66
+ --cb-shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
67
+ --cb-shadow-md:
68
+ 0 4px 16px -2px rgb(0 0 0 / 0.08), 0 2px 4px -1px rgb(0 0 0 / 0.08);
69
+ --cb-shadow-lg:
70
+ 0 12px 32px -4px rgb(0 0 0 / 0.08), 0 4px 8px -2px rgb(0 0 0 / 0.08);
71
+
72
+ /* Sizes */
73
+ --cb-size-banner-max-width: 448px;
74
+ --cb-size-settings-max-height: 448px;
75
+ }
76
+
77
+ @media (prefers-color-scheme: dark) {
78
+ :root {
79
+ --cb-color-neutral-0: rgb(10, 10, 10);
80
+ --cb-color-neutral-50: rgb(23, 23, 23);
81
+ --cb-color-neutral-100: rgb(38, 38, 38);
82
+ --cb-color-neutral-200: rgb(64, 64, 64);
83
+ --cb-color-neutral-300: rgb(82, 82, 82);
84
+ --cb-color-neutral-400: rgb(115, 115, 115);
85
+ --cb-color-neutral-500: rgb(163, 163, 163);
86
+ --cb-color-neutral-600: rgb(212, 212, 212);
87
+ --cb-color-neutral-700: rgb(229, 229, 229);
88
+ --cb-color-neutral-800: rgb(245, 245, 245);
89
+ --cb-color-neutral-900: rgb(250, 250, 250);
90
+ --cb-color-neutral-950: rgb(255, 255, 255);
91
+
92
+ --cb-color-brand-50: rgb(15, 41, 30);
93
+ --cb-color-brand-100: rgb(17, 49, 35);
94
+ --cb-color-brand-200: rgb(19, 57, 41);
95
+ --cb-color-brand-300: rgb(22, 68, 48);
96
+ --cb-color-brand-400: rgb(27, 84, 58);
97
+ --cb-color-brand-500: rgb(35, 110, 74);
98
+ --cb-color-brand-600: rgb(48, 164, 108);
99
+ --cb-color-brand-700: rgb(60, 177, 121);
100
+ --cb-color-brand-800: rgb(76, 195, 138);
101
+ --cb-color-brand-900: rgb(229, 251, 235);
102
+ }
103
+ }
104
+ ```
105
+
106
+ ## React component
107
+
108
+ Install
109
+
110
+ ```bash
111
+ npm install @uninspired/cookie-banner
112
+ ```
113
+
114
+ Use
115
+
116
+ ```tsx
117
+ import "@uninspired/cookie-banner/react/style.css";
118
+ import "@uninspired/cookie-banner/react/theme.css";
119
+ import { Banner } from "@uninspired/cookie-banner/react";
120
+
121
+ function App() {
122
+ return <Banner noTarget items={[]} />;
123
+ }
124
+ ```
125
+
126
+ ## Embed script
127
+
128
+ Add this to the document head:
129
+
130
+ ```html
131
+ <link
132
+ rel="stylesheet"
133
+ href="https://esm.sh/@uninspired/cookie-banner/script/theme.css"
134
+ />
135
+ <link
136
+ rel="stylesheet"
137
+ href="https://esm.sh/@uninspired/cookie-banner/script/style.css"
138
+ />
139
+ ```
140
+
141
+ Add this to the end of the document body:
142
+
143
+ ```html
144
+ <script type="module" async defer>
145
+ import { mountBanner } from "https://esm.sh/@uninspired/cookie-banner/script/index.js";
146
+ mountBanner({
147
+ cookie: {
148
+ domain: ".uninspired.studio",
149
+ sameSite: "strict",
150
+ secure: true,
151
+ },
152
+ items: [
153
+ {
154
+ value: "functional",
155
+ label: "Functional",
156
+ sublabel: "The site would break if you disabled these.",
157
+ required: true,
158
+ description: `<b>Authentication</b><br/>
159
+ <p>Keeps you logged into your account across sessions. These cookies are essential for the app to work correctly and cannot be disabled.</p>
160
+ <b>Payments</b><br/>
161
+ <p>Required to process purchases and manage your subscription. Used by Paddle to handle transactions, tax calculation, and order management. These cannot be disabled as they're essential to completing and maintaining purchases.</p><b>Referral Tracking</b><br/>
162
+ <p>Ensures visits and sign-ups via our referral program are attributed correctly. Used by Tolt to credit partners or affiliates when you arrive through a referral link.</p>`,
163
+ scripts: [],
164
+ },
165
+ {
166
+ value: "analytics",
167
+ label: "Analytics",
168
+ sublabel: "Help us make our products better.",
169
+ defaultSelected: true,
170
+ description: `<b>Web & Product Analytics</b><br/>
171
+ <p>Helps us understand how visitors navigate the site and how customers interact with the product — including page views, feature usage, and session flows. Used by PostHog to improve the experience and inform what gets built next.</p>
172
+ <b>Error Tracking</b><br/>
173
+ <p>Captures technical errors and crashes to help us diagnose and resolve bugs quickly. Used by PostHog to collect error context without storing personally identifiable information.</p>`,
174
+ scripts: [
175
+ {
176
+ id: "web-analytics",
177
+ variant: "inline",
178
+ type: "text/javascript",
179
+ content: `!function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.async=!0,p.src=s.api_host.replace(".i.posthog.com","-assets.i.posthog.com")+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="init capture register register_once register_for_session unregister opt_out_capturing has_opted_out_capturing opt_in_capturing reset isFeatureEnabled getFeatureFlag getFeatureFlagPayload reloadFeatureFlags group identify setPersonProperties setPersonPropertiesForFlags resetPersonPropertiesForFlags setGroupPropertiesForFlags resetGroupPropertiesForFlags resetGroups onFeatureFlags addFeatureFlagsHandler onSessionId getSurveys getActiveMatchingSurveys renderSurvey canRenderSurvey getNextSurveyStep".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);
180
+ posthog.init('phc_hHdoTl2tu6OCEGksFIpD3PYmE8jVIeVOkwe97ebNQAa', {
181
+ api_host: 'https://eu.i.posthog.com',
182
+ defaults: '2026-01-30'
183
+ })`,
184
+ },
185
+ ],
186
+ },
187
+ {
188
+ value: "marketing",
189
+ label: "Marketing",
190
+ defaultSelected: true,
191
+ sublabel: "Help us measure the effectiveness of our marketing.",
192
+ description: `<b>Conversion Tracking</b><br/>
193
+ <p>Tracks actions taken after interacting with our ads, such as visiting a page or starting a trial. Used by Meta Pixel to measure campaign effectiveness and avoid spending budget on underperforming ads.</p>`,
194
+ scripts: [
195
+ {
196
+ id: "log",
197
+ variant: "inline",
198
+ type: "text/javascript",
199
+ content: "console.log('marketing');",
200
+ },
201
+ ],
202
+ },
203
+ ],
204
+ });
205
+ </script>
206
+ ```
@@ -1951,6 +1951,7 @@ function optional(innerType) {
1951
1951
  });
1952
1952
  }
1953
1953
  const remoteScriptDefinitionSchema = /* @__PURE__ */ object({
1954
+ id: /* @__PURE__ */ string(),
1954
1955
  variant: /* @__PURE__ */ literal("remote"),
1955
1956
  type: /* @__PURE__ */ optional(/* @__PURE__ */ string()),
1956
1957
  src: /* @__PURE__ */ string(),
@@ -1960,6 +1961,7 @@ const remoteScriptDefinitionSchema = /* @__PURE__ */ object({
1960
1961
  integrity: /* @__PURE__ */ optional(/* @__PURE__ */ string())
1961
1962
  });
1962
1963
  const inlineScriptDefinitionSchema = /* @__PURE__ */ object({
1964
+ id: /* @__PURE__ */ string(),
1963
1965
  variant: /* @__PURE__ */ literal("inline"),
1964
1966
  type: /* @__PURE__ */ optional(/* @__PURE__ */ string()),
1965
1967
  async: /* @__PURE__ */ optional(/* @__PURE__ */ boolean()),
@@ -1984,14 +1986,59 @@ const Switch = ({ label: label2, id, ...rest }) => {
1984
1986
  ] });
1985
1987
  };
1986
1988
  const selectionSchema = /* @__PURE__ */ record(/* @__PURE__ */ string(), /* @__PURE__ */ boolean());
1989
+ class Cookies {
1990
+ #domain;
1991
+ #prefix;
1992
+ #sameSite;
1993
+ #secure;
1994
+ constructor(options) {
1995
+ this.#domain = options.domain;
1996
+ this.#prefix = options.prefix ?? "us-cookie-banner-";
1997
+ this.#sameSite = options.sameSite ?? "lax";
1998
+ this.#secure = options.secure ?? true;
1999
+ }
2000
+ #serialize = (data) => {
2001
+ return btoa(String.fromCharCode(...new TextEncoder().encode(data)));
2002
+ };
2003
+ #deserialize = (data) => {
2004
+ return new TextDecoder().decode(
2005
+ Uint8Array.from(atob(data), (c) => c.charCodeAt(0))
2006
+ );
2007
+ };
2008
+ set = (key, value, ttl = 365) => {
2009
+ const expires = new Date(Date.now() + ttl * 24 * 60 * 60 * 1e3);
2010
+ const cookie = `${this.#prefix}${key}=${this.#serialize(value)}; expires=${expires}; path=/; domain=${this.#domain}; SameSite=${this.#sameSite}; ${this.#secure ? "secure" : ""}`;
2011
+ document.cookie = cookie;
2012
+ };
2013
+ get = (key) => {
2014
+ const match = document.cookie.match(
2015
+ new RegExp(`(?:^|; )${this.#prefix}${key}=([^;]*)`)
2016
+ );
2017
+ if (!match) return null;
2018
+ const [_, serializedValue] = match;
2019
+ if (!serializedValue) return null;
2020
+ return this.#deserialize(serializedValue);
2021
+ };
2022
+ remove = (key) => {
2023
+ this.set(key, "", -1);
2024
+ };
2025
+ }
2026
+ const SELECTION_KEY = "selection";
1987
2027
  const SelectionContext = require$$0.createContext(null);
1988
2028
  const SelectionProvider = ({
1989
2029
  children,
1990
2030
  items,
1991
- localStorageKey
2031
+ cookie
1992
2032
  }) => {
1993
- function getLsSelection(localStorageKey2) {
1994
- const storedSelection = localStorage.getItem(localStorageKey2);
2033
+ const { domain, prefix, sameSite, secure } = cookie;
2034
+ const [cookies, setCookies] = require$$0.useState(
2035
+ new Cookies({ domain, prefix, sameSite, secure })
2036
+ );
2037
+ require$$0.useEffect(() => {
2038
+ setCookies(new Cookies({ domain, prefix, sameSite, secure }));
2039
+ }, [domain, prefix, sameSite, secure]);
2040
+ function getCookieSelection() {
2041
+ const storedSelection = cookies.get(SELECTION_KEY);
1995
2042
  if (!storedSelection) return null;
1996
2043
  const { success, data } = selectionSchema.safeParse(
1997
2044
  JSON.parse(storedSelection)
@@ -2006,10 +2053,10 @@ const SelectionProvider = ({
2006
2053
  [items]
2007
2054
  );
2008
2055
  const [selection, setSelection] = require$$0.useState(
2009
- getLsSelection(localStorageKey) ?? defaultSelection
2056
+ getCookieSelection() ?? defaultSelection
2010
2057
  );
2011
2058
  const [savedSelection, setSavedSelection] = require$$0.useState(
2012
- getLsSelection(localStorageKey)
2059
+ getCookieSelection()
2013
2060
  );
2014
2061
  function toggleSelection(key, value) {
2015
2062
  const newSelection = selection ? { ...selection, [key]: value } : { [key]: value };
@@ -2024,47 +2071,51 @@ const SelectionProvider = ({
2024
2071
  (item) => selectedValues.includes(item.value)
2025
2072
  );
2026
2073
  for (const item of items) {
2027
- const elem = document.head.querySelector(`#${item.value}`);
2028
- if (!elem) continue;
2029
- elem.remove();
2074
+ if (!item.scripts) continue;
2075
+ for (const script of item.scripts) {
2076
+ const elem = document.head.querySelector(`#${item.value}-${script.id}`);
2077
+ if (!elem) continue;
2078
+ elem.remove();
2079
+ }
2030
2080
  }
2031
2081
  for (const item of mountedItems) {
2032
- const elem = document.createElement("script");
2033
- elem.id = item.value;
2034
- if (!item.script) {
2082
+ if (!item.scripts) {
2035
2083
  if (!item.required)
2036
2084
  console.warn("CookieBanner: Missing script for", item.value);
2037
2085
  continue;
2038
2086
  }
2039
- const { success, data: script } = scriptDefinitionSchema.safeParse(
2040
- item.script
2041
- );
2042
- if (!success) {
2043
- console.error(
2044
- "CookieBanner: Invalid script definition for",
2045
- item.value
2046
- );
2047
- continue;
2087
+ for (const script of item.scripts) {
2088
+ if (!script) continue;
2089
+ const elem = document.createElement("script");
2090
+ elem.id = `${item.value}-${script.id}`;
2091
+ const { success, data } = scriptDefinitionSchema.safeParse(script);
2092
+ if (!success) {
2093
+ console.error(
2094
+ "CookieBanner: Invalid script definition for",
2095
+ item.value
2096
+ );
2097
+ continue;
2098
+ }
2099
+ elem.type = data.type ?? "text/javascript";
2100
+ elem.async = data.async ?? false;
2101
+ elem.defer = data.defer ?? false;
2102
+ switch (data.variant) {
2103
+ case "inline":
2104
+ elem.textContent = data.content;
2105
+ break;
2106
+ case "remote":
2107
+ elem.src = data.src;
2108
+ elem.crossOrigin = data.crossorigin ?? null;
2109
+ elem.integrity = data.integrity ?? "";
2110
+ break;
2111
+ }
2112
+ document.head.appendChild(elem);
2048
2113
  }
2049
- elem.type = script.type ?? "text/javascript";
2050
- elem.async = script.async ?? false;
2051
- elem.defer = script.defer ?? false;
2052
- switch (script.variant) {
2053
- case "inline":
2054
- elem.textContent = script.content;
2055
- break;
2056
- case "remote":
2057
- elem.src = script.src;
2058
- elem.crossOrigin = script.crossorigin ?? null;
2059
- elem.integrity = script.integrity ?? "";
2060
- break;
2061
- }
2062
- document.head.appendChild(elem);
2063
2114
  }
2064
2115
  }, [savedSelection, items]);
2065
2116
  function saveSelection(newSelection) {
2066
2117
  setSavedSelection(newSelection);
2067
- localStorage.setItem(localStorageKey, JSON.stringify(newSelection));
2118
+ cookies.set(SELECTION_KEY, JSON.stringify(newSelection));
2068
2119
  }
2069
2120
  const onDeclineAll = require$$0.useCallback(() => {
2070
2121
  const newSelection = Object.fromEntries(
@@ -2167,7 +2218,7 @@ const BannerItem = ({
2167
2218
  ] });
2168
2219
  };
2169
2220
  const BannerContent = ({
2170
- noTarget: noTarget2 = true,
2221
+ container,
2171
2222
  heading: heading2 = "We use cookies.",
2172
2223
  subheading = "Please define your selection below.",
2173
2224
  selectLabel = "Select",
@@ -2181,12 +2232,12 @@ const BannerContent = ({
2181
2232
  const { onSave, onDeclineAll, selectionTaken } = useSelection();
2182
2233
  const [openItem, setOpenItem] = require$$0.useState(void 0);
2183
2234
  const [settingsOpen, setSettingsOpen] = require$$0.useState(defaultSettingsOpen);
2184
- return /* @__PURE__ */ jsxRuntimeExports.jsx(reactDialog.Root, { open: !selectionTaken, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
2235
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(reactDialog.Root, { open: !selectionTaken, children: /* @__PURE__ */ jsxRuntimeExports.jsx(reactDialog.Portal, { container, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
2185
2236
  reactDialog.Content,
2186
2237
  {
2187
2238
  className: clx({
2188
2239
  [classes$2.root]: true,
2189
- [classes$2.noTarget]: noTarget2
2240
+ [classes$2.noTarget]: !container
2190
2241
  }),
2191
2242
  children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
2192
2243
  reactCollapsible.Root,
@@ -2244,22 +2295,18 @@ const BannerContent = ({
2244
2295
  }
2245
2296
  )
2246
2297
  }
2247
- ) });
2298
+ ) }) });
2248
2299
  };
2249
- const Banner = ({
2250
- localStorageKey = "cb-selection",
2251
- items,
2252
- ...rest
2253
- }) => {
2300
+ const Banner = ({ cookie, items, ...rest }) => {
2254
2301
  const selectionItems = require$$0.useMemo(
2255
2302
  () => items.filter((item) => !item.required).map((item) => ({
2256
2303
  value: item.value,
2257
- script: item.script,
2304
+ scripts: item.scripts,
2258
2305
  defaultSelected: item.defaultSelected,
2259
2306
  required: item.required
2260
2307
  })),
2261
2308
  [items]
2262
2309
  );
2263
- return /* @__PURE__ */ jsxRuntimeExports.jsx(SelectionProvider, { items: selectionItems, localStorageKey, children: /* @__PURE__ */ jsxRuntimeExports.jsx(BannerContent, { items, ...rest }) });
2310
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(SelectionProvider, { items: selectionItems, cookie, children: /* @__PURE__ */ jsxRuntimeExports.jsx(BannerContent, { items, cookie, ...rest }) });
2264
2311
  };
2265
2312
  exports.Banner = Banner;
@@ -1,31 +1,26 @@
1
1
  import { JSX as JSX_2 } from 'react/jsx-runtime';
2
2
  import * as z from 'zod/mini';
3
3
 
4
- export declare const Banner: ({ localStorageKey, items, ...rest }: BannerProps) => JSX_2.Element;
4
+ export declare const Banner: ({ cookie, items, ...rest }: BannerProps) => JSX_2.Element;
5
5
 
6
- declare type BannerItemOptions = BannerItemOptionsRequired | BannerItemOptionsOptional;
7
-
8
- declare interface BannerItemOptionsBase {
6
+ declare interface BannerItemOptions {
9
7
  value: string;
10
8
  label: string;
11
9
  defaultSelected?: boolean;
12
10
  sublabel?: string;
13
11
  required?: boolean;
14
12
  description?: string;
15
- }
16
-
17
- declare interface BannerItemOptionsOptional extends BannerItemOptionsBase {
18
- required: false;
19
- script: ScriptDefinition;
20
- }
21
-
22
- declare interface BannerItemOptionsRequired extends BannerItemOptionsBase {
23
- required: true;
24
- script: undefined;
13
+ scripts: ScriptDefinition[];
25
14
  }
26
15
 
27
16
  declare interface BannerOptions {
28
- localStorageKey?: string;
17
+ container?: HTMLElement;
18
+ cookie: {
19
+ domain: string;
20
+ prefix?: string;
21
+ sameSite?: "lax" | "strict" | "none";
22
+ secure?: boolean;
23
+ };
29
24
  heading?: string;
30
25
  subheading?: string;
31
26
  selectLabel?: string;
@@ -41,12 +36,12 @@ declare interface BannerOptions {
41
36
  }
42
37
 
43
38
  export declare interface BannerProps extends BannerOptions {
44
- noTarget?: boolean;
45
39
  }
46
40
 
47
41
  declare type ScriptDefinition = z.infer<typeof scriptDefinitionSchema>;
48
42
 
49
43
  declare const scriptDefinitionSchema: z.ZodMiniDiscriminatedUnion<[z.ZodMiniObject<{
44
+ id: z.ZodMiniString<string>;
50
45
  variant: z.ZodMiniLiteral<"remote">;
51
46
  type: z.ZodMiniOptional<z.ZodMiniString<string>>;
52
47
  src: z.ZodMiniString<string>;
@@ -55,6 +50,7 @@ declare const scriptDefinitionSchema: z.ZodMiniDiscriminatedUnion<[z.ZodMiniObje
55
50
  crossorigin: z.ZodMiniOptional<z.ZodMiniString<string>>;
56
51
  integrity: z.ZodMiniOptional<z.ZodMiniString<string>>;
57
52
  }, z.core.$strip>, z.ZodMiniObject<{
53
+ id: z.ZodMiniString<string>;
58
54
  variant: z.ZodMiniLiteral<"inline">;
59
55
  type: z.ZodMiniOptional<z.ZodMiniString<string>>;
60
56
  async: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;