@fgv/ts-res 5.1.0-28 → 5.1.0-29
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/packlets/conditions/conditionDecls.js.map +1 -1
- package/dist/packlets/conditions/conditionSet.js +14 -5
- package/dist/packlets/conditions/conditionSet.js.map +1 -1
- package/dist/packlets/conditions/conditionSetDecls.js.map +1 -1
- package/dist/packlets/conditions/convert/conditionSetDecls.js +50 -6
- package/dist/packlets/conditions/convert/conditionSetDecls.js.map +1 -1
- package/dist/packlets/conditions/convert/decls.js +61 -5
- package/dist/packlets/conditions/convert/decls.js.map +1 -1
- package/dist/packlets/qualifiers/qualifierCollector.js +151 -7
- package/dist/packlets/qualifiers/qualifierCollector.js.map +1 -1
- package/dist/packlets/resource-json/convert.js +225 -0
- package/dist/packlets/resource-json/convert.js.map +1 -1
- package/dist/packlets/resource-json/json.js +2 -2
- package/dist/packlets/resource-json/json.js.map +1 -1
- package/dist/packlets/runtime/context/simpleContextQualifierProvider.js +3 -0
- package/dist/packlets/runtime/context/simpleContextQualifierProvider.js.map +1 -1
- package/dist/packlets/runtime/context/validatingSimpleContextQualifierProvider.js +3 -5
- package/dist/packlets/runtime/context/validatingSimpleContextQualifierProvider.js.map +1 -1
- package/dist/ts-res.d.ts +442 -52
- package/lib/packlets/conditions/conditionDecls.d.ts +6 -1
- package/lib/packlets/conditions/conditionDecls.d.ts.map +1 -1
- package/lib/packlets/conditions/conditionDecls.js.map +1 -1
- package/lib/packlets/conditions/conditionSet.d.ts.map +1 -1
- package/lib/packlets/conditions/conditionSet.js +14 -5
- package/lib/packlets/conditions/conditionSet.js.map +1 -1
- package/lib/packlets/conditions/conditionSetDecls.d.ts +7 -2
- package/lib/packlets/conditions/conditionSetDecls.d.ts.map +1 -1
- package/lib/packlets/conditions/conditionSetDecls.js.map +1 -1
- package/lib/packlets/conditions/convert/conditionSetDecls.d.ts +30 -2
- package/lib/packlets/conditions/convert/conditionSetDecls.d.ts.map +1 -1
- package/lib/packlets/conditions/convert/conditionSetDecls.js +51 -5
- package/lib/packlets/conditions/convert/conditionSetDecls.js.map +1 -1
- package/lib/packlets/conditions/convert/decls.d.ts +39 -3
- package/lib/packlets/conditions/convert/decls.d.ts.map +1 -1
- package/lib/packlets/conditions/convert/decls.js +63 -5
- package/lib/packlets/conditions/convert/decls.js.map +1 -1
- package/lib/packlets/qualifiers/qualifierCollector.d.ts +104 -6
- package/lib/packlets/qualifiers/qualifierCollector.d.ts.map +1 -1
- package/lib/packlets/qualifiers/qualifierCollector.js +150 -6
- package/lib/packlets/qualifiers/qualifierCollector.js.map +1 -1
- package/lib/packlets/resource-json/convert.d.ts +85 -0
- package/lib/packlets/resource-json/convert.d.ts.map +1 -1
- package/lib/packlets/resource-json/convert.js +237 -0
- package/lib/packlets/resource-json/convert.js.map +1 -1
- package/lib/packlets/resource-json/json.d.ts +128 -39
- package/lib/packlets/resource-json/json.d.ts.map +1 -1
- package/lib/packlets/resource-json/json.js +2 -2
- package/lib/packlets/resource-json/json.js.map +1 -1
- package/lib/packlets/runtime/context/simpleContextQualifierProvider.d.ts +9 -2
- package/lib/packlets/runtime/context/simpleContextQualifierProvider.d.ts.map +1 -1
- package/lib/packlets/runtime/context/simpleContextQualifierProvider.js +3 -0
- package/lib/packlets/runtime/context/simpleContextQualifierProvider.js.map +1 -1
- package/lib/packlets/runtime/context/validatingSimpleContextQualifierProvider.d.ts +8 -1
- package/lib/packlets/runtime/context/validatingSimpleContextQualifierProvider.d.ts.map +1 -1
- package/lib/packlets/runtime/context/validatingSimpleContextQualifierProvider.js +3 -5
- package/lib/packlets/runtime/context/validatingSimpleContextQualifierProvider.js.map +1 -1
- package/package.json +9 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qualifierCollector.js","sourceRoot":"","sources":["../../../src/packlets/qualifiers/qualifierCollector.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport * as Common from '../common';\nimport {\n captureResult,\n Collections,\n failWithDetail,\n Result,\n fail,\n succeed,\n succeedWithDetail,\n ValidatingConvertingCollector\n} from '@fgv/ts-utils';\nimport { IQualifierDecl, IValidatedQualifierDecl } from './qualifierDecl';\nimport { QualifierName } from '../common';\nimport { Qualifier } from './qualifier';\nimport { IQualifierDeclConvertContext, qualifierDecl, validatedQualifierDecl } from './convert';\nimport { ReadOnlyQualifierTypeCollector } from '../qualifier-types';\n\n/**\n * Readonly version of {@link Qualifiers.QualifierCollector | QualifierCollector}.\n * @public\n */\nexport interface IReadOnlyQualifierCollector extends Collections.IReadOnlyValidatingCollector<Qualifier> {\n /**\n * {@inheritDoc Qualifiers.QualifierCollector.qualifierTypes}\n */\n readonly qualifierTypes: ReadOnlyQualifierTypeCollector;\n\n /**\n * Gets a {@link Qualifiers.Qualifier | qualifier} by name or token.\n * @param nameOrToken - The name or token of the qualifier to retrieve.\n * @returns `Success` with the qualifier if found, or `Failure` if not.\n */\n getByNameOrToken(nameOrToken: string): Result<Qualifier>;\n\n /**\n * Checks if a qualifier with a given name or token is in the collection.\n * @param nameOrToken - The name or token of the qualifier to check.\n * @returns `true` if the qualifier is in the collection, `false` if not.\n */\n hasNameOrToken(nameOrToken: string): boolean;\n}\n\n/**\n * Parameters for creating a new {@link Qualifiers.QualifierCollector}.\n * @public\n */\nexport interface IQualifierCollectorCreateParams {\n /**\n * The {@link QualifierTypes.QualifierTypeCollector | qualifier types} used to\n * create {@link Qualifiers.Qualifier | qualifiers} from {@link Qualifiers.IQualifierDecl | declarations}.\n */\n qualifierTypes: ReadOnlyQualifierTypeCollector;\n\n /**\n * Optional list of {@link Qualifiers.IQualifierDecl | declarations} for the qualifiers to add to the collection\n * upon creation.\n */\n qualifiers?: IQualifierDecl[];\n}\n\n/**\n * Collects {@link Qualifiers.Qualifier | Qualifiers} from {@link Qualifiers.IQualifierDecl | declarations},\n * with strongly-typed ({@link QualifierName | QualifierName} and {@link QualifierIndex | QualifierIndex}) key\n * and index.\n * @public\n */\nexport class QualifierCollector\n extends ValidatingConvertingCollector<Qualifier, IQualifierDecl>\n implements IReadOnlyQualifierCollector\n{\n /**\n * The {@link QualifierTypes.QualifierTypeCollector | qualifier types} that this collector uses.\n */\n public qualifierTypes: ReadOnlyQualifierTypeCollector;\n\n /**\n * Constructor for a {@link Qualifiers.QualifierCollector | QualifierCollector} object.\n * @param params - Parameters for creating the collector.\n * @public\n */\n protected constructor(params: IQualifierCollectorCreateParams) {\n super({\n factory: (k, i, v) => this._qualifierFactory(k, i, v),\n converters: new Collections.KeyValueConverters({\n key: Common.Convert.qualifierName,\n value: qualifierDecl\n })\n });\n this.qualifierTypes = params.qualifierTypes;\n /* c8 ignore next 1 - coverage misses the branch intermittently */\n params.qualifiers?.forEach((q) => this.validating.add(q.name, q).orThrow());\n }\n\n /**\n * Creates a new {@link Qualifiers.QualifierCollector | QualifierCollector} object.\n * @param params - {@link Qualifiers.IQualifierCollectorCreateParams | Parameters} for creating a new {@link Qualifiers.QualifierCollector | QualifierCollector}.\n * @returns `Success` with the new collector if successful, or `Failure` if not.\n */\n public static create(params: IQualifierCollectorCreateParams): Result<QualifierCollector> {\n return captureResult(() => new QualifierCollector(params));\n }\n\n /**\n * {@inheritDoc Qualifiers.IReadOnlyQualifierCollector.getByNameOrToken}\n */\n public getByNameOrToken(nameOrToken: string): Result<Qualifier> {\n return this.validating.get(nameOrToken).onFailure((message) => {\n for (const q of this.values()) {\n if (q.token === nameOrToken) {\n return succeedWithDetail(q, 'success');\n }\n }\n return failWithDetail(`Qualifier token '${nameOrToken}' not found`, 'not-found');\n });\n }\n\n /**\n * {@inheritDoc Qualifiers.IReadOnlyQualifierCollector.hasNameOrToken}\n */\n public hasNameOrToken(nameOrToken: string): boolean {\n /* c8 ignore next 3 - functional code path tested but coverage intermittently missed */\n if (this.validating.has(nameOrToken)) {\n return true;\n }\n for (const q of this.values()) {\n /* c8 ignore next 3 - functional code path tested but coverage intermittently missed */\n if (q.token === nameOrToken) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Gets a read-only view of this collector.\n * @returns A read-only view of this collector.\n */\n public toReadOnly(): IReadOnlyQualifierCollector {\n return this;\n }\n\n /**\n * Factory method for creating a {@link Qualifiers.Qualifier | Qualifier} from a {@link Qualifiers.IQualifierDecl | declaration}.\n * @param __key - The key for the qualifier.\n * @param index - The index of the qualifier.\n * @param decl - The {@link Qualifiers.IQualifierDecl | declaration} for the qualifier.\n * @returns `Success` with the new {@link Qualifiers.Qualifier | Qualifier} if successful, or `Failure` if not.\n * @public\n */\n protected _qualifierFactory(__key: QualifierName, index: number, decl: IQualifierDecl): Result<Qualifier> {\n const convertContext: IQualifierDeclConvertContext = {\n qualifierTypes: this.qualifierTypes,\n qualifierIndex: index\n };\n return validatedQualifierDecl\n .convert(decl, convertContext)\n .onSuccess((validated) => {\n /* c8 ignore next 9 - coverage intermittently misses this block */\n if (this.hasNameOrToken(validated.token)) {\n return fail<IValidatedQualifierDecl>(\n `Qualifier token '${validated.token}' is not unique or collides with name`\n );\n } else if (this.hasNameOrToken(validated.name)) {\n return fail<IValidatedQualifierDecl>(\n `Qualifier name '${validated.name}' is not unique or collides with token`\n );\n }\n return succeed(validated);\n })\n .onSuccess(Qualifier.create);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"qualifierCollector.js","sourceRoot":"","sources":["../../../src/packlets/qualifiers/qualifierCollector.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport * as Common from '../common';\nimport {\n captureResult,\n Collections,\n Converter,\n Converters,\n failWithDetail,\n mapResults,\n Result,\n fail,\n succeed,\n succeedWithDetail,\n ValidatingConvertingCollector\n} from '@fgv/ts-utils';\nimport { IQualifierDecl, IValidatedQualifierDecl } from './qualifierDecl';\nimport { MaxConditionPriority, MinConditionPriority, QualifierName } from '../common';\nimport { Qualifier } from './qualifier';\nimport { IQualifierDeclConvertContext, qualifierDecl, validatedQualifierDecl } from './convert';\nimport {\n LiteralQualifierType,\n QualifierTypeCollector,\n ReadOnlyQualifierTypeCollector\n} from '../qualifier-types';\n\n/**\n * Converter for a single entry in the mixed-shape\n * {@link Qualifiers.IQualifierCollectorCreateParams.qualifiers | qualifiers}\n * input — either a bare axis-name string or a full\n * {@link Qualifiers.IQualifierDecl | declaration}. Validates the entry\n * shape at the public-API boundary rather than deferring to the\n * internal qualifier factory.\n */\nconst _qualifierEntriesConverter: Converter<ReadonlyArray<string | IQualifierDecl>> = Converters.arrayOf(\n Converters.oneOf<string | IQualifierDecl>([Converters.string, qualifierDecl])\n);\n\n/**\n * Readonly version of {@link Qualifiers.QualifierCollector | QualifierCollector}.\n * @public\n */\nexport interface IReadOnlyQualifierCollector extends Collections.IReadOnlyValidatingCollector<Qualifier> {\n /**\n * {@inheritDoc Qualifiers.QualifierCollector.qualifierTypes}\n */\n readonly qualifierTypes: ReadOnlyQualifierTypeCollector;\n\n /**\n * Gets a {@link Qualifiers.Qualifier | qualifier} by name or token.\n * @param nameOrToken - The name or token of the qualifier to retrieve.\n * @returns `Success` with the qualifier if found, or `Failure` if not.\n */\n getByNameOrToken(nameOrToken: string): Result<Qualifier>;\n\n /**\n * Checks if a qualifier with a given name or token is in the collection.\n * @param nameOrToken - The name or token of the qualifier to check.\n * @returns `true` if the qualifier is in the collection, `false` if not.\n */\n hasNameOrToken(nameOrToken: string): boolean;\n}\n\n/**\n * Parameters for creating a new {@link Qualifiers.QualifierCollector}.\n * @public\n *\n * @remarks\n * `qualifiers` accepts a mixed array of bare axis-name strings and full\n * {@link Qualifiers.IQualifierDecl | declarations}. A string element is\n * sugar for \"literal qualifier with this name\"; the library synthesizes a\n * {@link QualifierTypes.LiteralQualifierType | LiteralQualifierType} and a\n * declaration `{ name, typeName: name, defaultPriority: <descending> }`.\n *\n * Synthesized priorities are distributed across the\n * `[MinConditionPriority..MaxConditionPriority]` range adaptively to the\n * array length: `step = max(1, floor((Max - Min) / length))`,\n * `priority = max(Min, Max - index * step)`. Earlier elements get higher\n * priority. The formula never overflows the `ConditionPriority` range\n * regardless of input length; for inputs whose length exceeds the range\n * cardinality (\\>1000 axes), trailing priorities collapse at\n * `MinConditionPriority` — supply explicit priorities in that regime\n * if uniqueness matters.\n *\n * `qualifierTypes` may be omitted only when every element of `qualifiers`\n * is a string. If any element is an {@link Qualifiers.IQualifierDecl},\n * `qualifierTypes` must be supplied and must contain the referenced\n * {@link Qualifiers.IQualifierDecl.typeName | typeNames}.\n */\nexport interface IQualifierCollectorCreateParams {\n /**\n * The {@link QualifierTypes.QualifierTypeCollector | qualifier types} used to\n * create {@link Qualifiers.Qualifier | qualifiers} from {@link Qualifiers.IQualifierDecl | declarations}.\n *\n * Optional only when every entry in `qualifiers` is a bare axis-name string\n * (in which case the library synthesizes a literal qualifier type per name).\n */\n qualifierTypes?: ReadOnlyQualifierTypeCollector;\n\n /**\n * Optional list of {@link Qualifiers.IQualifierDecl | declarations} or bare\n * axis-name strings for the qualifiers to add to the collection on creation.\n *\n * @remarks\n * A string element `'foo'` is sugar for a literal qualifier:\n * `{ name: 'foo', typeName: 'foo', defaultPriority: <descending> }` backed by\n * a synthesized {@link QualifierTypes.LiteralQualifierType | LiteralQualifierType}\n * named `'foo'`.\n */\n qualifiers?: ReadonlyArray<string | IQualifierDecl>;\n}\n\n/**\n * Collects {@link Qualifiers.Qualifier | Qualifiers} from {@link Qualifiers.IQualifierDecl | declarations},\n * with strongly-typed ({@link QualifierName | QualifierName} and {@link QualifierIndex | QualifierIndex}) key\n * and index.\n * @public\n */\nexport class QualifierCollector\n extends ValidatingConvertingCollector<Qualifier, IQualifierDecl>\n implements IReadOnlyQualifierCollector\n{\n /**\n * The {@link QualifierTypes.QualifierTypeCollector | qualifier types} that this collector uses.\n */\n public qualifierTypes: ReadOnlyQualifierTypeCollector;\n\n /**\n * Constructor for a {@link Qualifiers.QualifierCollector | QualifierCollector} object.\n * @param qualifierTypes - The {@link QualifierTypes.ReadOnlyQualifierTypeCollector | qualifier types}\n * used to validate declarations.\n * @param qualifiers - Optional list of fully-resolved {@link Qualifiers.IQualifierDecl | declarations}.\n * @public\n */\n protected constructor(\n qualifierTypes: ReadOnlyQualifierTypeCollector,\n qualifiers?: ReadonlyArray<IQualifierDecl>\n ) {\n super({\n factory: (k, i, v) => this._qualifierFactory(k, i, v),\n converters: new Collections.KeyValueConverters({\n key: Common.Convert.qualifierName,\n value: qualifierDecl\n })\n });\n this.qualifierTypes = qualifierTypes;\n /* c8 ignore next 1 - coverage misses the branch intermittently */\n qualifiers?.forEach((q) => this.validating.add(q.name, q).orThrow());\n }\n\n /**\n * Creates a new {@link Qualifiers.QualifierCollector | QualifierCollector} object.\n * @param params - {@link Qualifiers.IQualifierCollectorCreateParams | Parameters} for creating a new {@link Qualifiers.QualifierCollector | QualifierCollector}.\n * @returns `Success` with the new collector if successful, or `Failure` if not.\n *\n * @remarks\n * Accepts a mixed array of bare axis-name strings and full\n * {@link Qualifiers.IQualifierDecl | declarations}. String elements are sugar\n * for a literal qualifier: the library synthesizes a\n * {@link QualifierTypes.LiteralQualifierType | LiteralQualifierType} named\n * after the string and a declaration `{ name, typeName: name, defaultPriority }`.\n * Synthesized priorities are distributed across the\n * `[MinConditionPriority..MaxConditionPriority]` range adaptively to the\n * input length (`step = max(1, floor((Max - Min) / length))`,\n * `priority = max(Min, Max - index * step)`). Earlier elements get higher\n * priority — matching the \"earlier qualifier wins when multiple match\"\n * mental model — and the formula never overflows the `ConditionPriority`\n * range regardless of input length.\n *\n * `qualifierTypes` may be omitted only when every element of `qualifiers`\n * is a string. If any element is a declaration, `qualifierTypes` is\n * required (and must include the referenced typeNames); the error message\n * names the offending typeName when it is missing.\n */\n public static create(params: IQualifierCollectorCreateParams): Result<QualifierCollector> {\n return QualifierCollector._resolveCreateParams(params).onSuccess(({ qualifierTypes, qualifiers }) => {\n return captureResult(() => new QualifierCollector(qualifierTypes, qualifiers));\n });\n }\n\n /**\n * Resolves the public {@link Qualifiers.IQualifierCollectorCreateParams | create params}\n * into the concrete `(qualifierTypes, qualifiers)` pair the constructor expects.\n *\n * @remarks\n * Validates the mixed-shape `qualifiers` input through\n * {@link Converters.oneOf} (string vs {@link Qualifiers.IQualifierDecl})\n * at the public-API boundary, then partitions into bare-string and decl\n * buckets to drive type synthesis. If any decl is present and\n * `qualifierTypes` is omitted, fails with an error that names the\n * offending typeNames.\n *\n * @internal\n */\n private static _resolveCreateParams(params: IQualifierCollectorCreateParams): Result<{\n qualifierTypes: ReadOnlyQualifierTypeCollector;\n qualifiers?: ReadonlyArray<IQualifierDecl>;\n }> {\n const raw = params.qualifiers;\n if (raw === undefined || raw.length === 0) {\n if (params.qualifierTypes === undefined) {\n return succeed({ qualifierTypes: QualifierCollector._emptyQualifierTypes(), qualifiers: undefined });\n }\n return succeed({ qualifierTypes: params.qualifierTypes, qualifiers: undefined });\n }\n\n return _qualifierEntriesConverter.convert(raw).onSuccess((entries) => {\n const stringNames: string[] = [];\n const declTypeNames: string[] = [];\n for (const entry of entries) {\n if (typeof entry === 'string') {\n stringNames.push(entry);\n } else {\n declTypeNames.push(entry.typeName);\n }\n }\n\n if (declTypeNames.length > 0 && params.qualifierTypes === undefined) {\n const unique = Array.from(new Set(declTypeNames));\n return fail<{\n qualifierTypes: ReadOnlyQualifierTypeCollector;\n qualifiers?: ReadonlyArray<IQualifierDecl>;\n }>(\n `qualifierTypes must be supplied when qualifiers include declarations; ` +\n `missing types for: ${unique.map((n) => `'${n}'`).join(', ')}`\n );\n }\n\n return QualifierCollector._resolveQualifierTypes(params.qualifierTypes, stringNames).onSuccess(\n (qualifierTypes) => {\n const decls = QualifierCollector._normalizeQualifierDecls(entries);\n return succeed({ qualifierTypes, qualifiers: decls });\n }\n );\n });\n }\n\n /**\n * Returns the provided {@link QualifierTypes.ReadOnlyQualifierTypeCollector | qualifier-type collector}\n * (or synthesizes a new one) augmented with synthesized literal qualifier types for the supplied\n * string names that are not already present.\n *\n * @internal\n */\n private static _resolveQualifierTypes(\n provided: ReadOnlyQualifierTypeCollector | undefined,\n stringNames: ReadonlyArray<string>\n ): Result<ReadOnlyQualifierTypeCollector> {\n if (stringNames.length === 0) {\n // No bare names to synthesize. The all-decls case requires `provided` to be defined\n // (else _resolveCreateParams would have failed before calling us); fall back to an\n // empty type collector only as a defensive measure.\n /* c8 ignore next 1 - defensive: unreachable when called from _resolveCreateParams */\n return succeed(provided ?? QualifierCollector._emptyQualifierTypes());\n }\n return mapResults(stringNames.map((name) => LiteralQualifierType.create({ name }))).onSuccess(\n (literalTypes) => {\n return QualifierTypeCollector.create().onSuccess((collector) => {\n const existingAdds: ReadonlyArray<Result<unknown>> =\n provided !== undefined\n ? Array.from(provided.values()).map((existing) => collector.add(existing))\n : [];\n const literalAdds: ReadonlyArray<Result<unknown>> = literalTypes\n .filter((lit) => !collector.has(lit.name))\n .map((lit) => collector.add(lit));\n return mapResults([...existingAdds, ...literalAdds]).onSuccess(() =>\n succeed(collector as ReadOnlyQualifierTypeCollector)\n );\n });\n }\n );\n }\n\n /**\n * Normalizes a mixed `(string | IQualifierDecl)[]` into a fully-resolved\n * `IQualifierDecl[]`, assigning descending default priorities to synthesized\n * decls within the `[MinConditionPriority..MaxConditionPriority]` range.\n *\n * @remarks\n * Step size is adaptive to input length:\n * `step = max(1, floor((Max - Min) / length))`. Each synthesized priority\n * is `max(Min, Max - index * step)` — clamped at the bottom so length\n * extremes (\\>1000 axes) degrade gracefully into a tail of equal-`Min`\n * priorities rather than overflowing the `ConditionPriority` range.\n *\n * @internal\n */\n private static _normalizeQualifierDecls(\n qualifiers: ReadonlyArray<string | IQualifierDecl>\n ): ReadonlyArray<IQualifierDecl> {\n const range = MaxConditionPriority - MinConditionPriority;\n const step = Math.max(1, Math.floor(range / qualifiers.length));\n return qualifiers.map((q, index) => {\n if (typeof q === 'string') {\n const raw = MaxConditionPriority - index * step;\n return {\n name: q,\n typeName: q,\n defaultPriority: Math.max(MinConditionPriority, raw)\n };\n }\n return q;\n });\n }\n\n /**\n * Returns an empty {@link QualifierTypes.ReadOnlyQualifierTypeCollector | qualifier-type collector}\n * used as a placeholder when no qualifiers are supplied and the caller omits\n * `qualifierTypes`.\n *\n * @internal\n */\n private static _emptyQualifierTypes(): ReadOnlyQualifierTypeCollector {\n /* c8 ignore next 1 - QualifierTypeCollector.create() is total for the empty case */\n return QualifierTypeCollector.create().orThrow();\n }\n\n /**\n * {@inheritDoc Qualifiers.IReadOnlyQualifierCollector.getByNameOrToken}\n */\n public getByNameOrToken(nameOrToken: string): Result<Qualifier> {\n return this.validating.get(nameOrToken).onFailure((message) => {\n for (const q of this.values()) {\n if (q.token === nameOrToken) {\n return succeedWithDetail(q, 'success');\n }\n }\n return failWithDetail(`Qualifier token '${nameOrToken}' not found`, 'not-found');\n });\n }\n\n /**\n * {@inheritDoc Qualifiers.IReadOnlyQualifierCollector.hasNameOrToken}\n */\n public hasNameOrToken(nameOrToken: string): boolean {\n /* c8 ignore next 3 - functional code path tested but coverage intermittently missed */\n if (this.validating.has(nameOrToken)) {\n return true;\n }\n for (const q of this.values()) {\n /* c8 ignore next 3 - functional code path tested but coverage intermittently missed */\n if (q.token === nameOrToken) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Gets a read-only view of this collector.\n * @returns A read-only view of this collector.\n */\n public toReadOnly(): IReadOnlyQualifierCollector {\n return this;\n }\n\n /**\n * Factory method for creating a {@link Qualifiers.Qualifier | Qualifier} from a {@link Qualifiers.IQualifierDecl | declaration}.\n * @param __key - The key for the qualifier.\n * @param index - The index of the qualifier.\n * @param decl - The {@link Qualifiers.IQualifierDecl | declaration} for the qualifier.\n * @returns `Success` with the new {@link Qualifiers.Qualifier | Qualifier} if successful, or `Failure` if not.\n * @public\n */\n protected _qualifierFactory(__key: QualifierName, index: number, decl: IQualifierDecl): Result<Qualifier> {\n const convertContext: IQualifierDeclConvertContext = {\n qualifierTypes: this.qualifierTypes,\n qualifierIndex: index\n };\n return validatedQualifierDecl\n .convert(decl, convertContext)\n .onSuccess((validated) => {\n /* c8 ignore next 9 - coverage intermittently misses this block */\n if (this.hasNameOrToken(validated.token)) {\n return fail<IValidatedQualifierDecl>(\n `Qualifier token '${validated.token}' is not unique or collides with name`\n );\n } else if (this.hasNameOrToken(validated.name)) {\n return fail<IValidatedQualifierDecl>(\n `Qualifier name '${validated.name}' is not unique or collides with token`\n );\n }\n return succeed(validated);\n })\n .onSuccess(Qualifier.create);\n }\n}\n"]}
|
|
@@ -168,4 +168,229 @@ export const importerResourceCollectionDecl = Converters.generic((from, self, co
|
|
|
168
168
|
metadata: JsonConverters.jsonObject.optional()
|
|
169
169
|
}).convert(from, context);
|
|
170
170
|
});
|
|
171
|
+
// --- Typed sibling converters (Phase B-2) -----------------------------------
|
|
172
|
+
//
|
|
173
|
+
// Each `typed*<TQualifierNames>(qualifierNameConverter)` returns a converter
|
|
174
|
+
// whose result type is narrowed on `TQualifierNames`. The existing untyped
|
|
175
|
+
// exports above remain unchanged at the signature and behavior level; consumers
|
|
176
|
+
// opt in by calling a typed sibling. Internally each typed factory composes
|
|
177
|
+
// lower-level typed factories so a single `qualifierNameConverter` flows
|
|
178
|
+
// end-to-end through the converter tree.
|
|
179
|
+
//
|
|
180
|
+
// DRIFT HAZARD: each typed sibling duplicates the field list of its untyped
|
|
181
|
+
// twin (the duplication exists to preserve `ObjectConverter` return types on
|
|
182
|
+
// the defaults — see phase-b2-result.md). If a field is added, removed, or
|
|
183
|
+
// re-typed on an untyped converter above, the typed sibling MUST be updated
|
|
184
|
+
// in lockstep. The per-pair `keep in sync with X` markers below flag each
|
|
185
|
+
// pair at the call site.
|
|
186
|
+
/**
|
|
187
|
+
* Returns a `Converter` for a `Json.ILooseConditionDecl<TQualifierNames>`
|
|
188
|
+
* narrowed on a supplied `qualifierName` converter.
|
|
189
|
+
*
|
|
190
|
+
* @public
|
|
191
|
+
*/
|
|
192
|
+
// Keep in sync with `looseConditionDecl` above.
|
|
193
|
+
export function typedLooseConditionDecl(qualifierNameConverter) {
|
|
194
|
+
return Converters.strictObject({
|
|
195
|
+
qualifierName: qualifierNameConverter,
|
|
196
|
+
value: Converters.string,
|
|
197
|
+
operator: CommonConvert.conditionOperator.optional(),
|
|
198
|
+
priority: CommonConvert.conditionPriority.optional(),
|
|
199
|
+
scoreAsDefault: Converters.number.optional()
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
function _typedConditionSetDeclFromArray(innerLooseConditionDecl) {
|
|
203
|
+
return Converters.arrayOf(innerLooseConditionDecl);
|
|
204
|
+
}
|
|
205
|
+
function _typedConditionSetDeclFromRecord(innerLooseConditionDecl) {
|
|
206
|
+
return Converters.generic((from, __self, context) => {
|
|
207
|
+
/* c8 ignore next 3 - branch covered by underlying record check */
|
|
208
|
+
if (!_isConditionSetRecord(from)) {
|
|
209
|
+
return fail('Expected an object');
|
|
210
|
+
}
|
|
211
|
+
return mapResults(Array.from(Object.entries(from)).map(([qualifierName, value]) => {
|
|
212
|
+
const toConvert = typeof value === 'string' ? { qualifierName, value } : Object.assign({ qualifierName }, value);
|
|
213
|
+
return innerLooseConditionDecl.convert(toConvert, context);
|
|
214
|
+
}));
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Returns a `Converter` for a `Json.ConditionSetDecl<TQualifierNames>`
|
|
219
|
+
* (either array form or record form) narrowed on a supplied `qualifierName`
|
|
220
|
+
* converter.
|
|
221
|
+
*
|
|
222
|
+
* @public
|
|
223
|
+
*/
|
|
224
|
+
// Keep in sync with `conditionSetDecl` (and its two private feeder converters
|
|
225
|
+
// `conditionSetDeclFromArray` / `conditionSetDeclFromRecord`) above.
|
|
226
|
+
export function typedConditionSetDecl(qualifierNameConverter) {
|
|
227
|
+
const inner = typedLooseConditionDecl(qualifierNameConverter);
|
|
228
|
+
return Converters.oneOf([
|
|
229
|
+
_typedConditionSetDeclFromArray(inner),
|
|
230
|
+
_typedConditionSetDeclFromRecord(inner)
|
|
231
|
+
]);
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Returns a `Converter` for a `Json.ILooseResourceCandidateDecl<TQualifierNames>`
|
|
235
|
+
* narrowed on a supplied `qualifierName` converter.
|
|
236
|
+
*
|
|
237
|
+
* @public
|
|
238
|
+
*/
|
|
239
|
+
// Keep in sync with `looseResourceCandidateDecl` above.
|
|
240
|
+
export function typedLooseResourceCandidateDecl(qualifierNameConverter) {
|
|
241
|
+
return Converters.strictObject({
|
|
242
|
+
id: CommonConvert.resourceId,
|
|
243
|
+
json: JsonConverters.jsonObject,
|
|
244
|
+
conditions: typedConditionSetDecl(qualifierNameConverter).optional(),
|
|
245
|
+
mergeMethod: CommonConvert.resourceValueMergeMethod.optional(),
|
|
246
|
+
isPartial: Converters.boolean.optional(),
|
|
247
|
+
resourceTypeName: CommonConvert.resourceTypeName.optional()
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Returns a `Converter` for a `Json.IImporterResourceCandidateDecl<TQualifierNames>`
|
|
252
|
+
* narrowed on a supplied `qualifierName` converter.
|
|
253
|
+
*
|
|
254
|
+
* @public
|
|
255
|
+
*/
|
|
256
|
+
// Keep in sync with `importerResourceCandidateDecl` above.
|
|
257
|
+
export function typedImporterResourceCandidateDecl(qualifierNameConverter) {
|
|
258
|
+
return Converters.strictObject({
|
|
259
|
+
id: CommonConvert.resourceId.optional(),
|
|
260
|
+
json: JsonConverters.jsonObject,
|
|
261
|
+
conditions: typedConditionSetDecl(qualifierNameConverter).optional(),
|
|
262
|
+
mergeMethod: CommonConvert.resourceValueMergeMethod.optional(),
|
|
263
|
+
isPartial: Converters.boolean.optional(),
|
|
264
|
+
resourceTypeName: CommonConvert.resourceTypeName.optional()
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Returns a `Converter` for a `Json.IChildResourceCandidateDecl<TQualifierNames>`
|
|
269
|
+
* narrowed on a supplied `qualifierName` converter.
|
|
270
|
+
*
|
|
271
|
+
* @public
|
|
272
|
+
*/
|
|
273
|
+
// Keep in sync with `childResourceCandidateDecl` above.
|
|
274
|
+
export function typedChildResourceCandidateDecl(qualifierNameConverter) {
|
|
275
|
+
return Converters.strictObject({
|
|
276
|
+
json: JsonConverters.jsonObject,
|
|
277
|
+
conditions: typedConditionSetDecl(qualifierNameConverter).optional(),
|
|
278
|
+
isPartial: Converters.boolean.optional(),
|
|
279
|
+
mergeMethod: CommonConvert.resourceValueMergeMethod.optional()
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Returns a `Converter` for a `Json.ILooseResourceDecl<TQualifierNames>`
|
|
284
|
+
* narrowed on a supplied `qualifierName` converter.
|
|
285
|
+
*
|
|
286
|
+
* @public
|
|
287
|
+
*/
|
|
288
|
+
// Keep in sync with `looseResourceDecl` above.
|
|
289
|
+
export function typedLooseResourceDecl(qualifierNameConverter) {
|
|
290
|
+
return Converters.strictObject({
|
|
291
|
+
id: CommonConvert.resourceId,
|
|
292
|
+
resourceTypeName: CommonConvert.resourceTypeName,
|
|
293
|
+
candidates: Converters.arrayOf(typedChildResourceCandidateDecl(qualifierNameConverter)).optional()
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Returns a `Converter` for a `Json.IChildResourceDecl<TQualifierNames>`
|
|
298
|
+
* narrowed on a supplied `qualifierName` converter.
|
|
299
|
+
*
|
|
300
|
+
* @public
|
|
301
|
+
*/
|
|
302
|
+
// Keep in sync with `childResourceDecl` above.
|
|
303
|
+
export function typedChildResourceDecl(qualifierNameConverter) {
|
|
304
|
+
return Converters.strictObject({
|
|
305
|
+
resourceTypeName: CommonConvert.resourceTypeName,
|
|
306
|
+
candidates: Converters.arrayOf(typedChildResourceCandidateDecl(qualifierNameConverter)).optional()
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Returns a `Converter` for a `Json.IContainerContextDecl<TQualifierNames>`
|
|
311
|
+
* narrowed on a supplied `qualifierName` converter.
|
|
312
|
+
*
|
|
313
|
+
* @public
|
|
314
|
+
*/
|
|
315
|
+
// Keep in sync with `containerContextDecl` above.
|
|
316
|
+
export function typedContainerContextDecl(qualifierNameConverter) {
|
|
317
|
+
return Converters.strictObject({
|
|
318
|
+
baseId: Converters.oneOf([CommonConvert.resourceId, Converters.literal('')]).optional(),
|
|
319
|
+
conditions: typedConditionSetDecl(qualifierNameConverter).optional(),
|
|
320
|
+
mergeMethod: CommonConvert.resourceValueMergeMethod.optional()
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Returns a `Converter` for a `Json.IResourceTreeChildNodeDecl<TQualifierNames>`
|
|
325
|
+
* narrowed on a supplied `qualifierName` converter.
|
|
326
|
+
*
|
|
327
|
+
* @public
|
|
328
|
+
*/
|
|
329
|
+
// Keep in sync with `resourceTreeChildNodeDecl` above.
|
|
330
|
+
export function typedResourceTreeChildNodeDecl(qualifierNameConverter) {
|
|
331
|
+
const childResource = typedChildResourceDecl(qualifierNameConverter);
|
|
332
|
+
return Converters.generic((from, self, context) => {
|
|
333
|
+
return Converters.strictObject({
|
|
334
|
+
resources: Converters.recordOf(childResource).optional(),
|
|
335
|
+
children: Converters.recordOf(self).optional()
|
|
336
|
+
}).convert(from, context);
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Returns a `Converter` for a `Json.IResourceTreeRootDecl<TQualifierNames>`
|
|
341
|
+
* narrowed on a supplied `qualifierName` converter.
|
|
342
|
+
*
|
|
343
|
+
* @public
|
|
344
|
+
*/
|
|
345
|
+
// Keep in sync with `resourceTreeRootDecl` above.
|
|
346
|
+
export function typedResourceTreeRootDecl(qualifierNameConverter) {
|
|
347
|
+
return Converters.strictObject({
|
|
348
|
+
context: typedContainerContextDecl(qualifierNameConverter).optional(),
|
|
349
|
+
resources: Converters.recordOf(typedChildResourceDecl(qualifierNameConverter)).optional(),
|
|
350
|
+
children: Converters.recordOf(typedResourceTreeChildNodeDecl(qualifierNameConverter)).optional()
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Returns a `Converter` for a `Json.IResourceCollectionDecl<TQualifierNames>`
|
|
355
|
+
* narrowed on a supplied `qualifierName` converter.
|
|
356
|
+
*
|
|
357
|
+
* @public
|
|
358
|
+
*/
|
|
359
|
+
// Keep in sync with `resourceCollectionDecl` above.
|
|
360
|
+
export function typedResourceCollectionDecl(qualifierNameConverter) {
|
|
361
|
+
const containerContext = typedContainerContextDecl(qualifierNameConverter);
|
|
362
|
+
const looseCandidate = typedLooseResourceCandidateDecl(qualifierNameConverter);
|
|
363
|
+
const looseResource = typedLooseResourceDecl(qualifierNameConverter);
|
|
364
|
+
return Converters.generic((from, self, context) => {
|
|
365
|
+
return Converters.strictObject({
|
|
366
|
+
context: containerContext.optional(),
|
|
367
|
+
candidates: Converters.arrayOf(looseCandidate).optional(),
|
|
368
|
+
resources: Converters.arrayOf(looseResource).optional(),
|
|
369
|
+
collections: Converters.arrayOf(self).optional(),
|
|
370
|
+
metadata: JsonConverters.jsonObject.optional()
|
|
371
|
+
}).convert(from, context);
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Returns a `Converter` for a `Json.IImporterResourceCollectionDecl<TQualifierNames>`
|
|
376
|
+
* narrowed on a supplied `qualifierName` converter.
|
|
377
|
+
*
|
|
378
|
+
* @public
|
|
379
|
+
*/
|
|
380
|
+
// Keep in sync with `importerResourceCollectionDecl` above.
|
|
381
|
+
export function typedImporterResourceCollectionDecl(qualifierNameConverter) {
|
|
382
|
+
const containerContext = typedContainerContextDecl(qualifierNameConverter);
|
|
383
|
+
const importerCandidate = typedImporterResourceCandidateDecl(qualifierNameConverter);
|
|
384
|
+
const looseResource = typedLooseResourceDecl(qualifierNameConverter);
|
|
385
|
+
const childResource = typedChildResourceDecl(qualifierNameConverter);
|
|
386
|
+
return Converters.generic((from, self, context) => {
|
|
387
|
+
return Converters.strictObject({
|
|
388
|
+
context: containerContext.optional(),
|
|
389
|
+
candidates: Converters.arrayOf(importerCandidate).optional(),
|
|
390
|
+
resources: Converters.arrayOf(Converters.oneOf([looseResource, childResource])).optional(),
|
|
391
|
+
collections: Converters.arrayOf(self).optional(),
|
|
392
|
+
metadata: JsonConverters.jsonObject.optional()
|
|
393
|
+
}).convert(from, context);
|
|
394
|
+
});
|
|
395
|
+
}
|
|
171
396
|
//# sourceMappingURL=convert.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convert.js","sourceRoot":"","sources":["../../../src/packlets/resource-json/convert.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Converter, Converters, mapResults, Result, fail } from '@fgv/ts-utils';\nimport { Convert as CommonConvert } from '../common';\nimport { isJsonObject, Converters as JsonConverters } from '@fgv/ts-json-base';\nimport * as Json from './json';\nimport * as Normalized from './normalized';\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Json.ILooseConditionDecl | loose condition declaration}.\n * @public\n */\nexport const looseConditionDecl: Converter<Json.ILooseConditionDecl> =\n Converters.strictObject<Json.ILooseConditionDecl>({\n qualifierName: CommonConvert.qualifierName,\n value: Converters.string,\n operator: CommonConvert.conditionOperator.optional(),\n priority: CommonConvert.conditionPriority.optional(),\n scoreAsDefault: Converters.number.optional()\n });\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Json.IChildConditionDecl | child condition declaration}.\n * @public\n */\nexport const childConditionDecl: Converter<Json.IChildConditionDecl> =\n Converters.strictObject<Json.IChildConditionDecl>({\n value: Converters.string,\n operator: CommonConvert.conditionOperator.optional(),\n priority: CommonConvert.conditionPriority.optional(),\n scoreAsDefault: Converters.number.optional()\n });\n\nfunction _isConditionSetRecord(from: unknown): from is Record<string, string | Json.IChildConditionDecl> {\n return isJsonObject(from);\n}\n\nconst conditionSetDeclFromArray: Converter<Normalized.ConditionSetDecl> =\n Converters.arrayOf(looseConditionDecl);\nconst conditionSetDeclFromRecord: Converter<Normalized.ConditionSetDecl> = Converters.generic<\n Normalized.ConditionSetDecl,\n unknown\n>(\n (\n from: unknown,\n __self: Converter<Normalized.ConditionSetDecl, unknown>,\n context?: unknown\n ): Result<Normalized.ConditionSetDecl> => {\n /* c8 ignore next 3 - this is tested but coverage is confused */\n if (!_isConditionSetRecord(from)) {\n return fail('Expected an object');\n }\n return mapResults(\n Array.from(Object.entries(from)).map(([qualifierName, value]) => {\n const toConvert: Json.ILooseConditionDecl =\n typeof value === 'string' ? { qualifierName, value } : { qualifierName, ...value };\n return looseConditionDecl.convert(toConvert, context);\n })\n );\n }\n);\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Normalized.ConditionSetDecl | condition set declaration}.\n * @public\n */\nexport const conditionSetDecl: Converter<Normalized.ConditionSetDecl> =\n Converters.oneOf<Normalized.ConditionSetDecl>([conditionSetDeclFromArray, conditionSetDeclFromRecord]);\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Json.ILooseResourceCandidateDecl | loose resource candidate declaration}.\n * @public\n */\nexport const looseResourceCandidateDecl: Converter<Normalized.ILooseResourceCandidateDecl> =\n Converters.strictObject<Normalized.ILooseResourceCandidateDecl>({\n id: CommonConvert.resourceId,\n json: JsonConverters.jsonObject,\n conditions: conditionSetDecl.optional(),\n mergeMethod: CommonConvert.resourceValueMergeMethod.optional(),\n isPartial: Converters.boolean.optional(),\n resourceTypeName: CommonConvert.resourceTypeName.optional()\n });\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Normalized.IImporterResourceCandidateDecl | importer resource candidate declaration}.\n * @public\n */\nexport const importerResourceCandidateDecl: Converter<Normalized.IImporterResourceCandidateDecl> =\n Converters.strictObject<Normalized.IImporterResourceCandidateDecl>({\n id: CommonConvert.resourceId.optional(),\n json: JsonConverters.jsonObject,\n conditions: conditionSetDecl.optional(),\n mergeMethod: CommonConvert.resourceValueMergeMethod.optional(),\n isPartial: Converters.boolean.optional(),\n resourceTypeName: CommonConvert.resourceTypeName.optional()\n });\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Json.IChildResourceCandidateDecl | child resource candidate declaration}.\n * @public\n */\nexport const childResourceCandidateDecl: Converter<Normalized.IChildResourceCandidateDecl> =\n Converters.strictObject<Normalized.IChildResourceCandidateDecl>({\n json: JsonConverters.jsonObject,\n conditions: conditionSetDecl.optional(),\n isPartial: Converters.boolean.optional(),\n mergeMethod: CommonConvert.resourceValueMergeMethod.optional()\n });\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Normalized.ILooseResourceDecl | loose resource declaration}.\n * @public\n */\nexport const looseResourceDecl: Converter<Normalized.ILooseResourceDecl> =\n Converters.strictObject<Normalized.ILooseResourceDecl>({\n id: CommonConvert.resourceId,\n resourceTypeName: CommonConvert.resourceTypeName,\n candidates: Converters.arrayOf(childResourceCandidateDecl).optional()\n });\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Normalized.IChildResourceDecl | child resource declaration}.\n * @public\n */\nexport const childResourceDecl: Converter<Normalized.IChildResourceDecl> =\n Converters.strictObject<Normalized.IChildResourceDecl>({\n resourceTypeName: CommonConvert.resourceTypeName,\n candidates: Converters.arrayOf(childResourceCandidateDecl).optional()\n });\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Normalized.IContainerContextDecl | resource context declaration}.\n * @public\n */\nexport const containerContextDecl: Converter<Normalized.IContainerContextDecl> =\n Converters.strictObject<Normalized.IContainerContextDecl>({\n baseId: Converters.oneOf([CommonConvert.resourceId, Converters.literal('')]).optional(),\n conditions: conditionSetDecl.optional(),\n mergeMethod: CommonConvert.resourceValueMergeMethod.optional()\n });\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Normalized.IResourceTreeChildNodeDecl | resource tree child node declaration}.\n * @public\n */\nexport const resourceTreeChildNodeDecl: Converter<Normalized.IResourceTreeChildNodeDecl> = Converters.generic<\n Normalized.IResourceTreeChildNodeDecl,\n unknown\n>(\n (\n from: unknown,\n self: Converter<Normalized.IResourceTreeChildNodeDecl, unknown>,\n context?: unknown\n ): Result<Normalized.IResourceTreeChildNodeDecl> => {\n return Converters.strictObject<Normalized.IResourceTreeChildNodeDecl>({\n resources: Converters.recordOf(childResourceDecl).optional(),\n children: Converters.recordOf(self).optional()\n }).convert(from, context);\n }\n);\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Normalized.IResourceTreeRootDecl | resource tree root declaration}.\n * @public\n */\nexport const resourceTreeRootDecl: Converter<Normalized.IResourceTreeRootDecl> =\n Converters.strictObject<Normalized.IResourceTreeRootDecl>({\n context: containerContextDecl.optional(),\n resources: Converters.recordOf(childResourceDecl).optional(),\n children: Converters.recordOf(resourceTreeChildNodeDecl).optional()\n });\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Normalized.IResourceCollectionDecl | resource collection declaration}.\n * @public\n */\nexport const resourceCollectionDecl: Converter<Normalized.IResourceCollectionDecl> = Converters.generic<\n Normalized.IResourceCollectionDecl,\n unknown\n>(\n (\n from: unknown,\n self: Converter<Normalized.IResourceCollectionDecl, unknown>,\n context?: unknown\n ): Result<Normalized.IResourceCollectionDecl> => {\n return Converters.strictObject<Normalized.IResourceCollectionDecl>({\n context: containerContextDecl.optional(),\n candidates: Converters.arrayOf(looseResourceCandidateDecl).optional(),\n resources: Converters.arrayOf(looseResourceDecl).optional(),\n collections: Converters.arrayOf(self).optional(),\n metadata: JsonConverters.jsonObject.optional()\n }).convert(from, context);\n }\n);\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Normalized.IImporterResourceCollectionDecl | importer resource collection declaration}.\n * This allows for a mix of loose and child resource declarations.\n * @public\n */\nexport const importerResourceCollectionDecl: Converter<Normalized.IImporterResourceCollectionDecl> =\n Converters.generic<Normalized.IImporterResourceCollectionDecl, unknown>(\n (\n from: unknown,\n self: Converter<Normalized.IImporterResourceCollectionDecl, unknown>,\n context?: unknown\n ): Result<Normalized.IImporterResourceCollectionDecl> => {\n return Converters.strictObject<Normalized.IImporterResourceCollectionDecl>({\n context: containerContextDecl.optional(),\n candidates: Converters.arrayOf(importerResourceCandidateDecl).optional(),\n resources: Converters.arrayOf(Converters.oneOf([looseResourceDecl, childResourceDecl])).optional(),\n collections: Converters.arrayOf(self).optional(),\n metadata: JsonConverters.jsonObject.optional()\n }).convert(from, context);\n }\n );\n"]}
|
|
1
|
+
{"version":3,"file":"convert.js","sourceRoot":"","sources":["../../../src/packlets/resource-json/convert.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Converter, Converters, mapResults, Result, fail } from '@fgv/ts-utils';\nimport { Convert as CommonConvert } from '../common';\nimport { isJsonObject, Converters as JsonConverters } from '@fgv/ts-json-base';\nimport * as Json from './json';\nimport * as Normalized from './normalized';\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Json.ILooseConditionDecl | loose condition declaration}.\n * @public\n */\nexport const looseConditionDecl: Converter<Json.ILooseConditionDecl> =\n Converters.strictObject<Json.ILooseConditionDecl>({\n qualifierName: CommonConvert.qualifierName,\n value: Converters.string,\n operator: CommonConvert.conditionOperator.optional(),\n priority: CommonConvert.conditionPriority.optional(),\n scoreAsDefault: Converters.number.optional()\n });\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Json.IChildConditionDecl | child condition declaration}.\n * @public\n */\nexport const childConditionDecl: Converter<Json.IChildConditionDecl> =\n Converters.strictObject<Json.IChildConditionDecl>({\n value: Converters.string,\n operator: CommonConvert.conditionOperator.optional(),\n priority: CommonConvert.conditionPriority.optional(),\n scoreAsDefault: Converters.number.optional()\n });\n\nfunction _isConditionSetRecord(from: unknown): from is Record<string, string | Json.IChildConditionDecl> {\n return isJsonObject(from);\n}\n\nconst conditionSetDeclFromArray: Converter<Normalized.ConditionSetDecl> =\n Converters.arrayOf(looseConditionDecl);\nconst conditionSetDeclFromRecord: Converter<Normalized.ConditionSetDecl> = Converters.generic<\n Normalized.ConditionSetDecl,\n unknown\n>(\n (\n from: unknown,\n __self: Converter<Normalized.ConditionSetDecl, unknown>,\n context?: unknown\n ): Result<Normalized.ConditionSetDecl> => {\n /* c8 ignore next 3 - this is tested but coverage is confused */\n if (!_isConditionSetRecord(from)) {\n return fail('Expected an object');\n }\n return mapResults(\n Array.from(Object.entries(from)).map(([qualifierName, value]) => {\n const toConvert: Json.ILooseConditionDecl =\n typeof value === 'string' ? { qualifierName, value } : { qualifierName, ...value };\n return looseConditionDecl.convert(toConvert, context);\n })\n );\n }\n);\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Normalized.ConditionSetDecl | condition set declaration}.\n * @public\n */\nexport const conditionSetDecl: Converter<Normalized.ConditionSetDecl> =\n Converters.oneOf<Normalized.ConditionSetDecl>([conditionSetDeclFromArray, conditionSetDeclFromRecord]);\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Json.ILooseResourceCandidateDecl | loose resource candidate declaration}.\n * @public\n */\nexport const looseResourceCandidateDecl: Converter<Normalized.ILooseResourceCandidateDecl> =\n Converters.strictObject<Normalized.ILooseResourceCandidateDecl>({\n id: CommonConvert.resourceId,\n json: JsonConverters.jsonObject,\n conditions: conditionSetDecl.optional(),\n mergeMethod: CommonConvert.resourceValueMergeMethod.optional(),\n isPartial: Converters.boolean.optional(),\n resourceTypeName: CommonConvert.resourceTypeName.optional()\n });\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Normalized.IImporterResourceCandidateDecl | importer resource candidate declaration}.\n * @public\n */\nexport const importerResourceCandidateDecl: Converter<Normalized.IImporterResourceCandidateDecl> =\n Converters.strictObject<Normalized.IImporterResourceCandidateDecl>({\n id: CommonConvert.resourceId.optional(),\n json: JsonConverters.jsonObject,\n conditions: conditionSetDecl.optional(),\n mergeMethod: CommonConvert.resourceValueMergeMethod.optional(),\n isPartial: Converters.boolean.optional(),\n resourceTypeName: CommonConvert.resourceTypeName.optional()\n });\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Json.IChildResourceCandidateDecl | child resource candidate declaration}.\n * @public\n */\nexport const childResourceCandidateDecl: Converter<Normalized.IChildResourceCandidateDecl> =\n Converters.strictObject<Normalized.IChildResourceCandidateDecl>({\n json: JsonConverters.jsonObject,\n conditions: conditionSetDecl.optional(),\n isPartial: Converters.boolean.optional(),\n mergeMethod: CommonConvert.resourceValueMergeMethod.optional()\n });\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Normalized.ILooseResourceDecl | loose resource declaration}.\n * @public\n */\nexport const looseResourceDecl: Converter<Normalized.ILooseResourceDecl> =\n Converters.strictObject<Normalized.ILooseResourceDecl>({\n id: CommonConvert.resourceId,\n resourceTypeName: CommonConvert.resourceTypeName,\n candidates: Converters.arrayOf(childResourceCandidateDecl).optional()\n });\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Normalized.IChildResourceDecl | child resource declaration}.\n * @public\n */\nexport const childResourceDecl: Converter<Normalized.IChildResourceDecl> =\n Converters.strictObject<Normalized.IChildResourceDecl>({\n resourceTypeName: CommonConvert.resourceTypeName,\n candidates: Converters.arrayOf(childResourceCandidateDecl).optional()\n });\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Normalized.IContainerContextDecl | resource context declaration}.\n * @public\n */\nexport const containerContextDecl: Converter<Normalized.IContainerContextDecl> =\n Converters.strictObject<Normalized.IContainerContextDecl>({\n baseId: Converters.oneOf([CommonConvert.resourceId, Converters.literal('')]).optional(),\n conditions: conditionSetDecl.optional(),\n mergeMethod: CommonConvert.resourceValueMergeMethod.optional()\n });\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Normalized.IResourceTreeChildNodeDecl | resource tree child node declaration}.\n * @public\n */\nexport const resourceTreeChildNodeDecl: Converter<Normalized.IResourceTreeChildNodeDecl> = Converters.generic<\n Normalized.IResourceTreeChildNodeDecl,\n unknown\n>(\n (\n from: unknown,\n self: Converter<Normalized.IResourceTreeChildNodeDecl, unknown>,\n context?: unknown\n ): Result<Normalized.IResourceTreeChildNodeDecl> => {\n return Converters.strictObject<Normalized.IResourceTreeChildNodeDecl>({\n resources: Converters.recordOf(childResourceDecl).optional(),\n children: Converters.recordOf(self).optional()\n }).convert(from, context);\n }\n);\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Normalized.IResourceTreeRootDecl | resource tree root declaration}.\n * @public\n */\nexport const resourceTreeRootDecl: Converter<Normalized.IResourceTreeRootDecl> =\n Converters.strictObject<Normalized.IResourceTreeRootDecl>({\n context: containerContextDecl.optional(),\n resources: Converters.recordOf(childResourceDecl).optional(),\n children: Converters.recordOf(resourceTreeChildNodeDecl).optional()\n });\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Normalized.IResourceCollectionDecl | resource collection declaration}.\n * @public\n */\nexport const resourceCollectionDecl: Converter<Normalized.IResourceCollectionDecl> = Converters.generic<\n Normalized.IResourceCollectionDecl,\n unknown\n>(\n (\n from: unknown,\n self: Converter<Normalized.IResourceCollectionDecl, unknown>,\n context?: unknown\n ): Result<Normalized.IResourceCollectionDecl> => {\n return Converters.strictObject<Normalized.IResourceCollectionDecl>({\n context: containerContextDecl.optional(),\n candidates: Converters.arrayOf(looseResourceCandidateDecl).optional(),\n resources: Converters.arrayOf(looseResourceDecl).optional(),\n collections: Converters.arrayOf(self).optional(),\n metadata: JsonConverters.jsonObject.optional()\n }).convert(from, context);\n }\n);\n\n/**\n * `Converter` for a normalized {@link ResourceJson.Normalized.IImporterResourceCollectionDecl | importer resource collection declaration}.\n * This allows for a mix of loose and child resource declarations.\n * @public\n */\nexport const importerResourceCollectionDecl: Converter<Normalized.IImporterResourceCollectionDecl> =\n Converters.generic<Normalized.IImporterResourceCollectionDecl, unknown>(\n (\n from: unknown,\n self: Converter<Normalized.IImporterResourceCollectionDecl, unknown>,\n context?: unknown\n ): Result<Normalized.IImporterResourceCollectionDecl> => {\n return Converters.strictObject<Normalized.IImporterResourceCollectionDecl>({\n context: containerContextDecl.optional(),\n candidates: Converters.arrayOf(importerResourceCandidateDecl).optional(),\n resources: Converters.arrayOf(Converters.oneOf([looseResourceDecl, childResourceDecl])).optional(),\n collections: Converters.arrayOf(self).optional(),\n metadata: JsonConverters.jsonObject.optional()\n }).convert(from, context);\n }\n );\n\n// --- Typed sibling converters (Phase B-2) -----------------------------------\n//\n// Each `typed*<TQualifierNames>(qualifierNameConverter)` returns a converter\n// whose result type is narrowed on `TQualifierNames`. The existing untyped\n// exports above remain unchanged at the signature and behavior level; consumers\n// opt in by calling a typed sibling. Internally each typed factory composes\n// lower-level typed factories so a single `qualifierNameConverter` flows\n// end-to-end through the converter tree.\n//\n// DRIFT HAZARD: each typed sibling duplicates the field list of its untyped\n// twin (the duplication exists to preserve `ObjectConverter` return types on\n// the defaults — see phase-b2-result.md). If a field is added, removed, or\n// re-typed on an untyped converter above, the typed sibling MUST be updated\n// in lockstep. The per-pair `keep in sync with X` markers below flag each\n// pair at the call site.\n\n/**\n * Returns a `Converter` for a `Json.ILooseConditionDecl<TQualifierNames>`\n * narrowed on a supplied `qualifierName` converter.\n *\n * @public\n */\n// Keep in sync with `looseConditionDecl` above.\nexport function typedLooseConditionDecl<TQualifierNames extends string>(\n qualifierNameConverter: Converter<TQualifierNames>\n): Converter<Json.ILooseConditionDecl<TQualifierNames>> {\n return Converters.strictObject<Json.ILooseConditionDecl<TQualifierNames>>({\n qualifierName: qualifierNameConverter,\n value: Converters.string,\n operator: CommonConvert.conditionOperator.optional(),\n priority: CommonConvert.conditionPriority.optional(),\n scoreAsDefault: Converters.number.optional()\n });\n}\n\nfunction _typedConditionSetDeclFromArray<TQualifierNames extends string>(\n innerLooseConditionDecl: Converter<Json.ILooseConditionDecl<TQualifierNames>>\n): Converter<Json.ConditionSetDeclAsArray<TQualifierNames>> {\n return Converters.arrayOf(innerLooseConditionDecl);\n}\n\nfunction _typedConditionSetDeclFromRecord<TQualifierNames extends string>(\n innerLooseConditionDecl: Converter<Json.ILooseConditionDecl<TQualifierNames>>\n): Converter<Json.ConditionSetDecl<TQualifierNames>> {\n return Converters.generic<Json.ConditionSetDecl<TQualifierNames>, unknown>(\n (\n from: unknown,\n __self: Converter<Json.ConditionSetDecl<TQualifierNames>, unknown>,\n context?: unknown\n ): Result<Json.ConditionSetDecl<TQualifierNames>> => {\n /* c8 ignore next 3 - branch covered by underlying record check */\n if (!_isConditionSetRecord(from)) {\n return fail('Expected an object');\n }\n return mapResults(\n Array.from(Object.entries(from)).map(([qualifierName, value]) => {\n const toConvert: Json.ILooseConditionDecl =\n typeof value === 'string' ? { qualifierName, value } : { qualifierName, ...value };\n return innerLooseConditionDecl.convert(toConvert, context);\n })\n );\n }\n );\n}\n\n/**\n * Returns a `Converter` for a `Json.ConditionSetDecl<TQualifierNames>`\n * (either array form or record form) narrowed on a supplied `qualifierName`\n * converter.\n *\n * @public\n */\n// Keep in sync with `conditionSetDecl` (and its two private feeder converters\n// `conditionSetDeclFromArray` / `conditionSetDeclFromRecord`) above.\nexport function typedConditionSetDecl<TQualifierNames extends string>(\n qualifierNameConverter: Converter<TQualifierNames>\n): Converter<Json.ConditionSetDecl<TQualifierNames>> {\n const inner = typedLooseConditionDecl(qualifierNameConverter);\n return Converters.oneOf<Json.ConditionSetDecl<TQualifierNames>>([\n _typedConditionSetDeclFromArray(inner),\n _typedConditionSetDeclFromRecord(inner)\n ]);\n}\n\n/**\n * Returns a `Converter` for a `Json.ILooseResourceCandidateDecl<TQualifierNames>`\n * narrowed on a supplied `qualifierName` converter.\n *\n * @public\n */\n// Keep in sync with `looseResourceCandidateDecl` above.\nexport function typedLooseResourceCandidateDecl<TQualifierNames extends string>(\n qualifierNameConverter: Converter<TQualifierNames>\n): Converter<Json.ILooseResourceCandidateDecl<TQualifierNames>> {\n return Converters.strictObject<Json.ILooseResourceCandidateDecl<TQualifierNames>>({\n id: CommonConvert.resourceId,\n json: JsonConverters.jsonObject,\n conditions: typedConditionSetDecl(qualifierNameConverter).optional(),\n mergeMethod: CommonConvert.resourceValueMergeMethod.optional(),\n isPartial: Converters.boolean.optional(),\n resourceTypeName: CommonConvert.resourceTypeName.optional()\n });\n}\n\n/**\n * Returns a `Converter` for a `Json.IImporterResourceCandidateDecl<TQualifierNames>`\n * narrowed on a supplied `qualifierName` converter.\n *\n * @public\n */\n// Keep in sync with `importerResourceCandidateDecl` above.\nexport function typedImporterResourceCandidateDecl<TQualifierNames extends string>(\n qualifierNameConverter: Converter<TQualifierNames>\n): Converter<Json.IImporterResourceCandidateDecl<TQualifierNames>> {\n return Converters.strictObject<Json.IImporterResourceCandidateDecl<TQualifierNames>>({\n id: CommonConvert.resourceId.optional(),\n json: JsonConverters.jsonObject,\n conditions: typedConditionSetDecl(qualifierNameConverter).optional(),\n mergeMethod: CommonConvert.resourceValueMergeMethod.optional(),\n isPartial: Converters.boolean.optional(),\n resourceTypeName: CommonConvert.resourceTypeName.optional()\n });\n}\n\n/**\n * Returns a `Converter` for a `Json.IChildResourceCandidateDecl<TQualifierNames>`\n * narrowed on a supplied `qualifierName` converter.\n *\n * @public\n */\n// Keep in sync with `childResourceCandidateDecl` above.\nexport function typedChildResourceCandidateDecl<TQualifierNames extends string>(\n qualifierNameConverter: Converter<TQualifierNames>\n): Converter<Json.IChildResourceCandidateDecl<TQualifierNames>> {\n return Converters.strictObject<Json.IChildResourceCandidateDecl<TQualifierNames>>({\n json: JsonConverters.jsonObject,\n conditions: typedConditionSetDecl(qualifierNameConverter).optional(),\n isPartial: Converters.boolean.optional(),\n mergeMethod: CommonConvert.resourceValueMergeMethod.optional()\n });\n}\n\n/**\n * Returns a `Converter` for a `Json.ILooseResourceDecl<TQualifierNames>`\n * narrowed on a supplied `qualifierName` converter.\n *\n * @public\n */\n// Keep in sync with `looseResourceDecl` above.\nexport function typedLooseResourceDecl<TQualifierNames extends string>(\n qualifierNameConverter: Converter<TQualifierNames>\n): Converter<Json.ILooseResourceDecl<TQualifierNames>> {\n return Converters.strictObject<Json.ILooseResourceDecl<TQualifierNames>>({\n id: CommonConvert.resourceId,\n resourceTypeName: CommonConvert.resourceTypeName,\n candidates: Converters.arrayOf(typedChildResourceCandidateDecl(qualifierNameConverter)).optional()\n });\n}\n\n/**\n * Returns a `Converter` for a `Json.IChildResourceDecl<TQualifierNames>`\n * narrowed on a supplied `qualifierName` converter.\n *\n * @public\n */\n// Keep in sync with `childResourceDecl` above.\nexport function typedChildResourceDecl<TQualifierNames extends string>(\n qualifierNameConverter: Converter<TQualifierNames>\n): Converter<Json.IChildResourceDecl<TQualifierNames>> {\n return Converters.strictObject<Json.IChildResourceDecl<TQualifierNames>>({\n resourceTypeName: CommonConvert.resourceTypeName,\n candidates: Converters.arrayOf(typedChildResourceCandidateDecl(qualifierNameConverter)).optional()\n });\n}\n\n/**\n * Returns a `Converter` for a `Json.IContainerContextDecl<TQualifierNames>`\n * narrowed on a supplied `qualifierName` converter.\n *\n * @public\n */\n// Keep in sync with `containerContextDecl` above.\nexport function typedContainerContextDecl<TQualifierNames extends string>(\n qualifierNameConverter: Converter<TQualifierNames>\n): Converter<Json.IContainerContextDecl<TQualifierNames>> {\n return Converters.strictObject<Json.IContainerContextDecl<TQualifierNames>>({\n baseId: Converters.oneOf([CommonConvert.resourceId, Converters.literal('')]).optional(),\n conditions: typedConditionSetDecl(qualifierNameConverter).optional(),\n mergeMethod: CommonConvert.resourceValueMergeMethod.optional()\n });\n}\n\n/**\n * Returns a `Converter` for a `Json.IResourceTreeChildNodeDecl<TQualifierNames>`\n * narrowed on a supplied `qualifierName` converter.\n *\n * @public\n */\n// Keep in sync with `resourceTreeChildNodeDecl` above.\nexport function typedResourceTreeChildNodeDecl<TQualifierNames extends string>(\n qualifierNameConverter: Converter<TQualifierNames>\n): Converter<Json.IResourceTreeChildNodeDecl<TQualifierNames>> {\n const childResource = typedChildResourceDecl(qualifierNameConverter);\n return Converters.generic<Json.IResourceTreeChildNodeDecl<TQualifierNames>, unknown>(\n (\n from: unknown,\n self: Converter<Json.IResourceTreeChildNodeDecl<TQualifierNames>, unknown>,\n context?: unknown\n ): Result<Json.IResourceTreeChildNodeDecl<TQualifierNames>> => {\n return Converters.strictObject<Json.IResourceTreeChildNodeDecl<TQualifierNames>>({\n resources: Converters.recordOf(childResource).optional(),\n children: Converters.recordOf(self).optional()\n }).convert(from, context);\n }\n );\n}\n\n/**\n * Returns a `Converter` for a `Json.IResourceTreeRootDecl<TQualifierNames>`\n * narrowed on a supplied `qualifierName` converter.\n *\n * @public\n */\n// Keep in sync with `resourceTreeRootDecl` above.\nexport function typedResourceTreeRootDecl<TQualifierNames extends string>(\n qualifierNameConverter: Converter<TQualifierNames>\n): Converter<Json.IResourceTreeRootDecl<TQualifierNames>> {\n return Converters.strictObject<Json.IResourceTreeRootDecl<TQualifierNames>>({\n context: typedContainerContextDecl(qualifierNameConverter).optional(),\n resources: Converters.recordOf(typedChildResourceDecl(qualifierNameConverter)).optional(),\n children: Converters.recordOf(typedResourceTreeChildNodeDecl(qualifierNameConverter)).optional()\n });\n}\n\n/**\n * Returns a `Converter` for a `Json.IResourceCollectionDecl<TQualifierNames>`\n * narrowed on a supplied `qualifierName` converter.\n *\n * @public\n */\n// Keep in sync with `resourceCollectionDecl` above.\nexport function typedResourceCollectionDecl<TQualifierNames extends string>(\n qualifierNameConverter: Converter<TQualifierNames>\n): Converter<Json.IResourceCollectionDecl<TQualifierNames>> {\n const containerContext = typedContainerContextDecl(qualifierNameConverter);\n const looseCandidate = typedLooseResourceCandidateDecl(qualifierNameConverter);\n const looseResource = typedLooseResourceDecl(qualifierNameConverter);\n return Converters.generic<Json.IResourceCollectionDecl<TQualifierNames>, unknown>(\n (\n from: unknown,\n self: Converter<Json.IResourceCollectionDecl<TQualifierNames>, unknown>,\n context?: unknown\n ): Result<Json.IResourceCollectionDecl<TQualifierNames>> => {\n return Converters.strictObject<Json.IResourceCollectionDecl<TQualifierNames>>({\n context: containerContext.optional(),\n candidates: Converters.arrayOf(looseCandidate).optional(),\n resources: Converters.arrayOf(looseResource).optional(),\n collections: Converters.arrayOf(self).optional(),\n metadata: JsonConverters.jsonObject.optional()\n }).convert(from, context);\n }\n );\n}\n\n/**\n * Returns a `Converter` for a `Json.IImporterResourceCollectionDecl<TQualifierNames>`\n * narrowed on a supplied `qualifierName` converter.\n *\n * @public\n */\n// Keep in sync with `importerResourceCollectionDecl` above.\nexport function typedImporterResourceCollectionDecl<TQualifierNames extends string>(\n qualifierNameConverter: Converter<TQualifierNames>\n): Converter<Json.IImporterResourceCollectionDecl<TQualifierNames>> {\n const containerContext = typedContainerContextDecl(qualifierNameConverter);\n const importerCandidate = typedImporterResourceCandidateDecl(qualifierNameConverter);\n const looseResource = typedLooseResourceDecl(qualifierNameConverter);\n const childResource = typedChildResourceDecl(qualifierNameConverter);\n return Converters.generic<Json.IImporterResourceCollectionDecl<TQualifierNames>, unknown>(\n (\n from: unknown,\n self: Converter<Json.IImporterResourceCollectionDecl<TQualifierNames>, unknown>,\n context?: unknown\n ): Result<Json.IImporterResourceCollectionDecl<TQualifierNames>> => {\n return Converters.strictObject<Json.IImporterResourceCollectionDecl<TQualifierNames>>({\n context: containerContext.optional(),\n candidates: Converters.arrayOf(importerCandidate).optional(),\n resources: Converters.arrayOf(Converters.oneOf([looseResource, childResource])).optional(),\n collections: Converters.arrayOf(self).optional(),\n metadata: JsonConverters.jsonObject.optional()\n }).convert(from, context);\n }\n );\n}\n"]}
|
|
@@ -24,13 +24,13 @@
|
|
|
24
24
|
* @public
|
|
25
25
|
*/
|
|
26
26
|
export function isLooseResourceCandidateDecl(decl) {
|
|
27
|
-
return 'id' in decl;
|
|
27
|
+
return 'id' in decl && typeof decl.id === 'string';
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
30
30
|
* Type guard function to check if a resource declaration is a loose resource declaration.
|
|
31
31
|
* @public
|
|
32
32
|
*/
|
|
33
33
|
export function isLooseResourceDecl(decl) {
|
|
34
|
-
return 'id' in decl;
|
|
34
|
+
return 'id' in decl && typeof decl.id === 'string';
|
|
35
35
|
}
|
|
36
36
|
//# sourceMappingURL=json.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json.js","sourceRoot":"","sources":["../../../src/packlets/resource-json/json.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAkQH;;;GAGG;AACH,MAAM,UAAU,4BAA4B,CAC1C,IAAoC;IAEpC,OAAO,IAAI,IAAI,IAAI,CAAC;AACtB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAA2B;IAC7D,OAAO,IAAI,IAAI,IAAI,CAAC;AACtB,CAAC","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { JsonObject } from '@fgv/ts-json-base';\nimport { ConditionOperator, ResourceValueMergeMethod } from '../common';\n\n/**\n * Non-validated loose declaration of a {@link Conditions.Condition | condition}.\n * @public\n */\nexport interface ILooseConditionDecl {\n /**\n * The name of the {@link Qualifiers.Qualifier | qualifier} to be compared.\n */\n qualifierName: string;\n /**\n * The value to be compared.\n */\n value: string;\n /**\n * The operator to be used in the comparison.\n * Default is 'matches'.\n */\n operator?: ConditionOperator;\n\n /**\n * The priority of the condition. Default is the default priority for the qualifier.\n */\n priority?: number;\n\n /**\n * The score to be used if the condition is used as a default.\n */\n scoreAsDefault?: number;\n}\n\n/**\n * Non-validated child declaration of a {@link Conditions.Condition | condition}.\n * @public\n */\nexport interface IChildConditionDecl {\n /**\n * The value to be compared.\n */\n value: string;\n /**\n * The operator to be used in the comparison.\n * Default is 'matches'.\n */\n operator?: ConditionOperator;\n\n /**\n * The priority of the condition. Default is the default priority for the qualifier.\n */\n priority?: number;\n\n /**\n * The score to be used if the condition is used as a default.\n */\n scoreAsDefault?: number;\n}\n\n/**\n * Non-validated declaration of a {@link Conditions.Condition | condition}.\n * @public\n */\nexport type ConditionSetDeclAsArray = ReadonlyArray<ILooseConditionDecl>;\n\n/**\n * Non-validated declaration of a {@link Conditions.Condition | condition}.\n * @public\n */\nexport type ConditionSetDeclAsRecord = Record<string, string | IChildConditionDecl>;\n\n/**\n * Non-validated declaration of a {@link Conditions.Condition | condition}.\n * @public\n */\nexport type ConditionSetDecl = ConditionSetDeclAsArray | ConditionSetDeclAsRecord;\n\n/**\n * Non-validated child declaration of a {@link Resources.ResourceCandidate | resource candidate}.\n * @public\n */\nexport interface IChildResourceCandidateDecl {\n /**\n * The JSON value of the resource.\n */\n readonly json: JsonObject;\n\n /**\n * The conditions that must be met for the resource to be selected.\n */\n readonly conditions?: ConditionSetDecl;\n\n /**\n * If true, the resource is only a partial representation of the full resource.\n */\n readonly isPartial?: boolean;\n\n /**\n * The merge method to be used when merging the resource into the existing resource.\n * default is 'augment'.\n */\n readonly mergeMethod?: ResourceValueMergeMethod;\n}\n\n/**\n * Non-validated declaration of a resource candidate for import,\n * which can be either a loose or child resource candidate.\n * @public\n */\nexport interface IImporterResourceCandidateDecl extends IChildResourceCandidateDecl {\n /**\n * The {@link ResourceId | id} of the resource.\n */\n readonly id?: string;\n\n /**\n * The name of the type of this resource.\n */\n readonly resourceTypeName?: string;\n}\n\n/**\n * Non-validated loose declaration of a {@link Resources.ResourceCandidate | resource candidate}.\n * @public\n */\nexport interface ILooseResourceCandidateDecl extends IChildResourceCandidateDecl {\n /**\n * The {@link ResourceId | id} of the resource.\n */\n readonly id: string;\n\n /**\n * The JSON value of the resource.\n */\n readonly json: JsonObject;\n\n /**\n * The conditions that must be met for the resource to be selected.\n */\n readonly conditions?: ConditionSetDecl;\n\n /**\n * If true, the resource is only a partial representation of the full resource.\n */\n readonly isPartial?: boolean;\n\n /**\n * The merge method to be used when merging the resource into the existing resource.\n * default is 'augment'.\n */\n readonly mergeMethod?: ResourceValueMergeMethod;\n\n /**\n * The type of the resource.\n */\n readonly resourceTypeName?: string;\n}\n\n/**\n * Non-validated child declaration of a {@link Resources.Resource | resource}.\n * @public\n */\nexport interface IChildResourceDecl {\n /**\n * The name of the type of this resource.\n */\n readonly resourceTypeName: string;\n\n /**\n * Possible candidates for this value.\n */\n readonly candidates?: ReadonlyArray<IChildResourceCandidateDecl>;\n}\n\n/**\n * Non-validated loose declaration of a {@link Resources.Resource | resource}.\n * @public\n */\nexport interface ILooseResourceDecl extends IChildResourceDecl {\n /**\n * The id of the resource.\n */\n readonly id: string;\n\n /**\n * The name of the type of this resource.\n */\n readonly resourceTypeName: string;\n\n /**\n * Possible candidates for this value.\n */\n readonly candidates?: ReadonlyArray<IChildResourceCandidateDecl>;\n}\n\n/**\n * Normalized non-validated declaration of a {@link Resources.Resource | resource} tree node.\n * @public\n */\nexport interface IResourceTreeChildNodeDecl {\n readonly resources?: Record<string, IChildResourceDecl>;\n readonly children?: Record<string, IResourceTreeChildNodeDecl>;\n}\n\n/**\n * Declared context for a resource container.\n * @public\n */\nexport interface IContainerContextDecl {\n readonly baseId?: string;\n readonly conditions?: ConditionSetDecl;\n readonly mergeMethod?: ResourceValueMergeMethod;\n}\n\n/**\n * Normalized non-validated declaration of a {@link Resources.Resource | resource} tree root.\n * @public\n */\nexport interface IResourceTreeRootDecl extends IResourceTreeChildNodeDecl {\n readonly context?: IContainerContextDecl;\n readonly resources?: Record<string, IChildResourceDecl>;\n readonly children?: Record<string, IResourceTreeChildNodeDecl>;\n readonly metadata?: JsonObject;\n}\n\n/**\n * Non-validated declaration of a collection of resources.\n * @public\n */\nexport interface IResourceCollectionDecl {\n readonly context?: IContainerContextDecl;\n readonly candidates?: ReadonlyArray<ILooseResourceCandidateDecl>;\n readonly resources?: ReadonlyArray<ILooseResourceDecl>;\n readonly collections?: ReadonlyArray<IResourceCollectionDecl>;\n readonly metadata?: JsonObject;\n}\n\n/**\n * Non-validated declaration of a resource for import,\n * which can be either a loose or child resource.\n * @public\n */\nexport type IImporterResourceDecl = ILooseResourceDecl | IChildResourceDecl;\n\n/**\n * Non-validated declaration of a collection of resources for an importer.\n * @public\n */\nexport interface IImporterResourceCollectionDecl {\n readonly context?: IContainerContextDecl;\n readonly candidates?: ReadonlyArray<IImporterResourceCandidateDecl>;\n readonly resources?: ReadonlyArray<IImporterResourceDecl>;\n readonly collections?: ReadonlyArray<IImporterResourceCollectionDecl>;\n readonly metadata?: JsonObject;\n}\n\n/**\n * Type guard function to check if a resource candidate declaration is a loose resource candidate declaration.\n * @public\n */\nexport function isLooseResourceCandidateDecl(\n decl: IImporterResourceCandidateDecl\n): decl is ILooseResourceCandidateDecl {\n return 'id' in decl;\n}\n\n/**\n * Type guard function to check if a resource declaration is a loose resource declaration.\n * @public\n */\nexport function isLooseResourceDecl(decl: IImporterResourceDecl): decl is ILooseResourceDecl {\n return 'id' in decl;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"json.js","sourceRoot":"","sources":["../../../src/packlets/resource-json/json.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAuWH;;;GAGG;AACH,MAAM,UAAU,4BAA4B,CAC1C,IAAqD;IAErD,OAAO,IAAI,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ,CAAC;AACrD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAA4C;IAE5C,OAAO,IAAI,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ,CAAC;AACrD,CAAC","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { JsonObject } from '@fgv/ts-json-base';\nimport { ConditionOperator, ResourceValueMergeMethod } from '../common';\n\n/**\n * Non-validated loose declaration of a {@link Conditions.Condition | condition}.\n *\n * @remarks\n * Parameterized on `TQualifierNames` so consumers authoring conditions\n * in code can opt into compile-time axis-name discipline (e.g. via a\n * literal-string union derived from a `qualifiers: ['tone'] as const`\n * decl-array). Defaults to `string`, so existing untyped callers\n * compile unchanged.\n *\n * @public\n */\nexport interface ILooseConditionDecl<TQualifierNames extends string = string> {\n /**\n * The name of the {@link Qualifiers.Qualifier | qualifier} to be compared.\n */\n qualifierName: TQualifierNames;\n /**\n * The value to be compared.\n */\n value: string;\n /**\n * The operator to be used in the comparison.\n * Default is 'matches'.\n */\n operator?: ConditionOperator;\n\n /**\n * The priority of the condition. Default is the default priority for the qualifier.\n */\n priority?: number;\n\n /**\n * The score to be used if the condition is used as a default.\n */\n scoreAsDefault?: number;\n}\n\n/**\n * Non-validated child declaration of a {@link Conditions.Condition | condition}.\n * @public\n */\nexport interface IChildConditionDecl {\n /**\n * The value to be compared.\n */\n value: string;\n /**\n * The operator to be used in the comparison.\n * Default is 'matches'.\n */\n operator?: ConditionOperator;\n\n /**\n * The priority of the condition. Default is the default priority for the qualifier.\n */\n priority?: number;\n\n /**\n * The score to be used if the condition is used as a default.\n */\n scoreAsDefault?: number;\n}\n\n/**\n * Non-validated array-form declaration of a {@link Conditions.ConditionSet | condition set}.\n *\n * @remarks\n * Parameterized on `TQualifierNames` via `ILooseConditionDecl`;\n * defaults to `string` for back-compat with existing untyped callers.\n *\n * @public\n */\nexport type ConditionSetDeclAsArray<TQualifierNames extends string = string> = ReadonlyArray<\n ILooseConditionDecl<TQualifierNames>\n>;\n\n/**\n * Non-validated record-form declaration of a {@link Conditions.ConditionSet | condition set}.\n *\n * @remarks\n * Parameterized on `TQualifierNames`; defaults to `string` for back-compat with\n * existing untyped callers. Uses `Readonly<Partial<Record<...>>>` to align with\n * runtime reality (missing keys produce `undefined`; the `Partial` makes TypeScript\n * aware of this, which is a strict type-system tightening).\n *\n * @public\n */\nexport type ConditionSetDeclAsRecord<TQualifierNames extends string = string> = Readonly<\n Partial<Record<TQualifierNames, string | IChildConditionDecl>>\n>;\n\n/**\n * Non-validated declaration of a {@link Conditions.ConditionSet | condition set}.\n *\n * @remarks\n * Parameterized on `TQualifierNames`; defaults to `string`. Both the\n * array form (`ConditionSetDeclAsArray`) and the record form\n * (`ConditionSetDeclAsRecord`) inherit the parameter, so a\n * consumer threading a narrow `TQualifierNames` gets compile-time\n * rejection of typo'd axis names in either form.\n *\n * @public\n */\nexport type ConditionSetDecl<TQualifierNames extends string = string> =\n | ConditionSetDeclAsArray<TQualifierNames>\n | ConditionSetDeclAsRecord<TQualifierNames>;\n\n/**\n * Non-validated child declaration of a {@link Resources.ResourceCandidate | resource candidate}.\n *\n * @remarks\n * Parameterized on `TQualifierNames` so the `conditions` field can carry a\n * narrowed axis-name set. Defaults to `string` so existing untyped callers\n * compile unchanged.\n *\n * @public\n */\nexport interface IChildResourceCandidateDecl<TQualifierNames extends string = string> {\n /**\n * The JSON value of the resource.\n */\n readonly json: JsonObject;\n\n /**\n * The conditions that must be met for the resource to be selected.\n */\n readonly conditions?: ConditionSetDecl<TQualifierNames>;\n\n /**\n * If true, the resource is only a partial representation of the full resource.\n */\n readonly isPartial?: boolean;\n\n /**\n * The merge method to be used when merging the resource into the existing resource.\n * default is 'augment'.\n */\n readonly mergeMethod?: ResourceValueMergeMethod;\n}\n\n/**\n * Non-validated declaration of a resource candidate for import,\n * which can be either a loose or child resource candidate.\n *\n * @remarks\n * Parameterized on `TQualifierNames`; inherits via `IChildResourceCandidateDecl`.\n * Defaults to `string` for back-compat.\n *\n * @public\n */\nexport interface IImporterResourceCandidateDecl<TQualifierNames extends string = string>\n extends IChildResourceCandidateDecl<TQualifierNames> {\n /**\n * The {@link ResourceId | id} of the resource.\n */\n readonly id?: string;\n\n /**\n * The name of the type of this resource.\n */\n readonly resourceTypeName?: string;\n}\n\n/**\n * Non-validated loose declaration of a {@link Resources.ResourceCandidate | resource candidate}.\n *\n * @remarks\n * Parameterized on `TQualifierNames`; inherits via `IChildResourceCandidateDecl`.\n * Defaults to `string` for back-compat.\n *\n * @public\n */\nexport interface ILooseResourceCandidateDecl<TQualifierNames extends string = string>\n extends IChildResourceCandidateDecl<TQualifierNames> {\n /**\n * The {@link ResourceId | id} of the resource.\n */\n readonly id: string;\n\n /**\n * The JSON value of the resource.\n */\n readonly json: JsonObject;\n\n /**\n * The conditions that must be met for the resource to be selected.\n */\n readonly conditions?: ConditionSetDecl<TQualifierNames>;\n\n /**\n * If true, the resource is only a partial representation of the full resource.\n */\n readonly isPartial?: boolean;\n\n /**\n * The merge method to be used when merging the resource into the existing resource.\n * default is 'augment'.\n */\n readonly mergeMethod?: ResourceValueMergeMethod;\n\n /**\n * The type of the resource.\n */\n readonly resourceTypeName?: string;\n}\n\n/**\n * Non-validated child declaration of a {@link Resources.Resource | resource}.\n *\n * @remarks\n * Parameterized on `TQualifierNames` so the `candidates` field threads the\n * narrowed axis-name set down to each candidate. Defaults to `string` for\n * back-compat.\n *\n * @public\n */\nexport interface IChildResourceDecl<TQualifierNames extends string = string> {\n /**\n * The name of the type of this resource.\n */\n readonly resourceTypeName: string;\n\n /**\n * Possible candidates for this value.\n */\n readonly candidates?: ReadonlyArray<IChildResourceCandidateDecl<TQualifierNames>>;\n}\n\n/**\n * Non-validated loose declaration of a {@link Resources.Resource | resource}.\n *\n * @remarks\n * Parameterized on `TQualifierNames`; inherits via `IChildResourceDecl`.\n * Defaults to `string` for back-compat.\n *\n * @public\n */\nexport interface ILooseResourceDecl<TQualifierNames extends string = string>\n extends IChildResourceDecl<TQualifierNames> {\n /**\n * The id of the resource.\n */\n readonly id: string;\n\n /**\n * The name of the type of this resource.\n */\n readonly resourceTypeName: string;\n\n /**\n * Possible candidates for this value.\n */\n readonly candidates?: ReadonlyArray<IChildResourceCandidateDecl<TQualifierNames>>;\n}\n\n/**\n * Normalized non-validated declaration of a {@link Resources.Resource | resource} tree node.\n *\n * @remarks\n * Parameterized on `TQualifierNames` so the `resources` and `children` fields\n * thread the narrowed axis-name set throughout the tree. Defaults to `string` for\n * back-compat.\n *\n * @public\n */\nexport interface IResourceTreeChildNodeDecl<TQualifierNames extends string = string> {\n readonly resources?: Record<string, IChildResourceDecl<TQualifierNames>>;\n readonly children?: Record<string, IResourceTreeChildNodeDecl<TQualifierNames>>;\n}\n\n/**\n * Declared context for a resource container.\n *\n * @remarks\n * Parameterized on `TQualifierNames` so the `conditions` field threads the\n * narrowed axis-name set to the container context. Defaults to `string` for\n * back-compat.\n *\n * @public\n */\nexport interface IContainerContextDecl<TQualifierNames extends string = string> {\n readonly baseId?: string;\n readonly conditions?: ConditionSetDecl<TQualifierNames>;\n readonly mergeMethod?: ResourceValueMergeMethod;\n}\n\n/**\n * Normalized non-validated declaration of a {@link Resources.Resource | resource} tree root.\n *\n * @remarks\n * Parameterized on `TQualifierNames` so the `context` field threads the\n * narrowed axis-name set to the tree root context. Defaults to `string` for\n * back-compat.\n *\n * @public\n */\nexport interface IResourceTreeRootDecl<TQualifierNames extends string = string>\n extends IResourceTreeChildNodeDecl<TQualifierNames> {\n readonly context?: IContainerContextDecl<TQualifierNames>;\n readonly resources?: Record<string, IChildResourceDecl<TQualifierNames>>;\n readonly children?: Record<string, IResourceTreeChildNodeDecl<TQualifierNames>>;\n readonly metadata?: JsonObject;\n}\n\n/**\n * Non-validated declaration of a collection of resources.\n *\n * @remarks\n * Parameterized on `TQualifierNames` so the `context`, `candidates`, and\n * `resources` fields thread the narrowed axis-name set throughout the\n * collection. Defaults to `string` for back-compat.\n *\n * @public\n */\nexport interface IResourceCollectionDecl<TQualifierNames extends string = string> {\n readonly context?: IContainerContextDecl<TQualifierNames>;\n readonly candidates?: ReadonlyArray<ILooseResourceCandidateDecl<TQualifierNames>>;\n readonly resources?: ReadonlyArray<ILooseResourceDecl<TQualifierNames>>;\n readonly collections?: ReadonlyArray<IResourceCollectionDecl<TQualifierNames>>;\n readonly metadata?: JsonObject;\n}\n\n/**\n * Non-validated declaration of a resource for import,\n * which can be either a loose or child resource.\n *\n * @remarks\n * Parameterized on `TQualifierNames`; defaults to `string` for back-compat.\n *\n * @public\n */\nexport type IImporterResourceDecl<TQualifierNames extends string = string> =\n | ILooseResourceDecl<TQualifierNames>\n | IChildResourceDecl<TQualifierNames>;\n\n/**\n * Non-validated declaration of a collection of resources for an importer.\n *\n * @remarks\n * Parameterized on `TQualifierNames` so the `context`, `candidates`, and\n * `resources` fields thread the narrowed axis-name set throughout the\n * importer collection. Defaults to `string` for back-compat.\n *\n * @public\n */\nexport interface IImporterResourceCollectionDecl<TQualifierNames extends string = string> {\n readonly context?: IContainerContextDecl<TQualifierNames>;\n readonly candidates?: ReadonlyArray<IImporterResourceCandidateDecl<TQualifierNames>>;\n readonly resources?: ReadonlyArray<IImporterResourceDecl<TQualifierNames>>;\n readonly collections?: ReadonlyArray<IImporterResourceCollectionDecl<TQualifierNames>>;\n readonly metadata?: JsonObject;\n}\n\n/**\n * Type guard function to check if a resource candidate declaration is a loose resource candidate declaration.\n * @public\n */\nexport function isLooseResourceCandidateDecl<TQualifierNames extends string = string>(\n decl: IImporterResourceCandidateDecl<TQualifierNames>\n): decl is ILooseResourceCandidateDecl<TQualifierNames> {\n return 'id' in decl && typeof decl.id === 'string';\n}\n\n/**\n * Type guard function to check if a resource declaration is a loose resource declaration.\n * @public\n */\nexport function isLooseResourceDecl<TQualifierNames extends string = string>(\n decl: IImporterResourceDecl<TQualifierNames>\n): decl is ILooseResourceDecl<TQualifierNames> {\n return 'id' in decl && typeof decl.id === 'string';\n}\n"]}
|
|
@@ -44,6 +44,9 @@ export class SimpleContextQualifierProvider extends ContextQualifierProvider {
|
|
|
44
44
|
this._qualifierValues = new ResultMap();
|
|
45
45
|
if (params.qualifierValues) {
|
|
46
46
|
for (const [name, value] of Object.entries(params.qualifierValues)) {
|
|
47
|
+
if (value === undefined) {
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
47
50
|
const qualifierName = Validate.toQualifierName(name).orThrow();
|
|
48
51
|
this._qualifierValues.set(qualifierName, value);
|
|
49
52
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simpleContextQualifierProvider.js","sourceRoot":"","sources":["../../../../src/packlets/runtime/context/simpleContextQualifierProvider.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Result, ResultMap, captureResult, succeed, succeedWithDetail, Converters } from '@fgv/ts-utils';\nimport {\n QualifierName,\n QualifierContextValue,\n QualifierIndex,\n Validate,\n Convert as CommonConverters\n} from '../../common';\nimport { IReadOnlyQualifierCollector, Qualifier } from '../../qualifiers';\nimport { ContextQualifierProvider, IMutableContextQualifierProvider } from './contextQualifierProvider';\n\n/**\n * Parameters for creating a {@link Runtime.SimpleContextQualifierProvider | SimpleContextQualifierProvider}.\n * @public\n */\nexport interface ISimpleContextQualifierProviderCreateParams {\n /**\n * The {@link Qualifiers.IReadOnlyQualifierCollector | readonly qualifier collector} that defines and validates qualifiers.\n */\n qualifiers: IReadOnlyQualifierCollector;\n\n /**\n * Optional record of initial qualifier name-value pairs to populate the provider.\n */\n qualifierValues?: Record<string, QualifierContextValue>;\n}\n\n/**\n * Simple concrete implementation of {@link Runtime.Context.IContextQualifierProvider | IContextQualifierProvider}\n * using a `ResultMap` for qualifier value storage.\n * @public\n */\nexport class SimpleContextQualifierProvider\n extends ContextQualifierProvider\n implements IMutableContextQualifierProvider\n{\n /**\n * Explicit mutability marker for compile-time type discrimination.\n * Always `true` for mutable providers.\n */\n public readonly mutable: true = true as const;\n\n /**\n * The readonly qualifier collector that defines and validates the qualifiers for this context.\n */\n public readonly qualifiers: IReadOnlyQualifierCollector;\n\n /**\n * Internal storage for qualifier values using a ResultMap.\n */\n private readonly _qualifierValues: ResultMap<QualifierName, QualifierContextValue>;\n\n /**\n * Constructor for a {@link Runtime.SimpleContextQualifierProvider | SimpleContextQualifierProvider} object.\n * @param params - {@link Runtime.ISimpleContextQualifierProviderCreateParams | Parameters} used to create the provider.\n */\n protected constructor(params: ISimpleContextQualifierProviderCreateParams) {\n super();\n this.qualifiers = params.qualifiers;\n this._qualifierValues = new ResultMap<QualifierName, QualifierContextValue>();\n\n if (params.qualifierValues) {\n for (const [name, value] of Object.entries(params.qualifierValues)) {\n const qualifierName = Validate.toQualifierName(name).orThrow();\n this._qualifierValues.set(qualifierName, value);\n }\n }\n }\n\n /**\n * Creates a new {@link Runtime.SimpleContextQualifierProvider | SimpleContextQualifierProvider} object.\n * @param params - {@link Runtime.ISimpleContextQualifierProviderCreateParams | Parameters} used to create the provider.\n * @returns `Success` with the new {@link Runtime.SimpleContextQualifierProvider | SimpleContextQualifierProvider} object if successful,\n * or `Failure` with an error message if not.\n * @public\n */\n public static create(\n params: ISimpleContextQualifierProviderCreateParams\n ): Result<SimpleContextQualifierProvider> {\n return captureResult(() => new SimpleContextQualifierProvider(params));\n }\n\n /**\n * Gets a qualifier value by its name, index, or qualifier object.\n * @param nameOrIndexOrQualifier - The {@link QualifierName | qualifier name}, {@link QualifierIndex | index}, or {@link Qualifiers.Qualifier | qualifier object} to look up.\n * @returns `Success` with the {@link QualifierContextValue | qualifier context value} if found,\n * or `Failure` with an error message if not found or an error occurs.\n */\n public get(\n nameOrIndexOrQualifier: QualifierName | QualifierIndex | Qualifier\n ): Result<QualifierContextValue> {\n return this._resolveQualifierName(nameOrIndexOrQualifier).onSuccess((qualifierName) => {\n return this._qualifierValues.get(qualifierName);\n });\n }\n\n /**\n * Gets a validated qualifier context value by its name, index, or qualifier object.\n * TODO: Implement validation logic using qualifier collectors.\n * @param nameOrIndexOrQualifier - The {@link QualifierName | qualifier name}, {@link QualifierIndex | index}, or {@link Qualifiers.Qualifier | qualifier object} to look up.\n * @returns `Success` with the validated {@link QualifierContextValue | qualifier context value} if found,\n * or `Failure` with an error message if not found, invalid, or an error occurs.\n */\n public getValidated(\n nameOrIndexOrQualifier: QualifierName | QualifierIndex | Qualifier\n ): Result<QualifierContextValue> {\n return this._resolveQualifier(nameOrIndexOrQualifier).onSuccess((qualifier) => {\n return this._qualifierValues.get(qualifier.name).asResult.onSuccess((value) => {\n return qualifier.validateContextValue(value);\n });\n });\n }\n\n /**\n * Checks if a qualifier value exists with the given name.\n * @param name - The {@link QualifierName | qualifier name} to check.\n * @returns `Success` with `true` if the qualifier value exists, `false` if it doesn't,\n * or `Failure` with an error message if an error occurs during the check.\n */\n public has(name: QualifierName): Result<boolean> {\n return succeed(this._qualifierValues.has(name));\n }\n\n /**\n * Gets all available qualifier names in this context.\n * @returns `Success` with an array of all {@link QualifierName | qualifier names},\n * or `Failure` with an error message if an error occurs.\n */\n public getNames(): Result<ReadonlyArray<QualifierName>> {\n return succeed(Array.from(this._qualifierValues.keys()));\n }\n\n /**\n * Sets a qualifier value in this provider.\n * @param name - The {@link QualifierName | qualifier name} to set.\n * @param value - The {@link QualifierContextValue | qualifier context value} to set.\n * @returns `Success` with the set {@link QualifierContextValue | qualifier context value} if successful,\n * or `Failure` with an error message if not.\n * @public\n */\n public set(name: QualifierName, value: QualifierContextValue): Result<QualifierContextValue> {\n this._qualifierValues.set(name, value);\n return succeed(value);\n }\n\n /**\n * Removes a qualifier value from this provider.\n * @param name - The {@link QualifierName | qualifier name} to remove.\n * @returns `Success` with the removed {@link QualifierContextValue | qualifier context value} if successful,\n * or `Failure` with an error message if not found or an error occurs.\n * @public\n */\n public remove(name: QualifierName): Result<QualifierContextValue> {\n return this._qualifierValues.get(name).onSuccess((value) => {\n this._qualifierValues.delete(name);\n return succeedWithDetail(value, 'success');\n });\n }\n\n /**\n * Gets the number of qualifier values in this provider.\n * @returns The count of qualifier values.\n * @public\n */\n public get size(): number {\n return this._qualifierValues.size;\n }\n\n /**\n * Clears all qualifier values from this provider.\n * @public\n */\n public clear(): void {\n this._qualifierValues.clear();\n }\n\n /**\n * Resolves a qualifier from a name, index, or qualifier object.\n * @param nameOrIndexOrQualifier - The input to resolve.\n * @returns `Success` with the {@link Qualifier | qualifier} if successful,\n * or `Failure` with an error message if not found or invalid.\n * @internal\n */\n private _resolveQualifier(\n nameOrIndexOrQualifier: QualifierName | QualifierIndex | Qualifier\n ): Result<Qualifier> {\n if (nameOrIndexOrQualifier instanceof Qualifier) {\n return succeed(nameOrIndexOrQualifier);\n }\n /* c8 ignore next 16 - functional code tested but coverage intermittently missed */\n if (typeof nameOrIndexOrQualifier === 'string') {\n return this.qualifiers.validating\n .get(nameOrIndexOrQualifier)\n .withErrorFormat((error) => `${nameOrIndexOrQualifier}: invalid qualifier name.`);\n }\n\n if (typeof nameOrIndexOrQualifier === 'number') {\n return this.qualifiers\n .getAt(nameOrIndexOrQualifier)\n .withErrorFormat((error) => `${nameOrIndexOrQualifier}: invalid qualifier index.`);\n }\n\n return SimpleContextQualifierProvider._qualifierNameFromQualifierLike(nameOrIndexOrQualifier)\n .onSuccess((qualifierName) => this.qualifiers.validating.get(qualifierName))\n .withErrorFormat((error) => `${nameOrIndexOrQualifier}: invalid Qualifier, name or index.`);\n }\n\n /**\n * Resolves a qualifier name from a name, index, or qualifier object.\n * @param nameOrIndexOrQualifier - The input to resolve.\n * @returns `Success` with the {@link QualifierName | qualifier name} if successful,\n * or `Failure` with an error message if not found or invalid.\n * @internal\n */\n private _resolveQualifierName(\n nameOrIndexOrQualifier: QualifierName | QualifierIndex | Qualifier\n ): Result<QualifierName> {\n return this._resolveQualifier(nameOrIndexOrQualifier).onSuccess((qualifier) => succeed(qualifier.name));\n }\n\n /**\n * Resolves a qualifier name from a qualifier-like object.\n * @param nameOrIndexOrQualifier - The input to resolve.\n * @returns `Success` with the {@link QualifierName | qualifier name} if successful,\n * or `Failure` with an error message if not found or invalid.\n * @internal\n */\n private static _qualifierNameFromQualifierLike(\n nameOrIndexOrQualifier: QualifierName | QualifierIndex | Qualifier\n ): Result<QualifierName> {\n return Converters.isA(\n 'Qualifier-like object',\n (v): v is { name: QualifierName } =>\n typeof v === 'object' &&\n v !== null &&\n 'name' in v &&\n typeof (v as Record<string, unknown>).name === 'string'\n )\n .map((v) => CommonConverters.qualifierName.convert(v.name))\n .convert(nameOrIndexOrQualifier);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"simpleContextQualifierProvider.js","sourceRoot":"","sources":["../../../../src/packlets/runtime/context/simpleContextQualifierProvider.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Result, ResultMap, captureResult, succeed, succeedWithDetail, Converters } from '@fgv/ts-utils';\nimport {\n QualifierName,\n QualifierContextValue,\n QualifierIndex,\n Validate,\n Convert as CommonConverters\n} from '../../common';\nimport { IReadOnlyQualifierCollector, Qualifier } from '../../qualifiers';\nimport { ContextQualifierProvider, IMutableContextQualifierProvider } from './contextQualifierProvider';\n\n/**\n * Parameters for creating a {@link Runtime.SimpleContextQualifierProvider | SimpleContextQualifierProvider}.\n * @public\n */\nexport interface ISimpleContextQualifierProviderCreateParams {\n /**\n * The {@link Qualifiers.IReadOnlyQualifierCollector | readonly qualifier collector} that defines and validates qualifiers.\n */\n qualifiers: IReadOnlyQualifierCollector;\n\n /**\n * Optional record of initial qualifier name-value pairs to populate the provider.\n *\n * @remarks\n * Typed as `Readonly<Partial<Record<string, QualifierContextValue>>>` so a\n * caller can naturally express conditional context construction, e.g.\n * `tone === 'formal' ? { tone: 'formal' } : {}`. Entries whose value is\n * `undefined` are skipped on load - semantically equivalent to omitting\n * the key, which is how the candidate selector treats a missing key.\n */\n qualifierValues?: Readonly<Partial<Record<string, QualifierContextValue>>>;\n}\n\n/**\n * Simple concrete implementation of {@link Runtime.Context.IContextQualifierProvider | IContextQualifierProvider}\n * using a `ResultMap` for qualifier value storage.\n * @public\n */\nexport class SimpleContextQualifierProvider\n extends ContextQualifierProvider\n implements IMutableContextQualifierProvider\n{\n /**\n * Explicit mutability marker for compile-time type discrimination.\n * Always `true` for mutable providers.\n */\n public readonly mutable: true = true as const;\n\n /**\n * The readonly qualifier collector that defines and validates the qualifiers for this context.\n */\n public readonly qualifiers: IReadOnlyQualifierCollector;\n\n /**\n * Internal storage for qualifier values using a ResultMap.\n */\n private readonly _qualifierValues: ResultMap<QualifierName, QualifierContextValue>;\n\n /**\n * Constructor for a {@link Runtime.SimpleContextQualifierProvider | SimpleContextQualifierProvider} object.\n * @param params - {@link Runtime.ISimpleContextQualifierProviderCreateParams | Parameters} used to create the provider.\n */\n protected constructor(params: ISimpleContextQualifierProviderCreateParams) {\n super();\n this.qualifiers = params.qualifiers;\n this._qualifierValues = new ResultMap<QualifierName, QualifierContextValue>();\n\n if (params.qualifierValues) {\n for (const [name, value] of Object.entries(params.qualifierValues)) {\n if (value === undefined) {\n continue;\n }\n const qualifierName = Validate.toQualifierName(name).orThrow();\n this._qualifierValues.set(qualifierName, value);\n }\n }\n }\n\n /**\n * Creates a new {@link Runtime.SimpleContextQualifierProvider | SimpleContextQualifierProvider} object.\n * @param params - {@link Runtime.ISimpleContextQualifierProviderCreateParams | Parameters} used to create the provider.\n * @returns `Success` with the new {@link Runtime.SimpleContextQualifierProvider | SimpleContextQualifierProvider} object if successful,\n * or `Failure` with an error message if not.\n * @public\n */\n public static create(\n params: ISimpleContextQualifierProviderCreateParams\n ): Result<SimpleContextQualifierProvider> {\n return captureResult(() => new SimpleContextQualifierProvider(params));\n }\n\n /**\n * Gets a qualifier value by its name, index, or qualifier object.\n * @param nameOrIndexOrQualifier - The {@link QualifierName | qualifier name}, {@link QualifierIndex | index}, or {@link Qualifiers.Qualifier | qualifier object} to look up.\n * @returns `Success` with the {@link QualifierContextValue | qualifier context value} if found,\n * or `Failure` with an error message if not found or an error occurs.\n */\n public get(\n nameOrIndexOrQualifier: QualifierName | QualifierIndex | Qualifier\n ): Result<QualifierContextValue> {\n return this._resolveQualifierName(nameOrIndexOrQualifier).onSuccess((qualifierName) => {\n return this._qualifierValues.get(qualifierName);\n });\n }\n\n /**\n * Gets a validated qualifier context value by its name, index, or qualifier object.\n * TODO: Implement validation logic using qualifier collectors.\n * @param nameOrIndexOrQualifier - The {@link QualifierName | qualifier name}, {@link QualifierIndex | index}, or {@link Qualifiers.Qualifier | qualifier object} to look up.\n * @returns `Success` with the validated {@link QualifierContextValue | qualifier context value} if found,\n * or `Failure` with an error message if not found, invalid, or an error occurs.\n */\n public getValidated(\n nameOrIndexOrQualifier: QualifierName | QualifierIndex | Qualifier\n ): Result<QualifierContextValue> {\n return this._resolveQualifier(nameOrIndexOrQualifier).onSuccess((qualifier) => {\n return this._qualifierValues.get(qualifier.name).asResult.onSuccess((value) => {\n return qualifier.validateContextValue(value);\n });\n });\n }\n\n /**\n * Checks if a qualifier value exists with the given name.\n * @param name - The {@link QualifierName | qualifier name} to check.\n * @returns `Success` with `true` if the qualifier value exists, `false` if it doesn't,\n * or `Failure` with an error message if an error occurs during the check.\n */\n public has(name: QualifierName): Result<boolean> {\n return succeed(this._qualifierValues.has(name));\n }\n\n /**\n * Gets all available qualifier names in this context.\n * @returns `Success` with an array of all {@link QualifierName | qualifier names},\n * or `Failure` with an error message if an error occurs.\n */\n public getNames(): Result<ReadonlyArray<QualifierName>> {\n return succeed(Array.from(this._qualifierValues.keys()));\n }\n\n /**\n * Sets a qualifier value in this provider.\n * @param name - The {@link QualifierName | qualifier name} to set.\n * @param value - The {@link QualifierContextValue | qualifier context value} to set.\n * @returns `Success` with the set {@link QualifierContextValue | qualifier context value} if successful,\n * or `Failure` with an error message if not.\n * @public\n */\n public set(name: QualifierName, value: QualifierContextValue): Result<QualifierContextValue> {\n this._qualifierValues.set(name, value);\n return succeed(value);\n }\n\n /**\n * Removes a qualifier value from this provider.\n * @param name - The {@link QualifierName | qualifier name} to remove.\n * @returns `Success` with the removed {@link QualifierContextValue | qualifier context value} if successful,\n * or `Failure` with an error message if not found or an error occurs.\n * @public\n */\n public remove(name: QualifierName): Result<QualifierContextValue> {\n return this._qualifierValues.get(name).onSuccess((value) => {\n this._qualifierValues.delete(name);\n return succeedWithDetail(value, 'success');\n });\n }\n\n /**\n * Gets the number of qualifier values in this provider.\n * @returns The count of qualifier values.\n * @public\n */\n public get size(): number {\n return this._qualifierValues.size;\n }\n\n /**\n * Clears all qualifier values from this provider.\n * @public\n */\n public clear(): void {\n this._qualifierValues.clear();\n }\n\n /**\n * Resolves a qualifier from a name, index, or qualifier object.\n * @param nameOrIndexOrQualifier - The input to resolve.\n * @returns `Success` with the {@link Qualifier | qualifier} if successful,\n * or `Failure` with an error message if not found or invalid.\n * @internal\n */\n private _resolveQualifier(\n nameOrIndexOrQualifier: QualifierName | QualifierIndex | Qualifier\n ): Result<Qualifier> {\n if (nameOrIndexOrQualifier instanceof Qualifier) {\n return succeed(nameOrIndexOrQualifier);\n }\n /* c8 ignore next 16 - functional code tested but coverage intermittently missed */\n if (typeof nameOrIndexOrQualifier === 'string') {\n return this.qualifiers.validating\n .get(nameOrIndexOrQualifier)\n .withErrorFormat((error) => `${nameOrIndexOrQualifier}: invalid qualifier name.`);\n }\n\n if (typeof nameOrIndexOrQualifier === 'number') {\n return this.qualifiers\n .getAt(nameOrIndexOrQualifier)\n .withErrorFormat((error) => `${nameOrIndexOrQualifier}: invalid qualifier index.`);\n }\n\n return SimpleContextQualifierProvider._qualifierNameFromQualifierLike(nameOrIndexOrQualifier)\n .onSuccess((qualifierName) => this.qualifiers.validating.get(qualifierName))\n .withErrorFormat((error) => `${nameOrIndexOrQualifier}: invalid Qualifier, name or index.`);\n }\n\n /**\n * Resolves a qualifier name from a name, index, or qualifier object.\n * @param nameOrIndexOrQualifier - The input to resolve.\n * @returns `Success` with the {@link QualifierName | qualifier name} if successful,\n * or `Failure` with an error message if not found or invalid.\n * @internal\n */\n private _resolveQualifierName(\n nameOrIndexOrQualifier: QualifierName | QualifierIndex | Qualifier\n ): Result<QualifierName> {\n return this._resolveQualifier(nameOrIndexOrQualifier).onSuccess((qualifier) => succeed(qualifier.name));\n }\n\n /**\n * Resolves a qualifier name from a qualifier-like object.\n * @param nameOrIndexOrQualifier - The input to resolve.\n * @returns `Success` with the {@link QualifierName | qualifier name} if successful,\n * or `Failure` with an error message if not found or invalid.\n * @internal\n */\n private static _qualifierNameFromQualifierLike(\n nameOrIndexOrQualifier: QualifierName | QualifierIndex | Qualifier\n ): Result<QualifierName> {\n return Converters.isA(\n 'Qualifier-like object',\n (v): v is { name: QualifierName } =>\n typeof v === 'object' &&\n v !== null &&\n 'name' in v &&\n typeof (v as Record<string, unknown>).name === 'string'\n )\n .map((v) => CommonConverters.qualifierName.convert(v.name))\n .convert(nameOrIndexOrQualifier);\n }\n}\n"]}
|
|
@@ -35,11 +35,9 @@ export class ValidatingSimpleContextQualifierProvider extends SimpleContextQuali
|
|
|
35
35
|
* @param params - {@link Runtime.IValidatingSimpleContextQualifierProviderCreateParams | Parameters} used to create the provider.
|
|
36
36
|
*/
|
|
37
37
|
constructor(params) {
|
|
38
|
-
//
|
|
39
|
-
|
|
40
|
-
const convertedValues = params.qualifierValues
|
|
41
|
-
? Object.fromEntries(Object.entries(params.qualifierValues).map(([key, value]) => [key, value]))
|
|
42
|
-
: undefined;
|
|
38
|
+
// The branded QualifierContextValue is structurally a string; widen via cast
|
|
39
|
+
// and let the base class skip undefined entries on load.
|
|
40
|
+
const convertedValues = params.qualifierValues;
|
|
43
41
|
super({
|
|
44
42
|
qualifiers: params.qualifiers,
|
|
45
43
|
qualifierValues: convertedValues
|