@layerfig/config
Version:
Layer and runtime-validate type-safe configs for JavaScript apps.
1 lines • 5.64 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","names":["fileExtension: string","options: ConfigBuilderOptions<T>","#options","#sources","partialConfig: Record<string, unknown>","#parser","#runtime","#slotPrefix","#configFolder","zod","source: Source","Source"],"sources":["../src/parser/define-config-parser.ts","../src/parser/parser-json.ts","../src/config-builder.ts"],"sourcesContent":["import type { Result } from \"../types\";\n\ntype ParserFunction = (\n\tfileContent: string,\n) => Result<Record<string, unknown>, Error>;\n\ninterface ConfigParserOptions {\n\tacceptedFileExtensions: string[];\n\tparse: ParserFunction;\n}\n\nexport interface ConfigParser {\n\tacceptsExtension(fileExtension: string): boolean;\n\tload: ConfigParserOptions[\"parse\"];\n\tacceptedFileExtensions: ConfigParserOptions[\"acceptedFileExtensions\"];\n}\n\nexport function defineConfigParser({\n\tacceptedFileExtensions,\n\tparse: load,\n}: ConfigParserOptions): ConfigParser {\n\treturn {\n\t\tacceptsExtension(fileExtension: string): boolean {\n\t\t\tconst ext = fileExtension.startsWith(\".\")\n\t\t\t\t? fileExtension\n\t\t\t\t: `.${fileExtension}`;\n\t\t\treturn acceptedFileExtensions.some(\n\t\t\t\t(accepted) => accepted === ext || accepted === ext.slice(1),\n\t\t\t);\n\t\t},\n\t\tacceptedFileExtensions,\n\t\tload,\n\t};\n}\n","import { defineConfigParser } from \"./define-config-parser\";\n\nexport const basicJsonParser = defineConfigParser({\n\tacceptedFileExtensions: [\"json\"],\n\tparse: (fileContent) => {\n\t\ttry {\n\t\t\tconst content = JSON.parse(fileContent);\n\n\t\t\treturn {\n\t\t\t\tok: true,\n\t\t\t\tdata: content,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror:\n\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t? error\n\t\t\t\t\t\t: new Error(\"Something went wrong while loading the file\"),\n\t\t\t};\n\t\t}\n\t},\n});\n","import { z as zod } from \"zod/v4\";\nimport type { ConfigParser } from \"./parser/define-config-parser\";\nimport { basicJsonParser } from \"./parser/parser-json\";\nimport { Source } from \"./sources/source\";\nimport { merge } from \"./utils\";\n\nexport interface ConfigBuilderOptions<\n\tT extends object = Record<string, unknown>,\n> {\n\t/**\n\t * A function to validate the configuration object.\n\t * @param config - The configuration object to be validated\n\t * @param z - The zod 4 instance\n\t */\n\tvalidate: (config: Record<string, unknown>, z: typeof zod) => T;\n\t/**\n\t * The folder where the configuration files are located.\n\t * @default \"./config\"\n\t */\n\tconfigFolder?: string;\n\t/**\n\t * Load source from different source types\n\t */\n\tparser?: ConfigParser;\n\t/**\n\t * Prefix used to search for slotted values\n\t * @default \"$\"\n\t */\n\tslotPrefix?: string;\n\t/**\n\t * The runtime environment variables to use (e.g., process.env, import.env, etc.)\n\t * @default process.env\n\t */\n\truntimeEnv?: {\n\t\t[key: string]: string | undefined;\n\t};\n}\n\nexport class ConfigBuilder<T extends object = Record<string, unknown>> {\n\t#options: ConfigBuilderOptions<T>;\n\n\t#sources: Source[] = [];\n\n\tconstructor(options: ConfigBuilderOptions<T>) {\n\t\tthis.#options = options;\n\t}\n\n\t/* Public */\n\tpublic build(): T {\n\t\tif (this.#sources.length === 0) {\n\t\t\tthrow new Error(\n\t\t\t\t\"No source was added. Please provide one by using .addSource(<source>)\",\n\t\t\t);\n\t\t}\n\n\t\tlet partialConfig: Record<string, unknown> = {};\n\n\t\tfor (const source of this.#sources) {\n\t\t\tconst data = source.loadSource({\n\t\t\t\tparser: this.#parser,\n\t\t\t\truntimeEnv: this.#runtime,\n\t\t\t\tslotPrefix: this.#slotPrefix,\n\t\t\t\trelativeConfigFolderPath: this.#configFolder,\n\t\t\t});\n\n\t\t\tpartialConfig = merge({}, partialConfig, data);\n\t\t}\n\n\t\treturn this.#options.validate(partialConfig, zod);\n\t}\n\n\tpublic addSource(source: Source): this {\n\t\tif (source instanceof Source === false) {\n\t\t\tthrow new Error(\"Invalid source. Please provide a valid one.\");\n\t\t}\n\n\t\tthis.#sources.push(source);\n\n\t\treturn this;\n\t}\n\n\t/* Private */\n\n\tget #configFolder() {\n\t\treturn this.#options.configFolder || \"./config\";\n\t}\n\n\tget #parser(): ConfigParser {\n\t\treturn this.#options.parser || basicJsonParser;\n\t}\n\n\tget #runtime() {\n\t\treturn this.#options.runtimeEnv || process.env;\n\t}\n\n\tget #slotPrefix() {\n\t\treturn this.#options.slotPrefix || \"$\";\n\t}\n}\n"],"mappings":";;;;;;AAiBA,SAAgB,mBAAmB,EAClC,wBACA,OAAO,MACc,EAAgB;AACrC,QAAO;EACN,iBAAiBA,eAAgC;GAChD,MAAM,MAAM,cAAc,WAAW,IAAI,GACtC,iBACC,GAAG,cAAc;AACrB,UAAO,uBAAuB,KAC7B,CAAC,aAAa,aAAa,OAAO,aAAa,IAAI,MAAM,EAAE,CAC3D;EACD;EACD;EACA;CACA;AACD;;;;AC/BD,MAAa,kBAAkB,mBAAmB;CACjD,wBAAwB,CAAC,MAAO;CAChC,OAAO,CAAC,gBAAgB;AACvB,MAAI;GACH,MAAM,UAAU,KAAK,MAAM,YAAY;AAEvC,UAAO;IACN,IAAI;IACJ,MAAM;GACN;EACD,SAAQ,OAAO;AACf,UAAO;IACN,IAAI;IACJ,OACC,iBAAiB,QACd,QACA,IAAI,MAAM;GACd;EACD;CACD;AACD,EAAC;;;;ACgBF,IAAa,gBAAb,MAAuE;CACtE;CAEA,WAAqB,CAAE;CAEvB,YAAYC,SAAkC;AAC7C,OAAKC,WAAW;CAChB;CAGD,AAAO,QAAW;AACjB,MAAI,KAAKC,SAAS,WAAW,EAC5B,OAAM,IAAI,MACT;EAIF,IAAIC,gBAAyC,CAAE;AAE/C,OAAK,MAAM,UAAU,KAAKD,UAAU;GACnC,MAAM,OAAO,OAAO,WAAW;IAC9B,QAAQ,KAAKE;IACb,YAAY,KAAKC;IACjB,YAAY,KAAKC;IACjB,0BAA0B,KAAKC;GAC/B,EAAC;AAEF,mBAAgB,oBAAM,CAAE,GAAE,eAAe,KAAK;EAC9C;AAED,SAAO,KAAKN,SAAS,SAAS,eAAeO,SAAI;CACjD;CAED,AAAO,UAAUC,QAAsB;AACtC,MAAI,kBAAkBC,0BAAW,MAChC,OAAM,IAAI,MAAM;AAGjB,OAAKR,SAAS,KAAK,OAAO;AAE1B,SAAO;CACP;CAID,IAAIK,gBAAgB;AACnB,SAAO,KAAKN,SAAS,gBAAgB;CACrC;CAED,IAAIG,UAAwB;AAC3B,SAAO,KAAKH,SAAS,UAAU;CAC/B;CAED,IAAII,WAAW;AACd,SAAO,KAAKJ,SAAS,cAAc,QAAQ;CAC3C;CAED,IAAIK,cAAc;AACjB,SAAO,KAAKL,SAAS,cAAc;CACnC;AACD"}