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

@lwc/ssr-runtime

Package Overview
Dependencies
Maintainers
0
Versions
83
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@lwc/ssr-runtime - npm Package Compare versions

Comparing version 8.1.2 to 8.1.3

dist/validate-style-text-contents.d.ts

173

dist/index.cjs.js

@@ -9,2 +9,50 @@ /**

/*
* Copyright (c) 2024, Salesforce, Inc.
* All rights reserved.
* SPDX-License-Identifier: MIT
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
*/
/**
* Per the HTML spec on restrictions for "raw text elements" like `<style>`:
*
* > The text in raw text and escapable raw text elements must not contain any occurrences of the string
* > "</" (U+003C LESS-THAN SIGN, U+002F SOLIDUS) followed by characters that case-insensitively match the tag name of
* > the element followed by one of:
* > - U+0009 CHARACTER TABULATION (tab)
* > - U+000A LINE FEED (LF)
* > - U+000C FORM FEED (FF)
* > - U+000D CARRIAGE RETURN (CR)
* > - U+0020 SPACE
* > - U+003E GREATER-THAN SIGN (>), or
* > - U+002F SOLIDUS (/)
* @see https://html.spec.whatwg.org/multipage/syntax.html#cdata-rcdata-restrictions
*/
const INVALID_STYLE_CONTENT = /<\/style[\t\n\f\r >/]/i;
/**
* The text content inside `<style>` is a special case. It is _only_ rendered by the LWC engine itself; `<style>` tags
* are disallowed inside of HTML templates.
*
* The `<style>` tag is unusual in how it's defined in HTML. Like `<script>`, it is considered a "raw text element,"
* which means that it is parsed as raw text, but certain character sequences are disallowed, namely to avoid XSS
* attacks like `</style><script>alert("pwned")</script>`.
*
* This also means that we cannot use "normal" HTML escaping inside `<style>` tags, e.g. we cannot use `&lt;`,
* `&gt;`, etc., because these are treated as-is by the HTML parser.
*
*
* @param contents CSS source to validate
* @throws Throws if the contents provided are not valid.
* @see https://html.spec.whatwg.org/multipage/syntax.html#raw-text-elements
* @see https://github.com/salesforce/lwc/issues/3439
* @example
* validateStyleTextContents('div { color: red }') // Ok
* validateStyleTextContents('</style><script>alert("pwned")</script>') // Throws
*/
function validateStyleTextContents(contents) {
if (INVALID_STYLE_CONTENT.test(contents)) {
throw new Error('CSS contains unsafe characters and cannot be serialized inside a style element');
}
}
/*
* Copyright (c) 2024, salesforce.com, inc.

@@ -15,2 +63,9 @@ * All rights reserved.

*/
// At runtime, we don't have access to the DOM, so we don't want TypeScript to allow accessing DOM
// globals. However, we're mimicking DOM functionality here, so we *do* want access to DOM types.
// To access the real DOM types when writing new code, uncomment the line below and comment out the
// stub types. Switch them back when you're done to validate that you're not accidentally using
// DOM globals. IMPORTANT: The comment below is a "triple slash directive", it must start with ///
// and be located before import statements.
// /// <reference lib="dom" />
const MULTI_SPACE = /\s+/g;

@@ -66,2 +121,20 @@ class ClassList {

}
get value() {
return this.el.className;
}
toString() {
return this.el.className;
}
item(_index) {
throw new Error('Method "item" not implemented.');
}
supports(_token) {
throw new Error('Method "supports" not implemented.');
}
forEach(_callbackfn, _thisArg) {
throw new Error('Method "forEach" not implemented.');
}
get length() {
throw new Error('Property "length" not implemented.');
}
}

