@ifc-lite/ids-authoring 0.0.0-stage → 0.2.2
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/LICENSE +373 -0
- package/README.md +469 -2
- package/dist/bsdd/cache.d.ts +37 -0
- package/dist/bsdd/cache.d.ts.map +1 -0
- package/dist/bsdd/cache.js +116 -0
- package/dist/bsdd/cache.js.map +1 -0
- package/dist/bsdd/contract.d.ts +31 -0
- package/dist/bsdd/contract.d.ts.map +1 -0
- package/dist/bsdd/contract.js +185 -0
- package/dist/bsdd/contract.js.map +1 -0
- package/dist/bsdd/dictionary.d.ts +42 -0
- package/dist/bsdd/dictionary.d.ts.map +1 -0
- package/dist/bsdd/dictionary.js +115 -0
- package/dist/bsdd/dictionary.js.map +1 -0
- package/dist/bsdd/generator.d.ts +82 -0
- package/dist/bsdd/generator.d.ts.map +1 -0
- package/dist/bsdd/generator.js +155 -0
- package/dist/bsdd/generator.js.map +1 -0
- package/dist/bsdd/http-source.d.ts +15 -0
- package/dist/bsdd/http-source.d.ts.map +1 -0
- package/dist/bsdd/http-source.js +196 -0
- package/dist/bsdd/http-source.js.map +1 -0
- package/dist/bsdd/idb-store.d.ts +16 -0
- package/dist/bsdd/idb-store.d.ts.map +1 -0
- package/dist/bsdd/idb-store.js +58 -0
- package/dist/bsdd/idb-store.js.map +1 -0
- package/dist/bsdd/insert.d.ts +55 -0
- package/dist/bsdd/insert.d.ts.map +1 -0
- package/dist/bsdd/insert.js +105 -0
- package/dist/bsdd/insert.js.map +1 -0
- package/dist/bsdd/mapping.d.ts +62 -0
- package/dist/bsdd/mapping.d.ts.map +1 -0
- package/dist/bsdd/mapping.js +163 -0
- package/dist/bsdd/mapping.js.map +1 -0
- package/dist/bsdd/picker.d.ts +91 -0
- package/dist/bsdd/picker.d.ts.map +1 -0
- package/dist/bsdd/picker.js +151 -0
- package/dist/bsdd/picker.js.map +1 -0
- package/dist/bsdd/types.d.ts +162 -0
- package/dist/bsdd/types.d.ts.map +1 -0
- package/dist/bsdd/types.js +26 -0
- package/dist/bsdd/types.js.map +1 -0
- package/dist/bsdd/uri-health.d.ts +65 -0
- package/dist/bsdd/uri-health.d.ts.map +1 -0
- package/dist/bsdd/uri-health.js +110 -0
- package/dist/bsdd/uri-health.js.map +1 -0
- package/dist/canonical-json.d.ts +7 -0
- package/dist/canonical-json.d.ts.map +1 -0
- package/dist/canonical-json.js +20 -0
- package/dist/canonical-json.js.map +1 -0
- package/dist/comments/view.d.ts +37 -0
- package/dist/comments/view.d.ts.map +1 -0
- package/dist/comments/view.js +61 -0
- package/dist/comments/view.js.map +1 -0
- package/dist/compound/expand.d.ts +5 -0
- package/dist/compound/expand.d.ts.map +1 -0
- package/dist/compound/expand.js +135 -0
- package/dist/compound/expand.js.map +1 -0
- package/dist/compound/from-bsdd.d.ts +9 -0
- package/dist/compound/from-bsdd.d.ts.map +1 -0
- package/dist/compound/from-bsdd.js +166 -0
- package/dist/compound/from-bsdd.js.map +1 -0
- package/dist/diff/align.d.ts +42 -0
- package/dist/diff/align.d.ts.map +1 -0
- package/dist/diff/align.js +78 -0
- package/dist/diff/align.js.map +1 -0
- package/dist/diff/changelog-text.d.ts +39 -0
- package/dist/diff/changelog-text.d.ts.map +1 -0
- package/dist/diff/changelog-text.js +120 -0
- package/dist/diff/changelog-text.js.map +1 -0
- package/dist/diff/changelog.d.ts +28 -0
- package/dist/diff/changelog.d.ts.map +1 -0
- package/dist/diff/changelog.js +173 -0
- package/dist/diff/changelog.js.map +1 -0
- package/dist/diff/compare.d.ts +25 -0
- package/dist/diff/compare.d.ts.map +1 -0
- package/dist/diff/compare.js +150 -0
- package/dist/diff/compare.js.map +1 -0
- package/dist/diff/diff.d.ts +13 -0
- package/dist/diff/diff.d.ts.map +1 -0
- package/dist/diff/diff.js +140 -0
- package/dist/diff/diff.js.map +1 -0
- package/dist/diff/index.d.ts +5 -0
- package/dist/diff/index.d.ts.map +1 -0
- package/dist/diff/index.js +7 -0
- package/dist/diff/index.js.map +1 -0
- package/dist/diff/patch.d.ts +10 -0
- package/dist/diff/patch.d.ts.map +1 -0
- package/dist/diff/patch.js +177 -0
- package/dist/diff/patch.js.map +1 -0
- package/dist/diff/types.d.ts +201 -0
- package/dist/diff/types.d.ts.map +1 -0
- package/dist/diff/types.js +5 -0
- package/dist/diff/types.js.map +1 -0
- package/dist/document/fields.d.ts +33 -0
- package/dist/document/fields.d.ts.map +1 -0
- package/dist/document/fields.js +117 -0
- package/dist/document/fields.js.map +1 -0
- package/dist/document/from-ids.d.ts +32 -0
- package/dist/document/from-ids.d.ts.map +1 -0
- package/dist/document/from-ids.js +47 -0
- package/dist/document/from-ids.js.map +1 -0
- package/dist/document/node-index.d.ts +32 -0
- package/dist/document/node-index.d.ts.map +1 -0
- package/dist/document/node-index.js +127 -0
- package/dist/document/node-index.js.map +1 -0
- package/dist/document/types.d.ts +170 -0
- package/dist/document/types.d.ts.map +1 -0
- package/dist/document/types.js +19 -0
- package/dist/document/types.js.map +1 -0
- package/dist/gate/bsdd.d.ts +12 -0
- package/dist/gate/bsdd.d.ts.map +1 -0
- package/dist/gate/bsdd.js +17 -0
- package/dist/gate/bsdd.js.map +1 -0
- package/dist/gate/check.d.ts +6 -0
- package/dist/gate/check.d.ts.map +1 -0
- package/dist/gate/check.js +125 -0
- package/dist/gate/check.js.map +1 -0
- package/dist/gate/context.d.ts +51 -0
- package/dist/gate/context.d.ts.map +1 -0
- package/dist/gate/context.js +74 -0
- package/dist/gate/context.js.map +1 -0
- package/dist/gate/grounding-pset.d.ts +5 -0
- package/dist/gate/grounding-pset.d.ts.map +1 -0
- package/dist/gate/grounding-pset.js +179 -0
- package/dist/gate/grounding-pset.js.map +1 -0
- package/dist/gate/grounding.d.ts +48 -0
- package/dist/gate/grounding.d.ts.map +1 -0
- package/dist/gate/grounding.js +146 -0
- package/dist/gate/grounding.js.map +1 -0
- package/dist/gate/rank.d.ts +28 -0
- package/dist/gate/rank.d.ts.map +1 -0
- package/dist/gate/rank.js +68 -0
- package/dist/gate/rank.js.map +1 -0
- package/dist/gate/structural.d.ts +43 -0
- package/dist/gate/structural.d.ts.map +1 -0
- package/dist/gate/structural.js +175 -0
- package/dist/gate/structural.js.map +1 -0
- package/dist/gate/types.d.ts +45 -0
- package/dist/gate/types.d.ts.map +1 -0
- package/dist/gate/types.js +5 -0
- package/dist/gate/types.js.map +1 -0
- package/dist/gate/values.d.ts +19 -0
- package/dist/gate/values.d.ts.map +1 -0
- package/dist/gate/values.js +124 -0
- package/dist/gate/values.js.map +1 -0
- package/dist/headless/apply-gated.d.ts +32 -0
- package/dist/headless/apply-gated.d.ts.map +1 -0
- package/dist/headless/apply-gated.js +26 -0
- package/dist/headless/apply-gated.js.map +1 -0
- package/dist/headless/diff.d.ts +41 -0
- package/dist/headless/diff.d.ts.map +1 -0
- package/dist/headless/diff.js +116 -0
- package/dist/headless/diff.js.map +1 -0
- package/dist/headless/node-path.d.ts +10 -0
- package/dist/headless/node-path.d.ts.map +1 -0
- package/dist/headless/node-path.js +24 -0
- package/dist/headless/node-path.js.map +1 -0
- package/dist/headless/read.d.ts +26 -0
- package/dist/headless/read.d.ts.map +1 -0
- package/dist/headless/read.js +78 -0
- package/dist/headless/read.js.map +1 -0
- package/dist/headless/schema-lookup.d.ts +52 -0
- package/dist/headless/schema-lookup.d.ts.map +1 -0
- package/dist/headless/schema-lookup.js +77 -0
- package/dist/headless/schema-lookup.js.map +1 -0
- package/dist/headless/write.d.ts +46 -0
- package/dist/headless/write.d.ts.map +1 -0
- package/dist/headless/write.js +103 -0
- package/dist/headless/write.js.map +1 -0
- package/dist/history/history.d.ts +90 -0
- package/dist/history/history.d.ts.map +1 -0
- package/dist/history/history.js +86 -0
- package/dist/history/history.js.map +1 -0
- package/dist/history/persistence.d.ts +33 -0
- package/dist/history/persistence.d.ts.map +1 -0
- package/dist/history/persistence.js +71 -0
- package/dist/history/persistence.js.map +1 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +75 -0
- package/dist/index.js.map +1 -0
- package/dist/lint/context.d.ts +15 -0
- package/dist/lint/context.d.ts.map +1 -0
- package/dist/lint/context.js +24 -0
- package/dist/lint/context.js.map +1 -0
- package/dist/lint/docs.d.ts +18 -0
- package/dist/lint/docs.d.ts.map +1 -0
- package/dist/lint/docs.js +117 -0
- package/dist/lint/docs.js.map +1 -0
- package/dist/lint/engine.d.ts +21 -0
- package/dist/lint/engine.d.ts.map +1 -0
- package/dist/lint/engine.js +123 -0
- package/dist/lint/engine.js.map +1 -0
- package/dist/lint/fix.d.ts +27 -0
- package/dist/lint/fix.d.ts.map +1 -0
- package/dist/lint/fix.js +22 -0
- package/dist/lint/fix.js.map +1 -0
- package/dist/lint/precision.d.ts +51 -0
- package/dist/lint/precision.d.ts.map +1 -0
- package/dist/lint/precision.js +64 -0
- package/dist/lint/precision.js.map +1 -0
- package/dist/lint/rules/bsdd.d.ts +5 -0
- package/dist/lint/rules/bsdd.d.ts.map +1 -0
- package/dist/lint/rules/bsdd.js +123 -0
- package/dist/lint/rules/bsdd.js.map +1 -0
- package/dist/lint/rules/card.d.ts +10 -0
- package/dist/lint/rules/card.d.ts.map +1 -0
- package/dist/lint/rules/card.js +140 -0
- package/dist/lint/rules/card.js.map +1 -0
- package/dist/lint/rules/doc-ver-part.d.ts +7 -0
- package/dist/lint/rules/doc-ver-part.d.ts.map +1 -0
- package/dist/lint/rules/doc-ver-part.js +155 -0
- package/dist/lint/rules/doc-ver-part.js.map +1 -0
- package/dist/lint/rules/entity.d.ts +12 -0
- package/dist/lint/rules/entity.d.ts.map +1 -0
- package/dist/lint/rules/entity.js +215 -0
- package/dist/lint/rules/entity.js.map +1 -0
- package/dist/lint/rules/index.d.ts +4 -0
- package/dist/lint/rules/index.d.ts.map +1 -0
- package/dist/lint/rules/index.js +63 -0
- package/dist/lint/rules/index.js.map +1 -0
- package/dist/lint/rules/pdt-att.d.ts +7 -0
- package/dist/lint/rules/pdt-att.d.ts.map +1 -0
- package/dist/lint/rules/pdt-att.js +209 -0
- package/dist/lint/rules/pdt-att.js.map +1 -0
- package/dist/lint/rules/pset.d.ts +12 -0
- package/dist/lint/rules/pset.d.ts.map +1 -0
- package/dist/lint/rules/pset.js +263 -0
- package/dist/lint/rules/pset.js.map +1 -0
- package/dist/lint/rules/regex.d.ts +6 -0
- package/dist/lint/rules/regex.d.ts.map +1 -0
- package/dist/lint/rules/regex.js +184 -0
- package/dist/lint/rules/regex.js.map +1 -0
- package/dist/lint/rules/spec-doc.d.ts +5 -0
- package/dist/lint/rules/spec-doc.d.ts.map +1 -0
- package/dist/lint/rules/spec-doc.js +132 -0
- package/dist/lint/rules/spec-doc.js.map +1 -0
- package/dist/lint/rules/spec.d.ts +24 -0
- package/dist/lint/rules/spec.d.ts.map +1 -0
- package/dist/lint/rules/spec.js +162 -0
- package/dist/lint/rules/spec.js.map +1 -0
- package/dist/lint/rules/units.d.ts +4 -0
- package/dist/lint/rules/units.d.ts.map +1 -0
- package/dist/lint/rules/units.js +101 -0
- package/dist/lint/rules/units.js.map +1 -0
- package/dist/lint/rules/util.d.ts +37 -0
- package/dist/lint/rules/util.d.ts.map +1 -0
- package/dist/lint/rules/util.js +117 -0
- package/dist/lint/rules/util.js.map +1 -0
- package/dist/lint/rules/value-sites.d.ts +28 -0
- package/dist/lint/rules/value-sites.d.ts.map +1 -0
- package/dist/lint/rules/value-sites.js +81 -0
- package/dist/lint/rules/value-sites.js.map +1 -0
- package/dist/lint/rules/values.d.ts +22 -0
- package/dist/lint/rules/values.d.ts.map +1 -0
- package/dist/lint/rules/values.js +237 -0
- package/dist/lint/rules/values.js.map +1 -0
- package/dist/lint/rules/xsd-regex.d.ts +34 -0
- package/dist/lint/rules/xsd-regex.d.ts.map +1 -0
- package/dist/lint/rules/xsd-regex.js +149 -0
- package/dist/lint/rules/xsd-regex.js.map +1 -0
- package/dist/lint/solver/sample.d.ts +3 -0
- package/dist/lint/solver/sample.d.ts.map +1 -0
- package/dist/lint/solver/sample.js +134 -0
- package/dist/lint/solver/sample.js.map +1 -0
- package/dist/lint/solver/solver.d.ts +39 -0
- package/dist/lint/solver/solver.d.ts.map +1 -0
- package/dist/lint/solver/solver.js +126 -0
- package/dist/lint/solver/solver.js.map +1 -0
- package/dist/lint/suppress.d.ts +12 -0
- package/dist/lint/suppress.d.ts.map +1 -0
- package/dist/lint/suppress.js +56 -0
- package/dist/lint/suppress.js.map +1 -0
- package/dist/lint/types.d.ts +162 -0
- package/dist/lint/types.d.ts.map +1 -0
- package/dist/lint/types.js +5 -0
- package/dist/lint/types.js.map +1 -0
- package/dist/lint/walk.d.ts +20 -0
- package/dist/lint/walk.d.ts.map +1 -0
- package/dist/lint/walk.js +47 -0
- package/dist/lint/walk.js.map +1 -0
- package/dist/match/cascade.d.ts +53 -0
- package/dist/match/cascade.d.ts.map +1 -0
- package/dist/match/cascade.js +135 -0
- package/dist/match/cascade.js.map +1 -0
- package/dist/match/reidentify.d.ts +46 -0
- package/dist/match/reidentify.d.ts.map +1 -0
- package/dist/match/reidentify.js +67 -0
- package/dist/match/reidentify.js.map +1 -0
- package/dist/merge/comments.d.ts +13 -0
- package/dist/merge/comments.d.ts.map +1 -0
- package/dist/merge/comments.js +61 -0
- package/dist/merge/comments.js.map +1 -0
- package/dist/merge/index.d.ts +4 -0
- package/dist/merge/index.d.ts.map +1 -0
- package/dist/merge/index.js +6 -0
- package/dist/merge/index.js.map +1 -0
- package/dist/merge/keys.d.ts +22 -0
- package/dist/merge/keys.d.ts.map +1 -0
- package/dist/merge/keys.js +54 -0
- package/dist/merge/keys.js.map +1 -0
- package/dist/merge/merge.d.ts +8 -0
- package/dist/merge/merge.d.ts.map +1 -0
- package/dist/merge/merge.js +206 -0
- package/dist/merge/merge.js.map +1 -0
- package/dist/merge/order.d.ts +11 -0
- package/dist/merge/order.d.ts.map +1 -0
- package/dist/merge/order.js +117 -0
- package/dist/merge/order.js.map +1 -0
- package/dist/merge/sidecar.d.ts +12 -0
- package/dist/merge/sidecar.d.ts.map +1 -0
- package/dist/merge/sidecar.js +64 -0
- package/dist/merge/sidecar.js.map +1 -0
- package/dist/merge/types.d.ts +50 -0
- package/dist/merge/types.d.ts.map +1 -0
- package/dist/merge/types.js +5 -0
- package/dist/merge/types.js.map +1 -0
- package/dist/merge/view.d.ts +28 -0
- package/dist/merge/view.d.ts.map +1 -0
- package/dist/merge/view.js +35 -0
- package/dist/merge/view.js.map +1 -0
- package/dist/ops/draft.d.ts +33 -0
- package/dist/ops/draft.d.ts.map +1 -0
- package/dist/ops/draft.js +253 -0
- package/dist/ops/draft.js.map +1 -0
- package/dist/ops/json-schema-lite.d.ts +41 -0
- package/dist/ops/json-schema-lite.d.ts.map +1 -0
- package/dist/ops/json-schema-lite.js +119 -0
- package/dist/ops/json-schema-lite.js.map +1 -0
- package/dist/ops/schema-values.d.ts +5 -0
- package/dist/ops/schema-values.d.ts.map +1 -0
- package/dist/ops/schema-values.js +233 -0
- package/dist/ops/schema-values.js.map +1 -0
- package/dist/ops/schema.d.ts +27 -0
- package/dist/ops/schema.d.ts.map +1 -0
- package/dist/ops/schema.js +258 -0
- package/dist/ops/schema.js.map +1 -0
- package/dist/ops/sidecar-ops.d.ts +85 -0
- package/dist/ops/sidecar-ops.d.ts.map +1 -0
- package/dist/ops/sidecar-ops.js +5 -0
- package/dist/ops/sidecar-ops.js.map +1 -0
- package/dist/ops/types.d.ts +400 -0
- package/dist/ops/types.d.ts.map +1 -0
- package/dist/ops/types.js +5 -0
- package/dist/ops/types.js.map +1 -0
- package/dist/ops/units.d.ts +4 -0
- package/dist/ops/units.d.ts.map +1 -0
- package/dist/ops/units.js +75 -0
- package/dist/ops/units.js.map +1 -0
- package/dist/reducer/apply.d.ts +33 -0
- package/dist/reducer/apply.d.ts.map +1 -0
- package/dist/reducer/apply.js +123 -0
- package/dist/reducer/apply.js.map +1 -0
- package/dist/reducer/comment-ops.d.ts +18 -0
- package/dist/reducer/comment-ops.d.ts.map +1 -0
- package/dist/reducer/comment-ops.js +104 -0
- package/dist/reducer/comment-ops.js.map +1 -0
- package/dist/reducer/edit.d.ts +38 -0
- package/dist/reducer/edit.d.ts.map +1 -0
- package/dist/reducer/edit.js +126 -0
- package/dist/reducer/edit.js.map +1 -0
- package/dist/reducer/facet-ops.d.ts +20 -0
- package/dist/reducer/facet-ops.d.ts.map +1 -0
- package/dist/reducer/facet-ops.js +184 -0
- package/dist/reducer/facet-ops.js.map +1 -0
- package/dist/reducer/meta-ops.d.ts +20 -0
- package/dist/reducer/meta-ops.d.ts.map +1 -0
- package/dist/reducer/meta-ops.js +52 -0
- package/dist/reducer/meta-ops.js.map +1 -0
- package/dist/reducer/spec-ops.d.ts +29 -0
- package/dist/reducer/spec-ops.d.ts.map +1 -0
- package/dist/reducer/spec-ops.js +181 -0
- package/dist/reducer/spec-ops.js.map +1 -0
- package/dist/reducer/test-ops.d.ts +15 -0
- package/dist/reducer/test-ops.d.ts.map +1 -0
- package/dist/reducer/test-ops.js +90 -0
- package/dist/reducer/test-ops.js.map +1 -0
- package/dist/reducer/value-ops.d.ts +26 -0
- package/dist/reducer/value-ops.d.ts.map +1 -0
- package/dist/reducer/value-ops.js +173 -0
- package/dist/reducer/value-ops.js.map +1 -0
- package/dist/render/describe.d.ts +20 -0
- package/dist/render/describe.d.ts.map +1 -0
- package/dist/render/describe.js +47 -0
- package/dist/render/describe.js.map +1 -0
- package/dist/revision/index.d.ts +4 -0
- package/dist/revision/index.d.ts.map +1 -0
- package/dist/revision/index.js +7 -0
- package/dist/revision/index.js.map +1 -0
- package/dist/revision/revision.d.ts +79 -0
- package/dist/revision/revision.d.ts.map +1 -0
- package/dist/revision/revision.js +120 -0
- package/dist/revision/revision.js.map +1 -0
- package/dist/revision/sha256.d.ts +3 -0
- package/dist/revision/sha256.d.ts.map +1 -0
- package/dist/revision/sha256.js +69 -0
- package/dist/revision/sha256.js.map +1 -0
- package/dist/revision/verify.d.ts +21 -0
- package/dist/revision/verify.d.ts.map +1 -0
- package/dist/revision/verify.js +51 -0
- package/dist/revision/verify.js.map +1 -0
- package/dist/revision/view.d.ts +36 -0
- package/dist/revision/view.d.ts.map +1 -0
- package/dist/revision/view.js +32 -0
- package/dist/revision/view.js.map +1 -0
- package/dist/sidecar/idsz.d.ts +14 -0
- package/dist/sidecar/idsz.d.ts.map +1 -0
- package/dist/sidecar/idsz.js +58 -0
- package/dist/sidecar/idsz.js.map +1 -0
- package/dist/sidecar/sidecar-schema.d.ts +4 -0
- package/dist/sidecar/sidecar-schema.d.ts.map +1 -0
- package/dist/sidecar/sidecar-schema.js +69 -0
- package/dist/sidecar/sidecar-schema.js.map +1 -0
- package/dist/sidecar/sidecar.d.ts +102 -0
- package/dist/sidecar/sidecar.d.ts.map +1 -0
- package/dist/sidecar/sidecar.js +160 -0
- package/dist/sidecar/sidecar.js.map +1 -0
- package/dist/testing/index.d.ts +6 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +8 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/junit.d.ts +10 -0
- package/dist/testing/junit.d.ts.map +1 -0
- package/dist/testing/junit.js +51 -0
- package/dist/testing/junit.js.map +1 -0
- package/dist/testing/outcome.d.ts +10 -0
- package/dist/testing/outcome.d.ts.map +1 -0
- package/dist/testing/outcome.js +22 -0
- package/dist/testing/outcome.js.map +1 -0
- package/dist/testing/runner.d.ts +72 -0
- package/dist/testing/runner.d.ts.map +1 -0
- package/dist/testing/runner.js +60 -0
- package/dist/testing/runner.js.map +1 -0
- package/dist/testing/types.d.ts +60 -0
- package/dist/testing/types.d.ts.map +1 -0
- package/dist/testing/types.js +5 -0
- package/dist/testing/types.js.map +1 -0
- package/dist/testing/view.d.ts +31 -0
- package/dist/testing/view.d.ts.map +1 -0
- package/dist/testing/view.js +30 -0
- package/dist/testing/view.js.map +1 -0
- package/dist/uuid.d.ts +39 -0
- package/dist/uuid.d.ts.map +1 -0
- package/dist/uuid.js +84 -0
- package/dist/uuid.js.map +1 -0
- package/package.json +56 -3
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
export { expectationMismatch, runTestSuites, selectCases, } from './runner.js';
|
|
5
|
+
export { outcomeFromSpecResult } from './outcome.js';
|
|
6
|
+
export { junitXml } from './junit.js';
|
|
7
|
+
export { testSuitesView } from './view.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAG/D,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,WAAW,GAQZ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,cAAc,EAA4D,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JUnit XML for a test run (`ifc-lite ids test --junit`), the format CI
|
|
3
|
+
* systems read: one `<testsuite>` per specification, one `<testcase>` per
|
|
4
|
+
* case, with `<failure>`, `<error>` or `<skipped>`.
|
|
5
|
+
*/
|
|
6
|
+
import type { TestRunReport } from './runner.js';
|
|
7
|
+
export declare function junitXml(report: TestRunReport, options?: {
|
|
8
|
+
name?: string;
|
|
9
|
+
}): string;
|
|
10
|
+
//# sourceMappingURL=junit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"junit.d.ts","sourceRoot":"","sources":["../../src/testing/junit.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AAEH,OAAO,KAAK,EAAc,aAAa,EAAE,MAAM,aAAa,CAAC;AAmC7D,wBAAgB,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,CAoBvF"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
/** Code points XML 1.0 cannot carry at all (C0 controls except tab/LF/CR, U+FFFE, U+FFFF). */
|
|
5
|
+
function xmlChar(c) {
|
|
6
|
+
const n = c.charCodeAt(0);
|
|
7
|
+
return (n >= 0x20 || n === 0x09 || n === 0x0a || n === 0x0d) && n !== 0xfffe && n !== 0xffff;
|
|
8
|
+
}
|
|
9
|
+
function esc(s) {
|
|
10
|
+
return [...s]
|
|
11
|
+
.filter(xmlChar)
|
|
12
|
+
.join('')
|
|
13
|
+
.replace(/&/g, '&')
|
|
14
|
+
.replace(/</g, '<')
|
|
15
|
+
.replace(/>/g, '>')
|
|
16
|
+
.replace(/"/g, '"');
|
|
17
|
+
}
|
|
18
|
+
const seconds = (ms) => (ms / 1000).toFixed(3);
|
|
19
|
+
function testcase(r) {
|
|
20
|
+
const open = ` <testcase classname="${esc(r.specName)}" name="${esc(r.name)}" time="${seconds(r.durationMs)}"`;
|
|
21
|
+
const message = esc(r.message ?? '');
|
|
22
|
+
switch (r.verdict) {
|
|
23
|
+
case 'passed':
|
|
24
|
+
return `${open}/>`;
|
|
25
|
+
case 'failed':
|
|
26
|
+
return `${open}>\n <failure message="${message}" type="expectation">${message}</failure>\n </testcase>`;
|
|
27
|
+
case 'error':
|
|
28
|
+
return `${open}>\n <error message="${message}"/>\n </testcase>`;
|
|
29
|
+
case 'skipped':
|
|
30
|
+
return `${open}>\n <skipped message="${message}"/>\n </testcase>`;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export function junitXml(report, options = {}) {
|
|
34
|
+
const bySpec = new Map();
|
|
35
|
+
for (const r of report.results)
|
|
36
|
+
bySpec.set(r.specId, [...(bySpec.get(r.specId) ?? []), r]);
|
|
37
|
+
const time = report.results.reduce((t, r) => t + r.durationMs, 0);
|
|
38
|
+
const s = report.summary;
|
|
39
|
+
const lines = [
|
|
40
|
+
'<?xml version="1.0" encoding="UTF-8"?>',
|
|
41
|
+
`<testsuites name="${esc(options.name ?? 'IDS tests')}" tests="${s.total}" failures="${s.failed}" errors="${s.error}" skipped="${s.skipped}" time="${seconds(time)}">`,
|
|
42
|
+
];
|
|
43
|
+
for (const results of bySpec.values()) {
|
|
44
|
+
const n = (v) => results.filter((r) => r.verdict === v).length;
|
|
45
|
+
const t = results.reduce((x, r) => x + r.durationMs, 0);
|
|
46
|
+
lines.push(` <testsuite name="${esc(results[0].specName)}" tests="${results.length}" failures="${n('failed')}" errors="${n('error')}" skipped="${n('skipped')}" time="${seconds(t)}">`, ...results.map(testcase), ' </testsuite>');
|
|
47
|
+
}
|
|
48
|
+
lines.push('</testsuites>', '');
|
|
49
|
+
return lines.join('\n');
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=junit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"junit.js","sourceRoot":"","sources":["../../src/testing/junit.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAU/D,8FAA8F;AAC9F,SAAS,OAAO,CAAC,CAAS;IACxB,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAC1B,OAAO,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,MAAM,CAAC;AAC/F,CAAC;AAED,SAAS,GAAG,CAAC,CAAS;IACpB,OAAO,CAAC,GAAG,CAAC,CAAC;SACV,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,EAAE,CAAC;SACR,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,OAAO,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAEvD,SAAS,QAAQ,CAAC,CAAa;IAC7B,MAAM,IAAI,GAAG,4BAA4B,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;IAClH,MAAM,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IACrC,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC;QAClB,KAAK,QAAQ;YACX,OAAO,GAAG,IAAI,IAAI,CAAC;QACrB,KAAK,QAAQ;YACX,OAAO,GAAG,IAAI,8BAA8B,OAAO,wBAAwB,OAAO,6BAA6B,CAAC;QAClH,KAAK,OAAO;YACV,OAAO,GAAG,IAAI,4BAA4B,OAAO,sBAAsB,CAAC;QAC1E,KAAK,SAAS;YACZ,OAAO,GAAG,IAAI,8BAA8B,OAAO,sBAAsB,CAAC;IAC9E,CAAC;AACH,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,MAAqB,EAAE,UAA6B,EAAE;IAC7E,MAAM,MAAM,GAAG,IAAI,GAAG,EAAwB,CAAC;IAC/C,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO;QAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3F,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IAClE,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC;IACzB,MAAM,KAAK,GAAG;QACZ,wCAAwC;QACxC,qBAAqB,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC,YAAY,CAAC,CAAC,KAAK,eAAe,CAAC,CAAC,MAAM,aAAa,CAAC,CAAC,KAAK,cAAc,CAAC,CAAC,OAAO,WAAW,OAAO,CAAC,IAAI,CAAC,IAAI;KACvK,CAAC;IACF,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,CAAwB,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;QACtF,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;QACxD,KAAK,CAAC,IAAI,CACR,sBAAsB,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,OAAO,CAAC,MAAM,eAAe,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,SAAS,CAAC,WAAW,OAAO,CAAC,CAAC,CAAC,IAAI,EAC5K,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EACxB,gBAAgB,CACjB,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IAChC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Map a validator result onto the runner's outcome. */
|
|
2
|
+
import type { IDSSpecificationResult } from '@ifc-lite/ids';
|
|
3
|
+
import type { SpecOutcome } from './runner.js';
|
|
4
|
+
/**
|
|
5
|
+
* The outcome of one specification result of `validateIDS`. Requirement
|
|
6
|
+
* ids are the Studio node ids when the validated document came from a
|
|
7
|
+
* `StudioDocument` (its requirement `id`s are node ids).
|
|
8
|
+
*/
|
|
9
|
+
export declare function outcomeFromSpecResult(result: IDSSpecificationResult): SpecOutcome;
|
|
10
|
+
//# sourceMappingURL=outcome.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outcome.d.ts","sourceRoot":"","sources":["../../src/testing/outcome.ts"],"names":[],"mappings":"AAIA,wDAAwD;AAExD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,sBAAsB,GAAG,WAAW,CAUjF"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
/**
|
|
5
|
+
* The outcome of one specification result of `validateIDS`. Requirement
|
|
6
|
+
* ids are the Studio node ids when the validated document came from a
|
|
7
|
+
* `StudioDocument` (its requirement `id`s are node ids).
|
|
8
|
+
*/
|
|
9
|
+
export function outcomeFromSpecResult(result) {
|
|
10
|
+
const failed = new Set();
|
|
11
|
+
for (const entity of result.entityResults) {
|
|
12
|
+
for (const r of entity.requirementResults)
|
|
13
|
+
if (r.status === 'fail')
|
|
14
|
+
failed.add(r.requirement.id);
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
status: result.status === 'not_applicable' ? 'notApplicable' : result.status,
|
|
18
|
+
failedRequirements: [...failed],
|
|
19
|
+
applicableCount: result.applicableCount,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=outcome.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outcome.js","sourceRoot":"","sources":["../../src/testing/outcome.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAO/D;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAA8B;IAClE,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;QAC1C,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,kBAAkB;YAAE,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM;gBAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IACnG,CAAC;IACD,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,MAAM,KAAK,gBAAgB,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM;QAC5E,kBAAkB,EAAE,CAAC,GAAG,MAAM,CAAC;QAC/B,eAAe,EAAE,MAAM,CAAC,eAAe;KACxC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The IDS test runner (headless). It owns the bookkeeping: which cases
|
|
3
|
+
* to run, comparing each outcome with its expectation, and the report.
|
|
4
|
+
* Turning a fixture into a verdict is the host's `evaluate` callback:
|
|
5
|
+
* `@ifc-lite/ids-testgen` provides one that builds or loads the IFC and
|
|
6
|
+
* runs `@ifc-lite/ids`' validator; the viewer can pass its worker.
|
|
7
|
+
*
|
|
8
|
+
* A case passes when the specification reports the expected status
|
|
9
|
+
* and, for `fail` cases with `expectFailureOn`, exactly those
|
|
10
|
+
* requirement facets fail.
|
|
11
|
+
*/
|
|
12
|
+
import type { IDSSpecification } from '@ifc-lite/ids';
|
|
13
|
+
import type { StudioDocument } from '../document/types.js';
|
|
14
|
+
import type { Uuid } from '../uuid.js';
|
|
15
|
+
import type { TestCase, TestExpectation } from './types.js';
|
|
16
|
+
/** What the specification reported on a fixture. */
|
|
17
|
+
export interface SpecOutcome {
|
|
18
|
+
status: TestExpectation;
|
|
19
|
+
/** Requirement node ids that failed on at least one applicable element. */
|
|
20
|
+
failedRequirements: Uuid[];
|
|
21
|
+
applicableCount: number;
|
|
22
|
+
}
|
|
23
|
+
export type EvaluateResult = SpecOutcome | {
|
|
24
|
+
unsupported: string;
|
|
25
|
+
} | {
|
|
26
|
+
error: string;
|
|
27
|
+
};
|
|
28
|
+
export type CaseEvaluator = (input: {
|
|
29
|
+
doc: StudioDocument;
|
|
30
|
+
spec: IDSSpecification;
|
|
31
|
+
testCase: TestCase;
|
|
32
|
+
}) => Promise<EvaluateResult>;
|
|
33
|
+
export type CaseVerdict = 'passed' | 'failed' | 'error' | 'skipped';
|
|
34
|
+
export interface CaseResult {
|
|
35
|
+
specId: Uuid;
|
|
36
|
+
specName: string;
|
|
37
|
+
testId: Uuid;
|
|
38
|
+
name: string;
|
|
39
|
+
expect: TestExpectation;
|
|
40
|
+
verdict: CaseVerdict;
|
|
41
|
+
outcome?: SpecOutcome;
|
|
42
|
+
/** Why it failed, errored or was skipped. */
|
|
43
|
+
message?: string;
|
|
44
|
+
durationMs: number;
|
|
45
|
+
}
|
|
46
|
+
export interface TestRunReport {
|
|
47
|
+
results: CaseResult[];
|
|
48
|
+
summary: {
|
|
49
|
+
total: number;
|
|
50
|
+
passed: number;
|
|
51
|
+
failed: number;
|
|
52
|
+
error: number;
|
|
53
|
+
skipped: number;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export interface RunOptions {
|
|
57
|
+
/** Only these specifications (default: all with a suite). */
|
|
58
|
+
specIds?: readonly Uuid[];
|
|
59
|
+
/** Called after each case (progress UI). */
|
|
60
|
+
onCase?: (result: CaseResult, index: number, total: number) => void;
|
|
61
|
+
/** Clock for durations (tests pass a fake). */
|
|
62
|
+
now?: () => number;
|
|
63
|
+
}
|
|
64
|
+
/** Compare an outcome with a case's expectation; `undefined` means it holds. */
|
|
65
|
+
export declare function expectationMismatch(testCase: TestCase, outcome: SpecOutcome): string | undefined;
|
|
66
|
+
/** Every case of the selected suites, in document order. */
|
|
67
|
+
export declare function selectCases(doc: StudioDocument, specIds?: readonly Uuid[]): {
|
|
68
|
+
spec: IDSSpecification;
|
|
69
|
+
testCase: TestCase;
|
|
70
|
+
}[];
|
|
71
|
+
export declare function runTestSuites(doc: StudioDocument, evaluate: CaseEvaluator, options?: RunOptions): Promise<TestRunReport>;
|
|
72
|
+
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/testing/runner.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE5D,oDAAoD;AACpD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,eAAe,CAAC;IACxB,2EAA2E;IAC3E,kBAAkB,EAAE,IAAI,EAAE,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvF,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE;IAAE,GAAG,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;AAEpI,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;AAEpE,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,IAAI,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,IAAI,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5F;AAED,MAAM,WAAW,UAAU;IACzB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,SAAS,IAAI,EAAE,CAAC;IAC1B,4CAA4C;IAC5C,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACpE,+CAA+C;IAC/C,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,gFAAgF;AAChF,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAUhG;AAED,4DAA4D;AAC5D,wBAAgB,WAAW,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,SAAS,IAAI,EAAE,GAAG;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,EAAE,CAQ5H;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,GAAE,UAAe,GAAG,OAAO,CAAC,aAAa,CAAC,CA2BlI"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
/** Compare an outcome with a case's expectation; `undefined` means it holds. */
|
|
5
|
+
export function expectationMismatch(testCase, outcome) {
|
|
6
|
+
if (outcome.status !== testCase.expect) {
|
|
7
|
+
return `expected ${testCase.expect}, the specification reported ${outcome.status} (${outcome.applicableCount} applicable)`;
|
|
8
|
+
}
|
|
9
|
+
if (testCase.expect === 'fail' && testCase.expectFailureOn?.length) {
|
|
10
|
+
const want = [...testCase.expectFailureOn].sort();
|
|
11
|
+
const got = [...new Set(outcome.failedRequirements)].sort();
|
|
12
|
+
if (want.join() !== got.join())
|
|
13
|
+
return `expected failures on [${want.join(', ')}], got [${got.join(', ')}]`;
|
|
14
|
+
}
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
/** Every case of the selected suites, in document order. */
|
|
18
|
+
export function selectCases(doc, specIds) {
|
|
19
|
+
const wanted = specIds ? new Set(specIds) : undefined;
|
|
20
|
+
const out = [];
|
|
21
|
+
for (const spec of doc.ids.specifications) {
|
|
22
|
+
if (wanted && !wanted.has(spec.id))
|
|
23
|
+
continue;
|
|
24
|
+
for (const testCase of doc.meta.tests[spec.id]?.cases ?? [])
|
|
25
|
+
out.push({ spec, testCase });
|
|
26
|
+
}
|
|
27
|
+
return out;
|
|
28
|
+
}
|
|
29
|
+
export async function runTestSuites(doc, evaluate, options = {}) {
|
|
30
|
+
const now = options.now ?? (() => Date.now());
|
|
31
|
+
const cases = selectCases(doc, options.specIds);
|
|
32
|
+
const results = [];
|
|
33
|
+
for (const [i, { spec, testCase }] of cases.entries()) {
|
|
34
|
+
const start = now();
|
|
35
|
+
const base = { specId: spec.id, specName: spec.name, testId: testCase.id, name: testCase.name, expect: testCase.expect };
|
|
36
|
+
let result;
|
|
37
|
+
try {
|
|
38
|
+
const r = await evaluate({ doc, spec, testCase });
|
|
39
|
+
if ('unsupported' in r)
|
|
40
|
+
result = { ...base, verdict: 'skipped', message: r.unsupported, durationMs: now() - start };
|
|
41
|
+
else if ('error' in r)
|
|
42
|
+
result = { ...base, verdict: 'error', message: r.error, durationMs: now() - start };
|
|
43
|
+
else {
|
|
44
|
+
const mismatch = expectationMismatch(testCase, r);
|
|
45
|
+
result = { ...base, verdict: mismatch ? 'failed' : 'passed', outcome: r, ...(mismatch ? { message: mismatch } : {}), durationMs: now() - start };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
result = { ...base, verdict: 'error', message: err instanceof Error ? err.message : String(err), durationMs: now() - start };
|
|
50
|
+
}
|
|
51
|
+
results.push(result);
|
|
52
|
+
options.onCase?.(result, i, cases.length);
|
|
53
|
+
}
|
|
54
|
+
const count = (v) => results.filter((r) => r.verdict === v).length;
|
|
55
|
+
return {
|
|
56
|
+
results,
|
|
57
|
+
summary: { total: results.length, passed: count('passed'), failed: count('failed'), error: count('error'), skipped: count('skipped') },
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/testing/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IDS test suites (07-interop-versioning-collab.md §5, ADR-013): "unit
|
|
3
|
+
* tests for information requirements". A specification carries test
|
|
4
|
+
* cases, each an IFC fixture plus the verdict the specification must give
|
|
5
|
+
* on it. Suites live in the sidecar (`meta.tests[specId]`) and change only
|
|
6
|
+
* through `meta.test.*` ops.
|
|
7
|
+
*/
|
|
8
|
+
import type { IFCVersion } from '@ifc-lite/ids';
|
|
9
|
+
import type { Uuid } from '../uuid.js';
|
|
10
|
+
/** What a specification must report on a fixture. */
|
|
11
|
+
export type TestExpectation = 'pass' | 'fail' | 'notApplicable';
|
|
12
|
+
/**
|
|
13
|
+
* How a synthetic fixture is (re)generated from the specification
|
|
14
|
+
* (`@ifc-lite/ids-testgen`). The fixture follows the specification: when
|
|
15
|
+
* the specification changes, so does the regenerated fixture.
|
|
16
|
+
*/
|
|
17
|
+
export interface FixtureRecipe {
|
|
18
|
+
generator: 'ids-testgen/1';
|
|
19
|
+
ifcVersion: IFCVersion;
|
|
20
|
+
variant: {
|
|
21
|
+
kind: 'pass';
|
|
22
|
+
}
|
|
23
|
+
/** Violates exactly this requirement facet. */
|
|
24
|
+
| {
|
|
25
|
+
kind: 'fail';
|
|
26
|
+
requirementId: Uuid;
|
|
27
|
+
}
|
|
28
|
+
/** Violates the first applicability facet. */
|
|
29
|
+
| {
|
|
30
|
+
kind: 'notApplicable';
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export type TestFixture = {
|
|
34
|
+
kind: 'synthetic';
|
|
35
|
+
recipe: FixtureRecipe;
|
|
36
|
+
}
|
|
37
|
+
/** Extracted from a real model ("pin element as test"); `ifcRef` names the stored subset. */
|
|
38
|
+
| {
|
|
39
|
+
kind: 'snapshot';
|
|
40
|
+
ifcRef: string;
|
|
41
|
+
entityRefs: string[];
|
|
42
|
+
}
|
|
43
|
+
/** Any IFC file, e.g. `fixtures/door-ok.ifc` inside an `.idsz` bundle. */
|
|
44
|
+
| {
|
|
45
|
+
kind: 'file';
|
|
46
|
+
path: string;
|
|
47
|
+
};
|
|
48
|
+
export interface TestCase {
|
|
49
|
+
id: Uuid;
|
|
50
|
+
name: string;
|
|
51
|
+
fixture: TestFixture;
|
|
52
|
+
expect: TestExpectation;
|
|
53
|
+
/** For `fail`: the requirement facets that must fail (exactly these). */
|
|
54
|
+
expectFailureOn?: Uuid[];
|
|
55
|
+
}
|
|
56
|
+
export interface TestSuite {
|
|
57
|
+
specId: Uuid;
|
|
58
|
+
cases: TestCase[];
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/testing/types.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,qDAAqD;AACrD,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,eAAe,CAAC;AAEhE;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,eAAe,CAAC;IAC3B,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,EACH;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE;IAClB,+CAA+C;OAC7C;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,IAAI,CAAA;KAAE;IACvC,8CAA8C;OAC5C;QAAE,IAAI,EAAE,eAAe,CAAA;KAAE,CAAC;CAC/B;AAED,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE;AAC9C,6FAA6F;GAC3F;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE;AAC5D,0EAA0E;GACxE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnC,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,IAAI,CAAC;IACT,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE,eAAe,CAAC;IACxB,yEAAyE;IACzE,eAAe,CAAC,EAAE,IAAI,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,IAAI,CAAC;IACb,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/testing/types.ts"],"names":[],"mappings":"AAAA;;+DAE+D"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework-free view model of the test suites ("Run tests" panel): one
|
|
3
|
+
* row per specification with its cases and, after a run, their verdicts.
|
|
4
|
+
*/
|
|
5
|
+
import type { StudioDocument } from '../document/types.js';
|
|
6
|
+
import type { Uuid } from '../uuid.js';
|
|
7
|
+
import type { CaseVerdict, TestRunReport } from './runner.js';
|
|
8
|
+
import type { TestExpectation, TestFixture } from './types.js';
|
|
9
|
+
export interface TestCaseRow {
|
|
10
|
+
testId: Uuid;
|
|
11
|
+
name: string;
|
|
12
|
+
expect: TestExpectation;
|
|
13
|
+
fixture: TestFixture['kind'];
|
|
14
|
+
verdict?: CaseVerdict;
|
|
15
|
+
message?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface TestSuiteRow {
|
|
18
|
+
specId: Uuid;
|
|
19
|
+
specName: string;
|
|
20
|
+
/** `untested`: no suite; `notRun`: suite, no result yet. */
|
|
21
|
+
status: 'untested' | 'notRun' | 'passing' | 'failing';
|
|
22
|
+
cases: TestCaseRow[];
|
|
23
|
+
}
|
|
24
|
+
export interface TestSuitesView {
|
|
25
|
+
rows: TestSuiteRow[];
|
|
26
|
+
/** Specifications with at least one case. */
|
|
27
|
+
covered: number;
|
|
28
|
+
total: number;
|
|
29
|
+
}
|
|
30
|
+
export declare function testSuitesView(doc: StudioDocument, report?: TestRunReport): TestSuitesView;
|
|
31
|
+
//# sourceMappingURL=view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../src/testing/view.ts"],"names":[],"mappings":"AAIA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE/D,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,IAAI,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,IAAI,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,4DAA4D;IAC5D,MAAM,EAAE,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;IACtD,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,cAAc,CAyB1F"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
export function testSuitesView(doc, report) {
|
|
5
|
+
const results = new Map((report?.results ?? []).map((r) => [r.testId, r]));
|
|
6
|
+
const rows = doc.ids.specifications.map((spec) => {
|
|
7
|
+
const cases = (doc.meta.tests[spec.id]?.cases ?? []).map((c) => {
|
|
8
|
+
const r = results.get(c.id);
|
|
9
|
+
return {
|
|
10
|
+
testId: c.id,
|
|
11
|
+
name: c.name,
|
|
12
|
+
expect: c.expect,
|
|
13
|
+
fixture: c.fixture.kind,
|
|
14
|
+
...(r ? { verdict: r.verdict } : {}),
|
|
15
|
+
...(r?.message ? { message: r.message } : {}),
|
|
16
|
+
};
|
|
17
|
+
});
|
|
18
|
+
const ran = cases.filter((c) => c.verdict);
|
|
19
|
+
const status = !cases.length
|
|
20
|
+
? 'untested'
|
|
21
|
+
: !ran.length
|
|
22
|
+
? 'notRun'
|
|
23
|
+
: ran.some((c) => c.verdict === 'failed' || c.verdict === 'error')
|
|
24
|
+
? 'failing'
|
|
25
|
+
: 'passing';
|
|
26
|
+
return { specId: spec.id, specName: spec.name, status, cases };
|
|
27
|
+
});
|
|
28
|
+
return { rows, covered: rows.filter((r) => r.cases.length).length, total: rows.length };
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view.js","sourceRoot":"","sources":["../../src/testing/view.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAoC/D,MAAM,UAAU,cAAc,CAAC,GAAmB,EAAE,MAAsB;IACxE,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3E,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,IAAI,EAAgB,EAAE;QAC7D,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAe,EAAE;YAC1E,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC5B,OAAO;gBACL,MAAM,EAAE,CAAC,CAAC,EAAE;gBACZ,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI;gBACvB,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACpC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC9C,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC3C,MAAM,MAAM,GAA2B,CAAC,KAAK,CAAC,MAAM;YAClD,CAAC,CAAC,UAAU;YACZ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM;gBACX,CAAC,CAAC,QAAQ;gBACV,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC;oBAChE,CAAC,CAAC,SAAS;oBACX,CAAC,CAAC,SAAS,CAAC;QAClB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IACjE,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;AAC1F,CAAC"}
|
package/dist/uuid.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node identity for Studio documents.
|
|
3
|
+
*
|
|
4
|
+
* - `uuidv7()` mints a fresh, time-ordered RFC 9562 version-7 UUID. It is the
|
|
5
|
+
* only impure id source in the package and is called by hosts (UI, agent,
|
|
6
|
+
* import) when they build ops; the reducer never calls it.
|
|
7
|
+
* - `deriveId(seed, salt)` is the pure counterpart the reducer uses when an
|
|
8
|
+
* op needs ids it was not handed (e.g. the facets a `spec.duplicate`
|
|
9
|
+
* creates): a deterministic name-based UUID (version 8, RFC 9562 §5.8)
|
|
10
|
+
* from an FNV-1a hash of `seed` and `salt`. The same op therefore always
|
|
11
|
+
* produces the same ids, which keeps `apply` a pure function and replays
|
|
12
|
+
* of a persisted op log byte-identical.
|
|
13
|
+
*/
|
|
14
|
+
/** A lower-case hyphenated UUID string. */
|
|
15
|
+
export type Uuid = string;
|
|
16
|
+
/** True for a lower-case hyphenated UUID of any version. */
|
|
17
|
+
export declare function isUuid(value: unknown): value is Uuid;
|
|
18
|
+
export interface UuidV7Source {
|
|
19
|
+
/** Milliseconds since the Unix epoch. Defaults to `Date.now()`. */
|
|
20
|
+
now?: () => number;
|
|
21
|
+
/** Fills `bytes` with random data. Defaults to `crypto.getRandomValues`. */
|
|
22
|
+
random?: (bytes: Uint8Array<ArrayBuffer>) => void;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Mint a UUIDv7. Ids minted within the same millisecond stay strictly
|
|
26
|
+
* increasing: the 12-bit `rand_a` field is used as a counter seeded from
|
|
27
|
+
* random data (RFC 9562 §6.2, method 1), and the timestamp is bumped when
|
|
28
|
+
* the counter overflows.
|
|
29
|
+
*/
|
|
30
|
+
export declare function uuidv7(source?: UuidV7Source): Uuid;
|
|
31
|
+
/** 64-bit FNV-1a over UTF-16 code units, starting from `basis`. */
|
|
32
|
+
export declare function fnv1a64(input: string, basis?: bigint): bigint;
|
|
33
|
+
/**
|
|
34
|
+
* Pure, deterministic UUIDv8 derived from `seed` and `salt`. Distinct
|
|
35
|
+
* `(seed, salt)` pairs give distinct ids with overwhelming probability
|
|
36
|
+
* (two 64-bit FNV-1a lanes with different offset bases).
|
|
37
|
+
*/
|
|
38
|
+
export declare function deriveId(seed: string, salt: string): Uuid;
|
|
39
|
+
//# sourceMappingURL=uuid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uuid.d.ts","sourceRoot":"","sources":["../src/uuid.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,2CAA2C;AAC3C,MAAM,MAAM,IAAI,GAAG,MAAM,CAAC;AAI1B,4DAA4D;AAC5D,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,IAAI,CAEpD;AAED,MAAM,WAAW,YAAY;IAC3B,mEAAmE;IACnE,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,4EAA4E;IAC5E,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;CACnD;AASD;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,MAAM,GAAE,YAAiB,GAAG,IAAI,CA2BtD;AAKD,mEAAmE;AACnE,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAA4B,GAAG,MAAM,CAOlF;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAYzD"}
|
package/dist/uuid.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
5
|
+
/** True for a lower-case hyphenated UUID of any version. */
|
|
6
|
+
export function isUuid(value) {
|
|
7
|
+
return typeof value === 'string' && UUID_RE.test(value);
|
|
8
|
+
}
|
|
9
|
+
function defaultRandom(bytes) {
|
|
10
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
11
|
+
}
|
|
12
|
+
let lastMs = -1;
|
|
13
|
+
let lastCounter = 0;
|
|
14
|
+
/**
|
|
15
|
+
* Mint a UUIDv7. Ids minted within the same millisecond stay strictly
|
|
16
|
+
* increasing: the 12-bit `rand_a` field is used as a counter seeded from
|
|
17
|
+
* random data (RFC 9562 §6.2, method 1), and the timestamp is bumped when
|
|
18
|
+
* the counter overflows.
|
|
19
|
+
*/
|
|
20
|
+
export function uuidv7(source = {}) {
|
|
21
|
+
const random = source.random ?? defaultRandom;
|
|
22
|
+
let ms = Math.floor((source.now ?? Date.now)());
|
|
23
|
+
const bytes = new Uint8Array(16);
|
|
24
|
+
random(bytes);
|
|
25
|
+
if (ms <= lastMs) {
|
|
26
|
+
ms = lastMs;
|
|
27
|
+
lastCounter += 1;
|
|
28
|
+
if (lastCounter > 0xfff) {
|
|
29
|
+
ms += 1;
|
|
30
|
+
lastCounter = ((bytes[6] & 0x07) << 8) | bytes[7];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
// Seed with the top bit clear so a burst has room to count upwards.
|
|
35
|
+
lastCounter = ((bytes[6] & 0x07) << 8) | bytes[7];
|
|
36
|
+
}
|
|
37
|
+
lastMs = ms;
|
|
38
|
+
// 48-bit big-endian timestamp.
|
|
39
|
+
let t = ms;
|
|
40
|
+
for (let i = 5; i >= 0; i--) {
|
|
41
|
+
bytes[i] = t % 256;
|
|
42
|
+
t = Math.floor(t / 256);
|
|
43
|
+
}
|
|
44
|
+
bytes[6] = 0x70 | ((lastCounter >> 8) & 0x0f);
|
|
45
|
+
bytes[7] = lastCounter & 0xff;
|
|
46
|
+
bytes[8] = 0x80 | (bytes[8] & 0x3f);
|
|
47
|
+
return format(bytes);
|
|
48
|
+
}
|
|
49
|
+
const FNV_PRIME = 0x100000001b3n;
|
|
50
|
+
const MASK_64 = 0xffffffffffffffffn;
|
|
51
|
+
/** 64-bit FNV-1a over UTF-16 code units, starting from `basis`. */
|
|
52
|
+
export function fnv1a64(input, basis = 0xcbf29ce484222325n) {
|
|
53
|
+
let h = basis;
|
|
54
|
+
for (let i = 0; i < input.length; i++) {
|
|
55
|
+
h ^= BigInt(input.charCodeAt(i));
|
|
56
|
+
h = (h * FNV_PRIME) & MASK_64;
|
|
57
|
+
}
|
|
58
|
+
return h;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Pure, deterministic UUIDv8 derived from `seed` and `salt`. Distinct
|
|
62
|
+
* `(seed, salt)` pairs give distinct ids with overwhelming probability
|
|
63
|
+
* (two 64-bit FNV-1a lanes with different offset bases).
|
|
64
|
+
*/
|
|
65
|
+
export function deriveId(seed, salt) {
|
|
66
|
+
const input = `${seed}\u0000${salt}`;
|
|
67
|
+
const hi = fnv1a64(input);
|
|
68
|
+
const lo = fnv1a64(input, 0x6c62272e07bb0142n);
|
|
69
|
+
const bytes = new Uint8Array(16);
|
|
70
|
+
for (let i = 0; i < 8; i++) {
|
|
71
|
+
bytes[i] = Number((hi >> BigInt(56 - i * 8)) & 0xffn);
|
|
72
|
+
bytes[8 + i] = Number((lo >> BigInt(56 - i * 8)) & 0xffn);
|
|
73
|
+
}
|
|
74
|
+
bytes[6] = 0x80 | (bytes[6] & 0x0f);
|
|
75
|
+
bytes[8] = 0x80 | (bytes[8] & 0x3f);
|
|
76
|
+
return format(bytes);
|
|
77
|
+
}
|
|
78
|
+
function format(bytes) {
|
|
79
|
+
let hex = '';
|
|
80
|
+
for (const b of bytes)
|
|
81
|
+
hex += b.toString(16).padStart(2, '0');
|
|
82
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=uuid.js.map
|
package/dist/uuid.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uuid.js","sourceRoot":"","sources":["../src/uuid.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,59 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ifc-lite/ids-authoring",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.2.2",
|
|
4
|
+
"description": "Headless IDS authoring core: Studio document with stable node ids, typed invertible operations, a grounding gate against the IFC schema tables, history, sidecar and re-identification",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"fflate": "^0.8.3",
|
|
18
|
+
"@ifc-lite/data": "6.2.0",
|
|
19
|
+
"@ifc-lite/ids": "3.3.2",
|
|
20
|
+
"@ifc-lite/regex-guard": "0.3.0"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/node": "^26.6.4",
|
|
24
|
+
"fake-indexeddb": "^6.2.5",
|
|
25
|
+
"typescript": "^6.0.3",
|
|
26
|
+
"vitest": "^5.0.3",
|
|
27
|
+
"@ifc-lite/parser": "9.5.0"
|
|
28
|
+
},
|
|
29
|
+
"license": "MPL-2.0",
|
|
30
|
+
"author": "Louis True",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/LTplus-AG/ifc-lite.git",
|
|
34
|
+
"directory": "packages/ids-authoring"
|
|
35
|
+
},
|
|
36
|
+
"homepage": "https://ifclite.dev/docs/",
|
|
37
|
+
"bugs": "https://github.com/LTplus-AG/ifc-lite/issues",
|
|
38
|
+
"keywords": [
|
|
39
|
+
"ifc",
|
|
40
|
+
"bim",
|
|
41
|
+
"ids",
|
|
42
|
+
"buildingsmart",
|
|
43
|
+
"authoring",
|
|
44
|
+
"information-delivery-specification"
|
|
45
|
+
],
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public"
|
|
48
|
+
},
|
|
49
|
+
"files": [
|
|
50
|
+
"dist",
|
|
51
|
+
"README.md"
|
|
52
|
+
],
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "pnpm exec tsc",
|
|
55
|
+
"typecheck": "node ../../scripts/typecheck-tests.mjs",
|
|
56
|
+
"dev": "pnpm exec tsc --watch",
|
|
57
|
+
"test": "vitest run"
|
|
58
|
+
}
|
|
6
59
|
}
|