@abw/badger 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"badger.cjs.js","sources":["../src/Badger/Utils/Misc.js","../src/Badger/Utils/Color.js","../src/Badger/Utils/Debug.js","../src/Badger/Codecs/Json.js","../src/Badger/Codecs/index.js","../src/Badger/Codecs/Yaml.js","../src/Badger/Filesystem/Path.js","../src/Badger/Filesystem/File.js","../src/Badger/Filesystem/Directory.js","../src/Badger/Utils/Text.js","../src/Badger/Utils/Params.js","../src/Badger/Config.js","../src/Badger/Library.js","../src/Badger/Workspace.js","../src/Badger/Component.js"],"sourcesContent":["/**\n * Determines if a value is a string\n * @param {String} value - value to test\n * @return {Boolean} true if `value` is a string or false if not\n */\nexport function isString(value) {\n return typeof value === 'string';\n}\n\n/**\n * Determines if a value is an array\n * @param {Array} value - value to test\n * @return {Boolean} true if `value` is an Array or false if not\n */\nexport function isArray(value) {\n return Array.isArray(value);\n}\n\n/**\n * Determines if a value is a Function\n * @param {Function} value - value to test\n * @return {Boolean} true if `value` is a Function or false if not\n */\nexport function isFunction(value) {\n return typeof value === 'function'\n}\n\n/**\n * Determines if a value is an Object (but not an Array)\n * @param {Object} value - value to test\n * @return {Boolean} true if `value` is an Object or false if not\n */\nexport function isObject(value) {\n return typeof value === \"object\"\n && ! isArray(value)\n && ! isNull(value);\n}\n\n/**\n * Determines if a value is `undefined`\n * @param {any} value - value to test\n * @return {Boolean} true if `value` is `undefined` or false if not\n */\nexport function isUndefined(value) {\n return typeof value === 'undefined';\n}\n\n/**\n * Determines if a value is `null`\n * @param {any} value - value to test\n * @return {Boolean} true if `value` is `null` or false if not\n */\nexport function isNull(value) {\n return value === null;\n}\n\n/**\n * Determines if a value is defined and not null\n * @param {any} value - value to test\n * @return {Boolean} true if `value` is not `undefined` or `null`\n */\nexport function hasValue(value) {\n return ! (isUndefined(value) || isNull(value));\n}\n\n/**\n * Determines if all values are defined and not null\n * @param {any[]} values - values to test\n * @return {Boolean} true if all values are not `undefined` or `null`\n */\nexport function haveValue(...values) {\n return values.every( value => hasValue(value) );\n}\n\n/**\n * Determines if a value is undefined or null\n * @param {any} value - value to test\n * @return {Boolean} true if `value` is `undefined` or `null`\n */\nexport function noValue(value) {\n return ! hasValue(value);\n}\n\n/**\n * Throws a new Error object\n * @param {String[]} message - error message string(s)\n * @throws {Error}\n */\nexport function fail(...message) {\n throw new Error(message.join(''));\n}\n\n/**\n * Re-throw an existing Error object\n * @param {Error} error - error object\n * @throws {Error}\n */\nexport function rethrow(error) {\n throw error;\n}\n\n/**\n * Do nothing. Nothing at all.\n */\nexport function doNothing() {\n // speak again Cordelia\n}","import { isObject } from \"./Misc.js\";\n\nexport const ANSIStart = '\\u001B[';\nexport const ANSIEnd = 'm';\nexport const ANSIColors = {\n reset: 0,\n bold: 1,\n bright: 1,\n dark: 2,\n black: 0,\n red: 1,\n green: 2,\n yellow: 3,\n blue: 4,\n magenta: 5,\n cyan: 6,\n grey: 7,\n white: 8,\n fg: 30,\n bg: 40,\n};\n\n/**\n * Returns an ANSI escape code for a color string. This can be a single color\n * name, e.g. `red`, `green`, etc., or a color prefixed with `bright` or `dark`,\n * e.g. `bright red`, `dark green`, etc. An optional section argument can be\n * set to `fg` (default) to set a foreground color or `bg` for a background color.\n * @param {String} color - color name with optional modifier prefix\n * @param {String} [base='fg'] - `fg` or `bg` to set foreground or background color respectively\n * @return {String} ANSI escape code string\n * @example\n * const str = escapeCode('red')\n * @example\n * const str = escapeCode('bright red')\n * @example\n * const str = escapeCode('bright red', 'bg')\n */\nexport const escapeCode = (color, base='fg') => {\n let codes = [ ];\n let pair = color.split(/ /, 2);\n const hue = pair.pop();\n const code = (base ? ANSIColors[base] : 0) + ANSIColors[hue];\n codes.push(code);\n if (pair.length) {\n const shade = pair.length ? pair.shift() : 'dark';\n codes.push(ANSIColors[shade])\n }\n return ANSIStart + codes.join(';') + ANSIEnd;\n}\n\n/**\n * Returns an ANSI escape code for a color string or combination of foreground and\n * background colors.\n * @param {String|Object} colors - either a simple color name or object contain foreground and background colors\n * @param {String} [colors.fg] - foreground color\n * @param {String} [colors.fg] - background color\n * @return {String} ANSI escape code string\n * @example\n * const str = escape('red')\n * @example\n * const str = escape('bright red')\n * @example\n * const str = escape({ fg: 'bright yellow', bg: 'blue' })\n */\nexport const escape = (colors={}) => {\n const col = isObject(colors) ? colors : { fg: colors };\n let escapes = [ ];\n if (col.bg) {\n escapes.push(escapeCode(col.bg, 'bg'));\n }\n if (col.fg) {\n escapes.push(escapeCode(col.fg, 'fg'));\n }\n return escapes.join('');\n}\n\nexport const reset = () => escapeCode('reset')\n\n","import { escape, reset } from './Color.js'\nimport { doNothing } from './Misc.js';\n\n/**\n * Returns a debugging function which is enabled by the first `enabled` argument.\n * If this is `false` then it returns a function which does nothing. If it is\n * true then it returns a function that forwards all arguments to `console.log`.\n * An optional `prefix` be be specified to prefix each debugging line. The\n * optional third argument `color` can be used to specify a color for the prefix.\n * @param {Boolean} enabled - is debugging enabled?\n * @param {String} [prefix] - optional prefix for debugging messages\n * @param {String|Object} [color] - a color name or object (see {@link Badger/Utils/Color})\n * @param {String} [color.fg] - foreground color\n * @param {String} [color.bg] - background color\n * @return {Function} a debugging function\n * @example\n * const debug = Debugger(true)\n * @example\n * const debug = Debugger(true, 'Debug > ')\n * @example\n * const debug = Debugger(true, 'Debug > ', 'blue')\n * @example\n * const debug = Debugger(true, 'Debug > ', { bg: 'blue', fg: 'bright yellow' })\n */\nexport function Debugger(enabled, prefix='', color) {\n return enabled\n ? prefix\n ? (format, ...args) =>\n console.log(\n '%s' + prefix + '%s' + format,\n color ? escape(color) : '',\n reset(),\n ...args,\n )\n : console.log.bind(console)\n : doNothing;\n}\n\n/**\n * Creates a debugging function via {@link Debugger} and attaches it to the object\n * passed as the first argument as the `debug` function.\n * @param {Object} obj - the object to receive the `debug` function\n * @param {Boolean} enabled - is debugging enabled?\n * @param {String} [prefix] - optional prefix for debugging messages\n * @param {String|Object} [color] - a color name or object (see {@link Badger/Utils/Color})\n * @param {String} [color.fg] - foreground color\n * @param {String} [color.bg] - background color\n * @example\n * const debug = addDebug(myObject, true)\n * @example\n * const debug = addDebug(myObject, true, 'Debug > ')\n * @example\n * const debug = addDebug(myObject, true, 'Debug > ', 'blue')\n * @example\n * const debug = addDebug(myObject, true, 'Debug > ', { bg: 'blue', fg: 'bright yellow' })\n */\nexport function addDebug(obj, enabled, prefix='', color) {\n obj.debug = Debugger(enabled, prefix, color);\n}\n","/**\n * Function to encode JSON\n * @param {Object} data - The data to encode as JSON text\n * @return {String} a JSON encoded string\n * @example\n * encode({ message: 'Hello World' })\n */\nexport const encode = data => JSON.stringify(data);\n\n/**\n * Function to decode JSON\n * @param {String} text - The JSON text to decode\n * @return {Object|Array} the decoded object or array\n * @example\n * decode(\"{ message: 'Hello World' }\")\n */\nexport const decode = text => JSON.parse(text);\n\n/**\n * An object containing the JSON `encode` and `decode` functions\n */\nexport const codec = { encode, decode };\n\nexport default codec\n","import json from './Json.js'\nimport yaml from './Yaml.js'\n\n/**\n * Codecs provide a consistent encode()/decode() interface for serialising\n * and de-serialising data. This standard naming convention makes it possible\n * for the ../Filesystem/File.js module to support a \"codec\" option for\n * files. When this option is set the file.read() and file.write() methods\n * automatically handle the translation to and from the serialised format\n * using a codec object returned by the codec() function below. The codec\n * name can be specified in any case, e.g. \"Yaml\", \"YAML\", \"yaml\", \"YaML\",\n * etc., and it will be converted to lower case.\n */\n\n/**\n * Lookup table for codecs\n */\nexport const codecs = {\n json, yaml\n};\n\n/**\n * Function to fetch a codec\n * @param {string} name - The title of the code, in any case, e.g. \"yaml\", \"YAML\", \"Yaml\"\n */\nexport const codec = name => codecs[\n name.toLowerCase()\n];\n\nexport default codecs\n","// simple wrapper around JSON load/dump\nimport yaml from 'js-yaml';\n\n/**\n * Function to encode YAML\n * @param {Object} data - The data to encode as YAML text\n * @return {String} a YAML encoded string\n * @example\n * encode({ message: 'Hello World' })\n */\nexport const encode = data => yaml.dump(data);\n\n/**\n * Function to decode YAML\n * @param {String} text - The YAML text to decode\n * @return {Object|Array} the decoded object or array\n * @example\n * decode(\"message: Hello World\")\n */\nexport const decode = text => yaml.load(text);\n\n/**\n * An object containing the YAML `encode` and `decode` functions\n */\nexport const codec = { encode, decode };\n\nexport default codec\n","import path from 'node:path';\nimport { stat } from 'node:fs/promises'\nimport { rethrow } from '../Utils/Misc.js';\nimport { addDebug } from '../Utils/Debug.js';\n\nconst defaultOptions = {\n encoding: 'utf8'\n}\n\nexport class Path {\n constructor(path, options={}) {\n // allow path/file/directory to be constructed from an existing object\n if (path instanceof Path) {\n path = path.path();\n }\n this.state = { path, options: { ...defaultOptions, ...options } };\n addDebug(this, options.debug, options.debugPrefix || 'Path', options.debugColor);\n }\n path() {\n return this.state.path;\n }\n relativePath(...parts) {\n return path.join(this.state.path, ...parts);\n }\n options(options={}) {\n return { ...this.state.options, ...options };\n }\n async exists() {\n try {\n await this.stat();\n return true;\n }\n catch (error) {\n return error.code === 'ENOENT'\n ? false\n : rethrow(error);\n }\n }\n async stat() {\n const stats = await stat(this.state.path);\n return this.state.stats = stats;\n }\n unstat() {\n this.state.stats = undefined;\n console.log('XXX unstat: ', this.state.stats);\n return this;\n }\n}\n\nexport default Path\n","import path from 'node:path'\nimport Path from './Path.js'\nimport { dir } from './Directory.js'\nimport { codec } from '../Codecs/index.js'\nimport { readFile, writeFile, rm } from 'node:fs/promises'\n\nclass File extends Path {\n /**\n * Returns a new {@link Directory} object for the parent directory of the file\n * @param {Object} [options] - directory configuration options\n * @param {Boolean} [options.codec] - codec for encoding/decoding file data\n * @return {Object} a {@link Directory} object for the parent\n */\n directory(options) {\n return dir(path.dirname(this.state.path), options);\n }\n\n /**\n * An alias for the {@link directory} method for lazy people\n * @return {Object} the parent {@link Directory} object\n */\n dir(...args) {\n return this.directory(...args);\n }\n\n /**\n * Reads the file content. If a `codec` has been specified then the content is decoded.\n * @param {Object} [options] - directory configuration options\n * @param {Boolean} [options.codec] - codec for encoding/decoding file data\n * @return {String|Object} the file content\n * @example\n * const text = file('myfile.txt').read();\n * @example\n * const data = file('myfile.json', { codec: 'json' }).read();\n * @example\n * const data = file('myfile.json').read({ codec: 'json' });\n */\n read(options) {\n const opts = this.options(options);\n const file = readFile(this.state.path, opts);\n return opts.codec\n ? file.then(text => codec(opts.codec).decode(text))\n : file;\n }\n\n /**\n * Writes the file content. If a `codec` has been specified then the content will be encoded.\n * @param {String|Object} data - directory configuration options\n * @param {Object} [options] - directory configuration options\n * @param {Boolean} [options.codec] - codec for encoding/decoding file data\n * @example\n * file('myfile.txt').write('Hello World');\n * @example\n * file('myfile.json', { codec: 'json' }).write({ message: 'Hello World' });\n * @example\n * file('myfile.json').write({ message: 'Hello World' }, { codec: 'json' });\n */\n write(data, options) {\n const opts = this.options(options);\n const text = opts.codec\n ? codec(opts.codec).encode(data)\n : data;\n return writeFile(this.state.path, text, opts).then( () => this );\n }\n\n async delete(options) {\n await rm(this.state.path, options);\n return this;\n }\n}\n\n/**\n * Function to create a new {@link File} object for a file\n * @param {String} path - file path\n * @param {Object} [options] - configuration options\n * @param {Boolean} [options.codec] - a codec for encoding/decoding files\n * @return {Object} the {@link File} object\n */\nexport const file = (path, options) => {\n return new File(path, options);\n}\n\nexport default File\n","import process from 'node:process';\nimport path from 'node:path';\nimport Path from './Path.js'\nimport { file } from './File.js'\nimport { fail } from '../Utils/Misc.js';\nimport { rm, mkdir, rmdir, readdir } from 'node:fs/promises'\n\nclass Directory extends Path {\n /**\n * Fetch a new {@link File} object for a file in the directory.\n * @param {string} path - file path\n * @param {Object} [options] - file configuration options\n * @param {String} [options.codec] - codec for encoding/decoding file data\n * @return {Object} the {@link File} object\n */\n file(path, options) {\n this.debug(\"file(%s, %o)\", path, options);\n return file(this.relativePath(path), this.options(options));\n }\n\n /**\n * Fetch a new {@link Directory} object for a sub-directory in the directory.\n * @param {string} path - directory path\n * @param {Object} [options] - directory configuration options\n * @param {String} [options.codec] - codec for encoding/decoding file data\n * @return {Object} the {@link Directory} object\n */\n directory(path, options) {\n this.debug(\"directory(%s, %o)\", path, options);\n return dir(this.relativePath(path), this.options(options));\n }\n\n /**\n * An alias for the {@link directory} method for lazy people\n * @return {Object} the {@link Directory} object\n */\n dir(path, options) {\n this.debug(\"dir(%s, %o)\", path, options);\n return this.directory(path, options);\n }\n\n /**\n * Returns a new {@link Directory} object for the parent directory\n * @param {Object} [options] - directory configuration options\n * @param {Boolean} [options.codec] - codec for encoding/decoding file data\n * @return {Object} a {@link Directory} object for the parent\n */\n parent(options) {\n this.debug(\"parent()\");\n return this.directory('..', options);\n }\n\n /**\n * Returns the names of the files and sub-directories in the directory\n * @return {Promise} fulfills with an array of the file and directory names\n */\n async read() {\n this.debug(\"read()\");\n return await readdir(this.path());\n }\n\n /**\n * Determines if the directory is empty.\n * @return {Promise} fulfills with a boolean value true (empty) or false (not empty).\n */\n async isEmpty() {\n this.debug(\"isEmpty()\");\n const entries = await this.read();\n return entries.length === 0;\n }\n\n /**\n * Determines if the directory is not empty.\n * @return {Promise} fulfills with a boolean value true (not empty) or false (empty).\n */\n async notEmpty() {\n this.debug(\"notEmpty()\");\n const empty = await this.isEmpty();\n return !empty;\n }\n\n /**\n * Empty the directory.\n * @param {Object} [options] - configuration options\n * @param {Boolean} [options.force] - force removal of files and directories\n * @param {Boolean} [options.recursive] - recursively empty and delete sub-directories\n * @return {Promise} fulfills to the {@link Directory} object\n */\n async empty(options={}) {\n this.debug(\"empty(%o)\", options);\n if (await this.exists() && await this.notEmpty()) {\n await rm(this.path(), options);\n }\n return this;\n }\n\n /**\n * Make the directory.\n * @param {Object} [options] - configuration options\n * @param {Boolean} [options.recursive] - create intermediate directories\n * @return {Promise} fulfills to the {@link Directory} object\n */\n async mkdir(options={}) {\n this.debug(\"mkdir(%o)\", options);\n const exists = await this.exists();\n if (! exists) {\n await mkdir(this.path(), options);\n }\n return this;\n }\n\n /**\n * Remove the directory.\n * @param {Object} [options] - configuration options\n * @param {Boolean} [options.empty] - delete items in directory\n * @param {Boolean} [options.force] - force delete files and directories\n * @param {Boolean} [options.recursive] - recursively delete sub-directories\n * @return {Promise} fulfills to the {@link Directory} object\n */\n async rmdir(options={}) {\n this.debug(\"rmdir(%o)\", options);\n if (options.empty) {\n await this.empty(options);\n }\n if (await this.exists()) {\n await rmdir(this.path());\n }\n return this;\n }\n\n /**\n * Create the directory and any intermediate directories.\n * @param {Object} [options] - configuration options\n * @param {Boolean} [options.recursive=true] - recursively create intermediate directories\n * @return {Promise} fulfills to the {@link Directory} object\n */\n create(options={ recursive: true }) {\n this.debug(\"create(%o)\", options);\n return this.mkdir(options);\n }\n\n /**\n * Empty and delete the directory.\n * @param {Object} [options] - configuration options\n * @param {Boolean} [options.empty=true] - empty directory of any files and sub-directories\n * @param {Boolean} [options.recursive=true] - recursively delete sub-directories\n * @param {Boolean} [options.force=true] - force deletion of files and sub-directories\n * @return {Promise} fulfills to the {@link Directory} object\n */\n destroy(options={ empty: true, recursive: true, force: true }) {\n this.debug(\"destroy(%o)\", options);\n return this.rmdir(options);\n }\n\n /**\n * Assert that a directory exists and optionally create it\n * @param {Object} [options] - configuration options\n * @param {Boolean} [options.create] - create the directory and any intermediate directories if it doesn't exist - equivalent to adding `mkdir` and `recursive` options or calling {@link create}\n * @param {Boolean} [options.mkdir] - create the directory, add the `recursive` option to create intermediate directories - equivalent to calling {@link mkdir}\n * @param {Boolean} [options.recursive] - when used with `mkdir`, creates any intermediate directories\n * @return {Promise} fulfills to the {@link Directory} object\n */\n async mustExist(options={}) {\n this.debug(\"mustExist(%o)\", options);\n if (await this.exists()) {\n return this;\n }\n if (options.mkdir) {\n return this.mkdir(options);\n }\n if (options.create) {\n return this.create();\n }\n fail(\"Directory does not exist: \", this.path());\n }\n}\n\n/**\n * Function to create a new {@link Directory} object\n * @param {string} path - directory path\n * @param {Object} [options] - configuration options\n * @param {Boolean} [options.codec] - a codec for encoding/decoding files\n * @return {Object} the {@link Directory} object\n */\nexport const dir = (path, options) => {\n return new Directory(path, options);\n}\n\n/**\n * Function to create a new {@link Directory} object for the current working directory\n * @param {Object} [options] - configuration options\n * @param {Boolean} [options.codec] - a codec for encoding/decoding files\n * @return {Object} the {@link Directory} object\n */\nexport const cwd = options => {\n return dir(process.cwd(), options);\n}\n\n/**\n * Function to create a new {@link Directory} object for the directory of a JS source file\n * @param {string} url - module url - from `import.meta.url`\n * @param {Object} [options] - configuration options\n * @param {Boolean} [options.codec] - a codec for encoding/decoding files\n * @return {Object} the {@link Directory} object\n */\nexport const bin = (url, options) => {\n return dir(\n path.dirname(url.replace(/^file:\\/\\//, '')),\n options\n );\n}\n\nexport default Directory\n","import { isString, isArray } from \"./Misc.js\";\n\n/**\n * Split a comma/whitespace delimited string into an Array\n * @param {String} [value] - string to split\n * @return {Array} array of split strings\n * @example\n * const strings = splitList('one two three')\n * @example\n * const strings = splitList('one,two,three')\n * @example\n * const strings = splitList('one, two, three')\n */\nexport function splitList(value) {\n return isString(value)\n ? value.split(/,\\s*|\\s+/)\n : isArray(value)\n ? value\n : [value];\n}\n\n/**\n * Join an Array into a single string\n * @param {Array} [array] - array to join\n * @param {String} [joint=' '] - delimiter to join strings\n * @param {String} [lastJoint=joint] - delimiter for final item\n * @return {String} joined string\n * @example\n * joinList(['one', 'two', 'three']); // one two three\n * @example\n * joinList(['one', 'two', 'three'], ', '); // one, two, three\n * @example\n * joinList(['one', 'two', 'three'], ', ', ' and '); // one, two and three\n */\nexport function joinList(array, joint=' ', lastJoint=joint) {\n let copy = [...array];\n const last = copy.pop();\n return copy.length\n ? [copy.join(joint), last].join(lastJoint)\n : last;\n}\n\n/**\n * Join an Array into a single string using commas for delimiters and ` and ` for the final item\n * @param {Array} [array] - array to join\n * @param {String} [joint=', '] - delimiter to join strings\n * @param {String} [lastJoint=' and '] - delimiter for final item\n * @return {String} joined string\n * @example\n * joinListAnd(['one', 'two', 'three']); // one, two and three\n */\nexport function joinListAnd(array, joint=', ', lastJoint=' and ') {\n return joinList(array, joint, lastJoint);\n}\n\n/**\n * Join an Array into a single string using commas for delimiters and ` or ` for the final item\n * @param {Array} [array] - array to join\n * @param {String} [joint=', '] - delimiter to join strings\n * @param {String} [lastJoint=' or '] - delimiter for final item\n * @return {String} joined string\n * @example\n * joinListOr(['one', 'two', 'three']); // one, two or three\n */\nexport function joinListOr(array, joint=', ', lastJoint=' or ') {\n return joinList(array, joint, lastJoint);\n}\n\n/**\n * Capitalise a string by converting the first character to upper case and other characters to lower case\n * @param {String} [word] - word to capitalise\n * @return {String} capitalised string\n * @example\n * capitalise('badger'); // Badger\n * @example\n * capitalise('BADGER'); // Badger\n */\nexport function capitalise(word) {\n return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();\n}\n\n/**\n * Convert a snake case string to studly caps\n * @param {String} [snake] - word to capitalise\n * @return {String} capitalised string\n * @example\n * snakeToStudly('happy_badger_dance'); // HappyBadgerDance\n * @example\n * snakeToStudly('happy_badger/dance'); // HappyBadger/Dance\n */\nexport function snakeToStudly(snake) {\n return snake.split('/').map(\n // each segment can be like foo_bar which we convert to FooBar\n segment => segment.split('_').map(capitalise).join('')\n ).join('/');\n}\n\n/**\n * Convert a snake case string to camel case\n * @param {String} [snake] - word to capitalise\n * @return {String} capitalised string\n * @example\n * snakeToCamel('happy_badger_dance'); // happyBadgerDance\n * @example\n * snakeToCamel('happy_badger/dance'); // happyBadger/dance\n */\nexport function snakeToCamel(snake) {\n return snake.split('/').map(\n // each segment can be like foo_bar which we convert to fooBar\n segment => segment.split('_').map((i, n) => n ? capitalise(i) : i).join('')\n ).join('/');\n}\n","import { hasValue, fail } from \"./Misc.js\";\nimport { joinListOr, splitList } from \"./Text.js\";\n\n/**\n * Assert that a parameter object contains an item with a defined/non-null value\n * @param {Object} params={} - parameters object\n * @param {String} name - parameter that must be included\n * @return {any} the parameter value\n * @throws {Error} if the parameter is not defined or null\n * @example\n * const foo = requiredParam({ foo: 10 }, 'foo');\n */\nexport function requiredParam(params={}, name) {\n const value = params[name];\n if (hasValue(value)) {\n return value;\n }\n else {\n fail(\"Missing value for required parameter: \", name);\n }\n}\n\n/**\n * Assert that a parameter object contains all specified item with a defined/non-null value\n * @param {Object} params={} - parameters object\n * @param {Array|String} names - parameters that must be included, as an Array or whitespace/comma delimited string (see {@link splitList})\n * @return {Array} the parameter values\n * @throws {Error} if any parameter is not defined or null\n * @example\n * const [foo, bar] = requiredParams({ foo: 10, bar: 20 }, 'foo bar');\n */\nexport function requiredParams(params={}, names) {\n return splitList(names).map( name => requiredParam(params, name) );\n}\n\n/**\n * An alias for {@link requiredParams} for people who don't like typing long names (and for symmetry with {@link anyParams}))\n */\nexport const allParams=requiredParams;\n\n/**\n * Assert that a parameter object contains any of the specified items with a defined/non-null value\n * @param {Object} params={} - parameters object\n * @param {Array|String} names - parameters of which at least one must be included, as an Array or whitespace/comma delimited string (see {@link splitList})\n * @return {Array} the parameter values\n * @throws {Error} if any parameter is not defined or null\n * @example\n * const [foo, bar] = anyParams({ foo: 10, wiz: 99 }, 'foo bar');\n */\nexport function anyParams(params, names) {\n let found = false;\n const nlist = splitList(names);\n const values = nlist.map(\n name => {\n const value = params[name];\n if (hasValue(value)) {\n found = true;\n }\n return value;\n }\n );\n return found\n ? values\n : fail(\"Missing value for one of: \", joinListOr(nlist));\n}\n","import { dir } from './Filesystem/Directory.js'\nimport { allParams, anyParams } from './Utils/Params.js'\nimport { splitList } from './Utils/Text.js'\nimport { fail } from './Utils/Misc.js';\nimport { addDebug } from './Utils/Debug.js';\n\nconst defaults = {\n codecs: 'yaml json',\n};\n\nexport class Config {\n constructor(params={}) {\n const options = { ...defaults, ...params };\n const [rootDir] = allParams(options, 'dir');\n const [codec, codecs] = anyParams(options, 'codec codecs');\n\n this.state = {\n dir: dir(rootDir),\n codecs: splitList(codecs) || [codec],\n }\n\n addDebug(this, options.debug, options.debugPrefix, options.debugColor);\n this.debug('root dir: ', this.state.dir.path());\n this.debug('codecs: ', this.state.codecs);\n }\n async file(uri) {\n for (let codec of this.state.codecs) {\n const path = uri + '.' + codec;\n const file = this.state.dir.file(path, { codec });\n this.debug('looking for config file: ', file.path());\n if (await file.exists()) {\n this.debug('config file exists: ', file.path());\n return file;\n }\n }\n return undefined;\n }\n async config(uri, defaults) {\n const file = await this.file(uri);\n return file\n ? await file.read()\n : (defaults || fail(\"No configuration file for \" + uri))\n }\n}\n\nexport const config = options => new Config(options)\n\nexport default Config\n","import { dir as fsdir } from \"./Filesystem/Directory.js\";\nimport { requiredParam } from \"./Utils/Params.js\";\nimport { addDebug } from \"./Utils/Debug.js\";\nimport { splitList } from \"./Utils/Text.js\";\nimport { fail } from \"./Utils/Misc.js\";\n\nconst defaults = {\n dir: ['lib','library','src','components'],\n ext: ['js', 'mjs'],\n}\n\nexport class Library {\n constructor(props={}) {\n const root = fsdir(requiredParam(props, 'root'));\n const dir = props.directory || props.dir || props.dirs || defaults.dir;\n const ext = props.extension || props.ext || props.exts || defaults.ext;\n const dirs = splitList(dir).map( dir => root.dir(dir) ); // resolve to root dir\n const exts = splitList(ext).map( ext => ext.replace(/^\\./, '') ); // remove leading '.'\n this.state = {\n dirs, exts\n }\n addDebug(this, props.debug, props.debugPrefix, props.debugColor);\n }\n async dirs() {\n return this.state.dirsExist\n || ( this.state.dirsExist = await this.dirsExist() );\n }\n async dirsExist() {\n const dirs = this.state.dirs;\n const exists = await Promise.all(\n dirs.map( d => d.exists() )\n );\n return dirs.filter((value, index) => exists[index]);\n }\n async lib(uri) {\n const dirs = await this.dirs();\n const exts = this.state.exts;\n for (let dir of dirs) {\n for (let ext of exts) {\n const file = dir.file(uri + '.' + ext);\n this.debug('looking for module %s as', uri, file.path());\n const exists = await file.exists();\n if (exists) {\n const load = await import(file.path());\n this.debug('loaded %s as', file.path());\n return load;\n }\n }\n }\n fail(\"Library not found: \", uri);\n }\n}\n\nexport const library = props => new Library(props);\n\nexport default library;","import { dir } from \"./Filesystem/Directory.js\";\nimport { requiredParam } from \"./Utils/Params.js\";\nimport { fail, hasValue } from \"./Utils/Misc.js\";\nimport { addDebug } from \"./Utils/Debug.js\";\nimport { Config } from \"./Config.js\";\nimport { Library } from \"./Library.js\";\n\nconst defaults = {\n library: {\n },\n config: {\n dir: 'config',\n }\n}\nexport class Workspace {\n constructor(props={}) {\n const rootDir = dir(requiredParam(props, 'dir'));\n const cfgDir = rootDir.dir(props.config?.dir || defaults.config.dir);\n const cfgOpts = { ...defaults.config, ...(props.config||{}), dir: cfgDir };\n const config = new Config(cfgOpts);\n const libOpts = { ...defaults.library, ...(props.library||{}), root: rootDir };\n const library = new Library(libOpts);\n\n this.state = {\n rootDir,\n config,\n library\n }\n\n addDebug(this, props.debug, props.debugPrefix, props.debugColor);\n this.debug('root dir: ', rootDir.path());\n this.debug('config dir: ', cfgDir.path());\n }\n dir(path, options) {\n this.debug(\"dir(%s, %o)\", path, options);\n return hasValue(path)\n ? this.state.rootDir.dir(path, options)\n : this.state.rootDir;\n }\n file(path, options) {\n this.debug(\"file(%s, %o)\", path, options);\n return this.state.rootDir.file(path, options)\n }\n read(path, options) {\n this.debug(\"read(%s, %o)\", path, options);\n return this.file(path, options).read();\n }\n write(path, data, options) {\n this.debug(\"write(%s, %o, %o)\", path, data, options);\n return this.file(path, options).write(data);\n }\n configDir(path, options) {\n this.debug(\"configDir(%s, %o)\", path, options);\n return hasValue(path)\n ? this.state.configDir(path, options)\n : this.state.configDir;\n }\n async config(uri, defaults) {\n this.debug(\"config(%s, %o)\", uri, defaults);\n return hasValue(uri)\n ? this.state.config.config(uri, defaults)\n : this.state.config;\n }\n async lib(uri) {\n return this.state.library.lib(uri);\n }\n async component(uri, props) {\n const config = await this.config(uri, {});\n const lib = await this.lib(config.component?.library || uri);\n const exp = config.component?.export || 'default';\n const compcls = lib[exp] || fail(\"No '\", exp, \"' export from component library: \", uri);\n const comp = new compcls(this, { ...config, ...props });\n // this.debug(\"created component \", uri)\n return comp;\n }\n}\n\nexport const workspace = props => new Workspace(props);\n\nexport default Workspace;","import { addDebug } from \"./Utils/Debug.js\";\n\nexport class Component {\n constructor(workspace, props={}) {\n this.workspace = workspace;\n this.props = props;\n addDebug(this, props.debug, props.debugPrefix, props.debugColor);\n this.initComponent(props);\n }\n initComponent() {\n // stub for subclasses\n }\n}\n\nexport default Component"],"names":["isString","value","isArray","Array","isObject","isNull","isUndefined","hasValue","fail","message","Error","join","rethrow","error","doNothing","ANSIColors","reset","bold","bright","dark","black","red","green","yellow","blue","magenta","cyan","grey","white","fg","bg","escapeCode","color","base","codes","pair","split","hue","pop","code","push","length","shade","shift","Debugger","enabled","prefix","format","args","console","log","colors","col","escapes","escape","bind","addDebug","obj","debug","codecs","json","encode","data","JSON","stringify","decode","text","parse","yaml","dump","load","codec","name","toLowerCase","defaultOptions","encoding","Path","constructor","path","options","this","state","debugPrefix","debugColor","relativePath","parts","async","stat","stats","unstat","undefined","File","directory","dir","dirname","read","opts","file","readFile","then","write","writeFile","rm","Directory","parent","readdir","isEmpty","exists","notEmpty","mkdir","empty","rmdir","create","recursive","destroy","force","splitList","joinList","array","joint","lastJoint","copy","last","joinListOr","capitalise","word","charAt","toUpperCase","slice","requiredParam","params","requiredParams","names","map","allParams","anyParams","found","nlist","values","defaults","Config","rootDir","uri","ext","Library","props","root","fsdir","dirs","extension","exts","replace","dirsExist","Promise","all","d","filter","index","t","resolve","_interopNamespace","require","Workspace","cfgDir","config","cfgOpts","libOpts","library","configDir","lib","component","exp","export","workspace","initComponent","url","process","cwd","every","snake","segment","i","n"],"mappings":"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"}