New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@vueuse/head

Package Overview
Dependencies
Maintainers
3
Versions
97
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@vueuse/head - npm Package Compare versions

Comparing version 1.0.0-rc.4 to 1.0.0-rc.5

73

dist/index.d.ts

@@ -6,3 +6,2 @@ import * as vue from 'vue';

import { MaybeComputedRef } from '@vueuse/shared';
import { RawHeadAugmentation } from '@zhead/schema-raw';

@@ -34,4 +33,2 @@ interface HandlesDuplicates {

*
* @deprecated This can only be used with `useHeadRaw`.
*
* Alias for children

@@ -82,6 +79,14 @@ */

declare type ResolvedUseHeadInput<T extends MergeHead = {}> = Head$1<T & VueUseHeadSchema>;
declare type UseHeadRawInput = MaybeComputedRef<ReactiveHead<RawHeadAugmentation & VueUseHeadSchema>>;
interface HeadAttrs {
[k: string]: any;
}
declare type HookBeforeDomUpdate = (() => Promise<void | boolean> | void | boolean);
declare type HookTagsResolved = ((tags: HeadTag[]) => Promise<void> | void);
declare type HookEntriesResolved = ((entries: HeadEntry[]) => Promise<void> | void);
declare type HeadTagOptions = HeadEntryOptions & HandlesDuplicates & HasRenderPriority & RendersToBody & HasTextContent;
interface HeadEntryOptions {
raw?: boolean;
safe?: boolean;
resolved?: boolean;
beforeTagRender?: (tag: HeadTag) => void;
}

@@ -96,10 +101,2 @@ interface HeadEntry<T extends MergeHead = {}> {

declare type TagKeys = keyof Omit<HeadObjectPlain, 'titleTemplate'>;
interface HeadAttrs {
[k: string]: any;
}
declare type HookBeforeDomUpdate = (() => Promise<void | boolean> | void | boolean);
declare type HookTagsResolved = ((tags: HeadTag[]) => Promise<void> | void);
declare type HookEntriesResolved = ((entries: HeadEntry[]) => Promise<void> | void);
declare type HeadTagOptions = HeadEntryOptions & HandlesDuplicates & HasRenderPriority & RendersToBody & HasTextContent;
interface HeadTag {

@@ -112,2 +109,3 @@ tag: TagKeys;

entryId?: number;
beforeTagRender?: (tag: HeadTag) => void;
};

@@ -136,22 +134,3 @@ options?: HeadTagOptions;

declare const escapeHtml: (s: string) => string;
declare const escapeJS: (s: string) => string;
/**
* Attribute names must consist of one or more characters other than controls, U+0020 SPACE, U+0022 ("), U+0027 ('),
* U+003E (>), U+002F (/), U+003D (=), and noncharacters.
*
* We strip them for the attribute name as they shouldn't exist even if encoded.
*
* @see https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
*/
declare const stringifyAttrName: (str: string) => string;
/**
* Double-quoted attribute value must not contain any literal U+0022 QUOTATION MARK characters ("). Including
* < and > will cause HTML to be invalid.
*
* @see https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
*/
declare const stringifyAttrValue: (str: string) => string;
declare const stringifyAttrs: (attributes: Record<string, any>, options?: HeadEntryOptions) => string;
declare const propsToString: (props: HeadTag['props']) => string;
declare const tagToString: (tag: HeadTag) => string;

@@ -170,10 +149,2 @@ declare const resolveHeadEntries: (entries: HeadEntry[], force?: boolean) => HeadEntry<{}>[];

headEntries: HeadEntry<T>[];
/**
* Backwards compatibility function to fetch the headTags.
*
* This function forces reactivity resolving and is not performant.
*
* @deprecated Use hooks.
*/
headTags: HeadTag[];
addEntry: (entry: UseHeadInput<T>, options?: HeadEntryOptions) => HeadObjectApi<T>;

@@ -196,2 +167,18 @@ addReactiveEntry: (objs: UseHeadInput<T>, options?: HeadEntryOptions) => () => void;

Record<'resolved:tags', HookTagsResolved[]>;
/**
* Backwards compatibility function to fetch the headTags.
*
* This function forces reactivity resolving and is not performant.
*
* @deprecated Use hooks.
*/
headTags: HeadTag[];
/**
* Backwards compatibility function to add a head obj.
*
* Note: This will not support reactivity. Use `addReactiveEntry` instead.
*
* @deprecated Use addEntry
*/
addHeadObjs: (entry: UseHeadInput<T>, options?: HeadEntryOptions) => HeadObjectApi<T>;
}

@@ -206,4 +193,4 @@ declare const IS_BROWSER: boolean;

declare const useHead: <T extends MergeHead = {}>(headObj: UseHeadInput<T>) => void;
declare const useHeadRaw: (headObj: UseHeadRawInput) => void;
declare const useHeadSafe: <T extends MergeHead = {}>(headObj: UseHeadInput<T>) => void;
export { HTMLResult, HandlesDuplicates, HasRenderPriority, HasTextContent, Head, HeadAttrs, HeadClient, HeadEntry, HeadEntryOptions, HeadObject, HeadObjectApi, HeadObjectPlain, HeadTag, HeadTagOptions, HookBeforeDomUpdate, HookEntriesResolved, HookTagsResolved, IS_BROWSER, Never, RendersToBody, ResolvedUseHeadInput, TagKeys, UseHeadInput, UseHeadRawInput, VueUseHeadSchema, createElement, createHead, escapeHtml, escapeJS, headInputToTags, injectHead, isEqualNode, renderHeadToString, resolveHeadEntries, resolveHeadEntriesToTags, resolveUnrefHeadInput, setAttrs, sortTags, stringifyAttrName, stringifyAttrValue, stringifyAttrs, tagDedupeKey, tagToString, updateElements, useHead, useHeadRaw };
export { HTMLResult, HandlesDuplicates, HasRenderPriority, HasTextContent, Head, HeadAttrs, HeadClient, HeadEntry, HeadEntryOptions, HeadObject, HeadObjectApi, HeadObjectPlain, HeadTag, HeadTagOptions, HookBeforeDomUpdate, HookEntriesResolved, HookTagsResolved, IS_BROWSER, Never, RendersToBody, ResolvedUseHeadInput, TagKeys, UseHeadInput, VueUseHeadSchema, createElement, createHead, headInputToTags, injectHead, isEqualNode, propsToString, renderHeadToString, resolveHeadEntries, resolveHeadEntriesToTags, resolveUnrefHeadInput, setAttrs, sortTags, tagDedupeKey, tagToString, updateElements, useHead, useHeadSafe };

@@ -27,7 +27,6 @@ "use strict";

createHead: () => createHead,
escapeHtml: () => escapeHtml,
escapeJS: () => escapeJS,
headInputToTags: () => headInputToTags,
injectHead: () => injectHead,
isEqualNode: () => isEqualNode,
propsToString: () => propsToString,
renderHeadToString: () => renderHeadToString,

@@ -39,5 +38,2 @@ resolveHeadEntries: () => resolveHeadEntries,

sortTags: () => sortTags,
stringifyAttrName: () => stringifyAttrName,
stringifyAttrValue: () => stringifyAttrValue,
stringifyAttrs: () => stringifyAttrs,
tagDedupeKey: () => tagDedupeKey,

@@ -47,3 +43,3 @@ tagToString: () => tagToString,

useHead: () => useHead,
useHeadRaw: () => useHeadRaw
useHeadSafe: () => useHeadSafe
});

