New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

shell

Package Overview
Dependencies
Maintainers
0
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

shell - npm Package Compare versions

Comparing version 0.11.0 to 0.12.0

377

dist/esm/index.js

@@ -27,4 +27,4 @@ import { is_object_literal, mutate, clone, merge } from 'mixme';

`Invalid Error Argument: expect an object literal, got ${JSON.stringify(
arg
)}.`
arg,
)}.`,
);

@@ -90,2 +90,6 @@ }

}
config.router.error_message ??= true;
config.router.error_stack ??= false;
config.router.error_help ??= false;
config.router.exit ??= false;
config.router.handler ??= "shell/routes/help";

@@ -97,6 +101,4 @@ config.router.promise ??= false;

config.router.stderr ??= process.stderr;
if (config.router.stderr_end == null) {
config.router.stderr_end = false;
}
if (!config.router.stdin instanceof stream.Readable) {
config.router.stderr_end ??= false;
if (!(config.router.stdin instanceof stream.Readable)) {
throw error([

@@ -108,3 +110,3 @@ "Invalid Configuration Property:",

}
if (!config.router.stdout instanceof stream.Writable) {
if (!(config.router.stdout instanceof stream.Writable)) {
throw error([

@@ -116,3 +118,3 @@ "Invalid Configuration Property:",

}
if (!config.router.stderr instanceof stream.Writable) {
if (!(config.router.stderr instanceof stream.Writable)) {
throw error([

@@ -139,5 +141,5 @@ "Invalid Configuration Property:",

"accept string or function",
!command.length
? "in application,"
: `in command ${JSON.stringify(command.join(" "))},`,
!command.length ? "in application," : (
`in command ${JSON.stringify(command.join(" "))},`
),
`got ${JSON.stringify(config.handler)}`,

@@ -176,3 +178,3 @@ ]);

throw error(
`Invalid Handler: expect a string or a function, got ${handler}`
`Invalid Handler: expect a string or a function, got ${handler}`,
);

@@ -183,18 +185,17 @@ }

const config = this.config().get();
context = {
// argv: process.argv.slice(2),
stdin: config.router.stdin,
stdout: config.router.stdout,
stdout_end: config.router.stdout_end,
stderr: config.router.stderr,
stderr_end: config.router.stderr_end,
...context,
command: command,
error: err,
params: params,
args: args,
};
return this.plugins.call_sync({
name: "shell:router:call",
args: context,
args: {
// argv: process.argv.slice(2),
stdin: config.router.stdin,
stdout: config.router.stdout,
stdout_end: config.router.stdout_end,
stderr: config.router.stderr,
stderr_end: config.router.stderr_end,
...context,
command: command,
error: err,
params: params,
args: args,
},
handler: (context) => {

@@ -206,13 +207,11 @@ if (!config.router.promise) {

// Otherwise wrap result in a promise
// Return value may be a promise
const result = handler.call(this, context, ...args);
if (result && typeof result.then === "function") {
if (result?.then) {
return result;
} else {
return Promise.resolve(result);
}
return new Promise(function (resolve, reject) {
return resolve(result);
});
} catch (err) {
return new Promise(function (resolve, reject) {
return reject(err);
});
return Promise.reject(err);
}

@@ -222,12 +221,25 @@ },

};
const route_error = (err, command) => {
context.argv = command.length ? ["help", ...command] : ["--help"];
const params = this.parse(context.argv);
const handler = route_load(this._config.router.handler);
if (handler.then) {
return handler.then(function (handler) {
const route_error = (err, message, command) => {
// Print message
if (message && appconfig.router.error_message) {
appconfig.router.stderr.write(`\n${message}\n`);
}
// Print stack
if (err && appconfig.router.error_stack) {
appconfig.router.stderr.write(`\n${err.stack}\n`);
}
// Print help command
if (!err | appconfig.router.error_help) {
context.argv = command.length ? ["help", ...command] : ["--help"];
const params = this.parse(context.argv);
const handler = route_load(this._config.router.handler);
if (handler.then) {
return handler.then(function (handler) {
return route_call(handler, command, params, err, args);
});
} else {
return route_call(handler, command, params, err, args);
});
}
} else {
return route_call(handler, command, params, err, args);
return Promise.resolve();
}

@@ -242,4 +254,5 @@ };

// Object.keys(config.commands).length or
err = config.root
? error([
err =
config.root ?
error([
"Missing Application Handler:",

@@ -250,12 +263,9 @@ 'a "handler" definition is required when no child command is defined',

"Missing Command Handler:",
`a \"handler\" definition ${JSON.stringify(
params[appconfig.command]
`a "handler" definition ${JSON.stringify(
params[appconfig.command],
)} is required when no child command is defined`,
]);
}
// Convert argument to an help command
// context.argv = command.length ? ['help', ...command] : ['--help'];
// params = this.parse(context.argv);
// handler = this.config.router.handler;
return route_error(err, command);
// Print help, error might be null
return route_error(err, err?.message, command);
}

