@shopify/react-network
Advanced tools
Comparing version 3.0.0-beta.1 to 3.0.0
@@ -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 @@ |
"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" |
110
README.md
@@ -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. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
0
125
0
29416
639
+ Added@shopify/react-effect@3.3.6(transitive)
+ Addedobject-assign@4.1.1(transitive)
+ Addedprop-types@15.8.1(transitive)
+ Addedreact@16.14.0(transitive)
+ Addedreact-dom@16.14.0(transitive)
+ Addedreact-is@16.13.1(transitive)
+ Addedscheduler@0.19.1(transitive)
- Removed@shopify/react-effect@3.0.0-beta.1(transitive)
- Removed@shopify/useful-types@1.3.0(transitive)
- Removed@types/prop-types@15.7.13(transitive)
- Removed@types/react@18.3.7(transitive)
- Removedcsstype@3.1.3(transitive)
- Removedreact@18.3.1(transitive)
Updated@shopify/react-effect@^3.0.0