![Kill Switch Hidden in npm Packages Typosquatting Chalk and Chokidar](https://cdn.sanity.io/images/cgdhsj6q/production/6199b2d12ffc9c39c6ca08c94d7b3217946ad92a-1024x1024.webp?w=400&fit=max&auto=format)
Research
Security News
Kill Switch Hidden in npm Packages Typosquatting Chalk and Chokidar
Socket researchers found several malicious npm packages typosquatting Chalk and Chokidar, targeting Node.js developers with kill switches and data theft.
Promzard is a Node.js module that allows you to create interactive command-line prompts for user input. It is particularly useful for creating configuration files or setting up project templates by asking users a series of questions and then generating the necessary files based on their responses.
Interactive Prompts
This feature allows you to create interactive command-line prompts by specifying a configuration file. The user is prompted to answer questions, and the responses are used to generate a configuration object.
const promzard = require('promzard');
const path = require('path');
const file = path.resolve(__dirname, 'config.js');
promzard(file).then((result) => {
console.log('Configuration:', result);
}).catch((err) => {
console.error('Error:', err);
});
Default Values
You can provide default values for the prompts, which will be used if the user does not provide an input. This is useful for setting up common configurations quickly.
const promzard = require('promzard');
const path = require('path');
const file = path.resolve(__dirname, 'config.js');
const defaults = { name: 'defaultName', version: '1.0.0' };
promzard(file, defaults).then((result) => {
console.log('Configuration:', result);
}).catch((err) => {
console.error('Error:', err);
});
Custom Validation
Promzard allows you to add custom validation logic to the user inputs. This ensures that the configuration generated meets certain criteria before it is accepted.
const promzard = require('promzard');
const path = require('path');
const file = path.resolve(__dirname, 'config.js');
const validate = (input) => {
if (input.name.length < 3) {
throw new Error('Name must be at least 3 characters long');
}
return input;
};
promzard(file, {}, validate).then((result) => {
console.log('Configuration:', result);
}).catch((err) => {
console.error('Error:', err);
});
Inquirer.js is a collection of common interactive command-line user interfaces. It provides a more extensive set of features compared to Promzard, including support for various types of prompts (e.g., list, checkbox, password) and more advanced validation and formatting options.
The 'prompt' package is a simple, flexible, and powerful command-line prompt library for Node.js. It offers similar functionality to Promzard but with a focus on simplicity and ease of use. It supports schema-based prompts and asynchronous operations.
Enquirer is a stylish, intuitive, and user-friendly prompt library for Node.js. It offers a rich set of features, including support for custom themes, advanced validation, and conditional prompts. Enquirer is designed to be highly customizable and easy to extend.
A prompting wizard for building files from specialized PromZard modules.
Used by npm init
.
A reimplementation of @SubStack's prompter, which does not use AST traversal.
From another point of view, it's a reimplementation of @Marak's wizard which doesn't use schemas.
The goal is a nice drop-in enhancement for npm init
.
const promzard = require('promzard')
const data = await promzard(inputFile, optionalContextAdditions, options)
In the inputFile
you can have something like this:
const fs = require('fs/promises')
module.exports = {
"greeting": prompt("Who shall you greet?", "world", (who) => `Hello, ${who}`),
"filename": __filename,
"directory": async () => {
const entries = await fs.readdir(__dirname)
return entries.map(e => `entry: ${e}`)
}
}
When run, promzard will display the prompts and resolve the async functions in order, and then either give you an error, or the resolved data, ready to be dropped into a JSON file or some other place.
The inputFile is just a node module. You can require() things, set module.exports, etc. Whatever that module exports is the result, and it is walked over to call any functions as described below.
The only caveat is that you must give PromZard the full absolute path
to the module (you can get this via Node's require.resolve
.) Also,
the prompt
function is injected into the context object, so watch out.
Whatever you put in that ctx
will of course also be available in the
module. You can get quite fancy with this, passing in existing configs
and so on.
Use the backupFile
option as a fallback when inputFile
fails to be read.
Just like the promzard
function, but the class that makes it
all happen. The load
method returns a promise which will resolve
to the resolved data or throw with an error.
In the promzard input module, you can call the prompt
function.
This prompts the user to input some data. The arguments are interpreted
based on type:
string
The first string encountered is the prompt. The second is
the default value.function
A transformer function which receives the data and returns
something else. More than meets the eye.object
The prompt
member is the prompt, the default
member is
the default value, and the transform
is the transformer.Whatever the final value is, that's what will be put on the resulting object.
If there are any functions on the promzard input module's exports, then promzard will await each of them. This way, your module can do asynchronous actions if necessary to validate or ascertain whatever needs verification.
The functions are called in the context of the ctx object.
In the async function, you can also call prompt() and return the result of the prompt.
For example, this works fine in a promzard module:
exports.asyncPrompt = async function () {
const st = await fs.stat(someFile)
// if there's an error, no prompt, just error
// otherwise prompt and use the actual file size as the default
return prompt('file size', st.size)
}
You can also return other async functions in the async function callback. Though that's a bit silly, it could be a handy way to reuse functionality in some cases.
The prompt()
function is not synchronous, though it appears that way.
It just returns a token that is swapped out when the data object is
walked over asynchronously later, and returns a token.
For that reason, prompt() calls whose results don't end up on the data object are never shown to the user. For example, this will only prompt once:
exports.promptThreeTimes = prompt('prompt me once', 'shame on you')
exports.promptThreeTimes = prompt('prompt me twice', 'um....')
exports.promptThreeTimes = prompt('you cant prompt me again')
Yeah, sorta. I wouldn't use promzard for anything more complicated than a wizard that spits out prompts to set up a config file or something. Maybe there are other use cases I haven't considered.
FAQs
prompting wizardly
We found that promzard demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 6 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers found several malicious npm packages typosquatting Chalk and Chokidar, targeting Node.js developers with kill switches and data theft.
Security News
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.
Product
Socket now supports uv.lock files to ensure consistent, secure dependency resolution for Python projects and enhance supply chain security.