@manta-eu/cli 0.5.2 → 0.7.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 CHANGED
@@ -1,7 +1,8 @@
1
1
  # @manta-eu/cli
2
2
 
3
3
  The `manta` CLI keeps what a Manta datastore holds in line with files you track in git. It covers your app's
4
- vocabulary (the classes and properties your app adds to the knowledge graph) and the SHACL shapes for those classes.
4
+ vocabulary (the classes and properties your app adds to the knowledge graph), the SHACL shapes for those classes, and
5
+ the Datalog rules that derive new facts from them.
5
6
 
6
7
  Documentation: [developers.manta.eu](https://developers.manta.eu)
7
8
 
@@ -81,12 +82,35 @@ shapes pushed under the same `--name` are still in the datastore.
81
82
  The vocabulary push keeps the prefixes your file declares for your own namespace, so `manta-codegen` names your schemas
82
83
  after them (`todo.ts`). Declare your namespace with its prefix in the vocabulary before you push shapes for it.
83
84
 
85
+ ## Push your rules
86
+
87
+ Keep your Datalog rules in a `.dlog` file, each one named by a `# s:` line in your own namespace. Use only the
88
+ prefixes the realm's rules declare, and spell your own IRIs out in full: a realm deploy recommits your rules under the
89
+ realm's prefixes, so a prefix of your own would stop them.
90
+
91
+ ```datalog
92
+ # s: <https://todomvc.example/vocab#Rule_Done>
93
+ <https://todomvc.example/vocab#isDone>[?todo, true] :-
94
+ <https://todomvc.example/vocab#Todo>[?todo], <https://todomvc.example/vocab#completed>[?todo, true] .
95
+ ```
96
+
97
+ ```shell
98
+ pnpm manta rules push manta/rules.dlog --datastore your-datastore --name todomvc
99
+ ```
100
+
101
+ - **Committed, not only staged.** The push makes the file your app's whole live rule set in one transaction: new rules
102
+ are added, changed ones replaced, and the ones the file no longer holds removed. The datastore starts deriving at once.
103
+ - **Survives a deploy.** Your rules are owned by your app, and a realm deploy only replaces the realm's own.
104
+ - **Dry run.** `--dry-run` reports how many rules would be added, changed and removed, and commits nothing.
105
+
106
+ `manta rules delete` withdraws all of your app's rules.
107
+
84
108
  The command targets hiremanta.com production unless `--api-url`, `--keycloak-url` and `--keycloak-realm` name another
85
109
  deployment, as for `manta-codegen`.
86
110
 
87
111
  ## What the API checks
88
112
 
89
- The whole push is refused, and nothing is written, when the file:
113
+ The whole push is refused, and nothing is written, when a Turtle file:
90
114
 
91
115
  - is not valid Turtle, declares nothing, or is larger than 1 MiB;
92
116
  - declares a term outside `--namespace`, or names a namespace that overlaps one another app's vocabulary already
@@ -98,6 +122,11 @@ The whole push is refused, and nothing is written, when the file:
98
122
  A shapes file is also refused when it declares no `sh:NodeShape`, uses `sh:targetNode`, `sh:targetSubjectsOf` or
99
123
  `sh:targetObjectsOf`, or targets a class the realm's own shapes already cover.
100
124
 
125
+ A rules file is refused when a rule has no `# s:` name or shares one, uses a prefix the file does not declare, declares
126
+ a prefix the realm's rules do not, binds a prefix differently from the datastore's rules, is not valid Datalog, derives a predicate the platform protects or a
127
+ variable predicate, names an action the datastore cannot run, or takes a name in a namespace Manta owns or one
128
+ another owner already holds.
129
+
101
130
  `--name` is 1 to 64 lowercase letters, digits and dashes, and may not end in `ontology`, which marks the realm
102
131
  ontology. `--namespace` is an http(s) IRI ending in `#` or `/`, and may not overlap a namespace Manta already owns: the
103
132
  realm's own vocabulary, an integration's (such as `meta:` or `shopify:`), or RDF, RDFS, OWL, XSD, SHACL and the other
@@ -14,7 +14,19 @@ export type AppFileDeletion = {
14
14
  graphIri: string;
15
15
  deleted: boolean;
16
16
  };
17
- export type AppFileCollection = "vocabularies" | "shapes";
17
+ export type RulesPush = {
18
+ name: string;
19
+ graphIri: string;
20
+ owner: string;
21
+ added: number;
22
+ changed: number;
23
+ removed: number;
24
+ unchanged: number;
25
+ prefixesRebound: boolean;
26
+ written: boolean;
27
+ dryRun: boolean;
28
+ };
29
+ export type AppFileCollection = "vocabularies" | "shapes" | "rules";
18
30
  export type AppFileLocation = {
19
31
  apiUrl: string;
20
32
  datastore: string;
@@ -31,6 +43,11 @@ export declare function pushAppFile(target: AppFileTarget & {
31
43
  turtle: string;
32
44
  dryRun: boolean;
33
45
  }): Promise<AppFilePush>;
46
+ export declare function pushRules(target: Omit<AppFileTarget, "collection"> & {
47
+ text: string;
48
+ dryRun: boolean;
49
+ }): Promise<RulesPush>;
34
50
  export declare function deleteAppFile(target: AppFileTarget): Promise<AppFileDeletion>;
35
51
  export declare function describePush(push: AppFilePush): string;
52
+ export declare function describeRulesPush(push: RulesPush): string;
36
53
  //# sourceMappingURL=app-file.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-file.d.ts","sourceRoot":"","sources":["../src/app-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,SAAS,EAGd,KAAK,WAAW,EAEjB,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AAEnF,MAAM,MAAM,iBAAiB,GAAG,cAAc,GAAG,QAAQ,CAAC;AAE1D,MAAM,MAAM,eAAe,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,iBAAiB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjH,MAAM,MAAM,aAAa,GAAG,eAAe,GAAG;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,CAAA;CAAE,CAAC;AAE5F,wBAAgB,eAAe,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,eAAe,GAAG,MAAM,CAEhG;AAED,wBAAgB,WAAW,CACzB,MAAM,EAAE,aAAa,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAC9E,OAAO,CAAC,WAAW,CAAC,CAUtB;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC,CAE7E;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAStD"}
1
+ {"version":3,"file":"app-file.d.ts","sourceRoot":"","sources":["../src/app-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,SAAS,EAGd,KAAK,WAAW,EAEjB,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AAEnF,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,cAAc,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEpE,MAAM,MAAM,eAAe,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,iBAAiB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjH,MAAM,MAAM,aAAa,GAAG,eAAe,GAAG;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,CAAA;CAAE,CAAC;AAE5F,wBAAgB,eAAe,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,eAAe,GAAG,MAAM,CAEhG;AAED,wBAAgB,WAAW,CACzB,MAAM,EAAE,aAAa,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAC9E,OAAO,CAAC,WAAW,CAAC,CAEtB;AAED,wBAAgB,SAAS,CACvB,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAC5E,OAAO,CAAC,SAAS,CAAC,CAEpB;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC,CAE7E;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAStD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAWzD"}
package/dist/app-file.js CHANGED
@@ -3,16 +3,10 @@ export function appFileEndpoint({ apiUrl, datastore, collection, name }) {
3
3
  return `${apiUrl.replace(/\/$/, "")}/d/${encodeURIComponent(datastore)}/${collection}/${encodeURIComponent(name)}`;
4
4
  }
5
5
  export function pushAppFile(target) {
6
- const endpoint = new URL(appFileEndpoint(target));
7
- if (target.namespace !== undefined)
8
- endpoint.searchParams.set("namespace", target.namespace);
9
- if (target.dryRun)
10
- endpoint.searchParams.set("dryRun", "true");
11
- return send(target, endpoint.toString(), {
12
- method: "PUT",
13
- headers: { "content-type": "text/turtle" },
14
- body: target.turtle,
15
- });
6
+ return put(target, "text/turtle", target.turtle);
7
+ }
8
+ export function pushRules(target) {
9
+ return put({ ...target, collection: "rules" }, "application/x.datalog", target.text);
16
10
  }
17
11
  export function deleteAppFile(target) {
18
12
  return send(target, appFileEndpoint(target), { method: "DELETE", headers: {} });
@@ -27,6 +21,29 @@ export function describePush(push) {
27
21
  return `${push.name} would change: ${changes}${dryRun}`;
28
22
  return `updated ${push.name} in <${push.graphIri}>: ${changes}`;
29
23
  }
24
+ export function describeRulesPush(push) {
25
+ const dryRun = push.dryRun ? " (dry run, nothing committed)" : "";
26
+ const rebound = push.prefixesRebound ? ", prefixes rebound" : "";
27
+ const counts = `${push.added} added, ${push.changed} changed, ${push.removed} removed, ${push.unchanged} unchanged${rebound}`;
28
+ if (push.added + push.changed + push.removed === 0 && !push.prefixesRebound) {
29
+ return `${push.name}'s rules are already up to date${dryRun}`;
30
+ }
31
+ if (push.dryRun)
32
+ return `${push.name}'s rules would change: ${counts}${dryRun}`;
33
+ return `committed ${push.name}'s rules: ${counts}`;
34
+ }
35
+ function put(target, contentType, body) {
36
+ const endpoint = new URL(appFileEndpoint(target));
37
+ if (target.namespace !== undefined)
38
+ endpoint.searchParams.set("namespace", target.namespace);
39
+ if (target.dryRun)
40
+ endpoint.searchParams.set("dryRun", "true");
41
+ return send(target, endpoint.toString(), {
42
+ method: "PUT",
43
+ headers: { "content-type": contentType },
44
+ body,
45
+ });
46
+ }
30
47
  async function send({ token, fetchImpl = fetch }, endpoint, init) {
31
48
  return withRenewal(token, async (accessToken) => {
32
49
  let response;
@@ -1 +1 @@
1
- {"version":3,"file":"app-file.js","sourceRoot":"","sources":["../src/app-file.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EAEb,QAAQ,EACR,mBAAmB,EAEnB,WAAW,GACZ,MAAM,gBAAgB,CAAC;AAqBxB,MAAM,UAAU,eAAe,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAmB;IACtF,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,kBAAkB,CAAC,SAAS,CAAC,IAAI,UAAU,IAAI,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;AACrH,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,MAA+E;IAE/E,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;IAClD,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS;QAAE,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IAC7F,IAAI,MAAM,CAAC,MAAM;QAAE,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAE/D,OAAO,IAAI,CAAc,MAAM,EAAE,QAAQ,CAAC,QAAQ,EAAE,EAAE;QACpD,MAAM,EAAE,KAAK;QACb,OAAO,EAAE,EAAE,cAAc,EAAE,aAAa,EAAE;QAC1C,IAAI,EAAE,MAAM,CAAC,MAAM;KACpB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAqB;IACjD,OAAO,IAAI,CAAkB,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;AACnG,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAiB;IAC5C,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,gBAAgB,+BAA+B,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9G,MAAM,OAAO,GAAG,GAAG,IAAI,CAAC,KAAK,WAAW,IAAI,CAAC,OAAO,WAAW,UAAU,EAAE,CAAC;IAC5E,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,EAAE,CAAC;IAEhE,IAAI,CAAC,IAAI,CAAC,OAAO;QAAE,OAAO,GAAG,IAAI,CAAC,IAAI,yBAAyB,MAAM,EAAE,CAAC;IACxE,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,GAAG,IAAI,CAAC,IAAI,kBAAkB,OAAO,GAAG,MAAM,EAAE,CAAC;IAEzE,OAAO,WAAW,IAAI,CAAC,IAAI,QAAQ,IAAI,CAAC,QAAQ,MAAM,OAAO,EAAE,CAAC;AAClE,CAAC;AAED,KAAK,UAAU,IAAI,CACjB,EAAE,KAAK,EAAE,SAAS,GAAG,KAAK,EAAiB,EAC3C,QAAgB,EAChB,IAAuD;IAEvD,OAAO,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE;QAC9C,IAAI,QAAkB,CAAC;QAEvB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,SAAS,CAAC,QAAQ,EAAE;gBACnC,GAAG,IAAI;gBACP,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,aAAa,EAAE,UAAU,WAAW,EAAE,EAAE;aACrE,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,gBAAgB,QAAQ,KAAK,aAAa,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAClF,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAA0B,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAEzE,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,MAAM,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAEvE,MAAM,IAAI,mBAAmB,CAAC,GAAG,QAAQ,oBAAoB,QAAQ,CAAC,MAAM,GAAG,MAAM,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC5G,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"app-file.js","sourceRoot":"","sources":["../src/app-file.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { clientIdHelp, cliTokenSource, defaultDeployment, describeError, registerAuthCommands, } from "@manta-eu/auth";
3
3
  import { Command } from "commander";
4
4
  import { readFile } from "node:fs/promises";
5
- import { deleteAppFile, describePush, pushAppFile } from "./app-file.js";
5
+ import { deleteAppFile, describePush, describeRulesPush, pushAppFile, pushRules, } from "./app-file.js";
6
6
  const label = "manta";
7
7
  function withTargetOptions(command) {
8
8
  return command
@@ -36,24 +36,19 @@ async function run(action) {
36
36
  const program = new Command()
37
37
  .name(label)
38
38
  .description("Keep what a Manta datastore holds in line with files you track in git.");
39
- function registerAppFileCommands({ command, collection, description, noun, addPushOptions }) {
39
+ const pushTurtle = async (target, turtle, options) => describePush(await pushAppFile({ ...target, ...options, turtle }));
40
+ function registerAppFileCommands({ command, collection, description, noun, format, push, addPushOptions, }) {
40
41
  const group = program.command(command).description(description);
41
- const push = group
42
+ const pushCommand = group
42
43
  .command("push")
43
- .description(`make the datastore hold exactly the ${noun} the Turtle file declares`)
44
- .argument("<file>", `Turtle file with your app's ${noun}`)
44
+ .description(`make the datastore hold exactly the ${noun} the ${format} file declares`)
45
+ .argument("<file>", `${format} file with your app's ${noun}`)
45
46
  .option("--dry-run", "report what would change without writing it");
46
- addPushOptions?.(push);
47
- withTargetOptions(push).action((file, options) => run(async () => {
48
- const turtle = await readFile(file, "utf8");
49
- const pushed = await pushAppFile({
50
- ...targetFrom(collection, options),
51
- namespace: options.namespace,
52
- turtle,
53
- dryRun: options.dryRun === true,
54
- });
55
- return describePush(pushed);
56
- }));
47
+ addPushOptions?.(pushCommand);
48
+ withTargetOptions(pushCommand).action((file, options) => run(async () => push(targetFrom(collection, options), await readFile(file, "utf8"), {
49
+ namespace: options.namespace,
50
+ dryRun: options.dryRun === true,
51
+ })));
57
52
  withTargetOptions(group.command("delete").description(`remove your app's ${noun} from the datastore`)).action((options) => run(async () => {
58
53
  const deletion = await deleteAppFile(targetFrom(collection, options));
59
54
  return deletion.deleted ? `deleted ${deletion.name}` : `${deletion.name} was not in the datastore`;
@@ -64,6 +59,8 @@ registerAppFileCommands({
64
59
  collection: "vocabularies",
65
60
  description: "your app's vocabulary: its classes and properties",
66
61
  noun: "vocabulary",
62
+ format: "Turtle",
63
+ push: pushTurtle,
67
64
  addPushOptions: (push) => push.requiredOption("--namespace <iri>", "your app's namespace, ending in # or /: every term the file declares is under it"),
68
65
  });
69
66
  registerAppFileCommands({
@@ -71,6 +68,16 @@ registerAppFileCommands({
71
68
  collection: "shapes",
72
69
  description: "your app's SHACL shapes",
73
70
  noun: "shapes",
71
+ format: "Turtle",
72
+ push: pushTurtle,
73
+ });
74
+ registerAppFileCommands({
75
+ command: "rules",
76
+ collection: "rules",
77
+ description: "your app's Datalog rules, committed as one set",
78
+ noun: "rules",
79
+ format: "Datalog",
80
+ push: async (target, text, { dryRun }) => describeRulesPush(await pushRules({ ...target, text, dryRun })),
74
81
  });
75
82
  registerAuthCommands(program, { label });
76
83
  await program.parseAsync();
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { appFileEndpoint, deleteAppFile, describePush, pushAppFile, type AppFileCollection, type AppFileDeletion, type AppFileLocation, type AppFilePush, type AppFileTarget, } from "./app-file.js";
1
+ export { appFileEndpoint, deleteAppFile, describePush, describeRulesPush, pushAppFile, pushRules, type AppFileCollection, type AppFileDeletion, type AppFileLocation, type AppFilePush, type AppFileTarget, type RulesPush, } from "./app-file.js";
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,aAAa,EACb,YAAY,EACZ,WAAW,EACX,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,aAAa,GACnB,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,SAAS,EACT,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,SAAS,GACf,MAAM,eAAe,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { appFileEndpoint, deleteAppFile, describePush, pushAppFile, } from "./app-file.js";
1
+ export { appFileEndpoint, deleteAppFile, describePush, describeRulesPush, pushAppFile, pushRules, } from "./app-file.js";
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,aAAa,EACb,YAAY,EACZ,WAAW,GAMZ,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,SAAS,GAOV,MAAM,eAAe,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@manta-eu/cli",
3
- "version": "0.5.2",
4
- "description": "CLI that keeps what a Manta datastore holds in line with files you track in git: your app's vocabulary and shapes",
3
+ "version": "0.7.0",
4
+ "description": "CLI that keeps what a Manta datastore holds in line with files you track in git: your app's vocabulary, shapes and rules",
5
5
  "homepage": "https://developers.manta.eu",
6
6
  "keywords": [
7
7
  "manta",
@@ -19,26 +19,19 @@
19
19
  "import": "./dist/index.js"
20
20
  }
21
21
  },
22
- "scripts": {
23
- "build": "rimraf dist && tsc -p tsconfig.build.json",
24
- "test": "vitest --run",
25
- "types": "tsc --noEmit",
26
- "lint": "eslint .",
27
- "lint:fix": "eslint . --fix"
28
- },
29
22
  "author": "",
30
23
  "license": "MIT",
31
24
  "dependencies": {
32
- "@manta-eu/auth": "workspace:*",
33
- "commander": "catalog:"
25
+ "commander": "^15.0.0",
26
+ "@manta-eu/auth": "0.7.0"
34
27
  },
35
28
  "devDependencies": {
36
- "@manta-eu/eslint-config": "workspace:*",
37
- "@types/node": "catalog:",
38
- "eslint": "catalog:",
39
- "rimraf": "catalog:",
40
- "typescript": "catalog:",
41
- "vitest": "catalog:vitest"
29
+ "@types/node": "^24.13.3",
30
+ "eslint": "^9.39.2",
31
+ "rimraf": "^6.1.3",
32
+ "typescript": "^5.9.3",
33
+ "vitest": "^4.1.8",
34
+ "@manta-eu/eslint-config": "0.1.0"
42
35
  },
43
36
  "main": "./dist/index.js",
44
37
  "types": "./dist/index.d.ts",
@@ -52,5 +45,12 @@
52
45
  ],
53
46
  "publishConfig": {
54
47
  "access": "public"
48
+ },
49
+ "scripts": {
50
+ "build": "rimraf dist && tsc -p tsconfig.build.json",
51
+ "test": "vitest --run",
52
+ "types": "tsc --noEmit",
53
+ "lint": "eslint .",
54
+ "lint:fix": "eslint . --fix"
55
55
  }
56
- }
56
+ }
package/src/app-file.ts CHANGED
@@ -20,7 +20,20 @@ export type AppFilePush = {
20
20
 
21
21
  export type AppFileDeletion = { name: string; graphIri: string; deleted: boolean };
22
22
 
23
- export type AppFileCollection = "vocabularies" | "shapes";
23
+ export type RulesPush = {
24
+ name: string;
25
+ graphIri: string;
26
+ owner: string;
27
+ added: number;
28
+ changed: number;
29
+ removed: number;
30
+ unchanged: number;
31
+ prefixesRebound: boolean;
32
+ written: boolean;
33
+ dryRun: boolean;
34
+ };
35
+
36
+ export type AppFileCollection = "vocabularies" | "shapes" | "rules";
24
37
 
25
38
  export type AppFileLocation = { apiUrl: string; datastore: string; collection: AppFileCollection; name: string };
26
39
 
@@ -33,15 +46,13 @@ export function appFileEndpoint({ apiUrl, datastore, collection, name }: AppFile
33
46
  export function pushAppFile(
34
47
  target: AppFileTarget & { namespace?: string; turtle: string; dryRun: boolean },
35
48
  ): Promise<AppFilePush> {
36
- const endpoint = new URL(appFileEndpoint(target));
37
- if (target.namespace !== undefined) endpoint.searchParams.set("namespace", target.namespace);
38
- if (target.dryRun) endpoint.searchParams.set("dryRun", "true");
49
+ return put<AppFilePush>(target, "text/turtle", target.turtle);
50
+ }
39
51
 
40
- return send<AppFilePush>(target, endpoint.toString(), {
41
- method: "PUT",
42
- headers: { "content-type": "text/turtle" },
43
- body: target.turtle,
44
- });
52
+ export function pushRules(
53
+ target: Omit<AppFileTarget, "collection"> & { text: string; dryRun: boolean },
54
+ ): Promise<RulesPush> {
55
+ return put<RulesPush>({ ...target, collection: "rules" }, "application/x.datalog", target.text);
45
56
  }
46
57
 
47
58
  export function deleteAppFile(target: AppFileTarget): Promise<AppFileDeletion> {
@@ -59,6 +70,35 @@ export function describePush(push: AppFilePush): string {
59
70
  return `updated ${push.name} in <${push.graphIri}>: ${changes}`;
60
71
  }
61
72
 
73
+ export function describeRulesPush(push: RulesPush): string {
74
+ const dryRun = push.dryRun ? " (dry run, nothing committed)" : "";
75
+ const rebound = push.prefixesRebound ? ", prefixes rebound" : "";
76
+ const counts = `${push.added} added, ${push.changed} changed, ${push.removed} removed, ${push.unchanged} unchanged${rebound}`;
77
+
78
+ if (push.added + push.changed + push.removed === 0 && !push.prefixesRebound) {
79
+ return `${push.name}'s rules are already up to date${dryRun}`;
80
+ }
81
+ if (push.dryRun) return `${push.name}'s rules would change: ${counts}${dryRun}`;
82
+
83
+ return `committed ${push.name}'s rules: ${counts}`;
84
+ }
85
+
86
+ function put<T>(
87
+ target: AppFileTarget & { namespace?: string; dryRun: boolean },
88
+ contentType: string,
89
+ body: string,
90
+ ): Promise<T> {
91
+ const endpoint = new URL(appFileEndpoint(target));
92
+ if (target.namespace !== undefined) endpoint.searchParams.set("namespace", target.namespace);
93
+ if (target.dryRun) endpoint.searchParams.set("dryRun", "true");
94
+
95
+ return send<T>(target, endpoint.toString(), {
96
+ method: "PUT",
97
+ headers: { "content-type": contentType },
98
+ body,
99
+ });
100
+ }
101
+
62
102
  async function send<T>(
63
103
  { token, fetchImpl = fetch }: AppFileTarget,
64
104
  endpoint: string,
package/src/cli.ts CHANGED
@@ -9,7 +9,15 @@ import {
9
9
  } from "@manta-eu/auth";
10
10
  import { Command } from "commander";
11
11
  import { readFile } from "node:fs/promises";
12
- import { type AppFileCollection, type AppFileTarget, deleteAppFile, describePush, pushAppFile } from "./app-file.js";
12
+ import {
13
+ type AppFileCollection,
14
+ type AppFileTarget,
15
+ deleteAppFile,
16
+ describePush,
17
+ describeRulesPush,
18
+ pushAppFile,
19
+ pushRules,
20
+ } from "./app-file.js";
13
21
 
14
22
  const label = "manta";
15
23
 
@@ -50,35 +58,45 @@ const program = new Command()
50
58
  .name(label)
51
59
  .description("Keep what a Manta datastore holds in line with files you track in git.");
52
60
 
61
+ type AppFilePushOptions = { namespace?: string; dryRun: boolean };
62
+
53
63
  type AppFileCommand = {
54
64
  command: string;
55
65
  collection: AppFileCollection;
56
66
  description: string;
57
67
  noun: string;
68
+ format: string;
69
+ push: (target: AppFileTarget, text: string, options: AppFilePushOptions) => Promise<string>;
58
70
  addPushOptions?: (push: Command) => Command;
59
71
  };
60
72
 
61
- function registerAppFileCommands({ command, collection, description, noun, addPushOptions }: AppFileCommand): void {
73
+ const pushTurtle: AppFileCommand["push"] = async (target, turtle, options) =>
74
+ describePush(await pushAppFile({ ...target, ...options, turtle }));
75
+
76
+ function registerAppFileCommands({
77
+ command,
78
+ collection,
79
+ description,
80
+ noun,
81
+ format,
82
+ push,
83
+ addPushOptions,
84
+ }: AppFileCommand): void {
62
85
  const group = program.command(command).description(description);
63
- const push = group
86
+ const pushCommand = group
64
87
  .command("push")
65
- .description(`make the datastore hold exactly the ${noun} the Turtle file declares`)
66
- .argument("<file>", `Turtle file with your app's ${noun}`)
88
+ .description(`make the datastore hold exactly the ${noun} the ${format} file declares`)
89
+ .argument("<file>", `${format} file with your app's ${noun}`)
67
90
  .option("--dry-run", "report what would change without writing it");
68
- addPushOptions?.(push);
91
+ addPushOptions?.(pushCommand);
69
92
 
70
- withTargetOptions(push).action((file: string, options: TargetOptions & { namespace?: string; dryRun?: boolean }) =>
71
- run(async () => {
72
- const turtle = await readFile(file, "utf8");
73
- const pushed = await pushAppFile({
74
- ...targetFrom(collection, options),
93
+ withTargetOptions(pushCommand).action((file: string, options: TargetOptions & AppFilePushOptions) =>
94
+ run(async () =>
95
+ push(targetFrom(collection, options), await readFile(file, "utf8"), {
75
96
  namespace: options.namespace,
76
- turtle,
77
97
  dryRun: options.dryRun === true,
78
- });
79
-
80
- return describePush(pushed);
81
- }),
98
+ }),
99
+ ),
82
100
  );
83
101
 
84
102
  withTargetOptions(group.command("delete").description(`remove your app's ${noun} from the datastore`)).action(
@@ -96,6 +114,8 @@ registerAppFileCommands({
96
114
  collection: "vocabularies",
97
115
  description: "your app's vocabulary: its classes and properties",
98
116
  noun: "vocabulary",
117
+ format: "Turtle",
118
+ push: pushTurtle,
99
119
  addPushOptions: (push) =>
100
120
  push.requiredOption(
101
121
  "--namespace <iri>",
@@ -108,6 +128,17 @@ registerAppFileCommands({
108
128
  collection: "shapes",
109
129
  description: "your app's SHACL shapes",
110
130
  noun: "shapes",
131
+ format: "Turtle",
132
+ push: pushTurtle,
133
+ });
134
+
135
+ registerAppFileCommands({
136
+ command: "rules",
137
+ collection: "rules",
138
+ description: "your app's Datalog rules, committed as one set",
139
+ noun: "rules",
140
+ format: "Datalog",
141
+ push: async (target, text, { dryRun }) => describeRulesPush(await pushRules({ ...target, text, dryRun })),
111
142
  });
112
143
 
113
144
  registerAuthCommands(program, { label });
package/src/index.ts CHANGED
@@ -2,10 +2,13 @@ export {
2
2
  appFileEndpoint,
3
3
  deleteAppFile,
4
4
  describePush,
5
+ describeRulesPush,
5
6
  pushAppFile,
7
+ pushRules,
6
8
  type AppFileCollection,
7
9
  type AppFileDeletion,
8
10
  type AppFileLocation,
9
11
  type AppFilePush,
10
12
  type AppFileTarget,
13
+ type RulesPush,
11
14
  } from "./app-file.js";