@@ -109,5 +182,86 @@ class LightningElement {

getAttribute(attrName) {
const value = this.__attrs?.[attrName];
return value === true ? '' : (value ?? null);
return this.__attrs[attrName] ?? null;
}
setAttribute(attrName, value) {
this.__attrs[attrName] = String(value);
}
hasAttribute(attrName) {
return Boolean(this.__attrs && attrName in this.__attrs);
}
removeAttribute(attrName) {
this.__attrs[attrName] = null;
}
addEventListener(_type, _listener, _options) {
// noop
}
removeEventListener(_type, _listener, _options) {
// noop
}
// ----------------------------------------------------------- //
// Props/methods explicitly not available in this environment //
// Getters are named "get*" for parity with @lwc/engine-server //
// ----------------------------------------------------------- //
get children() {
throw new TypeError('"getChildren" is not supported in this environment');
}
get childNodes() {
throw new TypeError('"getChildNodes" is not supported in this environment');
}
get firstChild() {
throw new TypeError('"getFirstChild" is not supported in this environment');
}
get firstElementChild() {
throw new TypeError('"getFirstElementChild" is not supported in this environment');
}
get hostElement() {
// Intentionally different to match @lwc/engine-*core*
throw new TypeError('this.hostElement is not supported in this environment');
}
get lastChild() {
throw new TypeError('"getLastChild" is not supported in this environment');
}
get lastElementChild() {
throw new TypeError('"getLastElementChild" is not supported in this environment');
}
get ownerDocument() {
// Intentionally not "get*" to match @lwc/engine-server
throw new TypeError('"ownerDocument" is not supported in this environment');
}
get style() {
// Intentionally not "get*" to match @lwc/engine-server
throw new TypeError('"style" is not supported in this environment');
}
attachInternals() {
throw new TypeError('"attachInternals" is not supported in this environment');
}
dispatchEvent(_event) {
throw new TypeError('"dispatchEvent" is not supported in this environment');
}
getBoundingClientRect() {
throw new TypeError('"getBoundingClientRect" is not supported in this environment');
}
getElementsByClassName(_classNames) {
throw new TypeError('"getElementsByClassName" is not supported in this environment');
}
getElementsByTagName(_qualifiedName) {
throw new TypeError('"getElementsByTagName" is not supported in this environment');
}
querySelector(_selectors) {
throw new TypeError('"querySelector" is not supported in this environment');
}
querySelectorAll(_selectors) {
throw new TypeError('"querySelectorAll" is not supported in this environment');
}
getAttributeNS(_namespace, _localName) {
throw new Error('Method "getAttributeNS" not implemented.');
}
hasAttributeNS(_namespace, _localName) {
throw new Error('Method "hasAttributeNS" not implemented.');
}
removeAttributeNS(_namespace, _localName) {
throw new Error('Method "removeAttributeNS" not implemented.');
}
setAttributeNS(_namespace, _qualifiedName, _value) {
throw new Error('Method "setAttributeNS" not implemented.');
}
}

@@ -120,10 +274,8 @@ const escapeAttrVal = (attrVal) => attrVal.replaceAll('&', '&amp;').replaceAll('"', '&quot;');

for (const [key, val] of Object.entries(attrs)) {
if (val) {
if (typeof val === 'string') {
yield ` ${key}="${escapeAttrVal(val)}"`;
}
else {
yield ` ${key}`;
}
if (typeof val === 'string') {
yield val === '' ? ` ${key}` : ` ${key}="${escapeAttrVal(val)}"`;
}
else if (val === null) {
return '';
}
}

@@ -148,3 +300,4 @@ }

exports.serverSideRenderComponent = serverSideRenderComponent;
/** version: 8.1.2 */
exports.validateStyleTextContents = validateStyleTextContents;
/** version: 8.1.3 */
//# sourceMappingURL=index.cjs.js.map

@@ -1,4 +0,10 @@

