
Research
Security News
Malicious PyPI Package Exploits Deezer API for Coordinated Music Piracy
Socket researchers uncovered a malicious PyPI package exploiting Deezer’s API to enable coordinated music piracy through API abuse and C2 server control.
@gravity-ui/app-layout
Advanced tools
npm install --save-dev @gravity-ui/app-layout
With express
:
import express from 'express';
import {createRenderFunction} from '@gravity-ui/app-layout';
const app = express();
const renderLayout = createRenderFunction();
app.get('/', function (req, res) {
res.send(
renderLayout({
// RenderParams
title: 'Home page',
bodyContent: {
root: 'Hello world!',
},
}),
);
});
app.listen(3000);
where
interface RenderParams<Data, Plugins> {
// Any json compatible data, will be set to window.__DATA__ on the page
data?: Data;
// favicon
icon?: Icon;
// nonce to be set on the appropriate tags
nonce?: string;
// common options
// Page title
title: string;
// language of page, will be set to html tag
lang?: string;
isMobile?: boolean;
// header tag content
// meta tags
meta?: Meta[];
// link tags
links?: Link[];
// script tags
scripts?: Script[];
// style tags
styleSheets?: Stylesheet[];
// script tags with inlined code
inlineScripts?: string[];
// style tags with inlined styles
inlineStyleSheets?: string[];
// content of body tag
bodyContent?: {
// initial application theme if @gravity-ui/uikit is used
theme?: string;
// class name for body tag
className?: string;
// body content before div tag with id root
beforeRoot?: string;
// innerHtml content of div tag with id root
root?: string;
// body content after div tag with id root
afterRoot?: string;
};
// plugins options
pluginsOptions?: Partial<PluginsOptions<Plugins>>;
}
Describes meta
tag:
interface Meta {
name: string;
content: string;
}
Example:
const meta = [
{name: 'description', content: 'some text'},
{name: 'robots', content: 'noindex'},
{name: 'og:title', content: 'Some title'},
];
Will be rendered as:
<meta name="description" content="some text" />
<meta name="robots" content="noindex" />
<meta property="og:title" content="Some title" />
Describes page favicon:
interface Icon {
type?: string;
sizes?: string;
href?: string;
}
Default value is:
const icon = {
type: 'image/png',
sizes: '16x16',
href: '/favicon.png',
};
Describes link
tag:
interface Link {
as?: string;
href: string;
rel?: string;
type?: string;
title?: HTMLLinkElement['title'];
crossOrigin?: '' | 'anonymous' | 'use-credentials';
}
Example:
const link = {
href: 'myFont.woff2',
rel: 'preload',
as: 'font',
type: 'font/woff2',
crossOrigin: 'anonymous',
};
will be rendered as:
<link href="myFont.woff2" rel="preload" as="font" type="font/woff2" crossorigin="anonymous" />
Describes link to script with preload:
interface Script {
src: string;
defer?: boolean;
async?: boolean;
crossOrigin?: '' | 'anonymous' | 'use-credentials';
type?: 'importmap' | 'module' | string;
}
Example:
const script = {
src: 'url/to/script',
defer: true,
async: false,
crossOrigin: 'anonymous',
};
will be rendered as:
<link href="url/to/script" rel="preload" as="script" crossorigin="anonymous" />
<script src="url/to/script" defer="true" async="false" crossorigin="anonymous" nonce="..."></script>
Describe link to styles:
interface Stylesheet {
href: string;
}
Example:
const styleSheet = {
href: 'url/to/stylesheet',
};
will be rendered as:
<link href="url/to/stylesheet" rel="stylesheet" />
Render function can be extended by plugins. Plugin may rewrite user defined render content.
Plugin is an object with name
and apply
properties:
interface Plugin<Options = any, Name = string> {
name: Name;
apply: (params: {
options: Options | undefined; // passed through `renderLayout` function in `pluginsOptions` parameter.
commonOptions: CommonOptions;
renderContent: RenderContent;
utils: RenderHelpers;
}) => void;
}
interface CommonOptions {
name: string;
title: string;
lang?: string;
isMobile?: boolean;
}
interface RenderContent {
meta: Meta[];
links: Link[];
scripts: Script[];
styleSheets: Stylesheet[];
inlineScripts: string[];
inlineStyleSheets: string[];
bodyContent: {
theme?: string;
className: string[];
beforeRoot: string[];
root?: string;
afterRoot: string[];
};
}
export interface RenderHelpers {
renderScript(script: Script): string;
renderInlineScript(content: string): string;
renderStyle(style: Stylesheet): string;
renderInlineStyle(content: string): string;
renderMeta(meta: Meta): string;
renderLink(link: Link): string;
}
There are some plugins in this package:
Adds google analytics counter on the page.
Usage:
import {createRenderFunction, createGoogleAnalyticsPlugin} from '@gravity-ui/app-layout';
const renderLayout = createRenderFunction([createGoogleAnalyticsPlugin()]);
app.get((req, res) => {
res.send(
renderLayout({
title: 'Home page',
pluginsOptions: {
googleAnalytics: {
useBeaconTransport: true, // enables use of navigator.sendBeacon
counter: {
id: 'some id',
},
},
},
}),
);
});
Plugin options:
interface GoogleAnalyticsCounter {
id: string;
}
interface GoogleAnalyticsOptions {
useBeaconTransport?: boolean;
counter: GoogleAnalyticsCounter;
}
Adds Yandex metrics counters on the page.
Usage:
import {createMiddleware, createYandexMetrikaPlugin} from '@gravity-ui/app-layout';
const renderLayout = createRenderFunction([createYandexMetrikaPlugin()]);
app.get((req, res) => {
res.send(
renderLayout({
title: 'Home page',
pluginsOptions: {
yandexMetrika: {
counter: {
id: 123123123,
defer: true,
clickmap: true,
trackLinks: true,
accurateTrackBounce: true,
},
},
},
}),
);
});
Plugin options:
export type UserParams = {
[x: string]: boolean | string | number | null | UserParams;
};
export interface MetrikaCounter {
id: number;
defer: boolean;
clickmap: boolean;
trackLinks: boolean;
accurateTrackBounce: boolean | number;
webvisor?: boolean;
nonce?: string;
encryptedExperiments?: string;
triggerEvent?: boolean;
trackHash?: boolean;
ecommerce?: boolean | string;
type?: number;
userParams?: UserParams;
}
export type MetrikaOptions = {
src?: string;
counter: MetrikaCounter | MetrikaCounter[];
};
Adds script and styles from webpack assets manifest file.
Usage:
import {createMiddleware, createLayoutPlugin} from '@gravity-ui/app-layout';
const renderLayout = createRenderFunction([
createLayoutPlugin({manifest: 'path/to/assets-manifest.json', publicPath: '/build/'}),
]);
app.get((req, res) => {
res.send(
renderLayout({
title: 'Home page',
pluginsOptions: {
layout: {
name: 'home',
},
},
}),
);
});
Plugin options:
export interface LayoutOptions {
name: string;
prefix?: string;
}
There is helper to create all plugins:
import {createMiddleware, createDefaultPlugins} from '@gravity-ui/app-layout';
const renderLayout = createRenderFunction(
createDefaultPlugins({layout: {manifest: 'path/to/assets-manifest.json'}})
);
app.get((req, res) => {
res.send(renderLayout({
title: 'Home page',
pluginsOptions: {
layout: {
name: 'home'
},
googleAnalytics: {
counter: {...}
},
yandexMetrika: {
counter: {...}
},
},
}));
})
FAQs
## Install
The npm package @gravity-ui/app-layout receives a total of 827 weekly downloads. As such, @gravity-ui/app-layout popularity was classified as not popular.
We found that @gravity-ui/app-layout demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncovered a malicious PyPI package exploiting Deezer’s API to enable coordinated music piracy through API abuse and C2 server control.
Research
The Socket Research Team discovered a malicious npm package, '@ton-wallet/create', stealing cryptocurrency wallet keys from developers and users in the TON ecosystem.
Security News
Newly introduced telemetry in devenv 1.4 sparked a backlash over privacy concerns, leading to the removal of its AI-powered feature after strong community pushback.