@uncefact/untp-utils 0.1.0 → 0.3.0
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/README.md +52 -2
- package/artefacts/context/untp/0.6.0/dcc.json +1241 -0
- package/artefacts/context/untp/0.6.0/dfr.json +619 -0
- package/artefacts/context/untp/0.6.0/dia.json +162 -0
- package/artefacts/context/untp/0.6.0/dpp.json +1078 -0
- package/artefacts/context/untp/0.6.0/dte.json +1285 -0
- package/artefacts/context/untp/0.6.1/dcc.json +1388 -0
- package/artefacts/context/untp/0.6.1/dfr.json +690 -0
- package/artefacts/context/untp/0.6.1/dia.json +196 -0
- package/artefacts/context/untp/0.6.1/dpp.json +1164 -0
- package/artefacts/context/untp/0.6.1/dte.json +1340 -0
- package/artefacts/context/untp/0.7.0/untp.json +3493 -0
- package/artefacts/context/vcdm/2/credentials.json +301 -0
- package/artefacts/manifest.json +214 -0
- package/artefacts/schema/untp/0.6.0/dcc.json +1131 -0
- package/artefacts/schema/untp/0.6.0/dfr.json +1028 -0
- package/artefacts/schema/untp/0.6.0/dia.json +236 -0
- package/artefacts/schema/untp/0.6.0/dpp.json +1219 -0
- package/artefacts/schema/untp/0.6.0/dte.json +845 -0
- package/artefacts/schema/untp/0.6.1/dcc.json +1196 -0
- package/artefacts/schema/untp/0.6.1/dfr.json +1037 -0
- package/artefacts/schema/untp/0.6.1/dia.json +236 -0
- package/artefacts/schema/untp/0.6.1/dpp.json +1229 -0
- package/artefacts/schema/untp/0.6.1/dte.json +845 -0
- package/artefacts/schema/untp/0.7.0/cvc.json +701 -0
- package/artefacts/schema/untp/0.7.0/dcc.json +1133 -0
- package/artefacts/schema/untp/0.7.0/dfr.json +1245 -0
- package/artefacts/schema/untp/0.7.0/dia.json +443 -0
- package/artefacts/schema/untp/0.7.0/dpp.json +1300 -0
- package/artefacts/schema/untp/0.7.0/dte.json +1226 -0
- package/artefacts/schema/untp/0.7.0/linkset.json +119 -0
- package/artefacts/schema/vcdm/2/verifiable-credential.json +318 -0
- package/build/artefacts/detect-version-from-context.d.ts +46 -0
- package/build/artefacts/detect-version-from-context.js +77 -0
- package/build/artefacts/detect-version-from-context.js.map +1 -0
- package/build/artefacts/detect-version-from-context.test.d.ts +1 -0
- package/build/artefacts/detect-version-from-context.test.js +69 -0
- package/build/artefacts/detect-version-from-context.test.js.map +1 -0
- package/build/artefacts/index.d.ts +3 -0
- package/build/artefacts/index.js +4 -0
- package/build/artefacts/index.js.map +1 -0
- package/build/artefacts/urls.d.ts +85 -0
- package/build/artefacts/urls.js +141 -0
- package/build/artefacts/urls.js.map +1 -0
- package/build/artefacts/urls.test.d.ts +1 -0
- package/build/artefacts/urls.test.js +99 -0
- package/build/artefacts/urls.test.js.map +1 -0
- package/build/artefacts/version.d.ts +9 -0
- package/build/artefacts/version.js +17 -0
- package/build/artefacts/version.js.map +1 -0
- package/build/artefacts/version.test.d.ts +1 -0
- package/build/artefacts/version.test.js +16 -0
- package/build/artefacts/version.test.js.map +1 -0
- package/build/bundle/artefacts/context/untp/0.6.0/dcc.d.ts +2 -0
- package/build/bundle/artefacts/context/untp/0.6.0/dcc.js +1244 -0
- package/build/bundle/artefacts/context/untp/0.6.0/dcc.js.map +1 -0
- package/build/bundle/artefacts/context/untp/0.6.0/dfr.d.ts +2 -0
- package/build/bundle/artefacts/context/untp/0.6.0/dfr.js +622 -0
- package/build/bundle/artefacts/context/untp/0.6.0/dfr.js.map +1 -0
- package/build/bundle/artefacts/context/untp/0.6.0/dia.d.ts +2 -0
- package/build/bundle/artefacts/context/untp/0.6.0/dia.js +165 -0
- package/build/bundle/artefacts/context/untp/0.6.0/dia.js.map +1 -0
- package/build/bundle/artefacts/context/untp/0.6.0/dpp.d.ts +2 -0
- package/build/bundle/artefacts/context/untp/0.6.0/dpp.js +1081 -0
- package/build/bundle/artefacts/context/untp/0.6.0/dpp.js.map +1 -0
- package/build/bundle/artefacts/context/untp/0.6.0/dte.d.ts +2 -0
- package/build/bundle/artefacts/context/untp/0.6.0/dte.js +1288 -0
- package/build/bundle/artefacts/context/untp/0.6.0/dte.js.map +1 -0
- package/build/bundle/artefacts/context/untp/0.6.1/dcc.d.ts +2 -0
- package/build/bundle/artefacts/context/untp/0.6.1/dcc.js +1391 -0
- package/build/bundle/artefacts/context/untp/0.6.1/dcc.js.map +1 -0
- package/build/bundle/artefacts/context/untp/0.6.1/dfr.d.ts +2 -0
- package/build/bundle/artefacts/context/untp/0.6.1/dfr.js +693 -0
- package/build/bundle/artefacts/context/untp/0.6.1/dfr.js.map +1 -0
- package/build/bundle/artefacts/context/untp/0.6.1/dia.d.ts +2 -0
- package/build/bundle/artefacts/context/untp/0.6.1/dia.js +199 -0
- package/build/bundle/artefacts/context/untp/0.6.1/dia.js.map +1 -0
- package/build/bundle/artefacts/context/untp/0.6.1/dpp.d.ts +2 -0
- package/build/bundle/artefacts/context/untp/0.6.1/dpp.js +1167 -0
- package/build/bundle/artefacts/context/untp/0.6.1/dpp.js.map +1 -0
- package/build/bundle/artefacts/context/untp/0.6.1/dte.d.ts +2 -0
- package/build/bundle/artefacts/context/untp/0.6.1/dte.js +1343 -0
- package/build/bundle/artefacts/context/untp/0.6.1/dte.js.map +1 -0
- package/build/bundle/artefacts/context/untp/0.7.0/untp.d.ts +2 -0
- package/build/bundle/artefacts/context/untp/0.7.0/untp.js +3496 -0
- package/build/bundle/artefacts/context/untp/0.7.0/untp.js.map +1 -0
- package/build/bundle/artefacts/context/vcdm/2/credentials.d.ts +2 -0
- package/build/bundle/artefacts/context/vcdm/2/credentials.js +304 -0
- package/build/bundle/artefacts/context/vcdm/2/credentials.js.map +1 -0
- package/build/bundle/artefacts/schema/untp/0.6.0/dcc.d.ts +2 -0
- package/build/bundle/artefacts/schema/untp/0.6.0/dcc.js +1134 -0
- package/build/bundle/artefacts/schema/untp/0.6.0/dcc.js.map +1 -0
- package/build/bundle/artefacts/schema/untp/0.6.0/dfr.d.ts +2 -0
- package/build/bundle/artefacts/schema/untp/0.6.0/dfr.js +1031 -0
- package/build/bundle/artefacts/schema/untp/0.6.0/dfr.js.map +1 -0
- package/build/bundle/artefacts/schema/untp/0.6.0/dia.d.ts +2 -0
- package/build/bundle/artefacts/schema/untp/0.6.0/dia.js +239 -0
- package/build/bundle/artefacts/schema/untp/0.6.0/dia.js.map +1 -0
- package/build/bundle/artefacts/schema/untp/0.6.0/dpp.d.ts +2 -0
- package/build/bundle/artefacts/schema/untp/0.6.0/dpp.js +1222 -0
- package/build/bundle/artefacts/schema/untp/0.6.0/dpp.js.map +1 -0
- package/build/bundle/artefacts/schema/untp/0.6.0/dte.d.ts +2 -0
- package/build/bundle/artefacts/schema/untp/0.6.0/dte.js +848 -0
- package/build/bundle/artefacts/schema/untp/0.6.0/dte.js.map +1 -0
- package/build/bundle/artefacts/schema/untp/0.6.1/dcc.d.ts +2 -0
- package/build/bundle/artefacts/schema/untp/0.6.1/dcc.js +1199 -0
- package/build/bundle/artefacts/schema/untp/0.6.1/dcc.js.map +1 -0
- package/build/bundle/artefacts/schema/untp/0.6.1/dfr.d.ts +2 -0
- package/build/bundle/artefacts/schema/untp/0.6.1/dfr.js +1040 -0
- package/build/bundle/artefacts/schema/untp/0.6.1/dfr.js.map +1 -0
- package/build/bundle/artefacts/schema/untp/0.6.1/dia.d.ts +2 -0
- package/build/bundle/artefacts/schema/untp/0.6.1/dia.js +239 -0
- package/build/bundle/artefacts/schema/untp/0.6.1/dia.js.map +1 -0
- package/build/bundle/artefacts/schema/untp/0.6.1/dpp.d.ts +2 -0
- package/build/bundle/artefacts/schema/untp/0.6.1/dpp.js +1232 -0
- package/build/bundle/artefacts/schema/untp/0.6.1/dpp.js.map +1 -0
- package/build/bundle/artefacts/schema/untp/0.6.1/dte.d.ts +2 -0
- package/build/bundle/artefacts/schema/untp/0.6.1/dte.js +848 -0
- package/build/bundle/artefacts/schema/untp/0.6.1/dte.js.map +1 -0
- package/build/bundle/artefacts/schema/untp/0.7.0/cvc.d.ts +2 -0
- package/build/bundle/artefacts/schema/untp/0.7.0/cvc.js +704 -0
- package/build/bundle/artefacts/schema/untp/0.7.0/cvc.js.map +1 -0
- package/build/bundle/artefacts/schema/untp/0.7.0/dcc.d.ts +2 -0
- package/build/bundle/artefacts/schema/untp/0.7.0/dcc.js +1136 -0
- package/build/bundle/artefacts/schema/untp/0.7.0/dcc.js.map +1 -0
- package/build/bundle/artefacts/schema/untp/0.7.0/dfr.d.ts +2 -0
- package/build/bundle/artefacts/schema/untp/0.7.0/dfr.js +1248 -0
- package/build/bundle/artefacts/schema/untp/0.7.0/dfr.js.map +1 -0
- package/build/bundle/artefacts/schema/untp/0.7.0/dia.d.ts +2 -0
- package/build/bundle/artefacts/schema/untp/0.7.0/dia.js +446 -0
- package/build/bundle/artefacts/schema/untp/0.7.0/dia.js.map +1 -0
- package/build/bundle/artefacts/schema/untp/0.7.0/dpp.d.ts +2 -0
- package/build/bundle/artefacts/schema/untp/0.7.0/dpp.js +1303 -0
- package/build/bundle/artefacts/schema/untp/0.7.0/dpp.js.map +1 -0
- package/build/bundle/artefacts/schema/untp/0.7.0/dte.d.ts +2 -0
- package/build/bundle/artefacts/schema/untp/0.7.0/dte.js +1229 -0
- package/build/bundle/artefacts/schema/untp/0.7.0/dte.js.map +1 -0
- package/build/bundle/artefacts/schema/untp/0.7.0/linkset.d.ts +2 -0
- package/build/bundle/artefacts/schema/untp/0.7.0/linkset.js +122 -0
- package/build/bundle/artefacts/schema/untp/0.7.0/linkset.js.map +1 -0
- package/build/bundle/artefacts/schema/vcdm/2/verifiable-credential.d.ts +2 -0
- package/build/bundle/artefacts/schema/vcdm/2/verifiable-credential.js +321 -0
- package/build/bundle/artefacts/schema/vcdm/2/verifiable-credential.js.map +1 -0
- package/build/bundle/fallback.d.ts +41 -0
- package/build/bundle/fallback.js +62 -0
- package/build/bundle/fallback.js.map +1 -0
- package/build/bundle/fallback.test.d.ts +1 -0
- package/build/bundle/fallback.test.js +124 -0
- package/build/bundle/fallback.test.js.map +1 -0
- package/build/bundle/index.d.ts +4 -0
- package/build/bundle/index.js +77 -0
- package/build/bundle/index.js.map +1 -0
- package/build/bundle/lookup.d.ts +14 -0
- package/build/bundle/lookup.js +40 -0
- package/build/bundle/lookup.js.map +1 -0
- package/build/bundle/lookup.test.d.ts +1 -0
- package/build/bundle/lookup.test.js +70 -0
- package/build/bundle/lookup.test.js.map +1 -0
- package/build/bundle/public.d.ts +25 -0
- package/build/bundle/public.js +56 -0
- package/build/bundle/public.js.map +1 -0
- package/build/bundle/public.test.d.ts +1 -0
- package/build/bundle/public.test.js +35 -0
- package/build/bundle/public.test.js.map +1 -0
- package/build/bundle/refresh-classify.test.d.ts +1 -0
- package/build/bundle/refresh-classify.test.js +20 -0
- package/build/bundle/refresh-classify.test.js.map +1 -0
- package/build/bundle/refresh-main.test.d.ts +1 -0
- package/build/bundle/refresh-main.test.js +98 -0
- package/build/bundle/refresh-main.test.js.map +1 -0
- package/build/cache/in-memory-ttl-cache.d.ts +2 -0
- package/build/cache/in-memory-ttl-cache.js +76 -0
- package/build/cache/in-memory-ttl-cache.js.map +1 -0
- package/build/cache/in-memory-ttl-cache.test.d.ts +1 -0
- package/build/cache/in-memory-ttl-cache.test.js +236 -0
- package/build/cache/in-memory-ttl-cache.test.js.map +1 -0
- package/build/cache/index.d.ts +2 -0
- package/build/cache/index.js +2 -0
- package/build/cache/index.js.map +1 -0
- package/build/cache/ttl-cache.d.ts +22 -0
- package/build/cache/ttl-cache.js +2 -0
- package/build/cache/ttl-cache.js.map +1 -0
- package/build/common/as-date-time.d.ts +13 -0
- package/build/common/as-date-time.js +44 -0
- package/build/common/as-date-time.js.map +1 -0
- package/build/common/as-date-time.test.d.ts +1 -0
- package/build/common/as-date-time.test.js +42 -0
- package/build/common/as-date-time.test.js.map +1 -0
- package/build/common/as-non-empty-string.d.ts +14 -0
- package/build/common/as-non-empty-string.js +20 -0
- package/build/common/as-non-empty-string.js.map +1 -0
- package/build/common/as-non-empty-string.test.d.ts +1 -0
- package/build/common/as-non-empty-string.test.js +30 -0
- package/build/common/as-non-empty-string.test.js.map +1 -0
- package/build/common/index.d.ts +4 -0
- package/build/common/index.js +5 -0
- package/build/common/index.js.map +1 -0
- package/build/common/require-string.d.ts +12 -0
- package/build/common/require-string.js +27 -0
- package/build/common/require-string.js.map +1 -0
- package/build/common/require-string.test.d.ts +1 -0
- package/build/common/require-string.test.js +53 -0
- package/build/common/require-string.test.js.map +1 -0
- package/build/common/validity-window.d.ts +45 -0
- package/build/common/validity-window.js +68 -0
- package/build/common/validity-window.js.map +1 -0
- package/build/common/validity-window.test.d.ts +1 -0
- package/build/common/validity-window.test.js +67 -0
- package/build/common/validity-window.test.js.map +1 -0
- package/build/conformity-vocabulary/codes.d.ts +10 -0
- package/build/conformity-vocabulary/codes.js +10 -0
- package/build/conformity-vocabulary/codes.js.map +1 -0
- package/build/conformity-vocabulary/errors.d.ts +44 -0
- package/build/conformity-vocabulary/errors.js +68 -0
- package/build/conformity-vocabulary/errors.js.map +1 -0
- package/build/conformity-vocabulary/index.d.ts +6 -0
- package/build/conformity-vocabulary/index.js +7 -0
- package/build/conformity-vocabulary/index.js.map +1 -0
- package/build/conformity-vocabulary/parse-conformity-catalogue.d.ts +26 -0
- package/build/conformity-vocabulary/parse-conformity-catalogue.js +106 -0
- package/build/conformity-vocabulary/parse-conformity-catalogue.js.map +1 -0
- package/build/conformity-vocabulary/parse-conformity-catalogue.test.d.ts +1 -0
- package/build/conformity-vocabulary/parse-conformity-catalogue.test.js +327 -0
- package/build/conformity-vocabulary/parse-conformity-catalogue.test.js.map +1 -0
- package/build/conformity-vocabulary/parse-conformity-scheme.d.ts +28 -0
- package/build/conformity-vocabulary/parse-conformity-scheme.js +47 -0
- package/build/conformity-vocabulary/parse-conformity-scheme.js.map +1 -0
- package/build/conformity-vocabulary/parse-conformity-scheme.test.d.ts +1 -0
- package/build/conformity-vocabulary/parse-conformity-scheme.test.js +284 -0
- package/build/conformity-vocabulary/parse-conformity-scheme.test.js.map +1 -0
- package/build/conformity-vocabulary/parsers/v0-7-0.parser.d.ts +19 -0
- package/build/conformity-vocabulary/parsers/v0-7-0.parser.js +219 -0
- package/build/conformity-vocabulary/parsers/v0-7-0.parser.js.map +1 -0
- package/build/conformity-vocabulary/types.d.ts +180 -0
- package/build/conformity-vocabulary/types.js +2 -0
- package/build/conformity-vocabulary/types.js.map +1 -0
- package/build/conformity-vocabulary/validate-conformity-claim.d.ts +26 -0
- package/build/conformity-vocabulary/validate-conformity-claim.js +165 -0
- package/build/conformity-vocabulary/validate-conformity-claim.js.map +1 -0
- package/build/conformity-vocabulary/validate-conformity-claim.test.d.ts +1 -0
- package/build/conformity-vocabulary/validate-conformity-claim.test.js +478 -0
- package/build/conformity-vocabulary/validate-conformity-claim.test.js.map +1 -0
- package/build/http-headers/index.d.ts +5 -0
- package/build/http-headers/index.js +6 -0
- package/build/http-headers/index.js.map +1 -0
- package/build/http-headers/is-safe-header-value.d.ts +10 -0
- package/build/http-headers/is-safe-header-value.js +15 -0
- package/build/http-headers/is-safe-header-value.js.map +1 -0
- package/build/http-headers/is-safe-header-value.test.d.ts +1 -0
- package/build/http-headers/is-safe-header-value.test.js +37 -0
- package/build/http-headers/is-safe-header-value.test.js.map +1 -0
- package/build/http-headers/parse-entity-tag.d.ts +9 -0
- package/build/http-headers/parse-entity-tag.js +18 -0
- package/build/http-headers/parse-entity-tag.js.map +1 -0
- package/build/http-headers/parse-entity-tag.test.d.ts +1 -0
- package/build/http-headers/parse-entity-tag.test.js +41 -0
- package/build/http-headers/parse-entity-tag.test.js.map +1 -0
- package/build/http-headers/parse-imf-date.d.ts +13 -0
- package/build/http-headers/parse-imf-date.js +23 -0
- package/build/http-headers/parse-imf-date.js.map +1 -0
- package/build/http-headers/parse-imf-date.test.d.ts +1 -0
- package/build/http-headers/parse-imf-date.test.js +31 -0
- package/build/http-headers/parse-imf-date.test.js.map +1 -0
- package/build/http-headers/parse-media-type.d.ts +8 -0
- package/build/http-headers/parse-media-type.js +21 -0
- package/build/http-headers/parse-media-type.js.map +1 -0
- package/build/http-headers/parse-media-type.test.d.ts +1 -0
- package/build/http-headers/parse-media-type.test.js +39 -0
- package/build/http-headers/parse-media-type.test.js.map +1 -0
- package/build/http-headers/user-agent.d.ts +35 -0
- package/build/http-headers/user-agent.js +45 -0
- package/build/http-headers/user-agent.js.map +1 -0
- package/build/http-headers/user-agent.test.d.ts +1 -0
- package/build/http-headers/user-agent.test.js +27 -0
- package/build/http-headers/user-agent.test.js.map +1 -0
- package/build/index.d.ts +1 -1
- package/build/index.js +1 -1
- package/build/index.js.map +1 -1
- package/build/loaders/errors.d.ts +21 -0
- package/build/loaders/errors.js +45 -0
- package/build/loaders/errors.js.map +1 -0
- package/build/loaders/index.d.ts +5 -0
- package/build/loaders/index.js +5 -0
- package/build/loaders/index.js.map +1 -0
- package/build/loaders/jsonld-document-loader.d.ts +48 -0
- package/build/loaders/jsonld-document-loader.js +43 -0
- package/build/loaders/jsonld-document-loader.js.map +1 -0
- package/build/loaders/jsonld-document-loader.test.d.ts +1 -0
- package/build/loaders/jsonld-document-loader.test.js +111 -0
- package/build/loaders/jsonld-document-loader.test.js.map +1 -0
- package/build/loaders/schema-loader.d.ts +31 -0
- package/build/loaders/schema-loader.js +83 -0
- package/build/loaders/schema-loader.js.map +1 -0
- package/build/loaders/schema-loader.ssrf.test.d.ts +1 -0
- package/build/loaders/schema-loader.ssrf.test.js +55 -0
- package/build/loaders/schema-loader.ssrf.test.js.map +1 -0
- package/build/loaders/schema-loader.test.d.ts +1 -0
- package/build/loaders/schema-loader.test.js +217 -0
- package/build/loaders/schema-loader.test.js.map +1 -0
- package/build/multibase-digest/multibase-digest.d.ts +23 -0
- package/build/multibase-digest/multibase-digest.js +40 -0
- package/build/multibase-digest/multibase-digest.js.map +1 -1
- package/build/multibase-digest/multibase-digest.test.js +46 -0
- package/build/multibase-digest/multibase-digest.test.js.map +1 -1
- package/build/node/errors.d.ts +47 -0
- package/build/node/errors.js +86 -0
- package/build/node/errors.js.map +1 -0
- package/build/node/index.d.ts +3 -0
- package/build/node/index.js +4 -0
- package/build/node/index.js.map +1 -0
- package/build/node/is-private-ip.d.ts +45 -0
- package/build/node/is-private-ip.fail-closed.test.d.ts +1 -0
- package/build/node/is-private-ip.fail-closed.test.js +36 -0
- package/build/node/is-private-ip.fail-closed.test.js.map +1 -0
- package/build/node/is-private-ip.js +203 -0
- package/build/node/is-private-ip.js.map +1 -0
- package/build/node/is-private-ip.test.d.ts +1 -0
- package/build/node/is-private-ip.test.js +124 -0
- package/build/node/is-private-ip.test.js.map +1 -0
- package/build/node/validate-public-url.d.ts +81 -0
- package/build/node/validate-public-url.js +128 -0
- package/build/node/validate-public-url.js.map +1 -0
- package/build/node/validate-public-url.test.d.ts +1 -0
- package/build/node/validate-public-url.test.js +324 -0
- package/build/node/validate-public-url.test.js.map +1 -0
- package/build/resolvers/errors.d.ts +73 -0
- package/build/resolvers/errors.js +133 -0
- package/build/resolvers/errors.js.map +1 -0
- package/build/resolvers/index.d.ts +5 -0
- package/build/resolvers/index.js +6 -0
- package/build/resolvers/index.js.map +1 -0
- package/build/resolvers/resolve-document-if-changed.d.ts +48 -0
- package/build/resolvers/resolve-document-if-changed.js +42 -0
- package/build/resolvers/resolve-document-if-changed.js.map +1 -0
- package/build/resolvers/resolve-document-if-changed.test.d.ts +1 -0
- package/build/resolvers/resolve-document-if-changed.test.js +116 -0
- package/build/resolvers/resolve-document-if-changed.test.js.map +1 -0
- package/build/resolvers/resolve-document.d.ts +106 -0
- package/build/resolvers/resolve-document.integration.test.d.ts +1 -0
- package/build/resolvers/resolve-document.integration.test.js +108 -0
- package/build/resolvers/resolve-document.integration.test.js.map +1 -0
- package/build/resolvers/resolve-document.js +319 -0
- package/build/resolvers/resolve-document.js.map +1 -0
- package/build/resolvers/resolve-document.test.d.ts +1 -0
- package/build/resolvers/resolve-document.test.js +749 -0
- package/build/resolvers/resolve-document.test.js.map +1 -0
- package/build/resolvers/resolve-json-document.d.ts +43 -0
- package/build/resolvers/resolve-json-document.js +43 -0
- package/build/resolvers/resolve-json-document.js.map +1 -0
- package/build/resolvers/resolve-json-document.test.d.ts +1 -0
- package/build/resolvers/resolve-json-document.test.js +78 -0
- package/build/resolvers/resolve-json-document.test.js.map +1 -0
- package/build/structured-error.d.ts +49 -0
- package/build/structured-error.js +17 -0
- package/build/structured-error.js.map +1 -0
- package/build/structured-error.test.d.ts +1 -0
- package/build/structured-error.test.js +112 -0
- package/build/structured-error.test.js.map +1 -0
- package/build/validation/describe-jsonld-failure.d.ts +90 -0
- package/build/validation/describe-jsonld-failure.js +171 -0
- package/build/validation/describe-jsonld-failure.js.map +1 -0
- package/build/validation/describe-jsonld-failure.test.d.ts +1 -0
- package/build/validation/describe-jsonld-failure.test.js +226 -0
- package/build/validation/describe-jsonld-failure.test.js.map +1 -0
- package/build/validation/errors.d.ts +40 -0
- package/build/validation/errors.js +75 -0
- package/build/validation/errors.js.map +1 -0
- package/build/validation/index.d.ts +5 -0
- package/build/validation/index.js +5 -0
- package/build/validation/index.js.map +1 -0
- package/build/validation/validate-against-schemas.d.ts +22 -0
- package/build/validation/validate-against-schemas.js +65 -0
- package/build/validation/validate-against-schemas.js.map +1 -0
- package/build/validation/validate-against-schemas.test.d.ts +1 -0
- package/build/validation/validate-against-schemas.test.js +169 -0
- package/build/validation/validate-against-schemas.test.js.map +1 -0
- package/build/validation/validate-jsonld.context-cache.test.d.ts +1 -0
- package/build/validation/validate-jsonld.context-cache.test.js +32 -0
- package/build/validation/validate-jsonld.context-cache.test.js.map +1 -0
- package/build/validation/validate-jsonld.d.ts +59 -0
- package/build/validation/validate-jsonld.js +126 -0
- package/build/validation/validate-jsonld.js.map +1 -0
- package/build/validation/validate-jsonld.ssrf.test.d.ts +1 -0
- package/build/validation/validate-jsonld.ssrf.test.js +108 -0
- package/build/validation/validate-jsonld.ssrf.test.js.map +1 -0
- package/build/validation/validate-jsonld.test.d.ts +1 -0
- package/build/validation/validate-jsonld.test.js +257 -0
- package/build/validation/validate-jsonld.test.js.map +1 -0
- package/package.json +86 -5
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// Drives the refresh script's main() against a temporary copy of the bundle
|
|
2
|
+
// with fetch stubbed, so the refusal, repair and dry-run paths are proven
|
|
3
|
+
// without the network. The script is loaded by runtime URL (tsc's rootDir is
|
|
4
|
+
// `src`); UNTP_ARTEFACTS_ROOT points it at the temporary tree.
|
|
5
|
+
import { jest } from '@jest/globals';
|
|
6
|
+
import { cp, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
|
|
7
|
+
import { tmpdir } from 'node:os';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
const scriptUrl = new URL('../../scripts/refresh-artefacts.mjs', import.meta.url).href;
|
|
10
|
+
const packageRoot = new URL('../../', import.meta.url).pathname;
|
|
11
|
+
describe('refresh-artefacts main', () => {
|
|
12
|
+
let root;
|
|
13
|
+
let script;
|
|
14
|
+
let exit;
|
|
15
|
+
let stubbed;
|
|
16
|
+
let fetchImpl;
|
|
17
|
+
const run = (argv) => script.main(argv, { fetchImpl });
|
|
18
|
+
beforeAll(async () => {
|
|
19
|
+
// The script resolves its root when it loads, so the temporary root is
|
|
20
|
+
// fixed before the import and refilled from the real bundle per test.
|
|
21
|
+
root = await mkdtemp(join(tmpdir(), 'untp-artefacts-'));
|
|
22
|
+
process.env.UNTP_ARTEFACTS_ROOT = root;
|
|
23
|
+
script = (await import(scriptUrl));
|
|
24
|
+
});
|
|
25
|
+
afterAll(async () => {
|
|
26
|
+
delete process.env.UNTP_ARTEFACTS_ROOT;
|
|
27
|
+
await rm(root, { recursive: true, force: true });
|
|
28
|
+
});
|
|
29
|
+
beforeEach(async () => {
|
|
30
|
+
await rm(join(root, 'artefacts'), { recursive: true, force: true });
|
|
31
|
+
await rm(join(root, 'src'), { recursive: true, force: true });
|
|
32
|
+
await cp(join(packageRoot, 'artefacts'), join(root, 'artefacts'), { recursive: true });
|
|
33
|
+
await cp(join(packageRoot, 'src', 'bundle'), join(root, 'src', 'bundle'), { recursive: true });
|
|
34
|
+
// Serve every source from the bundled copy on disk, so "published" equals "bundled".
|
|
35
|
+
stubbed = new Map();
|
|
36
|
+
for (const { file, source } of script.ARTEFACTS) {
|
|
37
|
+
stubbed.set(source, await readFile(join(packageRoot, 'artefacts', file), 'utf8'));
|
|
38
|
+
}
|
|
39
|
+
fetchImpl = (async (url) => {
|
|
40
|
+
const body = stubbed.get(String(url));
|
|
41
|
+
return body === undefined
|
|
42
|
+
? new Response('missing', { status: 404 })
|
|
43
|
+
: new Response(body, { status: 200, headers: { 'content-type': 'application/json' } });
|
|
44
|
+
});
|
|
45
|
+
exit = jest.spyOn(process, 'exit').mockImplementation(((code) => {
|
|
46
|
+
throw new Error(`exit ${code}`);
|
|
47
|
+
}));
|
|
48
|
+
jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
49
|
+
jest.spyOn(console, 'error').mockImplementation(() => { });
|
|
50
|
+
});
|
|
51
|
+
afterEach(() => {
|
|
52
|
+
jest.restoreAllMocks();
|
|
53
|
+
});
|
|
54
|
+
const corruptFile = 'context/untp/0.6.0/dia.json';
|
|
55
|
+
it('--check passes on a matching tree and writes nothing', async () => {
|
|
56
|
+
const before = await readFile(join(root, 'artefacts', 'manifest.json'), 'utf8');
|
|
57
|
+
await run(['--check']);
|
|
58
|
+
expect(exit).not.toHaveBeenCalled();
|
|
59
|
+
expect(await readFile(join(root, 'artefacts', 'manifest.json'), 'utf8')).toBe(before);
|
|
60
|
+
});
|
|
61
|
+
it('--check refuses a corrupt bundled copy, naming it, and writes nothing', async () => {
|
|
62
|
+
await writeFile(join(root, 'artefacts', corruptFile), '{not json');
|
|
63
|
+
await expect(run(['--check'])).rejects.toThrow('exit 1');
|
|
64
|
+
expect(await readFile(join(root, 'artefacts', corruptFile), 'utf8')).toBe('{not json');
|
|
65
|
+
});
|
|
66
|
+
it('a plain refresh also refuses a corrupt copy rather than hashing it', async () => {
|
|
67
|
+
await writeFile(join(root, 'artefacts', corruptFile), '{not json');
|
|
68
|
+
await expect(run([])).rejects.toThrow('exit 1');
|
|
69
|
+
expect(await readFile(join(root, 'artefacts', corruptFile), 'utf8')).toBe('{not json');
|
|
70
|
+
});
|
|
71
|
+
it('--force repairs a corrupt copy from the published source', async () => {
|
|
72
|
+
await writeFile(join(root, 'artefacts', corruptFile), '{not json');
|
|
73
|
+
await run(['--force']);
|
|
74
|
+
expect(exit).not.toHaveBeenCalled();
|
|
75
|
+
expect(JSON.parse(await readFile(join(root, 'artefacts', corruptFile), 'utf8'))).toHaveProperty('@context');
|
|
76
|
+
});
|
|
77
|
+
it('refuses a published copy that differs unless forced', async () => {
|
|
78
|
+
const entry = script.ARTEFACTS.find((a) => a.file === corruptFile);
|
|
79
|
+
stubbed.set(entry.source, JSON.stringify({ '@context': { changed: true } }));
|
|
80
|
+
await expect(run(['--check'])).rejects.toThrow('exit 1');
|
|
81
|
+
await expect(run([])).rejects.toThrow('exit 1');
|
|
82
|
+
await run(['--force']);
|
|
83
|
+
expect(JSON.parse(await readFile(join(root, 'artefacts', corruptFile), 'utf8'))).toEqual({
|
|
84
|
+
'@context': { changed: true },
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
it('writes nothing when a later fetch fails', async () => {
|
|
88
|
+
const entry = script.ARTEFACTS[script.ARTEFACTS.length - 1];
|
|
89
|
+
stubbed.delete(entry.source);
|
|
90
|
+
await writeFile(join(root, 'artefacts', corruptFile), '{not json');
|
|
91
|
+
await expect(run(['--force'])).rejects.toThrow(/answered 404/);
|
|
92
|
+
expect(await readFile(join(root, 'artefacts', corruptFile), 'utf8')).toBe('{not json');
|
|
93
|
+
});
|
|
94
|
+
it('rejects --check together with --force', async () => {
|
|
95
|
+
await expect(run(['--check', '--force'])).rejects.toThrow('exit 1');
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
//# sourceMappingURL=refresh-main.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refresh-main.test.js","sourceRoot":"","sources":["../../src/bundle/refresh-main.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export function createInMemoryTtlCache(options) {
|
|
2
|
+
const { ttlMs, maxEntries } = options;
|
|
3
|
+
if (!Number.isFinite(ttlMs) || ttlMs < 0) {
|
|
4
|
+
throw new RangeError(`ttlMs must be a non-negative finite number, got ${ttlMs}.`);
|
|
5
|
+
}
|
|
6
|
+
if (maxEntries !== undefined && (!Number.isInteger(maxEntries) || maxEntries < 1)) {
|
|
7
|
+
throw new RangeError(`maxEntries must be a positive integer when supplied, got ${maxEntries}.`);
|
|
8
|
+
}
|
|
9
|
+
const cache = new Map();
|
|
10
|
+
const inflight = new Map();
|
|
11
|
+
const isFresh = (storedAt) => Date.now() - storedAt < ttlMs;
|
|
12
|
+
// Retention bound: expired entries go first (they are dead weight whatever
|
|
13
|
+
// the cap), then the least recently used live entry. Recency comes from
|
|
14
|
+
// Map insertion order: hits re-insert their key (see get), so iteration
|
|
15
|
+
// order is oldest-touched first.
|
|
16
|
+
const evictForCapacity = () => {
|
|
17
|
+
if (maxEntries === undefined || cache.size < maxEntries)
|
|
18
|
+
return;
|
|
19
|
+
for (const [key, entry] of cache) {
|
|
20
|
+
if (!isFresh(entry.storedAt))
|
|
21
|
+
cache.delete(key);
|
|
22
|
+
}
|
|
23
|
+
while (cache.size >= maxEntries) {
|
|
24
|
+
const oldest = cache.keys().next().value;
|
|
25
|
+
cache.delete(oldest);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
return {
|
|
29
|
+
async get(key, fetcher) {
|
|
30
|
+
if (ttlMs > 0) {
|
|
31
|
+
const cached = cache.get(key);
|
|
32
|
+
if (cached) {
|
|
33
|
+
if (isFresh(cached.storedAt)) {
|
|
34
|
+
// Re-insert so Map iteration order tracks recency for eviction.
|
|
35
|
+
cache.delete(key);
|
|
36
|
+
cache.set(key, cached);
|
|
37
|
+
return cached.value;
|
|
38
|
+
}
|
|
39
|
+
// Expired entries are removed when met rather than lingering until
|
|
40
|
+
// the same key happens to be rewritten.
|
|
41
|
+
cache.delete(key);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const existing = inflight.get(key);
|
|
45
|
+
if (existing)
|
|
46
|
+
return existing;
|
|
47
|
+
let promise;
|
|
48
|
+
promise = (async () => {
|
|
49
|
+
try {
|
|
50
|
+
const value = await fetcher();
|
|
51
|
+
if (ttlMs > 0 && inflight.get(key) === promise) {
|
|
52
|
+
evictForCapacity();
|
|
53
|
+
cache.set(key, { value, storedAt: Date.now() });
|
|
54
|
+
}
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
57
|
+
finally {
|
|
58
|
+
if (inflight.get(key) === promise) {
|
|
59
|
+
inflight.delete(key);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
})();
|
|
63
|
+
inflight.set(key, promise);
|
|
64
|
+
return promise;
|
|
65
|
+
},
|
|
66
|
+
async invalidate(key) {
|
|
67
|
+
cache.delete(key);
|
|
68
|
+
inflight.delete(key);
|
|
69
|
+
},
|
|
70
|
+
async clear() {
|
|
71
|
+
cache.clear();
|
|
72
|
+
inflight.clear();
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=in-memory-ttl-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory-ttl-cache.js","sourceRoot":"","sources":["../../src/cache/in-memory-ttl-cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { jest } from '@jest/globals';
|
|
2
|
+
import { createInMemoryTtlCache } from './in-memory-ttl-cache.js';
|
|
3
|
+
describe('createInMemoryTtlCache', () => {
|
|
4
|
+
describe('hit / miss', () => {
|
|
5
|
+
it('returns the fetcher result on a miss', async () => {
|
|
6
|
+
const cache = createInMemoryTtlCache({ ttlMs: 1000 });
|
|
7
|
+
await expect(cache.get('a', async () => 'fetched')).resolves.toBe('fetched');
|
|
8
|
+
});
|
|
9
|
+
it('returns the cached value on a subsequent hit within the TTL', async () => {
|
|
10
|
+
const cache = createInMemoryTtlCache({ ttlMs: 1000 });
|
|
11
|
+
const fetcher = jest.fn(async () => 'fetched');
|
|
12
|
+
await cache.get('a', fetcher);
|
|
13
|
+
await cache.get('a', fetcher);
|
|
14
|
+
expect(fetcher).toHaveBeenCalledTimes(1);
|
|
15
|
+
});
|
|
16
|
+
it('refetches after the TTL expires', async () => {
|
|
17
|
+
const realNow = Date.now;
|
|
18
|
+
let now = 1000;
|
|
19
|
+
jest.spyOn(Date, 'now').mockImplementation(() => now);
|
|
20
|
+
try {
|
|
21
|
+
const cache = createInMemoryTtlCache({ ttlMs: 100 });
|
|
22
|
+
const fetcher = jest.fn(async () => 'v');
|
|
23
|
+
await cache.get('a', fetcher);
|
|
24
|
+
now += 101;
|
|
25
|
+
await cache.get('a', fetcher);
|
|
26
|
+
expect(fetcher).toHaveBeenCalledTimes(2);
|
|
27
|
+
}
|
|
28
|
+
finally {
|
|
29
|
+
Date.now = realNow;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
it('treats the TTL boundary strictly: ttlMs - 1 ms is a hit, ttlMs ms is a miss', async () => {
|
|
33
|
+
const realNow = Date.now;
|
|
34
|
+
let now = 1000;
|
|
35
|
+
jest.spyOn(Date, 'now').mockImplementation(() => now);
|
|
36
|
+
try {
|
|
37
|
+
const cache = createInMemoryTtlCache({ ttlMs: 100 });
|
|
38
|
+
const fetcher = jest.fn(async () => 'v');
|
|
39
|
+
await cache.get('a', fetcher);
|
|
40
|
+
now += 99;
|
|
41
|
+
await cache.get('a', fetcher);
|
|
42
|
+
expect(fetcher).toHaveBeenCalledTimes(1);
|
|
43
|
+
now += 1;
|
|
44
|
+
await cache.get('a', fetcher);
|
|
45
|
+
expect(fetcher).toHaveBeenCalledTimes(2);
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
Date.now = realNow;
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
it('treats ttlMs: 0 as a no-cache policy (always misses)', async () => {
|
|
52
|
+
const cache = createInMemoryTtlCache({ ttlMs: 0 });
|
|
53
|
+
const fetcher = jest.fn(async () => 'v');
|
|
54
|
+
await cache.get('a', fetcher);
|
|
55
|
+
await cache.get('a', fetcher);
|
|
56
|
+
expect(fetcher).toHaveBeenCalledTimes(2);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
describe('invalidate during inflight', () => {
|
|
60
|
+
it('does not repopulate the cache when invalidate runs while a fetch is inflight', async () => {
|
|
61
|
+
const cache = createInMemoryTtlCache({ ttlMs: 60_000 });
|
|
62
|
+
let resolveFetcher;
|
|
63
|
+
const fetcher = jest.fn(() => new Promise((r) => {
|
|
64
|
+
resolveFetcher = r;
|
|
65
|
+
}));
|
|
66
|
+
const inflightLoad = cache.get('k', fetcher);
|
|
67
|
+
await cache.invalidate('k');
|
|
68
|
+
resolveFetcher('value-that-should-not-be-cached');
|
|
69
|
+
await inflightLoad;
|
|
70
|
+
const second = await cache.get('k', jest.fn(async () => 'fresh-value'));
|
|
71
|
+
expect(second).toBe('fresh-value');
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
describe('options', () => {
|
|
75
|
+
it('rejects negative ttlMs', () => {
|
|
76
|
+
expect(() => createInMemoryTtlCache({ ttlMs: -1 })).toThrow(RangeError);
|
|
77
|
+
});
|
|
78
|
+
it('rejects non-finite ttlMs', () => {
|
|
79
|
+
expect(() => createInMemoryTtlCache({ ttlMs: NaN })).toThrow(RangeError);
|
|
80
|
+
expect(() => createInMemoryTtlCache({ ttlMs: Infinity })).toThrow(RangeError);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
describe('retention bound (maxEntries)', () => {
|
|
84
|
+
it('rejects a non-positive or non-integer maxEntries', () => {
|
|
85
|
+
expect(() => createInMemoryTtlCache({ ttlMs: 1000, maxEntries: 0 })).toThrow(RangeError);
|
|
86
|
+
expect(() => createInMemoryTtlCache({ ttlMs: 1000, maxEntries: 1.5 })).toThrow(RangeError);
|
|
87
|
+
expect(() => createInMemoryTtlCache({ ttlMs: 1000, maxEntries: -1 })).toThrow(RangeError);
|
|
88
|
+
});
|
|
89
|
+
it('evicts the least recently used entry when the cap is reached', async () => {
|
|
90
|
+
const cache = createInMemoryTtlCache({ ttlMs: 60_000, maxEntries: 2 });
|
|
91
|
+
const fetches = [];
|
|
92
|
+
const fetcher = (v) => async () => {
|
|
93
|
+
fetches.push(v);
|
|
94
|
+
return v;
|
|
95
|
+
};
|
|
96
|
+
await cache.get('a', fetcher('a'));
|
|
97
|
+
await cache.get('b', fetcher('b'));
|
|
98
|
+
await cache.get('a', fetcher('a-refetch')); // touch a, so b is now least recent
|
|
99
|
+
await cache.get('c', fetcher('c')); // cap reached: evicts b
|
|
100
|
+
expect(await cache.get('a', fetcher('a-refetch'))).toBe('a'); // still cached
|
|
101
|
+
expect(await cache.get('b', fetcher('b-refetch'))).toBe('b-refetch'); // evicted, refetched
|
|
102
|
+
expect(fetches).toEqual(['a', 'b', 'c', 'b-refetch']);
|
|
103
|
+
});
|
|
104
|
+
it('evicts expired entries before evicting live ones', async () => {
|
|
105
|
+
const realNow = Date.now;
|
|
106
|
+
let now = 1_000_000;
|
|
107
|
+
Date.now = () => now;
|
|
108
|
+
try {
|
|
109
|
+
const cache = createInMemoryTtlCache({ ttlMs: 1000, maxEntries: 2 });
|
|
110
|
+
await cache.get('old', async () => 'old');
|
|
111
|
+
now += 2000; // 'old' expires
|
|
112
|
+
await cache.get('live', async () => 'live');
|
|
113
|
+
await cache.get('new', async () => 'new'); // cap: removes expired 'old', keeps 'live'
|
|
114
|
+
const fetches = [];
|
|
115
|
+
expect(await cache.get('live', async () => {
|
|
116
|
+
fetches.push('live-refetch');
|
|
117
|
+
return 'live-refetch';
|
|
118
|
+
})).toBe('live');
|
|
119
|
+
expect(fetches).toEqual([]);
|
|
120
|
+
}
|
|
121
|
+
finally {
|
|
122
|
+
Date.now = realNow;
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
it('removes an expired entry when it is met, even with no cap configured', async () => {
|
|
126
|
+
const realNow = Date.now;
|
|
127
|
+
let now = 1_000_000;
|
|
128
|
+
Date.now = () => now;
|
|
129
|
+
try {
|
|
130
|
+
const cache = createInMemoryTtlCache({ ttlMs: 1000 });
|
|
131
|
+
await cache.get('k', async () => 'v1');
|
|
132
|
+
now += 2000;
|
|
133
|
+
// Expired: refetches, and the stale entry is deleted rather than
|
|
134
|
+
// lingering until this key happens to be rewritten.
|
|
135
|
+
await expect(cache.get('k', async () => 'v2')).resolves.toBe('v2');
|
|
136
|
+
expect(await cache.get('k', async () => 'v3')).toBe('v2');
|
|
137
|
+
}
|
|
138
|
+
finally {
|
|
139
|
+
Date.now = realNow;
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
describe('deduplication', () => {
|
|
144
|
+
it('deduplicates concurrent fetches for the same key', async () => {
|
|
145
|
+
const cache = createInMemoryTtlCache({ ttlMs: 1000 });
|
|
146
|
+
let resolveFetcher;
|
|
147
|
+
const fetcher = jest.fn(() => new Promise((r) => {
|
|
148
|
+
resolveFetcher = r;
|
|
149
|
+
}));
|
|
150
|
+
const a = cache.get('k', fetcher);
|
|
151
|
+
const b = cache.get('k', fetcher);
|
|
152
|
+
resolveFetcher('done');
|
|
153
|
+
await expect(a).resolves.toBe('done');
|
|
154
|
+
await expect(b).resolves.toBe('done');
|
|
155
|
+
expect(fetcher).toHaveBeenCalledTimes(1);
|
|
156
|
+
});
|
|
157
|
+
it('runs fetcher independently for distinct keys', async () => {
|
|
158
|
+
const cache = createInMemoryTtlCache({ ttlMs: 1000 });
|
|
159
|
+
const fetcher = jest.fn(async () => 'v');
|
|
160
|
+
await cache.get('a', fetcher);
|
|
161
|
+
await cache.get('b', fetcher);
|
|
162
|
+
expect(fetcher).toHaveBeenCalledTimes(2);
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
describe('errors', () => {
|
|
166
|
+
it('propagates fetcher rejections without caching the failure', async () => {
|
|
167
|
+
const cache = createInMemoryTtlCache({ ttlMs: 1000 });
|
|
168
|
+
let attempt = 0;
|
|
169
|
+
const fetcher = jest.fn(async () => {
|
|
170
|
+
attempt += 1;
|
|
171
|
+
if (attempt === 1)
|
|
172
|
+
throw new Error('boom');
|
|
173
|
+
return 'ok';
|
|
174
|
+
});
|
|
175
|
+
await expect(cache.get('a', fetcher)).rejects.toThrow('boom');
|
|
176
|
+
await expect(cache.get('a', fetcher)).resolves.toBe('ok');
|
|
177
|
+
expect(fetcher).toHaveBeenCalledTimes(2);
|
|
178
|
+
});
|
|
179
|
+
it('fans the same rejection out to every concurrent caller and retries on the next call', async () => {
|
|
180
|
+
const cache = createInMemoryTtlCache({ ttlMs: 1000 });
|
|
181
|
+
let rejectFetcher;
|
|
182
|
+
const fetcher = jest.fn(() => new Promise((_resolve, reject) => {
|
|
183
|
+
rejectFetcher = reject;
|
|
184
|
+
}));
|
|
185
|
+
const a = cache.get('k', fetcher);
|
|
186
|
+
const b = cache.get('k', fetcher);
|
|
187
|
+
const sharedError = new Error('shared boom');
|
|
188
|
+
rejectFetcher(sharedError);
|
|
189
|
+
const aErr = await a.catch((e) => e);
|
|
190
|
+
const bErr = await b.catch((e) => e);
|
|
191
|
+
expect(aErr).toBe(sharedError);
|
|
192
|
+
expect(bErr).toBe(sharedError);
|
|
193
|
+
expect(fetcher).toHaveBeenCalledTimes(1);
|
|
194
|
+
const c = await cache.get('k', jest.fn(async () => 'ok'));
|
|
195
|
+
expect(c).toBe('ok');
|
|
196
|
+
});
|
|
197
|
+
it('clears inflight on rejection so subsequent callers retry', async () => {
|
|
198
|
+
const cache = createInMemoryTtlCache({ ttlMs: 1000 });
|
|
199
|
+
let resolveFetcher;
|
|
200
|
+
let rejectFetcher;
|
|
201
|
+
const fetcher = jest.fn(() => new Promise((r, rej) => {
|
|
202
|
+
resolveFetcher = r;
|
|
203
|
+
rejectFetcher = rej;
|
|
204
|
+
}));
|
|
205
|
+
const first = cache.get('k', fetcher);
|
|
206
|
+
rejectFetcher(new Error('first fail'));
|
|
207
|
+
await expect(first).rejects.toThrow('first fail');
|
|
208
|
+
const second = cache.get('k', fetcher);
|
|
209
|
+
resolveFetcher('second ok');
|
|
210
|
+
await expect(second).resolves.toBe('second ok');
|
|
211
|
+
expect(fetcher).toHaveBeenCalledTimes(2);
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
describe('invalidate / clear', () => {
|
|
215
|
+
it('invalidate removes a single key without touching others', async () => {
|
|
216
|
+
const cache = createInMemoryTtlCache({ ttlMs: 1000 });
|
|
217
|
+
const fetcher = jest.fn(async () => 'v');
|
|
218
|
+
await cache.get('a', fetcher);
|
|
219
|
+
await cache.get('b', fetcher);
|
|
220
|
+
await cache.invalidate('a');
|
|
221
|
+
await cache.get('a', fetcher);
|
|
222
|
+
await cache.get('b', fetcher);
|
|
223
|
+
expect(fetcher).toHaveBeenCalledTimes(3);
|
|
224
|
+
});
|
|
225
|
+
it('clear removes every cached value', async () => {
|
|
226
|
+
const cache = createInMemoryTtlCache({ ttlMs: 1000 });
|
|
227
|
+
const fetcher = jest.fn(async () => 'v');
|
|
228
|
+
await cache.get('a', fetcher);
|
|
229
|
+
await cache.get('b', fetcher);
|
|
230
|
+
await cache.clear();
|
|
231
|
+
await cache.get('a', fetcher);
|
|
232
|
+
expect(fetcher).toHaveBeenCalledTimes(3);
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
//# sourceMappingURL=in-memory-ttl-cache.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory-ttl-cache.test.js","sourceRoot":"","sources":["../../src/cache/in-memory-ttl-cache.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface TtlCacheOptions {
|
|
2
|
+
/** TTL in ms. `0` disables caching. */
|
|
3
|
+
ttlMs: number;
|
|
4
|
+
/**
|
|
5
|
+
* Maximum number of stored entries. When a write would exceed it, expired
|
|
6
|
+
* entries are removed first, then the least recently used live entry is
|
|
7
|
+
* evicted. Omit for no bound (suitable only when keys come from trusted
|
|
8
|
+
* configuration; caller-controlled keys need a cap so a stream of unique
|
|
9
|
+
* keys cannot grow process memory without limit).
|
|
10
|
+
*/
|
|
11
|
+
maxEntries?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface TtlCache<T> {
|
|
14
|
+
/**
|
|
15
|
+
* Returns the cached value for `key` if fresh; otherwise invokes
|
|
16
|
+
* `fetcher`, stores its result, and returns it. Implementations may
|
|
17
|
+
* deduplicate concurrent misses; rejected fetches are not cached.
|
|
18
|
+
*/
|
|
19
|
+
get(key: string, fetcher: () => Promise<T>): Promise<T>;
|
|
20
|
+
invalidate(key: string): Promise<void>;
|
|
21
|
+
clear(): Promise<void>;
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ttl-cache.js","sourceRoot":"","sources":["../../src/cache/ttl-cache.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the date and time `value` refers to, when `value` is a well-formed
|
|
3
|
+
* RFC 3339 date-time for a day that exists. Otherwise returns `undefined`.
|
|
4
|
+
*
|
|
5
|
+
* `new Date()` alone is not enough. It accepts loose forms such as `2024-01-15`
|
|
6
|
+
* or `January 15, 2024`, and it quietly normalises an impossible date, turning
|
|
7
|
+
* `2024-02-30` into 1 March, which would report a date the document never
|
|
8
|
+
* asserted.
|
|
9
|
+
*
|
|
10
|
+
* `undefined` rather than `null` because this reports what a document does not
|
|
11
|
+
* usably contain. How to record that absence is the caller's decision.
|
|
12
|
+
*/
|
|
13
|
+
export declare function asDateTime(value: unknown): Date | undefined;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Matches the JSON Schema `date-time` format (RFC 3339 section 5.6).
|
|
3
|
+
*
|
|
4
|
+
* As of UNTP 0.7.0, every data model declares a credential's `validFrom` and
|
|
5
|
+
* `validUntil` as `"type": "string", "format": "date-time"`, and that is what
|
|
6
|
+
* this system validates a payload against before signing it.
|
|
7
|
+
*
|
|
8
|
+
* The W3C VC Data Model 2.0 is looser: it requires only an XML Schema 1.1
|
|
9
|
+
* `dateTime`, which permits an offsetless local time, years outside four
|
|
10
|
+
* digits, and `24:00:00` (https://www.w3.org/TR/vc-data-model-2.0/#validity-period).
|
|
11
|
+
* A credential issued elsewhere may therefore carry a value this rejects, and
|
|
12
|
+
* it is reported as absent rather than guessed: with no timezone there is no
|
|
13
|
+
* way to tell which moment a local time such as `09:00` refers to.
|
|
14
|
+
*/
|
|
15
|
+
const RFC3339_DATE_TIME = /^\d{4}-\d{2}-\d{2}[Tt]\d{2}:\d{2}:\d{2}(\.\d+)?([Zz]|[+-]\d{2}:\d{2})$/;
|
|
16
|
+
/**
|
|
17
|
+
* Returns the date and time `value` refers to, when `value` is a well-formed
|
|
18
|
+
* RFC 3339 date-time for a day that exists. Otherwise returns `undefined`.
|
|
19
|
+
*
|
|
20
|
+
* `new Date()` alone is not enough. It accepts loose forms such as `2024-01-15`
|
|
21
|
+
* or `January 15, 2024`, and it quietly normalises an impossible date, turning
|
|
22
|
+
* `2024-02-30` into 1 March, which would report a date the document never
|
|
23
|
+
* asserted.
|
|
24
|
+
*
|
|
25
|
+
* `undefined` rather than `null` because this reports what a document does not
|
|
26
|
+
* usably contain. How to record that absence is the caller's decision.
|
|
27
|
+
*/
|
|
28
|
+
export function asDateTime(value) {
|
|
29
|
+
if (typeof value !== 'string' || !RFC3339_DATE_TIME.test(value))
|
|
30
|
+
return undefined;
|
|
31
|
+
const parsed = new Date(value);
|
|
32
|
+
if (Number.isNaN(parsed.getTime()))
|
|
33
|
+
return undefined;
|
|
34
|
+
// Round-trip the calendar day: a normalised day (30 February) lands on a
|
|
35
|
+
// different day-of-month than the string names.
|
|
36
|
+
const day = Number(value.slice(8, 10));
|
|
37
|
+
const offsetMatch = /([+-])(\d{2}):(\d{2})$/.exec(value);
|
|
38
|
+
const offsetMinutes = offsetMatch
|
|
39
|
+
? (offsetMatch[1] === '-' ? -1 : 1) * (Number(offsetMatch[2]) * 60 + Number(offsetMatch[3]))
|
|
40
|
+
: 0;
|
|
41
|
+
const local = new Date(parsed.getTime() + offsetMinutes * 60_000);
|
|
42
|
+
return local.getUTCDate() === day ? parsed : undefined;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=as-date-time.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"as-date-time.js","sourceRoot":"","sources":["../../src/common/as-date-time.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,iBAAiB,GAAG,wEAAwE,CAAC;AAEnG;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAClF,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/B,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAAE,OAAO,SAAS,CAAC;IACrD,yEAAyE;IACzE,gDAAgD;IAChD,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACvC,MAAM,WAAW,GAAG,wBAAwB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzD,MAAM,aAAa,GAAG,WAAW;QAC/B,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5F,CAAC,CAAC,CAAC,CAAC;IACN,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,aAAa,GAAG,MAAM,CAAC,CAAC;IAClE,OAAO,KAAK,CAAC,UAAU,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AACzD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { asDateTime } from './as-date-time.js';
|
|
2
|
+
describe('asDateTime', () => {
|
|
3
|
+
it('returns the date and time a well-formed UTC value refers to', () => {
|
|
4
|
+
expect(asDateTime('2024-01-15T00:00:00Z')).toEqual(new Date('2024-01-15T00:00:00.000Z'));
|
|
5
|
+
expect(asDateTime('2024-01-15T10:30:00.250Z')).toEqual(new Date('2024-01-15T10:30:00.250Z'));
|
|
6
|
+
});
|
|
7
|
+
it('reads an offset value as the same moment in UTC', () => {
|
|
8
|
+
expect(asDateTime('2024-01-15T23:30:00+10:00')).toEqual(new Date('2024-01-15T13:30:00.000Z'));
|
|
9
|
+
expect(asDateTime('2024-01-15T00:30:00-05:00')).toEqual(new Date('2024-01-15T05:30:00.000Z'));
|
|
10
|
+
});
|
|
11
|
+
it('returns undefined for a day the calendar does not have, rather than normalising it', () => {
|
|
12
|
+
expect(asDateTime('2024-02-30T00:00:00Z')).toBeUndefined();
|
|
13
|
+
expect(asDateTime('2023-02-29T00:00:00Z')).toBeUndefined();
|
|
14
|
+
});
|
|
15
|
+
it('accepts a real leap day', () => {
|
|
16
|
+
expect(asDateTime('2024-02-29T00:00:00Z')).toEqual(new Date('2024-02-29T00:00:00.000Z'));
|
|
17
|
+
});
|
|
18
|
+
it('returns undefined for a leap second', () => {
|
|
19
|
+
// Well-formed RFC 3339, but JavaScript has no value for it.
|
|
20
|
+
expect(asDateTime('1990-12-31T23:59:60Z')).toBeUndefined();
|
|
21
|
+
});
|
|
22
|
+
it.each([
|
|
23
|
+
['a date with no time', '2024-01-15'],
|
|
24
|
+
['a human-readable date', 'January 15, 2024'],
|
|
25
|
+
['a bare number', '0'],
|
|
26
|
+
['nonsense', 'not-a-date'],
|
|
27
|
+
['the empty string', ''],
|
|
28
|
+
['a time with no zone', '2024-01-15T00:00:00'],
|
|
29
|
+
])('returns undefined for %s', (_label, value) => {
|
|
30
|
+
expect(asDateTime(value)).toBeUndefined();
|
|
31
|
+
});
|
|
32
|
+
it.each([
|
|
33
|
+
['number', 1705276800000],
|
|
34
|
+
['null', null],
|
|
35
|
+
['undefined', undefined],
|
|
36
|
+
['Date', new Date()],
|
|
37
|
+
['object', {}],
|
|
38
|
+
])('returns undefined for a non-string %s', (_label, value) => {
|
|
39
|
+
expect(asDateTime(value)).toBeUndefined();
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
//# sourceMappingURL=as-date-time.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"as-date-time.test.js","sourceRoot":"","sources":["../../src/common/as-date-time.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,MAAM,CAAC,UAAU,CAAC,sBAAsB,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC;QACzF,MAAM,CAAC,UAAU,CAAC,0BAA0B,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC;IAC/F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,CAAC,UAAU,CAAC,2BAA2B,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC;QAC9F,MAAM,CAAC,UAAU,CAAC,2BAA2B,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC;IAChG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oFAAoF,EAAE,GAAG,EAAE;QAC5F,MAAM,CAAC,UAAU,CAAC,sBAAsB,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;QAC3D,MAAM,CAAC,UAAU,CAAC,sBAAsB,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,MAAM,CAAC,UAAU,CAAC,sBAAsB,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC;IAC3F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,4DAA4D;QAC5D,MAAM,CAAC,UAAU,CAAC,sBAAsB,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,IAAI,CAAC;QACN,CAAC,qBAAqB,EAAE,YAAY,CAAC;QACrC,CAAC,uBAAuB,EAAE,kBAAkB,CAAC;QAC7C,CAAC,eAAe,EAAE,GAAG,CAAC;QACtB,CAAC,UAAU,EAAE,YAAY,CAAC;QAC1B,CAAC,kBAAkB,EAAE,EAAE,CAAC;QACxB,CAAC,qBAAqB,EAAE,qBAAqB,CAAC;KAC/C,CAAC,CAAC,0BAA0B,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;QAC/C,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,IAAI,CAAC;QACN,CAAC,QAAQ,EAAE,aAAa,CAAC;QACzB,CAAC,MAAM,EAAE,IAAI,CAAC;QACd,CAAC,WAAW,EAAE,SAAS,CAAC;QACxB,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;QACpB,CAAC,QAAQ,EAAE,EAAE,CAAC;KACf,CAAC,CAAC,uCAAuC,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;QAC5D,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns `value` trimmed if it is a string with non-whitespace content,
|
|
3
|
+
* otherwise `undefined`.
|
|
4
|
+
*
|
|
5
|
+
* Surrounding whitespace is never meaningful in the values this reads (names,
|
|
6
|
+
* identifiers, labels), and a whitespace-only string carries no more
|
|
7
|
+
* information than an absent one, so both collapse to `undefined`.
|
|
8
|
+
*
|
|
9
|
+
* `undefined` rather than `null` because this reports what a document does
|
|
10
|
+
* not contain. Recording that absence as a stored or transmitted value is a
|
|
11
|
+
* separate decision, made by the caller at the boundary where a read becomes
|
|
12
|
+
* a row or a response.
|
|
13
|
+
*/
|
|
14
|
+
export declare function asNonEmptyString(value: unknown): string | undefined;
|