Skip to content

Commit 6d6b606

Browse files
authored
Merge pull request #157 from filip26/feat/v011
v1.0.0
2 parents 4dacd1a + 1c9ef30 commit 6d6b606

23 files changed

+942
-440
lines changed

README.md

Lines changed: 59 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
# Linked Data CLI
22

3-
A simple command-line utility designed to process JSON-LD, RDF, and CBOR-LD documents. Built with GraalVM, `ld-cli` delivers native executables for Ubuntu, macOS, and Windows - eliminating JVM dependencies and runtime overhead.
3+
A simple command-line utility designed to process JSON-LD, RDF, CBOR-LD, and multiformats documents.
4+
5+
Supports batch workflows, canonicalization, serialization, encoding, decoding, and format conversion for linked data resources, binary identifiers, and content addressing formats in knowledge graphs, decentralized identifiers (DIDs), and semantic web applications.
46

5-
It's ideal for batch workflows, automated validation, canonicalization, and serialization of linked data resources in knowledge graphs, decentralized identifiers (DIDs), and semantic web applications.
7+
Built with GraalVM, `ld-cli` delivers native executables for Ubuntu, macOS, and Windows - eliminating JVM dependencies.
68

79
## Features
810

911
* [W3C JSON-LD 1.1](https://www.w3.org/TR/json-ld/)
1012
* [W3C CBOR-LD 1.0](https://json-ld.github.io/cbor-ld-spec/)
1113
* [W3C Standard RDF Dataset Canonicalization Algorithm](https://www.w3.org/TR/rdf-canon/)
1214
* [RFC 8785 JSON Canonicalization Scheme (JCS)](https://www.rfc-editor.org/rfc/rfc8785)
15+
* [W3C CCG Multibase](https://github.com/w3c-ccg/multibase)
16+
* [Multicodec](https://github.com/multiformats/multicodec)
17+
* [Multihash](https://github.com/multiformats/multihash)
1318

1419
## Status
1520

@@ -29,7 +34,7 @@ sudo snap install ld-cli
2934

3035
### 📁 Manual Download
3136

32-
Download the latest release from the [GitHub Releases page](https://github.com/filip26/ld-cli/releases/).
37+
Download the latest release from the [GitHub Releases page](https://github.com/filip26/ld-cli/releases/). Click Assets to see the available downloads.
3338

3439
After downloading, extract the archive and make the binary executable:
3540

@@ -47,34 +52,40 @@ Usage: ld-cli [-hv] [COMMAND]
4752
Linked Data Command Line Processor
4853

4954
Options:
50-
-h, --help display help message
51-
-v, --version display a version
55+
-h, --help Display help message.
56+
-v, --version Display version information.
5257

5358
Commands:
54-
expand Expand JSON-LD document
55-
compact Compact JSON-LD document using the context
56-
flatten Flatten JSON-LD document and optionally compact using a context
57-
frame Frame JSON-LD document using the frame
58-
fromrdf Transform N-Quads document into a JSON-LD document in an expanded form
59-
tordf Transform JSON-LD document into N-Quads document
60-
compress Compress JSON-LD document into CBOR-LD
61-
decompress Decompress CBOR-LD document into JSON-LD
62-
rdfc Canonize an RDF N-Quads document with RDFC-1.0
63-
jcs Canonize a JSON document using the JSON Canonicalization Scheme (JCS)
59+
expand Expand a JSON-LD document.
60+
compact Compact a JSON-LD document using the provided context.
61+
flatten Flatten a JSON-LD document and optionally compact it using a
62+
context.
63+
frame Frame a JSON-LD document using the provided frame.
64+
fromrdf Transform an N-Quads document into a JSON-LD document in expanded
65+
form.
66+
tordf Transform a JSON-LD document into an RDF N-Quads document.
67+
compress Compress JSON-LD document into CBOR-LD.
68+
decompress Decompress CBOR-LD document into JSON-LD.
69+
rdfc Canonize an RDF N-Quads document using the RDFC-1.0 algorithm.
70+
jcs Canonize a JSON document using the JSON Canonicalization Scheme
71+
(JCS).
72+
multibase Encode, decode, detect, or list multibase encodings.
73+
multicodec Add, remove, detect, or list multicodec headers.
6474

6575
> ld-cli expand -h
66-
Usage: ld-cli expand [-op] [-b=<base>] [-c=<context>] [-i=<input>] [-m=1.0|1.1]
76+
Usage: ld-cli expand [-op] [--debug] [-b=<uri>] [-c=<uri>] [-i=<uri|file>]
77+
[-m=1.0|1.1]
6778

68-
Expand JSON-LD document
79+
Expand a JSON-LD document.
6980

7081
Options:
71-
-b, --base=<base> input document base IRI
72-
-c, --context=<context> context IRI
73-
-i, --input=<input> input document IRI
74-
-m, --mode=1.0|1.1 processing mode
75-
-o, --ordered certain algorithm processing steps are ordered
76-
lexicographically
77-
-p, --pretty pretty print output JSON
82+
-b, --base=<uri> Base URI of the input document.
83+
-c, --context=<uri> Context URI.
84+
--debug Print detailed error information.
85+
-i, --input=<uri|file> Input document URI or file path.
86+
-m, --mode=1.0|1.1 Processing mode.
87+
-o, --ordered Order certain algorithm steps lexicographically.
88+
-p, --pretty Pretty-print the output JSON.
7889

7990
```
8091

@@ -97,7 +108,27 @@ ld-cli compress -i file:/home/filip/example.jsonld
97108

98109
### Custom CBOR-LD dictionaries
99110
```bash
100-
ld-cli decompress --pretty --dictionary=./utopia-barcodes-dictionary-example.json <<< 'd90664a60183198000198001198002189d82187618a418b8a3189c18a618ce18b218d01ae592208118baa2189c18a018a8447582002018be18aa18c0a5189c186c18d60418e018e618e258417ab7c2e56b49e2cce62184ce26818e15a8b173164401b5d3bb93ffd6d2b5eb8f6ac0971502ae3dd49d17ec66528164034c912685b8111bc04cdc9ec13dbadd91cc18e418ac'
111+
ld-cli decompress --pretty --dictionary ./utopia-barcodes-dictionary-example.json <<< 'd90664a60183198000198001198002189d82187618a418b8a3189c18a618ce18b218d01ae592208118baa2189c18a018a8447582002018be18aa18c0a5189c186c18d60418e018e618e258417ab7c2e56b49e2cce62184ce26818e15a8b173164401b5d3bb93ffd6d2b5eb8f6ac0971502ae3dd49d17ec66528164034c912685b8111bc04cdc9ec13dbadd91cc18e418ac'
112+
```
113+
114+
### Multicodec
115+
```bash
116+
ld-cli multicodec --analyze --multibase <<< 'z6MkmM42vxfqZQsv4ehtTjFFxQ4sQKS2w6WR7emozFAn5cxu'
117+
```
118+
```bash
119+
Multibase: name=base58btc, prefix=z, length=58 chars
120+
Multicodec: name=ed25519-pub, code=237, varint=[0xED,0x01], tag=Key, status=Draft
121+
Length: 32 bytes
122+
```
123+
124+
### Multihash
125+
```bash
126+
ld-cli multicodec --analyze --multibase <<< 'MEiCcvAfD+ZFyWDajqipYHKICkZiqQgudmbwOEx2fPiy+Rw=='
127+
```
128+
```bash
129+
Multibase: name=base64pad, prefix=M, length=64 chars
130+
Multihash: name=sha2-256, code=18, varint=[0x12], tag=Multihash, status=Permanent
131+
Length: 32 bytes
101132
```
102133

103134
## Contributing
@@ -108,7 +139,7 @@ All PR's welcome!
108139

109140
1. [Install GraalVM and Native Image](https://www.graalvm.org/latest/docs/)
110141
- download and unpack ```graalvm-jdk-....tar.gz```
111-
- set ```JAVA_HOME``` and ```PATH``` env variables
142+
- set ```GRAALVM_HOME``` env variable
112143
3. ```mvn clean package -Pnative```
113144
4. ```./target/ld-cli```
114145

@@ -119,6 +150,8 @@ All PR's welcome!
119150
* [Titanium RDFC](https://github.com/filip26/titanium-rfc-canon)
120151
* [Titanium JCS](https://github.com/filip26/titanium-jcs)
121152
* [Iridium CBOR-LD](https://github.com/filip26/iridium-cbor-ld)
153+
* [Copper Multibase](https://github.com/filip26/copper-multibase)
154+
* [Copper Multicodec](https://github.com/filip26/copper-multicodec)
122155

123156
## Sponsors
124157

pom.xml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,17 @@
66
<modelVersion>4.0.0</modelVersion>
77
<groupId>com.apicatalog</groupId>
88
<artifactId>ld-cli</artifactId>
9-
<version>0.10.0</version>
9+
<version>1.0.0</version>
1010
<packaging>jar</packaging>
1111

1212
<name>A Command Line Processor for Linked Data Processing</name>
13+
14+
<description>
15+
Supports batch workflows, canonicalization, serialization, encoding,
16+
decoding, and format conversion for linked data resources, binary
17+
identifiers, and content addressing formats in knowledge graphs,
18+
decentralized identifiers (DIDs), and semantic web applications.
19+
</description>
1320

1421
<url>https://github.com/filip26/ld-cli</url>
1522

@@ -284,5 +291,4 @@
284291
</build>
285292
</profile>
286293
</profiles>
287-
288294
</project>

snapcraft.yaml

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,21 @@
11
name: ld-cli
22
title: Linked Data CLI
3-
version: 0.10.0
3+
version: 1.0.0
44
license: Apache-2.0
5-
summary: Command-line tool for JSON-LD, RDF, RDFC, JCS, and CBOR-LD processing
5+
summary: Command-line tool for JSON-LD, RDF, RDFC, JCS, CBOR-LD, semantic processing
66
description: |
7-
Linked Data CLI (`ld-cli`) is a command-line tool for processing and transforming linked data formats,
8-
including:
7+
Linked Data CLI (`ld-cli`) is a command-line tool for processing and transforming linked data formats, including:
98
109
• JSON-LD (JavaScript Object Notation for Linked Data)
1110
• RDF (Resource Description Framework)
1211
• RDFC (RDF Canonicalization)
1312
• JCS (JSON Canonicalization Scheme)
1413
• CBOR-LD (Concise Binary Object Representation for Linked Data)
15-
16-
Built with GraalVM, `ld-cli` provides native execution with zero JVM startup overhead.
17-
It's ideal for batch workflows, automated validation, canonicalization, and serialization of
18-
linked data resources in knowledge graphs, decentralized identifiers (DIDs), and semantic web applications.
19-
20-
This Snap includes a precompiled native executable built with GraalVM for optimal performance
21-
on modern Ubuntu systems.
22-
14+
• multibase (Base-encoding format with self-describing prefixes)
15+
• multicodec (Self-describing content type identifiers)
16+
17+
Supports batch workflows, canonicalization, serialization, encoding, decoding, and format conversion for linked data resources, binary identifiers, and content addressing formats in knowledge graphs, decentralized identifiers (DIDs), and semantic web applications.
18+
2319
source-code: https://github.com/filip26/ld-cli
2420
issues: https://github.com/filip26/ld-cli/issues
2521
contact: filip26@gmail.com
@@ -30,7 +26,7 @@ grade: stable
3026
parts:
3127
graalvm:
3228
plugin: nil
33-
source: https://download.oracle.com/graalvm/21/latest/graalvm-jdk-21_linux-x64_bin.tar.gz
29+
source: https://download.oracle.com/graalvm/24/latest/graalvm-jdk-24_linux-x64_bin.tar.gz
3430
build-packages:
3531
- wget
3632
- tar

src/main/java/com/apicatalog/cli/App.java

Lines changed: 47 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -8,73 +8,65 @@
88
import com.apicatalog.cli.command.FrameCmd;
99
import com.apicatalog.cli.command.FromRdfCmd;
1010
import com.apicatalog.cli.command.JcsCmd;
11+
import com.apicatalog.cli.command.MultibaseCmd;
12+
import com.apicatalog.cli.command.MulticodecCmd;
1113
import com.apicatalog.cli.command.RdfCanonCmd;
1214
import com.apicatalog.cli.command.ToRdfCmd;
1315
import com.apicatalog.jsonld.http.media.MediaType;
1416
import com.apicatalog.jsonld.loader.HttpLoader;
1517

1618
import picocli.CommandLine;
1719
import picocli.CommandLine.Command;
20+
import picocli.CommandLine.MissingParameterException;
1821
import picocli.CommandLine.Option;
1922
import picocli.CommandLine.ParseResult;
2023

21-
@Command(
22-
name = "ld-cli",
23-
description = "Linked Data Command Line Processor",
24-
subcommands = {
25-
ExpandCmd.class,
26-
CompactCmd.class,
27-
FlattenCmd.class,
28-
FrameCmd.class,
29-
FromRdfCmd.class,
30-
ToRdfCmd.class,
31-
CompressCmd.class,
32-
DecompressCmd.class,
33-
RdfCanonCmd.class,
34-
JcsCmd.class,
35-
},
36-
mixinStandardHelpOptions = false,
37-
descriptionHeading = "%n",
38-
parameterListHeading = "%nParameters:%n",
39-
optionListHeading = "%nOptions:%n",
40-
commandListHeading = "%nCommands:%n",
41-
version = {
42-
"ld-cli 0.10.0 https://github.com/filip26/ld-cli",
43-
"titanium-json-ld 1.6.0 https://github.com/filip26/titanium-json-ld",
44-
"titanium-rdfc 2.0.0 https://github.com/filip26/titanium-rdf-canon",
45-
"titanium-jcs 1.0.0 https://github.com/filip26/titanium-jcs",
46-
"iridium-cbor-ld 0.3.0 https://github.com/filip26/iridium-cbor-ld",
47-
}
48-
)
24+
@Command(name = "ld-cli", description = "Linked Data Command Line Processor", subcommands = {
25+
ExpandCmd.class,
26+
CompactCmd.class,
27+
FlattenCmd.class,
28+
FrameCmd.class,
29+
FromRdfCmd.class,
30+
ToRdfCmd.class,
31+
CompressCmd.class,
32+
DecompressCmd.class,
33+
RdfCanonCmd.class,
34+
JcsCmd.class,
35+
MultibaseCmd.class,
36+
MulticodecCmd.class,
37+
}, mixinStandardHelpOptions = false, descriptionHeading = "%n", parameterListHeading = "%nParameters:%n", optionListHeading = "%nOptions:%n", commandListHeading = "%nCommands:%n", version = {
38+
"ld-cli 0.11.0 https://github.com/filip26/ld-cli",
39+
"titanium-json-ld 1.6.0 https://github.com/filip26/titanium-json-ld",
40+
"titanium-rdfc 2.0.0 https://github.com/filip26/titanium-rdf-canon",
41+
"titanium-jcs 1.0.0 https://github.com/filip26/titanium-jcs",
42+
"iridium-cbor-ld 0.7.0 https://github.com/filip26/iridium-cbor-ld",
43+
"copper-multibase 4.0.0 https://github.com/filip26/copper-multibase",
44+
"copper-multicodec 2.1.0 https://github.com/filip26/copper-multicodec",
45+
})
4946
public final class App {
50-
51-
@Option(names = { "-h", "--help" }, usageHelp = true, description = "display help message")
47+
48+
@Option(names = { "-h", "--help" }, usageHelp = true, description = "Display help message.")
5249
boolean help = false;
5350

54-
@Option(names = {"-v", "--version"}, versionHelp = true, description = "display a version")
55-
boolean version;
51+
@Option(names = { "-v", "--version" }, versionHelp = true, description = "Display version information.")
52+
boolean version;
5653

5754
static {
5855
((HttpLoader) HttpLoader.defaultInstance()).fallbackContentType(MediaType.JSON);
5956
}
60-
57+
6158
public static void main(String[] args) {
6259

6360
final CommandLine cli = new CommandLine(new App());
6461
cli.setCaseInsensitiveEnumValuesAllowed(true);
62+
cli.setExecutionExceptionHandler(new ErrorHandler());
6563

6664
try {
6765

6866
final ParseResult result = cli.parseArgs(args);
6967

7068
if (cli.isUsageHelpRequested()) {
71-
72-
if (result.subcommand() != null) {
73-
result.subcommand().commandSpec().commandLine().usage(cli.getOut());
74-
return;
75-
}
76-
77-
cli.usage(cli.getOut());
69+
usage(cli, result);
7870
System.exit(cli.getCommandSpec().exitCodeOnUsageHelp());
7971
return;
8072
}
@@ -86,10 +78,24 @@ public static void main(String[] args) {
8678
}
8779

8880
System.exit(cli.execute(args));
81+
return;
82+
83+
} catch (MissingParameterException e) {
84+
cli.getErr().println(e.getMessage());
85+
e.getCommandLine().getCommandSpec().commandLine().usage(cli.getOut());
8986

9087
} catch (Exception ex) {
9188
cli.getErr().println(ex.getMessage());
92-
System.exit(cli.getCommandSpec().exitCodeOnExecutionException());
9389
}
90+
91+
System.exit(cli.getCommandSpec().exitCodeOnExecutionException());
9492
}
93+
94+
static final void usage(final CommandLine cli, final ParseResult result) {
95+
if (result.subcommand() != null) {
96+
result.subcommand().commandSpec().commandLine().usage(cli.getOut());
97+
return;
98+
}
99+
cli.usage(cli.getOut());
100+
}
95101
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.apicatalog.cli;
2+
3+
import com.apicatalog.cli.mixin.CommandOptions;
4+
5+
import picocli.CommandLine;
6+
import picocli.CommandLine.IExecutionExceptionHandler;
7+
import picocli.CommandLine.ParseResult;
8+
9+
public class ErrorHandler implements IExecutionExceptionHandler {
10+
@Override
11+
public int handleExecutionException(Exception ex,
12+
CommandLine cmd,
13+
ParseResult parseResult) {
14+
15+
cmd.getErr().println(ex.getMessage());
16+
17+
var options = ((CommandOptions) cmd.getMixins().get("options"));
18+
19+
if (options.debug) {
20+
ex.printStackTrace(cmd.getErr());
21+
}
22+
23+
return cmd.getCommandSpec().exitCodeOnExecutionException();
24+
}
25+
}

src/main/java/com/apicatalog/cli/JsonCborDictionary.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,15 @@ public static DocumentDictionary of(JsonObject json) {
4545
switch (item.getKey()) {
4646
case "code":
4747
continue;
48+
4849
case "context":
4950
item.getValue().asJsonObject().entrySet()
5051
.forEach(e -> builder.context(e.getKey(),
5152
((JsonNumber) e.getValue()).intValue()));
53+
case "uri":
54+
item.getValue().asJsonObject().entrySet()
55+
.forEach(e -> builder.uri(e.getKey(),
56+
((JsonNumber) e.getValue()).intValue()));
5257
default:
5358
item.getValue().asJsonObject().entrySet()
5459
.forEach(e -> builder.type(

0 commit comments

Comments
 (0)