Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
@beuluis/create-helper
Advanced tools
A helper to create your own create-something app
·
Report Bug
·
Request Feature
·
A helper to create your own create-something
app. Inspired by create-initializer.
npm i @beuluis/create-helper
The next
dist-tag is kept in sync with the latest commit on main. So this contains always the latest changes but is highly unstable.
npm i @beuluis/create-helper@next
This pack is meant to be used with the npm init which runs the main bin of a pack when provided as parameter.
Use @beuluis/create-something or
Create a new create-something
pack.
Create a bin script in the desired destination. (Make sure to set main and bin)
Call the create
helper function and configure it.
Publish your pack. The pack name has to be prefixed with create-
for npm create
to work.
Run
npm create @scope/your-pack <create_path>
# or
npx @scope/create-your-pack <create_path>
Create helper function accepts CreateOptions as parameter.
Example:
#!/usr/bin/node
import { resolve } from 'path';
import { create } from '@beuluis/create-helper';
import autocomplete, { AutocompleteQuestionOptions } from 'inquirer-autocomplete-prompt';
// needed if you register a new prompt type
declare module 'inquirer' {
interface QuestionMap<T> {
autocomplete: AutocompleteQuestionOptions<T>;
}
}
const fetchTotallyDynamicReactVersion = () => '1.0.0';
create({
templatesDirectory: resolve(__dirname, 'templates'),
templatesPrefix: 'test-',
defaultTemplate: 'test',
partials: resolve(__dirname, 'templates', 'partials'),
layouts: resolve(__dirname, 'templates', 'layouts'),
argumentAnswerParsing: toParseAnswerArguments => {
const result = toParseAnswerArguments;
// Only map the argument isEarthling to a JS boolean if provided
// You probably want to do this for every boolean type to use non interactive mode correctly
if ('isEarthling' in result) {
result.isEarthling = Boolean(result.isEarthling);
}
return result;
},
setupInteractiveUI: (engine, buildInQuestions) => {
// exposes the internal used interactive UI engine helper and build in questions for modifications/usage
engine.registerPrompt('autocomplete', autocomplete);
// This is just to show this function you can also combine this with registerQuestions
engine.registerQuestion({
type: 'input',
message: 'Message was overridden?',
name: 'name',
});
engine.registerQuestions([
buildInQuestions.name,
buildInQuestions.description,
buildInQuestions.license,
{
type: 'input',
message: 'World?',
name: 'hello',
},
{
type: 'autocomplete',
name: 'from',
message: 'Select a state to travel from',
source: (answersSoFar, input) => myApi.searchStates(input),
},
{
type: 'confirm',
name: 'isEarthling',
message: 'Are you from earth?',
},
]);
},
setupTemplateEngine: engine => {
engine.registerFilter('upper', v => v.toUpperCase());
engine.registerTag('upper', myTag);
},
beforeCreationHook: async ({ getBeforeHookHelper, answers }) => {
console.log(`I run before ${answers.template} scaffold being created.`);
const helper = getBeforeHookHelper();
await helper.runCommand('echo', ['hello world']);
// Could be used to inject some dynamic values
return { ...answers, reactVersion: fetchTotallyDynamicReactVersion() };
},
afterCreationHook: async ({ getAfterHookHelper, answers }) => {
console.log(`${answers.name} is a perfect name for a new project!`);
const helper = getAfterHookHelper();
await helper.runCommand('echo', ['hello world']);
},
});
A template
variable is always injected into the answers hash to use it in answer validation or when conditions.
engine.registerQuestions([
{
type: 'input',
message: 'World?',
name: 'hello',
when: ({ template }) => template === 'abc',
},
]);
Setup function that exposes the internal used helper instance and build in questions for modifications/usage. Gets UIHelper and a indexed object of the inquire question type as parameter. See build in questions
Setup function that exposes the internal used helper instance for modifications. Gets TemplateHelper as parameter
Hook run after all files are copied. Gets AfterCreationHookObject as parameter
Function to parse/modify argument from the command line. Good for mapping falsy value to JS false.
Hook run before all files are copied. Gets BeforeCreationHookObject as parameter and returns new answerers to be used
void create({
argumentAnswerParsing: toParseAnswerArguments => {
const result = toParseAnswerArguments;
if ('isEarthling' in result) {
result.isEarthling = Boolean(result.isEarthling);
}
return result;
},
});
npm create something --isEarthling
Results in { isEarthling: true }
.
npm create something --isEarthling 0 # or other falsy values
Results in { isEarthling: false }
.
We need to do enable an explicit true/false like that since simply not providing --isEarthling
is confusion the library.
There is no way to tell if you simply want it to be traded as false
or not answered to trigger the prompting.
Get function to get a helper to run predefined actions. Gets AfterCreationHookOptions as parameter and returns AfterHookHelper
Get function to get a helper to run predefined actions. Returns HookHelper
templatesDirectory
- Directory for template lookup
templatesPrefix
- Prefix for template lookup. Can be useful if you want to mix other directories in the template directory.
defaultTemplate
- Default template without the prefix.
templateIgnorePattern
- Regex patterns to ignore while templating files with liquidjs. Default: [/\.(gif|jpe?g|tiff?|png|webp|bmp)$/u]
partials
- Partials directory. See partials-and-layouts
layouts
- layouts directory. See partials-and-layouts
setupInteractiveUI
- Exposed the internal used interactive UI engine helper and build in questions for modifications/usage. See setupInteractiveUI and build in questions.
setupTemplateEngine
- Exposed the internal used template engine helper for modifications. See setupTemplateEngine
afterCreationHook
- Hook run after all files are copied. See afterCreationHook
argumentAnswerParsing
- Function to parse/modify argument from the command line. Good for mapping falsy value to JS false.
beforeCreationHook
- Hook run before all files are copied. See beforeCreationHook
modifyCreatePath
- Dangerous option: Gets the user selected create path to modify. Returned string will be used as new create path. Can be useful for temp directories or already full paths in certain situations
registerPrompt
- Registered a new prompt. See documentation of inquirer
registerQuestion
- Registers a new question with name as selector. See documentation of inquirer for question examples and types
registerQuestions
- Bulk register new questions with name as selector. See documentation of inquirer for question examples and types
prompt
- internal use
registerTag
- Registered a new tag. See register-filters-tags
registerFilter
- Registered a new filter. See register-filters-tags
parseAndRender
- internal use
renderFile
- internal use
packageManager
- Packagemanager to be used for actionsresolvedCreatePath
- Used create path
resolvedTemplateDirectory
- Used template directory
createOptions
- Used create options. See CreateOptions
answers
- All given answers
getAfterHookHelper
- Get function to configure the after hook helper and to run predefined actions. See getAfterHookHelpergetBeforeHookHelper
- Get function to configure the before hook helper and to run predefined actions. See getBeforeHookHelperinitGit
- Initialize a empty git repository.
installDependencies
- Installs all dependencies with the configured package manager. See AfterCreationHookOptions
runCommand
- runs a command with the new project root ad cwd.For templating this pack internally use liquidjs.
name
- Name for the new project
description
- Description of the new project
license
- License of the new project
The Create helper function uses minimist to parse provided arguments.
Those can be used to answer questions via arguments.
Templates are provided via arguments: --template <template_name>
will do the trick.
If nothing is provided that helper function wil, fallback to the defined default template
npm run test-cli
It will create a project from test templates
File permissions are preserved
The template engine is also run for file and directory names
NPM renames .gitignore
to .npmignore
during publish. To prevent this you can use echo in the filename: {% echo '.gitignore' %}
NPM processed every package.json
during publish and applied the files
filter. To prevent this you can use echo in the filename: {% echo 'package' %}.json
and add the $schema
to the file for 'linting':
{
"$schema": "https://json.schemastore.org/package.json"
}
Seeing something like Unexpected error occurred during the processing of test.png
? This file cannot be parsed by liquidjs. Try to adapt the templateIgnorePattern
to ignore those files.
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
git checkout -b feature/AmazingFeature
)git commit -m 'Add some AmazingFeature'
)git push origin feature/AmazingFeature
)Luis Beu - me@luisbeu.de
FAQs
A helper to create a create-something app
We found that @beuluis/create-helper demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer 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.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.