Socket
Socket
Sign inDemoInstall

@shopify/react-network

Package Overview
Dependencies
Maintainers
13
Versions
162
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@shopify/react-network - npm Package Compare versions

Comparing version 3.0.0-beta.1 to 3.0.0

dist/hooks.d.ts

8

CHANGELOG.md

@@ -10,2 +10,10 @@ # Changelog

## [3.0.0] - 2019-04-08
This library now requires React 16.8.
### Added
- Added hook versions of most component APIs: `useRedirect`, `useStatus`, and `useCspDirective` ([#547](https://github.com/Shopify/quilt/pull/547))
## [1.0.5]

@@ -12,0 +20,0 @@

6

dist/components/BaseUri.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var network_1 = require("@shopify/network");
var hook_1 = require("../hook");
var hooks_1 = require("../hooks");
function BaseUri(_a) {
var uri = _a.uri;
hook_1.useNetworkEffect(function (network) {
return network.addCspDirective(network_1.CspDirective.BaseUri, uri);
});
hooks_1.useCspDirective(network_1.CspDirective.BaseUri, uri);
return null;
}
exports.default = BaseUri;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var network_1 = require("@shopify/network");
var hook_1 = require("../hook");
var hooks_1 = require("../hooks");
function BlockAllMixedContent(_a) {
var _b = _a.value, value = _b === void 0 ? true : _b;
hook_1.useNetworkEffect(function (network) {
return network.addCspDirective(network_1.CspDirective.BlockAllMixedContent, value);
});
hooks_1.useCspDirective(network_1.CspDirective.BlockAllMixedContent, value);
return null;
}
exports.default = BlockAllMixedContent;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var network_1 = require("@shopify/network");
var hook_1 = require("../hook");
var hooks_1 = require("../hooks");
function ChildSource(_a) {
var sources = _a.sources;
hook_1.useNetworkEffect(function (network) {
return network.addCspDirective(network_1.CspDirective.ChildSrc, sources);
});
hooks_1.useCspDirective(network_1.CspDirective.ChildSrc, sources);
return null;
}
exports.default = ChildSource;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var network_1 = require("@shopify/network");
var hook_1 = require("../hook");
var hooks_1 = require("../hooks");
function ConnectSource(_a) {
var sources = _a.sources;
hook_1.useNetworkEffect(function (network) {
return network.addCspDirective(network_1.CspDirective.ConnectSrc, sources);
});
hooks_1.useCspDirective(network_1.CspDirective.ConnectSrc, sources);
return null;
}
exports.default = ConnectSource;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var network_1 = require("@shopify/network");
var hook_1 = require("../hook");
var hooks_1 = require("../hooks");
function DefaultSource(_a) {
var sources = _a.sources;
hook_1.useNetworkEffect(function (network) {
return network.addCspDirective(network_1.CspDirective.DefaultSrc, sources);
});
hooks_1.useCspDirective(network_1.CspDirective.DefaultSrc, sources);
return null;
}
exports.default = DefaultSource;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var network_1 = require("@shopify/network");
var hook_1 = require("../hook");
var hooks_1 = require("../hooks");
function FontSource(_a) {
var sources = _a.sources;
hook_1.useNetworkEffect(function (network) {
return network.addCspDirective(network_1.CspDirective.FontSrc, sources);
});
hooks_1.useCspDirective(network_1.CspDirective.FontSrc, sources);
return null;
}
exports.default = FontSource;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var network_1 = require("@shopify/network");
var hook_1 = require("../hook");
var hooks_1 = require("../hooks");
function FormAction(_a) {
var sources = _a.sources;
hook_1.useNetworkEffect(function (network) {
return network.addCspDirective(network_1.CspDirective.FormAction, sources);
});
hooks_1.useCspDirective(network_1.CspDirective.FormAction, sources);
return null;
}
exports.default = FormAction;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var network_1 = require("@shopify/network");
var hook_1 = require("../hook");
var hooks_1 = require("../hooks");
function FrameAncestors(_a) {
var sources = _a.sources;
hook_1.useNetworkEffect(function (network) {
return network.addCspDirective(network_1.CspDirective.FrameAncestors, sources);
});
hooks_1.useCspDirective(network_1.CspDirective.FrameAncestors, sources);
return null;
}
exports.default = FrameAncestors;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var network_1 = require("@shopify/network");
var hook_1 = require("../hook");
var hooks_1 = require("../hooks");
function FrameSource(_a) {
var sources = _a.sources;
hook_1.useNetworkEffect(function (network) {
return network.addCspDirective(network_1.CspDirective.FrameSrc, sources);
});
hooks_1.useCspDirective(network_1.CspDirective.FrameSrc, sources);
return null;
}
exports.default = FrameSource;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var network_1 = require("@shopify/network");
var hook_1 = require("../hook");
var hooks_1 = require("../hooks");
function ImageSource(_a) {
var sources = _a.sources;
hook_1.useNetworkEffect(function (network) {
return network.addCspDirective(network_1.CspDirective.ImgSrc, sources);
});
hooks_1.useCspDirective(network_1.CspDirective.ImgSrc, sources);
return null;
}
exports.default = ImageSource;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var network_1 = require("@shopify/network");
var hook_1 = require("../hook");
var hooks_1 = require("../hooks");
function ManifestSource(_a) {
var sources = _a.sources;
hook_1.useNetworkEffect(function (network) {
return network.addCspDirective(network_1.CspDirective.ManifestSrc, sources);
});
hooks_1.useCspDirective(network_1.CspDirective.ManifestSrc, sources);
return null;
}
exports.default = ManifestSource;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var network_1 = require("@shopify/network");
var hook_1 = require("../hook");
var hooks_1 = require("../hooks");
function MediaSource(_a) {
var sources = _a.sources;
hook_1.useNetworkEffect(function (network) {
return network.addCspDirective(network_1.CspDirective.MediaSrc, sources);
});
hooks_1.useCspDirective(network_1.CspDirective.MediaSrc, sources);
return null;
}
exports.default = MediaSource;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var network_1 = require("@shopify/network");
var hook_1 = require("../hook");
var hooks_1 = require("../hooks");
function ObjectSource(_a) {
var sources = _a.sources;
hook_1.useNetworkEffect(function (network) {
return network.addCspDirective(network_1.CspDirective.ObjectSrc, sources);
});
hooks_1.useCspDirective(network_1.CspDirective.ObjectSrc, sources);
return null;
}
exports.default = ObjectSource;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var network_1 = require("@shopify/network");
var hook_1 = require("../hook");
var hooks_1 = require("../hooks");
function PluginTypes(_a) {
var types = _a.types;
hook_1.useNetworkEffect(function (network) {
return network.addCspDirective(network_1.CspDirective.PluginTypes, types);
});
hooks_1.useCspDirective(network_1.CspDirective.PluginTypes, types);
return null;
}
exports.default = PluginTypes;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var network_1 = require("@shopify/network");
var hook_1 = require("../hook");
var hooks_1 = require("../hooks");
function PrefetchSource(_a) {
var sources = _a.sources;
hook_1.useNetworkEffect(function (network) {
return network.addCspDirective(network_1.CspDirective.PrefetchSrc, sources);
});
hooks_1.useCspDirective(network_1.CspDirective.PrefetchSrc, sources);
return null;
}
exports.default = PrefetchSource;
import { StatusCode } from '@shopify/network';
interface Props {
url: string;
status?: StatusCode;
code?: StatusCode;
}
export default function Redirect({ url, status }: Props): null;
export default function Redirect({ url, code }: Props): null;
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var hook_1 = require("../hook");
var hooks_1 = require("../hooks");
function Redirect(_a) {
var url = _a.url, status = _a.status;
hook_1.useNetworkEffect(function (network) { return network.redirectTo(url, status); });
var url = _a.url, code = _a.code;
hooks_1.useRedirect(url, code);
return null;
}
exports.default = Redirect;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var network_1 = require("@shopify/network");
var hook_1 = require("../hook");
var hooks_1 = require("../hooks");
function ReportUri(_a) {
var uri = _a.uri;
hook_1.useNetworkEffect(function (network) {
return network.addCspDirective(network_1.CspDirective.ReportUri, uri);
});
hooks_1.useCspDirective(network_1.CspDirective.ReportUri, uri);
return null;
}
exports.default = ReportUri;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var network_1 = require("@shopify/network");
var hook_1 = require("../hook");
var hooks_1 = require("../hooks");
function RequireSriFor(_a) {

@@ -14,7 +14,5 @@ var scripts = _a.scripts, styles = _a.styles;

}
hook_1.useNetworkEffect(function (network) {
return network.addCspDirective(network_1.CspDirective.RequireSriFor, value);
});
hooks_1.useCspDirective(network_1.CspDirective.RequireSriFor, value);
return null;
}
exports.default = RequireSriFor;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var network_1 = require("@shopify/network");
var hook_1 = require("../hook");
var hooks_1 = require("../hooks");
function Sandbox(_a) {
var allowed = _a.allowed;
hook_1.useNetworkEffect(function (network) {
return network.addCspDirective(network_1.CspDirective.Sandbox, allowed);
});
hooks_1.useCspDirective(network_1.CspDirective.Sandbox, allowed);
return null;
}
exports.default = Sandbox;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var network_1 = require("@shopify/network");
var hook_1 = require("../hook");
var hooks_1 = require("../hooks");
function ScriptSource(_a) {
var sources = _a.sources;
hook_1.useNetworkEffect(function (network) {
return network.addCspDirective(network_1.CspDirective.ScriptSrc, sources);
});
hooks_1.useCspDirective(network_1.CspDirective.ScriptSrc, sources);
return null;
}
exports.default = ScriptSource;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var hook_1 = require("../hook");
var hooks_1 = require("../hooks");
function Status(_a) {
var code = _a.code;
hook_1.useNetworkEffect(function (network) { return network.addStatusCode(code); });
hooks_1.useStatus(code);
return null;
}
exports.default = Status;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var network_1 = require("@shopify/network");
var hook_1 = require("../hook");
var hooks_1 = require("../hooks");
function StyleSource(_a) {
var sources = _a.sources;
hook_1.useNetworkEffect(function (network) {
return network.addCspDirective(network_1.CspDirective.StyleSrc, sources);
});
hooks_1.useCspDirective(network_1.CspDirective.StyleSrc, sources);
return null;
}
exports.default = StyleSource;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var network_1 = require("@shopify/network");
var hook_1 = require("../hook");
var hooks_1 = require("../hooks");
function UpgradeInsecureRequests(_a) {
var _b = _a.value, value = _b === void 0 ? true : _b;
hook_1.useNetworkEffect(function (network) {
return network.addCspDirective(network_1.CspDirective.UpgradeInsecureRequests, value);
});
hooks_1.useCspDirective(network_1.CspDirective.UpgradeInsecureRequests, value);
return null;
}
exports.default = UpgradeInsecureRequests;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var network_1 = require("@shopify/network");
var hook_1 = require("../hook");
var hooks_1 = require("../hooks");
function WebRtcSource(_a) {
var sources = _a.sources;
hook_1.useNetworkEffect(function (network) {
return network.addCspDirective(network_1.CspDirective.WebrtcSrc, sources);
});
hooks_1.useCspDirective(network_1.CspDirective.WebrtcSrc, sources);
return null;
}
exports.default = WebRtcSource;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var network_1 = require("@shopify/network");
var hook_1 = require("../hook");
var hooks_1 = require("../hooks");
function WorkerSource(_a) {
var sources = _a.sources;
hook_1.useNetworkEffect(function (network) {
return network.addCspDirective(network_1.CspDirective.WorkerSrc, sources);
});
hooks_1.useCspDirective(network_1.CspDirective.WorkerSrc, sources);
return null;
}
exports.default = WorkerSource;
import * as React from 'react';
import { Manager } from './manager';
export declare const NetworkContext: React.Context<Manager | undefined>;
import { NetworkManager } from './manager';
export declare const NetworkContext: React.Context<NetworkManager | null>;

@@ -5,2 +5,2 @@ "use strict";

var React = tslib_1.__importStar(require("react"));
exports.NetworkContext = React.createContext(undefined);
exports.NetworkContext = React.createContext(null);
export * from '@shopify/network';
export * from './components';
export { Manager } from './manager';
export { NetworkManager } from './manager';
export { NetworkContext } from './context';
export { useNetworkEffect } from './hook';
export { useNetworkEffect, useStatus, useCspDirective } from './hooks';

@@ -6,5 +6,9 @@ "use strict";

tslib_1.__exportStar(require("./components"), exports);
var manager_1 = require("./manager");
exports.NetworkManager = manager_1.NetworkManager;
var context_1 = require("./context");
exports.NetworkContext = context_1.NetworkContext;
var hook_1 = require("./hook");
exports.useNetworkEffect = hook_1.useNetworkEffect;
var hooks_1 = require("./hooks");
exports.useNetworkEffect = hooks_1.useNetworkEffect;
exports.useStatus = hooks_1.useStatus;
exports.useCspDirective = hooks_1.useCspDirective;
import { StatusCode, CspDirective } from '@shopify/network';
import { EffectKind } from '@shopify/react-effect';
export interface Manager {
effect?: EffectKind;
export { NetworkContext } from './context';
export declare const EFFECT_ID: unique symbol;
export declare class NetworkManager {
readonly effect: EffectKind;
private statusCodes;
private csp;
private redirectUrl?;
reset(): void;
redirectTo(url: string, status?: StatusCode): void;
addStatusCode(statusCode: StatusCode): void;
addCspDirective(directive: CspDirective, value: boolean | string | string[]): void;
addCspDirective(directive: CspDirective, value: string | string[] | boolean): void;
extract(): {
status: number | undefined;
csp: {
[key: string]: string | boolean | string[];
};
redirectUrl: string | undefined;
};
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var network_1 = require("@shopify/network");
var context_1 = require("./context");
exports.NetworkContext = context_1.NetworkContext;
exports.EFFECT_ID = Symbol('network');
var NetworkManager = /** @class */ (function () {
function NetworkManager() {
var _this = this;
this.effect = {
id: exports.EFFECT_ID,
betweenEachPass: function () { return _this.reset(); },
};
this.statusCodes = [];
this.csp = new Map();
}
NetworkManager.prototype.reset = function () {
this.statusCodes = [];
this.csp.clear();
this.redirectUrl = undefined;
};
NetworkManager.prototype.redirectTo = function (url, status) {
if (status === void 0) { status = network_1.StatusCode.Found; }
this.addStatusCode(status);
this.redirectUrl = url;
};
NetworkManager.prototype.addStatusCode = function (statusCode) {
this.statusCodes.push(statusCode);
};
NetworkManager.prototype.addCspDirective = function (directive, value) {
var normalizedValue = typeof value === 'string' ? [value] : value;
var currentValue = this.csp.get(directive) || [];
var normalizedCurrentValue = Array.isArray(currentValue)
? currentValue
: [String(currentValue)];
var newValue = Array.isArray(normalizedValue)
? tslib_1.__spread(normalizedCurrentValue, normalizedValue) : normalizedValue;
this.csp.set(directive, newValue);
};
NetworkManager.prototype.extract = function () {
return {
status: this.statusCodes.length > 0
? this.statusCodes.reduce(function (large, code) { return Math.max(large, code); }, 0)
: undefined,
csp: tslib_1.__spread(this.csp.entries()).reduce(function (csp, _a) {
var _b = tslib_1.__read(_a, 2), directive = _b[0], value = _b[1];
var _c;
return (tslib_1.__assign({}, csp, (_c = {}, _c[directive] = value, _c)));
}, {}),
redirectUrl: this.redirectUrl,
};
};
return NetworkManager;
}());
exports.NetworkManager = NetworkManager;
import { Context } from 'koa';
import { StatusCode, CspDirective } from '@shopify/network';
import { EffectKind } from '@shopify/react-effect';
import { Manager } from './manager';
import { NetworkManager, EFFECT_ID } from './manager';
export { NetworkContext } from './context';
export declare const EFFECT_ID: unique symbol;
export declare class ServerManager implements Manager {
readonly effect: EffectKind;
private statusCodes;
private csp;
private redirectUrl?;
reset(): void;
redirectTo(url: string, status?: StatusCode): void;
addStatusCode(statusCode: StatusCode): void;
addCspDirective(directive: CspDirective, value: string | string[] | boolean): void;
extract(): {
status: number | undefined;
csp: {
[key: string]: string | boolean | string[];
};
redirectUrl: string | undefined;
};
}
export declare function applyToContext<T extends Context>(ctx: T, manager: ServerManager): T;
export { NetworkManager, EFFECT_ID };
export declare function applyToContext<T extends Context>(ctx: T, manager: NetworkManager): T;

@@ -5,54 +5,7 @@ "use strict";

var network_1 = require("@shopify/network");
var manager_1 = require("./manager");
exports.NetworkManager = manager_1.NetworkManager;
exports.EFFECT_ID = manager_1.EFFECT_ID;
var context_1 = require("./context");
exports.NetworkContext = context_1.NetworkContext;
exports.EFFECT_ID = Symbol('network');
var ServerManager = /** @class */ (function () {
function ServerManager() {
var _this = this;
this.effect = {
id: exports.EFFECT_ID,
betweenEachPass: function () { return _this.reset(); },
};
this.statusCodes = [];
this.csp = new Map();
}
ServerManager.prototype.reset = function () {
this.statusCodes = [];
this.csp.clear();
this.redirectUrl = undefined;
};
ServerManager.prototype.redirectTo = function (url, status) {
if (status === void 0) { status = network_1.StatusCode.Found; }
this.addStatusCode(status);
this.redirectUrl = url;
};
ServerManager.prototype.addStatusCode = function (statusCode) {
this.statusCodes.push(statusCode);
};
ServerManager.prototype.addCspDirective = function (directive, value) {
var normalizedValue = typeof value === 'string' ? [value] : value;
var currentValue = this.csp.get(directive) || [];
var normalizedCurrentValue = Array.isArray(currentValue)
? currentValue
: [String(currentValue)];
var newValue = Array.isArray(normalizedValue)
? tslib_1.__spread(normalizedCurrentValue, normalizedValue) : normalizedValue;
this.csp.set(directive, newValue);
};
ServerManager.prototype.extract = function () {
return {
status: this.statusCodes.length > 0
? this.statusCodes.reduce(function (large, code) { return Math.max(large, code); }, 0)
: undefined,
csp: tslib_1.__spread(this.csp.entries()).reduce(function (csp, _a) {
var _b = tslib_1.__read(_a, 2), directive = _b[0], value = _b[1];
var _c;
return (tslib_1.__assign({}, csp, (_c = {}, _c[directive] = value, _c)));
}, {}),
redirectUrl: this.redirectUrl,
};
};
return ServerManager;
}());
exports.ServerManager = ServerManager;
function applyToContext(ctx, manager) {

@@ -59,0 +12,0 @@ var _a = manager.extract(), status = _a.status, csp = _a.csp, redirectUrl = _a.redirectUrl;

{
"name": "@shopify/react-network",
"version": "3.0.0-beta.1",
"version": "3.0.0",
"license": "MIT",

@@ -28,3 +28,3 @@ "description": "A collection of components that allow you to set common HTTP headers from within your React application.",

"@shopify/network": "^1.2.2",
"@shopify/react-effect": "3.0.0-beta.1",
"@shopify/react-effect": "^3.0.0",
"@types/koa": "^2.0.46",

@@ -31,0 +31,0 @@ "tslib": "^1.9.3"

@@ -18,70 +18,41 @@ # `@shopify/react-network`

To start, have your app accept a `Manager` object, and pass in a `ServerManager` object in your server render (on the client rehydration, you can safely omit any manager, and the library will simply no-op all of the components discussed below):
### Application
```tsx
// in App.tsx
import {Manager, Provider} from '@shopify/react-network';
This library provides a number of React hooks and components you can use anywhere in application to register network-related details on the server.
export default function App({networkManager}: {networkManager: Manager}) {
return <Provider manager={networkManager}>Your app here!</Provider>;
}
#### `useRedirect()` and `<Redirect />`
// in your server render
import {ServerManager} from '@shopify/react-network';
import App from './App';
Specifies a redirect location. `applyToContext` will call `ctx.redirect()` with the passed URL, and set the status code, if you pass the `code` prop.
export default function render(ctx: Context) {
const networkManager = new ServerManager();
const app = <App networkManager={networkManager} />;
}
```
```tsx
import {useRedirect, Redirect, StatusCode} from '@shopify/react-network';
This process lets your server-rendered application store some state about the HTTP details. The next step is to extract this information using `@shopify/react-effect`, and then the `applyToContext` utility from this package to apply it to the response. Your final server middleware will resemble the example below:
function MyComponent() {
useRedirect('/login', StatusCode.SeeOther);
```tsx
import {renderToString} from 'react-dom/server';
import {extract} from '@shopify/react-effect/server';
import {ServerManager, applyToContext} from '@shopify/react-network';
import App from './App';
// or
export default function render(ctx: Context) {
const networkManager = new ServerManager();
const app = <App networkManager={networkManager} />;
await extract(app);
applyToContext(ctx, networkManager);
ctx.body = renderToString(app);
return <Redirect url="/login" code={StatusCode.SeeOther} />;
}
```
> Note: You can selectively extract _only_ the network details by using the `EFFECT_ID` exported from `@shopify/react-network`, and using this as the second argument to `@shopify/react-effect`’s `extract()` as detailed in its documentation. Most consumers of this package will be fine with just the example above.
#### `useStatus()` and `<Status />`
### `<Redirect />`
Specifies a status code. `applyToContext` will set `ctx.status` with the passed status code. If multiple status codes are set during the navigation of the tree, the most "significant" one will be used — that is, the status code that is the highest numerically.
Specifies a redirect location. `applyToContext` will call `ctx.redirect()` with the passed URL, and set the status code, if you pass the `status` prop.
```tsx
<Redirect url="/login">
```
import {useStatus, Status, StatusCode} from '@shopify/react-network';
### `<Status />`
function MyComponent() {
useStatus(StatusCode.NotFound);
Specifies a status code. `applyToContext` will set `ctx.status` with the passed status code. If multiple status codes are set during the navigation of the tree, the most "significant" one will be used — that is, the status code that is the highest numerically. The example below illustrates how you can use this component to always return a 404 status code for a `NotFound` component:
// or
```tsx
import {Status, StatusCode} from '@shopify/react-network';
export default function NotFound() {
return (
<>
<div>We couldn’t find that page :(</div>
<Status code={StatusCode.NotFound} />
</>
);
return <Status code={StatusCode.SeeOther} />;
}
```
### Content security policy
#### `useCspDirective()` and content security policy components
This package exports many components for constructing a [content security policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy). Every CSP directive has a matching component in this library that exposes a nice API for setting that directive. When `applyToContext` is run, it will group together all of the directives and set the CSP header.
This package exports a `useCspDirective()` hook (and many components) for constructing a [content security policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy). Every CSP directive has a matching component in this library that exposes a nice API for setting that directive. When `applyToContext` is run, it will group together all of the directives and set the CSP header.

@@ -92,5 +63,7 @@ There are too many to go over individually, but the example below illustrates setting up a simple CSP. Review the available imports from the library for all available components.

import {
useCspDirective,
DefaultSource,
StyleSource,
SpecialSource,
CspDirective,
UpgradeInsecureRequests,

@@ -100,2 +73,11 @@ } from '@shopify/react-network';

export default function ContentSecurityPolicy() {
useCspDirective(CspDirective.DefaultSrc, [SpecialSource.Self]);
useCspDirective(CspDirective.StyleSrc, [
SpecialSource.Self,
SpecialSource.UnsafeInline,
]);
useCspDirective(CspDirective.UpgradeInsecureRequests, true);
// OR
return (

@@ -111,4 +93,36 @@ <>

### Server
To extract details from your application, render a `NetworkContext.Provider` around your app, and give it an instance of the `NetworkManager`. When using `react-effect`, this decoration can be done in the `decorate` option of `extract()`. Finally, you can use the `applyToContext` utility from this package to apply the necessary headers to the response. Your final server middleware will resemble the example below:
```tsx
import {renderToString} from 'react-dom/server';
import {extract} from '@shopify/react-effect/server';
import {
NetworkManager,
NetworkContext,
applyToContext,
} from '@shopify/react-network/server';
import App from './App';
export default function render(ctx: Context) {
const networkManager = new NetworkManager();
const app = <App />;
await extract(app, {
decorate: element => (
<NetworkContext.Provider value={networkManager}>
{element}
</NetworkContext.Provider>
),
});
applyToContext(ctx, networkManager);
ctx.body = renderToString(app);
}
```
> Note: You can selectively extract _only_ the network details by using the `EFFECT_ID` exported from `@shopify/react-network/server`, and using this as the second argument to `@shopify/react-effect`’s `extract()` as detailed in its documentation. Most consumers of this package will be fine with just the example above.
### Other utilities
This library re-exports the entirety of [`@shopify/network`](https://github.com/Shopify/quilt/tree/master/packages/network), so you do not need to install both.
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