@@ -268,10 +278,20 @@ // Loader is

return handler
.catch(async (err) => {
return route_error(
err,
`Fail to load module ${JSON.stringify(config.handler)}, message is: ${err.message}.`,
command,
);
})
.then(function (handler) {
if (!handler) return;
return route_call(handler, command, params, err, args);
})
.catch(async (err) => {
return route_error(
await route_error(
err,
`Fail to load route. Message is: ${err.message}`,
command
command,
);
throw err;
});

@@ -284,4 +304,5 @@ } else {

await route_error(
`Fail to load route. Message is: ${err.message}`,
command
err,
`Command failed to execute, message is: ${err.message}`,
command,
);

@@ -294,3 +315,7 @@ throw err;

} catch (err) {
route_error(`Fail to load route. Message is: ${err.message}`, command);
route_error(
err,
`Command failed to execute, message is: ${JSON.stringify(err.message)}`,
command,
);
throw err;

@@ -300,35 +325,61 @@ }

};
let params;
try {
// Read arguments
params = this.parse(context.argv);
} catch (err) {
return route_error(err, err.command || []);
}
// Print help
let command = this.helping(params);
if (command) {
// this seems wrong, must be the handler of the command
const handler = route_load(appconfig.router.handler);
if (handler.then) {
return handler.then(function (handler) {
// Dispose streams
const dispose = () => {
if (appconfig.router.stdout_end) {
appconfig.router.stdout.end();
}
if (appconfig.router.stderr_end) {
appconfig.router.stderr.end();
}
};
const run = () => {
let params;
try {
// Read arguments
params = this.parse(context.argv);
} catch (err) {
return route_error(null, err.message, err.command || []);
}
// Print help
let command = this.helping(params);
if (command) {
// this seems wrong, must be the handler of the command
const handler = route_load(appconfig.router.handler);
if (handler.then) {
return handler.then(function (handler) {
return route_call(handler, command, params, undefined, args);
});
} else {
return route_call(handler, command, params, undefined, args);
});
}
} else {
return route_call(handler, command, params, undefined, args);
}
} else {
// Return undefined if not parsing command based arguments
// Load a command route
command = params[appconfig.command];
if (appconfig.extended) {
// TODO: not tested yet, construct a commands array like in flatten mode when extended is activated
// command = (for i in [0...params.length] then params[i][appconfig.command]) if appconfig.extended
command = [];
for (const param in params) {
command.push[appconfig.command];
// Return undefined if not parsing command based arguments
// Load a command route
command = params[appconfig.command];
if (appconfig.extended) {
// TODO: not tested yet, construct a commands array like in flatten mode when extended is activated
// command = (for i in [0...params.length] then params[i][appconfig.command]) if appconfig.extended
// command = [];
// for (const param in params) {
// command.push[appconfig.command];
// }
console.warn("TODO");
}
const config = this.config(command).get();
return route_from_config(config, command || [], params);
}
const config = this.config(command).get();
return route_from_config(config, command || [], params);
};
try {
const res = run();
res?.finally?.(dispose);
if (appconfig.router.exit) {
res?.catch?.(() => process.exit(1));
}
return res;
} catch (err) {
dispose();
if (appconfig.router.exit) {
process.exit(1);
}
throw err;
}

@@ -436,3 +487,3 @@ };

config.options[name],
values
values,
));

