lutaml-jsonschema 0.1.24 → 0.1.26

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 229f1667cd05ad90ee3f424ebc68ae1720ec3219eeec3584a1f65d76f09cf90c
4
- data.tar.gz: 224e628bec6fe5d06986a0dbdee00cb5946b8d39b00e1baa4c3777503db4fbb2
3
+ metadata.gz: b7c72a0b9f42bf072c40e4f52b986ba536f59ed1eaa96650bd6df86d469a16e1
4
+ data.tar.gz: 818f5e758c204d40d20f371ccb3cc6e772ab2c9e7b54e59c5f02de9b0050b9db
5
5
  SHA512:
6
- metadata.gz: 2602ab20233317d4d1ae319739dbc98b86a92598d5decb13a6f5e4e5c3bd0398b69c53698d16c35426599ccd029b565c7a3ceda8546b837d6030d471bcae2c13
7
- data.tar.gz: f647240a0ce3da5e729da26cbe79e71e02ae3a17bd16b58c71e80bff88711cb8e34d81787caad00522c6494c2ca90c0c0b59966c252f6d96e56e550be6cf355b
6
+ metadata.gz: 85878a652c2ffee03bed715b5ee1eb83c0b54b8d16e04ef5dee20977ebed04f7b239a8f2a0c43a2c49e25b14a96a55dc620e9c8033b5f4d20afd3fc0108fef56
7
+ data.tar.gz: 4ab26811feb7b7be7ff0ebe407582ba1adf2c6a2109c84d4a411e16e544cec7186ad276043425f027178fd2782fbb5aea54c6c921a90c069341d722c38d2f850
data/.rubocop_todo.yml CHANGED
@@ -187,7 +187,7 @@ Metrics/AbcSize:
187
187
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
188
188
  # AllowedMethods: refine
189
189
  Metrics/BlockLength:
190
- Max: 54
190
+ Max: 57
191
191
 
192
192
  # Offense count: 12
193
193
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
data/CLAUDE.md CHANGED
@@ -16,14 +16,14 @@ bundle exec rspec # full suite
16
16
  bundle exec rspec spec/lutaml/cli_spec.rb # one file
17
17
  bundle exec rspec spec/lutaml/cli_spec.rb:76 # one example
18
18
  bundle exec rubocop # lint (-a to autofix; .rubocop_todo.yml holds baselined offenses)
19
- bundle exec rake # spec + rubocop (what CI runs)
19
+ bundle exec rake # spec + rubocop + perf gate + axe AA audit (what CI runs)
20
20
 
21
21
  bundle exec rake frontend:build # npm install + vite build → frontend/dist
22
22
  cd frontend && npm test # vitest (frontend unit tests)
23
23
 
24
24
  bundle exec exe/lutaml-jsonschema spa SCHEMA_FILES... [--diff BASELINE...]
25
25
  bundle exec exe/lutaml-jsonschema combine|validate SCHEMA_FILES...
26
- bundle exec exe/lutaml-jsonschema export SCHEMA_FILES... -f cddl|openapi|xsd|adoc
26
+ bundle exec exe/lutaml-jsonschema export SCHEMA_FILES... -f cddl|openapi|xsd|adoc|lml
27
27
  bundle exec exe/lutaml-jsonschema diff OLD NEW [--format json]
28
28
  ```
29
29
 
@@ -34,13 +34,14 @@ bundle exec exe/lutaml-jsonschema diff OLD NEW [--format json]
34
34
  Data flow: schema files → `SchemaSet.load_from_files` → `Spa::SpaBuilder` → `Spa::SpaDocument` → `to_json` → `Spa::VueInlinedStrategy` (embeds `window.SCHEMA_DATA` + inlined JS/CSS into `index.html`).
35
35
 
36
36
  - **`Base`** — everything inherits from `Lutaml::Model::Serializable`. `Base` also forward-declares `Schema` to break the circular `Schema ↔ PropertyEntry ↔ Link` references.
37
- - **`Schema`** — the central model of a JSON Schema document. Every `$`-prefixed keyword is a `dollar_`-prefixed attribute (`$schema` → `dollar_schema`) via json mappings. `Schema.from_json` / `to_json` are lutaml-model serialization.
37
+ - **`Schema`** — the central model of a JSON Schema document. Every `$`-prefixed keyword is a `dollar_`-prefixed attribute (`$schema` → `dollar_schema`) via json mappings. `Schema.from_json` / `to_json` are lutaml-model serialization. The model is **lossless**: `map_unmapped to: :extensions` collects every unmodeled keyword (vendor `x-*`, dialect additions) verbatim and re-emits it — new keywords land as attributes, not in a hand-rolled serializer.
38
38
  - **`SchemaSet`** — in-memory named collection of schemas plus `$ref` resolution (local `#/...` pointers and relative `./file.json` refs through `ReferenceResolver`) and validation.
