UNPKG

properties-reader

Version:

Properties file reader for Node.js

1 lines 21.6 kB
{"version":3,"sources":["../../src/index.ts","../../src/actions/append.ts","../../src/actions/read.ts","../../src/actions/save.ts","../../src/bind-to-express.ts","../../src/parse-value.ts","../../src/get-by-root.ts","../../src/output.ts","../../src/properties-path.ts","../../src/reader.ts"],"sourcesContent":["import { createPropertiesReader } from './reader';\n\nexport default createPropertiesReader;\n\nexport const propertiesReader = createPropertiesReader;\n\nexport { bindToExpress, expressBasePath } from './bind-to-express';\nexport type { Reader } from './properties-reader.types';\nexport type { PropertiesFactoryOptions } from './reader';\n","import { readFileSync } from 'node:fs';\n\nimport { type ReadLineTask, read } from './read';\n\nfunction newTask(): ReadLineTask {\n return { section: '', properties: new Map() };\n}\n\nexport function append(\n sourceFile: string | undefined | null,\n encoding: BufferEncoding,\n task = newTask()\n) {\n if (!sourceFile) {\n return task;\n }\n\n const file = readFileSync(sourceFile, encoding);\n return read(file, task);\n}\n","export type ReadLineTask = {\n section: string;\n properties: Map<string, string>;\n};\n\nfunction readLine(line: string, task: ReadLineTask): ReadLineTask {\n const trimmed = line.trim();\n if (!trimmed) {\n return task;\n }\n\n const section = /^\\[([^=]+)]$/.exec(trimmed);\n const property = !section && /^([^#=]+)(={0,1})(.*)$/.exec(trimmed);\n\n if (section) {\n task.section = section[1];\n } else if (property) {\n const currentSection = task.section ? `${task.section}.` : '';\n task.properties.set(currentSection + property[1].trim(), property[3].trim());\n }\n\n return task;\n}\n\nexport function read(input: string, task: ReadLineTask): ReadLineTask {\n return String(input)\n .split('\\n')\n .reduce<ReadLineTask>(\n (task, line) => {\n return readLine(line, task);\n },\n { ...task, section: '' }\n );\n}\n","import { type FileHandle, open } from 'node:fs/promises';\n\nimport type { PropertiesIterator } from '../properties-reader.types';\n\nexport async function save(destFile: string, props: PropertiesIterator) {\n let pointer: null | FileHandle = null;\n try {\n pointer = await open(destFile, 'w');\n for (const line of props) {\n await pointer.writeFile(`${line}\\n`, 'utf8');\n }\n } finally {\n await pointer?.close();\n }\n}\n","import { dirname, resolve, sep } from 'node:path';\n\nimport { exists, FOLDER } from '@kwsites/file-exists';\nimport { mkdirp } from 'mkdirp';\n\nimport type { ExpressAppLike, Nullable, Reader } from './properties-reader.types';\n\n/**\n * Helper to ensure the provided `basePath` has a trailing slash suffix. When omitted\n * or empty, defaults to using the process current working directory.\n *\n * @param basePath\n */\nexport function expressBasePath(basePath?: Nullable<string>): string {\n return resolve(basePath || process.cwd(), './') + sep;\n}\n\n/**\n * Binds properties into the settings for an express app.\n *\n * Where properties have a key ending with either `path` or `dir`, the value of the property\n * resolved relative to the `basePath` directory and optionally (when `makePaths` is `true`)\n * the path will be created.\n *\n * Where a property key starts with `browser.`, the `app.locals` will have a property added\n * (without the `browser.` prefix). Useful for including variables for templating libraries.\n *\n * ```\n * import { propertiesReader, bindToExpress } from 'properties-reader';\n *\n * const props = propertiesReader()\n * .set('config.dir', './config')\n * .set('service.username', 'some secret here')\n * .set('browser.app.name', 'My App');\n *\n * bindToExpress(\n * props, app, '/bin/my-app', true\n * );\n *\n * app.get('config.dir') === '/bin/my-app/config';\n * app.get('service.username') === 'some secret here';\n * app.get('properties') === props;\n *\n * // only if `app.locals` had already been enabled before using `bindToExpress`\n * app.locals?.['app-name'] === 'My App';\n * ```\n *\n *\n * @param reader\n * @param app\n * @param basePath\n * @param makePaths\n */\nexport function bindToExpress(\n reader: Reader,\n app: ExpressAppLike,\n basePath: string,\n makePaths: boolean\n) {\n for (const [key, value] of reader.entries()) {\n if (value && /\\.(path|dir)$/.test(key)) {\n const resolvedValue = resolve(basePath, value);\n reader.set(key, resolvedValue);\n\n try {\n const directoryPath = /dir$/.test(key) ? resolvedValue : dirname(resolvedValue);\n if (makePaths) {\n mkdirp.sync(directoryPath);\n } else if (!exists(directoryPath, FOLDER)) {\n throw new Error('Path is not a directory that already exists');\n }\n } catch {\n throw new Error(`Unable to create directory ${value}`);\n }\n }\n\n app.set(key, reader.get(key));\n\n if (/^browser\\./.test(key) && app.locals) {\n app.locals[key.substr(8)] = reader.get(key);\n }\n }\n\n app.set('properties', reader);\n\n return reader;\n}\n","import type { ParsedValue } from './properties-reader.types';\n\nexport function parseValue(input?: string): ParsedValue {\n const parsedValue = String(input).trim();\n switch (parsedValue) {\n case 'undefined':\n case 'null':\n return null;\n case !isNaN(parsedValue as unknown as number) && !!parsedValue && parsedValue:\n return +parsedValue;\n case 'false':\n case 'true':\n return parsedValue === 'true';\n default: {\n const replacements: Record<string, string> = { '\\\\n': '\\n', '\\\\r': '\\r', '\\\\t': '\\t' };\n return parsedValue.replace(/\\\\[nrt]/g, (key) => replacements[key]);\n }\n }\n}\n","import { parseValue } from './parse-value';\nimport type { ParsedValue } from './properties-reader.types';\n\nexport function getByRoot(store: Map<string, string>, root = '') {\n return Object.fromEntries(parsedEntries(store, `${root}.`));\n}\n\nexport function* parsedEntries(\n store: Map<string, string>,\n prefix = ''\n): MapIterator<[string, ParsedValue]> {\n for (const [storeKey, storeValue] of store.entries()) {\n const key = parsedKey(storeKey, prefix);\n if (key) {\n yield [key, parseValue(storeValue)];\n }\n }\n}\n\nfunction parsedKey(key: string, prefix: string) {\n if (!prefix) {\n return key;\n }\n if (key.startsWith(prefix)) {\n return key.substring(prefix.length);\n }\n}\n","import type { PropertiesIterator } from './properties-reader.types';\n\nexport function output(\n properties: Map<string, string>,\n allowDuplicateSections: boolean,\n saveSections: boolean\n): PropertiesIterator {\n if (!allowDuplicateSections) {\n properties = collapseSections(properties);\n }\n\n return saveSections\n ? generatePropertiesWithSections(properties)\n : generatePropertiesWithoutSections(properties);\n}\n\nfunction* generatePropertiesWithoutSections(properties: Map<string, string>) {\n for (const [key, value] of properties.entries()) {\n yield `${key}=${value}`;\n }\n}\n\nfunction* generatePropertiesWithSections(properties: Map<string, string>) {\n let section: null | string = null;\n for (let [key, value] of properties.entries()) {\n const [prefix, ...tokens] = key.split('.');\n\n if (tokens.length) {\n if (section !== prefix) {\n section = prefix;\n yield `[${section}]`;\n }\n key = tokens.join('.');\n } else {\n section = null;\n }\n\n yield `${key}=${value}`;\n }\n}\n\nfunction collapseSections(properties: Map<string, string>) {\n const sections = new Map<string, [string, string][]>();\n\n for (const [key, value] of properties.entries()) {\n const [section] = key.split('.');\n const map = sections.get(section) ?? [];\n map.push([key, value]);\n sections.set(section, map);\n }\n\n return new Map(Array.from(sections.values()).flat());\n}\n","import type { PathProxy } from './properties-reader.types';\n\ntype NestedPathBranch = {\n dual: boolean;\n leaves: Map<string, string>;\n branches: NestedPath;\n readonly path: string;\n parent: NestedPathBranch | null;\n};\ntype NestedPath = Record<string, NestedPathBranch>;\n\nfunction addLeaf(branch: NestedPathBranch, leaf: string, key: string) {\n branch.leaves.set(leaf, key);\n\n if (Object.hasOwn(branch.branches, leaf)) {\n branch.branches[leaf].dual = true;\n }\n}\nfunction addBranch(branch: NestedPathBranch, token: string) {\n const next = (branch.branches[token] ??= childBranch(branch, token));\n if (branch.leaves.has(token)) {\n next.dual = true;\n }\n return next;\n}\n\nfunction childBranch(parent: NestedPathBranch | null, child = ''): NestedPathBranch {\n return {\n dual: false,\n leaves: new Map(),\n branches: Object.create(null),\n path: (parent?.path ? `${parent.path}.` : '') + child,\n parent,\n };\n}\n\nfunction pathLayers(map: Map<string, string>) {\n const paths: NestedPathBranch = childBranch(null);\n\n for (const key of map.keys()) {\n const tokens = key.split('.');\n const leaf = tokens.pop()!;\n const path = tokens.reduce((branch, token) => addBranch(branch, token), paths);\n addLeaf(path, leaf, key);\n }\n\n return paths;\n}\n\nfunction memoize<T, U>(fn: (cacheKey: T) => U): (cacheKey: T) => U {\n const cache = new Map<T, U>();\n return (key) => {\n if (!cache.has(key)) {\n cache.set(key, fn(key));\n }\n return cache.get(key)!;\n };\n}\n\nexport function propertiesPath(map: Map<string, string>): PathProxy {\n const shape = pathLayers(map);\n const value = (layer: NestedPathBranch, key: string) => {\n if (!key) {\n return map.get(layer.path);\n }\n\n const leaf = layer.leaves.get(key);\n const branch = Object.hasOwn(layer.branches, key);\n\n if (branch) {\n return make(layer.branches[key]);\n }\n\n return typeof leaf === 'string' ? map.get(leaf) : undefined;\n };\n\n const make = memoize((layer: NestedPathBranch) => {\n const ownKeys = new Set([...layer.leaves.keys(), ...Object.keys(layer.branches)]);\n\n const target = Object.defineProperties(\n Object.create(null),\n Object.fromEntries(\n [...ownKeys].map((name) => [\n name,\n {\n configurable: false,\n enumerable: true,\n get() {\n return value(layer, name);\n },\n },\n ])\n )\n );\n\n if (layer.dual) {\n Object.defineProperty(target, '', {\n configurable: false,\n enumerable: true,\n get() {\n return value(layer, '');\n },\n });\n }\n\n return target;\n });\n\n return make(shape);\n}\n","import { append } from './actions/append';\nimport { read } from './actions/read';\nimport { save } from './actions/save';\nimport { bindToExpress, expressBasePath } from './bind-to-express';\nimport { getByRoot, parsedEntries } from './get-by-root';\nimport { output } from './output';\nimport { parseValue } from './parse-value';\nimport { propertiesPath } from './properties-path';\nimport type { ExpressAppLike, Reader, Value } from './properties-reader.types';\n\ntype AppenderOptions = {\n allowDuplicateSections: boolean;\n};\n\ntype WriterOptions = {\n saveSections: boolean;\n};\n\nexport type PropertiesFactoryOptions = {\n encoding?: BufferEncoding;\n sourceFile?: string;\n} & Partial<AppenderOptions> &\n Partial<WriterOptions>;\n\nexport const createPropertiesReader = ({\n sourceFile,\n encoding = 'utf-8',\n allowDuplicateSections = false,\n saveSections = true,\n}: PropertiesFactoryOptions = {}) => {\n const store = append(sourceFile, encoding);\n\n function entries(options?: { parsed?: false | undefined }): MapIterator<[string, string]>;\n function entries(options: { parsed: true }): MapIterator<[string, null | Value]>;\n function entries(\n options: { parsed?: boolean } = {}\n ): MapIterator<[string, string | null | Value]> {\n return options.parsed === true ? parsedEntries(store.properties) : store.properties.entries();\n }\n\n const instance: Reader = {\n get length() {\n return store.properties.size;\n },\n\n append(sourceFile?: string | null, enc: BufferEncoding = encoding) {\n append(sourceFile, enc, store);\n return instance;\n },\n\n clone() {\n const next = createPropertiesReader({ allowDuplicateSections, encoding, saveSections });\n for (const [key, value] of store.properties.entries()) {\n next.set(key, value);\n }\n return next;\n },\n\n bindToExpress(app: ExpressAppLike, basePath?: string | null, makePaths = false) {\n return bindToExpress(instance, app, expressBasePath(basePath), makePaths);\n },\n\n each(fn: (key: string, value: string) => void, scope?: unknown) {\n for (const [key, value] of store.properties.entries()) {\n fn.call(scope || instance, key, value);\n }\n\n return instance;\n },\n\n entries,\n\n get(key: string) {\n return parseValue(store.properties.get(key));\n },\n\n getAllProperties() {\n return Object.fromEntries(store.properties.entries());\n },\n\n getByRoot(root: string) {\n return getByRoot(store.properties, root);\n },\n\n getRaw(key: string) {\n return store.properties.has(key) ? store.properties.get(key)! : null;\n },\n\n out() {\n return output(store.properties, allowDuplicateSections, saveSections);\n },\n\n path() {\n return propertiesPath(store.properties);\n },\n\n read(input: string | Buffer) {\n read(typeof input === 'string' ? input : input.toString(encoding), store);\n\n return instance;\n },\n\n save(destFile: string) {\n return save(destFile, instance.out());\n },\n\n set(key: string, value: string | number | boolean) {\n store.properties.set(key, String(value));\n return instance;\n },\n };\n\n return instance;\n};\n"],"mappings":"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","names":["task","sourceFile"]}