@getvitops/utils 0.2.1 → 0.4.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/dist/index.d.mts +205 -1
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +299 -1
- package/dist/index.mjs.map +1 -0
- package/package.json +2 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,2 +1,206 @@
|
|
|
1
1
|
import { FaviconLink, FaviconOptions, FaviconTagOptions, WebManifestOptions, faviconLinks, faviconManifest, generateFavicons, writeFaviconManifest } from "./favicon.mjs";
|
|
2
|
-
|
|
2
|
+
import { DefaultTreeAdapterTypes } from "parse5";
|
|
3
|
+
|
|
4
|
+
//#region src/content.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Framework-agnostic content-model types, guards, i18n, and part-attr resolution.
|
|
7
|
+
*
|
|
8
|
+
* Extracted from @getvitops/astro so the pure-TS helpers live in one place (no
|
|
9
|
+
* Astro dependency). The Astro-typed element tag was `astro/types`' `HTMLTag`;
|
|
10
|
+
* here it's a plain `string` (any tag name), keeping these fully framework-neutral.
|
|
11
|
+
*/
|
|
12
|
+
/** A translatable value: a plain string, or a locale → string map. */
|
|
13
|
+
type Localizable = string | Record<string, string>;
|
|
14
|
+
/**
|
|
15
|
+
* An HTML attribute bag. `class` may be a string or a class:list-style array
|
|
16
|
+
* (falsy entries dropped); everything else is passed through to the element.
|
|
17
|
+
*/
|
|
18
|
+
interface Attrs {
|
|
19
|
+
class?: string | (string | false | null | undefined)[];
|
|
20
|
+
[attr: string]: unknown;
|
|
21
|
+
}
|
|
22
|
+
/** An image reference used by image links. */
|
|
23
|
+
interface ImageRef {
|
|
24
|
+
src: string;
|
|
25
|
+
alt?: Localizable;
|
|
26
|
+
[key: string]: unknown;
|
|
27
|
+
}
|
|
28
|
+
/** A link with a text label. */
|
|
29
|
+
interface TextLink {
|
|
30
|
+
label: Localizable;
|
|
31
|
+
href: string;
|
|
32
|
+
attrs?: Attrs;
|
|
33
|
+
[key: string]: unknown;
|
|
34
|
+
}
|
|
35
|
+
/** A link whose content is an image. */
|
|
36
|
+
interface ImageLink {
|
|
37
|
+
image: ImageRef;
|
|
38
|
+
href: string;
|
|
39
|
+
attrs?: Attrs;
|
|
40
|
+
[key: string]: unknown;
|
|
41
|
+
}
|
|
42
|
+
/** Any link — text or image. */
|
|
43
|
+
type Link = TextLink | ImageLink;
|
|
44
|
+
/**
|
|
45
|
+
* A generic content element wrapper (discriminated by `type: 'element'`),
|
|
46
|
+
* carrying a payload `T` rendered as `Tag` (any HTML tag name).
|
|
47
|
+
*/
|
|
48
|
+
interface Elmnt<T = unknown, Tag extends string = 'div'> {
|
|
49
|
+
type: 'element';
|
|
50
|
+
tag?: Tag;
|
|
51
|
+
attrs?: Attrs;
|
|
52
|
+
content?: T;
|
|
53
|
+
[key: string]: unknown;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* A renderable node tree — a text string (Localizable) or an element with
|
|
57
|
+
* optional attrs and either `text` shorthand or `children`.
|
|
58
|
+
*/
|
|
59
|
+
type ContentNode = string | {
|
|
60
|
+
tag: string;
|
|
61
|
+
attrs?: Attrs;
|
|
62
|
+
text?: Localizable;
|
|
63
|
+
children?: ContentNode[];
|
|
64
|
+
};
|
|
65
|
+
declare function isElmnt<T, Tag extends string = 'div'>(item: any): item is Elmnt<T, Tag>;
|
|
66
|
+
declare function isLink(item: any): item is Link;
|
|
67
|
+
declare function isTextLink(item: any): item is TextLink;
|
|
68
|
+
declare function isImageLink(item: any): item is ImageLink;
|
|
69
|
+
/**
|
|
70
|
+
* Resolve a Localizable value to a string for the given locale. A plain string
|
|
71
|
+
* is returned as-is; a locale map returns the best match (locale → default → '').
|
|
72
|
+
*/
|
|
73
|
+
declare function t(value: Localizable | undefined, locale: string, defaultLocale: string): string;
|
|
74
|
+
/**
|
|
75
|
+
* Resolve per-part attrs from a presentation-type config. For the `root` part,
|
|
76
|
+
* merges legacy `attrs` with `parts.root` (backward compat).
|
|
77
|
+
*/
|
|
78
|
+
declare function partAttrs(present: {
|
|
79
|
+
attrs?: Attrs;
|
|
80
|
+
parts?: Record<string, Attrs>;
|
|
81
|
+
} | undefined, part: string): Attrs;
|
|
82
|
+
//#endregion
|
|
83
|
+
//#region src/html.d.ts
|
|
84
|
+
type ChildNode = DefaultTreeAdapterTypes.ChildNode;
|
|
85
|
+
declare function parseRenderedSlots(html: string): ChildNode[];
|
|
86
|
+
declare function getAttribute(node: ChildNode, attrName: string): string | null;
|
|
87
|
+
declare function serialize(nodes: ChildNode | ChildNode[]): string[];
|
|
88
|
+
/** Style value types that can be combined (camelCase or --custom-prop keys). */
|
|
89
|
+
type StyleObject = Record<string, string | number | null | undefined>;
|
|
90
|
+
type StyleValue = string | StyleObject | null | undefined;
|
|
91
|
+
type StyleList = StyleValue | StyleValue[];
|
|
92
|
+
/** Combine multiple style formats into one CSS string (like `class:list` for styles). */
|
|
93
|
+
declare function styleList(...styles: StyleList[]): string;
|
|
94
|
+
/** Element descriptor: a tag name, text content, and optional attributes. */
|
|
95
|
+
interface El<Tag extends string = string> {
|
|
96
|
+
text: string;
|
|
97
|
+
tag: Tag;
|
|
98
|
+
attributes?: Record<string, unknown>;
|
|
99
|
+
}
|
|
100
|
+
/** Normalize a string or `El` object into an HTML string (for `set:html`). */
|
|
101
|
+
declare function toHtml<Tag extends string>(content: string | El<Tag>): string;
|
|
102
|
+
/** Render an array of `ContentNode`s to an HTML string. */
|
|
103
|
+
declare function nodesToHtml(nodes: ContentNode[], resolveText?: (value: Localizable) => string): string;
|
|
104
|
+
//#endregion
|
|
105
|
+
//#region src/schema/article.d.ts
|
|
106
|
+
interface ArticleAuthor {
|
|
107
|
+
name: string;
|
|
108
|
+
url?: string;
|
|
109
|
+
}
|
|
110
|
+
interface ArticleGraphOptions {
|
|
111
|
+
headline: string;
|
|
112
|
+
description?: string;
|
|
113
|
+
image?: string | string[];
|
|
114
|
+
datePublished: string;
|
|
115
|
+
dateModified?: string;
|
|
116
|
+
author: ArticleAuthor | ArticleAuthor[];
|
|
117
|
+
publisher?: {
|
|
118
|
+
name: string;
|
|
119
|
+
logo?: string;
|
|
120
|
+
};
|
|
121
|
+
mainEntityOfPage?: string;
|
|
122
|
+
articleSection?: string;
|
|
123
|
+
wordCount?: number;
|
|
124
|
+
keywords?: string[];
|
|
125
|
+
}
|
|
126
|
+
/** Build a schema.org Article JSON-LD graph. */
|
|
127
|
+
declare function articleGraph(options: ArticleGraphOptions): Record<string, unknown>;
|
|
128
|
+
//#endregion
|
|
129
|
+
//#region src/schema/breadcrumb.d.ts
|
|
130
|
+
interface BreadcrumbItem {
|
|
131
|
+
name: string;
|
|
132
|
+
url: string;
|
|
133
|
+
}
|
|
134
|
+
interface BreadcrumbGraphOptions {
|
|
135
|
+
items: BreadcrumbItem[];
|
|
136
|
+
}
|
|
137
|
+
/** Build a schema.org BreadcrumbList JSON-LD graph. */
|
|
138
|
+
declare function breadcrumbGraph(options: BreadcrumbGraphOptions): Record<string, unknown>;
|
|
139
|
+
//#endregion
|
|
140
|
+
//#region src/schema/faq.d.ts
|
|
141
|
+
interface FAQItem {
|
|
142
|
+
question: string;
|
|
143
|
+
answer: string;
|
|
144
|
+
}
|
|
145
|
+
interface FAQGraphOptions {
|
|
146
|
+
items: FAQItem[];
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Build a schema.org FAQPage JSON-LD graph.
|
|
150
|
+
*
|
|
151
|
+
* NOTE: Google recommends FAQ markup only for authoritative government
|
|
152
|
+
* and health sites. For other sites, consider using QAPage schema instead.
|
|
153
|
+
*/
|
|
154
|
+
declare function faqGraph(options: FAQGraphOptions): Record<string, unknown>;
|
|
155
|
+
//#endregion
|
|
156
|
+
//#region src/schema/organization.d.ts
|
|
157
|
+
interface OrganizationGraphOptions {
|
|
158
|
+
name: string;
|
|
159
|
+
url?: string;
|
|
160
|
+
logo?: string;
|
|
161
|
+
description?: string;
|
|
162
|
+
email?: string;
|
|
163
|
+
telephone?: string;
|
|
164
|
+
address?: {
|
|
165
|
+
streetAddress?: string;
|
|
166
|
+
addressLocality?: string;
|
|
167
|
+
addressRegion?: string;
|
|
168
|
+
postalCode?: string;
|
|
169
|
+
addressCountry?: string;
|
|
170
|
+
};
|
|
171
|
+
sameAs?: string[];
|
|
172
|
+
foundingDate?: string;
|
|
173
|
+
founders?: string[];
|
|
174
|
+
numberOfEmployees?: number | {
|
|
175
|
+
minValue: number;
|
|
176
|
+
maxValue: number;
|
|
177
|
+
};
|
|
178
|
+
parentOrganization?: {
|
|
179
|
+
name: string;
|
|
180
|
+
url?: string;
|
|
181
|
+
};
|
|
182
|
+
subOrganization?: {
|
|
183
|
+
name: string;
|
|
184
|
+
url?: string;
|
|
185
|
+
}[];
|
|
186
|
+
contactPoint?: {
|
|
187
|
+
type?: 'customer service' | 'technical support' | 'sales' | 'billing support' | 'reservations';
|
|
188
|
+
telephone: string;
|
|
189
|
+
email?: string;
|
|
190
|
+
contactType: string;
|
|
191
|
+
availableLanguage?: string[];
|
|
192
|
+
areaServed?: string[];
|
|
193
|
+
}[];
|
|
194
|
+
areaServed?: string[];
|
|
195
|
+
brand?: string;
|
|
196
|
+
award?: string[];
|
|
197
|
+
memberOf?: {
|
|
198
|
+
name: string;
|
|
199
|
+
url?: string;
|
|
200
|
+
}[];
|
|
201
|
+
}
|
|
202
|
+
/** Build a schema.org Organization JSON-LD graph. */
|
|
203
|
+
declare function organizationGraph(options: OrganizationGraphOptions): Record<string, unknown>;
|
|
204
|
+
//#endregion
|
|
205
|
+
export { type ArticleAuthor, type ArticleGraphOptions, type Attrs, type BreadcrumbGraphOptions, type BreadcrumbItem, type ChildNode, type ContentNode, type El, type Elmnt, type FAQGraphOptions, type FAQItem, type FaviconLink, type FaviconOptions, type FaviconTagOptions, type ImageLink, type ImageRef, type Link, type Localizable, type OrganizationGraphOptions, type StyleList, type StyleValue, type TextLink, type WebManifestOptions, articleGraph, breadcrumbGraph, faqGraph, faviconLinks, faviconManifest, generateFavicons, getAttribute, isElmnt, isImageLink, isLink, isTextLink, nodesToHtml, organizationGraph, parseRenderedSlots, partAttrs, serialize, styleList, t, toHtml, writeFaviconManifest };
|
|
206
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/content.ts","../src/html.ts","../src/schema/article.ts","../src/schema/breadcrumb.ts","../src/schema/faq.ts","../src/schema/organization.ts"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,301 @@
|
|
|
1
1
|
import { faviconLinks, faviconManifest, generateFavicons, writeFaviconManifest } from "./favicon.mjs";
|
|
2
|
+
import { parseFragment, serialize as serialize$1 } from "parse5";
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
//#region src/content.ts
|
|
5
|
+
function isElmnt(item) {
|
|
6
|
+
return item && item.type === "element";
|
|
7
|
+
}
|
|
8
|
+
function isLink(item) {
|
|
9
|
+
return item && ("label" in item || "image" in item) && "href" in item;
|
|
10
|
+
}
|
|
11
|
+
function isTextLink(item) {
|
|
12
|
+
return item && "label" in item && "href" in item;
|
|
13
|
+
}
|
|
14
|
+
function isImageLink(item) {
|
|
15
|
+
return item && "image" in item && "href" in item;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Resolve a Localizable value to a string for the given locale. A plain string
|
|
19
|
+
* is returned as-is; a locale map returns the best match (locale → default → '').
|
|
20
|
+
*/
|
|
21
|
+
function t(value, locale, defaultLocale) {
|
|
22
|
+
if (value == null) return "";
|
|
23
|
+
if (typeof value === "string") return value;
|
|
24
|
+
return value[locale] ?? value[defaultLocale] ?? "";
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Resolve per-part attrs from a presentation-type config. For the `root` part,
|
|
28
|
+
* merges legacy `attrs` with `parts.root` (backward compat).
|
|
29
|
+
*/
|
|
30
|
+
function partAttrs(present, part) {
|
|
31
|
+
const fromParts = present?.parts?.[part];
|
|
32
|
+
if (part === "root") {
|
|
33
|
+
const legacy = present?.attrs;
|
|
34
|
+
if (!legacy && !fromParts) return {};
|
|
35
|
+
const { class: lc, ...lr } = legacy ?? {};
|
|
36
|
+
const { class: pc, ...pr } = fromParts ?? {};
|
|
37
|
+
const classes = [lc, pc].flat().filter((c) => typeof c === "string" && c !== "");
|
|
38
|
+
return {
|
|
39
|
+
...classes.length ? { class: classes } : {},
|
|
40
|
+
...lr,
|
|
41
|
+
...pr
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
return fromParts ?? {};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region src/html.ts
|
|
49
|
+
/**
|
|
50
|
+
* Framework-agnostic HTML/markup helpers (parse5-based). Extracted from
|
|
51
|
+
* @getvitops/astro — no Astro runtime dependency; the Astro-typed `HTMLTag` /
|
|
52
|
+
* `HTMLAttributes` are generalized to `string` / `Record<string, unknown>`.
|
|
53
|
+
*/
|
|
54
|
+
function parseRenderedSlots(html) {
|
|
55
|
+
return parseFragment(html).childNodes;
|
|
56
|
+
}
|
|
57
|
+
function getAttribute(node, attrName) {
|
|
58
|
+
if ("attrs" in node) {
|
|
59
|
+
const attr = node.attrs.find((a) => a.name === attrName);
|
|
60
|
+
return attr ? attr.value : null;
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
function serialize(nodes) {
|
|
65
|
+
return (Array.isArray(nodes) ? nodes : [nodes]).map((node) => serialize$1(node));
|
|
66
|
+
}
|
|
67
|
+
/** camelCase → kebab-case, preserving CSS custom properties (`--var-name`). */
|
|
68
|
+
function toKebabCase(str) {
|
|
69
|
+
if (str.startsWith("--")) return str;
|
|
70
|
+
return str.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
71
|
+
}
|
|
72
|
+
function styleObjectToString(obj) {
|
|
73
|
+
return Object.entries(obj).filter(([, value]) => value != null).map(([key, value]) => `${toKebabCase(key)}: ${value}`).join("; ");
|
|
74
|
+
}
|
|
75
|
+
/** Combine multiple style formats into one CSS string (like `class:list` for styles). */
|
|
76
|
+
function styleList(...styles) {
|
|
77
|
+
const result = [];
|
|
78
|
+
const process = (item) => {
|
|
79
|
+
if (item == null) return;
|
|
80
|
+
if (Array.isArray(item)) item.forEach(process);
|
|
81
|
+
else if (typeof item === "string") {
|
|
82
|
+
const trimmed = item.trim();
|
|
83
|
+
if (trimmed) result.push(trimmed);
|
|
84
|
+
} else {
|
|
85
|
+
const str = styleObjectToString(item);
|
|
86
|
+
if (str) result.push(str);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
styles.forEach(process);
|
|
90
|
+
return result.join("; ");
|
|
91
|
+
}
|
|
92
|
+
function isEl(value) {
|
|
93
|
+
return typeof value === "object" && value !== null && "tag" in value && "text" in value;
|
|
94
|
+
}
|
|
95
|
+
function attributesToString(attrs) {
|
|
96
|
+
const parts = [];
|
|
97
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
98
|
+
if (value == null || value === false) continue;
|
|
99
|
+
if (value === true) parts.push(key);
|
|
100
|
+
else if (key === "style" && typeof value === "object") parts.push(`style="${styleList(value)}"`);
|
|
101
|
+
else {
|
|
102
|
+
const text = Array.isArray(value) ? value.filter((v) => typeof v === "string" && v !== "").join(" ") : typeof value === "object" ? JSON.stringify(value) : String(value);
|
|
103
|
+
parts.push(`${key}="${text.replace(/"/g, """)}"`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return parts.join(" ");
|
|
107
|
+
}
|
|
108
|
+
/** Normalize a string or `El` object into an HTML string (for `set:html`). */
|
|
109
|
+
function toHtml(content) {
|
|
110
|
+
if (!isEl(content)) return content;
|
|
111
|
+
const { tag, text, attributes } = content;
|
|
112
|
+
const attrStr = attributes ? attributesToString(attributes) : "";
|
|
113
|
+
const t = String(tag);
|
|
114
|
+
return attrStr ? `<${t} ${attrStr}>${text}</${t}>` : `<${t}>${text}</${t}>`;
|
|
115
|
+
}
|
|
116
|
+
const VOID_ELEMENTS = new Set([
|
|
117
|
+
"area",
|
|
118
|
+
"base",
|
|
119
|
+
"br",
|
|
120
|
+
"col",
|
|
121
|
+
"embed",
|
|
122
|
+
"hr",
|
|
123
|
+
"img",
|
|
124
|
+
"input",
|
|
125
|
+
"link",
|
|
126
|
+
"meta",
|
|
127
|
+
"param",
|
|
128
|
+
"source",
|
|
129
|
+
"track",
|
|
130
|
+
"wbr"
|
|
131
|
+
]);
|
|
132
|
+
function defaultResolveText(value) {
|
|
133
|
+
if (typeof value === "string") return value;
|
|
134
|
+
return Object.values(value)[0] ?? "";
|
|
135
|
+
}
|
|
136
|
+
function escapeHtml(text) {
|
|
137
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
138
|
+
}
|
|
139
|
+
function nodeToHtml(node, resolveText) {
|
|
140
|
+
if (typeof node === "string") return escapeHtml(resolveText(node));
|
|
141
|
+
const { tag, attrs, text, children } = node;
|
|
142
|
+
const attrStr = attrs ? attributesToString(attrs) : "";
|
|
143
|
+
const open = attrStr ? `<${tag} ${attrStr}>` : `<${tag}>`;
|
|
144
|
+
if (VOID_ELEMENTS.has(tag)) return open;
|
|
145
|
+
let inner = "";
|
|
146
|
+
if (text != null) inner = escapeHtml(resolveText(text));
|
|
147
|
+
else if (children?.length) inner = children.map((child) => nodeToHtml(child, resolveText)).join("");
|
|
148
|
+
return `${open}${inner}</${tag}>`;
|
|
149
|
+
}
|
|
150
|
+
/** Render an array of `ContentNode`s to an HTML string. */
|
|
151
|
+
function nodesToHtml(nodes, resolveText = defaultResolveText) {
|
|
152
|
+
return nodes.map((node) => nodeToHtml(node, resolveText)).join("");
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
//#endregion
|
|
156
|
+
//#region src/schema/article.ts
|
|
157
|
+
/** Build a schema.org Article JSON-LD graph. */
|
|
158
|
+
function articleGraph(options) {
|
|
159
|
+
const { headline, description, image, datePublished, dateModified, author, publisher, mainEntityOfPage, articleSection, wordCount, keywords } = options;
|
|
160
|
+
const authors = Array.isArray(author) ? author : [author];
|
|
161
|
+
return {
|
|
162
|
+
"@context": "https://schema.org",
|
|
163
|
+
"@type": "Article",
|
|
164
|
+
headline,
|
|
165
|
+
...description && { description },
|
|
166
|
+
...image && { image: Array.isArray(image) ? image : [image] },
|
|
167
|
+
datePublished,
|
|
168
|
+
...dateModified && { dateModified },
|
|
169
|
+
author: authors.map((a) => ({
|
|
170
|
+
"@type": "Person",
|
|
171
|
+
name: a.name,
|
|
172
|
+
...a.url && { url: a.url }
|
|
173
|
+
})),
|
|
174
|
+
...publisher && { publisher: {
|
|
175
|
+
"@type": "Organization",
|
|
176
|
+
name: publisher.name,
|
|
177
|
+
...publisher.logo && { logo: {
|
|
178
|
+
"@type": "ImageObject",
|
|
179
|
+
url: publisher.logo
|
|
180
|
+
} }
|
|
181
|
+
} },
|
|
182
|
+
...mainEntityOfPage && { mainEntityOfPage: {
|
|
183
|
+
"@type": "WebPage",
|
|
184
|
+
"@id": mainEntityOfPage
|
|
185
|
+
} },
|
|
186
|
+
...articleSection && { articleSection },
|
|
187
|
+
...wordCount && { wordCount },
|
|
188
|
+
...keywords && { keywords: keywords.join(", ") }
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
//#endregion
|
|
193
|
+
//#region src/schema/breadcrumb.ts
|
|
194
|
+
/** Build a schema.org BreadcrumbList JSON-LD graph. */
|
|
195
|
+
function breadcrumbGraph(options) {
|
|
196
|
+
return {
|
|
197
|
+
"@context": "https://schema.org",
|
|
198
|
+
"@type": "BreadcrumbList",
|
|
199
|
+
itemListElement: options.items.map((item, index) => ({
|
|
200
|
+
"@type": "ListItem",
|
|
201
|
+
position: index + 1,
|
|
202
|
+
name: item.name,
|
|
203
|
+
item: item.url
|
|
204
|
+
}))
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
//#endregion
|
|
209
|
+
//#region src/schema/faq.ts
|
|
210
|
+
/**
|
|
211
|
+
* Build a schema.org FAQPage JSON-LD graph.
|
|
212
|
+
*
|
|
213
|
+
* NOTE: Google recommends FAQ markup only for authoritative government
|
|
214
|
+
* and health sites. For other sites, consider using QAPage schema instead.
|
|
215
|
+
*/
|
|
216
|
+
function faqGraph(options) {
|
|
217
|
+
return {
|
|
218
|
+
"@context": "https://schema.org",
|
|
219
|
+
"@type": "FAQPage",
|
|
220
|
+
mainEntity: options.items.map((item) => ({
|
|
221
|
+
"@type": "Question",
|
|
222
|
+
name: item.question,
|
|
223
|
+
acceptedAnswer: {
|
|
224
|
+
"@type": "Answer",
|
|
225
|
+
text: item.answer
|
|
226
|
+
}
|
|
227
|
+
}))
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
//#endregion
|
|
232
|
+
//#region src/schema/organization.ts
|
|
233
|
+
/** Build a schema.org Organization JSON-LD graph. */
|
|
234
|
+
function organizationGraph(options) {
|
|
235
|
+
const { name, url, logo, description, email, telephone, address, sameAs, foundingDate, founders, numberOfEmployees, parentOrganization, subOrganization, contactPoint, areaServed, brand, award, memberOf } = options;
|
|
236
|
+
return {
|
|
237
|
+
"@context": "https://schema.org",
|
|
238
|
+
"@type": "Organization",
|
|
239
|
+
name,
|
|
240
|
+
...url && { url },
|
|
241
|
+
...logo && { logo },
|
|
242
|
+
...description && { description },
|
|
243
|
+
...email && { email },
|
|
244
|
+
...telephone && { telephone },
|
|
245
|
+
...address && { address: {
|
|
246
|
+
"@type": "PostalAddress",
|
|
247
|
+
...address.streetAddress && { streetAddress: address.streetAddress },
|
|
248
|
+
...address.addressLocality && { addressLocality: address.addressLocality },
|
|
249
|
+
...address.addressRegion && { addressRegion: address.addressRegion },
|
|
250
|
+
...address.postalCode && { postalCode: address.postalCode },
|
|
251
|
+
...address.addressCountry && { addressCountry: address.addressCountry }
|
|
252
|
+
} },
|
|
253
|
+
...sameAs && { sameAs },
|
|
254
|
+
...foundingDate && { foundingDate },
|
|
255
|
+
...founders && { founders: founders.map((f) => ({
|
|
256
|
+
"@type": "Person",
|
|
257
|
+
name: f
|
|
258
|
+
})) },
|
|
259
|
+
...numberOfEmployees && { numberOfEmployees: typeof numberOfEmployees === "number" ? {
|
|
260
|
+
"@type": "QuantitativeValue",
|
|
261
|
+
value: numberOfEmployees
|
|
262
|
+
} : {
|
|
263
|
+
"@type": "QuantitativeValue",
|
|
264
|
+
minValue: numberOfEmployees.minValue,
|
|
265
|
+
maxValue: numberOfEmployees.maxValue
|
|
266
|
+
} },
|
|
267
|
+
...parentOrganization && { parentOrganization: {
|
|
268
|
+
"@type": "Organization",
|
|
269
|
+
name: parentOrganization.name,
|
|
270
|
+
...parentOrganization.url && { url: parentOrganization.url }
|
|
271
|
+
} },
|
|
272
|
+
...subOrganization && { subOrganization: subOrganization.map((sub) => ({
|
|
273
|
+
"@type": "Organization",
|
|
274
|
+
name: sub.name,
|
|
275
|
+
...sub.url && { url: sub.url }
|
|
276
|
+
})) },
|
|
277
|
+
...contactPoint && { contactPoint: contactPoint.map((cp) => ({
|
|
278
|
+
"@type": "ContactPoint",
|
|
279
|
+
telephone: cp.telephone,
|
|
280
|
+
contactType: cp.contactType,
|
|
281
|
+
...cp.email && { email: cp.email },
|
|
282
|
+
...cp.availableLanguage && { availableLanguage: cp.availableLanguage },
|
|
283
|
+
...cp.areaServed && { areaServed: cp.areaServed }
|
|
284
|
+
})) },
|
|
285
|
+
...areaServed && { areaServed },
|
|
286
|
+
...brand && { brand: {
|
|
287
|
+
"@type": "Brand",
|
|
288
|
+
name: brand
|
|
289
|
+
} },
|
|
290
|
+
...award && { award },
|
|
291
|
+
...memberOf && { memberOf: memberOf.map((m) => ({
|
|
292
|
+
"@type": "Organization",
|
|
293
|
+
name: m.name,
|
|
294
|
+
...m.url && { url: m.url }
|
|
295
|
+
})) }
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
//#endregion
|
|
300
|
+
export { articleGraph, breadcrumbGraph, faqGraph, faviconLinks, faviconManifest, generateFavicons, getAttribute, isElmnt, isImageLink, isLink, isTextLink, nodesToHtml, organizationGraph, parseRenderedSlots, partAttrs, serialize, styleList, t, toHtml, writeFaviconManifest };
|
|
301
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["s"],"sources":["../src/content.ts","../src/html.ts","../src/schema/article.ts","../src/schema/breadcrumb.ts","../src/schema/faq.ts","../src/schema/organization.ts"],"sourcesContent":["/**\n * Framework-agnostic content-model types, guards, i18n, and part-attr resolution.\n *\n * Extracted from @getvitops/astro so the pure-TS helpers live in one place (no\n * Astro dependency). The Astro-typed element tag was `astro/types`' `HTMLTag`;\n * here it's a plain `string` (any tag name), keeping these fully framework-neutral.\n */\n\n// ── content-model types ──────────────────────────────────────────────────────\n\n/** A translatable value: a plain string, or a locale → string map. */\nexport type Localizable = string | Record<string, string>;\n\n/**\n * An HTML attribute bag. `class` may be a string or a class:list-style array\n * (falsy entries dropped); everything else is passed through to the element.\n */\nexport interface Attrs {\n class?: string | (string | false | null | undefined)[];\n [attr: string]: unknown;\n}\n\n/** An image reference used by image links. */\nexport interface ImageRef {\n src: string;\n alt?: Localizable;\n [key: string]: unknown;\n}\n\n/** A link with a text label. */\nexport interface TextLink {\n label: Localizable;\n href: string;\n attrs?: Attrs;\n [key: string]: unknown;\n}\n\n/** A link whose content is an image. */\nexport interface ImageLink {\n image: ImageRef;\n href: string;\n attrs?: Attrs;\n [key: string]: unknown;\n}\n\n/** Any link — text or image. */\nexport type Link = TextLink | ImageLink;\n\n/**\n * A generic content element wrapper (discriminated by `type: 'element'`),\n * carrying a payload `T` rendered as `Tag` (any HTML tag name).\n */\nexport interface Elmnt<T = unknown, Tag extends string = 'div'> {\n type: 'element';\n tag?: Tag;\n attrs?: Attrs;\n content?: T;\n [key: string]: unknown;\n}\n\n/**\n * A renderable node tree — a text string (Localizable) or an element with\n * optional attrs and either `text` shorthand or `children`.\n */\nexport type ContentNode =\n | string\n | {\n tag: string;\n attrs?: Attrs;\n text?: Localizable;\n children?: ContentNode[];\n };\n\n// ── type guards ──────────────────────────────────────────────────────────────\n\nexport function isElmnt<T, Tag extends string = 'div'>(item: any): item is Elmnt<T, Tag> {\n return item && item.type === 'element';\n}\n\nexport function isLink(item: any): item is Link {\n return item && ('label' in item || 'image' in item) && 'href' in item;\n}\n\nexport function isTextLink(item: any): item is TextLink {\n return item && 'label' in item && 'href' in item;\n}\n\nexport function isImageLink(item: any): item is ImageLink {\n return item && 'image' in item && 'href' in item;\n}\n\n// ── i18n ─────────────────────────────────────────────────────────────────────\n\n/**\n * Resolve a Localizable value to a string for the given locale. A plain string\n * is returned as-is; a locale map returns the best match (locale → default → '').\n */\nexport function t(value: Localizable | undefined, locale: string, defaultLocale: string): string {\n if (value == null) return '';\n if (typeof value === 'string') return value;\n return value[locale] ?? value[defaultLocale] ?? '';\n}\n\n// ── part-attr resolution ─────────────────────────────────────────────────────\n\n/**\n * Resolve per-part attrs from a presentation-type config. For the `root` part,\n * merges legacy `attrs` with `parts.root` (backward compat).\n */\nexport function partAttrs(\n present: { attrs?: Attrs; parts?: Record<string, Attrs> } | undefined,\n part: string,\n): Attrs {\n const fromParts = present?.parts?.[part];\n if (part === 'root') {\n const legacy = present?.attrs;\n if (!legacy && !fromParts) return {};\n const { class: lc, ...lr } = legacy ?? {};\n const { class: pc, ...pr } = fromParts ?? {};\n const classes = [lc, pc].flat().filter((c): c is string => typeof c === 'string' && c !== '');\n return {\n ...(classes.length ? { class: classes } : {}),\n ...lr,\n ...pr,\n };\n }\n return fromParts ?? {};\n}\n","/**\n * Framework-agnostic HTML/markup helpers (parse5-based). Extracted from\n * @getvitops/astro — no Astro runtime dependency; the Astro-typed `HTMLTag` /\n * `HTMLAttributes` are generalized to `string` / `Record<string, unknown>`.\n */\nimport { parseFragment, serialize as s, type DefaultTreeAdapterTypes } from 'parse5';\nimport type { Localizable, ContentNode } from './content.ts';\n\nexport type ChildNode = DefaultTreeAdapterTypes.ChildNode;\n\nexport function parseRenderedSlots(html: string): ChildNode[] {\n return parseFragment(html).childNodes;\n}\n\nexport function getAttribute(node: ChildNode, attrName: string): string | null {\n if ('attrs' in node) {\n const attr = node.attrs.find((a) => a.name === attrName);\n return attr ? attr.value : null;\n }\n return null;\n}\n\nexport function serialize(nodes: ChildNode | ChildNode[]): string[] {\n return (Array.isArray(nodes) ? nodes : [nodes]).map((node) =>\n s(node as DefaultTreeAdapterTypes.ParentNode),\n );\n}\n\n/** Style value types that can be combined (camelCase or --custom-prop keys). */\ntype StyleObject = Record<string, string | number | null | undefined>;\nexport type StyleValue = string | StyleObject | null | undefined;\nexport type StyleList = StyleValue | StyleValue[];\n\n/** camelCase → kebab-case, preserving CSS custom properties (`--var-name`). */\nfunction toKebabCase(str: string): string {\n if (str.startsWith('--')) return str;\n return str.replace(/([A-Z])/g, '-$1').toLowerCase();\n}\nfunction styleObjectToString(obj: StyleObject): string {\n return Object.entries(obj)\n .filter(([, value]) => value != null)\n .map(([key, value]) => `${toKebabCase(key)}: ${value}`)\n .join('; ');\n}\n\n/** Combine multiple style formats into one CSS string (like `class:list` for styles). */\nexport function styleList(...styles: StyleList[]): string {\n const result: string[] = [];\n const process = (item: StyleList): void => {\n if (item == null) return;\n if (Array.isArray(item)) {\n item.forEach(process);\n } else if (typeof item === 'string') {\n const trimmed = item.trim();\n if (trimmed) result.push(trimmed);\n } else {\n const str = styleObjectToString(item as StyleObject);\n if (str) result.push(str);\n }\n };\n styles.forEach(process);\n return result.join('; ');\n}\n\n/** Element descriptor: a tag name, text content, and optional attributes. */\nexport interface El<Tag extends string = string> {\n text: string;\n tag: Tag;\n attributes?: Record<string, unknown>;\n}\n\nfunction isEl(value: string | El): value is El {\n return typeof value === 'object' && value !== null && 'tag' in value && 'text' in value;\n}\n\nfunction attributesToString(attrs: Record<string, unknown>): string {\n const parts: string[] = [];\n for (const [key, value] of Object.entries(attrs)) {\n if (value == null || value === false) continue;\n if (value === true) {\n parts.push(key);\n } else if (key === 'style' && typeof value === 'object') {\n parts.push(`style=\"${styleList(value as StyleValue)}\"`);\n } else {\n const text = Array.isArray(value)\n ? value.filter((v): v is string => typeof v === 'string' && v !== '').join(' ')\n : typeof value === 'object'\n ? JSON.stringify(value)\n : String(value as string | number | boolean);\n parts.push(`${key}=\"${text.replace(/\"/g, '"')}\"`);\n }\n }\n return parts.join(' ');\n}\n\n/** Normalize a string or `El` object into an HTML string (for `set:html`). */\nexport function toHtml<Tag extends string>(content: string | El<Tag>): string {\n if (!isEl(content)) return content;\n const { tag, text, attributes } = content;\n const attrStr = attributes ? attributesToString(attributes) : '';\n const t = String(tag);\n return attrStr ? `<${t} ${attrStr}>${text}</${t}>` : `<${t}>${text}</${t}>`;\n}\n\n// ── node-tree renderer — { tag, attrs, children } ────────────────────────────\nconst VOID_ELEMENTS = new Set([\n 'area',\n 'base',\n 'br',\n 'col',\n 'embed',\n 'hr',\n 'img',\n 'input',\n 'link',\n 'meta',\n 'param',\n 'source',\n 'track',\n 'wbr',\n]);\n\nfunction defaultResolveText(value: Localizable): string {\n if (typeof value === 'string') return value;\n const values = Object.values(value);\n return values[0] ?? '';\n}\n\nfunction escapeHtml(text: string): string {\n return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n}\n\nfunction nodeToHtml(node: ContentNode, resolveText: (value: Localizable) => string): string {\n if (typeof node === 'string') return escapeHtml(resolveText(node));\n const { tag, attrs, text, children } = node;\n const attrStr = attrs ? attributesToString(attrs) : '';\n const open = attrStr ? `<${tag} ${attrStr}>` : `<${tag}>`;\n if (VOID_ELEMENTS.has(tag)) return open;\n let inner = '';\n if (text != null) inner = escapeHtml(resolveText(text));\n else if (children?.length)\n inner = children.map((child) => nodeToHtml(child, resolveText)).join('');\n return `${open}${inner}</${tag}>`;\n}\n\n/** Render an array of `ContentNode`s to an HTML string. */\nexport function nodesToHtml(\n nodes: ContentNode[],\n resolveText: (value: Localizable) => string = defaultResolveText,\n): string {\n return nodes.map((node) => nodeToHtml(node, resolveText)).join('');\n}\n","export interface ArticleAuthor {\n name: string;\n url?: string;\n}\n\nexport interface ArticleGraphOptions {\n headline: string;\n description?: string;\n image?: string | string[];\n datePublished: string;\n dateModified?: string;\n author: ArticleAuthor | ArticleAuthor[];\n publisher?: {\n name: string;\n logo?: string;\n };\n mainEntityOfPage?: string;\n articleSection?: string;\n wordCount?: number;\n keywords?: string[];\n}\n\n/** Build a schema.org Article JSON-LD graph. */\nexport function articleGraph(options: ArticleGraphOptions): Record<string, unknown> {\n const {\n headline,\n description,\n image,\n datePublished,\n dateModified,\n author,\n publisher,\n mainEntityOfPage,\n articleSection,\n wordCount,\n keywords,\n } = options;\n\n const authors = Array.isArray(author) ? author : [author];\n\n return {\n '@context': 'https://schema.org',\n '@type': 'Article',\n headline,\n ...(description && { description }),\n ...(image && { image: Array.isArray(image) ? image : [image] }),\n datePublished,\n ...(dateModified && { dateModified }),\n author: authors.map((a) => ({\n '@type': 'Person',\n name: a.name,\n ...(a.url && { url: a.url }),\n })),\n ...(publisher && {\n publisher: {\n '@type': 'Organization',\n name: publisher.name,\n ...(publisher.logo && { logo: { '@type': 'ImageObject', url: publisher.logo } }),\n },\n }),\n ...(mainEntityOfPage && { mainEntityOfPage: { '@type': 'WebPage', '@id': mainEntityOfPage } }),\n ...(articleSection && { articleSection }),\n ...(wordCount && { wordCount }),\n ...(keywords && { keywords: keywords.join(', ') }),\n };\n}\n","export interface BreadcrumbItem {\n name: string;\n url: string;\n}\n\nexport interface BreadcrumbGraphOptions {\n items: BreadcrumbItem[];\n}\n\n/** Build a schema.org BreadcrumbList JSON-LD graph. */\nexport function breadcrumbGraph(options: BreadcrumbGraphOptions): Record<string, unknown> {\n return {\n '@context': 'https://schema.org',\n '@type': 'BreadcrumbList',\n itemListElement: options.items.map((item, index) => ({\n '@type': 'ListItem',\n position: index + 1,\n name: item.name,\n item: item.url,\n })),\n };\n}\n","export interface FAQItem {\n question: string;\n answer: string;\n}\n\nexport interface FAQGraphOptions {\n items: FAQItem[];\n}\n\n/**\n * Build a schema.org FAQPage JSON-LD graph.\n *\n * NOTE: Google recommends FAQ markup only for authoritative government\n * and health sites. For other sites, consider using QAPage schema instead.\n */\nexport function faqGraph(options: FAQGraphOptions): Record<string, unknown> {\n return {\n '@context': 'https://schema.org',\n '@type': 'FAQPage',\n mainEntity: options.items.map((item) => ({\n '@type': 'Question',\n name: item.question,\n acceptedAnswer: {\n '@type': 'Answer',\n text: item.answer,\n },\n })),\n };\n}\n","export interface OrganizationGraphOptions {\n name: string;\n url?: string;\n logo?: string;\n description?: string;\n email?: string;\n telephone?: string;\n address?: {\n streetAddress?: string;\n addressLocality?: string;\n addressRegion?: string;\n postalCode?: string;\n addressCountry?: string;\n };\n sameAs?: string[];\n foundingDate?: string;\n founders?: string[];\n numberOfEmployees?: number | { minValue: number; maxValue: number };\n parentOrganization?: {\n name: string;\n url?: string;\n };\n subOrganization?: {\n name: string;\n url?: string;\n }[];\n contactPoint?: {\n type?: 'customer service' | 'technical support' | 'sales' | 'billing support' | 'reservations';\n telephone: string;\n email?: string;\n contactType: string;\n availableLanguage?: string[];\n areaServed?: string[];\n }[];\n areaServed?: string[];\n brand?: string;\n award?: string[];\n memberOf?: {\n name: string;\n url?: string;\n }[];\n}\n\n/** Build a schema.org Organization JSON-LD graph. */\nexport function organizationGraph(options: OrganizationGraphOptions): Record<string, unknown> {\n const {\n name,\n url,\n logo,\n description,\n email,\n telephone,\n address,\n sameAs,\n foundingDate,\n founders,\n numberOfEmployees,\n parentOrganization,\n subOrganization,\n contactPoint,\n areaServed,\n brand,\n award,\n memberOf,\n } = options;\n\n return {\n '@context': 'https://schema.org',\n '@type': 'Organization',\n name,\n ...(url && { url }),\n ...(logo && { logo }),\n ...(description && { description }),\n ...(email && { email }),\n ...(telephone && { telephone }),\n ...(address && {\n address: {\n '@type': 'PostalAddress',\n ...(address.streetAddress && { streetAddress: address.streetAddress }),\n ...(address.addressLocality && { addressLocality: address.addressLocality }),\n ...(address.addressRegion && { addressRegion: address.addressRegion }),\n ...(address.postalCode && { postalCode: address.postalCode }),\n ...(address.addressCountry && { addressCountry: address.addressCountry }),\n },\n }),\n ...(sameAs && { sameAs }),\n ...(foundingDate && { foundingDate }),\n ...(founders && {\n founders: founders.map((f) => ({\n '@type': 'Person',\n name: f,\n })),\n }),\n ...(numberOfEmployees && {\n numberOfEmployees:\n typeof numberOfEmployees === 'number'\n ? { '@type': 'QuantitativeValue', value: numberOfEmployees }\n : {\n '@type': 'QuantitativeValue',\n minValue: numberOfEmployees.minValue,\n maxValue: numberOfEmployees.maxValue,\n },\n }),\n ...(parentOrganization && {\n parentOrganization: {\n '@type': 'Organization',\n name: parentOrganization.name,\n ...(parentOrganization.url && { url: parentOrganization.url }),\n },\n }),\n ...(subOrganization && {\n subOrganization: subOrganization.map((sub) => ({\n '@type': 'Organization',\n name: sub.name,\n ...(sub.url && { url: sub.url }),\n })),\n }),\n ...(contactPoint && {\n contactPoint: contactPoint.map((cp) => ({\n '@type': 'ContactPoint',\n telephone: cp.telephone,\n contactType: cp.contactType,\n ...(cp.email && { email: cp.email }),\n ...(cp.availableLanguage && { availableLanguage: cp.availableLanguage }),\n ...(cp.areaServed && { areaServed: cp.areaServed }),\n })),\n }),\n ...(areaServed && { areaServed }),\n ...(brand && { brand: { '@type': 'Brand', name: brand } }),\n ...(award && { award }),\n ...(memberOf && {\n memberOf: memberOf.map((m) => ({\n '@type': 'Organization',\n name: m.name,\n ...(m.url && { url: m.url }),\n })),\n }),\n };\n}\n"],"mappings":";;;;AA2EA,SAAgB,QAAuC,MAAkC;CACvF,OAAO,QAAQ,KAAK,SAAS;AAC/B;AAEA,SAAgB,OAAO,MAAyB;CAC9C,OAAO,SAAS,WAAW,QAAQ,WAAW,SAAS,UAAU;AACnE;AAEA,SAAgB,WAAW,MAA6B;CACtD,OAAO,QAAQ,WAAW,QAAQ,UAAU;AAC9C;AAEA,SAAgB,YAAY,MAA8B;CACxD,OAAO,QAAQ,WAAW,QAAQ,UAAU;AAC9C;;;;;AAQA,SAAgB,EAAE,OAAgC,QAAgB,eAA+B;CAC/F,IAAI,SAAS,MAAM,OAAO;CAC1B,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,OAAO,MAAM,WAAW,MAAM,kBAAkB;AAClD;;;;;AAQA,SAAgB,UACd,SACA,MACO;CACP,MAAM,YAAY,SAAS,QAAQ;CACnC,IAAI,SAAS,QAAQ;EACnB,MAAM,SAAS,SAAS;EACxB,IAAI,CAAC,UAAU,CAAC,WAAW,OAAO,CAAC;EACnC,MAAM,EAAE,OAAO,IAAI,GAAG,OAAO,UAAU,CAAC;EACxC,MAAM,EAAE,OAAO,IAAI,GAAG,OAAO,aAAa,CAAC;EAC3C,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,MAAmB,OAAO,MAAM,YAAY,MAAM,EAAE;EAC5F,OAAO;GACL,GAAI,QAAQ,SAAS,EAAE,OAAO,QAAQ,IAAI,CAAC;GAC3C,GAAG;GACH,GAAG;EACL;CACF;CACA,OAAO,aAAa,CAAC;AACvB;;;;;;;;;ACrHA,SAAgB,mBAAmB,MAA2B;CAC5D,OAAO,cAAc,IAAI,CAAC,CAAC;AAC7B;AAEA,SAAgB,aAAa,MAAiB,UAAiC;CAC7E,IAAI,WAAW,MAAM;EACnB,MAAM,OAAO,KAAK,MAAM,MAAM,MAAM,EAAE,SAAS,QAAQ;EACvD,OAAO,OAAO,KAAK,QAAQ;CAC7B;CACA,OAAO;AACT;AAEA,SAAgB,UAAU,OAA0C;CAClE,QAAQ,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK,EAAC,CAAE,KAAK,SACnDA,YAAE,IAA0C,CAC9C;AACF;;AAQA,SAAS,YAAY,KAAqB;CACxC,IAAI,IAAI,WAAW,IAAI,GAAG,OAAO;CACjC,OAAO,IAAI,QAAQ,YAAY,KAAK,CAAC,CAAC,YAAY;AACpD;AACA,SAAS,oBAAoB,KAA0B;CACrD,OAAO,OAAO,QAAQ,GAAG,CAAC,CACvB,QAAQ,GAAG,WAAW,SAAS,IAAI,CAAC,CACpC,KAAK,CAAC,KAAK,WAAW,GAAG,YAAY,GAAG,EAAE,IAAI,OAAO,CAAC,CACtD,KAAK,IAAI;AACd;;AAGA,SAAgB,UAAU,GAAG,QAA6B;CACxD,MAAM,SAAmB,CAAC;CAC1B,MAAM,WAAW,SAA0B;EACzC,IAAI,QAAQ,MAAM;EAClB,IAAI,MAAM,QAAQ,IAAI,GACpB,KAAK,QAAQ,OAAO;OACf,IAAI,OAAO,SAAS,UAAU;GACnC,MAAM,UAAU,KAAK,KAAK;GAC1B,IAAI,SAAS,OAAO,KAAK,OAAO;EAClC,OAAO;GACL,MAAM,MAAM,oBAAoB,IAAmB;GACnD,IAAI,KAAK,OAAO,KAAK,GAAG;EAC1B;CACF;CACA,OAAO,QAAQ,OAAO;CACtB,OAAO,OAAO,KAAK,IAAI;AACzB;AASA,SAAS,KAAK,OAAiC;CAC7C,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,SAAS,SAAS,UAAU;AACpF;AAEA,SAAS,mBAAmB,OAAwC;CAClE,MAAM,QAAkB,CAAC;CACzB,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,GAAG;EAChD,IAAI,SAAS,QAAQ,UAAU,OAAO;EACtC,IAAI,UAAU,MACZ,MAAM,KAAK,GAAG;OACT,IAAI,QAAQ,WAAW,OAAO,UAAU,UAC7C,MAAM,KAAK,UAAU,UAAU,KAAmB,EAAE,EAAE;OACjD;GACL,MAAM,OAAO,MAAM,QAAQ,KAAK,IAC5B,MAAM,QAAQ,MAAmB,OAAO,MAAM,YAAY,MAAM,EAAE,CAAC,CAAC,KAAK,GAAG,IAC5E,OAAO,UAAU,WACf,KAAK,UAAU,KAAK,IACpB,OAAO,KAAkC;GAC/C,MAAM,KAAK,GAAG,IAAI,IAAI,KAAK,QAAQ,MAAM,QAAQ,EAAE,EAAE;EACvD;CACF;CACA,OAAO,MAAM,KAAK,GAAG;AACvB;;AAGA,SAAgB,OAA2B,SAAmC;CAC5E,IAAI,CAAC,KAAK,OAAO,GAAG,OAAO;CAC3B,MAAM,EAAE,KAAK,MAAM,eAAe;CAClC,MAAM,UAAU,aAAa,mBAAmB,UAAU,IAAI;CAC9D,MAAM,IAAI,OAAO,GAAG;CACpB,OAAO,UAAU,IAAI,EAAE,GAAG,QAAQ,GAAG,KAAK,IAAI,EAAE,KAAK,IAAI,EAAE,GAAG,KAAK,IAAI,EAAE;AAC3E;AAGA,MAAM,gBAAgB,IAAI,IAAI;CAC5B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,SAAS,mBAAmB,OAA4B;CACtD,IAAI,OAAO,UAAU,UAAU,OAAO;CAEtC,OADe,OAAO,OAAO,KACjB,CAAC,CAAC,MAAM;AACtB;AAEA,SAAS,WAAW,MAAsB;CACxC,OAAO,KAAK,QAAQ,MAAM,OAAO,CAAC,CAAC,QAAQ,MAAM,MAAM,CAAC,CAAC,QAAQ,MAAM,MAAM;AAC/E;AAEA,SAAS,WAAW,MAAmB,aAAqD;CAC1F,IAAI,OAAO,SAAS,UAAU,OAAO,WAAW,YAAY,IAAI,CAAC;CACjE,MAAM,EAAE,KAAK,OAAO,MAAM,aAAa;CACvC,MAAM,UAAU,QAAQ,mBAAmB,KAAK,IAAI;CACpD,MAAM,OAAO,UAAU,IAAI,IAAI,GAAG,QAAQ,KAAK,IAAI,IAAI;CACvD,IAAI,cAAc,IAAI,GAAG,GAAG,OAAO;CACnC,IAAI,QAAQ;CACZ,IAAI,QAAQ,MAAM,QAAQ,WAAW,YAAY,IAAI,CAAC;MACjD,IAAI,UAAU,QACjB,QAAQ,SAAS,KAAK,UAAU,WAAW,OAAO,WAAW,CAAC,CAAC,CAAC,KAAK,EAAE;CACzE,OAAO,GAAG,OAAO,MAAM,IAAI,IAAI;AACjC;;AAGA,SAAgB,YACd,OACA,cAA8C,oBACtC;CACR,OAAO,MAAM,KAAK,SAAS,WAAW,MAAM,WAAW,CAAC,CAAC,CAAC,KAAK,EAAE;AACnE;;;;;AChIA,SAAgB,aAAa,SAAuD;CAClF,MAAM,EACJ,UACA,aACA,OACA,eACA,cACA,QACA,WACA,kBACA,gBACA,WACA,aACE;CAEJ,MAAM,UAAU,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM;CAExD,OAAO;EACL,YAAY;EACZ,SAAS;EACT;EACA,GAAI,eAAe,EAAE,YAAY;EACjC,GAAI,SAAS,EAAE,OAAO,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK,EAAE;EAC7D;EACA,GAAI,gBAAgB,EAAE,aAAa;EACnC,QAAQ,QAAQ,KAAK,OAAO;GAC1B,SAAS;GACT,MAAM,EAAE;GACR,GAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI;EAC5B,EAAE;EACF,GAAI,aAAa,EACf,WAAW;GACT,SAAS;GACT,MAAM,UAAU;GAChB,GAAI,UAAU,QAAQ,EAAE,MAAM;IAAE,SAAS;IAAe,KAAK,UAAU;GAAK,EAAE;EAChF,EACF;EACA,GAAI,oBAAoB,EAAE,kBAAkB;GAAE,SAAS;GAAW,OAAO;EAAiB,EAAE;EAC5F,GAAI,kBAAkB,EAAE,eAAe;EACvC,GAAI,aAAa,EAAE,UAAU;EAC7B,GAAI,YAAY,EAAE,UAAU,SAAS,KAAK,IAAI,EAAE;CAClD;AACF;;;;;ACvDA,SAAgB,gBAAgB,SAA0D;CACxF,OAAO;EACL,YAAY;EACZ,SAAS;EACT,iBAAiB,QAAQ,MAAM,KAAK,MAAM,WAAW;GACnD,SAAS;GACT,UAAU,QAAQ;GAClB,MAAM,KAAK;GACX,MAAM,KAAK;EACb,EAAE;CACJ;AACF;;;;;;;;;;ACNA,SAAgB,SAAS,SAAmD;CAC1E,OAAO;EACL,YAAY;EACZ,SAAS;EACT,YAAY,QAAQ,MAAM,KAAK,UAAU;GACvC,SAAS;GACT,MAAM,KAAK;GACX,gBAAgB;IACd,SAAS;IACT,MAAM,KAAK;GACb;EACF,EAAE;CACJ;AACF;;;;;ACgBA,SAAgB,kBAAkB,SAA4D;CAC5F,MAAM,EACJ,MACA,KACA,MACA,aACA,OACA,WACA,SACA,QACA,cACA,UACA,mBACA,oBACA,iBACA,cACA,YACA,OACA,OACA,aACE;CAEJ,OAAO;EACL,YAAY;EACZ,SAAS;EACT;EACA,GAAI,OAAO,EAAE,IAAI;EACjB,GAAI,QAAQ,EAAE,KAAK;EACnB,GAAI,eAAe,EAAE,YAAY;EACjC,GAAI,SAAS,EAAE,MAAM;EACrB,GAAI,aAAa,EAAE,UAAU;EAC7B,GAAI,WAAW,EACb,SAAS;GACP,SAAS;GACT,GAAI,QAAQ,iBAAiB,EAAE,eAAe,QAAQ,cAAc;GACpE,GAAI,QAAQ,mBAAmB,EAAE,iBAAiB,QAAQ,gBAAgB;GAC1E,GAAI,QAAQ,iBAAiB,EAAE,eAAe,QAAQ,cAAc;GACpE,GAAI,QAAQ,cAAc,EAAE,YAAY,QAAQ,WAAW;GAC3D,GAAI,QAAQ,kBAAkB,EAAE,gBAAgB,QAAQ,eAAe;EACzE,EACF;EACA,GAAI,UAAU,EAAE,OAAO;EACvB,GAAI,gBAAgB,EAAE,aAAa;EACnC,GAAI,YAAY,EACd,UAAU,SAAS,KAAK,OAAO;GAC7B,SAAS;GACT,MAAM;EACR,EAAE,EACJ;EACA,GAAI,qBAAqB,EACvB,mBACE,OAAO,sBAAsB,WACzB;GAAE,SAAS;GAAqB,OAAO;EAAkB,IACzD;GACE,SAAS;GACT,UAAU,kBAAkB;GAC5B,UAAU,kBAAkB;EAC9B,EACR;EACA,GAAI,sBAAsB,EACxB,oBAAoB;GAClB,SAAS;GACT,MAAM,mBAAmB;GACzB,GAAI,mBAAmB,OAAO,EAAE,KAAK,mBAAmB,IAAI;EAC9D,EACF;EACA,GAAI,mBAAmB,EACrB,iBAAiB,gBAAgB,KAAK,SAAS;GAC7C,SAAS;GACT,MAAM,IAAI;GACV,GAAI,IAAI,OAAO,EAAE,KAAK,IAAI,IAAI;EAChC,EAAE,EACJ;EACA,GAAI,gBAAgB,EAClB,cAAc,aAAa,KAAK,QAAQ;GACtC,SAAS;GACT,WAAW,GAAG;GACd,aAAa,GAAG;GAChB,GAAI,GAAG,SAAS,EAAE,OAAO,GAAG,MAAM;GAClC,GAAI,GAAG,qBAAqB,EAAE,mBAAmB,GAAG,kBAAkB;GACtE,GAAI,GAAG,cAAc,EAAE,YAAY,GAAG,WAAW;EACnD,EAAE,EACJ;EACA,GAAI,cAAc,EAAE,WAAW;EAC/B,GAAI,SAAS,EAAE,OAAO;GAAE,SAAS;GAAS,MAAM;EAAM,EAAE;EACxD,GAAI,SAAS,EAAE,MAAM;EACrB,GAAI,YAAY,EACd,UAAU,SAAS,KAAK,OAAO;GAC7B,SAAS;GACT,MAAM,EAAE;GACR,GAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI;EAC5B,EAAE,EACJ;CACF;AACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getvitops/utils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Shared build-time utilities for the Vitops toolchain — favicon generation and friends.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"files": [
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"colorjs.io": "^0.5.2",
|
|
30
|
+
"parse5": "^7.3.0",
|
|
30
31
|
"png-to-ico": "^3.0.2",
|
|
31
32
|
"sharp": "^0.35.3"
|
|
32
33
|
},
|