ci: setup

This commit is contained in:
Derrick Hammer 2023-07-04 02:14:19 -04:00
parent 62856686f2
commit 3f1b1dca42
Signed by: pcfreak30
GPG Key ID: C997C339BE476FF2
10 changed files with 31 additions and 704 deletions

View File

@ -1,152 +0,0 @@
{
"env": {
"es6": true,
"node": true
},
"extends": "eslint:recommended",
"globals": {
"Atomics": "readable",
"BigInt": "readable",
"BigInt64Array": "readable",
"BigUint64Array": "readable",
"queueMicrotask": "readable",
"SharedArrayBuffer": "readable",
"TextEncoder": "readable",
"TextDecoder": "readable"
},
"overrides": [
{
"files": ["*.mjs"],
"parserOptions": {
"sourceType": "module"
}
},
{
"files": ["*.cjs"],
"parserOptions": {
"sourceType": "script"
}
},
{
"files": [
"test/{,**/}*.{mjs,cjs,js}"
],
"env": {
"mocha": true
},
"globals": {
"register": "readable"
},
"rules": {
"max-len": "off",
"prefer-arrow-callback": "off"
}
}
],
"parser": "babel-eslint",
"parserOptions": {
"ecmaVersion": 10,
"ecmaFeatures": {
"globalReturn": true
},
"requireConfigFile": false,
"sourceType": "script"
},
"root": true,
"rules": {
"array-bracket-spacing": ["error", "never"],
"arrow-parens": ["error", "as-needed", {
"requireForBlockBody": true
}],
"arrow-spacing": "error",
"block-spacing": ["error", "always"],
"brace-style": ["error", "1tbs"],
"camelcase": ["error", {
"properties": "never"
}],
"comma-dangle": ["error", "never"],
"consistent-return": "error",
"eol-last": ["error", "always"],
"eqeqeq": ["error", "always", {
"null": "ignore"
}],
"func-name-matching": "error",
"indent": ["off", 2, {
"ArrayExpression": "off",
"SwitchCase": 1,
"CallExpression": {
"arguments": "off"
},
"FunctionDeclaration": {
"parameters": "off"
},
"FunctionExpression": {
"parameters": "off"
},
"MemberExpression": "off",
"ObjectExpression": "off",
"ImportDeclaration": "off"
}],
"handle-callback-err": "off",
"linebreak-style": ["error", "unix"],
"max-len": ["error", {
"code": 80,
"ignorePattern": "function \\w+\\(",
"ignoreUrls": true
}],
"max-statements-per-line": ["error", {
"max": 1
}],
"new-cap": ["error", {
"newIsCap": true,
"capIsNew": false
}],
"new-parens": "error",
"no-buffer-constructor": "error",
"no-console": "off",
"no-extra-semi": "off",
"no-fallthrough": "off",
"no-func-assign": "off",
"no-implicit-coercion": "error",
"no-multi-assign": "error",
"no-multiple-empty-lines": ["error", {
"max": 1
}],
"no-nested-ternary": "error",
"no-param-reassign": "off",
"no-return-assign": "error",
"no-return-await": "off",
"no-shadow-restricted-names": "error",
"no-tabs": "error",
"no-trailing-spaces": "error",
"no-unused-vars": ["error", {
"vars": "all",
"args": "none",
"ignoreRestSiblings": false
}],
"no-use-before-define": ["error", {
"functions": false,
"classes": false
}],
"no-useless-escape": "off",
"no-var": "error",
"nonblock-statement-body-position": ["error", "below"],
"padded-blocks": ["error", "never"],
"prefer-arrow-callback": "error",
"prefer-const": ["error", {
"destructuring": "all",
"ignoreReadBeforeAssign": true
}],
"prefer-template": "off",
"quotes": ["error", "single"],
"semi": ["error", "always"],
"spaced-comment": ["error", "always", {
"exceptions": ["!"]
}],
"space-before-blocks": "error",
"strict": "error",
"unicode-bom": ["error", "never"],
"valid-jsdoc": "error",
"wrap-iife": ["error", "inside"]
}
}

