Skip to content

Commit a0711e7

Browse files
committed
feat: Add issue message formatting
1 parent cb2fb0c commit a0711e7

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

src/schema/applyRules.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { GenericRule, GenericSchema, SchemaFields, SchemaTypeLike } from '../types/schema.ts'
22
import type { Severity } from '../types/issues.ts'
33
import type { BIDSContext } from './context.ts'
4-
import { contextFunction, prepareContext } from './expressionLanguage.ts'
4+
import { contextFunction, formatter, prepareContext } from './expressionLanguage.ts'
55
import { logger } from '../utils/logger.ts'
66
import { compile } from '../validators/json.ts'
77
import type { DefinedError } from '@ajv'
@@ -166,12 +166,13 @@ function _evalRuleChecks(
166166
): boolean {
167167
if (rule.checks && !mapEvalCheck(rule.checks, context)) {
168168
if (rule.issue?.code && rule.issue?.message) {
169+
const format = formatter(rule.issue.message)
169170
context.dataset.issues.add({
170171
code: rule.issue.code,
171172
location: context.path,
172173
rule: schemaPath,
173174
severity: rule.issue.level as Severity,
174-
}, rule.issue.message)
175+
}, format(context))
175176
} else {
176177
context.dataset.issues.add(
177178
{ code: 'CHECK_ERROR', location: context.path, rule: schemaPath },

src/schema/expressionLanguage.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,24 @@ function _contextFunction(expr: string): (context: BIDSContext) => any {
140140
*/
141141
export const contextFunction = memoize(_contextFunction)
142142

143+
function _formatter(format: string): (context: BIDSContext) => string {
144+
if (!format.includes('{')) {
145+
return (context: BIDSContext) => format
146+
}
147+
const template = format.replace(/{/g, '${').replace(/\\/g, '\\\\').replace(/`/g, '\\`')
148+
return new Function('context', `with (context) { return \`${template}\` }`) as (
149+
context: BIDSContext,
150+
) => string
151+
}
152+
153+
/**
154+
* Generate a function that formats a string using the BIDS context.
155+
*
156+
* Strings are expected to use Python-style formatting,
157+
* e.g., "sub-{entities.sub}/ses-{entities.ses}".
158+
*/
159+
export const formatter = memoize(_formatter)
160+
143161
function safeContext(context: BIDSContext): BIDSContext {
144162
return new Proxy(context, {
145163
has: () => true,

0 commit comments

Comments
 (0)