@@ -64,3 +60,3 @@ module.exports = __toCommonJS(src_exports);

// src/ssr/stringify-attrs.ts
// src/encoding/index.ts
var escapeHtml = (s) => s.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/'/g, "&#39;").replace(/</g, "&lt;").replace(/>/g, "&gt;");

@@ -84,23 +80,16 @@ var escapeJS = (s) => s.replace(/["'\\\n\r\u2028\u2029]/g, (character) => {

});
var stringifyAttrName = (str) => str.replace(/[\s"'><\/=]/g, "").replace(/[^a-zA-Z0-9_-]/g, "");
var stringifyAttrValue = (str) => escapeJS(str.replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;"));
var stringifyAttrs = (attributes, options = {}) => {
var sanitiseAttrName = (str) => str.replace(/[\s"'><\/=]/g, "").replace(/[^a-zA-Z0-9_-]/g, "");
var sanitiseAttrValue = (str) => escapeJS(
str.replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;")
);
// src/ssr/index.ts
var propsToString = (props) => {
const handledAttributes = [];
for (const [key, value] of Object.entries(attributes)) {
if (key === "children" || key === "innerHTML" || key === "textContent" || key === "key")
continue;
for (const [key, value] of Object.entries(props)) {
if (value === false || value == null)
continue;
let attribute = stringifyAttrName(key);
if (value !== true) {
const val = String(value);
if (options.raw) {
attribute += `="${val}"`;
} else {
if (attribute === "href" || attribute === "src")
attribute += `="${stringifyAttrValue(encodeURI(val))}"`;
else
attribute += `="${stringifyAttrValue(val)}"`;
}
}
let attribute = key;
if (value !== true)
attribute += `="${String(value).replace(/"/g, "&quot;")}"`;
handledAttributes.push(attribute);

@@ -110,13 +99,6 @@ }

};
// src/ssr/index.ts
var tagToString = (tag) => {
var _a, _b;
const body = ((_a = tag.options) == null ? void 0 : _a.body) ? ` ${BODY_TAG_ATTR_NAME}="true"` : "";
const attrs = stringifyAttrs(tag.props, tag.options);
if (SELF_CLOSING_TAGS.includes(tag.tag))
return `<${tag.tag}${attrs}${body}>`;
let children = tag.children || "";
children = ((_b = tag.options) == null ? void 0 : _b.raw) ? children : escapeJS(escapeHtml(children));
return `<${tag.tag}${attrs}${body}>${children}</${tag.tag}>`;
const attrs = propsToString(tag.props);
const openTag = `<${tag.tag}${attrs}>`;
return SELF_CLOSING_TAGS.includes(tag.tag) ? openTag : `${openTag}${tag.children || ""}</${tag.tag}>`;
};

@@ -131,3 +113,3 @@ var resolveHeadEntries = (entries, force) => {

var renderHeadToString = async (head) => {
var _a;
var _a, _b;
const headHtml = [];

@@ -144,2 +126,4 @@ const bodyHtml = [];

for (const tag of headTags) {
if ((_a = tag.options) == null ? void 0 : _a.beforeTagRender)
tag.options.beforeTagRender(tag);
if (tag.tag === "title") {

@@ -149,5 +133,5 @@ titleHtml = tagToString(tag);

for (const k in tag.props) {
attrs[tag.tag][stringifyAttrName(k)] = stringifyAttrValue(tag.props[k]);
attrs[tag.tag][sanitiseAttrName(k)] = sanitiseAttrValue(tag.props[k]);
}
} else if ((_a = tag.options) == null ? void 0 : _a.body) {
} else if ((_b = tag.options) == null ? void 0 : _b.body) {
bodyHtml.push(tagToString(tag));

@@ -164,18 +148,12 @@ } else {

get htmlAttrs() {
return stringifyAttrs(
{
...attrs.htmlAttrs,
[HEAD_ATTRS_KEY]: Object.keys(attrs.htmlAttrs).join(",")
},
{ raw: true }
);
return propsToString({
...attrs.htmlAttrs,
[HEAD_ATTRS_KEY]: Object.keys(attrs.htmlAttrs).join(",")
});
},
get bodyAttrs() {
return stringifyAttrs(
{
...attrs.bodyAttrs,
[HEAD_ATTRS_KEY]: Object.keys(attrs.bodyAttrs).join(",")
},
{ raw: true }
);
return propsToString({
...attrs.bodyAttrs,
[HEAD_ATTRS_KEY]: Object.keys(attrs.bodyAttrs).join(",")
});
},

@@ -252,2 +230,3 @@ get bodyTags() {

var resolveTag = (name, input, e) => {
var _a;
const tag = {

@@ -282,2 +261,4 @@ tag: name,

});
if ((_a = tag.options) == null ? void 0 : _a.body)
input[BODY_TAG_ATTR_NAME] = true;
tag.props = input;

@@ -321,3 +302,2 @@ return tag;

tags.forEach((tag, tagIdx) => {
var _a;
tag.runtime = tag.runtime || {};

@@ -331,8 +311,2 @@ tag.runtime.position = entryIndex * 1e4 + tagIdx;

}
if (!((_a = tag.options) == null ? void 0 : _a.raw)) {
for (const k in tag.props) {
if (k.startsWith("on") || k === "innerHTML")
delete tag.props[k];
}
}
deduping[tagDedupeKey(tag)] = tag;

@@ -384,3 +358,3 @@ });

var createElement = (tag, document) => {
var _a, _b;
var _a;
const $el = document.createElement(tag.tag);

@@ -391,7 +365,10 @@ Object.entries(tag.props).forEach(([k, v]) => {

});
if ((_a = tag.options) == null ? void 0 : _a.body) {
$el.setAttribute(BODY_TAG_ATTR_NAME, "true");
if (tag.children) {
if ((_a = tag.options) == null ? void 0 : _a.safe) {
if (tag.tag !== "script")
$el.textContent = tag.children;
} else {
$el.innerHTML = tag.children;
}
}
if (tag.children)
$el[((_b = tag.options) == null ? void 0 : _b.raw) ? "innerHTML" : "textContent"] = tag.children;
return $el;

@@ -460,3 +437,3 @@ };

newElements.forEach((t) => {
if (t.body === true)
if (t.body)
body.insertAdjacentElement("beforeend", t.element);

@@ -559,3 +536,3 @@ else

if (IS_BROWSER) {
const cleanUp = head.addReactiveEntry(obj, { raw: true });
const cleanUp = head.addReactiveEntry(obj);
(0, import_vue2.onBeforeUnmount)(() => {

@@ -565,3 +542,3 @@ cleanUp();

} else {
head.addEntry(obj, { raw: true });
head.addEntry(obj);
}

@@ -609,2 +586,5 @@ return () => {

},
addHeadObjs(input, options) {
return head.addEntry(input, options);
},
addEntry(input, options = {}) {

@@ -686,4 +666,26 @@ let resolved = false;

};
var useHeadRaw = (headObj) => {
_useHead(headObj, { raw: true });
var useHeadSafe = (headObj) => {
_useHead(
headObj,
{
beforeTagRender: (tag) => {
for (const p in tag.props) {
const value = tag.props[p];
const key = sanitiseAttrName(p);
delete tag.props[p];
if (!p.startsWith("on") && p !== "innerHTML") {
if (p === "href" || p === "src")
tag.props[key] = encodeURI(value);
tag.props[key] = sanitiseAttrValue(value);
}
}
if (tag.children) {
if (tag.tag === "script")
delete tag.children;
else
tag.children = escapeJS(escapeHtml(tag.children));
}
}
}
);
};

@@ -696,7 +698,6 @@ // Annotate the CommonJS export names for ESM import in node:

createHead,
escapeHtml,
escapeJS,
headInputToTags,
injectHead,
isEqualNode,
propsToString,
renderHeadToString,

@@ -708,5 +709,2 @@ resolveHeadEntries,

sortTags,
stringifyAttrName,
stringifyAttrValue,
stringifyAttrs,
tagDedupeKey,

@@ -716,3 +714,3 @@ tagToString,

useHead,
useHeadRaw
useHeadSafe
});
{
"name": "@vueuse/head",
"version": "1.0.0-rc.4",
"version": "1.0.0-rc.5",
"packageManager": "pnpm@7.5.0",

@@ -5,0 +5,0 @@ "description": "Document head manager for Vue 3. SSR ready.",

@@ -55,6 +55,4 @@ <h1 align='center'>@vueuse/head</h1>

To provide inner content you should use the `textContent` attribute (previously `children` which is deprecated).
To provide inner content you should use the `children` attribute.
Note: All values provided to `useHead` will be encoded to avoid XSS injection. If you need to insert raw data use `useHeadRaw`.
#### Example

@@ -75,3 +73,3 @@

style: [
{ type: 'text/css', textContent: 'body { background: red; }' },
{ type: 'text/css', children: 'body { background: red; }' },
],

@@ -107,11 +105,8 @@ script: [

### `useHeadRaw(head: MaybeComputedRef<HeadObject>)`
### `useHeadSafe(head: MaybeComputedRef<HeadObject>)`
Has the same functionality as `useHead` but does not encode values. This is useful for inserting raw data such as scripts
and attribute events.
Has the same functionality as `useHead` but encodes values to prevent XSS. This is useful for inserting untrusted data from third-parties.
When inserting raw inner content you should use `innerHTML`.
```ts
useHeadRaw({
useHeadSafe({
bodyAttrs: {

@@ -122,3 +117,3 @@ onfocus: 'alert("hello")',

{
innerHTML: 'alert("hello world")',
children: 'alert("hello world")',
},

@@ -155,3 +150,3 @@ ],

```ts
useHeadRaw({
useHead({
script: [

@@ -199,5 +194,2 @@ {

> :warning: Experimental feature
> Only available when rendering SSR.
To set the render priority of a tag you can use the `renderPriority` attribute:

@@ -204,0 +196,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc