Skip to content

fix(jsonschema): emit map property schemas directly and apply their key and value types - #293

Open
ujjwalv01 wants to merge 1 commit into
accordproject:mainfrom
ujjwalv01:fix/jsonschema-map-schema
Open

ujjwalv01 wants to merge 1 commit into
accordproject:mainfrom
ujjwalv01:fix/jsonschema-map-schema

Conversation

@ujjwalv01

Copy link
Copy Markdown
Contributor

Closes #292

For a property whose type is a map, JSONSchemaVisitor returned the map's schema wrapped in a schema key. schema isn't a JSON Schema keyword, so validators ignored it and map properties accepted any value, including a plain string. Strict Ajv rejected the schema outright (unknown keyword: "schema").

Removing the wrapper means map schemas are evaluated for the first time, which showed three more bugs in the same branch that the wrapper had been hiding:

Map Before After
value is a scalar (map … { o String o SSN }) { "type": "SSN" }: the scalar's name as a JSON type, an invalid schema { "type": "string", "pattern": "…" }, the scalar's base type and validators
key or value has a regex "pattern": "/(\\d{3}-\\d{2}-\\d{4})+/": the delimiters are part of the pattern, so valid SSNs would be rejected "pattern": "(\\d{3}-\\d{2}-\\d{4})+" (regex.source, as for fields)
value is a class declared in another namespace $ref built from the field's namespace, e.g. org.acme.hr@1.0.0.TShirtSizeType and org.acme.hr@1.0.0.Concept, which don't exist the declaration's own name (org.acme.hr.base@1.0.0.TShirtSizeType, concerto@1.0.0.Concept)
value is a class, with refRoot set (as OpenApiVisitor does) always #/definitions/… <refRoot>/…, like other references

Without these fixes, removing the wrapper would make hr_integration's schema fail to compile and make valid data fail validation, so they belong in the same change.

Changes

  • lib/codegen/fromcto/jsonschema/jsonschemavisitor.js: the map branch of visitField returns the map schema itself. Its key and value schemas come from a new private getMapEntrySchema(), which uses the same helper as fields for primitives and scalars (base type, regex.source, length and range validators, uuid and date-time formats), and references class and enum values by their fully qualified name under refRoot.
  • Tests (test/codegen/fromcto/jsonschema/jsonschemavisitor.js):
    • the 5 existing map tests read the property schema directly instead of .schema;
    • new: a map schema compiles with strict Ajv and rejects wrong value types and non-objects;
    • new: scalar map keys and values get their base type and validators (regex, uuid, date-time), checked by validating instances;
    • new: map values from another namespace are referenced correctly, under #/definitions and under a custom refRoot;
    • new: the fallback of getFieldOrScalarDeclarationValidatorsForSchema for an unrecognised type name. Only the scalar-name bug used to reach it, so it would otherwise lose coverage.
    • 8 of these tests fail on main.
  • test/codegen/__snapshots__/codegen.js.snap: regenerated. The diff is the 18 removed wrappers, 6 patterns without delimiters, "SSN" → "string", and the corrected $refs.
  • test/verification/cases.js: two OpenAPI skip reasons updated to what still fails (see Flags).

Flags

  • Generated output changes for every model with a map: map properties now validate. Anyone who relied on map properties accepting anything will now get validation errors for data that doesn't match the model.
  • OpenAPI is better but not fixed: the wrapper error is gone, but OpenAPI 3.0 schema objects don't allow propertyNames, which map key schemas use. So the collectionsize OpenAPI case stays skipped, with an updated reason. (My issue comment said this fix would unblock it; that was wrong, sorry.) For hr_integration, the invalid-type errors go from 5 to 0 and unresolved $refs from 3 to 1; $decorators and propertyNames remain. Both are OpenAPI-specific and out of scope here.
  • Local npm test reports branch coverage at 95.90%, below the 96% threshold, but main is at 95.91% locally for the same reason: without the Go/Java/Rust toolchains the verification tests are skipped, and fix(jsonschema): support non-URL $id values #285 left a branch in fromJsonSchema/cto/jsonSchemaVisitor.js (line 217) untested. CI has the toolchains. I can add a test for that in a separate PR.

Screenshots or Video

N/A

Related Issues

Author Checklist

  • Ensure you provide a DCO sign-off for your commits using the --signoff option of git commit.
  • Vital features and changes captured in unit and/or integration tests
  • Commits messages follow AP format
  • Extend the documentation, if necessary
  • Merging to main from fork:fix/jsonschema-map-schema

Testing (Node 24, Windows 11): npm test 671 passing, 80 pending (toolchains not installed), 0 failing; lint, licchk and jsdoc pass; npm run test:esm 7/7. The hr_integration JSON Schema verification, which compiles the HR model with Ajv, passes with the fix and fails if only the wrapper is removed.

…ey and value types

Map properties were emitted as { schema: {...} }, which validators ignore, so map values were never validated. Map keys and values now go through the same schema helper as fields: scalars contribute their base type and validators (regex.source, uuid and date-time formats), and class values are referenced by their own fully qualified name under refRoot. Fixes accordproject#292

Signed-off-by: Ujjwal Verma <ujjwalverma010305@gmail.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JSONSchemaVisitor: map properties are emitted as { "schema": {...} }, so map values are never validated

1 participant