Skip to content

Commit b285508

Browse files
feat(spec): the number-comparand declared-type door's contract and the platform's numeric grammar (#20414)
Fixes #20336 Clause-②: yes ## What this adds This is lane (1) of the split triage routed on #15661's precedent: the **contract** for the number-comparand declared-type door, plus the platform's **one numeric grammar** for a string. It adds one module to `@objectstack/spec/data`, `filter-number-comparand-declared-type.ts`, beside `filter-text-operator-declared-type.ts`, together with its test, the barrel line, the regenerated `api-surface/data.json` and `export-origins/data.json`, and a `minor` changeset. **No door is written here, and no evaluator changes.** The engine door and its three-driver, REST and per-aggregation `filter` pins are #20351's, which stays open and is `Blocked-by:` this card. The write side's string half adopts the same grammar under #20309, which also stays open. The new exports (27, all additive; `api-surface/data.json` +27 / -0): - **The grammar** - `NUMERIC_STRING_PATTERN`. - `parseNumericString(s)` returns the number, or `undefined`. - `readNumericString(s)` returns the number, or one of eight named forms (`NON_NUMERIC_STRING_FORMS`). - `NUMERIC_STRING_GRAMMAR_CASES` is the table of forms: 41 rows, each with its reason. - **The verdict** - `numberComparandFieldVerdict(field)` returns `judged` / `not-judged` / `deferred`. - `numberComparandDoorVerdict(field, comparand)` returns one of: - `door-refusal` (`INVALID_FILTER` / 400, with a `form`); - `narrows` (with the number); - `passes`; - `deferred`. - `NUMBER_COMPARAND_DOOR_JUDGED_TYPES` is `NUMERIC_VALUE_TYPES` itself, by identity. - `NUMBER_COMPARAND_DOOR_SCALAR_OPERATORS` / `NUMBER_COMPARAND_DOOR_LIST_OPERATORS`. - **The words:** `numberComparandRefusalMessage(site, context?)`. It names the field, the declared type, the bounded comparand, its position and what is wrong with the string, all ahead of the remedy. - **For the engine suite** - `NUMBER_COMPARAND_DOOR_FIXTURE` has one field per `FieldType`, plus the formula variants. - `NUMBER_COMPARAND_DOOR_CASES` has 136 derived cases: 52 refusals, 23 narrowings, 60 passes, 1 deferred. ## Decisions this contract takes (each argued in the module header; the four-axis reasons are below) 1. **The grammar is a JSON number literal that names a finite double.** Its forms were checked one by one against the card's A2 list (`NUMERIC_STRING_GRAMMAR_CASES` is the record): - **Admitted:** `"12"`, `"-3"`, `"12.5"`, `"0.10"`, `"1e3"`, `"2.5E+3"`, `"1e-7"`, `"1e+21"`. - Every `String(n)` for a finite `n` is admitted and parses back to `n`. This is pinned as a round-trip property over 418 numbers. - So a URL query is never refused: `?amount=5` is lowered to an implicit `{ amount: "5" }` in `metadata-protocol`'s `findData`. - Neither is `URLSearchParams`, nor a plain CSV cell. - Exponents are admitted because `String(1e-7)` is `"1e-7"`. - **Refused, and `Number()` would have read them:** `""`, `" "`, `" 12 "`, `"0x10"`, `"0o17"`, `"0b101"`, `"+5"`, `".5"`, `"5."`, `"007"`. - Hex and whitespace-padded strings are refused by name in #20309's triage direction. - The rest are refused for their spelling alone. - The test pins exactly this list, so that the narrowing against `Number()` stays deliberate. - **Refused:** `"Infinity"`, `"NaN"`, `"1e400"`, `"1,000"`, `"1.000,5"`, `"1_000"`, `"1 000"`, full-width digits, U+2212, and every `{placeholder}`. 2. **The door narrows a numeric string to its number**, copy-on-write. - This is the pattern the comparand-type door already uses for an exact-range `bigint`, and the write side's "store the parsed number". - Left as a string, `"12"` is read three ways: - JS loose equality and relational comparison coerce it (`driver-memory`'s matcher, read at source). - SQLite applies numeric affinity. - `driver-mongodb` compares by BSON type: its filter compiler coerces temporal comparands only (read at source). 3. **`summary` is judged.** Its column is numeric on every SQL dialect: `numericColumnFor` is defined for every judged type, and that is pinned. The write door exempts `summary` through `COMPUTED_VALUE_TYPES`, but that set answers *who writes*, not *what may be compared*. This answers A1. 4. **`formula` is judged by its `returnType`**, through the text door's own `FORMULA_RETURN_TYPE_AS_FIELD_TYPE`: - `number` is judged; - `text`, `boolean` and `date` are not number fields; - an absent `returnType` is deferred. As with the text door, no formula filter reaches the engine seam, because the unmaterializable-field door refuses every one of them first with `INVALID_FIELD`. The case table says the engine suite must partition those rows out. This also answers A1. 5. **Judged positions:** implicit equality; `$eq` / `$ne` / `$gt` / `$gte` / `$lt` / `$lte`; and each member of `$in` / `$nin` / `$between`. - Pinned: these, the seven text operators, and `$null` / `$exists` partition `FieldOperatorsSchema`'s keys exactly. - Only string comparands are judged. A number, `null`, a `Date`, a boolean or a `bigint` passes. 6. **A `{placeholder}` against a number field is refused, not stepped around.** - Every filter token resolves to a user or organization id, a `YYYY-MM-DD` day or an ISO instant (`resolveFilterToken` in `@objectstack/core`). None of these is numeric, so a resolved token reaches PostgreSQL as the same 500. - The field-aware doors run before the token resolver. 7. **A blank string is refused.** - On the write side, a blank becomes `null` before the number arm (#20308). - On the read side, `is_empty` lowers to `$null`, and #20311's ruling B keeps a number field on null alone. - objectui drops rows whose value is empty before they reach the server: `viewFilterFold.ts` and `ListView.convertFilterGroupToAST`, read at objectui `9f0c84a`. So the console sends no `{ amount: "" }`. 8. **The words and the envelope (A4):** no new error code. `INVALID_FILTER` / 400 is spelled as a literal, as `filter-comparand-type.ts` does, and pinned to `StandardErrorCode`. Each form's clause states only what holds for that form, so `"+5"` is not claimed to diverge between backends. Every refusal in the case table fits inside the 500-character client bound, and that is pinned. ### Four-axis reasons (for the grammar and the narrowing) - **Real business need:** the measured producers of numeric strings. - Read side: REST query parameters, lowered to implicit filters (`metadata-protocol` `findData`). - Write side: objectui's CSV-import legacy fallback (census 5863923799 on #20309). - Both carry what `String(n)` or a spreadsheet writes for a plain number. Every such form is admitted. - No measured producer writes `+5`, `.5`, `5.` or `007`. The objectui filter builder sends JS numbers (`convertScalarToFamily`). - **Long-term soundness:** one grammar in one place, read by both doors. It is externally specified (RFC 8259 §6), so it is one sentence. Narrowing on the read side mirrors the write side's "store the parsed number", so there is one reading per string. - **Keeping AI from writing wrong metadata or code:** the contract is tightened, never loosened. - Every form the backends read differently is refused loudly, with a named form and a remedy: blank, padded, hex, Infinity/NaN, locale separators, placeholders. - Nothing is silently coerced beyond the one declared conversion. - **No scope creep at the startup stage:** one module, no new error code, no gate, no door. The engine door stays #20351's. ## Premise check (rule 6) - `normalizeFilterComparandTypes` takes no schema. This was confirmed at `ab6fb027`, which is why this is a new module (the triage retriage route). - The precedent's shape matches A1: sets referenced by identity, a pure verdict, a fixture, and a derived case table. - A3 holds: the verdict needs no spec change beyond the new module. `@objectstack/objectql` imports `@objectstack/spec/data` already. Its build closure builds against this spec (turbo, 14/14 tasks at `b49a49b0`), and `check:lean-entry-closure` holds its admitted set (15 packages). - No package imports the new module yet. `git grep -l "filter-number-comparand-declared-type" -- packages` finds only the barrel, the module's own test and the generated `export-origins/data.json` shard. ## Tests (at `b49a49b0` unless noted) - `pnpm --filter @objectstack/spec typecheck`: exit 0. `check:test-typecheck` OK, with the new test file compiled and no debt added. - `vitest run --project local` (spec `test`): 562 files, 16551 tests passed (1 todo). - `vitest run --project repo` (spec `test:repo`): 35 files, 634 tests passed. It also passed at `a5680789`, before the main merge. - The new test file: 34 tests. It pins these, in both directions: - the grammar table; - the round-trip property; - the stricter-than-`Number()` list; - the FieldType census; - `summary`'s numeric column; - the operator partition; - the envelope literal; - that every form's words differ and carry no tracker number; - the 500-character bound and front-loading; - fixture legality (`FieldSchema` / `ObjectSchema`); - the case-table agreement with the verdict; - `parseFilterAST` accepting every case. - `pnpm --filter @objectstack/spec check:generated` at `b49a49b0`, after rebuilding from the merged tree: all 15 artifacts are up to date. ## Gates (`dispatch-gates --commands --repo objectstack-ai/objectstack` at `b49a49b0`: 85 derived) - 83 exited 0, and 2 are NOT MEASURED (exit 3, PREREQUISITE NOT MET): - `check:dual-build-cjs-loads`: needs every package built. - `check:type-check-debt`: needs the full build closure. CI runs both. - `dispatch-gates --ran`: 85 derived families are accounted for (83 run, 2 NOT-MEASURED, derived from the recorded exit 3), 0 UNRUN. - For comparison, the dispatch list derived at `ab6fb027` had 72 lines. The diff and changeset added 13 families, all of them run above: - `check-empty-changeset` ×2 - `release-rehearsal-clone --self-test` - spec `check:generated` - `check:engine-double-contract` - `check:objectql-double-limit` - `check:objectui-changeset` - `check:pm-changeset-deadline-census` - `check:pm-widening-tells` - `check:query-options-erasure` - `check:type-check-coverage` - `check:type-check-debt` - `check:where-matcher` - On the first pass these gates needed a prerequisite and were rerun green: - `check-plugin-teardown-shape --self-test` needed its pinned fixture commit fetched at depth 1 on this shallow clone. - `check:doc-formula-expressions` and `check:lean-entry-closure` needed the `@objectstack/objectql` closure built. ## Acceptance notes - **The door and its pins are #20351's.** The case table's census comparands are chosen so that no other door on the seam refuses them: `"2026-01-01"` / `"12:00"` for the temporal fields, `"abc"` otherwise. That choice is a design claim for #20351 to measure, not something measured here. - **Not measured live in this change:** - PostgreSQL's reading of the admitted and refused forms (documented numeric input only); - `driver-mongodb`'s numeric-string answer (read at source); - SQLite's affinity on read comparands (the write-side cells were measured on #20309). - **Out of this card's scope, noted and not filed:** a boolean or a `Date` compared against a number field is not judged here. The card and its direction are about strings. PostgreSQL's answer for those is not measured. - **Line budget:** n/a (no `skills/**` path in the diff). --- _Generated by [Claude Code](https://claude.ai/code/session_01B3TqpoQbTAfG7G74GMDWNW)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 3cf6449 commit b285508

6 files changed

Lines changed: 1228 additions & 0 deletions

File tree

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
'@objectstack/spec': minor
3+
---
4+
5+
`@objectstack/spec/data` declares the platform's numeric grammar for a string, and the contract of the number-comparand declared-type door: which string comparands a field whose declared type is numeric may be compared against (#20336).
6+
7+
Clause-②: yes
8+
9+
**The grammar.** A string is numeric when its whole content is a JSON number literal (`-?(0|[1-9][0-9]*)(.[0-9]+)?([eE][+-]?[0-9]+)?`) that names a finite number; it then means what the same characters mean as a JSON number. `NUMERIC_STRING_PATTERN`, `parseNumericString(s)` (the number, or `undefined`) and `readNumericString(s)` (the number, or which of eight named forms the string is: `empty`, `padded`, `placeholder`, `radix-prefix`, `non-finite`, `digit-separator`, `non-json-spelling`, `not-a-number`). `NUMERIC_STRING_GRAMMAR_CASES` records every form with the reason it is admitted or refused: `"12"`, `"-3"`, `"12.5"`, `"1e3"` and every string `String(n)` produces for a finite number are admitted; `""`, `" 12 "`, `"0x10"`, `"Infinity"`, `"NaN"`, `"1,000"`, `"+5"`, `".5"`, `"007"` and any `{placeholder}` are not.
10+
11+
**The door's contract.** `numberComparandDoorVerdict(field, comparand)` answers, for a comparand at a value position (implicit equality, `$eq` / `$ne` / `$gt` / `$gte` / `$lt` / `$lte`, and each member of `$in` / `$nin` / `$between`) of a filter on a field whose declared type is in `NUMERIC_VALUE_TYPES` (or a `formula` whose `returnType` is `number`): `door-refusal` (`INVALID_FILTER` / 400) for a non-numeric string, `narrows` with the number for a numeric one, `passes` for any other comparand or field, `deferred` for a `formula` without a readable `returnType`. `numberComparandRefusalMessage(site, context?)` is the refusal the door prints: the field, its declared type, the comparand, its position and what is wrong with it. A fixture object and a derived case table (`NUMBER_COMPARAND_DOOR_FIXTURE`, `NUMBER_COMPARAND_DOOR_CASES`) are published for the engine suite that pins the door.
12+
13+
**What moves for consumers.** Nothing yet. This is the contract only, and no door reads it in this release: a non-numeric string compared with a number field still reaches the driver as written (a 500 on PostgreSQL, an empty or different result elsewhere). The engine door that refuses it with `INVALID_FILTER` / 400 and narrows a numeric string lands with #20351, and the record validator's number arm adopts the same grammar for writes with #20309.

‎packages/spec/api-surface/data.json‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,11 +438,21 @@
438438
"MysqlConfig (type)",
439439
"MysqlConfigParsed (type)",
440440
"MysqlConfigSchema (const)",
441+
"NON_NUMERIC_STRING_FORMS (const)",
441442
"NON_TEXT_STORED_VALUE_TYPES (const)",
442443
"NOW_DEFAULT_LEGAL_TYPES (const)",
444+
"NUMBER_COMPARAND_DOOR_CASES (const)",
445+
"NUMBER_COMPARAND_DOOR_FIXTURE (const)",
446+
"NUMBER_COMPARAND_DOOR_FIXTURE_FIELDS (const)",
447+
"NUMBER_COMPARAND_DOOR_FIXTURE_OBJECT (const)",
448+
"NUMBER_COMPARAND_DOOR_JUDGED_TYPES (const)",
449+
"NUMBER_COMPARAND_DOOR_LIST_OPERATORS (const)",
450+
"NUMBER_COMPARAND_DOOR_SCALAR_OPERATORS (const)",
443451
"NUMERIC_COLUMN_PRECISION (const)",
444452
"NUMERIC_COLUMN_REPRESENTATION (const)",
445453
"NUMERIC_COLUMN_SCALE (const)",
454+
"NUMERIC_STRING_GRAMMAR_CASES (const)",
455+
"NUMERIC_STRING_PATTERN (const)",
446456
"NUMERIC_VALUE_TYPES (const)",
447457
"NoSQLDataTypeMapping (type)",
448458
"NoSQLDataTypeMappingSchema (const)",
@@ -462,9 +472,21 @@
462472
"NoSQLQueryOptionsSchema (const)",
463473
"NoSQLTransactionOptions (type)",
464474
"NoSQLTransactionOptionsSchema (const)",
475+
"NonNumericStringForm (type)",
465476
"NormalizedFilter (type)",
466477
"NormalizedFilterSchema (const)",
478+
"NumberComparandDoorCase (type)",
479+
"NumberComparandDoorDeferredCase (interface)",
480+
"NumberComparandDoorFieldMeta (interface)",
481+
"NumberComparandDoorFixtureField (interface)",
482+
"NumberComparandDoorNarrowsCase (interface)",
483+
"NumberComparandDoorPassesCase (interface)",
484+
"NumberComparandDoorRefusalCase (interface)",
485+
"NumberComparandDoorVerdict (type)",
486+
"NumberComparandRefusalSite (interface)",
467487
"NumericColumnRepresentation (type)",
488+
"NumericStringGrammarCase (type)",
489+
"NumericStringReading (type)",
468490
"OBJECT_KEY_GUIDANCE (const)",
469491
"OWNER_FIELD_DEF (const)",
470492
"OWNING_BUSINESS_UNIT_FIELD_DEF (const)",
@@ -831,19 +853,24 @@
831853
"missingFieldValues (function)",
832854
"nextUtcCalendarDay (function)",
833855
"normalizeFilterComparandTypes (function)",
856+
"numberComparandDoorVerdict (function)",
857+
"numberComparandFieldVerdict (function)",
858+
"numberComparandRefusalMessage (function)",
834859
"numericColumnFor (function)",
835860
"objectForm (const)",
836861
"objectTitleCompleteness (function)",
837862
"parseAutonumberFormat (function)",
838863
"parseDateMacroParam (function)",
839864
"parseFilterAST (function)",
865+
"parseNumericString (function)",
840866
"passthroughSecretPaths (function)",
841867
"percentScaleOf (function)",
842868
"placeholderFree (function)",
843869
"placeholderFreeDeep (function)",
844870
"platformProvisionsStorage (function)",
845871
"provisionPrimary (function)",
846872
"readAutonumberCounter (function)",
873+
"readNumericString (function)",
847874
"redactDatasourceConfig (function)",
848875
"redactUrlCredentialQueryParams (function)",
849876
"redactUrlCredentials (function)",

‎packages/spec/export-origins/data.json‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,11 +428,21 @@
428428
"MysqlConfig": "src/data/driver/mysql.zod.ts#MysqlConfig (type)",
429429
"MysqlConfigParsed": "src/data/driver/mysql.zod.ts#MysqlConfigParsed (type)",
430430
"MysqlConfigSchema": "src/data/driver/mysql.zod.ts#MysqlConfigSchema (const)",
431+
"NON_NUMERIC_STRING_FORMS": "src/data/filter-number-comparand-declared-type.ts#NON_NUMERIC_STRING_FORMS (const)",
431432
"NON_TEXT_STORED_VALUE_TYPES": "src/data/field-value.zod.ts#NON_TEXT_STORED_VALUE_TYPES (const)",
432433
"NOW_DEFAULT_LEGAL_TYPES": "src/data/default-value-shape.ts#NOW_DEFAULT_LEGAL_TYPES (const)",
434+
"NUMBER_COMPARAND_DOOR_CASES": "src/data/filter-number-comparand-declared-type.ts#NUMBER_COMPARAND_DOOR_CASES (const)",
435+
"NUMBER_COMPARAND_DOOR_FIXTURE": "src/data/filter-number-comparand-declared-type.ts#NUMBER_COMPARAND_DOOR_FIXTURE (const)",
436+
"NUMBER_COMPARAND_DOOR_FIXTURE_FIELDS": "src/data/filter-number-comparand-declared-type.ts#NUMBER_COMPARAND_DOOR_FIXTURE_FIELDS (const)",
437+
"NUMBER_COMPARAND_DOOR_FIXTURE_OBJECT": "src/data/filter-number-comparand-declared-type.ts#NUMBER_COMPARAND_DOOR_FIXTURE_OBJECT (const)",
438+
"NUMBER_COMPARAND_DOOR_JUDGED_TYPES": "src/data/filter-number-comparand-declared-type.ts#NUMBER_COMPARAND_DOOR_JUDGED_TYPES (const)",
439+
"NUMBER_COMPARAND_DOOR_LIST_OPERATORS": "src/data/filter-number-comparand-declared-type.ts#NUMBER_COMPARAND_DOOR_LIST_OPERATORS (const)",
440+
"NUMBER_COMPARAND_DOOR_SCALAR_OPERATORS": "src/data/filter-number-comparand-declared-type.ts#NUMBER_COMPARAND_DOOR_SCALAR_OPERATORS (const)",
433441
"NUMERIC_COLUMN_PRECISION": "src/data/numeric-column-representation.ts#NUMERIC_COLUMN_PRECISION (const)",
434442
"NUMERIC_COLUMN_REPRESENTATION": "src/data/numeric-column-representation.ts#NUMERIC_COLUMN_REPRESENTATION (const)",
435443
"NUMERIC_COLUMN_SCALE": "src/data/numeric-column-representation.ts#NUMERIC_COLUMN_SCALE (const)",
444+
"NUMERIC_STRING_GRAMMAR_CASES": "src/data/filter-number-comparand-declared-type.ts#NUMERIC_STRING_GRAMMAR_CASES (const)",
445+
"NUMERIC_STRING_PATTERN": "src/data/filter-number-comparand-declared-type.ts#NUMERIC_STRING_PATTERN (const)",
436446
"NUMERIC_VALUE_TYPES": "src/data/field-value.zod.ts#NUMERIC_VALUE_TYPES (const)",
437447
"NoSQLDataTypeMapping": "src/data/driver-nosql.zod.ts#NoSQLDataTypeMapping (type)",
438448
"NoSQLDataTypeMappingSchema": "src/data/driver-nosql.zod.ts#NoSQLDataTypeMappingSchema (const)",
@@ -452,9 +462,21 @@
452462
"NoSQLQueryOptionsSchema": "src/data/driver-nosql.zod.ts#NoSQLQueryOptionsSchema (const)",
453463
"NoSQLTransactionOptions": "src/data/driver-nosql.zod.ts#NoSQLTransactionOptions (type)",
454464
"NoSQLTransactionOptionsSchema": "src/data/driver-nosql.zod.ts#NoSQLTransactionOptionsSchema (const)",
465+
"NonNumericStringForm": "src/data/filter-number-comparand-declared-type.ts#NonNumericStringForm (type)",
455466
"NormalizedFilter": "src/data/filter.zod.ts#NormalizedFilter (type)",
456467
"NormalizedFilterSchema": "src/data/filter.zod.ts#NormalizedFilterSchema (const)",
468+
"NumberComparandDoorCase": "src/data/filter-number-comparand-declared-type.ts#NumberComparandDoorCase (type)",
469+
"NumberComparandDoorDeferredCase": "src/data/filter-number-comparand-declared-type.ts#NumberComparandDoorDeferredCase (interface)",
470+
"NumberComparandDoorFieldMeta": "src/data/filter-number-comparand-declared-type.ts#NumberComparandDoorFieldMeta (interface)",
471+
"NumberComparandDoorFixtureField": "src/data/filter-number-comparand-declared-type.ts#NumberComparandDoorFixtureField (interface)",
472+
"NumberComparandDoorNarrowsCase": "src/data/filter-number-comparand-declared-type.ts#NumberComparandDoorNarrowsCase (interface)",
473+
"NumberComparandDoorPassesCase": "src/data/filter-number-comparand-declared-type.ts#NumberComparandDoorPassesCase (interface)",
474+
"NumberComparandDoorRefusalCase": "src/data/filter-number-comparand-declared-type.ts#NumberComparandDoorRefusalCase (interface)",
475+
"NumberComparandDoorVerdict": "src/data/filter-number-comparand-declared-type.ts#NumberComparandDoorVerdict (type)",
476+
"NumberComparandRefusalSite": "src/data/filter-number-comparand-declared-type.ts#NumberComparandRefusalSite (interface)",
457477
"NumericColumnRepresentation": "src/data/numeric-column-representation.ts#NumericColumnRepresentation (type)",
478+
"NumericStringGrammarCase": "src/data/filter-number-comparand-declared-type.ts#NumericStringGrammarCase (type)",
479+
"NumericStringReading": "src/data/filter-number-comparand-declared-type.ts#NumericStringReading (type)",
458480
"OBJECT_KEY_GUIDANCE": "src/data/authoring-key-lint.ts#OBJECT_KEY_GUIDANCE (const)",
459481
"OWNER_FIELD_DEF": "src/data/injected-system-column-provenance.ts#OWNER_FIELD_DEF (const)",
460482
"OWNING_BUSINESS_UNIT_FIELD_DEF": "src/data/injected-system-column-provenance.ts#OWNING_BUSINESS_UNIT_FIELD_DEF (const)",
@@ -818,19 +840,24 @@
818840
"missingFieldValues": "src/data/autonumber-format.ts#missingFieldValues (function)",
819841
"nextUtcCalendarDay": "src/data/calendar-day.ts#nextUtcCalendarDay (function)",
820842
"normalizeFilterComparandTypes": "src/data/filter-comparand-type.ts#normalizeFilterComparandTypes (function)",
843+
"numberComparandDoorVerdict": "src/data/filter-number-comparand-declared-type.ts#numberComparandDoorVerdict (function)",
844+
"numberComparandFieldVerdict": "src/data/filter-number-comparand-declared-type.ts#numberComparandFieldVerdict (function)",
845+
"numberComparandRefusalMessage": "src/data/filter-number-comparand-declared-type.ts#numberComparandRefusalMessage (function)",
821846
"numericColumnFor": "src/data/numeric-column-representation.ts#numericColumnFor (function)",
822847
"objectForm": "src/data/object.form.ts#objectForm (const)",
823848
"objectTitleCompleteness": "src/data/display-name.ts#objectTitleCompleteness (function)",
824849
"parseAutonumberFormat": "src/data/autonumber-format.ts#parseAutonumberFormat (function)",
825850
"parseDateMacroParam": "src/data/date-macros.zod.ts#parseDateMacroParam (function)",
826851
"parseFilterAST": "src/data/filter.zod.ts#parseFilterAST (function)",
852+
"parseNumericString": "src/data/filter-number-comparand-declared-type.ts#parseNumericString (function)",
827853
"passthroughSecretPaths": "src/data/datasource-credential-redaction.ts#passthroughSecretPaths (function)",
828854
"percentScaleOf": "src/data/percent-scale.ts#percentScaleOf (function)",
829855
"placeholderFree": "src/data/driver/common.zod.ts#placeholderFree (function)",
830856
"placeholderFreeDeep": "src/data/driver/common.zod.ts#placeholderFreeDeep (function)",
831857
"platformProvisionsStorage": "src/data/injected-system-column-provenance.ts#platformProvisionsStorage (function)",
832858
"provisionPrimary": "src/data/display-name.ts#provisionPrimary (function)",
833859
"readAutonumberCounter": "src/data/autonumber-format.ts#readAutonumberCounter (function)",
860+
"readNumericString": "src/data/filter-number-comparand-declared-type.ts#readNumericString (function)",
834861
"redactDatasourceConfig": "src/data/datasource-credential-redaction.ts#redactDatasourceConfig (function)",
835862
"redactUrlCredentialQueryParams": "src/data/datasource-credential-redaction.ts#redactUrlCredentialQueryParams (function)",
836863
"redactUrlCredentials": "src/data/datasource-credential-redaction.ts#redactUrlCredentials (function)",

0 commit comments

Comments
 (0)