39
39
  - **`SchemaStore`** — `SchemaSet` subclass that adds on-disk persistence through **lutaml-store** (`PackageStore`, package shape from `LjrPackageDefinition`).
40
40
  - **`Combiner`** — compatibility facade; bundling lives in `SchemaSet#bundle` (hoists definitions, adds a top-level `$ref` property per source schema, rewrites `#/definitions/` → `#/$defs/`).
41
41
  - **`Spa::*`** — `SpaBuilder` flattens a `SchemaSet` into a `SpaDocument` (metadata, `SpaSchema` list, flat `search_index` for FlexSearch). `Spa::Generator` renders through an `OutputStrategy`; `VueInlinedStrategy` is the only implementation.
42
42
  - **`Configuration`** — YAML config for the SPA (title, theme, appearance…), loaded by `Cli#spa -c`.
43
- - **`Cli`** — Thor commands: `spa` (generate docs; `--diff` embeds a classified change set), `combine` (merge schemas), `export` (cddl/openapi/xsd/adoc), `diff` (exits 1 on breaking changes), `validate` (meta-schema checks), `version`.
43
+ - **`Cli`** — Thor commands: `spa` (generate docs; `--diff` embeds a classified change set), `combine` (merge schemas), `export` (cddl/openapi/xsd/adoc/lml; adoc `--embeddable` drops the level-0 title and namespaces anchors for Metanorma `include::`), `diff` (exits 1 on breaking changes), `validate` (offline meta-schema checks against fully vendored meta-schemas, JSON Pointer error paths), `version`.
44
+ - **`Exports::*`** — one renderer per target language (CDDL, OpenAPI 3.1, XSD, AsciiDoc, LML); all read the same `SchemaSet`, and each documents its approximations on the class. LML output parses back through `lutaml-lml`; CDDL through the RFC 8610 reference parser.
44
45
  - **`TupleItem`** — schema-or-boolean wrapper used by `items`/`prefixItems` arrays and composition collections; models that accept `true`/`false` store booleans in companion `*_boolean` attributes and expose `*_value` helpers.
45
46
 
46
47
  ## JSON engine: yeptris
@@ -51,9 +52,16 @@ Two distinct paths, both engine-backed:
51
52
  - **Model serialization** (`Schema.from_json`/`to_json`, `Configuration.from_yaml`, lutaml-store I/O) goes through lutaml-model, whose `AdapterResolver` auto-detects yeptris from the bundle and routes both `:json` and `:yaml` to its `YeptrisAdapter`. That adapter re-raises parse failures as `JSON::ParserError`, so error handling must cover **both** exception types — see the rescue in `Cli#validate`.