type Attributes = Record<string, string | true>;
export { validateStyleTextContents } from './validate-style-text-contents';
type DOMTokenList = object;
type EventListenerOrEventListenerObject = unknown;
type AddEventListenerOptions = unknown;
type EventListenerOptions = unknown;
type ShadowRoot = unknown;
type Attributes = Record<string, string | null>;
type LightningElementConstructor = typeof LightningElement;
declare class ClassList {
declare class ClassList implements DOMTokenList {
el: LightningElement;

@@ -11,18 +17,63 @@ constructor(el: LightningElement);

toggle(classNameToToggle: string, force?: boolean): boolean;
get value(): string;
toString(): string;
[index: number]: never;
item(_index: number): string | null;
supports(_token: string): boolean;
forEach(_callbackfn: (value: string, key: number, parent: DOMTokenList) => void, _thisArg?: any): void;
get length(): number;
}
export declare class LightningElement {
interface PropsAvailableAtConstruction {
tagName: string;
}
export declare class LightningElement implements PropsAvailableAtConstruction {
static renderMode?: 'light' | 'shadow';
isConnected: boolean;
className: string;
__attrs?: Attributes;
__classList: ClassList | null;
constructor(propsAvailableAtConstruction: Record<string, any>);
__internal__setState(props: Record<string, any>, reflectedProps: string[], attrs: Record<string, any>): void;
private __attrs;
private __classList;
tagName: string;
constructor(propsAvailableAtConstruction: PropsAvailableAtConstruction & Record<string, unknown>);
private __internal__setState;
get classList(): ClassList;
getAttribute(attrName: string): string | null;
setAttribute(attrName: string, value: string | null): void;
hasAttribute(attrName: string): boolean;
removeAttribute(attrName: string): void;
addEventListener(_type: string, _listener: EventListenerOrEventListenerObject, _options?: boolean | AddEventListenerOptions): void;
removeEventListener(_type: string, _listener: EventListenerOrEventListenerObject, _options?: boolean | EventListenerOptions): void;
get children(): never;
get childNodes(): never;
get firstChild(): never;
get firstElementChild(): never;
get hostElement(): never;
get lastChild(): never;
get lastElementChild(): never;
get ownerDocument(): never;
get style(): never;
attachInternals(): never;
dispatchEvent(_event: Event): never;
getBoundingClientRect(): never;
getElementsByClassName(_classNames: string): never;
getElementsByTagName(_qualifiedName: unknown): never;
querySelector(_selectors: string): never;
querySelectorAll(_selectors: string): never;
accessKey?: string;
dir?: string;
draggable?: boolean;
hidden?: boolean;
id?: string;
lang?: string;
shadowRoot?: ShadowRoot | null;
spellcheck?: boolean;
tabIndex?: number;
title?: string;
getAttributeNS(_namespace: string | null, _localName: string): string | null;
hasAttributeNS(_namespace: string | null, _localName: string): boolean;
removeAttributeNS(_namespace: string | null, _localName: string): void;
setAttributeNS(_namespace: string | null, _qualifiedName: string, _value: string): void;
}
export declare function renderAttrs(attrs: Attributes): Generator<string, void, unknown>;
export declare function renderAttrs(attrs: Attributes): Generator<string, "" | undefined, unknown>;
export declare function fallbackTmpl(_props: unknown, _attrs: unknown, _slotted: unknown, Cmp: LightningElementConstructor, _instance: unknown): Generator<string, void, unknown>;
export type GenerateMarkupFn = (tagName: string, props: Record<string, any> | null, attrs: Attributes | null, slotted: Record<number | string, AsyncGenerator<string>> | null) => AsyncGenerator<string>;
export declare function serverSideRenderComponent(tagName: string, compiledGenerateMarkup: GenerateMarkupFn, props: Record<string, any>): Promise<string>;
export {};

@@ -5,2 +5,50 @@ /**

/*
* Copyright (c) 2024, Salesforce, Inc.
* All rights reserved.
* SPDX-License-Identifier: MIT
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
*/
/**
* Per the HTML spec on restrictions for "raw text elements" like `<style>`:
*
* > The text in raw text and escapable raw text elements must not contain any occurrences of the string
* > "</" (U+003C LESS-THAN SIGN, U+002F SOLIDUS) followed by characters that case-insensitively match the tag name of
* > the element followed by one of:
* > - U+0009 CHARACTER TABULATION (tab)
* > - U+000A LINE FEED (LF)
* > - U+000C FORM FEED (FF)
* > - U+000D CARRIAGE RETURN (CR)
* > - U+0020 SPACE
* > - U+003E GREATER-THAN SIGN (>), or
* > - U+002F SOLIDUS (/)
* @see https://html.spec.whatwg.org/multipage/syntax.html#cdata-rcdata-restrictions
*/
const INVALID_STYLE_CONTENT = /<\/style[\t\n\f\r >/]/i;
/**
* The text content inside `<style>` is a special case. It is _only_ rendered by the LWC engine itself; `<style>` tags
* are disallowed inside of HTML templates.
*
* The `<style>` tag is unusual in how it's defined in HTML. Like `<script>`, it is considered a "raw text element,"
* which means that it is parsed as raw text, but certain character sequences are disallowed, namely to avoid XSS
* attacks like `</style><script>alert("pwned")</script>`.
*
* This also means that we cannot use "normal" HTML escaping inside `<style>` tags, e.g. we cannot use `&lt;`,
* `&gt;`, etc., because these are treated as-is by the HTML parser.
*
*
* @param contents CSS source to validate
* @throws Throws if the contents provided are not valid.
* @see https://html.spec.whatwg.org/multipage/syntax.html#raw-text-elements
* @see https://github.com/salesforce/lwc/issues/3439
* @example
* validateStyleTextContents('div { color: red }') // Ok
* validateStyleTextContents('</style><script>alert("pwned")</script>') // Throws
*/
function validateStyleTextContents(contents) {
if (INVALID_STYLE_CONTENT.test(contents)) {
throw new Error('CSS contains unsafe characters and cannot be serialized inside a style element');
}
}
/*
* Copyright (c) 2024, salesforce.com, inc.

@@ -11,2 +59,9 @@ * All rights reserved.

*/
// At runtime, we don't have access to the DOM, so we don't want TypeScript to allow accessing DOM
// globals. However, we're mimicking DOM functionality here, so we *do* want access to DOM types.
// To access the real DOM types when writing new code, uncomment the line below and comment out the
// stub types. Switch them back when you're done to validate that you're not accidentally using
// DOM globals. IMPORTANT: The comment below is a "triple slash directive", it must start with ///
// and be located before import statements.
// /// <reference lib="dom" />
const MULTI_SPACE = /\s+/g;

@@ -62,2 +117,20 @@ class ClassList {

}
get value() {
return this.el.className;
}
toString() {
return this.el.className;
}
item(_index) {
throw new Error('Method "item" not implemented.');
}
supports(_token) {
throw new Error('Method "supports" not implemented.');
}
forEach(_callbackfn, _thisArg) {
throw new Error('Method "forEach" not implemented.');
}
get length() {
throw new Error('Property "length" not implemented.');
}
}

@@ -105,5 +178,86 @@ class LightningElement {

getAttribute(attrName) {
const value = this.__attrs?.[attrName];
return value === true ? '' : (value ?? null);
return this.__attrs[attrName] ?? null;
}
setAttribute(attrName, value) {
this.__attrs[attrName] = String(value);
}
hasAttribute(attrName) {
return Boolean(this.__attrs && attrName in this.__attrs);
}
removeAttribute(attrName) {
this.__attrs[attrName] = null;
}
addEventListener(_type, _listener, _options) {
// noop
}
removeEventListener(_type, _listener, _options) {
// noop
}
// ----------------------------------------------------------- //
// Props/methods explicitly not available in this environment //
// Getters are named "get*" for parity with @lwc/engine-server //
// ----------------------------------------------------------- //
get children() {
throw new TypeError('"getChildren" is not supported in this environment');
}
get childNodes() {
throw new TypeError('"getChildNodes" is not supported in this environment');
}
get firstChild() {
throw new TypeError('"getFirstChild" is not supported in this environment');
}
get firstElementChild() {
throw new TypeError('"getFirstElementChild" is not supported in this environment');
}
get hostElement() {
// Intentionally different to match @lwc/engine-*core*
throw new TypeError('this.hostElement is not supported in this environment');
}
get lastChild() {
throw new TypeError('"getLastChild" is not supported in this environment');
}
get lastElementChild() {
throw new TypeError('"getLastElementChild" is not supported in this environment');
}
get ownerDocument() {
// Intentionally not "get*" to match @lwc/engine-server
throw new TypeError('"ownerDocument" is not supported in this environment');
}
get style() {
// Intentionally not "get*" to match @lwc/engine-server
throw new TypeError('"style" is not supported in this environment');
}
attachInternals() {
throw new TypeError('"attachInternals" is not supported in this environment');
}
dispatchEvent(_event) {
throw new TypeError('"dispatchEvent" is not supported in this environment');
}
getBoundingClientRect() {
throw new TypeError('"getBoundingClientRect" is not supported in this environment');
}
getElementsByClassName(_classNames) {
throw new TypeError('"getElementsByClassName" is not supported in this environment');
}
getElementsByTagName(_qualifiedName) {
throw new TypeError('"getElementsByTagName" is not supported in this environment');
}
querySelector(_selectors) {
throw new TypeError('"querySelector" is not supported in this environment');
}
querySelectorAll(_selectors) {
throw new TypeError('"querySelectorAll" is not supported in this environment');
}
getAttributeNS(_namespace, _localName) {
throw new Error('Method "getAttributeNS" not implemented.');
}
hasAttributeNS(_namespace, _localName) {
throw new Error('Method "hasAttributeNS" not implemented.');
}
removeAttributeNS(_namespace, _localName) {
throw new Error('Method "removeAttributeNS" not implemented.');
}
setAttributeNS(_namespace, _qualifiedName, _value) {
throw new Error('Method "setAttributeNS" not implemented.');
}
}

@@ -116,10 +270,8 @@ const escapeAttrVal = (attrVal) => attrVal.replaceAll('&', '&amp;').replaceAll('"', '&quot;');

for (const [key, val] of Object.entries(attrs)) {
if (val) {
if (typeof val === 'string') {
yield ` ${key}="${escapeAttrVal(val)}"`;
}
else {
yield ` ${key}`;
}
if (typeof val === 'string') {
yield val === '' ? ` ${key}` : ` ${key}="${escapeAttrVal(val)}"`;
}
else if (val === null) {
return '';
}
}

@@ -140,4 +292,4 @@ }

export { LightningElement, fallbackTmpl, renderAttrs, serverSideRenderComponent };
/** version: 8.1.2 */
export { LightningElement, fallbackTmpl, renderAttrs, serverSideRenderComponent, validateStyleTextContents };
/** version: 8.1.3 */
//# sourceMappingURL=index.js.map

2

package.json

@@ -7,3 +7,3 @@ {

"name": "@lwc/ssr-runtime",
"version": "8.1.2",
"version": "8.1.3",
"description": "Runtime complement to @lwc/ssr-compiler",

@@ -10,0 +10,0 @@ "keywords": [

Sorry, the diff of this file is not supported yet

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