@@ -453,5 +504,5 @@ if (!ctx._config.extended) {

`collide with the one in ${
ctx.collision[name].length === 0
? "application"
: JSON.stringify(ctx.collision[name].join(" "))
ctx.collision[name].length === 0 ?
"application"
: JSON.stringify(ctx.collision[name].join(" "))
},`,

@@ -476,5 +527,5 @@ "change its name or use the extended property",

`for option ${JSON.stringify(name)}`,
commands.length
? `in command ${JSON.stringify(commands.join(" "))}`
: void 0,
commands.length ?
`in command ${JSON.stringify(commands.join(" "))}`
: void 0,
]);

@@ -655,3 +706,3 @@ }

`key ${JSON.stringify(
config.name
config.name,
)} is not equal with name ${JSON.stringify(config.name)}`,

@@ -779,5 +830,5 @@ ]);

`the "-${shortcut}" argument is not a valid option`,
Array.isArray(config.command)
? `in command "${config.command.join(" ")}"`
: void 0,
Array.isArray(config.command) ?
`in command "${config.command.join(" ")}"`
: void 0,
]);

@@ -863,12 +914,12 @@ }

const required =
typeof option.required === "function"
? !!option.required.call(null, {
config: config,
command: command,
})
: !!option.required;
typeof option.required === "function" ?
!!option.required.call(null, {
config: config,
command: command,
})
: !!option.required;
if (required && params[option.name] == null) {
throw error([
"Required Option:",
`the \"${option.name}\" option must be provided`,
`the "${option.name}" option must be provided`,
]);

@@ -887,3 +938,3 @@ }

"Invalid Argument Value:",
`the value of option \"${option.name}\"`,
`the value of option "${option.name}"`,
`must be one of ${JSON.stringify(option.enum)},`,

@@ -909,3 +960,3 @@ `got ${JSON.stringify(value)}`,

"Invalid Argument:",
`fail to interpret all arguments \"${leftover.join(" ")}\"`,
`fail to interpret all arguments "${leftover.join(" ")}"`,
]);

@@ -929,8 +980,8 @@ }

const required =
typeof main.required === "function"
? !!main.required.call(null, {
config: config,
command: command,
})
: !!main.required;
typeof main.required === "function" ?
!!main.required.call(null, {
config: config,
command: command,
})
: !!main.required;
if (required && params[main.name].length === 0) {

@@ -1011,8 +1062,8 @@ throw error([

const required =
typeof option.required === "function"
? !!option.required.call(null, {
config: config,
command: undefined,
})
: !!option.required;
typeof option.required === "function" ?
!!option.required.call(null, {
config: config,
command: undefined,
})
: !!option.required;
if (required && value == null) {

@@ -1033,3 +1084,3 @@ throw error([

"Invalid Parameter Value:",
`the value of option \"${option.name}\"`,
`the value of option "${option.name}"`,
`must be one of ${JSON.stringify(option.enum)},`,

@@ -1065,8 +1116,8 @@ `got ${JSON.stringify(val)}`,

const required =
typeof config.main.required === "function"
? !!config.main.required.call(null, {
config: config,
command: undefined,
})
: !!config.main.required;
typeof config.main.required === "function" ?
!!config.main.required.call(null, {
config: config,
command: undefined,
})
: !!config.main.required;
if (required && value == null) {

@@ -1090,8 +1141,8 @@ throw error([

// Recursive
const has_child_commands = options.extended
? data.length
: Object.keys(config.commands).length;
const has_child_commands =
options.extended ? data.length : Object.keys(config.commands).length;
if (has_child_commands) {
const command = options.extended
? data[0][appconfig.command]
const command =
options.extended ?
data[0][appconfig.command]
: data[appconfig.command].shift();

@@ -1103,7 +1154,7 @@ if (!config.commands[command]) {

`expect one of ${JSON.stringify(
Object.keys(config.commands).sort()
Object.keys(config.commands).sort(),
)}`,
Array.isArray(config.command)
? `in command ${JSON.stringify(config.command.join(" "))}`
: void 0,
Array.isArray(config.command) ?
`in command ${JSON.stringify(config.command.join(" "))}`
: void 0,
]);

@@ -1116,3 +1167,3 @@ }

config.commands[command],
options.extended ? data.shift() : ldata
options.extended ? data.shift() : ldata,
);

@@ -1134,3 +1185,3 @@ }

`the property --${key} is not a registered argument`,
].join(" ")
].join(" "),
);

@@ -1224,3 +1275,3 @@ }

command,
config.commands[command.name]
config.commands[command.name],
);

@@ -1230,4 +1281,4 @@ }

