Socket
Socket
Sign inDemoInstall

graphile-build

Package Overview
Dependencies
Maintainers
1
Versions
167
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

graphile-build - npm Package Compare versions

Comparing version 4.0.0-beta.2 to 4.0.0-beta.4

node8plus/plugins/SubscriptionPlugin.js.flow

24

node8plus/extend.js

@@ -6,25 +6,19 @@ "use strict";

});
var _assign = require("babel-runtime/core-js/object/assign");
var _assign2 = _interopRequireDefault(_assign);
var _keys = require("babel-runtime/core-js/object/keys");
var _keys2 = _interopRequireDefault(_keys);
exports.default = extend;
const aExtendedB = new WeakMap();
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function extend(base, extra, hint) {
const keysA = (0, _keys2.default)(base);
const keysB = (0, _keys2.default)(extra);
const keysA = Object.keys(base);
const keysB = Object.keys(extra);
for (const key of keysB) {
if (keysA.indexOf(key) >= 0) {
const newValue = extra[key];
const oldValue = base[key];
if (aExtendedB.get(newValue) !== oldValue && keysA.indexOf(key) >= 0) {
throw new Error(`Overwriting key '${key}' is not allowed! ${hint || ""}`);
}
}
return (0, _assign2.default)({}, base, extra);
const obj = Object.assign({}, base, extra);
aExtendedB.set(obj, base);
return obj;
}
//# sourceMappingURL=extend.js.map

@@ -6,4 +6,55 @@ "use strict";

});
exports.MutationPayloadQueryPlugin = exports.ClientMutationIdDescriptionPlugin = exports.MutationPlugin = exports.QueryPlugin = exports.NodePlugin = exports.StandardTypesPlugin = exports.defaultPlugins = exports.buildSchema = exports.getBuilder = undefined;
exports.resolveNode = exports.MutationPayloadQueryPlugin = exports.ClientMutationIdDescriptionPlugin = exports.MutationPlugin = exports.QueryPlugin = exports.NodePlugin = exports.StandardTypesPlugin = exports.defaultPlugins = exports.buildSchema = exports.getBuilder = exports.singularize = exports.pluralize = exports.upperCamelCase = exports.constantCase = exports.camelCase = exports.upperFirst = exports.formatInsideUnderscores = exports.constantCaseAll = undefined;
var _utils = require("./utils");
Object.defineProperty(exports, "constantCaseAll", {
enumerable: true,
get: function () {
return _utils.constantCaseAll;
}
});
Object.defineProperty(exports, "formatInsideUnderscores", {
enumerable: true,
get: function () {
return _utils.formatInsideUnderscores;
}
});
Object.defineProperty(exports, "upperFirst", {
enumerable: true,
get: function () {
return _utils.upperFirst;
}
});
Object.defineProperty(exports, "camelCase", {
enumerable: true,
get: function () {
return _utils.camelCase;
}
});
Object.defineProperty(exports, "constantCase", {
enumerable: true,
get: function () {
return _utils.constantCase;
}
});
Object.defineProperty(exports, "upperCamelCase", {
enumerable: true,
get: function () {
return _utils.upperCamelCase;
}
});
Object.defineProperty(exports, "pluralize", {
enumerable: true,
get: function () {
return _utils.pluralize;
}
});
Object.defineProperty(exports, "singularize", {
enumerable: true,
get: function () {
return _utils.singularize;
}
});
var _util = require("util");

@@ -19,2 +70,6 @@

var _resolveNode = require("./resolveNode");
var _resolveNode2 = _interopRequireDefault(_resolveNode);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -40,3 +95,3 @@

const defaultPlugins = exports.defaultPlugins = [_plugins.StandardTypesPlugin, _plugins.NodePlugin, _plugins.QueryPlugin, _plugins.MutationPlugin, _plugins.ClientMutationIdDescriptionPlugin, _plugins.MutationPayloadQueryPlugin];
const defaultPlugins = exports.defaultPlugins = [_plugins.StandardTypesPlugin, _plugins.NodePlugin, _plugins.QueryPlugin, _plugins.MutationPlugin, _plugins.SubscriptionPlugin, _plugins.ClientMutationIdDescriptionPlugin, _plugins.MutationPayloadQueryPlugin];

@@ -49,2 +104,3 @@ exports.StandardTypesPlugin = _plugins.StandardTypesPlugin;

exports.MutationPayloadQueryPlugin = _plugins.MutationPayloadQueryPlugin;
exports.resolveNode = _resolveNode2.default;
//# sourceMappingURL=index.js.map

