From cf20e589f8fd95ab011b9fd14f0fcf9664f123ed Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Fri, 23 Oct 2026 21:18:32 +0200 Subject: [PATCH] chore(bundler): more tests Signed-off-by: Jan Kowalleck --- .../js/bundler/test/fixtures/main.schema.json | 13 +++ .../modules/used-whole-data.schema.json | 88 +++++++++++++++ .../snapshot/main-bundled.min.schema.json | 2 +- .../test/snapshot/main-bundled.schema.json | 101 +++++++++++++++++- .../main/js/bundler/test/snapshot/report.json | 8 ++ 5 files changed, 210 insertions(+), 2 deletions(-) create mode 100644 tools/src/main/js/bundler/test/fixtures/modules/used-whole-data.schema.json diff --git a/tools/src/main/js/bundler/test/fixtures/main.schema.json b/tools/src/main/js/bundler/test/fixtures/main.schema.json index ff59a103..b668fef2 100644 --- a/tools/src/main/js/bundler/test/fixtures/main.schema.json +++ b/tools/src/main/js/bundler/test/fixtures/main.schema.json @@ -5,6 +5,13 @@ "title": "Main", "description": "Root document of the bundler test fixtures.", "type": "object", + "required": [ + "whole" + ], + "examples": [ + {"whole": {}} + ], + "$comment": "FIXTURE: root schema; entry point of the bundle. This $comment is the only one that survives minification. The root title/description must survive in both outputs. The root `required`/`examples` are data arrays inside the (reached) root schema and must survive the tree-shaker untouched.", "properties": { "$comment": { "$comment": "the comment property is expected to stay - but this comment might be removed.", @@ -17,6 +24,12 @@ "description": "A module referenced in its entirety.", "$ref": "modules/used-whole.schema.json" }, + "wholeData": { + "$comment": "External ref without fragment to a module whose reached schemas carry data arrays/maps/literals and boolean subschemas -> all of that must survive the sweep.", + "title": "Whole data", + "description": "A data-heavy module referenced in its entirety.", + "$ref": "modules/used-whole-data.schema.json" + }, "sub": { "$comment": "External ref into a sub-def -> only that sub-def (and what it reaches) is kept.", "title": "Sub", diff --git a/tools/src/main/js/bundler/test/fixtures/modules/used-whole-data.schema.json b/tools/src/main/js/bundler/test/fixtures/modules/used-whole-data.schema.json new file mode 100644 index 00000000..aaf58b28 --- /dev/null +++ b/tools/src/main/js/bundler/test/fixtures/modules/used-whole-data.schema.json @@ -0,0 +1,88 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "http://example.com/test/modules/used-whole-data.schema.json", + "$comment": "FIXTURE: a module referenced as a whole whose REACHED schemas carry non-schema data (arrays, maps, literals) and boolean subschemas. The tree-shaker must leave every one of these byte-for-byte intact: a reached schema may only lose unreferenced `$defs`. Any `null` item, emptied map, or dropped key below is a sweep bug.", + "title": "Used whole data", + "description": "A module referenced in its entirety that carries data-bearing keywords inside reached schemas.", + "type": "object", + "required": [ + "status", + "level" + ], + "examples": [ + { + "status": "on", + "level": 1 + }, + { + "status": "off", + "level": 2 + } + ], + "default": { + "status": "on", + "level": 1 + }, + "properties": { + "status": { + "$comment": "`enum` is a data array inside a reached schema -> items must stay literals, never become `null`. `meta:enum` is a non-schema map -> entries must not be emptied.", + "title": "Status", + "description": "A status value.", + "type": "string", + "enum": [ + "on", + "off" + ], + "meta:enum": { + "on": "It is on.", + "off": "It is off." + } + }, + "level": { + "$comment": "`const`, `examples` and `default` are literal data in a reached schema -> must stay as is.", + "title": "Level", + "description": "A fixed level.", + "type": "integer", + "const": 1, + "examples": [ + 1 + ], + "default": 1 + }, + "flags": { + "$comment": "`properties` map that contains BOOLEAN subschemas. Booleans are not schema objects, so `subschemas()` never yields them; the sweep must nevertheless keep the keys `anything`/`nothing` with their boolean values.", + "title": "Flags", + "description": "An object with boolean-schema properties.", + "type": "object", + "required": [ + "anything" + ], + "properties": { + "anything": true, + "nothing": false + }, + "additionalProperties": false + }, + "tags": { + "$comment": "`items` is a schema; `uniqueItems`/`minItems` are scalars in a reached schema -> kept.", + "title": "Tags", + "description": "A list of tags.", + "type": "array", + "uniqueItems": true, + "minItems": 0, + "items": { + "title": "Tag", + "description": "A single tag.", + "type": "string" + } + } + }, + "$defs": { + "unusedDef": { + "$comment": "The ONLY thing the tree-shaker is allowed to drop from this module.", + "title": "Unused def", + "description": "A definition nothing reachable refers to.", + "type": "null" + } + } +} diff --git a/tools/src/main/js/bundler/test/snapshot/main-bundled.min.schema.json b/tools/src/main/js/bundler/test/snapshot/main-bundled.min.schema.json index fbf6b2ee..afb8f585 100644 --- a/tools/src/main/js/bundler/test/snapshot/main-bundled.min.schema.json +++ b/tools/src/main/js/bundler/test/snapshot/main-bundled.min.schema.json @@ -1 +1 @@ -{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"http://example.com/test/main-bundled.min.schema.json","$comment":"FIXTURE: root schema; entry point of the bundle. This $comment is the only one that survives minification. The root title/description must survive in both outputs.","title":"Main","description":"Root document of the bundler test fixtures.","type":"object","properties":{"$comment":{"type":"string","title":"Comment"},"whole":{"title":"Whole","description":"A module referenced in its entirety.","$ref":"#/$defs/used-whole"},"sub":{"title":"Sub","description":"A single definition of another module.","$ref":"#/$defs/used-subdefs-only/$defs/kept"},"local":{"title":"Local","description":"A definition of this very schema.","$ref":"#/$defs/main/$defs/mainLocal"},"composed":{"title":"Composed","description":"An object assembled from parts of another module.","type":"object","$defs":{"rootNestedDropped":{"title":"Root nested dropped","description":"An unreferenced nested definition of the root.","type":"null"}},"properties":{"street":{"title":"Street","description":"The street, taken from the module's address.","$ref":"#/$defs/used-properties-only/properties/address/properties/street"},"latitude":{"title":"Latitude","description":"The latitude, taken from the module's address.geo.","$ref":"#/$defs/used-properties-only/properties/address/properties/geo/properties/lat"},"contact":{"title":"Contact","description":"The contact block of the module, as is.","$ref":"#/$defs/used-properties-only/properties/contact"},"nested":{"title":"Nested","description":"A value defined in a property-level $defs.","$ref":"#/$defs/used-whole/properties/withDefs/$defs/nestedKept"}}},"middle":{"title":"Middle","description":"The middle part of the module's combined schema.","$ref":"#/$defs/used-array-items/properties/combined/allOf/1"},"lastChoice":{"title":"Last choice","description":"The last alternative of the module's choice.","$ref":"#/$defs/used-array-items/properties/choice/oneOf/1"},"anyValue":{"title":"Any value","description":"Accepts anything.","$ref":"#/$defs/used-subdefs-only/$defs/keptEmpty"},"todoValue":{"title":"Todo value","description":"A placeholder.","$ref":"#/$defs/used-subdefs-only/$defs/keptCommentOnly"},"annotatedValue":{"title":"Annotated value","description":"An annotation-only schema.","$ref":"#/$defs/used-subdefs-only/$defs/keptAnnotationsOnly"}},"$defs":{"dynamic-anchor":{"$dynamicAnchor":"node","title":"Dynamic anchor","description":"A recursive tree node, addressable via a dynamic anchor.","type":"object","properties":{"children":{"title":"Children","description":"The child nodes of this node.","type":"array","items":{"title":"Child","description":"A nested node.","$ref":"#/$defs/dynamic-anchor"}}}},"main":{"$defs":{"mainLocal":{"title":"Main local","description":"A local string definition of the root schema.","type":"string"},"mainUnused":{"title":"Main unused","description":"A definition nothing refers to.","type":"null"}},"not":{}},"unused":{"title":"Unused","description":"A module that nothing reachable refers to.","type":"object","properties":{"pullsNothingIn":{"title":"Pulls nothing in","description":"A flag defined by another module.","$ref":"#/$defs/used-whole/$defs/unused"}}},"used-array-items":{"title":"Used array items","description":"A module of which only individual array items and a non-schema value are referenced.","type":"object","properties":{"combined":{"title":"Combined","description":"A composition of which only the middle part is referenced.","allOf":[{"title":"Combined part 0","description":"The first part.","type":"object","properties":{"a":{"title":"A","description":"An unreferenced value.","type":"string"}}},{"title":"Combined part 1","description":"The middle part.","type":"object","properties":{"b":{"title":"B","description":"A value defined in this module.","$ref":"#/$defs/used-array-items/$defs/keptViaArray"}}},{"title":"Combined part 2","description":"The last part.","$ref":"#/$defs/unused"}]},"choice":{"title":"Choice","description":"A choice of which only the last alternative is referenced.","oneOf":[{"title":"Choice 0","description":"The first alternative.","type":"null","$defs":{"droppedDef":{"title":"Dropped def","description":"A definition nothing reachable refers to.","type":"null"}}},{"title":"Choice 1","description":"The second alternative.","type":"integer","$defs":{"droppedDef":{"title":"Dropped def","description":"A definition nothing reachable refers to.","type":"null"}}}],"examples":[null,1,2,3]}},"$defs":{"keptViaArray":{"title":"Kept via array","description":"A boolean value.","type":"boolean"},"droppedDef":{"title":"Dropped def","description":"A definition nothing reachable refers to.","type":"null"}}},"used-properties-only":{"title":"Used properties only","description":"A module of which only nested properties are referenced.","type":"object","properties":{"address":{"title":"Address","description":"A postal address.","type":"object","properties":{"street":{"title":"Street","description":"Street name and number.","type":"string"},"city":{"title":"City","description":"Name of the city.","type":"string"},"geo":{"title":"Geo","description":"Geographic coordinates.","type":"object","properties":{"lat":{"title":"Latitude","description":"Latitude in degrees.","$ref":"#/$defs/used-properties-only/$defs/degrees"},"lon":{"title":"Longitude","description":"Longitude in degrees.","$ref":"#/$defs/used-properties-only/$defs/degrees"}}}}},"contact":{"title":"Contact","description":"Contact details.","type":"object","properties":{"email":{"title":"E-mail","description":"An e-mail address.","type":"string","format":"email"},"phone":{"title":"Phone","description":"A phone number.","type":"string"}}},"unusedTopLevel":{"title":"Unused top level","description":"A property nothing refers to.","$ref":"#/$defs/unused"}},"$defs":{"degrees":{"title":"Degrees","description":"An angle in degrees.","type":"number","minimum":-180,"maximum":180},"unusedDef":{"title":"Unused def","description":"A definition nothing reachable refers to.","type":"null"}}},"used-subdefs-only":{"title":"Used sub-defs only","description":"A module of which only individual definitions are referenced.","type":"object","properties":{"body":{"title":"Body","description":"The body of this module.","$ref":"#/$defs/unused"}},"$defs":{"kept":{"title":"Kept","description":"A definition that is reached directly from the root schema.","type":"object","properties":{"shared":{"title":"Shared","description":"A value defined by another module.","$ref":"#/$defs/used-whole/$defs/sharedByOther"},"fromMain":{"title":"From main","description":"A value defined by the root schema.","$ref":"#/$defs/main/$defs/mainLocal"},"chain":{"title":"Chain","description":"A value defined further down in this module.","$ref":"#/$defs/used-subdefs-only/$defs/keptTransitively"}}},"keptEmpty":{},"keptCommentOnly":{},"keptAnnotationsOnly":{"title":"Kept annotations only","description":"A schema that is just an annotation."},"keptTransitively":{"title":"Kept transitively","description":"A string value.","type":"string"},"dropped":{"title":"Dropped","description":"A definition nothing reachable refers to.","type":"null"}}},"used-whole":{"title":"Used whole","description":"A module that is referenced in its entirety.","type":"object","properties":{"name":{"title":"Name","description":"A display name.","type":"string","$defs":{"nestedDropped":{"title":"Nested dropped","description":"An unreferenced nested definition.","type":"null"}}},"withDefs":{"title":"With defs","description":"A property that hosts its own definitions.","anyOf":[{"title":"Is string","type":"string"},{"title":"Non-zero number","type":"number","if":{"const":0,"$defs":{"unused":{"title":"Unused","type":"null"}}},"then":false,"else":true,"$defs":{"unusedPositive":{"title":"Number > 0","type":"number","exclusiveMinimum":0},"unusedNegative":{"title":"Number < 0","type":"number","exclusiveMaximum":0}}}],"$defs":{"nestedKept":{"title":"Nested kept","description":"A referenced nested definition.","type":"integer"},"nestedDropped":{"title":"Nested dropped","description":"An unreferenced nested definition.","type":"null"}}},"inner":{"title":"Inner","description":"Sibling annotations next to a $ref: title/description are kept, while the sibling $comment is removed in the minified output.","$ref":"#/$defs/used-whole/$defs/inner"},"license":{"title":"License","description":"The license of this item.","$ref":"externals/not-bundled.schema.json#/$defs/licenseId"},"remote":{"title":"Remote","description":"A thing defined by a remote schema.","$ref":"https://example.com/remote.schema.json#/$defs/thing"},"inArray":{"title":"In array","description":"A composition of several referenced schemas.","allOf":[{"$ref":"#/$defs/used-whole/$defs/inner"},{"$ref":"#/$defs/used-subdefs-only/$defs/keptTransitively"},{"$ref":"externals/not-bundled.schema.json#/$defs/licenseId"}]}},"$defs":{"inner":{"title":"Inner","description":"An integer value.","type":"integer"},"unused":{"title":"Unused","description":"A flag.","type":"boolean"},"sharedByOther":{"title":"Shared by other","description":"A numeric value shared across modules.","type":"number"}}}}} \ No newline at end of file +{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"http://example.com/test/main-bundled.min.schema.json","$comment":"FIXTURE: root schema; entry point of the bundle. This $comment is the only one that survives minification. The root title/description must survive in both outputs. The root `required`/`examples` are data arrays inside the (reached) root schema and must survive the tree-shaker untouched.","title":"Main","description":"Root document of the bundler test fixtures.","type":"object","required":["whole"],"examples":[{"whole":{}}],"properties":{"$comment":{"type":"string","title":"Comment"},"whole":{"title":"Whole","description":"A module referenced in its entirety.","$ref":"#/$defs/used-whole"},"wholeData":{"title":"Whole data","description":"A data-heavy module referenced in its entirety.","$ref":"#/$defs/used-whole-data"},"sub":{"title":"Sub","description":"A single definition of another module.","$ref":"#/$defs/used-subdefs-only/$defs/kept"},"local":{"title":"Local","description":"A definition of this very schema.","$ref":"#/$defs/main/$defs/mainLocal"},"composed":{"title":"Composed","description":"An object assembled from parts of another module.","type":"object","$defs":{"rootNestedDropped":{"title":"Root nested dropped","description":"An unreferenced nested definition of the root.","type":"null"}},"properties":{"street":{"title":"Street","description":"The street, taken from the module's address.","$ref":"#/$defs/used-properties-only/properties/address/properties/street"},"latitude":{"title":"Latitude","description":"The latitude, taken from the module's address.geo.","$ref":"#/$defs/used-properties-only/properties/address/properties/geo/properties/lat"},"contact":{"title":"Contact","description":"The contact block of the module, as is.","$ref":"#/$defs/used-properties-only/properties/contact"},"nested":{"title":"Nested","description":"A value defined in a property-level $defs.","$ref":"#/$defs/used-whole/properties/withDefs/$defs/nestedKept"}}},"middle":{"title":"Middle","description":"The middle part of the module's combined schema.","$ref":"#/$defs/used-array-items/properties/combined/allOf/1"},"lastChoice":{"title":"Last choice","description":"The last alternative of the module's choice.","$ref":"#/$defs/used-array-items/properties/choice/oneOf/1"},"anyValue":{"title":"Any value","description":"Accepts anything.","$ref":"#/$defs/used-subdefs-only/$defs/keptEmpty"},"todoValue":{"title":"Todo value","description":"A placeholder.","$ref":"#/$defs/used-subdefs-only/$defs/keptCommentOnly"},"annotatedValue":{"title":"Annotated value","description":"An annotation-only schema.","$ref":"#/$defs/used-subdefs-only/$defs/keptAnnotationsOnly"}},"$defs":{"dynamic-anchor":{"$dynamicAnchor":"node","title":"Dynamic anchor","description":"A recursive tree node, addressable via a dynamic anchor.","type":"object","properties":{"children":{"title":"Children","description":"The child nodes of this node.","type":"array","items":{"title":"Child","description":"A nested node.","$ref":"#/$defs/dynamic-anchor"}}}},"main":{"$defs":{"mainLocal":{"title":"Main local","description":"A local string definition of the root schema.","type":"string"},"mainUnused":{"title":"Main unused","description":"A definition nothing refers to.","type":"null"}},"not":{}},"unused":{"title":"Unused","description":"A module that nothing reachable refers to.","type":"object","properties":{"pullsNothingIn":{"title":"Pulls nothing in","description":"A flag defined by another module.","$ref":"#/$defs/used-whole/$defs/unused"}}},"used-array-items":{"title":"Used array items","description":"A module of which only individual array items and a non-schema value are referenced.","type":"object","properties":{"combined":{"title":"Combined","description":"A composition of which only the middle part is referenced.","allOf":[{"title":"Combined part 0","description":"The first part.","type":"object","properties":{"a":{"title":"A","description":"An unreferenced value.","type":"string"}}},{"title":"Combined part 1","description":"The middle part.","type":"object","properties":{"b":{"title":"B","description":"A value defined in this module.","$ref":"#/$defs/used-array-items/$defs/keptViaArray"}}},{"title":"Combined part 2","description":"The last part.","$ref":"#/$defs/unused"}]},"choice":{"title":"Choice","description":"A choice of which only the last alternative is referenced.","oneOf":[{"title":"Choice 0","description":"The first alternative.","type":"null","$defs":{"droppedDef":{"title":"Dropped def","description":"A definition nothing reachable refers to.","type":"null"}}},{"title":"Choice 1","description":"The second alternative.","type":"integer","$defs":{"droppedDef":{"title":"Dropped def","description":"A definition nothing reachable refers to.","type":"null"}}}],"examples":[null,1,2,3]}},"$defs":{"keptViaArray":{"title":"Kept via array","description":"A boolean value.","type":"boolean"},"droppedDef":{"title":"Dropped def","description":"A definition nothing reachable refers to.","type":"null"}}},"used-properties-only":{"title":"Used properties only","description":"A module of which only nested properties are referenced.","type":"object","properties":{"address":{"title":"Address","description":"A postal address.","type":"object","properties":{"street":{"title":"Street","description":"Street name and number.","type":"string"},"city":{"title":"City","description":"Name of the city.","type":"string"},"geo":{"title":"Geo","description":"Geographic coordinates.","type":"object","properties":{"lat":{"title":"Latitude","description":"Latitude in degrees.","$ref":"#/$defs/used-properties-only/$defs/degrees"},"lon":{"title":"Longitude","description":"Longitude in degrees.","$ref":"#/$defs/used-properties-only/$defs/degrees"}}}}},"contact":{"title":"Contact","description":"Contact details.","type":"object","properties":{"email":{"title":"E-mail","description":"An e-mail address.","type":"string","format":"email"},"phone":{"title":"Phone","description":"A phone number.","type":"string"}}},"unusedTopLevel":{"title":"Unused top level","description":"A property nothing refers to.","$ref":"#/$defs/unused"}},"$defs":{"degrees":{"title":"Degrees","description":"An angle in degrees.","type":"number","minimum":-180,"maximum":180},"unusedDef":{"title":"Unused def","description":"A definition nothing reachable refers to.","type":"null"}}},"used-subdefs-only":{"title":"Used sub-defs only","description":"A module of which only individual definitions are referenced.","type":"object","properties":{"body":{"title":"Body","description":"The body of this module.","$ref":"#/$defs/unused"}},"$defs":{"kept":{"title":"Kept","description":"A definition that is reached directly from the root schema.","type":"object","properties":{"shared":{"title":"Shared","description":"A value defined by another module.","$ref":"#/$defs/used-whole/$defs/sharedByOther"},"fromMain":{"title":"From main","description":"A value defined by the root schema.","$ref":"#/$defs/main/$defs/mainLocal"},"chain":{"title":"Chain","description":"A value defined further down in this module.","$ref":"#/$defs/used-subdefs-only/$defs/keptTransitively"}}},"keptEmpty":{},"keptCommentOnly":{},"keptAnnotationsOnly":{"title":"Kept annotations only","description":"A schema that is just an annotation."},"keptTransitively":{"title":"Kept transitively","description":"A string value.","type":"string"},"dropped":{"title":"Dropped","description":"A definition nothing reachable refers to.","type":"null"}}},"used-whole":{"title":"Used whole","description":"A module that is referenced in its entirety.","type":"object","properties":{"name":{"title":"Name","description":"A display name.","type":"string","$defs":{"nestedDropped":{"title":"Nested dropped","description":"An unreferenced nested definition.","type":"null"}}},"withDefs":{"title":"With defs","description":"A property that hosts its own definitions.","anyOf":[{"title":"Is string","type":"string"},{"title":"Non-zero number","type":"number","if":{"const":0,"$defs":{"unused":{"title":"Unused","type":"null"}}},"then":false,"else":true,"$defs":{"unusedPositive":{"title":"Number > 0","type":"number","exclusiveMinimum":0},"unusedNegative":{"title":"Number < 0","type":"number","exclusiveMaximum":0}}}],"$defs":{"nestedKept":{"title":"Nested kept","description":"A referenced nested definition.","type":"integer"},"nestedDropped":{"title":"Nested dropped","description":"An unreferenced nested definition.","type":"null"}}},"inner":{"title":"Inner","description":"Sibling annotations next to a $ref: title/description are kept, while the sibling $comment is removed in the minified output.","$ref":"#/$defs/used-whole/$defs/inner"},"license":{"title":"License","description":"The license of this item.","$ref":"externals/not-bundled.schema.json#/$defs/licenseId"},"remote":{"title":"Remote","description":"A thing defined by a remote schema.","$ref":"https://example.com/remote.schema.json#/$defs/thing"},"inArray":{"title":"In array","description":"A composition of several referenced schemas.","allOf":[{"$ref":"#/$defs/used-whole/$defs/inner"},{"$ref":"#/$defs/used-subdefs-only/$defs/keptTransitively"},{"$ref":"externals/not-bundled.schema.json#/$defs/licenseId"}]}},"$defs":{"inner":{"title":"Inner","description":"An integer value.","type":"integer"},"unused":{"title":"Unused","description":"A flag.","type":"boolean"},"sharedByOther":{"title":"Shared by other","description":"A numeric value shared across modules.","type":"number"}}},"used-whole-data":{"title":"Used whole data","description":"A module referenced in its entirety that carries data-bearing keywords inside reached schemas.","type":"object","required":["status","level"],"examples":[{"status":"on","level":1},{"status":"off","level":2}],"default":{"status":"on","level":1},"properties":{"status":{"title":"Status","description":"A status value.","type":"string","enum":["on","off"],"meta:enum":{"on":"It is on.","off":"It is off."}},"level":{"title":"Level","description":"A fixed level.","type":"integer","const":1,"examples":[1],"default":1},"flags":{"title":"Flags","description":"An object with boolean-schema properties.","type":"object","required":["anything"],"properties":{"anything":true,"nothing":false},"additionalProperties":false},"tags":{"title":"Tags","description":"A list of tags.","type":"array","uniqueItems":true,"minItems":0,"items":{"title":"Tag","description":"A single tag.","type":"string"}}},"$defs":{"unusedDef":{"title":"Unused def","description":"A definition nothing reachable refers to.","type":"null"}}}}} \ No newline at end of file diff --git a/tools/src/main/js/bundler/test/snapshot/main-bundled.schema.json b/tools/src/main/js/bundler/test/snapshot/main-bundled.schema.json index b683a4d1..c39871a5 100644 --- a/tools/src/main/js/bundler/test/snapshot/main-bundled.schema.json +++ b/tools/src/main/js/bundler/test/snapshot/main-bundled.schema.json @@ -1,10 +1,18 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "http://example.com/test/main-bundled.schema.json", - "$comment": "FIXTURE: root schema; entry point of the bundle. This $comment is the only one that survives minification. The root title/description must survive in both outputs.", + "$comment": "FIXTURE: root schema; entry point of the bundle. This $comment is the only one that survives minification. The root title/description must survive in both outputs. The root `required`/`examples` are data arrays inside the (reached) root schema and must survive the tree-shaker untouched.", "title": "Main", "description": "Root document of the bundler test fixtures.", "type": "object", + "required": [ + "whole" + ], + "examples": [ + { + "whole": {} + } + ], "properties": { "$comment": { "$comment": "the comment property is expected to stay - but this comment might be removed.", @@ -17,6 +25,12 @@ "description": "A module referenced in its entirety.", "$ref": "#/$defs/used-whole" }, + "wholeData": { + "$comment": "External ref without fragment to a module whose reached schemas carry data arrays/maps/literals and boolean subschemas -> all of that must survive the sweep.", + "title": "Whole data", + "description": "A data-heavy module referenced in its entirety.", + "$ref": "#/$defs/used-whole-data" + }, "sub": { "$comment": "External ref into a sub-def -> only that sub-def (and what it reaches) is kept.", "title": "Sub", @@ -532,6 +546,91 @@ "type": "number" } } + }, + "used-whole-data": { + "title": "Used whole data", + "description": "A module referenced in its entirety that carries data-bearing keywords inside reached schemas.", + "type": "object", + "required": [ + "status", + "level" + ], + "examples": [ + { + "status": "on", + "level": 1 + }, + { + "status": "off", + "level": 2 + } + ], + "default": { + "status": "on", + "level": 1 + }, + "properties": { + "status": { + "$comment": "`enum` is a data array inside a reached schema -> items must stay literals, never become `null`. `meta:enum` is a non-schema map -> entries must not be emptied.", + "title": "Status", + "description": "A status value.", + "type": "string", + "enum": [ + "on", + "off" + ], + "meta:enum": { + "on": "It is on.", + "off": "It is off." + } + }, + "level": { + "$comment": "`const`, `examples` and `default` are literal data in a reached schema -> must stay as is.", + "title": "Level", + "description": "A fixed level.", + "type": "integer", + "const": 1, + "examples": [ + 1 + ], + "default": 1 + }, + "flags": { + "$comment": "`properties` map that contains BOOLEAN subschemas. Booleans are not schema objects, so `subschemas()` never yields them; the sweep must nevertheless keep the keys `anything`/`nothing` with their boolean values.", + "title": "Flags", + "description": "An object with boolean-schema properties.", + "type": "object", + "required": [ + "anything" + ], + "properties": { + "anything": true, + "nothing": false + }, + "additionalProperties": false + }, + "tags": { + "$comment": "`items` is a schema; `uniqueItems`/`minItems` are scalars in a reached schema -> kept.", + "title": "Tags", + "description": "A list of tags.", + "type": "array", + "uniqueItems": true, + "minItems": 0, + "items": { + "title": "Tag", + "description": "A single tag.", + "type": "string" + } + } + }, + "$defs": { + "unusedDef": { + "$comment": "The ONLY thing the tree-shaker is allowed to drop from this module.", + "title": "Unused def", + "description": "A definition nothing reachable refers to.", + "type": "null" + } + } } } } \ No newline at end of file diff --git a/tools/src/main/js/bundler/test/snapshot/report.json b/tools/src/main/js/bundler/test/snapshot/report.json index 7afd047a..3a5e3dad 100644 --- a/tools/src/main/js/bundler/test/snapshot/report.json +++ b/tools/src/main/js/bundler/test/snapshot/report.json @@ -29,6 +29,10 @@ "modules/used-subdefs-only.schema.json", "#/$defs/used-subdefs-only" ], + [ + "modules/used-whole-data.schema.json", + "#/$defs/used-whole-data" + ], [ "modules/used-whole.schema.json", "#/$defs/used-whole" @@ -39,6 +43,10 @@ "modules/used-whole.schema.json", "#/$defs/used-whole" ], + [ + "modules/used-whole-data.schema.json", + "#/$defs/used-whole-data" + ], [ "modules/used-subdefs-only.schema.json#/$defs/kept", "#/$defs/used-subdefs-only/$defs/kept"