Socket
Socket
Sign inDemoInstall

nodeshift

Package Overview
Dependencies
Maintainers
4
Versions
104
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nodeshift - npm Package Compare versions

Comparing version 3.0.1 to 3.1.0

14

CHANGELOG.md

@@ -1,5 +0,17 @@

# Change Log
# Changelog
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
## [3.1.0](https://github.com/nodeshift/nodeshift/compare/v3.0.1...v3.1.0) (2019-08-19)
### Bug Fixes
* some typos in code and comments ([#330](https://github.com/nodeshift/nodeshift/issues/330)) ([b510e9d](https://github.com/nodeshift/nodeshift/commit/b510e9d))
### Features
* change the output Image Stream name and tag ([#347](https://github.com/nodeshift/nodeshift/issues/347)) ([3faa599](https://github.com/nodeshift/nodeshift/commit/3faa599)), closes [#337](https://github.com/nodeshift/nodeshift/issues/337)
## [3.0.1](https://github.com/nodeshift/nodeshift/compare/v3.0.0...v3.0.1) (2019-04-24)

@@ -6,0 +18,0 @@

54

index.js

@@ -5,5 +5,3 @@ 'use strict';

/** @module index */
/**
/*
This is the public facing API of nodeshift. The commands here mirror the commands from the CLI.

@@ -16,3 +14,3 @@ All methods take an options object

@param {object} [options] -
@param {object} [options] - Options object for the deploy function
@param {string} [options.projectLocation] - the location(directory) of your projects package.json. Defaults to `process.cwd`

@@ -23,5 +21,7 @@ @param {boolean} [options.expose] - Set to true to create a default Route and expose the default service. defaults to false

@param {boolean} [options.namespace.create] - flag to create the namespace if it does not exist. Only applicable for the build and deploy command. Must be used with namespace.name
@param {string} [options.namesapce.name] - flag to specify the project namespace name to build/deploy into. Overwrites any namespace settings in your OpenShift or Kubernetes configuration files
@param {string} [options.namespace.name] - flag to specify the project namespace name to build/deploy into. Overwrites any namespace settings in your OpenShift or Kubernetes configuration files
@param {string} [options.imageTag] - set the version to use for the nodeshift/centos7-s2i-image. Versions are docker hub tags: https://hub.docker.com/r/nodeshift/centos7-s2i-nodejs/tags/
@param {boolean} [options.quiet] - supress INFO and TRACE lines from output logs
@param {string} [options.outputImageStream] - the name of the ImageStream to output to. Defaults to project name from package.json
@param {string} [options.outputImageTag] - The tag of the ImageStream to output to. Defaults to latest
@param {boolean} [options.quiet] - suppress INFO and TRACE lines from output logs
@param {object} [options.deploy] -

@@ -35,3 +35,3 @@ @param {number} [options.deploy.port] - flag to update the default ports on the resource files. Defaults to 8080

@param {array} [options.definedProperties] - Array of objects with the format { key: value }. Used for template substitution
@returns {Promise} - Returns a JSON Object
@returns {Promise<object>} - Returns a JSON Object
*/

@@ -47,3 +47,3 @@ function deploy (options = {}) {

@param {object} [options] -
@param {object} [options] - Options object for the resource function
@param {string} [options.projectLocation] - the location(directory) of your projects package.json. Defaults to `process.cwd`

@@ -53,5 +53,7 @@ @param {boolean} [options.expose] - Set to true to create a default Route and expose the default service. defaults to false

@param {string} [options.namespace.displayName] - flag to specify the project namespace display name to build/deploy into. Overwrites any namespace settings in your OpenShift or Kubernetes configuration files
@param {string} [options.namesapce.name] - flag to specify the project namespace name to build/deploy into. Overwrites any namespace settings in your OpenShift or Kubernetes configuration files
@param {string} [options.namespace.name] - flag to specify the project namespace name to build/deploy into. Overwrites any namespace settings in your OpenShift or Kubernetes configuration files
@param {string} [options.imageTag] - set the version to use for the nodeshift/centos7-s2i-image. Versions are docker hub tags: https://hub.docker.com/r/nodeshift/centos7-s2i-nodejs/tags/
@param {boolean} [options.quiet] - supress INFO and TRACE lines from output logs
@param {string} [options.outputImageStream] - the name of the ImageStream to output to. Defaults to project name from package.json
@param {string} [options.outputImageTag] - The tag of the ImageStream to output to. Defaults to latest
@param {boolean} [options.quiet] - suppress INFO and TRACE lines from output logs
@param {object} [options.build] -

@@ -61,3 +63,3 @@ @param {string/boolean} [options.build.recreate] - flag to recreate a buildConfig or Imagestream. values are "buildConfig", "imageStream", true, false. Defaults to false

@param {array} [options.definedProperties] - Array of objects with the format { key: value }. Used for template substitution
@returns {Promise} - Returns a JSON Object
@returns {Promise<object>} - Returns a JSON Object
*/

@@ -72,3 +74,3 @@ function resource (options = {}) {

@param {object} [options] -
@param {object} [options] - Options object for the apply-resource function
@param {string} [options.projectLocation] - the location(directory) of your projects package.json. Defaults to `process.cwd`

@@ -79,5 +81,7 @@ @param {boolean} [options.expose] - Set to true to create a default Route and expose the default service. defaults to false

@param {boolean} [options.namespace.create] - flag to create the namespace if it does not exist. Only applicable for the build and deploy command. Must be used with namespace.name
@param {string} [options.namesapce.name] - flag to specify the project namespace name to build/deploy into. Overwrites any namespace settings in your OpenShift or Kubernetes configuration files
@param {string} [options.namespace.name] - flag to specify the project namespace name to build/deploy into. Overwrites any namespace settings in your OpenShift or Kubernetes configuration files
@param {string} [options.imageTag] - set the version to use for the nodeshift/centos7-s2i-image. Versions are docker hub tags: https://hub.docker.com/r/nodeshift/centos7-s2i-nodejs/tags/
@param {boolean} [options.quiet] - supress INFO and TRACE lines from output logs
@param {string} [options.outputImageStream] - the name of the ImageStream to output to. Defaults to project name from package.json
@param {string} [options.outputImageTag] - The tag of the ImageStream to output to. Defaults to latest
@param {boolean} [options.quiet] - suppress INFO and TRACE lines from output logs
@param {object} [options.deploy] -

@@ -90,3 +94,3 @@ @param {number} [options.deploy.port] - flag to update the default ports on the resource files. Defaults to 8080

@param {array} [options.definedProperties] - Array of objects with the format { key: value }. Used for template substitution
@returns {Promise} - Returns a JSON Object
@returns {Promise<object>} - Returns a JSON Object
*/

@@ -101,3 +105,3 @@ function applyResource (options = {}) {

@param {object} [options] -
@param {object} [options] - Options object for the undeploy function
@param {string} [options.projectLocation] - the location(directory) of your projects package.json. Defaults to `process.cwd`

@@ -107,5 +111,7 @@ @param {object} [options.namespace] -

@param {boolean} [options.namespace.remove] - flag to remove the user created namespace. Only applicable for the undeploy command. Must be used with namespace.name
@param {string} [options.namesapce.name] - flag to specify the project namespace name to build/deploy into. Overwrites any namespace settings in your OpenShift or Kubernetes configuration files
@param {string} [options.namespace.name] - flag to specify the project namespace name to build/deploy into. Overwrites any namespace settings in your OpenShift or Kubernetes configuration files
@param {string} [options.imageTag] - set the version to use for the nodeshift/centos7-s2i-image. Versions are docker hub tags: https://hub.docker.com/r/nodeshift/centos7-s2i-nodejs/tags/
@param {boolean} [options.quiet] - supress INFO and TRACE lines from output logs
@param {string} [options.outputImageStream] - the name of the ImageStream to output to. Defaults to project name from package.json
@param {string} [options.outputImageTag] - The tag of the ImageStream to output to. Defaults to latest
@param {boolean} [options.quiet] - suppress INFO and TRACE lines from output logs
@param {boolean} [options.removeAll] - option to remove builds, buildConfigs and Imagestreams. Defaults to false

@@ -119,3 +125,3 @@ @param {object} [options.deploy] -

@param {array} [options.definedProperties] - Array of objects with the format { key: value }. Used for template substitution
@returns {Promise} - Returns a JSON Object
@returns {Promise<object>} - Returns a JSON Object
*/

@@ -130,3 +136,3 @@ function undeploy (options = {}) {

@param {object} [options] -
@param {object} [options] - Options object for the build function
@param {string} [options.projectLocation] - the location(directory) of your projects package.json. Defaults to `process.cwd`

@@ -136,5 +142,7 @@ @param {object} [options.namespace] -

@param {boolean} [options.namespace.create] - flag to create the namespace if it does not exist. Only applicable for the build and deploy command. Must be used with namespace.name
@param {string} [options.namesapce.name] - flag to specify the project namespace name to build/deploy into. Overwrites any namespace settings in your OpenShift or Kubernetes configuration files
@param {string} [options.namespace.name] - flag to specify the project namespace name to build/deploy into. Overwrites any namespace settings in your OpenShift or Kubernetes configuration files
@param {string} [options.imageTag] - set the version to use for the nodeshift/centos7-s2i-image. Versions are docker hub tags: https://hub.docker.com/r/nodeshift/centos7-s2i-nodejs/tags/
@param {boolean} [options.quiet] - supress INFO and TRACE lines from output logs
@param {string} [options.outputImageStream] - the name of the ImageStream to output to. Defaults to project name from package.json
@param {string} [options.outputImageTag] - The tag of the ImageStream to output to. Defaults to latest
@param {boolean} [options.quiet] - suppress INFO and TRACE lines from output logs
@param {object} [options.build] -

@@ -145,3 +153,3 @@ @param {string/boolean} [options.build.recreate] - flag to recreate a buildConfig or Imagestream. values are "buildConfig", "imageStream", true, false. Defaults to false

@param {array} [options.definedProperties] - Array of objects with the format { key: value }. Used for template substitution
@returns {Promise} - Returns a JSON Object
@returns {Promise<object>} - Returns a JSON Object
*/

@@ -148,0 +156,0 @@ function build (options = {}) {

@@ -57,3 +57,3 @@ /*

logger.info(`Deleteing build configuration ${buildName}`);
logger.info(`Deleting build configuration ${buildName}`);
// First get the list of builds with the labelselector

@@ -72,3 +72,3 @@ // https://URL/oapi/v1/namespaces/NAMESPACE/builds?labelSelector=openshift.io/build-config.name=BUILD_NAME

for (const items of buildList.body.items) {
logger.info(`Deleteing build ${items.metadata.name}`);
logger.info(`Deleting build ${items.metadata.name}`);
await awaitRequest(config.openshiftRestClient.apis.build.v1.ns(config.namespace.name).builds(items.metadata.name).delete({ body: removeOptions }));

@@ -83,4 +83,3 @@ }

const buildName = config.buildName;
const imageStreamName = config.projectName;
const outputImageStreamTag = `${imageStreamName}:latest`; // TODO: base on a tag
const outputImageStreamTag = `${config.outputImageStreamName}:${config.outputImageStreamTag}`;
// The new code under the openshift rest client, returns an error when getting a 404, so we need to catch it and check the status code

@@ -124,3 +123,3 @@ // I wonder if it is better to find all buildConfigs, then do a Array.find on the returned item list

logger.info(`using existing build configuration ${buildName}`);
// TODO: be able to update the buildConfig
return buildConfig;

@@ -127,0 +126,0 @@ }

@@ -31,3 +31,3 @@ /*

const container = {
image: config.projectName,
image: config.outputImageStreamName,
name: config.projectName,

@@ -34,0 +34,0 @@ securityContext: {

@@ -56,3 +56,3 @@ /*

namespace: config.namespace.name,
name: `${config.projectName}:latest`
name: `${config.outputImageStreamName}:${config.outputImageStreamTag}`
}

@@ -59,0 +59,0 @@ }

@@ -27,3 +27,3 @@ /*

const metadata = {
name: options.name, // The proejcts name
name: options.name, // The projects name
namespace: options.namespace // The current namespace from the config, not required and should be picked up anyway, but...

@@ -30,0 +30,0 @@ };

@@ -53,3 +53,3 @@ /*

// then delete the deploymentconfig
logger.info(`Deleteing Deployment Config ${deploymentConfigResource.metadata.name}`);
logger.info(`Deleting Deployment Config ${deploymentConfigResource.metadata.name}`);
response.deploymentConfig = await awaitRequest(config.openshiftRestClient.apis['apps.openshift.io'].v1.ns(config.namespace.name).deploymentconfigs(deploymentConfigResource.metadata.name).delete({ body: removeOptionsDeploymentConfig }));

@@ -66,3 +66,3 @@ // Get the list of replication controllers

for (const items of rcList.body.items) {
logger.info(`Deleteing replication controller ${items.metadata.name}`);
logger.info(`Deleting replication controller ${items.metadata.name}`);
response.replicationControllers.push(

@@ -69,0 +69,0 @@ await awaitRequest(config.openshiftRestClient.api.v1.ns(config.namespace.name).replicationcontrollers(items.metadata.name).delete({ body: removeOptionsReplicationControllers }))

@@ -30,3 +30,3 @@ /*

module.exports = async function build (config) {
// arvhice the application source
// archive the application source
await projectArchiver.archiveAndTar(config);

@@ -33,0 +33,0 @@

@@ -49,25 +49,8 @@ /*

// TODO: make this a promise with the util.promisify
function createDir (directoryToCreate) {
return new Promise((resolve, reject) => {
mkdirp(directoryToCreate, (err) => {
if (err) {
return reject(new Error(err));
}
return resolve();
});
});
return promisify(mkdirp)(directoryToCreate);
}
// TODO: make this a promise with the util.promisify
function cleanUp (directoryToClean) {
return new Promise((resolve, reject) => {
rimraf(directoryToClean, (err) => {
if (err) {
return reject(new Error(err));
}
return resolve();
});
});
return promisify(rimraf)(directoryToClean);
}

@@ -74,0 +57,0 @@

@@ -38,3 +38,3 @@ /*

imageStream.metadata = objectMetadata({
name: config.projectName,
name: config.outputImageStreamName,
namespace: config.namespace.name,

@@ -51,6 +51,6 @@ labels: {

async function createOrUpdateImageStream (config) {
const imageStream = await awaitRequest(config.openshiftRestClient.apis.image.v1.ns(config.namespace.name).imagestreams(config.projectName).get());
const imageStream = await awaitRequest(config.openshiftRestClient.apis.image.v1.ns(config.namespace.name).imagestreams(config.outputImageStreamName).get());
if (imageStream.code === 404) {
// Need to create the image stream
logger.info(`creating image stream ${config.projectName}`);
logger.info(`creating ImageStream ${config.outputImageStreamName}`);
return config.openshiftRestClient.apis.image.v1.ns(config.namespace.name).imagestreams.post({ body: createImageStream(config) });

@@ -64,7 +64,7 @@ }

logger.info(`Re-creating image stream ${config.projectName}`);
logger.info(`Re-creating ImageStream ${config.outputImageStreamName}`);
return config.openshiftRestClient.apis.image.v1.ns(config.namespace.name).imagestreams.post({ body: createImageStream(config) });
}
logger.info(`using existing image stream ${config.projectName}`);
logger.info(`using existing image stream ${config.outputImageStreamName}`);
return imageStream;

@@ -74,3 +74,3 @@ }

function removeImageStream (config) {
logger.info(`Deleting Image Stream ${config.projectName}`);
logger.info(`Deleting ImageStream ${config.outputImageStreamName}`);

@@ -86,3 +86,3 @@ // Some default remove Body Options for the rest client, maybe at some point, these will be exposed to the user

// delete image stream
return awaitRequest(config.openshiftRestClient.apis.image.v1.ns(config.namespace.name).imagestreams(config.projectName).delete({ body: removeOptions }));
return awaitRequest(config.openshiftRestClient.apis.image.v1.ns(config.namespace.name).imagestreams(config.outputImageStreamName).delete({ body: removeOptions }));
}

@@ -89,0 +89,0 @@

@@ -63,2 +63,4 @@ /*

options.outputImageStreamName = options.outputImageStreamName || projectPackage.name;
options.outputImageStreamTag = options.outputImageStreamTag || 'latest';
// Return a new object with the config, the rest client and other data.

@@ -65,0 +67,0 @@ return Object.assign({}, config, {

@@ -50,3 +50,3 @@ /*

// First check to see if we have a Deployment
if (_.filter(resourceList, { 'kind': 'Deployment' }).length < 1 && _.filter(resourceList, { 'kind': 'DeploymentConfig' }).length < 1) {
if (_.filter(resourceList, { kind: 'Deployment' }).length < 1 && _.filter(resourceList, { kind: 'DeploymentConfig' }).length < 1) {
// create the default deployment config and add in to the resource list

@@ -53,0 +53,0 @@ resourceList.push(defaultDeploymentConfig(config));

@@ -49,3 +49,3 @@ /*

// First check to see if we have a Route
if (_.filter(resourceList, { 'kind': 'Route' }).length < 1) {
if (_.filter(resourceList, { kind: 'Route' }).length < 1) {
// check to see if the user wants to create a default route with the "expose" flag

@@ -52,0 +52,0 @@ if (config.expose) {

@@ -63,3 +63,3 @@ /*

// First check to see if we have a Service
if (_.filter(resourceList, { 'kind': 'Service' }).length < 1) {
if (_.filter(resourceList, { kind: 'Service' }).length < 1) {
// create the default service and add in to the resource list

@@ -66,0 +66,0 @@ resourceList.push(defaultService(config));

@@ -49,3 +49,3 @@ /*

async function loadJSON (fileLocation) {
const jsonFile = await readFile(fileLocation, { encoding: 'uttf8' });
const jsonFile = await readFile(fileLocation, { encoding: 'utf8' });
return JSON.parse(jsonFile);

@@ -78,3 +78,3 @@ }

if (!kind) {
return Promise.reject(new Error(`unknown type: ${resource.type} for filen: ${resource.filename}`));
return Promise.reject(new Error(`unknown type: ${resource.type} for file: ${resource.filename}`));
}

@@ -81,0 +81,0 @@ } else {

{
"name": "nodeshift",
"version": "3.0.1",
"version": "3.1.0",
"description": "Plugin for running openshift deployments",

@@ -9,3 +9,3 @@ "bin": {

"scripts": {
"lint": "eslint bin/* lib/**/*.js test/*-test.js test/**/*-test.js index.js",
"lint": "eslint --fix bin/* lib/**/*.js test/*-test.js test/**/*-test.js index.js",
"test": "cross-env NODESHIFT_QUIET=true tape test/*-test.js test/**/*-test.js | tap-spec",

@@ -15,6 +15,13 @@ "coverage": "nyc npm test",

"coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls",
"docs": "./node_modules/.bin/jsdoc --verbose -d docs -t ./node_modules/ink-docstrap/template -R README.md index.js",
"docs": "documentation build index.js --shallow -f html -o docs --config documentation.yml",
"ci": "npm run lint && npm run coveralls",
"release": "standard-version"
"prerelease": "npm run lint && npm run test",
"release": "standard-version -a"
},
"standard-version": {
"scripts": {
"postbump": "npm run docs",
"precommit": "git add docs/"
}
},
"files": [

@@ -55,28 +62,26 @@ "package.json",

"openshift-rest-client": "~2.2.0",
"request": "~2.88.0",
"rimraf": "^2.6.1",
"tar": "^4.0.1",
"yargs": "^13.1.0"
"rimraf": "^3.0.0",
"tar": "~4.4.10",
"yargs": "^13.2.4"
},
"devDependencies": {
"coveralls": "^3.0.0",
"coveralls": "~3.0.6",
"cross-env": "^5.1.1",
"eslint": "^5.0.1",
"eslint-config-semistandard": "^13.0.0",
"eslint-config-standard": "^12.0.0",
"eslint-plugin-import": "^2.2.0",
"eslint-plugin-node": "^8.0.0",
"eslint-plugin-promise": "^4.0.0",
"eslint-plugin-react": "^7.12.4",
"documentation": "~12.1.0",
"eslint": "^6.0.1",
"eslint-config-semistandard": "^14.0.0",
"eslint-config-standard": "^13.0.1",
"eslint-plugin-import": "~2.18.0",
"eslint-plugin-node": "~9.1.0",
"eslint-plugin-promise": "~4.2.1",
"eslint-plugin-standard": "^4.0.0",
"ink-docstrap": "^1.3.2",
"jsdoc": "^3.5.5",
"nock": "^10.0.0",
"nyc": "~14.0.0",
"proxyquire": "^2.0.1",
"sinon": "^7.2.4",
"standard-version": "^5.0.0",
"nyc": "~14.1.1",
"proxyquire": "^2.1.3",
"sinon": "~7.4.0",
"standard-version": "^7.0.0",
"tap-spec": "^5.0.0",
"tape": "^4.7.0"
"tape": "~4.11.0"
}
}

@@ -46,3 +46,3 @@ # Nodeshift [![CircleCI](https://circleci.com/gh/nodeshift/nodeshift.svg?style=svg)](https://circleci.com/gh/nodeshift/nodeshift)

The `.nodeshift` directory contains your resource fragements. These are `.yml` files that describe your services, deployments, routes, etc. By default, nodeshift will create a `Service` and `DeploymentConfig` in memory, if none are provided. A `Route` resource fragment should be provided or use the `expose` flag if you want to expose your application to the outside world.
The `.nodeshift` directory contains your resource fragments. These are `.yml` files that describe your services, deployments, routes, etc. By default, nodeshift will create a `Service` and `DeploymentConfig` in memory, if none are provided. A `Route` resource fragment should be provided or use the `expose` flag if you want to expose your application to the outside world.

@@ -63,5 +63,5 @@ ### Resource Fragments

The default port value is 8080, but that can be overriden with the `--deploy.port` flag.
The default port value is 8080, but that can be overridden with the `--deploy.port` flag.
You can also override this value by provideding a .nodeshift/deployment.yaml resource file
You can also override this value by providing a .nodeshift/deployment.yaml resource file

@@ -128,13 +128,13 @@

#### Example Usage
```javascript
const nodeshift = require('nodeshift');
const nodeshift = require('nodeshift');
// Deploy an Application
nodeshift.deploy().then((response) => {
console.log(response);
console.log('Application Deployed')
}).catch((err) => {
console.log(err);
})
// Deploy an Application
nodeshift.deploy().then((response) => {
console.log(response);
console.log('Application Deployed')
}).catch((err) => {
console.log(err);
})
````
_please note: Currently, once a route, service, deployment config, build config, and imagestream config are created, those are re-used. The only thing that changes from deployment to deployment is the source code. For application resources, you can update them by undeploying and then deploying again. BuildConfigs and Imagestreams can be re-created using the --build.recreate flag_

@@ -156,3 +156,3 @@

#### imageTag
Specify the tag of the docker image to use for the deployed application. defaults to latest. These version tags corespond to the docker hub tags of the [nodeshift s2i images](https://hub.docker.com/r/nodeshift/centos7-s2i-nodejs/tags/)
Specify the tag of the docker image to use for the deployed application. defaults to latest. These version tags correspond to the docker hub tags of the [nodeshift s2i images](https://hub.docker.com/r/nodeshift/centos7-s2i-nodejs/tags/)

@@ -162,4 +162,10 @@ #### dockerImage

#### outputImageStream
The name of the ImageStream to output to. Defaults to project name from package.json
#### outputImageStreamTag
The tag of the ImageStream to output to. Defaults to latest
#### quiet
supress INFO and TRACE lines from output logs.
suppress INFO and TRACE lines from output logs.

@@ -207,3 +213,6 @@ #### expose

application. [string] [default: "latest"]
--quiet supress INFO and TRACE lines from output logs
--outputImageStream The name of the ImageStream to output to. Defaults
to project name from package.json [string]
--outputImageStreamTag The tag of the ImageStream to output to. [string]
--quiet suppress INFO and TRACE lines from output logs
[boolean]

@@ -222,3 +231,3 @@ --expose flag to create a default Route and expose the default

with namespace.name [boolean]
--namesapce.name flag to specify the project namespace name to
--namespace.name flag to specify the project namespace name to
build/deploy into. Overwrites any namespace settings

@@ -225,0 +234,0 @@ in your OpenShift or Kubernetes configuration files

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