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

asset-assistant

Package Overview
Dependencies
Maintainers
1
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

asset-assistant - npm Package Compare versions

Comparing version 0.0.18 to 0.0.20

src/AddDependency.js

12

package.json
{
"name": "asset-assistant",
"version": "0.0.18",
"description": "A lightweight tool for copying files from other packages.",
"version": "0.0.20",
"repository": {
"type": "git",
"url": "https://github.com/Thaerious/asset-assistant"
},
"keywords": [
"util",
"browser",
"tool",
"development",
"cli"
"light-weight"
],

@@ -28,4 +32,4 @@ "license": "MIT",

"devDependencies": {
"ava": "^0.25.0"
"ava": "^1.3.1"
}
}
# Introduction
**Asset assistant** is a tool for coordinating non-js files across multiple
projects. The intended use for copying .css and media files from a project
in the *'node_modules'* directory into the projects public html directory.
**Asset assistant** is an npm tool for coordinating asset files across multiple
projects.

@@ -13,108 +12,25 @@ ## Versions

they make use of the **package.json** file and the **node_modules** directory.
All file selections use the [Glob](https://www.npmjs.com/package/glob) package.
## Programs
## assets
Copy all asset files from source directories and source packages to a specified
build directory.
## Installation
npm install -g asset-assistant
* The term *assets* refers to the assets parameter in package.json.
* The term *dependencies* refers to the dependencies parameter in package.json.
## Usage
* Run the assets intializeer with 'assets init'. Adds and 'assets' parameter to the package.json file.
* The following can now be found in the package.json 'assets' field.
* `src`: An array of paths from witch to copy this projects files. The directory tree will be preserved. Default is '/assets/**/*'.
* `root`: The directory to search for source paths. This directory tree will not be preserved. Default is 'src'.
* `dest`: The directory where files will be copied to. Default is 'public_html'.
This is where other projects assets will be copied to. defaults to 'public_html'.
* Remove 'assets' parameter from package.json with assets --clear. The scripts will remain unchanged. Note, this can be used to clear any parameter, defaults to assets.
0. Require: target project, default root project.
1. Retrieve assets parameter, if not found, terminate.
* If this is a top level project it will continue normally without attempting
to copy any local files. This is put in place so that dependencies with
assets can easily be installed without defining assets in the root.
2. Copy all files from *assets.src* into *assets.build*.
* assets.src is an array of strings which are interpreted
as globs.
* assets.build is a string which is the root destination of the copy. The
copy will preserve the directory structure.
3. For each project **p** in dependencies, perform task with target = p.
`assets add project`: add an assets dependency. The project must first be installed with 'npm -i' and have been initialized with 'assets init'.
`assets remove project`: remove a project from the assets dependency.
`assets clear`: remove the assets field from package.json.
## inline
Add `<script>` and `<link>` tags to an html file based upon directory
contents.
The asset command accepts the following flags:
# Quick Start
1. Install asset assistant into a project with `npm i asset-assistant`.
2. Run the assets intializeer with ' node_modules/.bin/assets --init'.
3. The follwing can now be found in the package.json 'assets' field.
1. The `src` parameter dictates the files to copy to destination. This refers
to local files and remote. Default is 'src/assets/**/*'.
2. The `local-src` parameter dictates the sources to copy only if this project
is the target.
3. The `dest` parameter dictates the target directory, defaults to `build/`.
This is where other projects assets will be copied to. defaults to 'public_html'.
4. The `flat` parameter when true copies files without the directory structure,
defaults to false.
5. The `up` parameter defines how many src directories to omit on copy.
Defaults to `1` which is the project name directory. This Typically is not
modified.
4. The 'assets' script is added to the 'scripts' field.
* -v : Verbose, print out packages looked at and files copied.
* -d : Debug, print out more information.
The asset command accepts the following flags
- -v : Verbose, print out packages looked at and files copied.
- -d : Debug, print out more information.
- --fileset=parameter : only copy the local files specified in this parameter (
in the assets parameter).
### example 1
In the package.json file (unrequired fields omitted).
```json
"dependencies": {
"Collection": "file:../Collection",
"Context": "file:../Context",
"asset-assistant": "file:D:/project-local/assets",
"jquery": "^3.3.1",
"nidget": "file:../Nidget"
},
"scripts": {
"build-assets": "assets",
"build-remote": "assets --fileset=local-src",
"inject-header": "inject src/* src/css/* index.html"
},
"assets": {
"src": [
"src/assets/**/*",
"src/css/dialog.css"
],
"local-src": [
"src/*.html"
]
}
```
The script 'build-assets' will recursively copy all files in the src/assets
directory into the build/src/assets directory. It will also copy 'dialog.css'
into the build/css directory. It will then look for the "assets" parameter
in the package.json of all dependencies (Collection, Context, etc), if found
it will copy files specified by their 'src' parameters and recursively look in
their dependencies for more assets. If not found then the recursive search will
not follow that branch.
The script 'build-remote' will copy all html files from src/html to build/html,
and will not recursive search.
The script 'inject-header' will add a `<script>` or `<link>` element into
'index.html' for each .js and .css file found. The paths will be relative to
the location of 'index.html'.
# Development
Development is setup as a NetBeans project. These are reminders to how the
project is setup and is not needed to run it.
1. Clone repository: `git clone git@git.sharcnet.ca:edward/asset-assistant.git`.
2. Install dependencies with `npm install` in the project root directory.
3. Publish with `npm publish`.
## Files
The package.json `bin` parameter specifies where to find command line tools.
* **src/assets.js** main entry for asset command line tool as setup in the
package.json *bin* paramater.
* **src/inject.js** main entry for css injection command line tool as setup in the
package.json *bin* paramater.
* **src/AbstractAssets** Collectes common flags for the CleanAssets and
LoadAssets classes.
See https://github.com/Thaerious/asset-assistant

@@ -6,2 +6,7 @@ #!/usr/bin/env node

const InitAssets = require('./InitAssets');
const RemoveParameter = require('./RemoveParameter');
const AddDependency = require('./AddDependency');
const PackageListBuilder = require("./PackageListBuilder");
const fs = require("fs");
const argv = {

@@ -11,19 +16,20 @@ s : false, // silent

d : false, // debug
t : false, // do not recurse over modules
p : "package.json",
init : false, // perform auto setup
field : "assets"
f : "assets",
command : []
};
if (process.argv.length === 2){
console.log("usage: assets [-s] [-v] [-d] [-t] [-p=package_file] [--init] [field_name]");
console.log("--init: setup package.json file with default asset settings");
console.log("-t: terminal, set to true to not recurse over modules");
console.log("-s: silent, do not print out to console");
console.log("-v: verbose, print out more information");
console.log("-d: debug, print out even more information");
console.log("-p: package file, defaults to 'package.json'");
console.log("field_name: field in package.json to get targets, defaults to 'assets'");
}
const version = "v0.0.20 (alpha)";
let loadAssets = function(path, field) {
if (!fs.existsSync(path)) {
let err = "file not found: " + path;
throw new Error(err);
}
let packageFile = fs.readFileSync(path, 'utf8');
return JSON.parse(packageFile)[field];
};
/* extract command line parameters */
for (let i = 2; i < process.argv.length; i++){

@@ -43,7 +49,23 @@ let arg = process.argv[i];

} else {
argv.field = arg;
argv.command.push(arg);
}
}
if (!argv.s) console.log(`Asset Assistant : v0.0.18`);
if (argv.length === 1 || argv.command[0] === 'help'){
console.log(`Asset Assistant : ${version}`);
console.log("usage: assets [-s] [-v] [-d] [run, init, clear, add, remove]\n");
console.log("init: setup package.json file with default asset settings");
console.log("help: print usage information");
console.log("clear: remove assets parameter.");
console.log("add: add a project dependency.");
console.log("remove: remove a project dependency.");
console.log("-s: silent, do not print out to console");
console.log("-v: verbose, print out more information");
console.log("-d: debug, print out even more information");
console.log("\nFor more information, see: https://github.com/Thaerious/asset-assistant");
return;
}
if (!argv.s) console.log(`Asset Assistant : ${version}`);
if (argv.d) console.log(argv);