13
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,13 @@
name: Build/Publish
on:
push:
branches:
- master
- develop
- develop-*
jobs:
main:
uses: lumeweb/github-node-deploy-workflow/.github/workflows/main.yml@master
secrets: inherit

3
.gitignore vendored
View File

@ -1,3 +0,0 @@
build/
node_modules/
npm-debug.log

View File

@ -1,17 +0,0 @@
.babel*
.bmocharc*
.bpkgignore
.editorconfig
.eslint*
.git*
.mocharc*
.yarnignore
bench/
build/
docs/
node_modules/
npm-debug.log
package-lock.json
test/
webpack.*.js
yarn.lock

5
.presetterrc.json Normal file
View File

@ -0,0 +1,5 @@
{
"preset": [
"@lumeweb/node-library-preset"
]
}

42
dist/index.d.ts vendored
View File

@ -1,42 +0,0 @@
/*!
* config.js - configuration parsing for bcoin
* Copyright (c) 2016-2017, Christopher Jeffrey (MIT License).
* https://github.com/bcoin-org/bcoin
*/
/// <reference types="node" />
import arg from "arg";
/**
* Config Parser
*/
export default class Config {
private module;
private data;
private configProperty;
constructor(module: string, configProperty: string);
inject(options: object): void;
load(): void;
openDir(dir: string): void;
open(file: string): void;
save(file: string, data: object): void;
savePath(file: string, path: string): void;
set(key: string, value: any): void;
has(key: string): any;
private normalize;
get(key: string, fallback?: any): any;
typeOf(key: string): "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | "null";
str(key: string, fallback?: any): any;
int(key: any, fallback?: any): any;
uint(key: any, fallback?: any): any;
float(key: any, fallback?: any): any;
ufloat(key: any, fallback?: any): any;
fixed(key: any, exp: any, fallback?: any): any;
ufixed(key: any, exp: any, fallback?: any): any;
bool(key: any, fallback?: any): any;
buf(key: string, fallback?: any, enc?: BufferEncoding): any;
array(key: string, fallback?: any): any;
obj(key: string, fallback?: any): any;
func(key: string, fallback?: any): any;
mb(key: string, fallback?: any): any;
parseArg(args: arg.Result<any>): void;
parseEnv(env?: object): void;
}

424
dist/index.js vendored
View File

