@app-config/core
Advanced tools
Comparing version 3.0.0-alpha.1 to 3.0.0-alpha.2
import { Json } from '@app-config/utils'; | ||
import { ParsedValue, ParsingExtension } from './parsed-value'; | ||
import { ParsedValue, ParsingContext, ParsingExtension } from './parsed-value'; | ||
export declare enum FileType { | ||
@@ -18,5 +18,5 @@ YAML = "YAML", | ||
/** Reads the contents of the source into a full ParsedValue (not the raw JSON, like readValue) */ | ||
read(extensions?: ParsingExtension[]): Promise<ParsedValue>; | ||
read(extensions?: ParsingExtension[], context?: ParsingContext): Promise<ParsedValue>; | ||
/** Ergonomic helper for chaining `source.read(extensions).then(v => v.toJSON())` */ | ||
readToJSON(extensions?: ParsingExtension[]): Promise<Json>; | ||
readToJSON(extensions?: ParsingExtension[], context?: ParsingContext): Promise<Json>; | ||
} | ||
@@ -36,3 +36,3 @@ /** Read configuration from a literal JS object */ | ||
readValue(): Promise<Json>; | ||
read(extensions?: ParsingExtension[]): Promise<ParsedValue>; | ||
read(extensions?: ParsingExtension[], context?: ParsingContext): Promise<ParsedValue>; | ||
} | ||
@@ -45,3 +45,3 @@ /** Read configuration from the first ConfigSource that doesn't fail */ | ||
readValue(): Promise<Json>; | ||
read(extensions?: ParsingExtension[]): Promise<ParsedValue>; | ||
read(extensions?: ParsingExtension[], context?: ParsingContext): Promise<ParsedValue>; | ||
} | ||
@@ -48,0 +48,0 @@ export declare function stringify(config: Json, fileType: FileType, minimal?: boolean): string; |
@@ -28,9 +28,9 @@ "use strict"; | ||
/** Reads the contents of the source into a full ParsedValue (not the raw JSON, like readValue) */ | ||
async read(extensions) { | ||
async read(extensions, context) { | ||
const rawValue = await this.readValue(); | ||
return parsed_value_1.ParsedValue.parse(rawValue, this, extensions); | ||
return parsed_value_1.ParsedValue.parse(rawValue, this, extensions, undefined, context); | ||
} | ||
/** Ergonomic helper for chaining `source.read(extensions).then(v => v.toJSON())` */ | ||
async readToJSON(extensions) { | ||
const parsed = await this.read(extensions); | ||
async readToJSON(extensions, context) { | ||
const parsed = await this.read(extensions, context); | ||
return parsed.toJSON(); | ||
@@ -73,4 +73,4 @@ } | ||
// override so that ParsedValue is directly from the originating ConfigSource | ||
async read(extensions) { | ||
const values = await Promise.all(this.sources.map((source) => source.read(extensions))); | ||
async read(extensions, context) { | ||
const values = await Promise.all(this.sources.map((source) => source.read(extensions, context))); | ||
const merged = values.reduce((acc, parsed) => { | ||
@@ -121,7 +121,7 @@ if (!acc) | ||
// override so that ParsedValue is directly from the originating ConfigSource | ||
async read(extensions) { | ||
async read(extensions, context) { | ||
// take the first value that comes back without an error | ||
for (const source of this.sources) { | ||
try { | ||
const value = await source.read(extensions); | ||
const value = await source.read(extensions, context); | ||
logging_1.logger.verbose(`FallbackSource found successful source`); | ||
@@ -128,0 +128,0 @@ return value; |
import { Json } from '@app-config/utils'; | ||
import { ParsedValue, ParsingExtension } from './parsed-value'; | ||
import { ParsedValue, ParsingContext, ParsingExtension } from './parsed-value'; | ||
export declare enum FileType { | ||
@@ -18,5 +18,5 @@ YAML = "YAML", | ||
/** Reads the contents of the source into a full ParsedValue (not the raw JSON, like readValue) */ | ||
read(extensions?: ParsingExtension[]): Promise<ParsedValue>; | ||
read(extensions?: ParsingExtension[], context?: ParsingContext): Promise<ParsedValue>; | ||
/** Ergonomic helper for chaining `source.read(extensions).then(v => v.toJSON())` */ | ||
readToJSON(extensions?: ParsingExtension[]): Promise<Json>; | ||
readToJSON(extensions?: ParsingExtension[], context?: ParsingContext): Promise<Json>; | ||
} | ||
@@ -36,3 +36,3 @@ /** Read configuration from a literal JS object */ | ||
readValue(): Promise<Json>; | ||
read(extensions?: ParsingExtension[]): Promise<ParsedValue>; | ||
read(extensions?: ParsingExtension[], context?: ParsingContext): Promise<ParsedValue>; | ||
} | ||
@@ -45,3 +45,3 @@ /** Read configuration from the first ConfigSource that doesn't fail */ | ||
readValue(): Promise<Json>; | ||
read(extensions?: ParsingExtension[]): Promise<ParsedValue>; | ||
read(extensions?: ParsingExtension[], context?: ParsingContext): Promise<ParsedValue>; | ||
} | ||
@@ -48,0 +48,0 @@ export declare function stringify(config: Json, fileType: FileType, minimal?: boolean): string; |
@@ -25,9 +25,9 @@ import { extname } from 'path'; | ||
/** Reads the contents of the source into a full ParsedValue (not the raw JSON, like readValue) */ | ||
async read(extensions) { | ||
async read(extensions, context) { | ||
const rawValue = await this.readValue(); | ||
return ParsedValue.parse(rawValue, this, extensions); | ||
return ParsedValue.parse(rawValue, this, extensions, undefined, context); | ||
} | ||
/** Ergonomic helper for chaining `source.read(extensions).then(v => v.toJSON())` */ | ||
async readToJSON(extensions) { | ||
const parsed = await this.read(extensions); | ||
async readToJSON(extensions, context) { | ||
const parsed = await this.read(extensions, context); | ||
return parsed.toJSON(); | ||
@@ -68,4 +68,4 @@ } | ||
// override so that ParsedValue is directly from the originating ConfigSource | ||
async read(extensions) { | ||
const values = await Promise.all(this.sources.map((source) => source.read(extensions))); | ||
async read(extensions, context) { | ||
const values = await Promise.all(this.sources.map((source) => source.read(extensions, context))); | ||
const merged = values.reduce((acc, parsed) => { | ||
@@ -115,7 +115,7 @@ if (!acc) | ||
// override so that ParsedValue is directly from the originating ConfigSource | ||
async read(extensions) { | ||
async read(extensions, context) { | ||
// take the first value that comes back without an error | ||
for (const source of this.sources) { | ||
try { | ||
const value = await source.read(extensions); | ||
const value = await source.read(extensions, context); | ||
logger.verbose(`FallbackSource found successful source`); | ||
@@ -122,0 +122,0 @@ return value; |
@@ -12,4 +12,7 @@ /// <reference types="node" /> | ||
export declare type ParsingExtensionKey = [typeof InObject, string] | [typeof InArray, number] | [typeof Root]; | ||
export declare type ParsingExtension = (value: Json, key: ParsingExtensionKey, context: ParsingExtensionKey[]) => false | ParsingExtensionTransform; | ||
export declare type ParsingExtensionTransform = (parse: (value: Json, metadata?: ParsedValueMetadata, source?: ConfigSource, extensions?: ParsingExtension[]) => Promise<ParsedValue>, parent: JsonObject | Json[] | undefined, source: ConfigSource, extensions: ParsingExtension[], root: Json) => Promise<ParsedValue> | ParsedValue; | ||
export interface ParsingContext { | ||
[k: string]: string | Record<string, string> | string[] | undefined; | ||
} | ||
export declare type ParsingExtension<T extends Json = Json> = (value: T, parentKeys: ParsingExtensionKey[], context: ParsingContext) => ParsingExtensionTransform | false; | ||
export declare type ParsingExtensionTransform = (parse: (value: Json, metadata?: ParsedValueMetadata, context?: ParsingContext, source?: ConfigSource, extensions?: ParsingExtension[]) => Promise<ParsedValue>, parent: JsonObject | Json[] | undefined, source: ConfigSource, extensions: ParsingExtension[], root: Json) => Promise<ParsedValue> | ParsedValue; | ||
export interface ParsedValueMetadata { | ||
@@ -31,3 +34,3 @@ [key: string]: any; | ||
/** Parses (with extensions) from a value that was read from ConfigSource */ | ||
static parse(raw: Json, source: ConfigSource, extensions?: ParsingExtension[], metadata?: ParsedValueMetadata): Promise<ParsedValue>; | ||
static parse(raw: Json, source: ConfigSource, extensions?: ParsingExtension[], metadata?: ParsedValueMetadata, context?: ParsingContext): Promise<ParsedValue>; | ||
/** Parses (with extensions) from a plain JSON object */ | ||
@@ -58,3 +61,3 @@ static parseLiteral(raw: Json, extensions?: ParsingExtension[]): Promise<ParsedValue>; | ||
} | ||
export declare function parseValue(value: Json, source: ConfigSource, extensions?: ParsingExtension[], metadata?: ParsedValueMetadata): Promise<ParsedValue>; | ||
export declare function parseValue(value: Json, source: ConfigSource, extensions?: ParsingExtension[], metadata?: ParsedValueMetadata, context?: ParsingContext): Promise<ParsedValue>; | ||
export {}; |
@@ -26,4 +26,4 @@ import { inspect } from 'util'; | ||
/** Parses (with extensions) from a value that was read from ConfigSource */ | ||
static async parse(raw, source, extensions, metadata) { | ||
return parseValue(raw, source, extensions, metadata); | ||
static async parse(raw, source, extensions, metadata, context) { | ||
return parseValue(raw, source, extensions, metadata, context); | ||
} | ||
@@ -239,8 +239,6 @@ /** Parses (with extensions) from a plain JSON object */ | ||
} | ||
export async function parseValue(value, source, extensions = [], metadata = {}) { | ||
return parseValueInner(value, source, extensions, metadata, [[Root]], value); | ||
export async function parseValue(value, source, extensions = [], metadata = {}, context = {}) { | ||
return parseValueInner(value, source, extensions, metadata, context, [[Root]], value); | ||
} | ||
async function parseValueInner(value, source, extensions, metadata = {}, context, root, parent, visitedExtensions = []) { | ||
const [currentKey] = context.slice(-1); | ||
const contextualKeys = context.slice(0, context.length - 1); | ||
async function parseValueInner(value, source, extensions, metadata = {}, context = {}, parentKeys, root, parent, visitedExtensions = []) { | ||
let applicableExtension; | ||
@@ -258,3 +256,3 @@ // before anything else, we check for parsing extensions that should be applied | ||
continue; | ||
const applicable = extension(value, currentKey, contextualKeys); | ||
const applicable = extension(value, parentKeys, context); | ||
if (applicable && !applicableExtension) { | ||
@@ -266,3 +264,3 @@ applicableExtension = applicable; | ||
if (applicableExtension) { | ||
const parse = (inner, metadataOverride, sourceOverride, extensionsOverride) => parseValueInner(inner, sourceOverride ?? source, extensionsOverride ?? extensions, { ...metadata, ...metadataOverride }, context, root, parent, visitedExtensions); | ||
const parse = (inner, metadataOverride, contextOverride, sourceOverride, extensionsOverride) => parseValueInner(inner, sourceOverride ?? source, extensionsOverride ?? extensions, { ...metadata, ...metadataOverride }, { ...context, ...contextOverride }, parentKeys, root, parent, visitedExtensions); | ||
// note that we don't traverse the object is an extension applied, that's up to them (with `parse`) | ||
@@ -273,3 +271,3 @@ return applicableExtension(parse, parent, source, extensions, root); | ||
const output = await Promise.all(Array.from(value.entries()).map(([index, item]) => { | ||
return parseValueInner(item, source, extensions, undefined, context.concat([[InArray, index]]), root, value); | ||
return parseValueInner(item, source, extensions, undefined, context, [[InArray, index], ...parentKeys], root, value); | ||
})); | ||
@@ -285,3 +283,3 @@ return new ParsedValue(source, value, output).assignMeta(metadata); | ||
await Promise.all(Object.entries(value).map(async ([key, item]) => { | ||
const parsed = await parseValueInner(item, source, extensions, undefined, context.concat([[InObject, key]]), root, value); | ||
const parsed = await parseValueInner(item, source, extensions, undefined, context, [[InObject, key], ...parentKeys], root, value); | ||
// NOTE: shouldMerge is treated as shouldFlatten when the value itself is not an object (because we cannot merge arrays or primitives) | ||
@@ -288,0 +286,0 @@ if (parsed.meta.shouldFlatten) { |
@@ -12,4 +12,7 @@ /// <reference types="node" /> | ||
export declare type ParsingExtensionKey = [typeof InObject, string] | [typeof InArray, number] | [typeof Root]; | ||
export declare type ParsingExtension = (value: Json, key: ParsingExtensionKey, context: ParsingExtensionKey[]) => false | ParsingExtensionTransform; | ||
export declare type ParsingExtensionTransform = (parse: (value: Json, metadata?: ParsedValueMetadata, source?: ConfigSource, extensions?: ParsingExtension[]) => Promise<ParsedValue>, parent: JsonObject | Json[] | undefined, source: ConfigSource, extensions: ParsingExtension[], root: Json) => Promise<ParsedValue> | ParsedValue; | ||
export interface ParsingContext { | ||
[k: string]: string | Record<string, string> | string[] | undefined; | ||
} | ||
export declare type ParsingExtension<T extends Json = Json> = (value: T, parentKeys: ParsingExtensionKey[], context: ParsingContext) => ParsingExtensionTransform | false; | ||
export declare type ParsingExtensionTransform = (parse: (value: Json, metadata?: ParsedValueMetadata, context?: ParsingContext, source?: ConfigSource, extensions?: ParsingExtension[]) => Promise<ParsedValue>, parent: JsonObject | Json[] | undefined, source: ConfigSource, extensions: ParsingExtension[], root: Json) => Promise<ParsedValue> | ParsedValue; | ||
export interface ParsedValueMetadata { | ||
@@ -31,3 +34,3 @@ [key: string]: any; | ||
/** Parses (with extensions) from a value that was read from ConfigSource */ | ||
static parse(raw: Json, source: ConfigSource, extensions?: ParsingExtension[], metadata?: ParsedValueMetadata): Promise<ParsedValue>; | ||
static parse(raw: Json, source: ConfigSource, extensions?: ParsingExtension[], metadata?: ParsedValueMetadata, context?: ParsingContext): Promise<ParsedValue>; | ||
/** Parses (with extensions) from a plain JSON object */ | ||
@@ -58,3 +61,3 @@ static parseLiteral(raw: Json, extensions?: ParsingExtension[]): Promise<ParsedValue>; | ||
} | ||
export declare function parseValue(value: Json, source: ConfigSource, extensions?: ParsingExtension[], metadata?: ParsedValueMetadata): Promise<ParsedValue>; | ||
export declare function parseValue(value: Json, source: ConfigSource, extensions?: ParsingExtension[], metadata?: ParsedValueMetadata, context?: ParsingContext): Promise<ParsedValue>; | ||
export {}; |
@@ -32,4 +32,4 @@ "use strict"; | ||
/** Parses (with extensions) from a value that was read from ConfigSource */ | ||
static async parse(raw, source, extensions, metadata) { | ||
return parseValue(raw, source, extensions, metadata); | ||
static async parse(raw, source, extensions, metadata, context) { | ||
return parseValue(raw, source, extensions, metadata, context); | ||
} | ||
@@ -248,9 +248,7 @@ /** Parses (with extensions) from a plain JSON object */ | ||
} | ||
async function parseValue(value, source, extensions = [], metadata = {}) { | ||
return parseValueInner(value, source, extensions, metadata, [[exports.Root]], value); | ||
async function parseValue(value, source, extensions = [], metadata = {}, context = {}) { | ||
return parseValueInner(value, source, extensions, metadata, context, [[exports.Root]], value); | ||
} | ||
exports.parseValue = parseValue; | ||
async function parseValueInner(value, source, extensions, metadata = {}, context, root, parent, visitedExtensions = []) { | ||
const [currentKey] = context.slice(-1); | ||
const contextualKeys = context.slice(0, context.length - 1); | ||
async function parseValueInner(value, source, extensions, metadata = {}, context = {}, parentKeys, root, parent, visitedExtensions = []) { | ||
let applicableExtension; | ||
@@ -268,3 +266,3 @@ // before anything else, we check for parsing extensions that should be applied | ||
continue; | ||
const applicable = extension(value, currentKey, contextualKeys); | ||
const applicable = extension(value, parentKeys, context); | ||
if (applicable && !applicableExtension) { | ||
@@ -276,3 +274,3 @@ applicableExtension = applicable; | ||
if (applicableExtension) { | ||
const parse = (inner, metadataOverride, sourceOverride, extensionsOverride) => parseValueInner(inner, sourceOverride !== null && sourceOverride !== void 0 ? sourceOverride : source, extensionsOverride !== null && extensionsOverride !== void 0 ? extensionsOverride : extensions, Object.assign(Object.assign({}, metadata), metadataOverride), context, root, parent, visitedExtensions); | ||
const parse = (inner, metadataOverride, contextOverride, sourceOverride, extensionsOverride) => parseValueInner(inner, sourceOverride !== null && sourceOverride !== void 0 ? sourceOverride : source, extensionsOverride !== null && extensionsOverride !== void 0 ? extensionsOverride : extensions, Object.assign(Object.assign({}, metadata), metadataOverride), Object.assign(Object.assign({}, context), contextOverride), parentKeys, root, parent, visitedExtensions); | ||
// note that we don't traverse the object is an extension applied, that's up to them (with `parse`) | ||
@@ -283,3 +281,3 @@ return applicableExtension(parse, parent, source, extensions, root); | ||
const output = await Promise.all(Array.from(value.entries()).map(([index, item]) => { | ||
return parseValueInner(item, source, extensions, undefined, context.concat([[exports.InArray, index]]), root, value); | ||
return parseValueInner(item, source, extensions, undefined, context, [[exports.InArray, index], ...parentKeys], root, value); | ||
})); | ||
@@ -295,3 +293,3 @@ return new ParsedValue(source, value, output).assignMeta(metadata); | ||
await Promise.all(Object.entries(value).map(async ([key, item]) => { | ||
const parsed = await parseValueInner(item, source, extensions, undefined, context.concat([[exports.InObject, key]]), root, value); | ||
const parsed = await parseValueInner(item, source, extensions, undefined, context, [[exports.InObject, key], ...parentKeys], root, value); | ||
// NOTE: shouldMerge is treated as shouldFlatten when the value itself is not an object (because we cannot merge arrays or primitives) | ||
@@ -298,0 +296,0 @@ if (parsed.meta.shouldFlatten) { |
{ | ||
"name": "@app-config/core", | ||
"description": "Core logic for App Config", | ||
"version": "3.0.0-alpha.1", | ||
"version": "3.0.0-alpha.2", | ||
"license": "MPL-2.0", | ||
@@ -33,4 +33,4 @@ "author": { | ||
"dependencies": { | ||
"@app-config/logging": "^3.0.0-alpha.1", | ||
"@app-config/utils": "^3.0.0-alpha.1", | ||
"@app-config/logging": "^3.0.0-alpha.2", | ||
"@app-config/utils": "^3.0.0-alpha.2", | ||
"@iarna/toml": "3", | ||
@@ -42,3 +42,3 @@ "js-yaml": "^3.13.1", | ||
"devDependencies": { | ||
"@app-config/test-utils": "^3.0.0-alpha.1", | ||
"@app-config/test-utils": "^3.0.0-alpha.2", | ||
"@types/js-yaml": "3", | ||
@@ -45,0 +45,0 @@ "@types/lodash.merge": "4" |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
112866
1617