@@ -55,14 +77,27 @@

if (argv.init){
let initAssets = new InitAssets(argv.p);
if (argv.command[0] === 'init'){
let initAssets = new InitAssets(argv.p, argv.f);
initAssets.run();
initAssets.write();
}
else {
let task = new CopyAssets();
if (argv.dry) task.setDry();
task.setFieldName(argv.field);
if (argv.t) task.setTerminal();
task.run(argv.p, argv.field);
else if (argv.command[0] === 'clear'){
let removeParameter = new RemoveParameter(argv.p, argv.f);
removeParameter.run();
removeParameter.write();
}
else if (argv.command[0] === 'run'){
let assets = loadAssets(argv.p, argv.f);
let list = [];
new PackageListBuilder("./", list, "./").run();
new CopyAssets(list, assets.dest).run();
}
else if (argv.command[0] === 'add'){
new AddDependency(argv.p, argv.f)
.add(argv.command[1])
.write();
}
else if (argv.command[0] === 'remove'){
new AddDependency(argv.p, argv.f)
.remove(argv.command[1])
.write();
}

@@ -7,6 +7,6 @@ const mkdirp = require("mkdirp");

function catPath(... paths){
function catPath(... paths) {
let rPath = "";
for (let path of paths){
for (let path of paths) {
rPath += path + "/";

@@ -22,3 +22,3 @@ }

*/
class CopyObject extends HasLog{
class CopyObject extends HasLog {
/**

@@ -30,6 +30,6 @@ * @param {type} file the filename

*/
constructor(file = "", src = "", dest = ""){
constructor(file = "", src = "", dest = "") {
super();
this.file = file;
this.src = src;
this.src = src;
this.dest = dest;

@@ -42,3 +42,3 @@ }

*/
doCopy(){
doCopy() {
let src = this.src + this.file;

@@ -52,3 +52,3 @@ let dest = this.dest + this.file;

if (fs.statSync(src).isDirectory() === false){
if (fs.statSync(src).isDirectory() === false) {
this.log(`| > ${dest}`);

@@ -58,45 +58,30 @@ fs.copyFileSync(src, dest);

}
doClean(){
if (!fs.existsSync(dest)){
doClean() {
if (!fs.existsSync(dest)) {
this.debugLog(`| c file not found: ${dest}`);
return;
}
if (fs.statSync(dest).isDirectory()){
if (fs.statSync(dest).isDirectory()) {
this.debugLog(`| c skipping directory: ${dest}`);
return;
}
let dest = this.dest + this.file;
fs.unlinkSync(dest);
this.log(`| < ${dest}`);
this.log(`| < ${dest}`);
}
}
class CopyAssets extends AssetFlags{
constructor() {
class CopyAssets extends AssetFlags {
constructor(descriptorList, dest) {
super();
this.traversedList = [];
this.descriptorList = descriptorList;
this.dest = dest;
this.copyList = [];
this.settingsFieldName = "assets";
this.terminal = false;
this.rootPkg = null;
this.rootAssets = null;
}
/**
* The the package.json field name that will have the settings.
* @param {string} settingsFieldName
* @returns {undefined}
*/
setFieldName(settingsFieldName){
this.settingsFieldName = settingsFieldName;
}
setTerminal(){
this.terminal = true;
}
loadPackage(path) {
loadAssets(path) {
if (!fs.existsSync(path)) {

@@ -106,83 +91,44 @@ let err = "file not found: " + path;

}
let packageFile = fs.readFileSync(path, 'utf8');
let pkg = JSON.parse(packageFile);
return pkg;
}
pathDepth(path){
let pathArray = path.match(/\/+/g);
if (pathArray === null) return 0;
return pathArray.length;
let packageFile = fs.readFileSync(catPath(path, "package.json"), 'utf8');
return JSON.parse(packageFile).assets;
}
run(packagePath, packageField, parentPath="./",){
this.debugLog(`CopyAssets.run(${packagePath}, ${packageField}, ${parentPath})`);
this.packageField = packageField;
this.rootPkg = this.loadPackage(packagePath);
if (this.rootPkg[packageField] === undefined){
this.warnLog("Package field '" + packageField + "' not found.");
return;
}
this.rootAssets = this.rootPkg[packageField];
this.build(packagePath, parentPath);
run() {
this.build();
this.debugLog(`+- File List ---------------------------------+`);
this.copyList.forEach(ele=>this.debugLog(`| {file: "${ele.file}", src: "${ele.src}", dest: "${ele.dest}"}`));
this.copyList.forEach(ele => this.debugLog(`| {file: "${ele.file}", src: "${ele.src}", dest: "${ele.dest}"}`));
this.log(`+- Copying Files -------------------------------------+`);
this.copyList.forEach(ele=>ele.doCopy());
this.copyList.forEach(ele => ele.doCopy());
}
/**
* Create the copy-object list.
* @param {type} packagePath
* @param {type} rootPath the root for souce files, changes if following a file:// link.
* @param {type} parentPath the root path the the parent used.
* @returns {undefined}
*/
build(packagePath, parentPath) {
let pkg = this.loadPackage(packagePath);
let assets = pkg[this.packageField];
if (typeof assets !== "object"){
this.verboseLog("| Asset field not found, skipping package: " + pkg.name);
return;
build() {
for (let desc of this.descriptorList) {
this.debugLog(`+--- build ${desc.name} -----------------------------------------+`);
this.debugLog(`| ${desc.name}, ${desc.pkgPath}, ${desc.rootPath}`);
let assets = this.loadAssets(desc.pkgPath);
if (assets === undefined) {
this.debugLog(`| * no assets field in ${desc.name}`);
continue;
}
let source = assets[CopyAssets.SRC];
if (source === undefined) {
this.debugLog(`| * no asset source field: ${CopyAssets.SRC} in ${desc.name}`);
continue;
}
let rootPath = catPath(desc.pkgPath, assets.root);
for (let src of assets.src) {
let fullpath = catPath(rootPath, src);
let pathArray = this.globToPathArray(fullpath, rootPath, this.dest);
pathArray.forEach(ele => this.copyList.push(ele));
pathArray.forEach(ele => this.debugLog(`| ${ele.src}${ele.file}`));
}
}
let rootPath = catPath(parentPath, assets.root);
this.traversedList.push(pkg.name);
this.verboseLog(`+-----------------------------------------------------+`);
this.verboseLog(`| Traversing package '${pkg.name}' on field '${this.settingsFieldName}'`);
this.debugLog(`| package path : ${packagePath}`);
this.debugLog(`| root path : ${rootPath}`);
this.debugLog(`| parent path : ${parentPath}`);
if (assets === undefined){
this.debugLog(`| * no assets parameter`);
return;
}
let source = assets[CopyAssets.SRC ];
if (source === undefined){
this.debugLog(`| * no source field: ${CopyAssets.SRC }`);
return;
}
let dest = this.rootAssets[CopyAssets.DEST];
if (dest === undefined){
throw new Error(`destination undefined in file ${packagePath}`);
}
if (source instanceof Array === false) throw new Error(`expected array value for parameter assets.${this.settingsFieldName}`);
for (let i in source) this.processSourceArrayElement(source[i], rootPath, parentPath, dest);
if (!this.terminal) this.recurse(packagePath, parentPath);
}
/**

@@ -197,10 +143,10 @@ * Replace all template literals in string, with values from the root

*/
templateLiteral(string){
templateLiteral(string) {
let foundLiterals = string.match(/[$][{][a-zA-Z0-0]+[}]/g);
if (foundLiterals === null) return string;
for (let literal of foundLiterals){
for (let literal of foundLiterals) {
let name = literal.substr(2, literal.length - 3);
if (typeof this.rootAssets[name] !== "string") throw new Error(`Attempted literal replacement on unknown key: ${name}`);
let value = this.rootAssets[name];
if (typeof this.assets[name] !== "string") throw new Error(`Attempted literal replacement on unknown key: ${name}`);
let value = this.assets[name];
string = string.split(literal).join(value);

@@ -210,38 +156,2 @@ }

}
processSourceArrayElement(element, rootPath, parentPath, dest){
let sourceGlob = "";
let flat = false;
if (typeof element === "string"){
this.debugLog(`| - source: element string`);
sourceGlob = catPath(rootPath, element);
}
let copyArray = this.globToPathArray(sourceGlob, rootPath, dest, flat);
copyArray.forEach(ele=>this.copyList.push(ele));
}
recurse(packagePath, parentPath){
let pkg = this.loadPackage(packagePath);
let dependencies = pkg[CopyAssets.DEPENDENCIES];
for (let dependencyName in dependencies){
let dependencyValue = dependencies[dependencyName];
if (this.traversedList.includes(dependencyName)){
this.verboseLog(`| * Skipping duplicate package: ${dependencyName}`);
}
else if (dependencyValue.startsWith("file") === false){
this.debugLog(`| * Including unique package file: ${dependencyName}`);
let truePath = catPath(parentPath, "node_modules", dependencyName);
let pkgPath = catPath(truePath, "package.json");
this.build(pkgPath, truePath);
} else {
this.debugLog(`| * Including unique package module: ${dependencyName}`);
let truePath = catPath(parentPath, "node_modules", dependencyName);
let pkgPath = catPath(truePath, "package.json");
this.build(pkgPath, truePath);
}
}
}

@@ -261,6 +171,3 @@ /**

globToPathArray(globpath, rootPath, dest) {
this.debugLog(`| - seeking globpaths in: ${globpath}`);
if (globpath.charAt(0) === "/"){
this.warnLog(`absolute path found in source: ${globpath}`);
}
this.debugLog(`| seeking globpaths in: ${globpath}`);

@@ -275,3 +182,2 @@ let filenames = glob.sync(globpath);

this.debugLog(`| - processing ${filename}`);
/* remove the filename from the path */

@@ -281,3 +187,3 @@ let pathArray = filename.split("/");

let src = pathArray.join("/") + "/";
let copyObj = new CopyObject(file, src);

@@ -291,151 +197,2 @@ copyObj.dest = dest + src.substring(rootPath.length);

}
/**
* Copy all files declared in 'field' to the destination directory.
* Called with both 'src' and 'local-src'.
* @param {type} field, parameter in package.json.assets that contains an array of
* strings representing glob paths. ie 'src', 'local-src'
* @param {type} traversedList list of previously traversed packages
* @returns {undefined}
*/
assets(field, traversedList) {
if (traversedList.includes(this.package.name)) {
this.verboseLog(`Package ${this.package.name} previously traversed`);
throw new Error("ERR");
return;
}
traversedList.push(this.package.name);
this.verboseLog(`+-----------------------------------------------------+`);
this.verboseLog(`| Traversing package '${this.package.name}' on field '${field}'`);
for (let i in this.options[field]) {
let src = this.options[field][i];
let srcArray = this.assetToArray(`${this.rootPath}/${src}`);
for (let idx in srcArray) {
let copyObj = srcArray[idx];
let src = copyObj.src + copyObj.file;
let dest = copyObj.dest + copyObj.file;
if (!this.isDry() && !fs.existsSync(copyObj.dest)) {
this.verboseLog(`| - creating directory ${copyObj.dest}`);
mkdirp.sync(copyObj.dest);
}
if (fs.statSync(src).isDirectory())
continue;
this.verboseLog(`| -> ${dest}`);
if (!this.isDry())
fs.copyFileSync(src, dest);
}
}
this.verboseLog(`+-----------------------------------------------------+`);
}
traverseDependencies(field, traversedList, dependencies) {
for (let pkg in dependencies) {
this.verboseLog(`| recurse ${pkg}`);
let pkgTarget = dependencies[pkg];
if (pkgTarget.startsWith("file:")) {
} else {
this.loadModule(field, traversedList, pkg);
}
}
}
loadModule(field, traversedList, module) {
this.verboseLog(`+-----------------------------------------------------+`);
this.debugLog(`| loadModule(${field}, [...], ${module})`);
let pkgpath = this.modulePath + "/" + module + "/package.json";
let pkg = this.loadPackage(pkgpath);
if (traversedList.includes(pkg.name)) {
this.verboseLog(`Package ${pkg.name} previously traversed`);
throw new Error("ERR");
return;
}
traversedList.push(pkg.name);
let options = pkg.assets;
for (let i in options[field]) {
let srcpath = this.modulePath + "/" + module + "/" + options[field][i];
this.verboseLog(`| globbing ${srcpath}`);
let srcArray = this.assetToArray(srcpath);
for (let idx in srcArray) {
this.verboseLog(`| processing ${srcpath}`);
let copyObj = srcArray[idx];
let src = copyObj.src + copyObj.file;
let dest = copyObj.dest + copyObj.file;
if (!this.isDry() && !fs.existsSync(copyObj.dest)) {
this.verboseLog(`| - creating directory ${copyObj.dest}`);
mkdirp.sync(copyObj.dest);
}
if (fs.statSync(src).isDirectory())
continue;
this.verboseLog(`| -> ${dest}`);
if (!this.isDry())
fs.copyFileSync(src, dest);
}
}
if (pkg.dependencies !== undefined) {
this.verboseLog(`| recursing on ${pkg.name}`);
this.traverseDependencies(field, traversedList, pkg.dependencies);
}
}
/**
* Copy files from dependencies.
* With the options provided by this object, create a new LoadAssets object
* for each dependency and if build() is true, run assets and dependencies
* on it. This is the function to recurse over dependencies.
* @param {type} field
* @param {type} traversedList list of previously traversed packages
* @returns {undefined}
*/
dependencies(field, traversedList) {
this.debugLog(`Running task 'dependencies' with field = ${field}`);
if (this.package.dependencies === undefined) return;
for (let pkg in this.package.dependencies) {
this.debugLog(`dependency ${pkg}`);
let pkgTarget = this.package.dependencies[pkg];
let loadAssets = null;
if (pkgTarget.startsWith("file:")) {
let path = `${this.modulePath}/${pkg}`;
let dDepth = path.match(/\/+/g).length + 1;
this.debugLog(`file source: Looking in ${path}`);
loadAssets = new LoadAssets()
.up(dDepth)
.root(`${this.modulePath}/${pkg}`)
.modules(`${this.modulePath}/${pkg}/node_modules`)
.package(`${this.modulePath}/${pkg}/package.json`);
if (this.isVerbose())
loadAssets.setVerbose();
if (this.isDebug())
loadAssets.setDebug();
if (this.isDry())
loadAssets.setDry();
if (loadAssets.build() === true) {
loadAssets.setDest(this.getDest());
loadAssets.assets(field, traversedList);
loadAssets.dependencies(field, traversedList);
}
} else {
this.loadModule(field, traversedList, pkg);
}
}
}
}

@@ -442,0 +199,0 @@

const fs = require("fs");
const HasLog = require("./HasLog");
class InitAssets {
constructor(filename) {
class InitAssets extends HasLog{
constructor(filename = 'package.json', parameter = 'assets') {
super();
this.filename = filename;
if (!fs.existsSync(filename)) {
let err = `file not found ${filename}`;
throw new Error(err);
fs.writeFileSync(filename, "{}\n");
}
this.package = JSON.parse(fs.readFileSync(filename, 'utf8'));
this.parameter = parameter;
}

@@ -17,24 +19,17 @@

this.__addAssets(root, destination);
this.__addScripts(destination);
}
}
__addScripts(){
let scripts = {};
if (this.package.scripts === undefined){
this.package.scripts = scripts;
} else {
scripts = this.package.scripts;
}
if (scripts[`assets`] === undefined) scripts[`assets`] = `assets -v`;
}
__addAssets(root, destination){
if (this.package.assets !== undefined) return;
if (this.package[this.parameter] !== undefined){
this.warnLog("'${this.parameter}' parameter already exists, no change made.");
return;
}
this.assets = {
let assets = {
src: [
`/assets/**/*`
],
dependencies:[
],
root: `${root}`,

@@ -44,3 +39,3 @@ dest: destination

this.package.assets = this.assets;
this.package[this.parameter] = assets;
}

@@ -47,0 +42,0 @@

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