@ -1,424 +0,0 @@
/*!
* config.js - configuration parsing for bcoin
* Copyright (c) 2016-2017, Christopher Jeffrey (MIT License).
* https://github.com/bcoin-org/bcoin
*/
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const bsert_1 = __importDefault(require("bsert"));
const path_1 = __importDefault(require("path"));
const fs_1 = __importDefault(require("fs"));
const arg_1 = __importDefault(require("arg"));
const object_path_1 = __importDefault(require("object-path"));
const deep_to_flat_object_1 = __importDefault(require("deep-to-flat-object"));
/**
* Config Parser
*/
class Config {
module;
data = {};
configProperty;
constructor(module, configProperty) {
(0, bsert_1.default)(typeof module === "string");
(0, bsert_1.default)(module.length > 0);
this.module = module;
this.configProperty = configProperty;
}
inject(options) {
for (const key of Object.keys(options)) {
const value = options[key];
switch (key) {
case "env":
case "argv":
case "config":
continue;
}
this.set(key, value);
}
}
load() {
const args = (0, arg_1.default)({}, { permissive: true });
this.parseArg(args);
}
openDir(dir) {
(0, bsert_1.default)(fs_1.default.existsSync(dir), `Directory ${dir} does not exist`);
let files = fs_1.default
.readdirSync(dir)
.filter((item) => item.endsWith(".json"))
.map((item) => path_1.default.join(dir, item));
files.forEach(this.open.bind(this));
}
open(file) {
let json;
try {
json = fs_1.default.readFileSync(file, "utf8");
json = JSON.parse(json);
}
catch (e) {
if (e.code === "ENOENT")
return;
throw new Error(`Error parsing file ${file}: ${e.message}`);
}
(0, bsert_1.default)(typeof json === "object", `Config file ${file} must be an object`);
const settings = (0, deep_to_flat_object_1.default)(json);
for (const key of Object.keys(settings)) {
const value = settings[key];
this.set(key, value);
}
}
save(file, data) {
(0, bsert_1.default)(typeof data === "object");
(0, bsert_1.default)(!Array.isArray(data));
const configDir = this.str(this.configProperty);
const fullPath = path_1.default.join(configDir, `${file}.json`);
if (!fs_1.default.existsSync(configDir)) {
fs_1.default.mkdirSync(configDir, { recursive: true });
}
fs_1.default.writeFileSync(fullPath, JSON.stringify(data));
this.open(fullPath);
}
savePath(file, path) {
this.save(file, this.get(path));
}
set(key, value) {
(0, bsert_1.default)(typeof key === "string", "Key must be a string.");
if (value == null) {
return;
}
key = this.normalize(key);
object_path_1.default.set(this.data, key, value);
}
has(key) {
(0, bsert_1.default)(typeof key === "string", "Key must be a string.");
key = key.replace(/-/g, "");
key = key.toLowerCase();
return object_path_1.default.has(this.data, key);
}
normalize(key, env = false) {
(0, bsert_1.default)(typeof key === "string", "Key must be a string.");
if (env) {
key = key.replace(/__/g, ".");
key = key.replace(/_/g, "");
}
else {
key = key.replace(/-/g, "");
}
key = key.toLowerCase();
return key;
}
get(key, fallback = null) {
if (Array.isArray(key)) {
const keys = key;
for (const key of keys) {
const value = this.get(key);
if (value !== null) {
return value;
}
}
return fallback;
}
(0, bsert_1.default)(typeof key === "string", "Key must be a string.");
key = this.normalize(key);
return object_path_1.default.get(this.data, key, fallback);
}
typeOf(key) {
const value = this.get(key);
if (value === null) {
return "null";
}
return typeof value;
}
str(key, fallback = null) {
const value = this.get(key);
if (value === null) {
return fallback;
}
if (typeof value !== "string") {
throw new Error(`${fmt(key)} must be a string.`);
}
return value;
}
int(key, fallback = null) {
const value = this.get(key);
if (value === null) {
return fallback;
}
if (typeof value !== "string") {
if (typeof value !== "number") {
throw new Error(`${fmt(key)} must be an int.`);
}
if (!Number.isSafeInteger(value)) {
throw new Error(`${fmt(key)} must be an int.`);
}
return value;
}
if (!/^\-?\d+$/.test(value)) {
throw new Error(`${fmt(key)} must be an int.`);
}
const num = parseInt(value, 10);
if (!Number.isSafeInteger(num)) {
throw new Error(`${fmt(key)} must be an int.`);
}
return num;
}
uint(key, fallback = null) {
const value = this.int(key);
if (value === null) {
return fallback;
}
if (value < 0) {
throw new Error(`${fmt(key)} must be a uint.`);
}
return value;
}
float(key, fallback = null) {
const value = this.get(key);
if (value === null) {
return fallback;
}
if (typeof value !== "string") {
if (typeof value !== "number") {
throw new Error(`${fmt(key)} must be a float.`);
}
if (!isFinite(value)) {
throw new Error(`${fmt(key)} must be a float.`);
}
return value;
}
if (!/^\-?\d*(?:\.\d*)?$/.test(value)) {
throw new Error(`${fmt(key)} must be a float.`);
}
if (!/\d/.test(value)) {
throw new Error(`${fmt(key)} must be a float.`);
}
const num = parseFloat(value);
if (!isFinite(num)) {
throw new Error(`${fmt(key)} must be a float.`);
}
return num;
}
ufloat(key, fallback = null) {
const value = this.float(key);
if (value === null) {
return fallback;
}
if (value < 0) {
throw new Error(`${fmt(key)} must be a positive float.`);
}
return value;
}
fixed(key, exp, fallback = null) {
const value = this.float(key);
if (value === null) {
return fallback;
}
try {
return fromFloat(value, exp || 0);
}
catch (e) {
throw new Error(`${fmt(key)} must be a fixed number.`);
}
}
ufixed(key, exp, fallback = null) {
const value = this.fixed(key, exp);
if (value === null) {
return fallback;
}
if (value < 0) {
throw new Error(`${fmt(key)} must be a positive fixed number.`);
}
return value;
}
bool(key, fallback = null) {
const value = this.get(key);
if (value === null) {
return fallback;
}
// Bitcoin Core compat.
if (typeof value === "number") {
if (value === 1) {
return true;
}
if (value === 0) {
return false;
}
}
if (typeof value !== "string") {
if (typeof value !== "boolean") {
throw new Error(`${fmt(key)} must be a boolean.`);
}
return value;
}
if (value === "true" || value === "1") {
return true;
}
if (value === "false" || value === "0") {
return false;
}
throw new Error(`${fmt(key)} must be a boolean.`);
}
buf(key, fallback = null, enc = "hex") {
const value = this.get(key);
if (value === null) {
return fallback;
}
if (typeof value !== "string") {
if (!Buffer.isBuffer(value)) {
throw new Error(`${fmt(key)} must be a buffer.`);
}
return value;
}
const data = Buffer.from(value, enc);
if (data.length !== Buffer.byteLength(value, enc)) {
throw new Error(`${fmt(key)} must be a ${enc} string.`);
}
return data;
}
array(key, fallback = null) {
const value = this.get(key);
if (value === null) {
return fallback;
}
if (typeof value !== "string") {
if (!Array.isArray(value)) {
throw new Error(`${fmt(key)} must be an array.`);
}
return value;
}
const parts = value.trim().split(/\s*,\s*/);
const result = [];
for (const part of parts) {
if (part.length === 0) {
continue;
}
result.push(part);
}
return result;
}
obj(key, fallback = null) {
const value = this.get(key);
if (value === null) {
return fallback;
}
if (typeof value !== "object" || Array.isArray(value)) {
throw new Error(`${fmt(key)} must be an object.`);
}
return value;
}
func(key, fallback = null) {
const value = this.get(key);
if (value === null) {
return fallback;
}
if (typeof value !== "function") {
throw new Error(`${fmt(key)} must be a function.`);
}
return value;
}
mb(key, fallback = null) {
const value = this.uint(key);
if (value === null) {
return fallback;
}
return value * 1024 * 1024;
}
parseArg(args) {
for (let key in args._) {
let newKey = key.replace("-", "");
object_path_1.default.set(this.data, newKey, args[key]);
}
}
parseEnv(env) {
let prefix = this.module;
prefix = prefix.toUpperCase();
prefix = prefix.replace(/-/g, "_");
prefix += "_";
if (!env || typeof env !== "object") {
env = process.env;
}
(0, bsert_1.default)(env && typeof env === "object");
for (let key of Object.keys(env)) {
const value = env[key];
(0, bsert_1.default)(typeof value === "string");
if (key.indexOf(prefix) !== 0) {
continue;
}
if (!isUpperKey(key)) {
continue;
}
key = key.substring(prefix.length);
key = this.normalize(key, true);
if (value.length === 0) {
continue;
}
object_path_1.default.set(this.data, key);
}
}
}
exports.default = Config;
/*
* Helpers
*/
function fmt(key) {
if (Array.isArray(key)) {
key = key[0];
}
if (typeof key === "number") {
return `Argument #${key}`;
}
return key;
}
function isAlpha(str) {
return /^[a-z0-9_\-]+$/i.test(str);
}
function isKey(key) {
return /^[a-zA-Z0-9]+$/.test(key);
}
function isUpperKey(key) {
if (!isKey(key)) {
return false;
}
return !/[a-z]/.test(key);
}
function fromFloat(num, exp) {
(0, bsert_1.default)(typeof num === "number" && isFinite(num));
(0, bsert_1.default)(Number.isSafeInteger(exp));
let str = num.toFixed(exp);
let sign = 1;
if (str.length > 0 && str[0] === "-") {
str = str.substring(1);
sign = -1;
}
let hi = str;
let lo = "0";
const index = str.indexOf(".");
if (index !== -1) {
hi = str.substring(0, index);
lo = str.substring(index + 1);
}
hi = hi.replace(/^0+/, "");
lo = lo.replace(/0+$/, "");
(0, bsert_1.default)(hi.length <= 16 - exp, "Fixed number string exceeds 2^53-1.");
(0, bsert_1.default)(lo.length <= exp, "Too many decimal places in fixed number string.");
if (hi.length === 0) {
hi = "0";
}
while (lo.length < exp) {
lo += "0";
}
if (lo.length === 0) {
lo = "0";
}
(0, bsert_1.default)(/^\d+$/.test(hi) && /^\d+$/.test(lo), "Non-numeric characters in fixed number string.");
hi = parseInt(hi, 10);
lo = parseInt(lo, 10);
const mult = Math.pow(10, exp);
const maxLo = Number.MAX_SAFE_INTEGER % mult;
const maxHi = (Number.MAX_SAFE_INTEGER - maxLo) / mult;
(0, bsert_1.default)(hi < maxHi || (hi === maxHi && lo <= maxLo), "Fixed number string exceeds 2^53-1.");
return sign * (hi * mult + lo);
}
//# sourceMappingURL=index.js.map

