@abtnode/util
Advanced tools
Comparing version 0.9.4 to 0.9.7
const pkg = require('../package.json'); | ||
const readBlockletConfig = require('./read_blocklet_config'); | ||
const normalizePathPrefix = require('./normalize_path_prefix'); | ||
const isDocker = require('./is_docker'); | ||
const checkDomainMatch = require('./check_domain_match'); | ||
module.exports = { | ||
isDocker, | ||
isValidPort: (port) => Number.isSafeInteger(port) && port >= 0 && port <= 65535, | ||
@@ -11,2 +14,3 @@ normalizePathPrefix, | ||
version: pkg.version, | ||
checkDomainMatch, | ||
}; |
@@ -5,12 +5,108 @@ const fs = require('fs'); | ||
const camelCase = require('lodash/camelCase'); | ||
const padStart = require('lodash/padStart'); | ||
const debug = require('debug')('@abtnode/util:readBlockletConfig'); | ||
const defaultAttrSpec = { | ||
name: true, | ||
description: true, | ||
group: true, | ||
provider: true, | ||
version: true, | ||
main: true, | ||
repoName: false, | ||
title: false, | ||
public_url: false, | ||
admin_url: false, | ||
config_url: false, | ||
doc_url: false, | ||
htmlAst: false, | ||
gitUrl: false, | ||
logoUrl: false, | ||
logo: false, | ||
author: false, | ||
charging: false, | ||
color: false, | ||
community: false, | ||
dir: false, | ||
documentation: false, | ||
homepage: false, | ||
keywords: false, | ||
licence: false, | ||
npm: false, | ||
screenshots: false, | ||
repository: false, | ||
usages: false, | ||
support: false, | ||
tags: false, | ||
hooks: false, | ||
requiredEnvironments: false, | ||
capabilities: false, | ||
}; | ||
const getTimeAsVersion = () => { | ||
const date = new Date(); | ||
const major = date.getFullYear(); | ||
const minor = `${padStart(date.getMonth() + 1, 2, '0')}${padStart(date.getDate(), 2, '0')}`; | ||
const patch = `${padStart(date.getHours(), 2, '0')}${padStart(date.getMinutes(), 2, '0')}`; | ||
return [major, minor, patch].map(Number).join('.'); | ||
}; | ||
// Assign sensible defaults: name/description/main/group/provider/version | ||
const ensureRequiredAttrs = (attrs, dir) => { | ||
if (!attrs.name) { | ||
attrs.name = path.basename(dir); | ||
} | ||
if (!attrs.description) { | ||
attrs.description = `Blocklet from ${dir}`; | ||
} | ||
if (!attrs.version) { | ||
attrs.version = getTimeAsVersion(); | ||
} | ||
if (!attrs.provider) { | ||
attrs.provider = 'community'; | ||
} | ||
if (!attrs.main && !attrs.group) { | ||
debug('guess main and group', dir); | ||
attrs.group = 'static'; | ||
attrs.main = '.'; | ||
const items = ['.'].concat(fs.readdirSync(dir)); | ||
const item = items.find( | ||
(x) => fs.existsSync(path.resolve(dir, x, 'index.html')) || fs.existsSync(path.resolve(dir, x, 'index.htm')) | ||
); | ||
if (item) { | ||
attrs.main = item; | ||
} | ||
} | ||
if (!attrs.group) { | ||
const main = path.join(dir, attrs.main); | ||
try { | ||
const stat = fs.statSync(main); | ||
if (stat.isDirectory()) { | ||
attrs.group = 'static'; | ||
} else { | ||
attrs.group = 'dapp'; | ||
} | ||
} catch (err) { | ||
attrs.group = 'static'; | ||
} | ||
} | ||
return attrs; | ||
}; | ||
/** | ||
* Get blocklet config from blocklet's package.json and blocklet.json, the attribute in blocklet.json will overwrite the attribute with the same name in package.json | ||
* @param {string} blockletDir blocklet directory | ||
* @param {string} dir blocklet directory | ||
* @param {object} option | ||
* @param {object} option.attributes custom whether attributes are required, this will overwrite the default definition | ||
* @param {object} option.extraAttrSpec custom whether attributes are required, this will overwrite the default definition | ||
* @param {object} option.extraRawAttrs extra attributes, will be merged to package.json and blocklet.json, if the same attribute exists in package.json or blocklet.json, it will be overwritten | ||
*/ | ||
const readBlockletConfig = (blockletDir, { attributes = {}, extraRawAttrs = {} }) => { | ||
const readBlockletConfig = (dir, { enableDefaults = true, extraAttrSpec = {}, extraRawAttrs = {} } = {}) => { | ||
const rawAttrs = {}; | ||
@@ -21,3 +117,3 @@ if (extraRawAttrs) { | ||
const packageConfig = path.join(blockletDir, 'package.json'); | ||
const packageConfig = path.join(dir, 'package.json'); | ||
if (fs.existsSync(packageConfig)) { | ||
@@ -28,3 +124,3 @@ const packageJson = JSON.parse(fs.readFileSync(packageConfig).toString()); | ||
const blockletConfig = path.join(blockletDir, 'blocklet.json'); | ||
const blockletConfig = path.join(dir, 'blocklet.json'); | ||
if (fs.existsSync(blockletConfig)) { | ||
@@ -34,51 +130,21 @@ Object.assign(rawAttrs, JSON.parse(fs.readFileSync(blockletConfig).toString())); | ||
debug('variables', { blockletDir, blockletConfig, packageConfig, rawAttrs }); | ||
// debug('variables', { dir, blockletConfig, packageConfig, rawAttrs }); | ||
const attrSpec = Object.assign(defaultAttrSpec, extraAttrSpec); | ||
let result = pick(rawAttrs, Object.keys(attrSpec)); | ||
if (enableDefaults) { | ||
result = ensureRequiredAttrs(result, dir); | ||
} | ||
const attrs = Object.assign( | ||
{ | ||
name: true, | ||
description: true, | ||
group: true, | ||
provider: true, | ||
version: true, | ||
repoName: false, | ||
main: false, | ||
title: false, | ||
// Ensure main if it's a required field | ||
if (attrSpec.main) { | ||
if (!result.main || !fs.existsSync(path.join(dir, result.main))) { | ||
throw new Error('`main` field is not properly configured for blocklet'); | ||
} | ||
} | ||
public_url: false, | ||
admin_url: false, | ||
config_url: false, | ||
doc_url: false, | ||
htmlAst: false, | ||
gitUrl: false, | ||
logoUrl: false, | ||
logo: false, | ||
author: false, | ||
charging: false, | ||
color: false, | ||
community: false, | ||
dir: false, | ||
documentation: false, | ||
homepage: false, | ||
keywords: false, | ||
licence: false, | ||
npm: false, | ||
screenshots: false, | ||
repository: false, | ||
usages: false, | ||
support: false, | ||
tags: false, | ||
hooks: false, | ||
requiredEnvironments: false, | ||
}, | ||
attributes | ||
); | ||
const selectedAttrs = pick(rawAttrs, Object.keys(attrs)); | ||
const requiredAttrs = Object.keys(attrs).filter((a) => attrs[a]); | ||
const requiredAttrs = Object.keys(attrSpec).filter((a) => attrSpec[a]); | ||
const notExistsFields = []; | ||
// eslint-disable-next-line no-restricted-syntax | ||
for (const key of requiredAttrs) { | ||
if (!selectedAttrs[key]) { | ||
if (!result[key]) { | ||
notExistsFields.push(key); | ||
@@ -88,27 +154,30 @@ } | ||
if (notExistsFields.length > 0) { | ||
throw new Error(`Blocklet not properly configured, missing required fields: ${notExistsFields.join(',')}`); | ||
throw new Error(`Missing required blocklet fields: ${notExistsFields.join(',')}`); | ||
} | ||
// Ensure main | ||
if (!selectedAttrs.main || !fs.existsSync(path.join(blockletDir, selectedAttrs.main))) { | ||
throw new Error('`main` field is not properly configured for blocklet'); | ||
} | ||
result.path = `/${result.group}/${result.name}`; | ||
result.folder = dir; | ||
selectedAttrs.path = `/${selectedAttrs.group}/${selectedAttrs.name}`; | ||
// Assign a color | ||
const colors = ['primary', 'secondary', 'error']; | ||
if (!selectedAttrs.color || !colors.includes(selectedAttrs.color)) { | ||
[selectedAttrs.color] = colors; | ||
if (!result.color || !colors.includes(result.color)) { | ||
[result.color] = colors; | ||
} | ||
// Default capabilities: a blocklet should support dynamic path prefix | ||
if (!result.capabilities) { | ||
result.capabilities = { dynamicPathPrefix: true }; | ||
} | ||
if (typeof result.capabilities.dynamicPathPrefix === 'undefined') { | ||
result.capabilities.dynamicPathPrefix = true; | ||
} | ||
result.capabilities.dynamicPathPrefix = !!result.capabilities.dynamicPathPrefix; | ||
// Set charging to free if not specified | ||
if (!selectedAttrs.charging) { | ||
selectedAttrs.charging = { price: 0 }; | ||
if (!result.charging) { | ||
result.charging = { price: 0 }; | ||
} | ||
selectedAttrs.folder = blockletDir; | ||
return Object.keys(selectedAttrs).reduce((acc, k) => { | ||
acc[camelCase(k)] = selectedAttrs[k]; | ||
return Object.keys(result).reduce((acc, k) => { | ||
acc[camelCase(k)] = result[k]; | ||
return acc; | ||
@@ -119,1 +188,2 @@ }, {}); | ||
module.exports = readBlockletConfig; | ||
module.exports.getTimeAsVersion = getTimeAsVersion; |
@@ -6,3 +6,3 @@ { | ||
}, | ||
"version": "0.9.4", | ||
"version": "0.9.7", | ||
"description": "ArcBlock's JavaScript utility", | ||
@@ -25,2 +25,3 @@ "main": "lib/index.js", | ||
"debug": "^4.1.1", | ||
"is-docker": "^2.1.1", | ||
"lodash": "^4.17.15", | ||
@@ -31,5 +32,6 @@ "nedb": "^1.8.0" | ||
"eslint": "7.5.0", | ||
"jest": "^25.2.7" | ||
"jest": "^25.2.7", | ||
"rimraf": "^3.0.2" | ||
}, | ||
"gitHead": "65f9d0b5af0c49d203877bfbee21baa279a1b7cd" | ||
"gitHead": "d33ac1b2674fa22510c6db2f2558c69a67092203" | ||
} |
@@ -11,8 +11,11 @@ # ArcBlock's JavaScript utility | ||
``` js | ||
require('@arcblock/js-util/lib/error-handler'); | ||
```js | ||
require('@abtnode/util/lib/error-handler'); | ||
``` | ||
## TODO | ||
### Read blocklet meta | ||
- [ ] Language translations | ||
```js | ||
const getBlockletMeta = require('@abtnode/util/lib/read_blocklet_config') | ||
const meta = getBlockletMeta(blockletDir); | ||
``` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
8506
8
217
21
4
3
3
+ Addedis-docker@^2.1.1
+ Addedis-docker@2.2.1(transitive)