handler.call(this, ...arguments);
return config.description != null
? config.description
return config.description != null ?
config.description
: (config.description = `No description yet for the ${config.name} command`);

@@ -1244,4 +1295,4 @@ };

handler.call(this, ...arguments);
return config.description != null
? config.description
return config.description != null ?
config.description
: (config.description = `No description yet for the ${config.name} command`);

@@ -1299,3 +1350,3 @@ };

`parameter ${JSON.stringify(
appconfig.command
appconfig.command,
)} must be an array in flatten mode,`,

@@ -1320,4 +1371,5 @@ `got ${JSON.stringify(params[appconfig.command])}`,

// Note, when argv equals ['help'], there is no leftover and main is null
const leftover = !options.extended
? params[appconfig.commands[commands[0]].main.name]
const leftover =
!options.extended ?
params[appconfig.commands[commands[0]].main.name]
: params[1][appconfig.commands[commands[0]].main.name];

@@ -1415,5 +1467,5 @@ if (leftover) {

"Invalid Command:",
`argument \"${commands
`argument "${commands
.slice(0, i + 1)
.join(" ")}\" is not a valid command`,
.join(" ")}" is not a valid command`,
]);

@@ -1438,3 +1490,3 @@ }

return `${options.indent}${l}`;
})
}),
);

@@ -1488,3 +1540,3 @@ } else {

return `${options.indent}${l}`;
})
}),
);

@@ -1522,3 +1574,3 @@ } else {

return `${options.indent}${l}`;
})
}),
);

@@ -1547,3 +1599,3 @@ } else {

`${options.indent}${[command.name].join(" ")}`,
options.columns
options.columns,
);

@@ -1564,3 +1616,3 @@ if (line.length > options.columns) {

content.push("");
content.push(`COMMAND \"${command.name}\"`);
content.push(`COMMAND "${command.name}"`);
// Raw command, no main, no child commands

@@ -1607,4 +1659,4 @@ if (

`${options.indent}Where command is ${Object.keys(
command.commands
)}.`
command.commands,
)}.`,
);

@@ -1614,4 +1666,4 @@ } else if (commands.length > 1) {

`${options.indent}Where command is one of ${Object.keys(
command.commands
).join(", ")}.`
command.commands,
).join(", ")}.`,
);

@@ -1626,7 +1678,7 @@ }

// has_help_option = Object.values(config.options).some (option) -> option.name is 'help'
const has_help_command = Object.values(config.commands).some(function (
command
) {
return command.name === "help";
});
const has_help_command = Object.values(config.commands).some(
function (command) {
return command.name === "help";
},
);
content.push("");

@@ -1644,3 +1696,3 @@ content.push("EXAMPLES");

return `${options.indent}${l}`;
})
}),
);

@@ -1662,3 +1714,3 @@ } else {

return `${options.indent}${l}`;
})
}),
);

@@ -1715,3 +1767,3 @@ } else {

`got ${JSON.stringify(module)}`,
].join(" ")
].join(" "),
);

@@ -1725,3 +1777,3 @@ }

const loader = await load(
this._config.load /* `, this._config.load.namespace` */
this._config.load /* `, this._config.load.namespace` */,
);

@@ -1741,3 +1793,2 @@ return loader(module, namespace);

