@stll/template-conditions 0.5.1 → 0.5.3

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/index.d.ts CHANGED
@@ -4,6 +4,9 @@ import { CompareNode, CompareOp, Condition, ConditionNode, ConditionNode as Cond
4
4
  declare const resolvePath: (path: string, data: Record<string, unknown>) => unknown;
5
5
  //#endregion
6
6
  //#region src/parse.d.ts
7
+ /** Bare words the tokenizer reads as operators or literals; a data path can
8
+ * never be one of them. */
9
+ declare const CONDITION_RESERVED_WORDS: readonly ["and", "or", "not", "in", "is", "defined", "true", "false"];
7
10
  declare const parseCondition: (expression: string) => ConditionNode$1 | null;
8
11
  //#endregion
9
12
  //#region src/referenced-paths.d.ts
@@ -606,4 +609,4 @@ declare const MAX_CONDITION_DEPTH = 50;
606
609
  */
607
610
  declare const evaluateCondition: (expression: string, data: Record<string, unknown>, namedConditions?: readonly NamedCondition[], _resolved?: ReadonlySet<string>, _depth?: number) => boolean;
608
611
  //#endregion
609
- export { ARRAY_FILTER_NAMES, BLOCK_DIRECTIVE_KINDS, type BlockDirectiveKind, type CompareNode, type CompareOp, type Condition, type ConditionNode, type ConditionTagOptions, DATE_FORMAT_EXAMPLE_ISO, DATE_FORMAT_STYLES, DIRECTIVE_KINDS, type DateFormatStyle, type DeterministicFieldConfig, type DirectiveKind, FILTER_NAMES, type FieldDateFormat, type FilterArgument, type FilterCall, type FilterName, type ForOpenerOptions, type GroupNode, type InvalidMarker, LOOP_PROPERTIES, type LoopProperty, MARKER_DEFECT_KINDS, MARKER_OUTPUT_BODY, MARKER_STATEMENT_BODY, MAX_CONDITION_DEPTH, type MarkerDefect, type MarkerDefectKind, type MarkerFieldConfig, type MarkerFieldInputType, type MarkerFieldLookup, type MarkerFieldSource, type MarkerFieldValidation, type MarkerForm, type MarkerLiteral, type MarkerMeta, type MarkerPrefix, NUMERIC_FUNCTION_NAMES, NamedCondition, type NumericFunctionName, type Operand, type PredicateNode, type PredicateOp, type RowBlockMarker, type RowBlockPair, type RowScope, type ScannedMarker, type UnwritableReason, arrayFiltersFromFieldConfig, assertNever, blockDirectiveLinePattern, classifyMarker, classifyMarkerDefect, clauseSlotKey, clauseSlotPattern, conditionHasFormula, conditionNodeSchema, conditionSchema, detectRowBlockPair, emptyCondition, evaluateCondition, evaluateNumericExpression, filtersFromFieldConfig, formatDate, hasBlockDirectivePattern, hasNumberingPattern, isArrayFilterName, isBlockDirectiveKind, isClauseSlotName, isFieldPath, isSafeFieldPath, legacyLoopAlias, legacyMarkerReplacement, loopPattern, markerPattern, normalizeMarkerInner, numPattern, parseCondition, placeholderPattern, qualifyLoopPath, qualifyRowScopedPath, qualifyRowScopedPlaceholder, refPattern, referencedConditionPaths, renderConditionTag, renderDeterministicFieldValue, renderFilterChain, renderForOpener, renderValueMarker, replaceOutputMarkers, resolvePath, rowScopePaths, scanInvalidMarkers, scanMarkers, serializeCondition, substitutionKey, translateLegacyExpression, unwritableFilterValues, unwritableMarkerLiteral };
612
+ export { ARRAY_FILTER_NAMES, BLOCK_DIRECTIVE_KINDS, type BlockDirectiveKind, CONDITION_RESERVED_WORDS, type CompareNode, type CompareOp, type Condition, type ConditionNode, type ConditionTagOptions, DATE_FORMAT_EXAMPLE_ISO, DATE_FORMAT_STYLES, DIRECTIVE_KINDS, type DateFormatStyle, type DeterministicFieldConfig, type DirectiveKind, FILTER_NAMES, type FieldDateFormat, type FilterArgument, type FilterCall, type FilterName, type ForOpenerOptions, type GroupNode, type InvalidMarker, LOOP_PROPERTIES, type LoopProperty, MARKER_DEFECT_KINDS, MARKER_OUTPUT_BODY, MARKER_STATEMENT_BODY, MAX_CONDITION_DEPTH, type MarkerDefect, type MarkerDefectKind, type MarkerFieldConfig, type MarkerFieldInputType, type MarkerFieldLookup, type MarkerFieldSource, type MarkerFieldValidation, type MarkerForm, type MarkerLiteral, type MarkerMeta, type MarkerPrefix, NUMERIC_FUNCTION_NAMES, NamedCondition, type NumericFunctionName, type Operand, type PredicateNode, type PredicateOp, type RowBlockMarker, type RowBlockPair, type RowScope, type ScannedMarker, type UnwritableReason, arrayFiltersFromFieldConfig, assertNever, blockDirectiveLinePattern, classifyMarker, classifyMarkerDefect, clauseSlotKey, clauseSlotPattern, conditionHasFormula, conditionNodeSchema, conditionSchema, detectRowBlockPair, emptyCondition, evaluateCondition, evaluateNumericExpression, filtersFromFieldConfig, formatDate, hasBlockDirectivePattern, hasNumberingPattern, isArrayFilterName, isBlockDirectiveKind, isClauseSlotName, isFieldPath, isSafeFieldPath, legacyLoopAlias, legacyMarkerReplacement, loopPattern, markerPattern, normalizeMarkerInner, numPattern, parseCondition, placeholderPattern, qualifyLoopPath, qualifyRowScopedPath, qualifyRowScopedPlaceholder, refPattern, referencedConditionPaths, renderConditionTag, renderDeterministicFieldValue, renderFilterChain, renderForOpener, renderValueMarker, replaceOutputMarkers, resolvePath, rowScopePaths, scanInvalidMarkers, scanMarkers, serializeCondition, substitutionKey, translateLegacyExpression, unwritableFilterValues, unwritableMarkerLiteral };
package/dist/index.js CHANGED
@@ -192,8 +192,24 @@ const COMPARE_SYMBOL_TO_OP = {
192
192
  "<=": "lte"
193
193
  };
194
194
  const escapeRegexLiteral = (value) => value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
195
+ /** Bare words the tokenizer reads as operators or literals; a data path can
196
+ * never be one of them. */
197
+ const CONDITION_RESERVED_WORDS = [
198
+ "and",
199
+ "or",
200
+ "not",
201
+ "in",
202
+ "is",
203
+ "defined",
204
+ "true",
205
+ "false"
206
+ ];
207
+ const RESERVED_WORDS = new Set(CONDITION_RESERVED_WORDS);
208
+ const isConditionKeyword = (raw) => raw !== "true" && raw !== "false" && RESERVED_WORDS.has(raw);
209
+ /** The keyword alternation of the tokenizer, derived from the same list. */
210
+ const KEYWORD_PATTERN = CONDITION_RESERVED_WORDS.filter(isConditionKeyword).map((word) => String.raw`${word}\b`).join("|");
195
211
  const COMPARE_SYMBOL_PATTERN = Object.keys(COMPARE_SYMBOL_TO_OP).sort((left, right) => right.length - left.length).map(escapeRegexLiteral).join("|");
196
- const NON_STRING_TOKEN_RE = new RegExp(String.raw`(?<token>${COMPARE_SYMBOL_PATTERN}|and\b|or\b|not\b|in\b|is\b|defined\b|[()]|-?\d[\p{N}_.]*|[\p{L}\p{N}_.]+(?:-[\p{L}\p{N}_.]+)*)`, "uy");
212
+ const NON_STRING_TOKEN_RE = new RegExp(String.raw`(?<token>${COMPARE_SYMBOL_PATTERN}|${KEYWORD_PATTERN}|[()]|-?\d[\p{N}_.]*|[\p{L}\p{N}_.]+(?:-[\p{L}\p{N}_.]+)*)`, "uy");
197
213
  const STARTS_WITH_DIGIT_RE = /^-?\d/u;
198
214
  const isCompareSymbol = (raw) => Object.hasOwn(COMPARE_SYMBOL_TO_OP, raw);
199
215
  /**
@@ -223,12 +239,7 @@ const scanString = (expr, start) => {
223
239
  };
224
240
  };
225
241
  const classifyNonString = (raw) => {
226
- if (raw === "and") return { type: "and" };
227
- if (raw === "or") return { type: "or" };
228
- if (raw === "not") return { type: "not" };
229
- if (raw === "in") return { type: "in" };
230
- if (raw === "is") return { type: "is" };
231
- if (raw === "defined") return { type: "defined" };
242
+ if (isConditionKeyword(raw)) return { type: raw };
232
243
  if (isCompareSymbol(raw)) return {
233
244
  type: "op",
234
245
  raw
@@ -1419,7 +1430,11 @@ const unwritableMarkerLiteral = (value, form = "output") => {
1419
1430
  /** One string literal, double-quoted, with backslashes and quotes escaped the
1420
1431
  * way `scanQuoted` reads them back. */
1421
1432
  const renderString = (value) => `"${value.replaceAll("\\", "\\\\").replaceAll("\"", "\\\"")}"`;
1422
- const renderLiteral = (value) => typeof value === "string" ? renderString(value) : String(value);
1433
+ const renderLiteral = (value) => {
1434
+ if (typeof value === "string") return renderString(value);
1435
+ if (typeof value === "number" && Object.is(value, -0)) return "-0";
1436
+ return String(value);
1437
+ };
1423
1438
  const renderArgument = (arg) => arg.kind === "positional" ? renderLiteral(arg.value) : `${arg.name}=${renderLiteral(arg.value)}`;
1424
1439
  /** Every value in a chain the grammar has no spelling for, with the filter it
1425
1440
  * was written on and why, so a caller can refuse a configuration before it
@@ -1649,4 +1664,4 @@ const evaluateCondition = (expression, data, namedConditions, _resolved = /* @__
1649
1664
  return evaluateCondition$1(node, makeResolver(data, namedConditions, _resolved, _depth));
1650
1665
  };
1651
1666
  //#endregion
1652
- export { ARRAY_FILTER_NAMES, BLOCK_DIRECTIVE_KINDS, DATE_FORMAT_EXAMPLE_ISO, DATE_FORMAT_STYLES, DIRECTIVE_KINDS, FILTER_NAMES, LOOP_PROPERTIES, MARKER_DEFECT_KINDS, MARKER_OUTPUT_BODY, MARKER_STATEMENT_BODY, MAX_CONDITION_DEPTH, NUMERIC_FUNCTION_NAMES, arrayFiltersFromFieldConfig, assertNever, blockDirectiveLinePattern, classifyMarker, classifyMarkerDefect, clauseSlotKey, clauseSlotPattern, conditionHasFormula, conditionNodeSchema, conditionSchema, detectRowBlockPair, emptyCondition, evaluateCondition, evaluateNumericExpression, filtersFromFieldConfig, formatDate, hasBlockDirectivePattern, hasNumberingPattern, isArrayFilterName, isBlockDirectiveKind, isClauseSlotName, isFieldPath, isSafeFieldPath, legacyLoopAlias, legacyMarkerReplacement, loopPattern, markerPattern, normalizeMarkerInner, numPattern, parseCondition, placeholderPattern, qualifyLoopPath, qualifyRowScopedPath, qualifyRowScopedPlaceholder, refPattern, referencedConditionPaths, renderConditionTag, renderDeterministicFieldValue, renderFilterChain, renderForOpener, renderValueMarker, replaceOutputMarkers, resolvePath, rowScopePaths, scanInvalidMarkers, scanMarkers, serializeCondition, substitutionKey, translateLegacyExpression, unwritableFilterValues, unwritableMarkerLiteral };
1667
+ export { ARRAY_FILTER_NAMES, BLOCK_DIRECTIVE_KINDS, CONDITION_RESERVED_WORDS, DATE_FORMAT_EXAMPLE_ISO, DATE_FORMAT_STYLES, DIRECTIVE_KINDS, FILTER_NAMES, LOOP_PROPERTIES, MARKER_DEFECT_KINDS, MARKER_OUTPUT_BODY, MARKER_STATEMENT_BODY, MAX_CONDITION_DEPTH, NUMERIC_FUNCTION_NAMES, arrayFiltersFromFieldConfig, assertNever, blockDirectiveLinePattern, classifyMarker, classifyMarkerDefect, clauseSlotKey, clauseSlotPattern, conditionHasFormula, conditionNodeSchema, conditionSchema, detectRowBlockPair, emptyCondition, evaluateCondition, evaluateNumericExpression, filtersFromFieldConfig, formatDate, hasBlockDirectivePattern, hasNumberingPattern, isArrayFilterName, isBlockDirectiveKind, isClauseSlotName, isFieldPath, isSafeFieldPath, legacyLoopAlias, legacyMarkerReplacement, loopPattern, markerPattern, normalizeMarkerInner, numPattern, parseCondition, placeholderPattern, qualifyLoopPath, qualifyRowScopedPath, qualifyRowScopedPlaceholder, refPattern, referencedConditionPaths, renderConditionTag, renderDeterministicFieldValue, renderFilterChain, renderForOpener, renderValueMarker, replaceOutputMarkers, resolvePath, rowScopePaths, scanInvalidMarkers, scanMarkers, serializeCondition, substitutionKey, translateLegacyExpression, unwritableFilterValues, unwritableMarkerLiteral };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stll/template-conditions",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
4
4
  "description": "A document-template marker and condition engine: {{...}} marker grammar, parse, compute, serialize, field values.",
5
5
  "keywords": [
6
6
  "condition",