52
53
  - Raw-parse speed depends on the resolved yeptris build shipping a **native materializer for the running Ruby version**; without one it falls back to a pure-Ruby tape engine that is several times slower than `JSON.parse` on large documents (yeptris-ruby#278). Check with `defined?(Yeptris::Native)` (0.6.28.x shipped only Ruby 3.3; 3.4-native starts at 0.6.29.1).
53
54
  - The GC-pressure SIGSEGV in the native JSON materializer (yeptris-ruby#279) is fixed in the yeptris **0.6.34 line** (staged pairs made GC-visible); the gemspec floors at `~> 0.6.34`, excluding the crashy 0.6.29.x–0.6.33.x native builds. Env-gated canary: yeptris-ruby#280.
55
+ - The 0.6.34 C **strict-dup pre-scan** was broken (one shared key table, no growth — false duplicates on ordinary schemas, hang on the 17th distinct key); fixed in yeptris v0.6.35 (per-container frame stacks). Lanes without a native materializer (all Windows) ride that marshal route, so engine bugs surface there first.
56
+
57
+ ## Frontend: i18n, RTL, a11y
58
+
59
+ - All UI strings come from the typed catalog `frontend/src/i18n/messages.ts` (`en` + `ar`); `t()`/`tf()` read a Vue ref, so the header switch re-renders live. A missing key in a locale is a type error — add both languages.
60
+ - The locale mirrors `lang`/`dir` onto `<html>`; layout uses CSS logical properties (`*-inline-*`), so RTL needs no second stylesheet. `?locale=ar` boots straight into a locale.
61
+ - `script/axe_audit` (in the default `rake` gate) scans the generated site with the vendored axe-core; browser-less lanes skip cleanly. The browser specs (boot, PDF, RTL render) run wherever Chrome exists.
54
62
 
55
63
  ## Repo notes
56
64
 
57
- - `README.md` is unreplaced gem-template boilerplate — don't treat it as documentation.
58
65
  - `TODO.redoc/`, `TODO.refactor/`, `TODO.store/` are untracked, numbered working notes (known gaps and planned refactors), not code. `TODO.sota/` holds the SOTA program (purpose, per-area tasks with done-when criteria, and the goal prompt).
59
66
  - CI is metanorma/ci's `generic-rake` workflow; releases run through `.github/workflows/release.yml`.
67
+ - Ruby 4.0 binds brace-less hash literals as keyword arguments — always brace hashes passed to positional-only methods (specs included).
data/README.md CHANGED
@@ -1,39 +1,103 @@
1
1
  # Lutaml::Jsonschema
2
2
 
3
- TODO: Delete this and the text below, and describe your gem
4
-
5
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/lutaml/jsonschema`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ **JSON Schema, fully legible** — a lossless typed model for machines and
4
+ Redoc-class, sovereign single-file documentation for humans, inside the
5
+ LutaML/metanorma standards ecosystem.
6
+
7
+ Parses JSON Schema documents (draft-04 through 2020-12, plus the
8
+ interagent-era hyper-schema corpus) into lutaml-model objects, resolves and
9
+ bundles `$ref` graphs (local pointers, cross-file, and opt-in remote HTTP(S)
10
+ with an offline SHA-256 cache), validates against fully vendored
11
+ meta-schemas, diffs schema versions with breaking-change classification, and
12
+ generates a self-contained documentation SPA — no runtime fetches, no
13
+ network, one `index.html`.
14
+
15
+ **The model is lossless**: every keyword the Ruby model does not name —
16
+ vendor `x-*` extensions, dialect additions, hyper-schema keywords — is
17
+ collected verbatim and re-emitted on serialization (`map_unmapped`).
6
18
 
7
19
  ## Installation
8
20
 
9
- TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
21
+ ```bash
22
+ gem install lutaml-jsonschema
23
+ ```
10
24
 
11
- Install the gem and add to the application's Gemfile by executing:
25
+ or add to your Gemfile:
12
26
 
13
27
  ```bash
14
- bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
28
+ bundle add lutaml-jsonschema
15
29
  ```
16
30
 
17
- If bundler is not being used to manage dependencies, install the gem by executing:
31
+ ## CLI
18
32
 
19
33
  ```bash
20
- gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
34
+ # generate the single-file documentation SPA
35
+ lutaml-jsonschema spa SCHEMA_FILES... [--diff BASELINE...] [-c CONFIG.yml]
36
+
37
+ # merge schema documents into one bundle
38
+ lutaml-jsonschema combine SCHEMA_FILES...
39
+
40
+ # export to other data-definition languages
41
+ lutaml-jsonschema export SCHEMA_FILES... -f cddl|openapi|xsd|adoc|lml
42
+
43
+ # semantic diff; exits non-zero when a breaking change is found
44
+ lutaml-jsonschema diff OLD_SCHEMA NEW_SCHEMA [--format json]
45
+
46
+ # validate against the dialect's meta-schema (offline; --format json)
47
+ lutaml-jsonschema validate SCHEMA_FILE
21
48
  ```
22
49
 
23
- ## Usage
50
+ The SPA supports light/dark themes, FlexSearch search, per-property and
51
+ per-definition detail views, composition tabs, a JSON builder, a change view
52
+ (`--diff`), RTL locales (`?locale=ar`), and prints to PDF.
24
53
 
25
- TODO: Write usage instructions here
54
+ ## Library
26
55
 
27
- ## Development
56
+ ```ruby
57
+ require "lutaml/jsonschema"
28
58
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
59
+ schema = Lutaml::Jsonschema::Schema.from_json(json_string)
60
+ schema.extensions # => unknown keywords, preserved verbatim
61
+ schema.to_json # lossless re-emission
30
62
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
63
+ set = Lutaml::Jsonschema::SchemaSet.load_from_files(*paths)
64
+ set.bundle # hoist definitions, rewrite refs
65
+ set.dereference("demo") # resolve the $ref graph
32
66
 
33
- ## Contributing
67
+ Lutaml::Jsonschema::Exports::Cddl.new(set).render # RFC 8610
68
+ Lutaml::Jsonschema::Exports::Openapi.new(set).render # OAS 3.1 components
69
+ Lutaml::Jsonschema::Exports::Xsd.new(set).render # W3C XML Schema
70
+ Lutaml::Jsonschema::Exports::Adoc.new(set).render # AsciiDoc reference
71
+ Lutaml::Jsonschema::Exports::Lml.new(set).render # LutaML UML models
72
+
73
+ Lutaml::Jsonschema::Diff.between(old_schema, new_schema) # classified changes
74
+ ```
75
+
76
+ `SchemaStore` (a `SchemaSet` subclass) adds on-disk persistence through
77
+ [lutaml-store](https://github.com/lutaml/lutaml-store).
78
+
79
+ ## JSON engine
80
+
81
+ Parsing rides [yeptris](https://github.com/leptris/yeptris-ruby), the org's
82
+ native YAML/JSON engine (FFI over libyeptris, strict RFC 8259 semantics with
83
+ `JSON.parse` parity), auto-detected by lutaml-model for both JSON and YAML.
84
+ JSON generation stays on the stdlib `json` gem.
85
+
86
+ ## Development
34
87
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/lutaml-jsonschema. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/lutaml-jsonschema/blob/main/CODE_OF_CONDUCT.md).
88
+ ```bash
89
+ bundle exec rake # specs + rubocop + perf gate + axe AA audit
90
+ bundle exec rspec # full suite
91
+ cd frontend && npm test # SPA unit tests
92
+ bundle exec rake frontend:build # build frontend/dist (needed for spa)
93
+ ```
36
94
 
37
- ## Code of Conduct
95
+ CI runs the full matrix (3 Ruby lines × ubuntu/macos/windows) on every push,
96
+ including the browser gates (headless-Chrome boot, PDF, RTL render) and the
97
+ WCAG AA audit. `spec/fixtures/` carries the real-world corpora (heroku,
98
+ interagent) the specs round-trip.
99
+
100
+ ## Contributing
38
101
 
39
- Everyone interacting in the Lutaml::Jsonschema project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/lutaml-jsonschema/blob/main/CODE_OF_CONDUCT.md).
102
+ Bug reports and pull requests are welcome on GitHub at
103
+ https://github.com/lutaml/lutaml-jsonschema.
data/Rakefile CHANGED
@@ -9,7 +9,7 @@ require "rubocop/rake_task"
9
9
 
10
10
  RuboCop::RakeTask.new
11
11
 
12
- task default: %i[spec rubocop perf]
12
+ task default: %i[spec rubocop perf frontend:audit]
13
13
 
14
14
  namespace :perf do
15
15
  desc "Pipeline performance harness with regression caps (TODO.sota/08)"