Security News
Node.js EOL Versions CVE Dubbed the "Worst CVE of the Year" by Security Experts
Critics call the Node.js EOL CVE a misuse of the system, sparking debate over CVE standards and the growing noise in vulnerability databases.
@pmnps/core
Advanced tools
This package is built for provide the file structure system
for pmnps.
export declare const structure: {
// the actual root dir node
root(): StructureRoot;
// the modify root dir node
alterRoot(): StructureRoot;
// the actual package.json content from 'root & packages & platforms'
packageJsons(): PackageJsons;
// the api to modify dir and file nodes
rebuild(redoCallback: RebuildCallback): StructureRoot;
// regenerate and modify dirs and files from the alterRoot()
flush(): Promise<void>;
// filter nodes you need
filter(
root: StructureRoot | StructureNode,
nodeLike: Partial<StructureNode> | ((node: StructureNode) => boolean)
): StructureNode[];
// find the node you need
find(
root: StructureRoot | StructureNode,
nodeLike: Partial<StructureNode> | ((node: StructureNode) => boolean)
): StructureNode | undefined;
};
This is a structure data describe the root dir of pmnps. You can use structure.root()
api to get the actual one, and use structure.alterRoot()
api to get the current modifing root.
export declare type StructureRoot = {
// the actual path of the root dir
path: string;
// mark out this is a root node
type: 'root';
// the primary child dir and file nodes
children: StructureNode[];
// write child nodes into root as part of `children` field,
// it compare `name` fields from new nodes with old children,
// and deside merge or create by the node actions
write(
children:
| string
| ((content: string) => string)
| (StructureNode | undefined | null)[]
): StructureRoot;
// find node matched by partial fields or a true callback
find(
nodeLike: Partial<StructureNode> | ((node: StructureNode) => boolean)
): StructureNode | undefined;
// filter nodes matched by partial fields or a true callback
filter(
nodeLike: Partial<StructureNode> | ((node: StructureNode) => boolean)
): StructureNode[];
};
structure:
- packages
- @scope
- my-pack
index.js
package.json
- my-pack
index.js
package.json
- platforms
package.json
.pmnpsrc.json
trans to root
- root
- node {name:'packages', type:'dir', children:[...belowNodes]}
- node {name:'@scope', type:'dir', children:[...belowNodes]}
- node {name:'my-pack', type:'dir', children:[...belowNodes]}
node {name:'index.js', type:'file'}
node {name:'package.json', type:'file'}
- node {name:'my-pack', type:'dir', children:[...belowNodes]}
node {name:'index.js', type:'file'}
node {name:'package.json', type:'file'}
- node {name:'platforms', type:'dir', children:[...belowNodes]}
node {name:'package.json', type:'file'}
node {name:'.pmnpsrc.json', type:'file'}
root.find
api can find out the node you want under this root.import {structure,path} from '@pmnps/core';
const actualRoot = structure.root();
// find the package dir node which name is 'my-pack'
const myNode = actualRoot.find({name:'my-pack', projectType:'package'});
// the find api find out the most close to root level node,
// so, here we find out the node path like `root/packages/my-pack`,
// not the one under `@scope` dir.
// If you want to find more exactly,
// the callback and the more attrs are needed.
const scopeMyNode = actualRoot.find(({name,parent,projectType})=>{
return name === 'my-pack' && projectType === 'package' && parent.path !== path.packagesPath;
});
root.filter
api can filter out the nodes you need under this root.import {structure,path} from '@pmnps/core';
const actualRoot = structure.root();
// filter the package dir nodes which name is 'my-pack'
const myNodes = actualRoot.filter({name:'my-pack', projectType:'package'});
root.write
api can modify structrure nodes, it only can be called in a rebuild callback.import {structure,path} from '@pmnps/core';
const packageJson = {name:'my-test',version:'1.0.0'};
structure.rebuild((root, {file, dir})=>{
// root will merge the dir nodes into alterRoot
root.write([
// the `packages` dir is exist, it will not be make again
dir('packages',[
// `@scope` is like packages
dir('@scope',[
// `my-test` is not exist in `@scope` dir,
// it will be created
dir('my-test',[
// create an empty `index.js` file in `my-test`
file('index.js'),
// create `package.json` with content in `my-test`
file('package.json', packageJson)
])
])
])
]);
});
// after modify, the pmnps will call `structure.flush()` to mkdir and write files.
Warning: the write
api can only be called in rebuild callback, or it will throw exception.
export declare type StructureNode = {
// the name of the node dir or file
name: string;
// the path of the node dir or file
path: string;
// 'file'|'dir'
type: StructureNodeType;
// content which is written into a file node
content?: string | ((c: string) => string);
// if this node is not exist in old parent, it is 'create'
// if the node is exist yet, and has been modified, it is 'write'
status?: StructureStatus;
// the parent node which has a `children` field contains this node
parent?: StructureNode | StructureRoot;
// if the node is a package project dir or package.json, it is 'package'
// if the node is a platform project dir or package.json, it is 'platform'
projectType?: ProjectType;
// if the node is a package.json, it is true.
isPackageJson?: boolean;
// the primary child nodes
children?: StructureNode[];
// a file node can write a string as content
// a file node can write an object, the json string will be content
// a file node can provide a content map function to map content
// a dir node can write children, and merge them with the old children
write(
children?:
| string
| ((content: string) => string)
| (StructureNode | undefined | null)[]
): StructureNode;
// a node can rename itself
rename(name: string): StructureNode;
// just like the find method in root to find out a node under the dir node
find(
nodeLike: Partial<StructureNode> | ((node: StructureNode) => boolean)
): StructureNode | undefined;
// just like the filter method in root to filter nodes under the dir node
filter(
nodeLike: Partial<StructureNode> | ((node: StructureNode) => boolean)
): StructureNode[];
};
The write method of StructureNode can only be called in a rebuild callback too.
import {structure,path} from '@pmnps/core';
const packageJson = {name:'my-test',version:'1.0.0'};
structure.rebuild((root, {file, dir})=>{
// find the `@scope` dir node first,
// and this node's parent should be 'packages'
const scopeNode = root.find(({name,parent})=> name==='@scope' && parent.path === path.packagesPath);
if(!scopeNode){
return;
}
// write `@scope` dir the `my-test` package project.
scopeNode.write([
dir('my-test',[
// create an empty `index.js` file in `my-test`
file('index.js'),
// create `package.json` with content in `my-test`
file('package.json', packageJson)
])
]);
});
// after modify, the pmnps will call `structure.flush()` to mkdir and write files.
Sometimes we want to write or rename files in a plugin, we can use the status
field which is create
, like:
import {structure,path} from '@pmnps/core';
const packageJson = {name:'my-test',version:'1.0.0'};
structure.rebuild((root, {file, dir})=>{
// find the creating project node by use status 'create',
// and projectType is exist.
const creatingProject = root.find(({status, projectType})=> status === 'create' && projectType);
if(!creatingProject){
return;
}
// find the index file
const indexNode = creatingProject.find(({name})=>name.startsWith('index.'));
if(!indexNode){
return;
}
// rename the index file to name index.ts
indexNode.rename('index.ts');
});
// after modify, the pmnps will call `structure.flush()` to mkdir and write files.
If we want to change the content of a package.json file, we can use write
api, and give it a callback to read the current content as a base start.
import {structure,path} from '@pmnps/core';
const packageJson = {name:'my-test',version:'1.0.0'};
structure.rebuild((root, {file, dir})=>{
// find the creating project node by use status 'create',
// and projectType is exist.
const creatingProject = root.find(({status, projectType})=> status === 'create' && projectType);
if(!creatingProject){
return;
}
// find the package.json file
const packageJsonNode = creatingProject.find({isPackageJson:true});
if(!packageJsonNode){
return;
}
// change package.json file with the old content
packageJsonNode.write((c)=>{
const json = JSON.parse(c);
// for example we change the private field to false
json.private = false;
return JSON.stringify(json);
});
});
// after modify, the pmnps will call `structure.flush()` to mkdir and write files.
Use structure.packageJsons
api can fetch all package.json
content as json objects.
The result is an object:
export declare type PackageJson = {
name: string;
description?: string;
private?: boolean;
main?: string;
module?: string;
type?: string;
typings?: string;
files?: string[];
bin?: string | Record<string, any>;
preferGlobal?: boolean;
scripts?: Record<string, string>;
version?: string;
dependencies?: Record<string, string>;
devDependencies?: Record<string, string>;
deps?: Array<PackageJson>;
dets?: Array<PackageJson>;
level?: number;
used?: boolean;
pmnps?: Pmnps;
getDirPath?: ()=>string;
};
export declare type PackageJsons = {
root?: PackageJson;
packages: PackageJson[];
platforms: PackageJson[];
};
You can use the data to analyze the relationShip of packages and platforms.
export declare const path: {
rootPath: string;
packagesPath(): string;
platformsPath(): string;
join(...params: (string | null | undefined)[]): string;
};
path.rootPath
is the root dir path.path.packagesPath()
returns the path of packages
dir in root.path.platformsPath()
returns the path of platforms
dir in root.path.join
is a method like the nodejs path.join
, but it can filter the undefined and null param out.The plugin structure is a function with or without a param object.
// a render returns a boolean resolve promise,
// if it resolves a false data,
// the command and other plugins will be stopped,
// the requires array is the third lib tools versions
export declare type PluginRender = (requires: string[]) => Promise<boolean>;
export declare type PluginRenders = {
// run before refresh command
refresh?: PluginRender;
// run after create command
create?: PluginRender;
// run before build command
build?: PluginRender;
// run before start command
start?: PluginRender;
};
// a plugin pack contains some default configs for pmnps
export declare type PluginPack = {
// the main function called in different commands
renders: PluginRenders;
// isOption marks this plugin is optional
isOption?: boolean;
// displayName can prettier current plugin name
displayName?: string;
// requires is the third lib tools you need to write to package.json
requires?: string[];
};
// plugin entry function
export declare type PluginComponent = (
// config for plugin
config?: Record<string | number, any>
) => PluginPack;
Let's make a simple react plugin for example:
import {structure} from '@pmnps/core';
export default function reactPlugin(){
return {
// is optional
isOption:true,
// require react version
requires:['react'],
renders:{
// accept required react version,
// only run in create command
create([reactVersion]){
structure.rebuild((root})=>{
const createProject = root.find(({status,projectType})=> status === 'create' && !!projectType);
if(!createProject){
return;
}
// find package.json node
const packageJson = createProject.find(({isPackageJson})=>isPackageJson);
if(!packageJson){
return;
}
// write 'react' to package.json dependencies
packageJson.write((c)=>{
const {dependencies={},...rest} = JSON.parse(c);
const newJson = {
...rest,
dependencies:{...dependencies,react:reactVersion}
};
return JSON.stringify(newJson);
})
});
}
}
}
}
This is a simple plugin example, the actual react plugin will be more complex.
The API is not complete now, but the content before is enough for writing a plugin, so we will stop it currently, and complete it in next version publish.
FAQs
This is the core logic of pmnps
We found that @pmnps/core 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
Critics call the Node.js EOL CVE a misuse of the system, sparking debate over CVE standards and the growing noise in vulnerability databases.
Security News
cURL and Go security teams are publicly rejecting CVSS as flawed for assessing vulnerabilities and are calling for more accurate, context-aware approaches.
Security News
Bun 1.2 enhances its JavaScript runtime with 90% Node.js compatibility, built-in S3 and Postgres support, HTML Imports, and faster, cloud-first performance.