@getvitops/astro 0.1.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/Head.astro +34 -0
- package/dist/index.d.mts +152 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +282 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +39 -0
- package/virtual.d.ts +18 -0
package/Head.astro
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
/**
|
|
3
|
+
* <Head /> — the Vitops design system's <head> contributions. Place inside your
|
|
4
|
+
* layout's <head>. Requires the getvitops() integration (it provides the
|
|
5
|
+
* `virtual:getvitops/head` config + copies the assets into public/).
|
|
6
|
+
*
|
|
7
|
+
* Renders: favicon + PWA manifest tags, and the web-component runtime scripts in
|
|
8
|
+
* canonical order/priority. It does NOT emit a stylesheet <link> — the CSS is
|
|
9
|
+
* imported into Astro's graph by the integration and Astro emits that link.
|
|
10
|
+
*/
|
|
11
|
+
// @ts-ignore — virtual module provided by the getvitops() integration at build time
|
|
12
|
+
import head from 'virtual:getvitops/head';
|
|
13
|
+
|
|
14
|
+
interface Props {
|
|
15
|
+
favicons?: boolean;
|
|
16
|
+
webComponents?: boolean;
|
|
17
|
+
}
|
|
18
|
+
const { favicons = head.favicons, webComponents = head.webComponents } = Astro.props;
|
|
19
|
+
const wc = head.wcBase;
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
{favicons && head.faviconLinks.map((l: { rel: string; href: string; type?: string; sizes?: string }) => (
|
|
23
|
+
<link rel={l.rel} href={l.href} type={l.type} sizes={l.sizes} />
|
|
24
|
+
))}
|
|
25
|
+
{favicons && head.themeColor && <meta name="theme-color" content={head.themeColor} />}
|
|
26
|
+
|
|
27
|
+
{webComponents && (
|
|
28
|
+
<>
|
|
29
|
+
<link rel="modulepreload" href={`${wc}/polyfills.js`} />
|
|
30
|
+
<script is:inline type="module" src={`${wc}/polyfills.js`}></script>
|
|
31
|
+
<script is:inline defer src={`${wc}/deferred.js`}></script>
|
|
32
|
+
<script is:inline type="module" src={`${wc}/elements.js`}></script>
|
|
33
|
+
</>
|
|
34
|
+
)}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { DefaultTreeAdapterTypes } from "parse5";
|
|
2
|
+
import { Format } from "@getvitops/generator";
|
|
3
|
+
import { AstroIntegration } from "astro";
|
|
4
|
+
import { HTMLAttributes, HTMLTag } from "astro/types";
|
|
5
|
+
|
|
6
|
+
//#region src/integration.d.ts
|
|
7
|
+
interface GetvitopsFaviconOptions {
|
|
8
|
+
/** Source SVG or PNG. */
|
|
9
|
+
source: string;
|
|
10
|
+
lowResSource?: string;
|
|
11
|
+
/** App name → enables `site.webmanifest`. */
|
|
12
|
+
name?: string;
|
|
13
|
+
/** PWA theme color (also `<meta name="theme-color">`). */
|
|
14
|
+
themeColor?: string;
|
|
15
|
+
backgroundColor?: string;
|
|
16
|
+
}
|
|
17
|
+
interface GetvitopsCssOptions {
|
|
18
|
+
/** Path to design-system.json (default 'design-system.json'). */
|
|
19
|
+
input?: string;
|
|
20
|
+
/** Output format (default 'tailwind'). */
|
|
21
|
+
format?: Format;
|
|
22
|
+
/** Directory the generated CSS is written to (default 'src/styles'). */
|
|
23
|
+
out?: string;
|
|
24
|
+
}
|
|
25
|
+
interface GetvitopsOptions {
|
|
26
|
+
favicon?: GetvitopsFaviconOptions;
|
|
27
|
+
/** Copy + link the web-component bundles (default true). */
|
|
28
|
+
webComponents?: boolean;
|
|
29
|
+
/** Generate + auto-inject the design-system CSS. Off unless provided. */
|
|
30
|
+
css?: GetvitopsCssOptions;
|
|
31
|
+
}
|
|
32
|
+
declare function getvitops(opts?: GetvitopsOptions): AstroIntegration;
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region types.d.ts
|
|
35
|
+
/** A translatable value: a plain string, or a locale → string map. */
|
|
36
|
+
type Localizable = string | Record<string, string>;
|
|
37
|
+
/**
|
|
38
|
+
* An HTML attribute bag. `class` may be a string or a class:list-style array
|
|
39
|
+
* (falsy entries dropped); everything else is passed through to the element.
|
|
40
|
+
*/
|
|
41
|
+
interface Attrs {
|
|
42
|
+
class?: string | (string | false | null | undefined)[];
|
|
43
|
+
[attr: string]: unknown;
|
|
44
|
+
}
|
|
45
|
+
/** An image reference used by image links. */
|
|
46
|
+
interface ImageRef {
|
|
47
|
+
src: string;
|
|
48
|
+
alt?: Localizable;
|
|
49
|
+
[key: string]: unknown;
|
|
50
|
+
}
|
|
51
|
+
/** A link with a text label. */
|
|
52
|
+
interface TextLink {
|
|
53
|
+
label: Localizable;
|
|
54
|
+
href: string;
|
|
55
|
+
attrs?: Attrs;
|
|
56
|
+
[key: string]: unknown;
|
|
57
|
+
}
|
|
58
|
+
/** A link whose content is an image. */
|
|
59
|
+
interface ImageLink {
|
|
60
|
+
image: ImageRef;
|
|
61
|
+
href: string;
|
|
62
|
+
attrs?: Attrs;
|
|
63
|
+
[key: string]: unknown;
|
|
64
|
+
}
|
|
65
|
+
/** Any link — text or image. */
|
|
66
|
+
type Link = TextLink | ImageLink;
|
|
67
|
+
/**
|
|
68
|
+
* A generic content element wrapper (discriminated by `type: 'element'`),
|
|
69
|
+
* carrying a payload `T` rendered as `Tag`.
|
|
70
|
+
*/
|
|
71
|
+
interface Elmnt<T = unknown, Tag extends HTMLTag = 'div'> {
|
|
72
|
+
type: 'element';
|
|
73
|
+
tag?: Tag;
|
|
74
|
+
attrs?: Attrs;
|
|
75
|
+
content?: T;
|
|
76
|
+
[key: string]: unknown;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* A renderable node tree — a text string (Localizable) or an element with
|
|
80
|
+
* optional attrs and either `text` shorthand or `children`.
|
|
81
|
+
*/
|
|
82
|
+
type ContentNode = string | {
|
|
83
|
+
tag: string;
|
|
84
|
+
attrs?: Attrs;
|
|
85
|
+
text?: Localizable;
|
|
86
|
+
children?: ContentNode[];
|
|
87
|
+
};
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region src/html.d.ts
|
|
90
|
+
type ChildNode = DefaultTreeAdapterTypes.ChildNode;
|
|
91
|
+
declare function parseRenderedSlots(html: string): ChildNode[];
|
|
92
|
+
declare function getAttribute(node: ChildNode, attrName: string): string | null;
|
|
93
|
+
declare function serialize(nodes: ChildNode | ChildNode[]): string[];
|
|
94
|
+
/**
|
|
95
|
+
* Style value types that can be combined. StyleObject is structurally
|
|
96
|
+
* compatible with astroHTML.JSX.CSSProperties (camelCase or --custom-prop keys).
|
|
97
|
+
*/
|
|
98
|
+
type StyleObject = Record<string, string | number | null | undefined>;
|
|
99
|
+
type StyleValue = string | StyleObject | null | undefined;
|
|
100
|
+
type StyleList = StyleValue | StyleValue[];
|
|
101
|
+
/**
|
|
102
|
+
* Combine multiple style formats into a single CSS string
|
|
103
|
+
* Similar to Astro's class:list but for inline styles
|
|
104
|
+
*/
|
|
105
|
+
declare function styleList(...styles: StyleList[]): string;
|
|
106
|
+
/**
|
|
107
|
+
* Element descriptor matching the El interface from env.d.ts
|
|
108
|
+
*/
|
|
109
|
+
interface El<Tag extends HTMLTag = HTMLTag> {
|
|
110
|
+
text: string;
|
|
111
|
+
tag: Tag;
|
|
112
|
+
attributes?: HTMLAttributes<Tag>;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Normalize a string or El object into an HTML string for use with set:html
|
|
116
|
+
*/
|
|
117
|
+
declare function toHtml<Tag extends HTMLTag>(content: string | El<Tag>): string;
|
|
118
|
+
/**
|
|
119
|
+
* Render an array of ContentNodes to an HTML string.
|
|
120
|
+
*
|
|
121
|
+
* @param nodes - Array of element nodes and/or text strings
|
|
122
|
+
* @param resolveText - Optional function to resolve Localizable values.
|
|
123
|
+
* Defaults to returning strings as-is and first locale value for maps.
|
|
124
|
+
*/
|
|
125
|
+
declare function nodesToHtml(nodes: ContentNode[], resolveText?: (value: Localizable) => string): string;
|
|
126
|
+
//#endregion
|
|
127
|
+
//#region src/types.d.ts
|
|
128
|
+
declare function isElmnt<T, Tag extends HTMLTag = 'div'>(item: any): item is Elmnt<T, Tag>;
|
|
129
|
+
declare function isLink(item: any): item is Link;
|
|
130
|
+
declare function isTextLink(item: any): item is TextLink;
|
|
131
|
+
declare function isImageLink(item: any): item is ImageLink;
|
|
132
|
+
//#endregion
|
|
133
|
+
//#region src/parts.d.ts
|
|
134
|
+
/**
|
|
135
|
+
* Resolve per-part attrs from a presentation type config.
|
|
136
|
+
* For the 'root' part, merges legacy `attrs` with `parts.root` (backward compat).
|
|
137
|
+
*/
|
|
138
|
+
declare function partAttrs(present: {
|
|
139
|
+
attrs?: Attrs;
|
|
140
|
+
parts?: Record<string, Attrs>;
|
|
141
|
+
} | undefined, part: string): Attrs;
|
|
142
|
+
//#endregion
|
|
143
|
+
//#region src/i18n.d.ts
|
|
144
|
+
/**
|
|
145
|
+
* Resolve a Localizable value to a string for the given locale.
|
|
146
|
+
* If the value is a plain string, it is returned as-is (treated as defaultLocale).
|
|
147
|
+
* If it is a locale map, the best match is returned.
|
|
148
|
+
*/
|
|
149
|
+
declare function t(value: Localizable | undefined, locale: string, defaultLocale: string): string;
|
|
150
|
+
//#endregion
|
|
151
|
+
export { Attrs, ChildNode, ContentNode, El, Elmnt, type GetvitopsCssOptions, type GetvitopsFaviconOptions, type GetvitopsOptions, ImageLink, ImageRef, Link, Localizable, StyleList, StyleValue, TextLink, getvitops as default, getAttribute, isElmnt, isImageLink, isLink, isTextLink, nodesToHtml, parseRenderedSlots, partAttrs, serialize, styleList, t, toHtml };
|
|
152
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/integration.ts","../types.ts","../src/html.ts","../src/types.ts","../src/parts.ts","../src/i18n.ts"],"mappings":";;;;;;UAuBiB,uBAAA;;EAEf,MAAA;EACA,YAAA;EAHe;EAKf,IAAA;;EAEA,UAAA;EACA,eAAA;AAAA;AAAA,UAGe,mBAAA;EAJf;EAMA,KAAA;EALe;EAOf,MAAA,GAAS,MAAM;EAJA;EAMf,GAAA;AAAA;AAAA,UAGe,gBAAA;EACf,OAAA,GAAU,uBAAA;EANV;EAQA,aAAA;EANA;EAQA,GAAA,GAAM,mBAAmB;AAAA;AAAA,iBA0BH,SAAA,CAAU,IAAA,GAAM,gBAAA,GAAwB,gBAAgB;;;;KC/DpE,WAAA,YAAuB,MAAM;;;;;UAMxB,KAAA;EACf,KAAA;EAAA,CACC,IAAY;AAAA;;UAIE,QAAA;EACf,GAAA;EACA,GAAA,GAAM,WAAW;EAAA,CAChB,GAAA;AAAA;;UAIc,QAAA;EACf,KAAA,EAAO,WAAA;EACP,IAAA;EACA,KAAA,GAAQ,KAAK;EAAA,CACZ,GAAA;AAAA;;UAIc,SAAA;EACf,KAAA,EAAO,QAAA;EACP,IAAA;EACA,KAAA,GAAQ,KAAK;EAAA,CACZ,GAAA;AAAA;;KAIS,IAAA,GAAO,QAAA,GAAW,SAAS;;;;;UAMtB,KAAA,0BAA+B,OAAA;EAC9C,IAAA;EACA,GAAA,GAAM,GAAA;EACN,KAAA,GAAQ,KAAA;EACR,OAAA,GAAU,CAAA;EAAA,CACT,GAAA;AAAA;;;AA9CsC;AAMzC;KA+CY,WAAA;EAGN,GAAA;EACA,KAAA,GAAQ,KAAA;EACR,IAAA,GAAO,WAAA;EACP,QAAA,GAAW,WAAA;AAAA;;;KClEL,SAAA,GAAY,uBAAA,CAAwB,SAAS;AAAA,iBAEzC,kBAAA,CAAmB,IAAA,WAAe,SAAS;AAAA,iBAK3C,YAAA,CAAa,IAAA,EAAM,SAAS,EAAE,QAAA;AAAA,iBAQ9B,SAAA,CAAU,KAAA,EAAO,SAAA,GAAY,SAAS;;;;;KAUjD,WAAA,GAAc,MAAM;AAAA,KACb,UAAA,YAAsB,WAAW;AAAA,KACjC,SAAA,GAAY,UAAA,GAAa,UAAU;;;AFA9B;AAGjB;iBEiBgB,SAAA,IAAa,MAAA,EAAQ,SAAS;;;;UAuB7B,EAAA,aAAe,OAAA,GAAU,OAAA;EACxC,IAAA;EACA,GAAA,EAAK,GAAA;EACL,UAAA,GAAa,cAAA,CAAe,GAAA;AAAA;AFlC9B;;;AAAA,iBE2EgB,MAAA,aAAmB,OAAA,EAAS,OAAA,WAAkB,EAAA,CAAG,GAAA;;;;;;;AFtEtC;iBEwJX,WAAA,CACd,KAAA,EAAO,WAAA,IACP,WAAA,IAAc,KAAA,EAAO,WAAW;;;iBCvMlB,OAAA,gBAAuB,OAAA,UAAiB,IAAA,QAAY,IAAA,IAAQ,KAAA,CAAM,CAAA,EAAG,GAAA;AAAA,iBAIrE,MAAA,CAAO,IAAA,QAAY,IAAA,IAAQ,IAAI;AAAA,iBAI/B,UAAA,CAAW,IAAA,QAAY,IAAA,IAAQ,QAAQ;AAAA,iBAIvC,WAAA,CAAY,IAAA,QAAY,IAAA,IAAQ,SAAS;;;;;;;iBCTzC,SAAA,CACd,OAAA;EAAW,KAAA,GAAQ,KAAA;EAAO,KAAA,GAAQ,MAAA,SAAe,KAAA;AAAA,eACjD,IAAA,WACC,KAAA;;;;;;;;iBCFa,CAAA,CACd,KAAA,EAAO,WAAW,cAClB,MAAA,UACA,aAAA"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import { cpSync, existsSync } from "node:fs";
|
|
2
|
+
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { faviconLinks, generateFavicons, writeFaviconManifest } from "@getvitops/utils";
|
|
5
|
+
import vitops from "@getvitops/vite";
|
|
6
|
+
import tailwindcss from "@tailwindcss/vite";
|
|
7
|
+
import { parseFragment, serialize as serialize$1 } from "parse5";
|
|
8
|
+
|
|
9
|
+
//#region src/integration.ts
|
|
10
|
+
/**
|
|
11
|
+
* @getvitops/astro — the Astro integration. One entry wires the design system's
|
|
12
|
+
* `<head>` contributions into a consumer site:
|
|
13
|
+
* - favicons + PWA manifest (generated into public/),
|
|
14
|
+
* - the web-component runtime bundles (copied into public/vitops/),
|
|
15
|
+
* - (opt-in) the design-system CSS, generated + auto-injected (no manual import).
|
|
16
|
+
* The `<Head />` component (shipped alongside) renders the tags, reading resolved
|
|
17
|
+
* config from the `virtual:getvitops/head` module this integration provides.
|
|
18
|
+
*/
|
|
19
|
+
const VIRTUAL_ID = "virtual:getvitops/head";
|
|
20
|
+
const RESOLVED_ID = `\0${VIRTUAL_ID}`;
|
|
21
|
+
function virtualHeadPlugin(data) {
|
|
22
|
+
return {
|
|
23
|
+
name: "@getvitops/astro:virtual-head",
|
|
24
|
+
resolveId(id) {
|
|
25
|
+
return id === VIRTUAL_ID ? RESOLVED_ID : null;
|
|
26
|
+
},
|
|
27
|
+
load(id) {
|
|
28
|
+
return id === RESOLVED_ID ? `export default ${JSON.stringify(data)};` : null;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function getvitops(opts = {}) {
|
|
33
|
+
return {
|
|
34
|
+
name: "@getvitops/astro",
|
|
35
|
+
hooks: { "astro:config:setup": async ({ config, updateConfig, injectScript, logger }) => {
|
|
36
|
+
const root = fileURLToPath(config.root);
|
|
37
|
+
const publicDir = fileURLToPath(config.publicDir);
|
|
38
|
+
const webComponents = opts.webComponents !== false;
|
|
39
|
+
const hasManifest = !!(opts.favicon?.name && opts.favicon?.themeColor);
|
|
40
|
+
let hasSvg = false;
|
|
41
|
+
if (opts.favicon) {
|
|
42
|
+
const source = resolve(root, opts.favicon.source);
|
|
43
|
+
hasSvg = source.endsWith(".svg");
|
|
44
|
+
await generateFavicons({
|
|
45
|
+
source,
|
|
46
|
+
outputDir: publicDir,
|
|
47
|
+
...opts.favicon.lowResSource ? { lowResSource: resolve(root, opts.favicon.lowResSource) } : {}
|
|
48
|
+
});
|
|
49
|
+
if (opts.favicon.name && opts.favicon.themeColor) await writeFaviconManifest(publicDir, {
|
|
50
|
+
name: opts.favicon.name,
|
|
51
|
+
themeColor: opts.favicon.themeColor,
|
|
52
|
+
...opts.favicon.backgroundColor ? { backgroundColor: opts.favicon.backgroundColor } : {}
|
|
53
|
+
});
|
|
54
|
+
logger.info("generated favicons + manifest → public/");
|
|
55
|
+
}
|
|
56
|
+
if (webComponents) {
|
|
57
|
+
const coreDist = join(dirname(fileURLToPath(import.meta.resolve("@getvitops/core/package.json"))), "dist");
|
|
58
|
+
const dest = join(publicDir, "vitops");
|
|
59
|
+
if (existsSync(coreDist)) {
|
|
60
|
+
for (const f of [
|
|
61
|
+
"polyfills.js",
|
|
62
|
+
"deferred.js",
|
|
63
|
+
"elements.js",
|
|
64
|
+
"polyfills"
|
|
65
|
+
]) {
|
|
66
|
+
const src = join(coreDist, f);
|
|
67
|
+
if (existsSync(src)) cpSync(src, join(dest, f), { recursive: true });
|
|
68
|
+
}
|
|
69
|
+
logger.info("copied web-component bundles → public/vitops/");
|
|
70
|
+
} else logger.warn(`@getvitops/core dist not found (${coreDist}); run build:core. Skipping WC copy.`);
|
|
71
|
+
}
|
|
72
|
+
updateConfig({ vite: { plugins: [virtualHeadPlugin({
|
|
73
|
+
favicons: !!opts.favicon,
|
|
74
|
+
faviconLinks: opts.favicon ? faviconLinks({
|
|
75
|
+
hasSvg,
|
|
76
|
+
manifest: hasManifest
|
|
77
|
+
}) : [],
|
|
78
|
+
themeColor: opts.favicon?.themeColor ?? null,
|
|
79
|
+
webComponents,
|
|
80
|
+
wcBase: "/vitops"
|
|
81
|
+
})] } });
|
|
82
|
+
if (opts.css) {
|
|
83
|
+
const format = opts.css.format ?? "tailwind";
|
|
84
|
+
const out = opts.css.out ?? "src/styles";
|
|
85
|
+
const plugins = [vitops({
|
|
86
|
+
input: opts.css.input ?? "design-system.json",
|
|
87
|
+
format,
|
|
88
|
+
out
|
|
89
|
+
})];
|
|
90
|
+
if (format === "tailwind") plugins.push(...tailwindcss());
|
|
91
|
+
updateConfig({ vite: { plugins } });
|
|
92
|
+
const cssFile = format === "tailwind" ? "tailwind.css" : "styles.css";
|
|
93
|
+
const cssPath = resolve(root, out, cssFile);
|
|
94
|
+
injectScript("page-ssr", `import ${JSON.stringify(cssPath)};`);
|
|
95
|
+
logger.info(`design-system CSS (${format}) auto-injected from ${out}/${cssFile}`);
|
|
96
|
+
}
|
|
97
|
+
} }
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
//#endregion
|
|
102
|
+
//#region src/html.ts
|
|
103
|
+
function parseRenderedSlots(html) {
|
|
104
|
+
return parseFragment(html).childNodes;
|
|
105
|
+
}
|
|
106
|
+
function getAttribute(node, attrName) {
|
|
107
|
+
if ("attrs" in node) {
|
|
108
|
+
const attr = node.attrs.find((a) => a.name === attrName);
|
|
109
|
+
return attr ? attr.value : null;
|
|
110
|
+
}
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
function serialize(nodes) {
|
|
114
|
+
return (Array.isArray(nodes) ? nodes : [nodes]).map((node) => serialize$1(node));
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Convert camelCase to kebab-case, preserving CSS custom properties (--var-name)
|
|
118
|
+
*/
|
|
119
|
+
function toKebabCase(str) {
|
|
120
|
+
if (str.startsWith("--")) return str;
|
|
121
|
+
return str.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
122
|
+
}
|
|
123
|
+
function styleObjectToString(obj) {
|
|
124
|
+
return Object.entries(obj).filter(([, value]) => value != null).map(([key, value]) => `${toKebabCase(key)}: ${value}`).join("; ");
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Combine multiple style formats into a single CSS string
|
|
128
|
+
* Similar to Astro's class:list but for inline styles
|
|
129
|
+
*/
|
|
130
|
+
function styleList(...styles) {
|
|
131
|
+
const result = [];
|
|
132
|
+
const process = (item) => {
|
|
133
|
+
if (item == null) return;
|
|
134
|
+
if (Array.isArray(item)) item.forEach(process);
|
|
135
|
+
else if (typeof item === "string") {
|
|
136
|
+
const trimmed = item.trim();
|
|
137
|
+
if (trimmed) result.push(trimmed);
|
|
138
|
+
} else {
|
|
139
|
+
const str = styleObjectToString(item);
|
|
140
|
+
if (str) result.push(str);
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
styles.forEach(process);
|
|
144
|
+
return result.join("; ");
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Type guard to check if a value is an El object
|
|
148
|
+
*/
|
|
149
|
+
function isEl(value) {
|
|
150
|
+
return typeof value === "object" && value !== null && "tag" in value && "text" in value;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Convert HTML attributes object to a string for use in markup
|
|
154
|
+
*/
|
|
155
|
+
function attributesToString(attrs) {
|
|
156
|
+
const parts = [];
|
|
157
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
158
|
+
if (value == null || value === false) continue;
|
|
159
|
+
if (value === true) parts.push(key);
|
|
160
|
+
else if (key === "style" && typeof value === "object") parts.push(`style="${styleList(value)}"`);
|
|
161
|
+
else {
|
|
162
|
+
const escaped = (Array.isArray(value) ? value.filter((v) => typeof v === "string" && v !== "").join(" ") : typeof value === "object" ? JSON.stringify(value) : String(value)).replace(/"/g, """);
|
|
163
|
+
parts.push(`${key}="${escaped}"`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return parts.join(" ");
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Normalize a string or El object into an HTML string for use with set:html
|
|
170
|
+
*/
|
|
171
|
+
function toHtml(content) {
|
|
172
|
+
if (!isEl(content)) return content;
|
|
173
|
+
const { tag, text, attributes } = content;
|
|
174
|
+
const attrStr = attributes ? attributesToString(attributes) : "";
|
|
175
|
+
const t = String(tag);
|
|
176
|
+
return attrStr ? `<${t} ${attrStr}>${text}</${t}>` : `<${t}>${text}</${t}>`;
|
|
177
|
+
}
|
|
178
|
+
/** Void elements that must not have a closing tag */
|
|
179
|
+
const VOID_ELEMENTS = new Set([
|
|
180
|
+
"area",
|
|
181
|
+
"base",
|
|
182
|
+
"br",
|
|
183
|
+
"col",
|
|
184
|
+
"embed",
|
|
185
|
+
"hr",
|
|
186
|
+
"img",
|
|
187
|
+
"input",
|
|
188
|
+
"link",
|
|
189
|
+
"meta",
|
|
190
|
+
"param",
|
|
191
|
+
"source",
|
|
192
|
+
"track",
|
|
193
|
+
"wbr"
|
|
194
|
+
]);
|
|
195
|
+
/** Default text resolver — strings pass through, locale maps return first value */
|
|
196
|
+
function defaultResolveText(value) {
|
|
197
|
+
if (typeof value === "string") return value;
|
|
198
|
+
return Object.values(value)[0] ?? "";
|
|
199
|
+
}
|
|
200
|
+
/** Escape text content for safe HTML output */
|
|
201
|
+
function escapeHtml(text) {
|
|
202
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Render a single ContentNode to an HTML string.
|
|
206
|
+
*/
|
|
207
|
+
function nodeToHtml(node, resolveText) {
|
|
208
|
+
if (typeof node === "string") return escapeHtml(resolveText(node));
|
|
209
|
+
const { tag, attrs, text, children } = node;
|
|
210
|
+
const attrStr = attrs ? attributesToString(attrs) : "";
|
|
211
|
+
const open = attrStr ? `<${tag} ${attrStr}>` : `<${tag}>`;
|
|
212
|
+
if (VOID_ELEMENTS.has(tag)) return open;
|
|
213
|
+
let inner = "";
|
|
214
|
+
if (text != null) inner = escapeHtml(resolveText(text));
|
|
215
|
+
else if (children?.length) inner = children.map((child) => nodeToHtml(child, resolveText)).join("");
|
|
216
|
+
return `${open}${inner}</${tag}>`;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Render an array of ContentNodes to an HTML string.
|
|
220
|
+
*
|
|
221
|
+
* @param nodes - Array of element nodes and/or text strings
|
|
222
|
+
* @param resolveText - Optional function to resolve Localizable values.
|
|
223
|
+
* Defaults to returning strings as-is and first locale value for maps.
|
|
224
|
+
*/
|
|
225
|
+
function nodesToHtml(nodes, resolveText = defaultResolveText) {
|
|
226
|
+
return nodes.map((node) => nodeToHtml(node, resolveText)).join("");
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
//#endregion
|
|
230
|
+
//#region src/types.ts
|
|
231
|
+
function isElmnt(item) {
|
|
232
|
+
return item && item.type === "element";
|
|
233
|
+
}
|
|
234
|
+
function isLink(item) {
|
|
235
|
+
return item && ("label" in item || "image" in item) && "href" in item;
|
|
236
|
+
}
|
|
237
|
+
function isTextLink(item) {
|
|
238
|
+
return item && "label" in item && "href" in item;
|
|
239
|
+
}
|
|
240
|
+
function isImageLink(item) {
|
|
241
|
+
return item && "image" in item && "href" in item;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
//#endregion
|
|
245
|
+
//#region src/parts.ts
|
|
246
|
+
/**
|
|
247
|
+
* Resolve per-part attrs from a presentation type config.
|
|
248
|
+
* For the 'root' part, merges legacy `attrs` with `parts.root` (backward compat).
|
|
249
|
+
*/
|
|
250
|
+
function partAttrs(present, part) {
|
|
251
|
+
const fromParts = present?.parts?.[part];
|
|
252
|
+
if (part === "root") {
|
|
253
|
+
const legacy = present?.attrs;
|
|
254
|
+
if (!legacy && !fromParts) return {};
|
|
255
|
+
const { class: lc, ...lr } = legacy ?? {};
|
|
256
|
+
const { class: pc, ...pr } = fromParts ?? {};
|
|
257
|
+
const classes = [lc, pc].flat().filter((c) => typeof c === "string" && c !== "");
|
|
258
|
+
return {
|
|
259
|
+
...classes.length ? { class: classes } : {},
|
|
260
|
+
...lr,
|
|
261
|
+
...pr
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
return fromParts ?? {};
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
//#endregion
|
|
268
|
+
//#region src/i18n.ts
|
|
269
|
+
/**
|
|
270
|
+
* Resolve a Localizable value to a string for the given locale.
|
|
271
|
+
* If the value is a plain string, it is returned as-is (treated as defaultLocale).
|
|
272
|
+
* If it is a locale map, the best match is returned.
|
|
273
|
+
*/
|
|
274
|
+
function t(value, locale, defaultLocale) {
|
|
275
|
+
if (value == null) return "";
|
|
276
|
+
if (typeof value === "string") return value;
|
|
277
|
+
return value[locale] ?? value[defaultLocale] ?? "";
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
//#endregion
|
|
281
|
+
export { getvitops as default, getAttribute, isElmnt, isImageLink, isLink, isTextLink, nodesToHtml, parseRenderedSlots, partAttrs, serialize, styleList, t, toHtml };
|
|
282
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["s"],"sources":["../src/integration.ts","../src/html.ts","../src/types.ts","../src/parts.ts","../src/i18n.ts"],"sourcesContent":["/**\n * @getvitops/astro — the Astro integration. One entry wires the design system's\n * `<head>` contributions into a consumer site:\n * - favicons + PWA manifest (generated into public/),\n * - the web-component runtime bundles (copied into public/vitops/),\n * - (opt-in) the design-system CSS, generated + auto-injected (no manual import).\n * The `<Head />` component (shipped alongside) renders the tags, reading resolved\n * config from the `virtual:getvitops/head` module this integration provides.\n */\nimport { cpSync, existsSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { Format } from '@getvitops/generator';\nimport {\n type FaviconLink,\n faviconLinks,\n generateFavicons,\n writeFaviconManifest,\n} from '@getvitops/utils';\nimport vitops from '@getvitops/vite';\nimport tailwindcss from '@tailwindcss/vite';\nimport type { AstroIntegration } from 'astro';\n\nexport interface GetvitopsFaviconOptions {\n /** Source SVG or PNG. */\n source: string;\n lowResSource?: string;\n /** App name → enables `site.webmanifest`. */\n name?: string;\n /** PWA theme color (also `<meta name=\"theme-color\">`). */\n themeColor?: string;\n backgroundColor?: string;\n}\n\nexport interface GetvitopsCssOptions {\n /** Path to design-system.json (default 'design-system.json'). */\n input?: string;\n /** Output format (default 'tailwind'). */\n format?: Format;\n /** Directory the generated CSS is written to (default 'src/styles'). */\n out?: string;\n}\n\nexport interface GetvitopsOptions {\n favicon?: GetvitopsFaviconOptions;\n /** Copy + link the web-component bundles (default true). */\n webComponents?: boolean;\n /** Generate + auto-inject the design-system CSS. Off unless provided. */\n css?: GetvitopsCssOptions;\n}\n\ninterface HeadData {\n favicons: boolean;\n faviconLinks: FaviconLink[];\n themeColor: string | null;\n webComponents: boolean;\n wcBase: string;\n}\n\nconst VIRTUAL_ID = 'virtual:getvitops/head';\nconst RESOLVED_ID = `\\0${VIRTUAL_ID}`;\n\nfunction virtualHeadPlugin(data: HeadData) {\n return {\n name: '@getvitops/astro:virtual-head',\n resolveId(id: string) {\n return id === VIRTUAL_ID ? RESOLVED_ID : null;\n },\n load(id: string) {\n return id === RESOLVED_ID ? `export default ${JSON.stringify(data)};` : null;\n },\n };\n}\n\nexport default function getvitops(opts: GetvitopsOptions = {}): AstroIntegration {\n return {\n name: '@getvitops/astro',\n hooks: {\n 'astro:config:setup': async ({ config, updateConfig, injectScript, logger }) => {\n const root = fileURLToPath(config.root);\n const publicDir = fileURLToPath(config.publicDir);\n const webComponents = opts.webComponents !== false;\n const hasManifest = !!(opts.favicon?.name && opts.favicon?.themeColor);\n let hasSvg = false;\n\n // 1. Favicons + manifest → public/\n if (opts.favicon) {\n const source = resolve(root, opts.favicon.source);\n hasSvg = source.endsWith('.svg');\n await generateFavicons({\n source,\n outputDir: publicDir,\n ...(opts.favicon.lowResSource\n ? { lowResSource: resolve(root, opts.favicon.lowResSource) }\n : {}),\n });\n if (opts.favicon.name && opts.favicon.themeColor) {\n await writeFaviconManifest(publicDir, {\n name: opts.favicon.name,\n themeColor: opts.favicon.themeColor,\n ...(opts.favicon.backgroundColor\n ? { backgroundColor: opts.favicon.backgroundColor }\n : {}),\n });\n }\n logger.info('generated favicons + manifest → public/');\n }\n\n // 2. Web-component bundles → public/vitops/\n if (webComponents) {\n const corePkg = fileURLToPath(import.meta.resolve('@getvitops/core/package.json'));\n const coreDist = join(dirname(corePkg), 'dist');\n const dest = join(publicDir, 'vitops');\n if (existsSync(coreDist)) {\n for (const f of ['polyfills.js', 'deferred.js', 'elements.js', 'polyfills']) {\n const src = join(coreDist, f);\n if (existsSync(src)) cpSync(src, join(dest, f), { recursive: true });\n }\n logger.info('copied web-component bundles → public/vitops/');\n } else {\n logger.warn(\n `@getvitops/core dist not found (${coreDist}); run build:core. Skipping WC copy.`,\n );\n }\n }\n\n // 3. Virtual head module for <Head/>\n updateConfig({\n vite: {\n plugins: [\n virtualHeadPlugin({\n favicons: !!opts.favicon,\n faviconLinks: opts.favicon ? faviconLinks({ hasSvg, manifest: hasManifest }) : [],\n themeColor: opts.favicon?.themeColor ?? null,\n webComponents,\n wcBase: '/vitops',\n }),\n ],\n },\n });\n\n // 4. CSS — generate + compile + auto-inject (consumer imports nothing).\n if (opts.css) {\n const format: Format = opts.css.format ?? 'tailwind';\n const out = opts.css.out ?? 'src/styles';\n const plugins = [vitops({ input: opts.css.input ?? 'design-system.json', format, out })];\n // tailwindcss() is typed against a newer vite than @getvitops/vite's\n // peer; the Plugin shapes are structurally compatible at runtime\n // (Astro forwards them verbatim), so bridge the two type identities.\n if (format === 'tailwind') plugins.push(...(tailwindcss() as unknown as typeof plugins));\n updateConfig({ vite: { plugins } });\n const cssFile = format === 'tailwind' ? 'tailwind.css' : 'styles.css';\n const cssPath = resolve(root, out, cssFile);\n injectScript('page-ssr', `import ${JSON.stringify(cssPath)};`);\n logger.info(`design-system CSS (${format}) auto-injected from ${out}/${cssFile}`);\n }\n },\n },\n };\n}\n","import { parseFragment, serialize as s, type DefaultTreeAdapterTypes } from 'parse5';\nimport type { HTMLTag, HTMLAttributes } from 'astro/types';\nimport type { Localizable, ContentNode } from '../types.js';\n\nexport type ChildNode = DefaultTreeAdapterTypes.ChildNode;\n\nexport function parseRenderedSlots(html: string): ChildNode[] {\n const document = parseFragment(html);\n return document.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/**\n * Style value types that can be combined. StyleObject is structurally\n * compatible with astroHTML.JSX.CSSProperties (camelCase or --custom-prop keys).\n */\ntype StyleObject = Record<string, string | number | null | undefined>;\nexport type StyleValue = string | StyleObject | null | undefined;\nexport type StyleList = StyleValue | StyleValue[];\n\n/**\n * Convert camelCase to kebab-case, preserving CSS custom properties (--var-name)\n */\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/**\n * Combine multiple style formats into a single CSS string\n * Similar to Astro's class:list but for inline styles\n */\nexport function styleList(...styles: StyleList[]): string {\n const result: string[] = [];\n\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\n styles.forEach(process);\n return result.join('; ');\n}\n\n/**\n * Element descriptor matching the El interface from env.d.ts\n */\nexport interface El<Tag extends HTMLTag = HTMLTag> {\n text: string;\n tag: Tag;\n attributes?: HTMLAttributes<Tag>;\n}\n\n/**\n * Type guard to check if a value is an El object\n */\nfunction isEl(value: string | El): value is El {\n return typeof value === 'object' && value !== null && 'tag' in value && 'text' in value;\n}\n\n/**\n * Convert HTML attributes object to a string for use in markup\n */\nfunction attributesToString(attrs: Record<string, unknown>): string {\n const parts: string[] = [];\n\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 // Class:list arrays join like Astro; other objects stringify as JSON\n // (never \"[object Object]\"). Escape double quotes for the attribute.\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 const escaped = text.replace(/\"/g, '"');\n parts.push(`${key}=\"${escaped}\"`);\n }\n }\n\n return parts.join(' ');\n}\n\n/**\n * Normalize a string or El object into an HTML string for use with set:html\n */\nexport function toHtml<Tag extends HTMLTag>(content: string | El<Tag>): string {\n if (!isEl(content)) {\n return content;\n }\n\n const { tag, text, attributes } = content;\n const attrStr = attributes ? attributesToString(attributes) : '';\n // HTMLTag is a key type (string | number | symbol to tsc) — stringify for templates.\n const t = String(tag);\n\n return attrStr ? `<${t} ${attrStr}>${text}</${t}>` : `<${t}>${text}</${t}>`;\n}\n\n// ---------------------------------------------------------------------------\n// Node tree renderer — { tag, attrs, children }\n// ---------------------------------------------------------------------------\n\n/** Void elements that must not have a closing tag */\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\n/** Default text resolver — strings pass through, locale maps return first value */\nfunction defaultResolveText(value: Localizable): string {\n if (typeof value === 'string') return value;\n const values = Object.values(value);\n return values[0] ?? '';\n}\n\n/** Escape text content for safe HTML output */\nfunction escapeHtml(text: string): string {\n return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n}\n\n/**\n * Render a single ContentNode to an HTML string.\n */\nfunction nodeToHtml(node: ContentNode, resolveText: (value: Localizable) => string): string {\n // String child → text node\n if (typeof node === 'string') {\n return escapeHtml(resolveText(node));\n }\n\n const { tag, attrs, text, children } = node;\n const attrStr = attrs ? attributesToString(attrs) : '';\n const open = attrStr ? `<${tag} ${attrStr}>` : `<${tag}>`;\n\n if (VOID_ELEMENTS.has(tag)) {\n return open;\n }\n\n // text is shorthand for children: [\"string\"]\n let inner = '';\n if (text != null) {\n inner = escapeHtml(resolveText(text));\n } else if (children?.length) {\n inner = children.map((child) => nodeToHtml(child, resolveText)).join('');\n }\n\n return `${open}${inner}</${tag}>`;\n}\n\n/**\n * Render an array of ContentNodes to an HTML string.\n *\n * @param nodes - Array of element nodes and/or text strings\n * @param resolveText - Optional function to resolve Localizable values.\n * Defaults to returning strings as-is and first locale value for maps.\n */\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","import type { Elmnt, Link, TextLink, ImageLink } from '../types.js';\nimport type { HTMLTag } from 'astro/types';\n\nexport function isElmnt<T, Tag extends HTMLTag = '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","import type { Attrs } from '../types.js';\n\n/**\n * Resolve per-part attrs from a presentation type config.\n * For the 'root' part, 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 // Flatten class:list-style values and keep only real class strings.\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","import type { Localizable } from '../types.js';\n\n/**\n * Resolve a Localizable value to a string for the given locale.\n * If the value is a plain string, it is returned as-is (treated as defaultLocale).\n * If it is a locale map, the best match is returned.\n */\nexport function t(\n value: Localizable | undefined,\n locale: string,\n defaultLocale: string,\n): string {\n if (value == null) return '';\n if (typeof value === 'string') return value;\n return value[locale] ?? value[defaultLocale] ?? '';\n}\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@getvitops/astro",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Astro integration for the Vitops design system — favicons/PWA, web-component scripts, and CSS, via a getvitops() integration + <Head /> component.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist",
|
|
8
|
+
"Head.astro",
|
|
9
|
+
"virtual.d.ts"
|
|
10
|
+
],
|
|
11
|
+
"type": "module",
|
|
12
|
+
"types": "./dist/index.d.mts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.mts",
|
|
16
|
+
"import": "./dist/index.mjs"
|
|
17
|
+
},
|
|
18
|
+
"./Head.astro": "./Head.astro",
|
|
19
|
+
"./package.json": "./package.json"
|
|
20
|
+
},
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@tailwindcss/vite": "^4.3.3",
|
|
26
|
+
"parse5": "^7.3.0",
|
|
27
|
+
"tailwindcss": "^4.3.3",
|
|
28
|
+
"@getvitops/core": "0.2.0",
|
|
29
|
+
"@getvitops/vite": "0.2.0",
|
|
30
|
+
"@getvitops/utils": "0.2.0",
|
|
31
|
+
"@getvitops/generator": "0.2.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"astro": "^7.1.2"
|
|
35
|
+
},
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"astro": ">=7"
|
|
38
|
+
}
|
|
39
|
+
}
|
package/virtual.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Types for the virtual module the getvitops() integration provides to <Head />. */
|
|
2
|
+
declare module 'virtual:getvitops/head' {
|
|
3
|
+
interface FaviconLink {
|
|
4
|
+
rel: string;
|
|
5
|
+
href: string;
|
|
6
|
+
type?: string;
|
|
7
|
+
sizes?: string;
|
|
8
|
+
}
|
|
9
|
+
interface HeadData {
|
|
10
|
+
favicons: boolean;
|
|
11
|
+
faviconLinks: FaviconLink[];
|
|
12
|
+
themeColor: string | null;
|
|
13
|
+
webComponents: boolean;
|
|
14
|
+
wcBase: string;
|
|
15
|
+
}
|
|
16
|
+
const data: HeadData;
|
|
17
|
+
export default data;
|
|
18
|
+
}
|