const shell = function (config) {

@@ -1744,0 +1795,0 @@ const shell = new Shell(config);

// Route Help
// Print the help information to stderr.
function help ({ params, error, stderr, stderr_end }) {
function help ({ params, stderr }) {
const command = this.helping(params);
if (error) {
stderr.write(`\n${typeof error === "string" ? error : error.message}\n`);
}
// if (error) {
// stderr.write(`\n${typeof error === "string" ? error : error.message}\n`);
// }
stderr.write(this.help(command));
if (stderr_end) {
stderr.end();
}
// if (stderr_end) {
// stderr.end();
// }
return null;

@@ -14,0 +14,0 @@ }

@@ -26,2 +26,6 @@ // Plugin "router"

}
config.router.error_message ??= true;
config.router.error_stack ??= false;
config.router.error_help ??= false;
config.router.exit ??= false;
config.router.handler ??= "shell/routes/help";

@@ -33,5 +37,3 @@ config.router.promise ??= false;

config.router.stderr ??= process.stderr;
if (config.router.stderr_end == null) {
config.router.stderr_end = false;
}
config.router.stderr_end ??= false;
if (!(config.router.stdin instanceof stream.Readable)) {

@@ -115,18 +117,17 @@ throw error([

const config = this.config().get();
context = {
// argv: process.argv.slice(2),
stdin: config.router.stdin,
stdout: config.router.stdout,
stdout_end: config.router.stdout_end,
stderr: config.router.stderr,
stderr_end: config.router.stderr_end,
...context,
command: command,
error: err,
params: params,
args: args,
};
return this.plugins.call_sync({
name: "shell:router:call",
args: context,
args: {
// argv: process.argv.slice(2),
stdin: config.router.stdin,
stdout: config.router.stdout,
stdout_end: config.router.stdout_end,
stderr: config.router.stderr,
stderr_end: config.router.stderr_end,
...context,
command: command,
error: err,
params: params,
args: args,
},
handler: (context) => {

@@ -138,13 +139,11 @@ if (!config.router.promise) {

// Otherwise wrap result in a promise
// Return value may be a promise
const result = handler.call(this, context, ...args);
if (result && typeof result.then === "function") {
if (result?.then) {
return result;
} else {
return Promise.resolve(result);
}
return new Promise(function (resolve) {
return resolve(result);
});
} catch (err) {
return new Promise(function (resolve, reject) {
return reject(err);
});
return Promise.reject(err);
}

@@ -154,12 +153,25 @@ },

};
const route_error = (err, command) => {
context.argv = command.length ? ["help", ...command] : ["--help"];
const params = this.parse(context.argv);
const handler = route_load(this._config.router.handler);
if (handler.then) {
return handler.then(function (handler) {
const route_error = (err, message, command) => {
// Print message
if (message && appconfig.router.error_message) {
appconfig.router.stderr.write(`\n${message}\n`);
}
// Print stack
if (err && appconfig.router.error_stack) {
appconfig.router.stderr.write(`\n${err.stack}\n`);
}
// Print help command
if (!err | appconfig.router.error_help) {
context.argv = command.length ? ["help", ...command] : ["--help"];
const params = this.parse(context.argv);
const handler = route_load(this._config.router.handler);
if (handler.then) {
return handler.then(function (handler) {
return route_call(handler, command, params, err, args);
});
} else {
return route_call(handler, command, params, err, args);
});
}
} else {
return route_call(handler, command, params, err, args);
return Promise.resolve();
}

@@ -187,7 +199,4 @@ };

}
// Convert argument to an help command
// context.argv = command.length ? ['help', ...command] : ['--help'];
// params = this.parse(context.argv);
// handler = this.config.router.handler;
return route_error(err, command);
// Print help, error might be null
return route_error(err, err?.message, command);
}

@@ -200,10 +209,20 @@ // Loader is

return handler
.catch(async (err) => {
return route_error(
err,
`Fail to load module ${JSON.stringify(config.handler)}, message is: ${err.message}.`,
command,
);
})
.then(function (handler) {
if (!handler) return;
return route_call(handler, command, params, err, args);
})
.catch(async (err) => {
return route_error(
await route_error(
err,
`Fail to load route. Message is: ${err.message}`,
command,
);
throw err;
});

@@ -216,3 +235,4 @@ } else {

await route_error(
`Fail to load route. Message is: ${err.message}`,
err,
`Command failed to execute, message is: ${err.message}`,
command,

@@ -226,3 +246,7 @@ );

} catch (err) {
route_error(`Fail to load route. Message is: ${err.message}`, command);
route_error(
err,
`Command failed to execute, message is: ${JSON.stringify(err.message)}`,
command,
);
throw err;

@@ -232,37 +256,62 @@ }

};
let params;
try {
// Read arguments
params = this.parse(context.argv);
} catch (err) {
return route_error(err, err.command || []);
}
// Print help
let command = this.helping(params);
if (command) {
// this seems wrong, must be the handler of the command
const handler = route_load(appconfig.router.handler);
if (handler.then) {
return handler.then(function (handler) {
// Dispose streams
const dispose = () => {
if (appconfig.router.stdout_end) {
appconfig.router.stdout.end();
}
if (appconfig.router.stderr_end) {
appconfig.router.stderr.end();
}
};
const run = () => {
let params;
try {
// Read arguments
params = this.parse(context.argv);
} catch (err) {
return route_error(null, err.message, err.command || []);
}
// Print help
let command = this.helping(params);
if (command) {
// this seems wrong, must be the handler of the command
const handler = route_load(appconfig.router.handler);
if (handler.then) {
return handler.then(function (handler) {
return route_call(handler, command, params, undefined, args);
});
} else {
return route_call(handler, command, params, undefined, args);
});
}
} else {
return route_call(handler, command, params, undefined, args);
// Return undefined if not parsing command based arguments
// Load a command route
command = params[appconfig.command];
if (appconfig.extended) {
// TODO: not tested yet, construct a commands array like in flatten mode when extended is activated
// command = (for i in [0...params.length] then params[i][appconfig.command]) if appconfig.extended
// command = [];
// for (const param in params) {
// command.push[appconfig.command];
// }
console.warn("TODO");
}
const config = this.config(command).get();
return route_from_config(config, command || [], params);
}
} else {
// Return undefined if not parsing command based arguments
// Load a command route
command = params[appconfig.command];
if (appconfig.extended) {
// TODO: not tested yet, construct a commands array like in flatten mode when extended is activated
// command = (for i in [0...params.length] then params[i][appconfig.command]) if appconfig.extended
// command = [];
// for (const param in params) {
// command.push[appconfig.command];
// }
console.warn("TODO");
};
try {
const res = run();
res?.finally?.(dispose);
if (appconfig.router.exit) {
res?.catch?.(() => process.exit(1));
}
const config = this.config(command).get();
return route_from_config(config, command || [], params);
return res;
} catch (err) {
dispose();
if (appconfig.router.exit) {
process.exit(1);
}
throw err;
}
};
// Route Help
// Print the help information to stderr.
export default function ({ params, error, stderr, stderr_end }) {
export default function ({ params, stderr }) {
const command = this.helping(params);
if (error) {
stderr.write(`\n${typeof error === "string" ? error : error.message}\n`);
}
// if (error) {
// stderr.write(`\n${typeof error === "string" ? error : error.message}\n`);
// }
stderr.write(this.help(command));
if (stderr_end) {
stderr.end();
}
// if (stderr_end) {
// stderr.end();
// }
return null;
}
{
"name": "shell",
"version": "0.11.0",
"version": "0.12.0",
"description": "Command line arguments parser and stringifier",

@@ -28,17 +28,16 @@ "keywords": [

"mixme": "^1.1.0",
"pad": "^3.2.0",
"pad": "^3.3.0",
"plug-and-play": "^2.5.8"
},
"devDependencies": {
"@eslint/js": "^9.8.0",
"@eslint/js": "^9.15.0",
"coffeescript": "^2.7.0",
"dedent": "^1.5.3",
"eslint": "^9.8.0",
"eslint": "^9.15.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-mocha": "^10.4.3",
"eslint-plugin-mocha": "^10.5.0",
"eslint-plugin-prettier": "^5.2.1",
"mocha": "^10.7.0",
"mocha": "^10.8.2",
"prettier": "^3.3.3",
"rollup": "^4.19.1",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup": "^4.27.4",
"should": "^13.2.3"

@@ -99,3 +98,3 @@ },

"type": "module",
"gitHead": "f5e3cbf1d9673dd84d2e11ab8b0b40f0427a1b35"
"gitHead": "a7452a2aa52cf8c14cdf546bd0feda3941efe367"
}

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