View File

@ -1,5 +1,5 @@
{
"name": "@lumeweb/cfg",
"name": "@lumeweb/relay-cfg",
"version": "0.1.7",
"license": "MIT",
"authors": [
@ -8,17 +8,19 @@
],
"main": "dist/index.js",
"scripts": {
"lint": "eslint lib/ || exit 0",
"test": "bmocha --reporter spec test/*-test.js"
},
"dependencies": {
"arg": "^5.0.2",
"bsert": "~0.0.10",
"deep-to-flat-object": "^1.0.1",
"object-path": "^0.11.8"
"prepare": "presetter bootstrap",
"build": "run build",
"semantic-release": "semantic-release"
},
"devDependencies": {
"@types/node": "^18.7.18",
"typescript": "^4.9.4"
"@lumeweb/node-library-preset": "^0.2.7",
"presetter": "*"
},
"readme": "ERROR: No README data found!",
"_id": "@lumeweb/cfg@0.1.7",
"dependencies": {
"bsert": "^0.0.12",
"deep-to-flat-object": "^1.0.1",
"object-path": "^0.11.8"
}
}

View File

@ -1,41 +0,0 @@
'use strict';
const assert = require('bsert');
const Config = require('../lib/config');
describe('bcfg', function() {
it('should filter options', () => {
const options = {
testString: 'hello',
childTestString: 'goodbye'
};
const parent = new Config('bcfg');
parent.inject(options);
parent.load(options);
assert.strictEqual(parent.str('test-string'), 'hello');
const child = parent.filter('child');
assert.strictEqual(child.str('test-string'), 'goodbye');
});
it('should filter argv', () => {
const parent = new Config('bcfg');
// process.argv
parent.parseArg([
'node',
'bcfg',
'--test-string=hello',
'--child-test-string=goodbye'
]);
assert.strictEqual(parent.str('test-string'), 'hello');
const child = parent.filter('child');
assert.strictEqual(child.str('test-string'), 'goodbye');
});
});

View File

@ -1,14 +0,0 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "esnext",
"sourceMap": true,
"esModuleInterop": true,
"outDir": "dist",
"declaration": true
},
"include": ["src"],
"exclude": [
"node_modules"
]
}