@canonical/pragma-cli 0.38.0 → 0.40.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 +1 -1
- package/dist/package.json +14 -14
- package/dist/pragma.conf.js +273 -176
- package/dist/pragma.conf.js.map +1 -1
- package/dist/src/capabilities/capabilities/capabilities.verb.js +2 -0
- package/dist/src/capabilities/capabilities/capabilities.verb.js.map +1 -1
- package/dist/src/capabilities/capabilities/catalog.js +47 -51
- package/dist/src/capabilities/capabilities/catalog.js.map +1 -1
- package/dist/src/capabilities/capabilities/index.js +2 -0
- package/dist/src/capabilities/capabilities/index.js.map +1 -1
- package/dist/src/capabilities/capabilities/types.js +5 -5
- package/dist/src/capabilities/colophon/colophon.render.js +7 -4
- package/dist/src/capabilities/colophon/colophon.render.js.map +1 -1
- package/dist/src/capabilities/colophon/colophon.verb.js +1 -0
- package/dist/src/capabilities/colophon/colophon.verb.js.map +1 -1
- package/dist/src/capabilities/config/get.verb.js +2 -0
- package/dist/src/capabilities/config/get.verb.js.map +1 -1
- package/dist/src/capabilities/config/runField.js +2 -2
- package/dist/src/capabilities/config/runField.js.map +1 -1
- package/dist/src/capabilities/config/set.verb.js +2 -0
- package/dist/src/capabilities/config/set.verb.js.map +1 -1
- package/dist/src/capabilities/config/show.verb.js +1 -0
- package/dist/src/capabilities/config/show.verb.js.map +1 -1
- package/dist/src/capabilities/config/unset.verb.js +2 -0
- package/dist/src/capabilities/config/unset.verb.js.map +1 -1
- package/dist/src/capabilities/create/constants.js +2 -2
- package/dist/src/capabilities/create/create.verb.js +14 -4
- package/dist/src/capabilities/create/create.verb.js.map +1 -1
- package/dist/src/capabilities/distribution.js +3 -1
- package/dist/src/capabilities/distribution.js.map +1 -1
- package/dist/src/capabilities/doctor/checks/checkPackageRefs.js +10 -2
- package/dist/src/capabilities/doctor/checks/checkPackageRefs.js.map +1 -1
- package/dist/src/capabilities/doctor/doctor.verb.js +2 -0
- package/dist/src/capabilities/doctor/doctor.verb.js.map +1 -1
- package/dist/src/capabilities/graph/connect.verb.js +2 -0
- package/dist/src/capabilities/graph/connect.verb.js.map +1 -1
- package/dist/src/capabilities/graph/inspect.render.js +7 -1
- package/dist/src/capabilities/graph/inspect.render.js.map +1 -1
- package/dist/src/capabilities/graph/inspect.verb.js +2 -0
- package/dist/src/capabilities/graph/inspect.verb.js.map +1 -1
- package/dist/src/capabilities/graph/query.render.js +37 -5
- package/dist/src/capabilities/graph/query.render.js.map +1 -1
- package/dist/src/capabilities/graph/query.verb.js +2 -0
- package/dist/src/capabilities/graph/query.verb.js.map +1 -1
- package/dist/src/capabilities/graph/queryText.js +28 -0
- package/dist/src/capabilities/graph/queryText.js.map +1 -1
- package/dist/src/capabilities/graph/runConnect.js +3 -3
- package/dist/src/capabilities/graph/runConnect.js.map +1 -1
- package/dist/src/capabilities/graph/runQuery.js +8 -6
- package/dist/src/capabilities/graph/runQuery.js.map +1 -1
- package/dist/src/capabilities/info/info.verb.js +2 -0
- package/dist/src/capabilities/info/info.verb.js.map +1 -1
- package/dist/src/capabilities/meta/mcp.verb.js +1 -0
- package/dist/src/capabilities/meta/mcp.verb.js.map +1 -1
- package/dist/src/capabilities/ontology/verbs.js +7 -10
- package/dist/src/capabilities/ontology/verbs.js.map +1 -1
- package/dist/src/capabilities/prompt/verbs.js +5 -4
- package/dist/src/capabilities/prompt/verbs.js.map +1 -1
- package/dist/src/capabilities/resources/provider.js +6 -3
- package/dist/src/capabilities/resources/provider.js.map +1 -1
- package/dist/src/capabilities/setup/setup.verb.js +13 -5
- package/dist/src/capabilities/setup/setup.verb.js.map +1 -1
- package/dist/src/capabilities/shared/calls.js +16 -0
- package/dist/src/capabilities/shared/calls.js.map +1 -0
- package/dist/src/capabilities/skill/render.js +7 -5
- package/dist/src/capabilities/skill/render.js.map +1 -1
- package/dist/src/capabilities/skill/verbs.js +5 -4
- package/dist/src/capabilities/skill/verbs.js.map +1 -1
- package/dist/src/capabilities/sources/collectStatus.js +6 -1
- package/dist/src/capabilities/sources/collectStatus.js.map +1 -1
- package/dist/src/capabilities/sources/index.js +4 -3
- package/dist/src/capabilities/sources/index.js.map +1 -1
- package/dist/src/capabilities/sources/reset.render.js +37 -0
- package/dist/src/capabilities/sources/reset.render.js.map +1 -0
- package/dist/src/capabilities/sources/reset.verb.js +51 -0
- package/dist/src/capabilities/sources/reset.verb.js.map +1 -0
- package/dist/src/capabilities/sources/runReset.js +59 -0
- package/dist/src/capabilities/sources/runReset.js.map +1 -0
- package/dist/src/capabilities/sources/runUpdate.js +7 -6
- package/dist/src/capabilities/sources/runUpdate.js.map +1 -1
- package/dist/src/capabilities/sources/status.render.js +24 -8
- package/dist/src/capabilities/sources/status.render.js.map +1 -1
- package/dist/src/capabilities/sources/status.verb.js +1 -0
- package/dist/src/capabilities/sources/status.verb.js.map +1 -1
- package/dist/src/capabilities/sources/update.verb.js +2 -0
- package/dist/src/capabilities/sources/update.verb.js.map +1 -1
- package/dist/src/capabilities/upgrade/upgrade.verb.js +1 -0
- package/dist/src/capabilities/upgrade/upgrade.verb.js.map +1 -1
- package/dist/src/capabilities/version/version.verb.js +1 -0
- package/dist/src/capabilities/version/version.verb.js.map +1 -1
- package/dist/src/constants.js +4 -3
- package/dist/src/constants.js.map +1 -1
- package/dist/src/kernel/error/index.js +1 -1
- package/dist/src/kernel/error/index.js.map +1 -1
- package/dist/src/kernel/error/recovery.js +24 -42
- package/dist/src/kernel/error/recovery.js.map +1 -1
- package/dist/src/kernel/packs/collect.js +123 -9
- package/dist/src/kernel/packs/collect.js.map +1 -1
- package/dist/src/kernel/packs/compile.js +74 -15
- package/dist/src/kernel/packs/compile.js.map +1 -1
- package/dist/src/kernel/packs/graphql/fetchGraphqlLookup.js +3 -3
- package/dist/src/kernel/packs/graphql/fetchGraphqlLookup.js.map +1 -1
- package/dist/src/kernel/packs/iri.js +2 -4
- package/dist/src/kernel/packs/iri.js.map +1 -1
- package/dist/src/kernel/packs/renderPack.js +90 -50
- package/dist/src/kernel/packs/renderPack.js.map +1 -1
- package/dist/src/kernel/packs/resolveEntity.js +202 -90
- package/dist/src/kernel/packs/resolveEntity.js.map +1 -1
- package/dist/src/kernel/packs/runBodies.js +89 -30
- package/dist/src/kernel/packs/runBodies.js.map +1 -1
- package/dist/src/kernel/packs/schema.js +66 -12
- package/dist/src/kernel/packs/schema.js.map +1 -1
- package/dist/src/kernel/packs/sparql/buildListQuery.js +80 -13
- package/dist/src/kernel/packs/sparql/buildListQuery.js.map +1 -1
- package/dist/src/kernel/packs/sparql/buildLookupQuery.js +41 -13
- package/dist/src/kernel/packs/sparql/buildLookupQuery.js.map +1 -1
- package/dist/src/kernel/packs/sparql/filterValues.js +32 -23
- package/dist/src/kernel/packs/sparql/filterValues.js.map +1 -1
- package/dist/src/kernel/packs/sparql/runSelect.js +3 -5
- package/dist/src/kernel/packs/sparql/runSelect.js.map +1 -1
- package/dist/src/kernel/packs/storyRules.js +31 -4
- package/dist/src/kernel/packs/storyRules.js.map +1 -1
- package/dist/src/kernel/packs/tierScope.js +3 -3
- package/dist/src/kernel/packs/tierScope.js.map +1 -1
- package/dist/src/kernel/packs/types.js +4 -0
- package/dist/src/kernel/packs/types.js.map +1 -1
- package/dist/src/kernel/project/cli/buildProgram.js +4 -0
- package/dist/src/kernel/project/cli/buildProgram.js.map +1 -1
- package/dist/src/kernel/project/cli/dispatch.js +32 -8
- package/dist/src/kernel/project/cli/dispatch.js.map +1 -1
- package/dist/src/kernel/project/cli/suggestNames.js +44 -1
- package/dist/src/kernel/project/cli/suggestNames.js.map +1 -1
- package/dist/src/kernel/project/cli/verbHelp.js +17 -18
- package/dist/src/kernel/project/cli/verbHelp.js.map +1 -1
- package/dist/src/kernel/project/mcp/buildServer.js +11 -4
- package/dist/src/kernel/project/mcp/buildServer.js.map +1 -1
- package/dist/src/kernel/project/mcp/envelope.js +3 -2
- package/dist/src/kernel/project/mcp/envelope.js.map +1 -1
- package/dist/src/kernel/project/mcp/instructions.js +101 -31
- package/dist/src/kernel/project/mcp/instructions.js.map +1 -1
- package/dist/src/kernel/project/mcp/registerVerb.js +59 -23
- package/dist/src/kernel/project/mcp/registerVerb.js.map +1 -1
- package/dist/src/kernel/render/renderers.js +3 -3
- package/dist/src/kernel/render/turtle.js +21 -4
- package/dist/src/kernel/render/turtle.js.map +1 -1
- package/dist/src/kernel/runtime/graphpack/build.js +54 -1
- package/dist/src/kernel/runtime/graphpack/build.js.map +1 -1
- package/dist/src/kernel/runtime/graphpack/manifest.js +14 -0
- package/dist/src/kernel/runtime/graphpack/manifest.js.map +1 -1
- package/dist/src/kernel/runtime/graphpack/read.js +3 -5
- package/dist/src/kernel/runtime/graphpack/read.js.map +1 -1
- package/dist/src/kernel/runtime/graphpack/schemas.js +1 -0
- package/dist/src/kernel/runtime/graphpack/schemas.js.map +1 -1
- package/dist/src/kernel/runtime/loadSession.js +8 -1
- package/dist/src/kernel/runtime/loadSession.js.map +1 -1
- package/dist/src/kernel/runtime/packVersion.js +75 -0
- package/dist/src/kernel/runtime/packVersion.js.map +1 -0
- package/dist/src/kernel/runtime/readEntity.js +43 -4
- package/dist/src/kernel/runtime/readEntity.js.map +1 -1
- package/dist/src/kernel/runtime/resolveSources.js +61 -9
- package/dist/src/kernel/runtime/resolveSources.js.map +1 -1
- package/dist/src/kernel/runtime/storeReadiness.js +3 -2
- package/dist/src/kernel/runtime/storeReadiness.js.map +1 -1
- package/dist/src/kernel/spec/call.js +167 -0
- package/dist/src/kernel/spec/call.js.map +1 -0
- package/dist/src/kernel/spec/emitReference.js +9 -13
- package/dist/src/kernel/spec/emitReference.js.map +1 -1
- package/dist/src/kernel/spec/emitSurface.js +8 -1
- package/dist/src/kernel/spec/emitSurface.js.map +1 -1
- package/dist/src/kernel/spec/guidance.js +63 -0
- package/dist/src/kernel/spec/guidance.js.map +1 -0
- package/dist/src/kernel/spec/wireType.js +36 -0
- package/dist/src/kernel/spec/wireType.js.map +1 -0
- package/package.json +14 -14
- package/pragma.conf.ts +294 -177
- package/src/capabilities/block.parity.test.ts +1 -1
- package/src/capabilities/callRule.test.ts +147 -0
- package/src/capabilities/capabilities/capabilities.test.ts +47 -19
- package/src/capabilities/capabilities/capabilities.verb.ts +2 -0
- package/src/capabilities/capabilities/catalog.ts +60 -55
- package/src/capabilities/capabilities/index.ts +2 -0
- package/src/capabilities/capabilities/types.ts +16 -19
- package/src/capabilities/colophon/colophon.render.ts +9 -5
- package/src/capabilities/colophon/colophon.verb.ts +1 -0
- package/src/capabilities/config/get.verb.ts +2 -0
- package/src/capabilities/config/runField.ts +3 -3
- package/src/capabilities/config/set.verb.ts +3 -0
- package/src/capabilities/config/show.verb.ts +2 -0
- package/src/capabilities/config/unset.verb.ts +2 -0
- package/src/capabilities/create/constants.ts +2 -2
- package/src/capabilities/create/create.verb.ts +16 -0
- package/src/capabilities/create/createGrammar.test.ts +1 -1
- package/src/capabilities/distribution.test.ts +6 -3
- package/src/capabilities/distribution.ts +6 -0
- package/src/capabilities/doctor/checks/checkPackageRefs.ts +14 -2
- package/src/capabilities/doctor/doctor.test.ts +38 -1
- package/src/capabilities/doctor/doctor.verb.ts +2 -0
- package/src/capabilities/emptyRecovery.test.ts +5 -0
- package/src/capabilities/graph/connect.verb.ts +2 -0
- package/src/capabilities/graph/inspect.render.ts +9 -1
- package/src/capabilities/graph/inspect.test.ts +73 -0
- package/src/capabilities/graph/inspect.verb.ts +2 -0
- package/src/capabilities/graph/query.render.test.ts +35 -0
- package/src/capabilities/graph/query.render.ts +45 -7
- package/src/capabilities/graph/query.shipped.exec.test.ts +44 -0
- package/src/capabilities/graph/query.verb.ts +2 -0
- package/src/capabilities/graph/queryText.test.ts +55 -1
- package/src/capabilities/graph/queryText.ts +47 -0
- package/src/capabilities/graph/runConnect.ts +4 -5
- package/src/capabilities/graph/runQuery.ts +23 -9
- package/src/capabilities/info/info.verb.ts +2 -0
- package/src/capabilities/links.shipped.exec.test.ts +398 -0
- package/src/capabilities/listBudget.shipped.exec.test.ts +2 -2
- package/src/capabilities/listLookup.shipped.exec.test.ts +122 -13
- package/src/capabilities/listQuery.shipped.exec.test.ts +39 -16
- package/src/capabilities/lookupBudget.shipped.exec.test.ts +208 -0
- package/src/capabilities/meta/mcp.verb.ts +2 -0
- package/src/capabilities/ontology/ontology.test.ts +24 -0
- package/src/capabilities/ontology/verbs.ts +16 -12
- package/src/capabilities/prompt/verbs.ts +10 -4
- package/src/capabilities/resources/provider.ts +7 -3
- package/src/capabilities/resources/resources.test.ts +2 -1
- package/src/capabilities/setup/setup.verb.ts +16 -0
- package/src/capabilities/shared/calls.ts +20 -0
- package/src/capabilities/skill/render.ts +9 -6
- package/src/capabilities/skill/verbs.ts +8 -4
- package/src/capabilities/sources/collectStatus.ts +6 -1
- package/src/capabilities/sources/index.ts +4 -3
- package/src/capabilities/sources/reset.render.test.ts +33 -0
- package/src/capabilities/sources/reset.render.ts +43 -0
- package/src/capabilities/sources/reset.verb.ts +59 -0
- package/src/capabilities/sources/runReset.ts +65 -0
- package/src/capabilities/sources/runUpdate.ts +12 -11
- package/src/capabilities/sources/sources.test.ts +158 -3
- package/src/capabilities/sources/status.render.test.ts +63 -1
- package/src/capabilities/sources/status.render.ts +25 -8
- package/src/capabilities/sources/status.verb.ts +2 -0
- package/src/capabilities/sources/types.ts +26 -0
- package/src/capabilities/sources/update.verb.ts +3 -0
- package/src/capabilities/surface.test.ts +2 -2
- package/src/capabilities/token.parity.test.ts +3 -2
- package/src/capabilities/tokenGraph.shipped.exec.test.ts +14 -2
- package/src/capabilities/upgrade/upgrade.verb.ts +1 -0
- package/src/capabilities/variable.parity.test.ts +2 -1
- package/src/capabilities/version/version.verb.ts +1 -0
- package/src/capabilities/wireContract.test.ts +110 -0
- package/src/constants.ts +4 -3
- package/src/kernel/copy.test.ts +1 -1
- package/src/kernel/error/PragmaError.test.ts +7 -3
- package/src/kernel/error/index.ts +1 -1
- package/src/kernel/error/recovery.test.ts +52 -18
- package/src/kernel/error/recovery.ts +25 -46
- package/src/kernel/error/types.ts +1 -1
- package/src/kernel/packs/collect.test.ts +79 -0
- package/src/kernel/packs/collect.ts +151 -11
- package/src/kernel/packs/compile.test.ts +107 -10
- package/src/kernel/packs/compile.ts +100 -11
- package/src/kernel/packs/filteredEmpty.test.ts +22 -5
- package/src/kernel/packs/graphql/fetchGraphqlLookup.ts +5 -6
- package/src/kernel/packs/graphqlSource.test.ts +42 -0
- package/src/kernel/packs/iri.ts +5 -4
- package/src/kernel/packs/listNotice.test.ts +1 -1
- package/src/kernel/packs/nounLink.test.ts +385 -0
- package/src/kernel/packs/renderPack.ts +137 -57
- package/src/kernel/packs/resolveEntity.test.ts +170 -1
- package/src/kernel/packs/resolveEntity.ts +281 -101
- package/src/kernel/packs/runBodies.ts +133 -31
- package/src/kernel/packs/schema.ts +77 -12
- package/src/kernel/packs/sparql/buildListQuery.test.ts +78 -1
- package/src/kernel/packs/sparql/buildListQuery.ts +106 -16
- package/src/kernel/packs/sparql/buildLookupQuery.ts +44 -13
- package/src/kernel/packs/sparql/filterValues.test.ts +36 -4
- package/src/kernel/packs/sparql/filterValues.ts +50 -31
- package/src/kernel/packs/sparql/runSelect.ts +4 -6
- package/src/kernel/packs/storyRules.ts +37 -4
- package/src/kernel/packs/tierScope.test.ts +120 -6
- package/src/kernel/packs/tierScope.ts +5 -7
- package/src/kernel/packs/toolDescription.test.ts +59 -74
- package/src/kernel/packs/types.ts +93 -11
- package/src/kernel/project/cli/buildProgram.ts +4 -0
- package/src/kernel/project/cli/dispatch.ts +34 -8
- package/src/kernel/project/cli/suggest.test.ts +77 -0
- package/src/kernel/project/cli/suggestNames.ts +47 -1
- package/src/kernel/project/cli/verbHelp.ts +16 -19
- package/src/kernel/project/mcp/buildServer.ts +15 -4
- package/src/kernel/project/mcp/envelope.ts +3 -2
- package/src/kernel/project/mcp/instructions.ts +123 -35
- package/src/kernel/project/mcp/prompts/prompts.test.ts +136 -20
- package/src/kernel/project/mcp/registerVerb.test.ts +28 -0
- package/src/kernel/project/mcp/registerVerb.ts +67 -29
- package/src/kernel/render/__snapshots__/renderers.test.ts.snap +1 -1
- package/src/kernel/render/renderers.test.ts +2 -2
- package/src/kernel/render/renderers.ts +3 -3
- package/src/kernel/render/turtle.ts +24 -4
- package/src/kernel/runtime/graphpack/build.ts +58 -1
- package/src/kernel/runtime/graphpack/graphpack.test.ts +20 -0
- package/src/kernel/runtime/graphpack/manifest.ts +15 -0
- package/src/kernel/runtime/graphpack/read.ts +4 -6
- package/src/kernel/runtime/graphpack/schemas.ts +1 -0
- package/src/kernel/runtime/graphpack/types.ts +13 -0
- package/src/kernel/runtime/loadSession.ts +8 -1
- package/src/kernel/runtime/packVersion.test.ts +61 -0
- package/src/kernel/runtime/packVersion.ts +84 -0
- package/src/kernel/runtime/readEntity.ts +61 -6
- package/src/kernel/runtime/resolveSources.test.ts +90 -7
- package/src/kernel/runtime/resolveSources.ts +91 -10
- package/src/kernel/runtime/storeReadiness.ts +4 -4
- package/src/kernel/runtime/types.ts +12 -0
- package/src/kernel/spec/call.test.ts +95 -0
- package/src/kernel/spec/call.ts +186 -0
- package/src/kernel/spec/emitReference.ts +9 -13
- package/src/kernel/spec/emitSurface.ts +9 -1
- package/src/kernel/spec/guidance.test.ts +49 -0
- package/src/kernel/spec/guidance.ts +68 -0
- package/src/kernel/spec/index.ts +4 -0
- package/src/kernel/spec/surfaceConformance.test.ts +2 -2
- package/src/kernel/spec/types.ts +64 -7
- package/src/kernel/spec/wireType.ts +53 -0
- package/src/testing/behavioral/errorMatrix.mcp.test.ts +2 -1
- package/src/testing/behavioral/journeys.firstInstall.test.ts +72 -2
- package/src/testing/behavioral/parity.test.ts +40 -0
- package/src/testing/eval/__snapshots__/eval.test.ts.snap +1 -1
- package/src/testing/eval/cases/assembly.ts +4 -3
- package/src/testing/eval/cases/stable.ts +2 -3
- package/src/testing/helpers/callSchema.ts +40 -0
- package/src/testing/helpers/parity.ts +35 -2
- package/src/testing/setupCallChecking.ts +30 -0
- package/dist/src/capabilities/capabilities/hints.js +0 -223
- package/dist/src/capabilities/capabilities/hints.js.map +0 -1
- package/src/capabilities/capabilities/hints.ts +0 -266
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A filter that names a noun accepts what that noun's lookup accepts, and a
|
|
3
|
+
* `many` expand field adds values to a row, never rows.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { beforeAll, describe, expect, it } from "vitest";
|
|
7
|
+
import { buildFixtureRuntime } from "../../testing/helpers/packRuntime.js";
|
|
8
|
+
import type { ConfigLayers } from "../config/index.js";
|
|
9
|
+
import type { PragmaRuntime } from "../runtime/types.js";
|
|
10
|
+
import type { CapabilityModule, VerbSpec } from "../spec/types.js";
|
|
11
|
+
import { assembleEffectiveModules, screenPackageStories } from "./collect.js";
|
|
12
|
+
import { compilePack, compileStoryModule } from "./compile.js";
|
|
13
|
+
import type { LookupOutput } from "./resolveEntity.js";
|
|
14
|
+
import { parsePackDefinition } from "./schema.js";
|
|
15
|
+
import {
|
|
16
|
+
distributionSource,
|
|
17
|
+
type PackDefinition,
|
|
18
|
+
type PackPage,
|
|
19
|
+
} from "./types.js";
|
|
20
|
+
import { verbKey } from "./uniqueness.js";
|
|
21
|
+
|
|
22
|
+
const PREFIXES = {
|
|
23
|
+
ex: "https://example.org/shop#",
|
|
24
|
+
owl: "http://www.w3.org/2002/07/owl#",
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const TTL = `
|
|
28
|
+
@prefix ex: <https://example.org/shop#> .
|
|
29
|
+
@prefix owl: <http://www.w3.org/2002/07/owl#> .
|
|
30
|
+
|
|
31
|
+
ex:Maker a owl:Class .
|
|
32
|
+
ex:Widget a owl:Class .
|
|
33
|
+
|
|
34
|
+
ex:acme a ex:Maker ; ex:name "Acme" ; ex:code "A1" .
|
|
35
|
+
ex:acme2 a ex:Maker ; ex:name "Acme" .
|
|
36
|
+
ex:bolt a ex:Maker ; ex:name "Bolt" .
|
|
37
|
+
ex:idle a ex:Maker ; ex:name "Idle" .
|
|
38
|
+
|
|
39
|
+
ex:button a ex:Widget ; ex:name "Button" ; ex:madeBy ex:acme ;
|
|
40
|
+
ex:alias "btn" , "Btn" , "push-button" .
|
|
41
|
+
ex:label a ex:Widget ; ex:name "Label" ; ex:madeBy ex:acme2 .
|
|
42
|
+
ex:slider a ex:Widget ; ex:name "Slider" ; ex:madeBy ex:bolt .
|
|
43
|
+
|
|
44
|
+
ex:bolt ex:part
|
|
45
|
+
[ ex:group "g" ; ex:label "f" ; ex:tag "x" , "y" ] ,
|
|
46
|
+
[ ex:group "g" ; ex:label "c" ; ex:tag "x" ] ,
|
|
47
|
+
[ ex:group "g" ; ex:label "e" ] ,
|
|
48
|
+
[ ex:group "g" ; ex:label "a" ; ex:tag "y" ] ,
|
|
49
|
+
[ ex:group "g" ; ex:label "d" ; ex:tag "x" ] ,
|
|
50
|
+
[ ex:group "g" ; ex:label "b" ] .
|
|
51
|
+
`;
|
|
52
|
+
|
|
53
|
+
const MAKER: PackDefinition = {
|
|
54
|
+
noun: "maker",
|
|
55
|
+
lookup: {
|
|
56
|
+
by: "ex:name",
|
|
57
|
+
type: "ex:Maker",
|
|
58
|
+
expand: [
|
|
59
|
+
{
|
|
60
|
+
name: "widgets",
|
|
61
|
+
kind: "table",
|
|
62
|
+
relation: "^ex:madeBy",
|
|
63
|
+
select: [
|
|
64
|
+
{ name: "name", property: "ex:name", noun: "widget" },
|
|
65
|
+
{ name: "aliases", property: "ex:alias", many: true },
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: "parts",
|
|
70
|
+
kind: "table",
|
|
71
|
+
relation: "ex:part",
|
|
72
|
+
// Every part ties on the one declared key.
|
|
73
|
+
orderBy: ["group"],
|
|
74
|
+
select: [
|
|
75
|
+
{ name: "group", property: "ex:group" },
|
|
76
|
+
{ name: "label", property: "ex:label" },
|
|
77
|
+
{ name: "tags", property: "ex:tag", many: true },
|
|
78
|
+
],
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const WIDGET: PackDefinition = {
|
|
85
|
+
noun: "widget",
|
|
86
|
+
list: {
|
|
87
|
+
query: [
|
|
88
|
+
"SELECT ?uri ?name ?maker ?makerUri WHERE {",
|
|
89
|
+
" ?uri a ex:Widget ; ex:name ?name ; ex:madeBy ?makerUri .",
|
|
90
|
+
" ?makerUri ex:name ?maker .",
|
|
91
|
+
"} ORDER BY ?name",
|
|
92
|
+
].join("\n"),
|
|
93
|
+
columns: [
|
|
94
|
+
{ field: "name", label: "Name" },
|
|
95
|
+
{ field: "maker", label: "Maker", noun: "maker" },
|
|
96
|
+
],
|
|
97
|
+
filters: [
|
|
98
|
+
{ param: "maker", variable: "maker", noun: "maker", entity: "makerUri" },
|
|
99
|
+
],
|
|
100
|
+
},
|
|
101
|
+
lookup: { by: "ex:name", type: "ex:Widget" },
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const STORIES = new Map([MAKER, WIDGET].map((story) => [story.noun, story]));
|
|
105
|
+
|
|
106
|
+
const verb = (story: PackDefinition, name: string): VerbSpec =>
|
|
107
|
+
compilePack(
|
|
108
|
+
story,
|
|
109
|
+
distributionSource("test:links"),
|
|
110
|
+
PREFIXES,
|
|
111
|
+
(noun) => STORIES.get(noun)?.lookup,
|
|
112
|
+
).find((v) => verbKey(v.path) === `${story.noun} ${name}`) as VerbSpec;
|
|
113
|
+
|
|
114
|
+
let rt: PragmaRuntime;
|
|
115
|
+
beforeAll(async () => {
|
|
116
|
+
({ rt } = await buildFixtureRuntime({ ttl: TTL, prefixes: PREFIXES }));
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const widgetsBy = async (maker: unknown): Promise<PackPage["rows"]> =>
|
|
120
|
+
((await verb(WIDGET, "list").run({ maker }, rt)) as PackPage).rows;
|
|
121
|
+
|
|
122
|
+
describe("a filter that names a noun", () => {
|
|
123
|
+
it("takes a name, and a shared name means every entity it reaches", async () => {
|
|
124
|
+
const rows = await widgetsBy("acme");
|
|
125
|
+
expect(rows.map((row) => row.name)).toEqual(["Button", "Label"]);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it("takes a prefixed IRI and an absolute IRI, which reach one entity", async () => {
|
|
129
|
+
expect((await widgetsBy("ex:acme2")).map((row) => row.name)).toEqual([
|
|
130
|
+
"Label",
|
|
131
|
+
]);
|
|
132
|
+
expect(
|
|
133
|
+
(await widgetsBy("https://example.org/shop#bolt")).map((row) => row.name),
|
|
134
|
+
).toEqual(["Slider"]);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it("takes several values as a union", async () => {
|
|
138
|
+
const rows = await widgetsBy(["Bolt", "ex:acme"]);
|
|
139
|
+
expect(rows.map((row) => row.name)).toEqual(["Button", "Slider"]);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it("leaves the entity variable out of the rows", async () => {
|
|
143
|
+
expect(Object.keys((await widgetsBy("Bolt"))[0] ?? {})).toEqual([
|
|
144
|
+
"uri",
|
|
145
|
+
"name",
|
|
146
|
+
"maker",
|
|
147
|
+
]);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it("answers a calm empty list for an entity that exists and no row names", async () => {
|
|
151
|
+
expect(await widgetsBy("Idle")).toEqual([]);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it("refuses a value the noun's lookup cannot resolve, offering what a lookup miss offers", async () => {
|
|
155
|
+
await expect(widgetsBy(["Bolt", "Bolts"])).rejects.toMatchObject({
|
|
156
|
+
code: "INVALID_INPUT",
|
|
157
|
+
message: 'No maker is named "Bolts".',
|
|
158
|
+
suggestions: ["Bolt"],
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it("refuses an empty value as empty input", async () => {
|
|
163
|
+
await expect(widgetsBy("")).rejects.toMatchObject({
|
|
164
|
+
code: "INVALID_INPUT",
|
|
165
|
+
message: 'Invalid maker "(empty)".',
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it("is a configuration error when no story declares the noun", async () => {
|
|
170
|
+
const orphan = compilePack(
|
|
171
|
+
WIDGET,
|
|
172
|
+
distributionSource("test:links"),
|
|
173
|
+
PREFIXES,
|
|
174
|
+
)[0] as VerbSpec;
|
|
175
|
+
await expect(orphan.run({ maker: "Acme" }, rt)).rejects.toMatchObject({
|
|
176
|
+
code: "CONFIG_ERROR",
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
describe("a noun filter across the shipped and the project's stories", () => {
|
|
182
|
+
const shipped = (...stories: PackDefinition[]): CapabilityModule[] =>
|
|
183
|
+
stories.map((story) =>
|
|
184
|
+
compileStoryModule(
|
|
185
|
+
story,
|
|
186
|
+
distributionSource("test:shipped"),
|
|
187
|
+
PREFIXES,
|
|
188
|
+
(noun) => STORIES.get(noun)?.lookup,
|
|
189
|
+
),
|
|
190
|
+
);
|
|
191
|
+
const project = (stories: unknown[]): ConfigLayers =>
|
|
192
|
+
({
|
|
193
|
+
config: { stories, prefixes: PREFIXES },
|
|
194
|
+
origins: { packs: "default", stories: "project" },
|
|
195
|
+
}) as unknown as ConfigLayers;
|
|
196
|
+
const makerFilter = (modules: readonly CapabilityModule[], maker: string) =>
|
|
197
|
+
(
|
|
198
|
+
modules
|
|
199
|
+
.flatMap((module) => module.verbs)
|
|
200
|
+
.find((v) => verbKey(v.path) === "widget list") as VerbSpec
|
|
201
|
+
).run({ maker: [maker] }, rt) as Promise<PackPage>;
|
|
202
|
+
|
|
203
|
+
it("a project story resolves its filter through a shipped noun", async () => {
|
|
204
|
+
const modules = assembleEffectiveModules(shipped(MAKER), project([WIDGET]));
|
|
205
|
+
const page = await makerFilter(modules, "Bolt");
|
|
206
|
+
expect(page.rows.map((row) => row.name)).toEqual(["Slider"]);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it("a shipped filter resolves through the project's override of the noun it names", async () => {
|
|
210
|
+
const byCode = {
|
|
211
|
+
noun: "maker",
|
|
212
|
+
lookup: { by: "ex:code", type: "ex:Maker" },
|
|
213
|
+
};
|
|
214
|
+
const modules = assembleEffectiveModules(
|
|
215
|
+
shipped(MAKER, WIDGET),
|
|
216
|
+
project([byCode]),
|
|
217
|
+
);
|
|
218
|
+
const page = await makerFilter(modules, "A1");
|
|
219
|
+
expect(page.rows.map((row) => row.name)).toEqual(["Button"]);
|
|
220
|
+
await expect(makerFilter(modules, "Acme")).rejects.toMatchObject({
|
|
221
|
+
code: "INVALID_INPUT",
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it("refuses a story naming a noun no story declares, where it is assembled", () => {
|
|
226
|
+
expect(() => assembleEffectiveModules([], project([WIDGET]))).toThrow(
|
|
227
|
+
/Invalid story in config: "widget" names the noun "maker"/,
|
|
228
|
+
);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it("a project overriding a named noun with no lookup breaks only the filter, when used", async () => {
|
|
232
|
+
const listOnly = { noun: "maker", list: WIDGET.list };
|
|
233
|
+
const modules = assembleEffectiveModules(
|
|
234
|
+
shipped(MAKER, WIDGET),
|
|
235
|
+
project([listOnly]),
|
|
236
|
+
);
|
|
237
|
+
const widgets = modules
|
|
238
|
+
.flatMap((module) => module.verbs)
|
|
239
|
+
.find((v) => verbKey(v.path) === "widget list") as VerbSpec;
|
|
240
|
+
expect(((await widgets.run({}, rt)) as PackPage).rows).toHaveLength(3);
|
|
241
|
+
await expect(makerFilter(modules, "Bolt")).rejects.toMatchObject({
|
|
242
|
+
code: "CONFIG_ERROR",
|
|
243
|
+
message: expect.stringMatching(
|
|
244
|
+
/The "maker" story in config declares no lookup/,
|
|
245
|
+
),
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
it("a package story is screened against the assembled nouns, whatever the order", () => {
|
|
250
|
+
const entry = { source: "pkg/stories/widget.json", definition: WIDGET };
|
|
251
|
+
const withMaker = screenPackageStories(
|
|
252
|
+
assembleEffectiveModules([], project([MAKER]), [entry]),
|
|
253
|
+
);
|
|
254
|
+
expect(withMaker.modules.map((module) => module.name)).toContain("widget");
|
|
255
|
+
expect(withMaker.problems).toEqual([]);
|
|
256
|
+
|
|
257
|
+
const other = { noun: "gadget", lookup: MAKER.lookup };
|
|
258
|
+
const without = screenPackageStories(
|
|
259
|
+
assembleEffectiveModules([], project([other]), [entry]),
|
|
260
|
+
);
|
|
261
|
+
expect(without.modules.map((module) => module.name)).toEqual(["gadget"]);
|
|
262
|
+
expect(without.problems).toEqual([
|
|
263
|
+
{
|
|
264
|
+
source: "pkg/stories/widget.json",
|
|
265
|
+
message: 'it names the noun "maker", and no story declares it.',
|
|
266
|
+
},
|
|
267
|
+
]);
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
describe("a many expand field", () => {
|
|
272
|
+
it("is one cell per child holding every value, sorted", async () => {
|
|
273
|
+
const output = (await verb(MAKER, "lookup").run(
|
|
274
|
+
{ name: ["ex:acme"] },
|
|
275
|
+
rt,
|
|
276
|
+
)) as LookupOutput;
|
|
277
|
+
const widgets = output.results[0]?.widgets as { aliases?: string }[];
|
|
278
|
+
expect(widgets).toHaveLength(1);
|
|
279
|
+
expect(widgets[0]?.aliases).toBe("Btn btn push-button");
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
describe("a grouped expand", () => {
|
|
284
|
+
it("orders rows that tie on orderBy the same way on every store", async () => {
|
|
285
|
+
const labels: string[] = [];
|
|
286
|
+
for (let boot = 0; boot < 3; boot += 1) {
|
|
287
|
+
const fresh = await buildFixtureRuntime({ ttl: TTL, prefixes: PREFIXES });
|
|
288
|
+
const output = (await verb(MAKER, "lookup").run(
|
|
289
|
+
{ name: ["Bolt"] },
|
|
290
|
+
fresh.rt,
|
|
291
|
+
)) as LookupOutput;
|
|
292
|
+
const parts = output.results[0]?.parts as { label: string }[];
|
|
293
|
+
labels.push(parts.map((part) => part.label).join(""));
|
|
294
|
+
}
|
|
295
|
+
expect(labels).toEqual(["abcdef", "abcdef", "abcdef"]);
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
describe("the grammar", () => {
|
|
300
|
+
const withFilter = (filter: Record<string, unknown>): unknown => ({
|
|
301
|
+
...WIDGET,
|
|
302
|
+
list: { ...WIDGET.list, filters: [filter] },
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
it("accepts both stories as declared", () => {
|
|
306
|
+
expect(() => parsePackDefinition(MAKER, "test")).not.toThrow();
|
|
307
|
+
expect(() => parsePackDefinition(WIDGET, "test")).not.toThrow();
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
it.each([
|
|
311
|
+
[
|
|
312
|
+
"a noun filter with no entity",
|
|
313
|
+
{ param: "maker", variable: "maker", noun: "maker" },
|
|
314
|
+
/must declare the "entity"/,
|
|
315
|
+
],
|
|
316
|
+
[
|
|
317
|
+
"a noun filter with a vocabulary of its own",
|
|
318
|
+
{
|
|
319
|
+
param: "maker",
|
|
320
|
+
variable: "maker",
|
|
321
|
+
noun: "maker",
|
|
322
|
+
entity: "makerUri",
|
|
323
|
+
values: ["Acme"],
|
|
324
|
+
},
|
|
325
|
+
/mutually exclusive/,
|
|
326
|
+
],
|
|
327
|
+
[
|
|
328
|
+
"an entity the query does not project",
|
|
329
|
+
{ param: "maker", variable: "maker", noun: "maker", entity: "absent" },
|
|
330
|
+
/"absent" is filtered or searched but not projected/,
|
|
331
|
+
],
|
|
332
|
+
[
|
|
333
|
+
"an entity without a noun",
|
|
334
|
+
{
|
|
335
|
+
param: "maker",
|
|
336
|
+
variable: "maker",
|
|
337
|
+
values: ["Acme"],
|
|
338
|
+
entity: "makerUri",
|
|
339
|
+
},
|
|
340
|
+
/belong to a filter that names a "noun"/,
|
|
341
|
+
],
|
|
342
|
+
])("refuses %s", (_, filter, reason) => {
|
|
343
|
+
expect(() => parsePackDefinition(withFilter(filter), "test")).toThrow(
|
|
344
|
+
reason,
|
|
345
|
+
);
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
it.each([
|
|
349
|
+
[
|
|
350
|
+
"many with blankWhenSelf",
|
|
351
|
+
{ many: true, blankWhenSelf: true },
|
|
352
|
+
{},
|
|
353
|
+
/mutually exclusive/,
|
|
354
|
+
],
|
|
355
|
+
[
|
|
356
|
+
"many on the GraphQL lane",
|
|
357
|
+
{ many: true },
|
|
358
|
+
{ source: "graphql" },
|
|
359
|
+
/sets "many", which only the SPARQL lane/,
|
|
360
|
+
],
|
|
361
|
+
[
|
|
362
|
+
"ordering by a many field",
|
|
363
|
+
{ many: true },
|
|
364
|
+
{ orderBy: ["aliases"] },
|
|
365
|
+
/a "many" field/,
|
|
366
|
+
],
|
|
367
|
+
])("refuses %s", (_, field, expand, reason) => {
|
|
368
|
+
const lookup = MAKER.lookup as NonNullable<PackDefinition["lookup"]>;
|
|
369
|
+
const story = {
|
|
370
|
+
...MAKER,
|
|
371
|
+
lookup: {
|
|
372
|
+
...lookup,
|
|
373
|
+
...("source" in expand ? { source: "graphql" } : {}),
|
|
374
|
+
expand: [
|
|
375
|
+
{
|
|
376
|
+
...lookup.expand?.[0],
|
|
377
|
+
...("orderBy" in expand ? expand : {}),
|
|
378
|
+
select: [{ name: "aliases", property: "ex:alias", ...field }],
|
|
379
|
+
},
|
|
380
|
+
],
|
|
381
|
+
},
|
|
382
|
+
};
|
|
383
|
+
expect(() => parsePackDefinition(story, "test")).toThrow(reason);
|
|
384
|
+
});
|
|
385
|
+
});
|