brand-shell 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +316 -0
- package/dist/brand-shell.schema.json +89 -0
- package/dist/default.css +644 -0
- package/dist/index.d.mts +93 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +280 -0
- package/dist/index.mjs.map +1 -0
- package/dist/svelte.d.mts +14 -0
- package/dist/svelte.d.mts.map +1 -0
- package/dist/svelte.mjs +29 -0
- package/dist/svelte.mjs.map +1 -0
- package/dist/types-PQziYg7Z.d.mts +81 -0
- package/dist/types-PQziYg7Z.d.mts.map +1 -0
- package/dist/validation-xdqzwr3p.mjs +430 -0
- package/dist/validation-xdqzwr3p.mjs.map +1 -0
- package/dist/vue.d.mts +81 -0
- package/dist/vue.d.mts.map +1 -0
- package/dist/vue.mjs +62 -0
- package/dist/vue.mjs.map +1 -0
- package/dist/web.d.mts +61 -0
- package/dist/web.d.mts.map +1 -0
- package/dist/web.mjs +328 -0
- package/dist/web.mjs.map +1 -0
- package/package.json +112 -0
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
//#region src/core/social.ts
|
|
2
|
+
function detailsToSocialLinks(details) {
|
|
3
|
+
const links = [];
|
|
4
|
+
if (details.website) links.push({
|
|
5
|
+
platform: "website",
|
|
6
|
+
href: details.website,
|
|
7
|
+
label: "Website"
|
|
8
|
+
});
|
|
9
|
+
if (details.linkedin) links.push({
|
|
10
|
+
platform: "linkedin",
|
|
11
|
+
href: details.linkedin,
|
|
12
|
+
label: "LinkedIn"
|
|
13
|
+
});
|
|
14
|
+
if (details.gmail) {
|
|
15
|
+
const mailHref = details.gmail.startsWith("mailto:") ? details.gmail : `mailto:${details.gmail}`;
|
|
16
|
+
links.push({
|
|
17
|
+
platform: "email",
|
|
18
|
+
href: mailHref,
|
|
19
|
+
label: "Email"
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
if (details.github) links.push({
|
|
23
|
+
platform: "github",
|
|
24
|
+
href: details.github,
|
|
25
|
+
label: "GitHub"
|
|
26
|
+
});
|
|
27
|
+
if (details.twitter) links.push({
|
|
28
|
+
platform: "twitter",
|
|
29
|
+
href: details.twitter,
|
|
30
|
+
label: "Twitter"
|
|
31
|
+
});
|
|
32
|
+
if (details.discord) links.push({
|
|
33
|
+
platform: "discord",
|
|
34
|
+
href: details.discord,
|
|
35
|
+
label: "Discord"
|
|
36
|
+
});
|
|
37
|
+
return links;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
//#endregion
|
|
41
|
+
//#region src/core/links.ts
|
|
42
|
+
const ABSOLUTE_SCHEME_PATTERN = /^([a-zA-Z][a-zA-Z\d+.-]*):/;
|
|
43
|
+
const UNSAFE_CHAR_PATTERN = /[\u0000-\u001f\u007f]/;
|
|
44
|
+
const ALLOWED_PROTOCOLS = new Set([
|
|
45
|
+
"http:",
|
|
46
|
+
"https:",
|
|
47
|
+
"mailto:",
|
|
48
|
+
"tel:"
|
|
49
|
+
]);
|
|
50
|
+
const REQUIRED_BLANK_REL_TOKENS = ["noopener", "noreferrer"];
|
|
51
|
+
function normalizeSafeHref(href) {
|
|
52
|
+
if (typeof href !== "string") return void 0;
|
|
53
|
+
const trimmed = href.trim();
|
|
54
|
+
if (trimmed.length === 0) return void 0;
|
|
55
|
+
if (UNSAFE_CHAR_PATTERN.test(trimmed)) return void 0;
|
|
56
|
+
if (trimmed.startsWith("//")) return void 0;
|
|
57
|
+
const schemeMatch = trimmed.match(ABSOLUTE_SCHEME_PATTERN);
|
|
58
|
+
if (!schemeMatch) return trimmed;
|
|
59
|
+
const protocol = `${schemeMatch[1]?.toLowerCase()}:`;
|
|
60
|
+
if (!ALLOWED_PROTOCOLS.has(protocol)) return;
|
|
61
|
+
return trimmed;
|
|
62
|
+
}
|
|
63
|
+
function normalizeRel(target, rel) {
|
|
64
|
+
const normalizedRel = typeof rel === "string" ? rel.trim() : "";
|
|
65
|
+
if (target !== "_blank") return normalizedRel.length > 0 ? normalizedRel : void 0;
|
|
66
|
+
const tokens = normalizedRel.length > 0 ? normalizedRel.split(/\s+/).filter(Boolean) : [];
|
|
67
|
+
const tokenSet = new Set(tokens.map((token) => token.toLowerCase()));
|
|
68
|
+
for (const requiredToken of REQUIRED_BLANK_REL_TOKENS) if (!tokenSet.has(requiredToken)) tokens.push(requiredToken);
|
|
69
|
+
return tokens.join(" ");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region src/core/shell.ts
|
|
74
|
+
function normalizeNavLinks(navLinks = []) {
|
|
75
|
+
return navLinks.flatMap((link) => {
|
|
76
|
+
const href = normalizeSafeHref(link.href);
|
|
77
|
+
if (!href) return [];
|
|
78
|
+
const { target, rel } = normalizeLinkTargetRel(link.target, link.rel);
|
|
79
|
+
return {
|
|
80
|
+
...link,
|
|
81
|
+
href,
|
|
82
|
+
ariaLabel: link.ariaLabel ?? link.label,
|
|
83
|
+
target,
|
|
84
|
+
rel
|
|
85
|
+
};
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
function normalizeBrandDetails(details) {
|
|
89
|
+
const normalizedPrimaryAction = normalizeAction(details.primaryAction);
|
|
90
|
+
const normalizedSecondaryAction = normalizeAction(details.secondaryAction);
|
|
91
|
+
return {
|
|
92
|
+
...details,
|
|
93
|
+
homeHref: normalizeSafeHref(details.homeHref),
|
|
94
|
+
gmail: normalizeGmailHref(details.gmail),
|
|
95
|
+
website: normalizeSafeHref(details.website),
|
|
96
|
+
linkedin: normalizeSafeHref(details.linkedin),
|
|
97
|
+
github: normalizeSafeHref(details.github),
|
|
98
|
+
twitter: normalizeSafeHref(details.twitter),
|
|
99
|
+
discord: normalizeSafeHref(details.discord),
|
|
100
|
+
navLinks: normalizeNavLinks(details.navLinks),
|
|
101
|
+
primaryAction: normalizedPrimaryAction,
|
|
102
|
+
secondaryAction: normalizedSecondaryAction
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function normalizeCtaLinks(primaryAction, secondaryAction) {
|
|
106
|
+
const normalizedPrimaryAction = normalizeAction(primaryAction);
|
|
107
|
+
const actions = [normalizeAction(secondaryAction), normalizedPrimaryAction].filter((action) => Boolean(action));
|
|
108
|
+
return actions.map((action, index) => {
|
|
109
|
+
const variant = action.variant ?? (action === normalizedPrimaryAction || index === actions.length - 1 ? "primary" : "secondary");
|
|
110
|
+
return {
|
|
111
|
+
...action,
|
|
112
|
+
variant
|
|
113
|
+
};
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
function buildShellViewModel(details) {
|
|
117
|
+
const normalizedDetails = normalizeBrandDetails(details);
|
|
118
|
+
return {
|
|
119
|
+
navLinks: normalizedDetails.navLinks,
|
|
120
|
+
ctaLinks: normalizeCtaLinks(normalizedDetails.primaryAction, normalizedDetails.secondaryAction),
|
|
121
|
+
socialLinks: detailsToSocialLinks(normalizedDetails)
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function normalizeGmailHref(gmail) {
|
|
125
|
+
if (typeof gmail !== "string") return void 0;
|
|
126
|
+
const trimmed = gmail.trim();
|
|
127
|
+
if (trimmed.length === 0) return void 0;
|
|
128
|
+
if (trimmed.toLowerCase().startsWith("mailto:")) {
|
|
129
|
+
const address = trimmed.slice(7).trim();
|
|
130
|
+
if (address.length === 0) return void 0;
|
|
131
|
+
return normalizeSafeHref(`mailto:${address}`);
|
|
132
|
+
}
|
|
133
|
+
return normalizeSafeHref(`mailto:${trimmed}`);
|
|
134
|
+
}
|
|
135
|
+
function normalizeAction(action) {
|
|
136
|
+
if (!action) return void 0;
|
|
137
|
+
const href = normalizeSafeHref(action.href);
|
|
138
|
+
if (!href) return void 0;
|
|
139
|
+
const { target, rel } = normalizeLinkTargetRel(action.target, action.rel);
|
|
140
|
+
return {
|
|
141
|
+
...action,
|
|
142
|
+
href,
|
|
143
|
+
target,
|
|
144
|
+
rel,
|
|
145
|
+
ariaLabel: action.ariaLabel ?? action.label
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function normalizeLinkTargetRel(target, rel) {
|
|
149
|
+
const normalizedTarget = target ?? "_self";
|
|
150
|
+
return {
|
|
151
|
+
target: normalizedTarget,
|
|
152
|
+
rel: normalizeRel(normalizedTarget, rel)
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
//#endregion
|
|
157
|
+
//#region src/core/dev.ts
|
|
158
|
+
function shouldValidateInDev() {
|
|
159
|
+
const nodeEnv = typeof process !== "undefined" ? process.env?.NODE_ENV : void 0;
|
|
160
|
+
if (typeof nodeEnv === "string") return nodeEnv !== "production";
|
|
161
|
+
const { env } = import.meta;
|
|
162
|
+
if (typeof env?.DEV === "boolean") return env.DEV;
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
//#endregion
|
|
167
|
+
//#region src/core/theme.ts
|
|
168
|
+
const THEME_VAR_PREFIX = "brand";
|
|
169
|
+
const DARK_TEXT = "#0f172a";
|
|
170
|
+
const LIGHT_TEXT = "#f8fafc";
|
|
171
|
+
function themeToCssVariables(theme) {
|
|
172
|
+
if (!theme) return {};
|
|
173
|
+
const style = {};
|
|
174
|
+
if (theme.primaryColor != null) style[`--${THEME_VAR_PREFIX}-primary`] = theme.primaryColor;
|
|
175
|
+
if (theme.backgroundColor != null) style[`--${THEME_VAR_PREFIX}-bg`] = theme.backgroundColor;
|
|
176
|
+
if (theme.textColor != null) style[`--${THEME_VAR_PREFIX}-text`] = theme.textColor;
|
|
177
|
+
if (theme.fontFamily != null) style[`--${THEME_VAR_PREFIX}-font`] = theme.fontFamily;
|
|
178
|
+
if (theme.linkColor != null) style[`--${THEME_VAR_PREFIX}-link`] = theme.linkColor;
|
|
179
|
+
if (theme.socialIconSize != null) style[`--${THEME_VAR_PREFIX}-social-size`] = theme.socialIconSize;
|
|
180
|
+
if (theme.buttonTextColor != null) style[`--${THEME_VAR_PREFIX}-button-text`] = theme.buttonTextColor;
|
|
181
|
+
else if (theme.primaryColor != null) {
|
|
182
|
+
const buttonTextColor = getAccessibleTextColor(theme.primaryColor);
|
|
183
|
+
if (buttonTextColor) style[`--${THEME_VAR_PREFIX}-button-text`] = buttonTextColor;
|
|
184
|
+
}
|
|
185
|
+
return style;
|
|
186
|
+
}
|
|
187
|
+
function getAccessibleTextColor(backgroundColor) {
|
|
188
|
+
const rgb = parseHexColor(backgroundColor);
|
|
189
|
+
if (!rgb) return void 0;
|
|
190
|
+
return contrastRatio(rgb, {
|
|
191
|
+
r: 15,
|
|
192
|
+
g: 23,
|
|
193
|
+
b: 42
|
|
194
|
+
}) > contrastRatio(rgb, {
|
|
195
|
+
r: 248,
|
|
196
|
+
g: 250,
|
|
197
|
+
b: 252
|
|
198
|
+
}) ? DARK_TEXT : LIGHT_TEXT;
|
|
199
|
+
}
|
|
200
|
+
function parseHexColor(color) {
|
|
201
|
+
const trimmed = color.trim();
|
|
202
|
+
const match = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(trimmed);
|
|
203
|
+
if (!match) return void 0;
|
|
204
|
+
const value = match[1];
|
|
205
|
+
if (value.length === 3) return {
|
|
206
|
+
r: Number.parseInt(value[0] + value[0], 16),
|
|
207
|
+
g: Number.parseInt(value[1] + value[1], 16),
|
|
208
|
+
b: Number.parseInt(value[2] + value[2], 16)
|
|
209
|
+
};
|
|
210
|
+
return {
|
|
211
|
+
r: Number.parseInt(value.slice(0, 2), 16),
|
|
212
|
+
g: Number.parseInt(value.slice(2, 4), 16),
|
|
213
|
+
b: Number.parseInt(value.slice(4, 6), 16)
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
function contrastRatio(first, second) {
|
|
217
|
+
const firstLuminance = relativeLuminance(first);
|
|
218
|
+
const secondLuminance = relativeLuminance(second);
|
|
219
|
+
const lighter = Math.max(firstLuminance, secondLuminance);
|
|
220
|
+
const darker = Math.min(firstLuminance, secondLuminance);
|
|
221
|
+
return (lighter + .05) / (darker + .05);
|
|
222
|
+
}
|
|
223
|
+
function relativeLuminance(color) {
|
|
224
|
+
const transform = (channel) => {
|
|
225
|
+
const normalized = channel / 255;
|
|
226
|
+
if (normalized <= .03928) return normalized / 12.92;
|
|
227
|
+
return ((normalized + .055) / 1.055) ** 2.4;
|
|
228
|
+
};
|
|
229
|
+
const r = transform(color.r);
|
|
230
|
+
const g = transform(color.g);
|
|
231
|
+
const b = transform(color.b);
|
|
232
|
+
return .2126 * r + .7152 * g + .0722 * b;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
//#endregion
|
|
236
|
+
//#region src/core/validation.ts
|
|
237
|
+
const LINK_TARGETS = new Set([
|
|
238
|
+
"_blank",
|
|
239
|
+
"_self",
|
|
240
|
+
"_parent",
|
|
241
|
+
"_top"
|
|
242
|
+
]);
|
|
243
|
+
const CTA_VARIANTS = new Set([
|
|
244
|
+
"primary",
|
|
245
|
+
"secondary",
|
|
246
|
+
"ghost"
|
|
247
|
+
]);
|
|
248
|
+
const CTA_LAYOUTS = new Set(["inline", "stacked"]);
|
|
249
|
+
const THEME_KEYS = new Set([
|
|
250
|
+
"primaryColor",
|
|
251
|
+
"backgroundColor",
|
|
252
|
+
"textColor",
|
|
253
|
+
"fontFamily",
|
|
254
|
+
"linkColor",
|
|
255
|
+
"socialIconSize",
|
|
256
|
+
"buttonTextColor",
|
|
257
|
+
"ctaLayout"
|
|
258
|
+
]);
|
|
259
|
+
var BrandShellValidationError = class extends Error {
|
|
260
|
+
constructor(context, errors) {
|
|
261
|
+
super(formatValidationErrors(context, errors));
|
|
262
|
+
this.name = "BrandShellValidationError";
|
|
263
|
+
this.context = context;
|
|
264
|
+
this.errors = errors;
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
function validateBrandDetails(details) {
|
|
268
|
+
const errors = [];
|
|
269
|
+
if (!isRecord(details)) {
|
|
270
|
+
errors.push("details must be an object.");
|
|
271
|
+
return {
|
|
272
|
+
valid: false,
|
|
273
|
+
errors,
|
|
274
|
+
normalized: null
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
validateRequiredString(details.name, "details.name", errors);
|
|
278
|
+
validateOptionalString(details.homeHref, "details.homeHref", errors);
|
|
279
|
+
validateSafeHref(details.homeHref, "details.homeHref", errors);
|
|
280
|
+
validateOptionalString(details.website, "details.website", errors);
|
|
281
|
+
validateSafeHref(details.website, "details.website", errors);
|
|
282
|
+
validateOptionalString(details.linkedin, "details.linkedin", errors);
|
|
283
|
+
validateSafeHref(details.linkedin, "details.linkedin", errors);
|
|
284
|
+
validateOptionalString(details.gmail, "details.gmail", errors);
|
|
285
|
+
validateGmail(details.gmail, "details.gmail", errors);
|
|
286
|
+
validateOptionalString(details.github, "details.github", errors);
|
|
287
|
+
validateSafeHref(details.github, "details.github", errors);
|
|
288
|
+
validateOptionalString(details.twitter, "details.twitter", errors);
|
|
289
|
+
validateSafeHref(details.twitter, "details.twitter", errors);
|
|
290
|
+
validateOptionalString(details.discord, "details.discord", errors);
|
|
291
|
+
validateSafeHref(details.discord, "details.discord", errors);
|
|
292
|
+
validateOptionalString(details.tagline, "details.tagline", errors);
|
|
293
|
+
if (details.navLinks != null) if (!Array.isArray(details.navLinks)) errors.push("details.navLinks must be an array.");
|
|
294
|
+
else details.navLinks.forEach((link, index) => validateNavLink(link, `details.navLinks[${index}]`, errors));
|
|
295
|
+
if (details.primaryAction != null) validateAction(details.primaryAction, "details.primaryAction", errors);
|
|
296
|
+
if (details.secondaryAction != null) validateAction(details.secondaryAction, "details.secondaryAction", errors);
|
|
297
|
+
if (errors.length > 0) return {
|
|
298
|
+
valid: false,
|
|
299
|
+
errors,
|
|
300
|
+
normalized: null
|
|
301
|
+
};
|
|
302
|
+
return {
|
|
303
|
+
valid: true,
|
|
304
|
+
errors: [],
|
|
305
|
+
normalized: normalizeBrandDetails(details)
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
function validateBrandTheme(theme) {
|
|
309
|
+
if (theme == null) return {
|
|
310
|
+
valid: true,
|
|
311
|
+
errors: [],
|
|
312
|
+
normalized: null
|
|
313
|
+
};
|
|
314
|
+
const errors = [];
|
|
315
|
+
if (!isRecord(theme)) {
|
|
316
|
+
errors.push("theme must be an object when provided.");
|
|
317
|
+
return {
|
|
318
|
+
valid: false,
|
|
319
|
+
errors,
|
|
320
|
+
normalized: null
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
for (const key of Object.keys(theme)) {
|
|
324
|
+
if (!THEME_KEYS.has(key)) {
|
|
325
|
+
errors.push(`theme.${key} is not a supported theme key.`);
|
|
326
|
+
continue;
|
|
327
|
+
}
|
|
328
|
+
if (key === "ctaLayout") {
|
|
329
|
+
validateCtaLayout(theme[key], "theme.ctaLayout", errors);
|
|
330
|
+
continue;
|
|
331
|
+
}
|
|
332
|
+
validateOptionalString(theme[key], `theme.${key}`, errors);
|
|
333
|
+
}
|
|
334
|
+
if (errors.length > 0) return {
|
|
335
|
+
valid: false,
|
|
336
|
+
errors,
|
|
337
|
+
normalized: null
|
|
338
|
+
};
|
|
339
|
+
return {
|
|
340
|
+
valid: true,
|
|
341
|
+
errors: [],
|
|
342
|
+
normalized: normalizeBrandTheme(theme)
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
function assertValidBrandDetails(details, context = "BrandDetails") {
|
|
346
|
+
const result = validateBrandDetails(details);
|
|
347
|
+
if (!result.valid) throw new BrandShellValidationError(context, result.errors);
|
|
348
|
+
}
|
|
349
|
+
function assertValidBrandTheme(theme, context = "BrandTheme") {
|
|
350
|
+
const result = validateBrandTheme(theme);
|
|
351
|
+
if (!result.valid) throw new BrandShellValidationError(context, result.errors);
|
|
352
|
+
}
|
|
353
|
+
function normalizeBrandTheme(theme) {
|
|
354
|
+
if (!theme) return null;
|
|
355
|
+
const normalized = {};
|
|
356
|
+
for (const key of THEME_KEYS) {
|
|
357
|
+
const value = theme[key];
|
|
358
|
+
if (key === "ctaLayout") {
|
|
359
|
+
if (typeof value === "string" && CTA_LAYOUTS.has(value)) normalized[key] = value;
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
362
|
+
if (typeof value === "string") {
|
|
363
|
+
const trimmed = value.trim();
|
|
364
|
+
if (trimmed.length > 0) normalized[key] = trimmed;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
return Object.keys(normalized).length > 0 ? normalized : null;
|
|
368
|
+
}
|
|
369
|
+
function formatValidationErrors(context, errors) {
|
|
370
|
+
return `${context} validation failed:\n${errors.map((error) => `- ${error}`).join("\n")}`;
|
|
371
|
+
}
|
|
372
|
+
function validateNavLink(link, path, errors) {
|
|
373
|
+
if (!isRecord(link)) {
|
|
374
|
+
errors.push(`${path} must be an object.`);
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
validateRequiredString(link.label, `${path}.label`, errors);
|
|
378
|
+
validateRequiredString(link.href, `${path}.href`, errors);
|
|
379
|
+
validateSafeHref(link.href, `${path}.href`, errors);
|
|
380
|
+
validateOptionalString(link.ariaLabel, `${path}.ariaLabel`, errors);
|
|
381
|
+
validateOptionalString(link.rel, `${path}.rel`, errors);
|
|
382
|
+
validateTarget(link.target, `${path}.target`, errors);
|
|
383
|
+
}
|
|
384
|
+
function validateAction(action, path, errors) {
|
|
385
|
+
if (!isRecord(action)) {
|
|
386
|
+
errors.push(`${path} must be an object.`);
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
validateRequiredString(action.label, `${path}.label`, errors);
|
|
390
|
+
validateRequiredString(action.href, `${path}.href`, errors);
|
|
391
|
+
validateSafeHref(action.href, `${path}.href`, errors);
|
|
392
|
+
validateOptionalString(action.ariaLabel, `${path}.ariaLabel`, errors);
|
|
393
|
+
validateOptionalString(action.rel, `${path}.rel`, errors);
|
|
394
|
+
validateTarget(action.target, `${path}.target`, errors);
|
|
395
|
+
if (action.variant != null) {
|
|
396
|
+
if (typeof action.variant !== "string" || !CTA_VARIANTS.has(action.variant)) errors.push(`${path}.variant must be one of: primary, secondary, ghost.`);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
function validateTarget(target, path, errors) {
|
|
400
|
+
if (target == null) return;
|
|
401
|
+
if (typeof target !== "string" || !LINK_TARGETS.has(target)) errors.push(`${path} must be one of: _blank, _self, _parent, _top.`);
|
|
402
|
+
}
|
|
403
|
+
function validateCtaLayout(value, path, errors) {
|
|
404
|
+
if (value == null) return;
|
|
405
|
+
if (typeof value !== "string" || !CTA_LAYOUTS.has(value)) errors.push(`${path} must be one of: inline, stacked.`);
|
|
406
|
+
}
|
|
407
|
+
function validateRequiredString(value, path, errors) {
|
|
408
|
+
if (typeof value !== "string" || value.trim().length === 0) errors.push(`${path} must be a non-empty string.`);
|
|
409
|
+
}
|
|
410
|
+
function validateOptionalString(value, path, errors) {
|
|
411
|
+
if (value == null) return;
|
|
412
|
+
if (typeof value !== "string" || value.trim().length === 0) errors.push(`${path} must be a non-empty string when provided.`);
|
|
413
|
+
}
|
|
414
|
+
function validateSafeHref(value, path, errors) {
|
|
415
|
+
if (value == null) return;
|
|
416
|
+
if (typeof value !== "string" || value.trim().length === 0) return;
|
|
417
|
+
if (!normalizeSafeHref(value)) errors.push(`${path} must use a safe URL/path (http, https, mailto, tel, or relative path).`);
|
|
418
|
+
}
|
|
419
|
+
function validateGmail(value, path, errors) {
|
|
420
|
+
if (value == null) return;
|
|
421
|
+
if (typeof value !== "string" || value.trim().length === 0) return;
|
|
422
|
+
if (!normalizeGmailHref(value)) errors.push(`${path} must be a valid email or mailto URL.`);
|
|
423
|
+
}
|
|
424
|
+
function isRecord(value) {
|
|
425
|
+
return typeof value === "object" && value !== null;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
//#endregion
|
|
429
|
+
export { normalizeBrandTheme as a, themeToCssVariables as c, normalizeBrandDetails as d, normalizeCtaLinks as f, detailsToSocialLinks as h, formatValidationErrors as i, shouldValidateInDev as l, normalizeNavLinks as m, assertValidBrandDetails as n, validateBrandDetails as o, normalizeGmailHref as p, assertValidBrandTheme as r, validateBrandTheme as s, BrandShellValidationError as t, buildShellViewModel as u };
|
|
430
|
+
//# sourceMappingURL=validation-xdqzwr3p.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation-xdqzwr3p.mjs","names":[],"sources":["../src/core/social.ts","../src/core/links.ts","../src/core/shell.ts","../src/core/dev.ts","../src/core/theme.ts","../src/core/validation.ts"],"sourcesContent":["import type { BrandDetails } from \"./types\";\n\nexport type SocialPlatform = \"website\" | \"linkedin\" | \"email\" | \"github\" | \"twitter\" | \"discord\";\n\nexport interface SocialLink {\n platform: SocialPlatform;\n href: string;\n label: string;\n}\n\nexport function detailsToSocialLinks(details: BrandDetails): SocialLink[] {\n const links: SocialLink[] = [];\n if (details.website) links.push({ platform: \"website\", href: details.website, label: \"Website\" });\n if (details.linkedin) links.push({ platform: \"linkedin\", href: details.linkedin, label: \"LinkedIn\" });\n if (details.gmail) {\n const mailHref = details.gmail.startsWith(\"mailto:\") ? details.gmail : `mailto:${details.gmail}`;\n links.push({ platform: \"email\", href: mailHref, label: \"Email\" });\n }\n if (details.github) links.push({ platform: \"github\", href: details.github, label: \"GitHub\" });\n if (details.twitter) links.push({ platform: \"twitter\", href: details.twitter, label: \"Twitter\" });\n if (details.discord) links.push({ platform: \"discord\", href: details.discord, label: \"Discord\" });\n return links;\n}\n","const ABSOLUTE_SCHEME_PATTERN = /^([a-zA-Z][a-zA-Z\\d+.-]*):/;\nconst UNSAFE_CHAR_PATTERN = /[\\u0000-\\u001f\\u007f]/;\nconst ALLOWED_PROTOCOLS = new Set([\"http:\", \"https:\", \"mailto:\", \"tel:\"]);\nconst REQUIRED_BLANK_REL_TOKENS = [\"noopener\", \"noreferrer\"];\n\nexport function normalizeSafeHref(href: unknown): string | undefined {\n if (typeof href !== \"string\") return undefined;\n const trimmed = href.trim();\n if (trimmed.length === 0) return undefined;\n if (UNSAFE_CHAR_PATTERN.test(trimmed)) return undefined;\n if (trimmed.startsWith(\"//\")) return undefined;\n\n const schemeMatch = trimmed.match(ABSOLUTE_SCHEME_PATTERN);\n if (!schemeMatch) {\n return trimmed;\n }\n\n const protocol = `${schemeMatch[1]?.toLowerCase()}:`;\n if (!ALLOWED_PROTOCOLS.has(protocol)) {\n return undefined;\n }\n\n return trimmed;\n}\n\nexport function isSafeHref(href: unknown): boolean {\n return normalizeSafeHref(href) != null;\n}\n\nexport function normalizeRel(target: \"_blank\" | \"_self\" | \"_parent\" | \"_top\", rel?: string): string | undefined {\n const normalizedRel = typeof rel === \"string\" ? rel.trim() : \"\";\n if (target !== \"_blank\") {\n return normalizedRel.length > 0 ? normalizedRel : undefined;\n }\n\n const tokens = normalizedRel.length > 0 ? normalizedRel.split(/\\s+/).filter(Boolean) : [];\n const tokenSet = new Set(tokens.map((token) => token.toLowerCase()));\n\n for (const requiredToken of REQUIRED_BLANK_REL_TOKENS) {\n if (!tokenSet.has(requiredToken)) {\n tokens.push(requiredToken);\n }\n }\n\n return tokens.join(\" \");\n}\n","import { detailsToSocialLinks, type SocialLink } from \"./social\";\nimport type { BrandAction, BrandDetails, BrandNavLink } from \"./types\";\nimport { normalizeRel, normalizeSafeHref } from \"./links\";\n\nexport type LinkTarget = NonNullable<BrandNavLink[\"target\"]>;\n\nexport interface ShellNavLink extends BrandNavLink {\n ariaLabel: string;\n rel?: string;\n target: LinkTarget;\n}\n\nexport interface ShellActionLink extends BrandAction {\n ariaLabel: string;\n rel?: string;\n target: LinkTarget;\n variant: NonNullable<BrandAction[\"variant\"]>;\n}\n\nexport interface ShellViewModel {\n navLinks: ShellNavLink[];\n ctaLinks: ShellActionLink[];\n socialLinks: SocialLink[];\n}\n\nexport type NormalizedActionLink = Omit<ShellActionLink, \"variant\"> & Pick<BrandAction, \"variant\">;\n\nexport interface NormalizedBrandDetails extends Omit<BrandDetails, \"navLinks\" | \"primaryAction\" | \"secondaryAction\"> {\n navLinks: ShellNavLink[];\n primaryAction?: NormalizedActionLink;\n secondaryAction?: NormalizedActionLink;\n}\n\nexport function normalizeNavLinks(navLinks: BrandNavLink[] = []): ShellNavLink[] {\n return navLinks.flatMap((link) => {\n const href = normalizeSafeHref(link.href);\n if (!href) return [];\n\n const { target, rel } = normalizeLinkTargetRel(link.target, link.rel);\n return {\n ...link,\n href,\n ariaLabel: link.ariaLabel ?? link.label,\n target,\n rel,\n };\n });\n}\n\nexport function normalizeBrandDetails(details: BrandDetails): NormalizedBrandDetails {\n const normalizedPrimaryAction = normalizeAction(details.primaryAction);\n const normalizedSecondaryAction = normalizeAction(details.secondaryAction);\n\n return {\n ...details,\n homeHref: normalizeSafeHref(details.homeHref),\n gmail: normalizeGmailHref(details.gmail),\n website: normalizeSafeHref(details.website),\n linkedin: normalizeSafeHref(details.linkedin),\n github: normalizeSafeHref(details.github),\n twitter: normalizeSafeHref(details.twitter),\n discord: normalizeSafeHref(details.discord),\n navLinks: normalizeNavLinks(details.navLinks),\n primaryAction: normalizedPrimaryAction,\n secondaryAction: normalizedSecondaryAction,\n };\n}\n\nexport function normalizeCtaLinks(\n primaryAction?: BrandAction,\n secondaryAction?: BrandAction,\n): ShellActionLink[] {\n const normalizedPrimaryAction = normalizeAction(primaryAction);\n const normalizedSecondaryAction = normalizeAction(secondaryAction);\n const actions = [normalizedSecondaryAction, normalizedPrimaryAction].filter(\n (action): action is NonNullable<typeof action> => Boolean(action),\n );\n\n return actions.map((action, index) => {\n const variant =\n action.variant ?? (action === normalizedPrimaryAction || index === actions.length - 1 ? \"primary\" : \"secondary\");\n\n return {\n ...action,\n variant,\n };\n });\n}\n\nexport function buildShellViewModel(details: BrandDetails): ShellViewModel {\n const normalizedDetails = normalizeBrandDetails(details);\n\n return {\n navLinks: normalizedDetails.navLinks,\n ctaLinks: normalizeCtaLinks(normalizedDetails.primaryAction, normalizedDetails.secondaryAction),\n socialLinks: detailsToSocialLinks(normalizedDetails),\n };\n}\n\nexport function normalizeGmailHref(gmail?: string): string | undefined {\n if (typeof gmail !== \"string\") return undefined;\n const trimmed = gmail.trim();\n if (trimmed.length === 0) return undefined;\n if (trimmed.toLowerCase().startsWith(\"mailto:\")) {\n const address = trimmed.slice(7).trim();\n if (address.length === 0) return undefined;\n return normalizeSafeHref(`mailto:${address}`);\n }\n return normalizeSafeHref(`mailto:${trimmed}`);\n}\n\nfunction normalizeAction(action?: BrandAction): NormalizedActionLink | undefined {\n if (!action) return undefined;\n\n const href = normalizeSafeHref(action.href);\n if (!href) return undefined;\n\n const { target, rel } = normalizeLinkTargetRel(action.target, action.rel);\n return {\n ...action,\n href,\n target,\n rel,\n ariaLabel: action.ariaLabel ?? action.label,\n };\n}\n\nexport function normalizeLinkTargetRel(target?: BrandNavLink[\"target\"], rel?: string) {\n const normalizedTarget: LinkTarget = target ?? \"_self\";\n const normalizedRel = normalizeRel(normalizedTarget, rel);\n return {\n target: normalizedTarget,\n rel: normalizedRel,\n };\n}\n","type ImportMetaEnv = {\n DEV?: boolean;\n MODE?: string;\n};\n\ntype ImportMetaLike = {\n env?: ImportMetaEnv;\n};\n\nexport function shouldValidateInDev(): boolean {\n const nodeEnv = typeof process !== \"undefined\" ? process.env?.NODE_ENV : undefined;\n if (typeof nodeEnv === \"string\") {\n return nodeEnv !== \"production\";\n }\n\n const { env } = import.meta as unknown as ImportMetaLike;\n if (typeof env?.DEV === \"boolean\") {\n return env.DEV;\n }\n\n return false;\n}\n","import type { BrandTheme } from \"./types\";\n\nconst THEME_VAR_PREFIX = \"brand\";\nconst DARK_TEXT = \"#0f172a\";\nconst LIGHT_TEXT = \"#f8fafc\";\n\nexport type ThemeVariables = Record<string, string>;\n\nexport function themeToCssVariables(theme?: BrandTheme | null): ThemeVariables {\n if (!theme) return {};\n const style: ThemeVariables = {};\n if (theme.primaryColor != null) style[`--${THEME_VAR_PREFIX}-primary`] = theme.primaryColor;\n if (theme.backgroundColor != null) style[`--${THEME_VAR_PREFIX}-bg`] = theme.backgroundColor;\n if (theme.textColor != null) style[`--${THEME_VAR_PREFIX}-text`] = theme.textColor;\n if (theme.fontFamily != null) style[`--${THEME_VAR_PREFIX}-font`] = theme.fontFamily;\n if (theme.linkColor != null) style[`--${THEME_VAR_PREFIX}-link`] = theme.linkColor;\n if (theme.socialIconSize != null) style[`--${THEME_VAR_PREFIX}-social-size`] = theme.socialIconSize;\n if (theme.buttonTextColor != null) {\n style[`--${THEME_VAR_PREFIX}-button-text`] = theme.buttonTextColor;\n } else if (theme.primaryColor != null) {\n const buttonTextColor = getAccessibleTextColor(theme.primaryColor);\n if (buttonTextColor) style[`--${THEME_VAR_PREFIX}-button-text`] = buttonTextColor;\n }\n return style;\n}\n\nfunction getAccessibleTextColor(backgroundColor: string): string | undefined {\n const rgb = parseHexColor(backgroundColor);\n if (!rgb) return undefined;\n\n const contrastWithDark = contrastRatio(rgb, { r: 15, g: 23, b: 42 });\n const contrastWithLight = contrastRatio(rgb, { r: 248, g: 250, b: 252 });\n\n return contrastWithDark > contrastWithLight ? DARK_TEXT : LIGHT_TEXT;\n}\n\nfunction parseHexColor(color: string): { r: number; g: number; b: number } | undefined {\n const trimmed = color.trim();\n const match = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(trimmed);\n if (!match) return undefined;\n\n const value = match[1];\n if (value.length === 3) {\n return {\n r: Number.parseInt(value[0] + value[0], 16),\n g: Number.parseInt(value[1] + value[1], 16),\n b: Number.parseInt(value[2] + value[2], 16),\n };\n }\n\n return {\n r: Number.parseInt(value.slice(0, 2), 16),\n g: Number.parseInt(value.slice(2, 4), 16),\n b: Number.parseInt(value.slice(4, 6), 16),\n };\n}\n\nfunction contrastRatio(\n first: { r: number; g: number; b: number },\n second: { r: number; g: number; b: number },\n): number {\n const firstLuminance = relativeLuminance(first);\n const secondLuminance = relativeLuminance(second);\n const lighter = Math.max(firstLuminance, secondLuminance);\n const darker = Math.min(firstLuminance, secondLuminance);\n return (lighter + 0.05) / (darker + 0.05);\n}\n\nfunction relativeLuminance(color: { r: number; g: number; b: number }): number {\n const transform = (channel: number) => {\n const normalized = channel / 255;\n if (normalized <= 0.03928) return normalized / 12.92;\n return ((normalized + 0.055) / 1.055) ** 2.4;\n };\n\n const r = transform(color.r);\n const g = transform(color.g);\n const b = transform(color.b);\n return 0.2126 * r + 0.7152 * g + 0.0722 * b;\n}\n","import { normalizeBrandDetails, normalizeGmailHref, type NormalizedBrandDetails } from \"./shell\";\nimport { normalizeSafeHref } from \"./links\";\nimport type { BrandAction, BrandDetails, BrandNavLink, BrandTheme } from \"./types\";\n\nconst LINK_TARGETS = new Set<NonNullable<BrandNavLink[\"target\"]>>([\"_blank\", \"_self\", \"_parent\", \"_top\"]);\nconst CTA_VARIANTS = new Set<NonNullable<BrandAction[\"variant\"]>>([\"primary\", \"secondary\", \"ghost\"]);\nconst CTA_LAYOUTS = new Set<NonNullable<BrandTheme[\"ctaLayout\"]>>([\"inline\", \"stacked\"]);\nconst THEME_KEYS = new Set<keyof BrandTheme>([\n \"primaryColor\",\n \"backgroundColor\",\n \"textColor\",\n \"fontFamily\",\n \"linkColor\",\n \"socialIconSize\",\n \"buttonTextColor\",\n \"ctaLayout\",\n]);\n\ntype ValidationErrorPath = string;\n\nexport interface BrandValidationResult<T> {\n valid: boolean;\n errors: string[];\n normalized: T | null;\n}\n\nexport class BrandShellValidationError extends Error {\n readonly context: string;\n readonly errors: string[];\n\n constructor(context: string, errors: string[]) {\n super(formatValidationErrors(context, errors));\n this.name = \"BrandShellValidationError\";\n this.context = context;\n this.errors = errors;\n }\n}\n\nexport function validateBrandDetails(details: unknown): BrandValidationResult<NormalizedBrandDetails> {\n const errors: string[] = [];\n\n if (!isRecord(details)) {\n errors.push(\"details must be an object.\");\n return { valid: false, errors, normalized: null };\n }\n\n validateRequiredString(details.name, \"details.name\", errors);\n validateOptionalString(details.homeHref, \"details.homeHref\", errors);\n validateSafeHref(details.homeHref, \"details.homeHref\", errors);\n validateOptionalString(details.website, \"details.website\", errors);\n validateSafeHref(details.website, \"details.website\", errors);\n validateOptionalString(details.linkedin, \"details.linkedin\", errors);\n validateSafeHref(details.linkedin, \"details.linkedin\", errors);\n validateOptionalString(details.gmail, \"details.gmail\", errors);\n validateGmail(details.gmail, \"details.gmail\", errors);\n validateOptionalString(details.github, \"details.github\", errors);\n validateSafeHref(details.github, \"details.github\", errors);\n validateOptionalString(details.twitter, \"details.twitter\", errors);\n validateSafeHref(details.twitter, \"details.twitter\", errors);\n validateOptionalString(details.discord, \"details.discord\", errors);\n validateSafeHref(details.discord, \"details.discord\", errors);\n validateOptionalString(details.tagline, \"details.tagline\", errors);\n\n if (details.navLinks != null) {\n if (!Array.isArray(details.navLinks)) {\n errors.push(\"details.navLinks must be an array.\");\n } else {\n details.navLinks.forEach((link, index) => validateNavLink(link, `details.navLinks[${index}]`, errors));\n }\n }\n\n if (details.primaryAction != null) {\n validateAction(details.primaryAction, \"details.primaryAction\", errors);\n }\n if (details.secondaryAction != null) {\n validateAction(details.secondaryAction, \"details.secondaryAction\", errors);\n }\n\n if (errors.length > 0) {\n return { valid: false, errors, normalized: null };\n }\n\n return {\n valid: true,\n errors: [],\n normalized: normalizeBrandDetails(details as unknown as BrandDetails),\n };\n}\n\nexport function validateBrandTheme(theme: unknown): BrandValidationResult<BrandTheme | null> {\n if (theme == null) {\n return {\n valid: true,\n errors: [],\n normalized: null,\n };\n }\n\n const errors: string[] = [];\n\n if (!isRecord(theme)) {\n errors.push(\"theme must be an object when provided.\");\n return { valid: false, errors, normalized: null };\n }\n\n for (const key of Object.keys(theme)) {\n if (!THEME_KEYS.has(key as keyof BrandTheme)) {\n errors.push(`theme.${key} is not a supported theme key.`);\n continue;\n }\n if (key === \"ctaLayout\") {\n validateCtaLayout(theme[key], \"theme.ctaLayout\", errors);\n continue;\n }\n validateOptionalString(theme[key], `theme.${key}`, errors);\n }\n\n if (errors.length > 0) {\n return { valid: false, errors, normalized: null };\n }\n\n return {\n valid: true,\n errors: [],\n normalized: normalizeBrandTheme(theme as BrandTheme),\n };\n}\n\nexport function assertValidBrandDetails(details: unknown, context = \"BrandDetails\"): asserts details is BrandDetails {\n const result = validateBrandDetails(details);\n if (!result.valid) {\n throw new BrandShellValidationError(context, result.errors);\n }\n}\n\nexport function assertValidBrandTheme(theme: unknown, context = \"BrandTheme\"): asserts theme is BrandTheme | null | undefined {\n const result = validateBrandTheme(theme);\n if (!result.valid) {\n throw new BrandShellValidationError(context, result.errors);\n }\n}\n\nexport function normalizeBrandTheme(theme?: BrandTheme | null): BrandTheme | null {\n if (!theme) return null;\n\n const normalized: BrandTheme = {};\n for (const key of THEME_KEYS) {\n const value = theme[key];\n if (key === \"ctaLayout\") {\n if (typeof value === \"string\" && CTA_LAYOUTS.has(value as NonNullable<BrandTheme[\"ctaLayout\"]>)) {\n normalized[key] = value as BrandTheme[\"ctaLayout\"];\n }\n continue;\n }\n\n if (typeof value === \"string\") {\n const trimmed = value.trim();\n if (trimmed.length > 0) {\n normalized[key] = trimmed;\n }\n }\n }\n\n return Object.keys(normalized).length > 0 ? normalized : null;\n}\n\nexport function formatValidationErrors(context: string, errors: string[]): string {\n return `${context} validation failed:\\n${errors.map((error) => `- ${error}`).join(\"\\n\")}`;\n}\n\nfunction validateNavLink(link: unknown, path: ValidationErrorPath, errors: string[]) {\n if (!isRecord(link)) {\n errors.push(`${path} must be an object.`);\n return;\n }\n\n validateRequiredString(link.label, `${path}.label`, errors);\n validateRequiredString(link.href, `${path}.href`, errors);\n validateSafeHref(link.href, `${path}.href`, errors);\n validateOptionalString(link.ariaLabel, `${path}.ariaLabel`, errors);\n validateOptionalString(link.rel, `${path}.rel`, errors);\n validateTarget(link.target, `${path}.target`, errors);\n}\n\nfunction validateAction(action: unknown, path: ValidationErrorPath, errors: string[]) {\n if (!isRecord(action)) {\n errors.push(`${path} must be an object.`);\n return;\n }\n\n validateRequiredString(action.label, `${path}.label`, errors);\n validateRequiredString(action.href, `${path}.href`, errors);\n validateSafeHref(action.href, `${path}.href`, errors);\n validateOptionalString(action.ariaLabel, `${path}.ariaLabel`, errors);\n validateOptionalString(action.rel, `${path}.rel`, errors);\n validateTarget(action.target, `${path}.target`, errors);\n\n if (action.variant != null) {\n if (typeof action.variant !== \"string\" || !CTA_VARIANTS.has(action.variant as NonNullable<BrandAction[\"variant\"]>)) {\n errors.push(`${path}.variant must be one of: primary, secondary, ghost.`);\n }\n }\n}\n\nfunction validateTarget(target: unknown, path: ValidationErrorPath, errors: string[]) {\n if (target == null) return;\n if (typeof target !== \"string\" || !LINK_TARGETS.has(target as NonNullable<BrandNavLink[\"target\"]>)) {\n errors.push(`${path} must be one of: _blank, _self, _parent, _top.`);\n }\n}\n\nfunction validateCtaLayout(value: unknown, path: ValidationErrorPath, errors: string[]) {\n if (value == null) return;\n if (typeof value !== \"string\" || !CTA_LAYOUTS.has(value as NonNullable<BrandTheme[\"ctaLayout\"]>)) {\n errors.push(`${path} must be one of: inline, stacked.`);\n }\n}\n\nfunction validateRequiredString(value: unknown, path: ValidationErrorPath, errors: string[]) {\n if (typeof value !== \"string\" || value.trim().length === 0) {\n errors.push(`${path} must be a non-empty string.`);\n }\n}\n\nfunction validateOptionalString(value: unknown, path: ValidationErrorPath, errors: string[]) {\n if (value == null) return;\n if (typeof value !== \"string\" || value.trim().length === 0) {\n errors.push(`${path} must be a non-empty string when provided.`);\n }\n}\n\nfunction validateSafeHref(value: unknown, path: ValidationErrorPath, errors: string[]) {\n if (value == null) return;\n if (typeof value !== \"string\" || value.trim().length === 0) return;\n if (!normalizeSafeHref(value)) {\n errors.push(`${path} must use a safe URL/path (http, https, mailto, tel, or relative path).`);\n }\n}\n\nfunction validateGmail(value: unknown, path: ValidationErrorPath, errors: string[]) {\n if (value == null) return;\n if (typeof value !== \"string\" || value.trim().length === 0) return;\n if (!normalizeGmailHref(value)) {\n errors.push(`${path} must be a valid email or mailto URL.`);\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n"],"mappings":"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"}
|
package/dist/vue.d.mts
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { i as BrandTheme, n as BrandDetails } from "./types-PQziYg7Z.mjs";
|
|
2
|
+
import * as vue from "vue";
|
|
3
|
+
import { PropType } from "vue";
|
|
4
|
+
|
|
5
|
+
//#region src/vue/index.d.ts
|
|
6
|
+
interface BrandShellVueProps {
|
|
7
|
+
details: BrandDetails;
|
|
8
|
+
theme?: BrandTheme | null;
|
|
9
|
+
shellClass?: string | null;
|
|
10
|
+
}
|
|
11
|
+
declare const BrandHeader: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
12
|
+
details: {
|
|
13
|
+
type: PropType<BrandDetails>;
|
|
14
|
+
required: true;
|
|
15
|
+
};
|
|
16
|
+
theme: {
|
|
17
|
+
type: PropType<BrandTheme | null>;
|
|
18
|
+
default: null;
|
|
19
|
+
};
|
|
20
|
+
shellClass: {
|
|
21
|
+
type: PropType<string | null>;
|
|
22
|
+
default: null;
|
|
23
|
+
};
|
|
24
|
+
}>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
|
|
25
|
+
[key: string]: any;
|
|
26
|
+
}>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
|
|
27
|
+
details: {
|
|
28
|
+
type: PropType<BrandDetails>;
|
|
29
|
+
required: true;
|
|
30
|
+
};
|
|
31
|
+
theme: {
|
|
32
|
+
type: PropType<BrandTheme | null>;
|
|
33
|
+
default: null;
|
|
34
|
+
};
|
|
35
|
+
shellClass: {
|
|
36
|
+
type: PropType<string | null>;
|
|
37
|
+
default: null;
|
|
38
|
+
};
|
|
39
|
+
}>> & Readonly<{}>, {
|
|
40
|
+
theme: BrandTheme | null;
|
|
41
|
+
shellClass: string | null;
|
|
42
|
+
}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
|
|
43
|
+
declare const BrandFooter: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
44
|
+
details: {
|
|
45
|
+
type: PropType<BrandDetails>;
|
|
46
|
+
required: true;
|
|
47
|
+
};
|
|
48
|
+
theme: {
|
|
49
|
+
type: PropType<BrandTheme | null>;
|
|
50
|
+
default: null;
|
|
51
|
+
};
|
|
52
|
+
shellClass: {
|
|
53
|
+
type: PropType<string | null>;
|
|
54
|
+
default: null;
|
|
55
|
+
};
|
|
56
|
+
}>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
|
|
57
|
+
[key: string]: any;
|
|
58
|
+
}>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
|
|
59
|
+
details: {
|
|
60
|
+
type: PropType<BrandDetails>;
|
|
61
|
+
required: true;
|
|
62
|
+
};
|
|
63
|
+
theme: {
|
|
64
|
+
type: PropType<BrandTheme | null>;
|
|
65
|
+
default: null;
|
|
66
|
+
};
|
|
67
|
+
shellClass: {
|
|
68
|
+
type: PropType<string | null>;
|
|
69
|
+
default: null;
|
|
70
|
+
};
|
|
71
|
+
}>> & Readonly<{}>, {
|
|
72
|
+
theme: BrandTheme | null;
|
|
73
|
+
shellClass: string | null;
|
|
74
|
+
}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
|
|
75
|
+
declare function registerBrandShellVueElements(): {
|
|
76
|
+
headerTagName: string;
|
|
77
|
+
footerTagName: string;
|
|
78
|
+
};
|
|
79
|
+
//#endregion
|
|
80
|
+
export { type BrandDetails, BrandFooter, BrandHeader, BrandShellVueProps, type BrandTheme, registerBrandShellVueElements };
|
|
81
|
+
//# sourceMappingURL=vue.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vue.d.mts","names":[],"sources":["../src/vue/index.ts"],"mappings":";;;;;UAQiB,kBAAA;EACf,OAAA,EAAS,YAAA;EACT,KAAA,GAAQ,UAAA;EACR,UAAA;AAAA;AAAA,cAmEW,WAAA,MAAW,eAAA,CA1CQ,GAAA,CA0CR,gBAAA;;UAlDA,QAAA,CAAS,YAAA;;;;UAIT,QAAA,CAAS,UAAA;;;;UAIT,QAAA;;;oBA0CA,GAAA,CAAA,YAAA;;4GA1CQ,GAAA,CAAA,gBAAA;;UARR,QAAA,CAAS,YAAA;;;;UAIT,QAAA,CAAS,UAAA;;;;UAIT,QAAA;;;;;;;cA2CX,WAAA,MAAW,eAAA,CA3CQ,GAAA,CA2CR,gBAAA;;UAnDA,QAAA,CAAS,YAAA;;;;UAIT,QAAA,CAAS,UAAA;;;;UAIT,QAAA;;;oBA2CA,GAAA,CAAA,YAAA;;4GA3CQ,GAAA,CAAA,gBAAA;;UARR,QAAA,CAAS,YAAA;;;;UAIT,QAAA,CAAS,UAAA;;;;UAIT,QAAA;;;;;;;iBA6CR,6BAAA,CAAA;EAA6B,aAAA;EAAA,aAAA;AAAA"}
|
package/dist/vue.mjs
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { l as shouldValidateInDev, n as assertValidBrandDetails, r as assertValidBrandTheme } from "./validation-xdqzwr3p.mjs";
|
|
2
|
+
import { applyBrandShellProps, registerBrandShellElements } from "./web.mjs";
|
|
3
|
+
import { defineComponent, h, onMounted, ref, watch } from "vue";
|
|
4
|
+
|
|
5
|
+
//#region src/vue/index.ts
|
|
6
|
+
function ensureBrandShellElementsRegistered() {
|
|
7
|
+
if (typeof customElements !== "undefined") registerBrandShellElements();
|
|
8
|
+
}
|
|
9
|
+
function createBrandShellVueComponent(tagName, componentName) {
|
|
10
|
+
return defineComponent({
|
|
11
|
+
name: componentName,
|
|
12
|
+
props: {
|
|
13
|
+
details: {
|
|
14
|
+
type: Object,
|
|
15
|
+
required: true
|
|
16
|
+
},
|
|
17
|
+
theme: {
|
|
18
|
+
type: Object,
|
|
19
|
+
default: null
|
|
20
|
+
},
|
|
21
|
+
shellClass: {
|
|
22
|
+
type: String,
|
|
23
|
+
default: null
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
setup(props) {
|
|
27
|
+
ensureBrandShellElementsRegistered();
|
|
28
|
+
const elementRef = ref(null);
|
|
29
|
+
const syncProps = () => {
|
|
30
|
+
if (shouldValidateInDev()) {
|
|
31
|
+
assertValidBrandDetails(props.details, `brand-shell/vue ${componentName} details`);
|
|
32
|
+
assertValidBrandTheme(props.theme, `brand-shell/vue ${componentName} theme`);
|
|
33
|
+
}
|
|
34
|
+
applyBrandShellProps(elementRef.value, {
|
|
35
|
+
details: props.details,
|
|
36
|
+
theme: props.theme ?? null,
|
|
37
|
+
shellClass: props.shellClass ?? null
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
onMounted(() => {
|
|
41
|
+
syncProps();
|
|
42
|
+
});
|
|
43
|
+
watch(() => [
|
|
44
|
+
props.details,
|
|
45
|
+
props.theme,
|
|
46
|
+
props.shellClass
|
|
47
|
+
], () => {
|
|
48
|
+
syncProps();
|
|
49
|
+
}, { deep: true });
|
|
50
|
+
return () => h(tagName, { ref: elementRef });
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
const BrandHeader = createBrandShellVueComponent("brand-header", "BrandHeader");
|
|
55
|
+
const BrandFooter = createBrandShellVueComponent("brand-footer", "BrandFooter");
|
|
56
|
+
function registerBrandShellVueElements() {
|
|
57
|
+
return registerBrandShellElements();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
//#endregion
|
|
61
|
+
export { BrandFooter, BrandHeader, registerBrandShellVueElements };
|
|
62
|
+
//# sourceMappingURL=vue.mjs.map
|
package/dist/vue.mjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vue.mjs","names":[],"sources":["../src/vue/index.ts"],"sourcesContent":["import { defineComponent, h, onMounted, ref, watch, type PropType } from \"vue\";\n\nimport type { BrandDetails, BrandTheme } from \"../core\";\nimport { assertValidBrandDetails, assertValidBrandTheme, shouldValidateInDev } from \"../core\";\nimport { applyBrandShellProps, registerBrandShellElements, type BrandShellElementLike } from \"../web\";\n\nexport type { BrandDetails, BrandTheme } from \"../core\";\n\nexport interface BrandShellVueProps {\n details: BrandDetails;\n theme?: BrandTheme | null;\n shellClass?: string | null;\n}\n\nfunction ensureBrandShellElementsRegistered() {\n if (typeof customElements !== \"undefined\") {\n registerBrandShellElements();\n }\n}\n\nfunction createBrandShellVueComponent(\n tagName: \"brand-header\" | \"brand-footer\",\n componentName: \"BrandHeader\" | \"BrandFooter\",\n) {\n return defineComponent({\n name: componentName,\n props: {\n details: {\n type: Object as PropType<BrandDetails>,\n required: true,\n },\n theme: {\n type: Object as PropType<BrandTheme | null>,\n default: null,\n },\n shellClass: {\n type: String as PropType<string | null>,\n default: null,\n },\n },\n setup(props) {\n ensureBrandShellElementsRegistered();\n\n const elementRef = ref<BrandShellElementLike | null>(null);\n\n const syncProps = () => {\n if (shouldValidateInDev()) {\n assertValidBrandDetails(props.details, `brand-shell/vue ${componentName} details`);\n assertValidBrandTheme(props.theme, `brand-shell/vue ${componentName} theme`);\n }\n\n applyBrandShellProps(elementRef.value, {\n details: props.details,\n theme: props.theme ?? null,\n shellClass: props.shellClass ?? null,\n });\n };\n\n onMounted(() => {\n syncProps();\n });\n\n watch(\n () => [props.details, props.theme, props.shellClass],\n () => {\n syncProps();\n },\n { deep: true },\n );\n\n return () =>\n h(tagName, {\n ref: elementRef,\n });\n },\n });\n}\n\nexport const BrandHeader = createBrandShellVueComponent(\"brand-header\", \"BrandHeader\");\nexport const BrandFooter = createBrandShellVueComponent(\"brand-footer\", \"BrandFooter\");\n\nexport function registerBrandShellVueElements() {\n return registerBrandShellElements();\n}\n"],"mappings":";;;;;AAcA,SAAS,qCAAqC;AAC5C,KAAI,OAAO,mBAAmB,YAC5B,6BAA4B;;AAIhC,SAAS,6BACP,SACA,eACA;AACA,QAAO,gBAAgB;EACrB,MAAM;EACN,OAAO;GACL,SAAS;IACP,MAAM;IACN,UAAU;IACX;GACD,OAAO;IACL,MAAM;IACN,SAAS;IACV;GACD,YAAY;IACV,MAAM;IACN,SAAS;IACV;GACF;EACD,MAAM,OAAO;AACX,uCAAoC;GAEpC,MAAM,aAAa,IAAkC,KAAK;GAE1D,MAAM,kBAAkB;AACtB,QAAI,qBAAqB,EAAE;AACzB,6BAAwB,MAAM,SAAS,mBAAmB,cAAc,UAAU;AAClF,2BAAsB,MAAM,OAAO,mBAAmB,cAAc,QAAQ;;AAG9E,yBAAqB,WAAW,OAAO;KACrC,SAAS,MAAM;KACf,OAAO,MAAM,SAAS;KACtB,YAAY,MAAM,cAAc;KACjC,CAAC;;AAGJ,mBAAgB;AACd,eAAW;KACX;AAEF,eACQ;IAAC,MAAM;IAAS,MAAM;IAAO,MAAM;IAAW,QAC9C;AACJ,eAAW;MAEb,EAAE,MAAM,MAAM,CACf;AAED,gBACE,EAAE,SAAS,EACT,KAAK,YACN,CAAC;;EAEP,CAAC;;AAGJ,MAAa,cAAc,6BAA6B,gBAAgB,cAAc;AACtF,MAAa,cAAc,6BAA6B,gBAAgB,cAAc;AAEtF,SAAgB,gCAAgC;AAC9C,QAAO,4BAA4B"}
|