@next-box/appsettings 0.0.2 → 0.0.4
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.
- package/dist/cjs/cli/command.cjs.map +1 -0
- package/dist/cjs/cli/handler.cjs.map +1 -0
- package/dist/cjs/cli.cjs +2 -0
- package/dist/cjs/cli.cjs.map +1 -0
- package/dist/cjs/config/ConfigMerger.cjs.map +1 -0
- package/dist/cjs/config/ConfigValidator.cjs.map +1 -0
- package/dist/cjs/config/createAppSettings.cjs.map +1 -0
- package/dist/cjs/sources/AppSettingsSource.cjs.map +1 -0
- package/dist/cjs/sources/EnvironmentSource.cjs.map +1 -0
- package/dist/cjs/sources/MemorySource.cjs.map +1 -0
- package/dist/cjs/sources/RemoteSource.cjs.map +1 -0
- package/dist/cjs/sources/helpers/loadJson.cjs.map +1 -0
- package/dist/esm/cli/command.mjs.map +1 -0
- package/dist/esm/cli/handler.mjs.map +1 -0
- package/dist/esm/cli.mjs +2 -0
- package/dist/esm/cli.mjs.map +1 -0
- package/dist/esm/config/ConfigMerger.mjs.map +1 -0
- package/dist/esm/config/ConfigValidator.mjs.map +1 -0
- package/dist/esm/config/createAppSettings.mjs.map +1 -0
- package/dist/esm/sources/AppSettingsSource.mjs.map +1 -0
- package/dist/esm/sources/EnvironmentSource.mjs.map +1 -0
- package/dist/esm/sources/MemorySource.mjs.map +1 -0
- package/dist/esm/sources/RemoteSource.mjs.map +1 -0
- package/dist/esm/sources/helpers/loadJson.mjs.map +1 -0
- package/dist/types/{esm/cli/index.d.ts → cjs/cli.d.cts} +1 -1
- package/dist/types/cjs/cli.d.cts.map +1 -0
- package/dist/types/{cjs/cli/index.d.cts → esm/cli.d.ts} +1 -1
- package/dist/types/esm/cli.d.ts.map +1 -0
- package/dist/types/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/rollup.config.mjs +2 -10
- package/src/{cli/index.test.ts → cli.test.ts} +1 -1
- package/src/{cli/index.ts → cli.ts} +1 -1
- package/dist/cjs/cli/cli/command.cjs.map +0 -1
- package/dist/cjs/cli/cli/handler.cjs.map +0 -1
- package/dist/cjs/cli/cli/index.cjs +0 -2
- package/dist/cjs/cli/cli/index.cjs.map +0 -1
- package/dist/cjs/server/config/ConfigMerger.cjs.map +0 -1
- package/dist/cjs/server/config/ConfigValidator.cjs.map +0 -1
- package/dist/cjs/server/config/createAppSettings.cjs.map +0 -1
- package/dist/cjs/server/sources/AppSettingsSource.cjs.map +0 -1
- package/dist/cjs/server/sources/EnvironmentSource.cjs.map +0 -1
- package/dist/cjs/server/sources/MemorySource.cjs.map +0 -1
- package/dist/cjs/server/sources/RemoteSource.cjs.map +0 -1
- package/dist/cjs/server/sources/helpers/loadJson.cjs.map +0 -1
- package/dist/esm/cli/cli/command.mjs.map +0 -1
- package/dist/esm/cli/cli/handler.mjs.map +0 -1
- package/dist/esm/cli/cli/index.mjs +0 -2
- package/dist/esm/cli/cli/index.mjs.map +0 -1
- package/dist/esm/server/config/ConfigMerger.mjs.map +0 -1
- package/dist/esm/server/config/ConfigValidator.mjs.map +0 -1
- package/dist/esm/server/config/createAppSettings.mjs.map +0 -1
- package/dist/esm/server/sources/AppSettingsSource.mjs.map +0 -1
- package/dist/esm/server/sources/EnvironmentSource.mjs.map +0 -1
- package/dist/esm/server/sources/MemorySource.mjs.map +0 -1
- package/dist/esm/server/sources/RemoteSource.mjs.map +0 -1
- package/dist/esm/server/sources/helpers/loadJson.mjs.map +0 -1
- package/dist/types/cjs/cli/index.d.cts.map +0 -1
- package/dist/types/esm/cli/index.d.ts.map +0 -1
- /package/dist/cjs/cli/{cli/command.cjs → command.cjs} +0 -0
- /package/dist/cjs/cli/{cli/handler.cjs → handler.cjs} +0 -0
- /package/dist/cjs/{server/config → config}/ConfigMerger.cjs +0 -0
- /package/dist/cjs/{server/config → config}/ConfigValidator.cjs +0 -0
- /package/dist/cjs/{server/config → config}/createAppSettings.cjs +0 -0
- /package/dist/cjs/{server/server.cjs → server.cjs} +0 -0
- /package/dist/cjs/{server/server.cjs.map → server.cjs.map} +0 -0
- /package/dist/cjs/{server/sources → sources}/AppSettingsSource.cjs +0 -0
- /package/dist/cjs/{server/sources → sources}/EnvironmentSource.cjs +0 -0
- /package/dist/cjs/{server/sources → sources}/MemorySource.cjs +0 -0
- /package/dist/cjs/{server/sources → sources}/RemoteSource.cjs +0 -0
- /package/dist/cjs/{server/sources → sources}/helpers/loadJson.cjs +0 -0
- /package/dist/esm/cli/{cli/command.mjs → command.mjs} +0 -0
- /package/dist/esm/cli/{cli/handler.mjs → handler.mjs} +0 -0
- /package/dist/esm/{server/config → config}/ConfigMerger.mjs +0 -0
- /package/dist/esm/{server/config → config}/ConfigValidator.mjs +0 -0
- /package/dist/esm/{server/config → config}/createAppSettings.mjs +0 -0
- /package/dist/esm/{server/server.mjs → server.mjs} +0 -0
- /package/dist/esm/{server/server.mjs.map → server.mjs.map} +0 -0
- /package/dist/esm/{server/sources → sources}/AppSettingsSource.mjs +0 -0
- /package/dist/esm/{server/sources → sources}/EnvironmentSource.mjs +0 -0
- /package/dist/esm/{server/sources → sources}/MemorySource.mjs +0 -0
- /package/dist/esm/{server/sources → sources}/RemoteSource.mjs +0 -0
- /package/dist/esm/{server/sources → sources}/helpers/loadJson.mjs +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.cjs","sources":["../../../src/cli/command.ts"],"sourcesContent":["import { type CommandBuilder } from 'yargs';\nimport { type GenerateTypesArguments } from '#cli/handler.ts';\n\nexport const builder: CommandBuilder<object, GenerateTypesArguments> = yargs =>\n yargs\n .positional('schema', {\n demandOption: true,\n describe: 'TypeScript module that exports the inferred settings type.',\n type: 'string',\n })\n .positional('output', {\n default: 'appsettings.generated.d.ts',\n describe: 'Declaration file to generate.',\n type: 'string',\n })\n .option('type', {\n default: 'AppSettingsConfig',\n describe: 'Exported type name.',\n type: 'string',\n })\n .check(({ type }) => {\n if (!/^[A-Za-z_$][\\w$]*$/u.test(type)) {\n throw new Error('--type must be a TypeScript identifier.');\n }\n\n return true;\n });\n\nexport const command = 'generate-types <schema> <output>';\n\nexport const describe = 'Generate a declaration that types appsettings hooks from your schema.';\n\nexport { handler } from './handler.ts';\n"],"names":["yargs","positional","demandOption","describe","type","default","option","check","test","Error"],"mappings":"sFAGuEA,GACrEA,EACGC,WAAW,SAAU,CACpBC,cAAc,EACdC,SAAU,6DACVC,KAAM,WAEPH,WAAW,SAAU,CACpBI,QAAS,6BACTF,SAAU,gCACVC,KAAM,WAEPE,OAAO,OAAQ,CACdD,QAAS,oBACTF,SAAU,sBACVC,KAAM,WAEPG,MAAM,EAAGH,WACR,IAAK,sBAAsBI,KAAKJ,GAC9B,MAAM,IAAIK,MAAM,2CAGlB,OAAO,oBAGU,oDAEC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.cjs","sources":["../../../src/cli/handler.ts"],"sourcesContent":["import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname, relative, resolve, sep } from 'node:path';\n\nconst createModuleSpecifier = (path: string): string => {\n let specifier = path\n .split(sep)\n .join('/')\n .replace(/\\.(?:[cm]?tsx?)$/u, '');\n\n if (!specifier.startsWith('.')) {\n specifier = `./${specifier}`;\n }\n\n return specifier;\n};\n\nconst isMissingFile = (error: unknown): boolean =>\n !!error && typeof error === 'object' && 'code' in error && error.code === 'ENOENT';\n\nexport interface GenerateTypesArguments {\n output: string;\n schema: string;\n type: string;\n}\n\nexport const handler = async ({ output, schema, type }: GenerateTypesArguments): Promise<void> => {\n const schemaPath = resolve(process.cwd(), schema);\n const outputPath = resolve(process.cwd(), output);\n const schemaImportPath = createModuleSpecifier(relative(dirname(outputPath), schemaPath));\n\n const contents = [\n `import type { ${type} } from '${schemaImportPath}';`,\n '',\n \"declare module '@next-box/appsettings' {\",\n ` interface AppSettingsSchema extends ${type} {}`,\n '}',\n '',\n 'export {};',\n '',\n ].join('\\n');\n\n let existingContents: string | undefined;\n\n try {\n existingContents = await readFile(outputPath, 'utf8');\n } catch (error) {\n if (!isMissingFile(error)) {\n throw error;\n }\n }\n\n if (existingContents !== contents) {\n await mkdir(dirname(outputPath), { recursive: true });\n await writeFile(outputPath, contents, 'utf8');\n }\n\n process.stdout.write(`Generated ${relative(process.cwd(), outputPath)}\\n`);\n};\n"],"names":["async","output","schema","type","schemaPath","resolve","process","cwd","outputPath","contents","path","specifier","split","sep","join","replace","startsWith","createModuleSpecifier","relative","dirname","existingContents","readFile","error","code","isMissingFile","mkdir","recursive","writeFile","stdout","write"],"mappings":"sFAyBuBA,OAASC,SAAQC,SAAQC,WAC9C,MAAMC,EAAaC,EAAAA,QAAQC,QAAQC,MAAOL,GACpCM,EAAaH,EAAAA,QAAQC,QAAQC,MAAON,GAGpCQ,EAAW,CACf,iBAAiBN,aA5BS,CAACO,IAC7B,IAAIC,EAAYD,EACbE,MAAMC,OACNC,KAAK,KACLC,QAAQ,oBAAqB,IAMhC,OAJKJ,EAAUK,WAAW,OACxBL,EAAY,KAAKA,KAGZA,GAekBM,CAAsBC,EAAAA,SAASC,EAAAA,QAAQX,GAAaJ,QAI3E,GACA,2CACA,yCAAyCD,OACzC,IACA,GACA,aACA,IACAW,KAAK,MAEP,IAAIM,EAEJ,IACEA,QAAyBC,EAAAA,SAASb,EAAY,OAChD,CAAE,MAAOc,GACP,IA9BkB,CAACA,KACnBA,GAA0B,iBAAVA,GAAsB,SAAUA,GAAwB,WAAfA,EAAMC,KA6B1DC,CAAcF,GACjB,MAAMA,CAEV,CAEIF,IAAqBX,UACjBgB,EAAAA,MAAMN,UAAQX,GAAa,CAAEkB,WAAW,UACxCC,YAAUnB,EAAYC,EAAU,SAGxCH,QAAQsB,OAAOC,MAAM,aAAaX,EAAAA,SAASZ,QAAQC,MAAOC"}
|
package/dist/cjs/cli.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var e=require("yargs"),r=require("yargs/helpers"),s=require("./cli/command.cjs");exports.runAppsettingsCli=async()=>{await e(r.hideBin(process.argv)).scriptName("appsettings").command(s).demandCommand(1,"Choose a command to run.").strict().help().parseAsync()};
|
|
2
|
+
//# sourceMappingURL=cli.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.cjs","sources":["../../src/cli.ts"],"sourcesContent":["import yargs from 'yargs';\nimport { hideBin } from 'yargs/helpers';\nimport * as generateTypesCommand from './cli/command.ts';\n\nexport const runAppsettingsCli = async (): Promise<void> => {\n await yargs(hideBin(process.argv))\n .scriptName('appsettings')\n .command(generateTypesCommand)\n .demandCommand(1, 'Choose a command to run.')\n .strict()\n .help()\n .parseAsync();\n};\n"],"names":["async","yargs","hideBin","process","argv","scriptName","command","generateTypesCommand","demandCommand","strict","help","parseAsync"],"mappings":"wHAIiCA,gBACzBC,EAAMC,EAAAA,QAAQC,QAAQC,OACzBC,WAAW,eACXC,QAAQC,GACRC,cAAc,EAAG,4BACjBC,SACAC,OACAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConfigMerger.cjs","sources":["../../../src/config/ConfigMerger.ts"],"sourcesContent":["import { mergeDeep } from 'remeda';\n\nexport class ConfigMerger {\n merge<T extends object>(first: T, ...configs: readonly T[]): T {\n // TypeScript cannot guarantee that merging arbitrary objects produces T\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return configs.reduce((merged, config) => mergeDeep(merged, config) as T, first);\n }\n}\n"],"names":["merge","first","configs","reduce","merged","config","mergeDeep"],"mappings":"0DAEO,MACLA,KAAAA,CAAwBC,KAAaC,GAGnC,OAAOA,EAAQC,OAAO,CAACC,EAAQC,IAAWC,EAAAA,UAAUF,EAAQC,GAAcJ,EAC5E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConfigValidator.cjs","sources":["../../../src/config/ConfigValidator.ts"],"sourcesContent":["import { type ZodType, type output } from 'zod';\n\nexport class ConfigValidator<T extends ZodType> {\n private readonly schema: T;\n\n constructor(schema: T) {\n this.schema = schema;\n }\n\n validate(value: unknown): output<T> {\n return this.schema.parse(value);\n }\n}\n"],"names":["constructor","schema","this","validate","value","parse"],"mappings":"qCAEO,MAGL,WAAAA,CAAYC,GACVC,KAAKD,OAASA,CAChB,CAEAE,QAAAA,CAASC,GACP,OAAOF,KAAKD,OAAOI,MAAMD,EAC3B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createAppSettings.cjs","sources":["../../../src/config/createAppSettings.ts"],"sourcesContent":["import { type CreateAppSettingsOptions } from '#types/AppSettings.types.ts';\nimport { ConfigMerger } from './ConfigMerger.ts';\nimport { ConfigValidator } from './ConfigValidator.ts';\n\nexport const createAppSettings = async <T extends object>({\n defaults,\n schema,\n sources = [],\n}: CreateAppSettingsOptions<T>): Promise<Readonly<T>> => {\n const loadedSources: Record<string, unknown>[] = [];\n\n for (const source of sources) {\n loadedSources.push(await source.load());\n }\n\n const merged = new ConfigMerger().merge(defaults, ...loadedSources);\n return new ConfigValidator(schema).validate(merged);\n};\n"],"names":["async","defaults","schema","sources","loadedSources","source","push","load","merged","ConfigMerger","merge","ConfigValidator","validate"],"mappings":"8GAIiCA,OAC/BC,WACAC,SACAC,UAAU,OAEV,MAAMC,EAA2C,GAEjD,IAAK,MAAMC,KAAUF,EACnBC,EAAcE,WAAWD,EAAOE,QAGlC,MAAMC,GAAS,IAAIC,EAAAA,cAAeC,MAAMT,KAAaG,GACrD,OAAO,IAAIO,EAAAA,gBAAgBT,GAAQU,SAASJ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppSettingsSource.cjs","sources":["../../../src/sources/AppSettingsSource.ts"],"sourcesContent":["import { resolve } from 'node:path';\nimport { ConfigMerger } from '#config/ConfigMerger.ts';\nimport { loadJson } from '#sources/helpers/loadJson.ts';\nimport { type SettingsSource } from '../types/Source.types.ts';\n\nexport interface AppSettingsSourceOptions {\n directory?: string;\n environment?: string;\n name?: string;\n}\n\nexport class AppSettingsSource implements SettingsSource {\n private directory: string;\n private environment: string;\n public name: string;\n\n public constructor(options: AppSettingsSourceOptions) {\n this.directory = options.directory ?? process.cwd();\n this.environment = options.environment ?? process.env.NODE_ENV ?? 'development';\n this.name = options.name ?? `appsettings:${this.environment}`;\n }\n\n async load(): Promise<Record<string, unknown>> {\n const basePath = resolve(this.directory, 'appsettings.json');\n const environmentPath = resolve(this.directory, `appsettings.${this.environment}.json`);\n const base = await loadJson(basePath, false);\n const override = (await loadJson(environmentPath, true)) ?? {};\n return new ConfigMerger().merge(base, override);\n }\n}\n"],"names":["constructor","options","this","directory","process","cwd","environment","env","NODE_ENV","name","load","basePath","resolve","environmentPath","base","loadJson","override","ConfigMerger","merge"],"mappings":"8IAWO,MAKL,WAAAA,CAAmBC,GACjBC,KAAKC,UAAYF,EAAQE,WAAaC,QAAQC,MAC9CH,KAAKI,YAAcL,EAAQK,aAAeF,QAAQG,IAAIC,UAAY,cAClEN,KAAKO,KAAOR,EAAQQ,MAAQ,eAAeP,KAAKI,aAClD,CAEA,UAAMI,GACJ,MAAMC,EAAWC,EAAAA,QAAQV,KAAKC,UAAW,oBACnCU,EAAkBD,UAAQV,KAAKC,UAAW,eAAeD,KAAKI,oBAC9DQ,QAAaC,WAASJ,GAAU,GAChCK,QAAkBD,EAAAA,SAASF,GAAiB,IAAU,CAAA,EAC5D,OAAO,IAAII,EAAAA,cAAeC,MAAMJ,EAAME,EACxC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EnvironmentSource.cjs","sources":["../../../src/sources/EnvironmentSource.ts"],"sourcesContent":["import { capitalize, isPlainObject } from 'remeda';\nimport { type SettingsSource } from '../types/Source.types.ts';\n\nexport interface EnvironmentSourceOptions {\n envs: Record<string, string | undefined>;\n name?: string;\n prefix?: string;\n}\n\nexport class EnvironmentSource implements SettingsSource {\n private readonly envs: Record<string, string | undefined>;\n private readonly prefix: string;\n\n private normalizeSegment = (value: string): string =>\n value\n .toLowerCase()\n .split('_')\n .filter(Boolean)\n .map(part => capitalize(part))\n .join('');\n\n public readonly name: string;\n\n public constructor(options: EnvironmentSourceOptions) {\n this.envs = options.envs;\n this.prefix = options.prefix ?? 'APP_';\n this.name = options.name ?? `environment:${this.prefix}`;\n }\n\n private parseEnvironmentValue(value: string): unknown {\n if (value === 'true') {\n return true;\n }\n\n if (value === 'false') {\n return false;\n }\n\n if (value.trim() !== '' && Number.isFinite(Number(value))) {\n return Number(value);\n }\n\n return value;\n }\n\n load(): Promise<Record<string, unknown>> {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(this.envs)) {\n if (value === undefined || !key.startsWith(this.prefix)) {\n continue;\n }\n\n const path = key\n .slice(this.prefix.length)\n .split('__')\n .filter(Boolean)\n .map(part => this.normalizeSegment(part));\n\n const leaf = path.pop();\n\n if (!leaf) {\n continue;\n }\n\n let current = result;\n\n for (const part of path) {\n const next = current[part];\n\n if (!isPlainObject(next)) {\n current[part] = {};\n }\n\n const currentPart = current[part];\n\n if (isPlainObject(currentPart)) {\n current = currentPart;\n }\n }\n\n current[leaf] = this.parseEnvironmentValue(value);\n }\n\n return Promise.resolve(result);\n }\n}\n"],"names":["constructor","options","normalizeSegment","value","toLowerCase","split","filter","Boolean","map","part","capitalize","join","this","envs","prefix","name","parseEnvironmentValue","trim","Number","isFinite","load","result","key","Object","entries","undefined","startsWith","path","slice","length","leaf","pop","current","next","isPlainObject","currentPart","Promise","resolve"],"mappings":"+DASO,MAcL,WAAAA,CAAmBC,GAVXC,KAAAA,iBAAoBC,GAC1BA,EACGC,cACAC,MAAM,KACNC,OAAOC,SACPC,IAAIC,GAAQC,EAAAA,WAAWD,IACvBE,KAAK,IAKRC,KAAKC,KAAOZ,EAAQY,KACpBD,KAAKE,OAASb,EAAQa,QAAU,OAChCF,KAAKG,KAAOd,EAAQc,MAAQ,eAAeH,KAAKE,QAClD,CAEQE,qBAAAA,CAAsBb,GAC5B,MAAc,SAAVA,GAIU,UAAVA,IAIiB,KAAjBA,EAAMc,QAAiBC,OAAOC,SAASD,OAAOf,IACzCe,OAAOf,GAGTA,EACT,CAEAiB,IAAAA,GACE,MAAMC,EAAkC,CAAA,EAExC,IAAK,MAAOC,EAAKnB,KAAUoB,OAAOC,QAAQZ,KAAKC,MAAO,CACpD,QAAcY,IAAVtB,IAAwBmB,EAAII,WAAWd,KAAKE,QAC9C,SAGF,MAAMa,EAAOL,EACVM,MAAMhB,KAAKE,OAAOe,QAClBxB,MAAM,MACNC,OAAOC,SACPC,IAAIC,GAAQG,KAAKV,iBAAiBO,IAE/BqB,EAAOH,EAAKI,MAElB,IAAKD,EACH,SAGF,IAAIE,EAAUX,EAEd,IAAK,MAAMZ,KAAQkB,EAAM,CACvB,MAAMM,EAAOD,EAAQvB,GAEhByB,EAAAA,cAAcD,KACjBD,EAAQvB,GAAQ,CAAA,GAGlB,MAAM0B,EAAcH,EAAQvB,GAExByB,EAAAA,cAAcC,KAChBH,EAAUG,EAEd,CAEAH,EAAQF,GAAQlB,KAAKI,sBAAsBb,EAC7C,CAEA,OAAOiC,QAAQC,QAAQhB,EACzB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MemorySource.cjs","sources":["../../../src/sources/MemorySource.ts"],"sourcesContent":["import { clone } from 'remeda';\nimport { type SettingsSource } from '../types/Source.types.ts';\n\nexport interface MemorySourceOptions {\n name?: string;\n values: Record<string, unknown>;\n}\n\nexport class MemorySource implements SettingsSource {\n private readonly values: Record<string, unknown>;\n public readonly name: string;\n\n public constructor(options: MemorySourceOptions) {\n this.name = options.name ?? 'memory';\n this.values = options.values;\n }\n\n load(): Promise<Record<string, unknown>> {\n return Promise.resolve(clone(this.values));\n }\n}\n"],"names":["constructor","options","this","name","values","load","Promise","resolve","clone"],"mappings":"0DAQO,MAIL,WAAAA,CAAmBC,GACjBC,KAAKC,KAAOF,EAAQE,MAAQ,SAC5BD,KAAKE,OAASH,EAAQG,MACxB,CAEAC,IAAAA,GACE,OAAOC,QAAQC,QAAQC,EAAAA,MAAMN,KAAKE,QACpC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RemoteSource.cjs","sources":["../../../src/sources/RemoteSource.ts"],"sourcesContent":["import { isObjectType, isPlainObject, prop, stringToPath } from 'remeda';\nimport { type SettingsSource } from '#types/Source.types.ts';\n\nexport interface RemoteSourceOptions {\n fetch: typeof globalThis.fetch;\n name?: string;\n responsePath?: string;\n url: string;\n}\n\nexport class RemoteSource implements SettingsSource {\n private fetch: typeof globalThis.fetch;\n private responsePath?: string;\n private url: string;\n public name: string;\n\n public constructor(options: RemoteSourceOptions) {\n this.fetch = options.fetch;\n this.url = options.url;\n this.name = options.name ?? `remote:${this.url}`;\n this.responsePath = options.responsePath;\n }\n\n async load(): Promise<Record<string, unknown>> {\n if (typeof this.fetch !== 'function') {\n throw new TypeError('RemoteSource requires fetch, which is unavailable in this runtime.');\n }\n\n const response = await this.fetch(this.url);\n\n if (!response.ok) {\n throw new Error(`Failed to load settings from \"${this.url}\": ${String(response.status)} ${response.statusText}`);\n }\n\n let value: unknown = await response.json();\n\n if (this.responsePath && !isObjectType(value)) {\n throw new Error(`Fetched value must be an object type if response path is provided, but was ${typeof value}.`);\n }\n\n // @ts-expect-error Unable to statically type string literal\n value = this.responsePath ? prop(value, ...stringToPath(this.responsePath)) : value;\n\n if (!isPlainObject(value)) {\n throw new Error(`JSON settings from \"${this.url}\" must contain an object at the root.`);\n }\n\n return value;\n }\n}\n"],"names":["constructor","options","this","fetch","url","name","responsePath","load","TypeError","response","ok","Error","String","status","statusText","value","json","isObjectType","prop","stringToPath","isPlainObject"],"mappings":"0DAUO,MAML,WAAAA,CAAmBC,GACjBC,KAAKC,MAAQF,EAAQE,MACrBD,KAAKE,IAAMH,EAAQG,IACnBF,KAAKG,KAAOJ,EAAQI,MAAQ,UAAUH,KAAKE,MAC3CF,KAAKI,aAAeL,EAAQK,YAC9B,CAEA,UAAMC,GACJ,GAA0B,mBAAfL,KAAKC,MACd,MAAM,IAAIK,UAAU,sEAGtB,MAAMC,QAAiBP,KAAKC,MAAMD,KAAKE,KAEvC,IAAKK,EAASC,GACZ,MAAM,IAAIC,MAAM,iCAAiCT,KAAKE,SAASQ,OAAOH,EAASI,WAAWJ,EAASK,cAGrG,IAAIC,QAAuBN,EAASO,OAEpC,GAAId,KAAKI,eAAiBW,EAAAA,aAAaF,GACrC,MAAM,IAAIJ,MAAM,qFAAqFI,MAMvG,GAFAA,EAAQb,KAAKI,aAAeY,OAAKH,KAAUI,EAAAA,aAAajB,KAAKI,eAAiBS,GAEzEK,EAAAA,cAAcL,GACjB,MAAM,IAAIJ,MAAM,uBAAuBT,KAAKE,4CAG9C,OAAOW,CACT"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadJson.cjs","sources":["../../../../src/sources/helpers/loadJson.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { isPlainObject } from 'remeda';\n\nexport function loadJson(path: string, isOptional: false): Promise<Record<string, unknown>>;\nexport function loadJson(path: string, isOptional: true): Promise<Record<string, unknown> | undefined>;\n\n// Required for overloads\n// eslint-disable-next-line prefer-arrow/prefer-arrow-functions\nexport async function loadJson(path: string, isOptional: boolean): Promise<Record<string, unknown> | undefined> {\n let contents: string;\n\n try {\n contents = await readFile(path, 'utf8');\n } catch (error) {\n if (isOptional && typeof error === 'object' && error !== null && 'code' in error && error.code === 'ENOENT') {\n return undefined;\n }\n\n throw error;\n }\n\n const value: unknown = JSON.parse(contents);\n\n if (!isPlainObject(value)) {\n throw new Error(`JSON settings from \"${path}\" must contain an object at the root.`);\n }\n\n return value;\n}\n"],"names":["async","path","isOptional","contents","readFile","error","code","value","JSON","parse","isPlainObject","Error"],"mappings":"oFAQOA,eAAwBC,EAAcC,GAC3C,IAAIC,EAEJ,IACEA,QAAiBC,EAAAA,SAASH,EAAM,OAClC,CAAE,MAAOI,GACP,GAAIH,GAA+B,iBAAVG,GAAgC,OAAVA,GAAkB,SAAUA,GAAwB,WAAfA,EAAMC,KACxF,OAGF,MAAMD,CACR,CAEA,MAAME,EAAiBC,KAAKC,MAAMN,GAElC,IAAKO,EAAAA,cAAcH,GACjB,MAAM,IAAII,MAAM,uBAAuBV,0CAGzC,OAAOM,CACT"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.mjs","sources":["../../../src/cli/command.ts"],"sourcesContent":["import { type CommandBuilder } from 'yargs';\nimport { type GenerateTypesArguments } from '#cli/handler.ts';\n\nexport const builder: CommandBuilder<object, GenerateTypesArguments> = yargs =>\n yargs\n .positional('schema', {\n demandOption: true,\n describe: 'TypeScript module that exports the inferred settings type.',\n type: 'string',\n })\n .positional('output', {\n default: 'appsettings.generated.d.ts',\n describe: 'Declaration file to generate.',\n type: 'string',\n })\n .option('type', {\n default: 'AppSettingsConfig',\n describe: 'Exported type name.',\n type: 'string',\n })\n .check(({ type }) => {\n if (!/^[A-Za-z_$][\\w$]*$/u.test(type)) {\n throw new Error('--type must be a TypeScript identifier.');\n }\n\n return true;\n });\n\nexport const command = 'generate-types <schema> <output>';\n\nexport const describe = 'Generate a declaration that types appsettings hooks from your schema.';\n\nexport { handler } from './handler.ts';\n"],"names":["builder","yargs","positional","demandOption","describe","type","default","option","check","test","Error","command"],"mappings":"yCAGaA,EAA0DC,GACrEA,EACGC,WAAW,SAAU,CACpBC,cAAc,EACdC,SAAU,6DACVC,KAAM,WAEPH,WAAW,SAAU,CACpBI,QAAS,6BACTF,SAAU,gCACVC,KAAM,WAEPE,OAAO,OAAQ,CACdD,QAAS,oBACTF,SAAU,sBACVC,KAAM,WAEPG,MAAM,EAAGH,WACR,IAAK,sBAAsBI,KAAKJ,GAC9B,MAAM,IAAIK,MAAM,2CAGlB,OAAO,IAGAC,EAAU,mCAEVP,EAAW"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.mjs","sources":["../../../src/cli/handler.ts"],"sourcesContent":["import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname, relative, resolve, sep } from 'node:path';\n\nconst createModuleSpecifier = (path: string): string => {\n let specifier = path\n .split(sep)\n .join('/')\n .replace(/\\.(?:[cm]?tsx?)$/u, '');\n\n if (!specifier.startsWith('.')) {\n specifier = `./${specifier}`;\n }\n\n return specifier;\n};\n\nconst isMissingFile = (error: unknown): boolean =>\n !!error && typeof error === 'object' && 'code' in error && error.code === 'ENOENT';\n\nexport interface GenerateTypesArguments {\n output: string;\n schema: string;\n type: string;\n}\n\nexport const handler = async ({ output, schema, type }: GenerateTypesArguments): Promise<void> => {\n const schemaPath = resolve(process.cwd(), schema);\n const outputPath = resolve(process.cwd(), output);\n const schemaImportPath = createModuleSpecifier(relative(dirname(outputPath), schemaPath));\n\n const contents = [\n `import type { ${type} } from '${schemaImportPath}';`,\n '',\n \"declare module '@next-box/appsettings' {\",\n ` interface AppSettingsSchema extends ${type} {}`,\n '}',\n '',\n 'export {};',\n '',\n ].join('\\n');\n\n let existingContents: string | undefined;\n\n try {\n existingContents = await readFile(outputPath, 'utf8');\n } catch (error) {\n if (!isMissingFile(error)) {\n throw error;\n }\n }\n\n if (existingContents !== contents) {\n await mkdir(dirname(outputPath), { recursive: true });\n await writeFile(outputPath, contents, 'utf8');\n }\n\n process.stdout.write(`Generated ${relative(process.cwd(), outputPath)}\\n`);\n};\n"],"names":["handler","async","output","schema","type","schemaPath","resolve","process","cwd","outputPath","contents","path","specifier","split","sep","join","replace","startsWith","createModuleSpecifier","relative","dirname","existingContents","readFile","error","code","isMissingFile","mkdir","recursive","writeFile","stdout","write"],"mappings":"8IAGA,MAsBaA,EAAUC,OAASC,SAAQC,SAAQC,WAC9C,MAAMC,EAAaC,EAAQC,QAAQC,MAAOL,GACpCM,EAAaH,EAAQC,QAAQC,MAAON,GAGpCQ,EAAW,CACf,iBAAiBN,aA5BS,CAACO,IAC7B,IAAIC,EAAYD,EACbE,MAAMC,GACNC,KAAK,KACLC,QAAQ,oBAAqB,IAMhC,OAJKJ,EAAUK,WAAW,OACxBL,EAAY,KAAKA,KAGZA,GAekBM,CAAsBC,EAASC,EAAQX,GAAaJ,QAI3E,GACA,2CACA,yCAAyCD,OACzC,IACA,GACA,aACA,IACAW,KAAK,MAEP,IAAIM,EAEJ,IACEA,QAAyBC,EAASb,EAAY,OAChD,CAAE,MAAOc,GACP,IA9BkB,CAACA,KACnBA,GAA0B,iBAAVA,GAAsB,SAAUA,GAAwB,WAAfA,EAAMC,KA6B1DC,CAAcF,GACjB,MAAMA,CAEV,CAEIF,IAAqBX,UACjBgB,EAAMN,EAAQX,GAAa,CAAEkB,WAAW,UACxCC,EAAUnB,EAAYC,EAAU,SAGxCH,QAAQsB,OAAOC,MAAM,aAAaX,EAASZ,QAAQC,MAAOC"}
|
package/dist/esm/cli.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import m from"yargs";import{hideBin as a}from"yargs/helpers";import*as o from"./cli/command.mjs";const r=async()=>{await m(a(process.argv)).scriptName("appsettings").command(o).demandCommand(1,"Choose a command to run.").strict().help().parseAsync()};export{r as runAppsettingsCli};
|
|
2
|
+
//# sourceMappingURL=cli.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.mjs","sources":["../../src/cli.ts"],"sourcesContent":["import yargs from 'yargs';\nimport { hideBin } from 'yargs/helpers';\nimport * as generateTypesCommand from './cli/command.ts';\n\nexport const runAppsettingsCli = async (): Promise<void> => {\n await yargs(hideBin(process.argv))\n .scriptName('appsettings')\n .command(generateTypesCommand)\n .demandCommand(1, 'Choose a command to run.')\n .strict()\n .help()\n .parseAsync();\n};\n"],"names":["runAppsettingsCli","async","yargs","hideBin","process","argv","scriptName","command","generateTypesCommand","demandCommand","strict","help","parseAsync"],"mappings":"uGAIaA,EAAoBC,gBACzBC,EAAMC,EAAQC,QAAQC,OACzBC,WAAW,eACXC,QAAQC,GACRC,cAAc,EAAG,4BACjBC,SACAC,OACAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConfigMerger.mjs","sources":["../../../src/config/ConfigMerger.ts"],"sourcesContent":["import { mergeDeep } from 'remeda';\n\nexport class ConfigMerger {\n merge<T extends object>(first: T, ...configs: readonly T[]): T {\n // TypeScript cannot guarantee that merging arbitrary objects produces T\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return configs.reduce((merged, config) => mergeDeep(merged, config) as T, first);\n }\n}\n"],"names":["ConfigMerger","merge","first","configs","reduce","merged","config","mergeDeep"],"mappings":"mCAEO,MAAMA,EACXC,KAAAA,CAAwBC,KAAaC,GAGnC,OAAOA,EAAQC,OAAO,CAACC,EAAQC,IAAWC,EAAUF,EAAQC,GAAcJ,EAC5E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConfigValidator.mjs","sources":["../../../src/config/ConfigValidator.ts"],"sourcesContent":["import { type ZodType, type output } from 'zod';\n\nexport class ConfigValidator<T extends ZodType> {\n private readonly schema: T;\n\n constructor(schema: T) {\n this.schema = schema;\n }\n\n validate(value: unknown): output<T> {\n return this.schema.parse(value);\n }\n}\n"],"names":["ConfigValidator","constructor","schema","this","validate","value","parse"],"mappings":"AAEO,MAAMA,EAGX,WAAAC,CAAYC,GACVC,KAAKD,OAASA,CAChB,CAEAE,QAAAA,CAASC,GACP,OAAOF,KAAKD,OAAOI,MAAMD,EAC3B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createAppSettings.mjs","sources":["../../../src/config/createAppSettings.ts"],"sourcesContent":["import { type CreateAppSettingsOptions } from '#types/AppSettings.types.ts';\nimport { ConfigMerger } from './ConfigMerger.ts';\nimport { ConfigValidator } from './ConfigValidator.ts';\n\nexport const createAppSettings = async <T extends object>({\n defaults,\n schema,\n sources = [],\n}: CreateAppSettingsOptions<T>): Promise<Readonly<T>> => {\n const loadedSources: Record<string, unknown>[] = [];\n\n for (const source of sources) {\n loadedSources.push(await source.load());\n }\n\n const merged = new ConfigMerger().merge(defaults, ...loadedSources);\n return new ConfigValidator(schema).validate(merged);\n};\n"],"names":["createAppSettings","async","defaults","schema","sources","loadedSources","source","push","load","merged","ConfigMerger","merge","ConfigValidator","validate"],"mappings":"0GAIO,MAAMA,EAAoBC,OAC/BC,WACAC,SACAC,UAAU,OAEV,MAAMC,EAA2C,GAEjD,IAAK,MAAMC,KAAUF,EACnBC,EAAcE,WAAWD,EAAOE,QAGlC,MAAMC,GAAS,IAAIC,GAAeC,MAAMT,KAAaG,GACrD,OAAO,IAAIO,EAAgBT,GAAQU,SAASJ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppSettingsSource.mjs","sources":["../../../src/sources/AppSettingsSource.ts"],"sourcesContent":["import { resolve } from 'node:path';\nimport { ConfigMerger } from '#config/ConfigMerger.ts';\nimport { loadJson } from '#sources/helpers/loadJson.ts';\nimport { type SettingsSource } from '../types/Source.types.ts';\n\nexport interface AppSettingsSourceOptions {\n directory?: string;\n environment?: string;\n name?: string;\n}\n\nexport class AppSettingsSource implements SettingsSource {\n private directory: string;\n private environment: string;\n public name: string;\n\n public constructor(options: AppSettingsSourceOptions) {\n this.directory = options.directory ?? process.cwd();\n this.environment = options.environment ?? process.env.NODE_ENV ?? 'development';\n this.name = options.name ?? `appsettings:${this.environment}`;\n }\n\n async load(): Promise<Record<string, unknown>> {\n const basePath = resolve(this.directory, 'appsettings.json');\n const environmentPath = resolve(this.directory, `appsettings.${this.environment}.json`);\n const base = await loadJson(basePath, false);\n const override = (await loadJson(environmentPath, true)) ?? {};\n return new ConfigMerger().merge(base, override);\n }\n}\n"],"names":["AppSettingsSource","constructor","options","this","directory","process","cwd","environment","env","NODE_ENV","name","load","basePath","resolve","environmentPath","base","loadJson","override","ConfigMerger","merge"],"mappings":"gJAWO,MAAMA,EAKX,WAAAC,CAAmBC,GACjBC,KAAKC,UAAYF,EAAQE,WAAaC,QAAQC,MAC9CH,KAAKI,YAAcL,EAAQK,aAAeF,QAAQG,IAAIC,UAAY,cAClEN,KAAKO,KAAOR,EAAQQ,MAAQ,eAAeP,KAAKI,aAClD,CAEA,UAAMI,GACJ,MAAMC,EAAWC,EAAQV,KAAKC,UAAW,oBACnCU,EAAkBD,EAAQV,KAAKC,UAAW,eAAeD,KAAKI,oBAC9DQ,QAAaC,EAASJ,GAAU,GAChCK,QAAkBD,EAASF,GAAiB,IAAU,CAAA,EAC5D,OAAO,IAAII,GAAeC,MAAMJ,EAAME,EACxC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EnvironmentSource.mjs","sources":["../../../src/sources/EnvironmentSource.ts"],"sourcesContent":["import { capitalize, isPlainObject } from 'remeda';\nimport { type SettingsSource } from '../types/Source.types.ts';\n\nexport interface EnvironmentSourceOptions {\n envs: Record<string, string | undefined>;\n name?: string;\n prefix?: string;\n}\n\nexport class EnvironmentSource implements SettingsSource {\n private readonly envs: Record<string, string | undefined>;\n private readonly prefix: string;\n\n private normalizeSegment = (value: string): string =>\n value\n .toLowerCase()\n .split('_')\n .filter(Boolean)\n .map(part => capitalize(part))\n .join('');\n\n public readonly name: string;\n\n public constructor(options: EnvironmentSourceOptions) {\n this.envs = options.envs;\n this.prefix = options.prefix ?? 'APP_';\n this.name = options.name ?? `environment:${this.prefix}`;\n }\n\n private parseEnvironmentValue(value: string): unknown {\n if (value === 'true') {\n return true;\n }\n\n if (value === 'false') {\n return false;\n }\n\n if (value.trim() !== '' && Number.isFinite(Number(value))) {\n return Number(value);\n }\n\n return value;\n }\n\n load(): Promise<Record<string, unknown>> {\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(this.envs)) {\n if (value === undefined || !key.startsWith(this.prefix)) {\n continue;\n }\n\n const path = key\n .slice(this.prefix.length)\n .split('__')\n .filter(Boolean)\n .map(part => this.normalizeSegment(part));\n\n const leaf = path.pop();\n\n if (!leaf) {\n continue;\n }\n\n let current = result;\n\n for (const part of path) {\n const next = current[part];\n\n if (!isPlainObject(next)) {\n current[part] = {};\n }\n\n const currentPart = current[part];\n\n if (isPlainObject(currentPart)) {\n current = currentPart;\n }\n }\n\n current[leaf] = this.parseEnvironmentValue(value);\n }\n\n return Promise.resolve(result);\n }\n}\n"],"names":["EnvironmentSource","constructor","options","normalizeSegment","value","toLowerCase","split","filter","Boolean","map","part","capitalize","join","this","envs","prefix","name","parseEnvironmentValue","trim","Number","isFinite","load","result","key","Object","entries","undefined","startsWith","path","slice","length","leaf","pop","current","next","isPlainObject","currentPart","Promise","resolve"],"mappings":"uDASO,MAAMA,EAcX,WAAAC,CAAmBC,GAVXC,KAAAA,iBAAoBC,GAC1BA,EACGC,cACAC,MAAM,KACNC,OAAOC,SACPC,IAAIC,GAAQC,EAAWD,IACvBE,KAAK,IAKRC,KAAKC,KAAOZ,EAAQY,KACpBD,KAAKE,OAASb,EAAQa,QAAU,OAChCF,KAAKG,KAAOd,EAAQc,MAAQ,eAAeH,KAAKE,QAClD,CAEQE,qBAAAA,CAAsBb,GAC5B,MAAc,SAAVA,GAIU,UAAVA,IAIiB,KAAjBA,EAAMc,QAAiBC,OAAOC,SAASD,OAAOf,IACzCe,OAAOf,GAGTA,EACT,CAEAiB,IAAAA,GACE,MAAMC,EAAkC,CAAA,EAExC,IAAK,MAAOC,EAAKnB,KAAUoB,OAAOC,QAAQZ,KAAKC,MAAO,CACpD,QAAcY,IAAVtB,IAAwBmB,EAAII,WAAWd,KAAKE,QAC9C,SAGF,MAAMa,EAAOL,EACVM,MAAMhB,KAAKE,OAAOe,QAClBxB,MAAM,MACNC,OAAOC,SACPC,IAAIC,GAAQG,KAAKV,iBAAiBO,IAE/BqB,EAAOH,EAAKI,MAElB,IAAKD,EACH,SAGF,IAAIE,EAAUX,EAEd,IAAK,MAAMZ,KAAQkB,EAAM,CACvB,MAAMM,EAAOD,EAAQvB,GAEhByB,EAAcD,KACjBD,EAAQvB,GAAQ,CAAA,GAGlB,MAAM0B,EAAcH,EAAQvB,GAExByB,EAAcC,KAChBH,EAAUG,EAEd,CAEAH,EAAQF,GAAQlB,KAAKI,sBAAsBb,EAC7C,CAEA,OAAOiC,QAAQC,QAAQhB,EACzB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MemorySource.mjs","sources":["../../../src/sources/MemorySource.ts"],"sourcesContent":["import { clone } from 'remeda';\nimport { type SettingsSource } from '../types/Source.types.ts';\n\nexport interface MemorySourceOptions {\n name?: string;\n values: Record<string, unknown>;\n}\n\nexport class MemorySource implements SettingsSource {\n private readonly values: Record<string, unknown>;\n public readonly name: string;\n\n public constructor(options: MemorySourceOptions) {\n this.name = options.name ?? 'memory';\n this.values = options.values;\n }\n\n load(): Promise<Record<string, unknown>> {\n return Promise.resolve(clone(this.values));\n }\n}\n"],"names":["MemorySource","constructor","options","this","name","values","load","Promise","resolve","clone"],"mappings":"+BAQO,MAAMA,EAIX,WAAAC,CAAmBC,GACjBC,KAAKC,KAAOF,EAAQE,MAAQ,SAC5BD,KAAKE,OAASH,EAAQG,MACxB,CAEAC,IAAAA,GACE,OAAOC,QAAQC,QAAQC,EAAMN,KAAKE,QACpC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RemoteSource.mjs","sources":["../../../src/sources/RemoteSource.ts"],"sourcesContent":["import { isObjectType, isPlainObject, prop, stringToPath } from 'remeda';\nimport { type SettingsSource } from '#types/Source.types.ts';\n\nexport interface RemoteSourceOptions {\n fetch: typeof globalThis.fetch;\n name?: string;\n responsePath?: string;\n url: string;\n}\n\nexport class RemoteSource implements SettingsSource {\n private fetch: typeof globalThis.fetch;\n private responsePath?: string;\n private url: string;\n public name: string;\n\n public constructor(options: RemoteSourceOptions) {\n this.fetch = options.fetch;\n this.url = options.url;\n this.name = options.name ?? `remote:${this.url}`;\n this.responsePath = options.responsePath;\n }\n\n async load(): Promise<Record<string, unknown>> {\n if (typeof this.fetch !== 'function') {\n throw new TypeError('RemoteSource requires fetch, which is unavailable in this runtime.');\n }\n\n const response = await this.fetch(this.url);\n\n if (!response.ok) {\n throw new Error(`Failed to load settings from \"${this.url}\": ${String(response.status)} ${response.statusText}`);\n }\n\n let value: unknown = await response.json();\n\n if (this.responsePath && !isObjectType(value)) {\n throw new Error(`Fetched value must be an object type if response path is provided, but was ${typeof value}.`);\n }\n\n // @ts-expect-error Unable to statically type string literal\n value = this.responsePath ? prop(value, ...stringToPath(this.responsePath)) : value;\n\n if (!isPlainObject(value)) {\n throw new Error(`JSON settings from \"${this.url}\" must contain an object at the root.`);\n }\n\n return value;\n }\n}\n"],"names":["RemoteSource","constructor","options","this","fetch","url","name","responsePath","load","TypeError","response","ok","Error","String","status","statusText","value","json","isObjectType","prop","stringToPath","isPlainObject"],"mappings":"qFAUO,MAAMA,EAMX,WAAAC,CAAmBC,GACjBC,KAAKC,MAAQF,EAAQE,MACrBD,KAAKE,IAAMH,EAAQG,IACnBF,KAAKG,KAAOJ,EAAQI,MAAQ,UAAUH,KAAKE,MAC3CF,KAAKI,aAAeL,EAAQK,YAC9B,CAEA,UAAMC,GACJ,GAA0B,mBAAfL,KAAKC,MACd,MAAM,IAAIK,UAAU,sEAGtB,MAAMC,QAAiBP,KAAKC,MAAMD,KAAKE,KAEvC,IAAKK,EAASC,GACZ,MAAM,IAAIC,MAAM,iCAAiCT,KAAKE,SAASQ,OAAOH,EAASI,WAAWJ,EAASK,cAGrG,IAAIC,QAAuBN,EAASO,OAEpC,GAAId,KAAKI,eAAiBW,EAAaF,GACrC,MAAM,IAAIJ,MAAM,qFAAqFI,MAMvG,GAFAA,EAAQb,KAAKI,aAAeY,EAAKH,KAAUI,EAAajB,KAAKI,eAAiBS,GAEzEK,EAAcL,GACjB,MAAM,IAAIJ,MAAM,uBAAuBT,KAAKE,4CAG9C,OAAOW,CACT"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadJson.mjs","sources":["../../../../src/sources/helpers/loadJson.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { isPlainObject } from 'remeda';\n\nexport function loadJson(path: string, isOptional: false): Promise<Record<string, unknown>>;\nexport function loadJson(path: string, isOptional: true): Promise<Record<string, unknown> | undefined>;\n\n// Required for overloads\n// eslint-disable-next-line prefer-arrow/prefer-arrow-functions\nexport async function loadJson(path: string, isOptional: boolean): Promise<Record<string, unknown> | undefined> {\n let contents: string;\n\n try {\n contents = await readFile(path, 'utf8');\n } catch (error) {\n if (isOptional && typeof error === 'object' && error !== null && 'code' in error && error.code === 'ENOENT') {\n return undefined;\n }\n\n throw error;\n }\n\n const value: unknown = JSON.parse(contents);\n\n if (!isPlainObject(value)) {\n throw new Error(`JSON settings from \"${path}\" must contain an object at the root.`);\n }\n\n return value;\n}\n"],"names":["async","loadJson","path","isOptional","contents","readFile","error","code","value","JSON","parse","isPlainObject","Error"],"mappings":"mFAQOA,eAAeC,EAASC,EAAcC,GAC3C,IAAIC,EAEJ,IACEA,QAAiBC,EAASH,EAAM,OAClC,CAAE,MAAOI,GACP,GAAIH,GAA+B,iBAAVG,GAAgC,OAAVA,GAAkB,SAAUA,GAAwB,WAAfA,EAAMC,KACxF,OAGF,MAAMD,CACR,CAEA,MAAME,EAAiBC,KAAKC,MAAMN,GAElC,IAAKO,EAAcH,GACjB,MAAM,IAAII,MAAM,uBAAuBV,0CAGzC,OAAOM,CACT"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export declare const runAppsettingsCli: () => Promise<void>;
|
|
2
|
-
//# sourceMappingURL=
|
|
2
|
+
//# sourceMappingURL=cli.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.cts","sourceRoot":"","sources":["../../../src/cli.cts"],"names":[],"mappings":"AAIA,eAAO,MAAM,iBAAiB,QAAa,OAAO,CAAC,IAAI,CAQtD,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export declare const runAppsettingsCli: () => Promise<void>;
|
|
2
|
-
//# sourceMappingURL=
|
|
2
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../../src/cli.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,iBAAiB,QAAa,OAAO,CAAC,IAAI,CAQtD,CAAC"}
|