@@ -6,19 +6,2 @@ "use strict";

});
var _assign = require("babel-runtime/core-js/object/assign");
var _assign2 = _interopRequireDefault(_assign);
var _isFrozen = require("babel-runtime/core-js/object/is-frozen");
var _isFrozen2 = _interopRequireDefault(_isFrozen);
var _map = require("babel-runtime/core-js/map");
var _map2 = _interopRequireDefault(_map);
var _keys = require("babel-runtime/core-js/object/keys");
var _keys2 = _interopRequireDefault(_keys);
exports.default = makeNewBuild;

@@ -36,2 +19,8 @@

var _pluralize = require("pluralize");
var _pluralize2 = _interopRequireDefault(_pluralize);
var _utils = require("./utils");
var _extend = require("./extend");

@@ -43,6 +32,6 @@

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const isString = str => typeof str === "string";

@@ -78,3 +67,3 @@

for (const result of results) {
for (const k of (0, _keys2.default)(result)) {
for (const k of Object.keys(result)) {
data[k] = data[k] || [];

@@ -129,4 +118,4 @@ const value = result[k];

// information of this kind)
const fieldDataGeneratorsByFieldNameByType = new _map2.default();
const fieldArgDataGeneratorsByFieldNameByType = new _map2.default();
const fieldDataGeneratorsByFieldNameByType = new Map();
const fieldArgDataGeneratorsByFieldNameByType = new Map();

@@ -165,3 +154,3 @@ return {

}
if (!this.newWithHooks || !(0, _isFrozen2.default)(this)) {
if (!this.newWithHooks || !Object.isFrozen(this)) {
throw new Error("Please do not generate the schema during the build building phase, use 'init' instead");

@@ -205,3 +194,3 @@ }

const typeFields = StrippedType.getFields();
for (const alias of (0, _keys2.default)(fields)) {
for (const alias of Object.keys(fields)) {
const field = fields[alias];

@@ -231,3 +220,3 @@ // Run generators with `field` as the `parsedResolveInfoFragment`, pushing results to `results`

};
newSpec = builder.applyHooks(this, "GraphQLObjectType", newSpec, (0, _assign2.default)({}, commonContext, {
newSpec = builder.applyHooks(this, "GraphQLObjectType", newSpec, Object.assign({}, commonContext, {
addDataGeneratorForField,

@@ -238,5 +227,5 @@ recurseDataGeneratorsForField

const rawSpec = newSpec;
newSpec = (0, _assign2.default)({}, newSpec, {
newSpec = Object.assign({}, newSpec, {
interfaces: () => {
const interfacesContext = (0, _assign2.default)({}, commonContext, {
const interfacesContext = Object.assign({}, commonContext, {
Self,

@@ -253,3 +242,3 @@ GraphQLObjectType: rawSpec

const processedFields = [];
const fieldsContext = (0, _assign2.default)({}, commonContext, {
const fieldsContext = Object.assign({}, commonContext, {
addDataGeneratorForField,

@@ -271,3 +260,3 @@ recurseDataGeneratorsForField,

let newSpec = spec;
let context = (0, _assign2.default)({}, commonContext, {
let context = Object.assign({}, commonContext, {
Self,

@@ -307,3 +296,3 @@ addDataGenerator(fn) {

const typeFields = Type.getFields();
for (const alias of (0, _keys2.default)(fields)) {
for (const alias of Object.keys(fields)) {
const field = fields[alias];

@@ -330,4 +319,4 @@ const gens = fieldDataGeneratorsByFieldName[field.name];

newSpec.args = newSpec.args || {};
newSpec = (0, _assign2.default)({}, newSpec, {
args: builder.applyHooks(this, "GraphQLObjectType:fields:field:args", newSpec.args, (0, _assign2.default)({}, context, {
newSpec = Object.assign({}, newSpec, {
args: builder.applyHooks(this, "GraphQLObjectType:fields:field:args", newSpec.args, Object.assign({}, context, {
field: newSpec,

@@ -369,6 +358,6 @@ returnType: newSpec.type

const rawSpec = newSpec;
newSpec = (0, _assign2.default)({}, newSpec, {
newSpec = Object.assign({}, newSpec, {
fields: () => {
const processedFields = [];
const fieldsContext = (0, _assign2.default)({}, commonContext, {
const fieldsContext = Object.assign({}, commonContext, {
Self,

@@ -380,3 +369,3 @@ GraphQLInputObjectType: rawSpec,

}
let context = (0, _assign2.default)({}, commonContext, {
let context = Object.assign({}, commonContext, {
Self,

@@ -424,3 +413,3 @@ scope: (0, _extend2.default)((0, _extend2.default)(scope, {

const values = newSpec.values;
newSpec.values = (0, _keys2.default)(values).reduce((memo, valueKey) => {
newSpec.values = Object.keys(values).reduce((memo, valueKey) => {
const value = values[valueKey];

@@ -466,5 +455,12 @@ const newValue = builder.applyHooks(this, "GraphQLEnumType:values:value", value, commonContext, `|${newSpec.name}|${valueKey}`);

fieldDataGeneratorsByFieldNameByType,
fieldArgDataGeneratorsByFieldNameByType
fieldArgDataGeneratorsByFieldNameByType,
inflection: {
pluralize: _pluralize2.default,
singularize: _pluralize2.default.singular,
upperCamelCase: _utils.upperCamelCase,
camelCase: _utils.camelCase,
constantCase: _utils.constantCase
}
};
}
//# sourceMappingURL=makeNewBuild.js.map

@@ -7,8 +7,2 @@ "use strict";

var _assign = require("babel-runtime/core-js/object/assign");
var _assign2 = _interopRequireDefault(_assign);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
exports.default = function ClientMutationIdDescriptionPlugin(builder) {

@@ -46,3 +40,3 @@ builder.hook("GraphQLInputObjectType:fields:field", (field, { extend }, { scope: { isMutationInput, fieldName }, Self }) => {

}
return (0, _assign2.default)({}, args, {
return Object.assign({}, args, {
input: extend(args.input, {

@@ -49,0 +43,0 @@ description: "The exclusive input argument for this mutation. An object type, make sure to see documentation for this object’s fields."

@@ -6,3 +6,3 @@ "use strict";

});
exports.StandardTypesPlugin = exports.QueryPlugin = exports.NodePlugin = exports.MutationPlugin = exports.MutationPayloadQueryPlugin = exports.ClientMutationIdDescriptionPlugin = undefined;
exports.StandardTypesPlugin = exports.QueryPlugin = exports.NodePlugin = exports.SubscriptionPlugin = exports.MutationPlugin = exports.MutationPayloadQueryPlugin = exports.ClientMutationIdDescriptionPlugin = undefined;

@@ -21,2 +21,6 @@ var _ClientMutationIdDescriptionPlugin = require("./ClientMutationIdDescriptionPlugin");

var _SubscriptionPlugin = require("./SubscriptionPlugin");
var _SubscriptionPlugin2 = _interopRequireDefault(_SubscriptionPlugin);
var _NodePlugin = require("./NodePlugin");

@@ -39,2 +43,3 @@

exports.MutationPlugin = _MutationPlugin2.default;
exports.SubscriptionPlugin = _SubscriptionPlugin2.default;
exports.NodePlugin = _NodePlugin2.default;

@@ -41,0 +46,0 @@ exports.QueryPlugin = _QueryPlugin2.default;

@@ -7,8 +7,3 @@ "use strict";

var _keys = require("babel-runtime/core-js/object/keys");
var _keys2 = _interopRequireDefault(_keys);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function isValidMutation(Mutation) {

@@ -19,3 +14,3 @@ try {

}
if ((0, _keys2.default)(Mutation.getFields()).length === 0) {
if (Object.keys(Mutation.getFields()).length === 0) {
return false;

@@ -22,0 +17,0 @@ }

@@ -7,18 +7,9 @@ "use strict";

var _defineProperty = require("babel-runtime/core-js/object/define-property");
var _resolveNode = require("../resolveNode");
var _defineProperty2 = _interopRequireDefault(_defineProperty);
var _resolveNode2 = _interopRequireDefault(_resolveNode);
var _stringify = require("babel-runtime/core-js/json/stringify");
var _stringify2 = _interopRequireDefault(_stringify);
var _symbol = require("babel-runtime/core-js/symbol");
var _symbol2 = _interopRequireDefault(_symbol);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const base64 = str => new Buffer(String(str)).toString("base64");
const base64Decode = str => new Buffer(String(str), "base64").toString("utf8");

@@ -33,6 +24,6 @@ exports.default = function NodePlugin(builder, { nodeIdFieldName: inNodeIdFieldName }) {

nodeIdFieldName,
$$nodeType: (0, _symbol2.default)("nodeType"),
$$nodeType: Symbol("nodeType"),
nodeFetcherByTypeName,
getNodeIdForTypeAndIdentifiers(Type, ...identifiers) {
return base64((0, _stringify2.default)([this.getNodeAlias(Type), ...identifiers]));
return base64(JSON.stringify([this.getNodeAlias(Type), ...identifiers]));
},

@@ -105,12 +96,3 @@ addNodeFetcherForTypeName(typeName, fetcher) {

builder.hook("GraphQLObjectType:fields", (fields, {
$$isQuery,
$$nodeType,
parseResolveInfo,
getTypeByName,
extend,
nodeFetcherByTypeName,
getNodeType,
graphql: { GraphQLNonNull, GraphQLID, getNamedType }
}, {
builder.hook("GraphQLObjectType:fields", (fields, build, {
scope: { isRootQuery },

@@ -122,2 +104,7 @@ fieldWithHooks

}
const {
getTypeByName,
extend,
graphql: { GraphQLNonNull, GraphQLID }
} = build;
return extend(fields, {

@@ -140,26 +127,5 @@ [nodeIdFieldName]: {

},
async resolve(data, args, context, resolveInfo) {
resolve(data, args, context, resolveInfo) {
const nodeId = args[nodeIdFieldName];
if (nodeId === "query") {
return $$isQuery;
}
try {
const [alias, ...identifiers] = JSON.parse(base64Decode(nodeId));
const Type = getNodeType(alias);
if (!Type) {
throw new Error("Type not found");
}
const resolver = nodeFetcherByTypeName[getNamedType(Type).name];
const parsedResolveInfoFragment = parseResolveInfo(resolveInfo, {}, Type);
const resolveData = getDataFromParsedResolveInfoFragment(parsedResolveInfoFragment, getNamedType(Type));
const node = await resolver(data, identifiers, context, parsedResolveInfoFragment, resolveInfo.returnType, resolveData);
(0, _defineProperty2.default)(node, $$nodeType, {
enumerable: false,
configurable: false,
value: Type
});
return node;
} catch (e) {
return null;
}
return (0, _resolveNode2.default)(nodeId, build, { getDataFromParsedResolveInfoFragment }, data, context, resolveInfo);
}

@@ -166,0 +132,0 @@ }), {

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

var _symbol = require("babel-runtime/core-js/symbol");
var _symbol2 = _interopRequireDefault(_symbol);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
exports.default = async function QueryPlugin(builder) {
builder.hook("build", build => build.extend(build, {
$$isQuery: (0, _symbol2.default)("isQuery")
$$isQuery: Symbol("isQuery")
}, `Extending Build`));

@@ -18,0 +12,0 @@ builder.hook("GraphQLSchema", (schema, {

@@ -7,8 +7,3 @@ "use strict";

var _keys = require("babel-runtime/core-js/object/keys");
var _keys2 = _interopRequireDefault(_keys);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function isValidSubscription(Subscription) {

@@ -19,3 +14,3 @@ try {

}
if ((0, _keys2.default)(Subscription.getFields()).length === 0) {
if (Object.keys(Subscription.getFields()).length === 0) {
return false;

@@ -22,0 +17,0 @@ }

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

});
var _defineProperty = require("babel-runtime/core-js/object/define-property");
var _defineProperty2 = _interopRequireDefault(_defineProperty);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const base64Decode = str => new Buffer(String(str), "base64").toString("utf8");

@@ -38,3 +31,3 @@

const node = await resolver(data, identifiers, context, parsedResolveInfoFragment, resolveInfo.returnType, resolveData);
(0, _defineProperty2.default)(node, $$nodeType, {
Object.defineProperty(node, $$nodeType, {
enumerable: false,

@@ -41,0 +34,0 @@ configurable: false,

@@ -7,10 +7,2 @@ "use strict";

var _freeze = require("babel-runtime/core-js/object/freeze");
var _freeze2 = _interopRequireDefault(_freeze);
var _keys = require("babel-runtime/core-js/object/keys");
var _keys2 = _interopRequireDefault(_keys);
var _debug = require("debug");

@@ -64,2 +56,6 @@

// Inflection is used for naming resulting types/fields/args/etc - it's
// hookable so that other plugins may extend it or override it
inflection: [],
// 'build' phase should not generate any GraphQL objects (because the

@@ -179,2 +175,6 @@ // build object isn't finalised yet so it risks weirdness occurring); so

const initialBuild = (0, _makeNewBuild2.default)(this);
// Inflection needs to come first, in case 'build' hooks depend on it
initialBuild.inflection = this.applyHooks(initialBuild, "inflection", initialBuild.inflection, {
scope: {}
});
const build = this.applyHooks(initialBuild, "build", initialBuild, {

@@ -184,4 +184,4 @@ scope: {}

// Bind all functions so they can be dereferenced
(0, _utils.bindAll)(build, (0, _keys2.default)(build).filter(key => typeof build[key] === "function"));
(0, _freeze2.default)(build);
(0, _utils.bindAll)(build, Object.keys(build).filter(key => typeof build[key] === "function"));
Object.freeze(build);
this.applyHooks(build, "init", {}, { scope: {} });

@@ -188,0 +188,0 @@ return build;

@@ -6,2 +6,18 @@ "use strict";

});
exports.singularize = exports.pluralize = exports.upperCamelCase = exports.constantCase = exports.camelCase = exports.upperFirst = exports.formatInsideUnderscores = exports.constantCaseAll = exports.bindAll = undefined;
var _upperFirst = require("lodash/upperFirst");
var _upperFirst2 = _interopRequireDefault(_upperFirst);
var _camelCase = require("lodash/camelCase");
var _camelCase2 = _interopRequireDefault(_camelCase);
var _pluralize = require("pluralize");
var _pluralize2 = _interopRequireDefault(_pluralize);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const bindAll = (obj, keys) => {

@@ -13,4 +29,22 @@ keys.forEach(key => {

};
exports.bindAll = bindAll;
const constantCaseAll = exports.constantCaseAll = str => str.replace(/[^a-zA-Z0-9_]+/g, "_").replace(/[A-Z]+/g, "_$&").replace(/__+/g, "_").replace(/^[^a-zA-Z0-9]+/, "").replace(/^[0-9]/, "_$&") // GraphQL enums must not start with a number
.toUpperCase();
exports.bindAll = bindAll;
const formatInsideUnderscores = exports.formatInsideUnderscores = fn => str => {
const matches = str.match(/^(_*)([\s\S]*?)(_*)$/);
if (!matches) {
throw new Error("Impossible?"); // Satiate Flow
}
const [, start, middle, end] = matches;
return `${start}${fn(middle)}${end}`;
};
const upperFirst = exports.upperFirst = formatInsideUnderscores(_upperFirst2.default);
const camelCase = exports.camelCase = formatInsideUnderscores(_camelCase2.default);
const constantCase = exports.constantCase = formatInsideUnderscores(constantCaseAll);
const upperCamelCase = exports.upperCamelCase = str => upperFirst(camelCase(str));
const pluralize = exports.pluralize = str => (0, _pluralize2.default)(str);
const singularize = exports.singularize = str => _pluralize2.default.singular(str);
//# sourceMappingURL=utils.js.map
{
"name": "graphile-build",
"version": "4.0.0-beta.2",
"version": "4.0.0-beta.4",
"description": "Build a GraphQL schema from plugins",

@@ -8,3 +8,3 @@ "main": "node8plus/index.js",

"test": "jest",
"prepublish": "mkdir -p node8plus && babel -s true --out-dir node8plus src && ../../node_modules/.bin/flow-copy-source src node8plus",
"prepublish": "mkdir -p node8plus && babel -s true --out-dir node8plus src && flow-copy-source src node8plus",
"watch": "mkdir -p node8plus && babel -s true --watch --out-dir node8plus src"

@@ -31,5 +31,6 @@ },

"dependencies": {
"babel-runtime": ">=6 <7",
"debug": ">=2 <3",
"graphql-parse-resolve-info": "4.0.0-beta.2"
"graphql-parse-resolve-info": "4.0.0-beta.4",
"lodash": ">=4 <5",
"pluralize": "7.0.0"
},

@@ -36,0 +37,0 @@ "engines": {

@@ -10,5 +10,7 @@ // @flow

MutationPlugin,
SubscriptionPlugin,
ClientMutationIdDescriptionPlugin,
MutationPayloadQueryPlugin,
} from "./plugins";
import resolveNode from "./resolveNode";
import type { GraphQLSchema } from "graphql";

@@ -18,2 +20,13 @@

export {
constantCaseAll,
formatInsideUnderscores,
upperFirst,
camelCase,
constantCase,
upperCamelCase,
pluralize,
singularize,
} from "./utils";
export type {

@@ -63,2 +76,3 @@ Plugin,

MutationPlugin,
SubscriptionPlugin,
ClientMutationIdDescriptionPlugin,

@@ -75,2 +89,4 @@ MutationPayloadQueryPlugin,

MutationPayloadQueryPlugin,
// resolveNode: EXPERIMENTAL, API might change!
resolveNode,
};

@@ -6,2 +6,3 @@ // @flow

import MutationPlugin from "./MutationPlugin";
import SubscriptionPlugin from "./SubscriptionPlugin";
import NodePlugin from "./NodePlugin";

@@ -15,2 +16,3 @@ import QueryPlugin from "./QueryPlugin";

MutationPlugin,
SubscriptionPlugin,
NodePlugin,

@@ -17,0 +19,0 @@ QueryPlugin,

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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