@opencrs/cli 0.1.0 → 0.1.1
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 +212 -83
- package/npm-shrinkwrap.json +2 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,139 +1,268 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://opencrs.dev">
|
|
3
|
+
<picture>
|
|
4
|
+
<source media="(prefers-color-scheme: dark)" srcset=".github/assets/opencrs-mark-on-dark.svg">
|
|
5
|
+
<img src=".github/assets/opencrs-mark.svg" alt="OpenCRS" width="96" height="96">
|
|
6
|
+
</picture>
|
|
7
|
+
</a>
|
|
8
|
+
</p>
|
|
9
|
+
|
|
10
|
+
<h1 align="center">OpenCRS</h1>
|
|
11
|
+
|
|
12
|
+
<p align="center">
|
|
13
|
+
<b>Every screen, described once. Every creative, right first time.</b><br>
|
|
14
|
+
The Open Creative Requirements Specification: one machine-readable file, on a publisher's own domain,<br>
|
|
15
|
+
that says what creative needs in order to work on each of its digital screens.
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
<p align="center">
|
|
19
|
+
<a href="https://github.com/OpenCRS-Org/opencrs/releases/latest"><img alt="Release" src="https://img.shields.io/github/v/release/OpenCRS-Org/opencrs?color=5B4CF0&label=release"></a>
|
|
20
|
+
<a href="https://opencrs.dev/spec/0.1/"><img alt="Spec 0.1 draft" src="https://img.shields.io/badge/spec-0.1%20draft-5B4CF0"></a>
|
|
21
|
+
<a href="conformance/"><img alt="Conformance: Full, 47 of 47" src="https://img.shields.io/badge/conformance-Full%20%C2%B7%2047%2F47-2ea44f"></a>
|
|
22
|
+
<a href="https://github.com/OpenCRS-Org/opencrs/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/OpenCRS-Org/opencrs/actions/workflows/ci.yml/badge.svg"></a>
|
|
23
|
+
<br>
|
|
24
|
+
<a href="https://www.npmjs.com/package/@opencrs/cli"><img alt="npm" src="https://img.shields.io/npm/v/@opencrs/cli?logo=npm&label=npx%20%40opencrs%2Fcli&color=121216"></a>
|
|
25
|
+
<a href="https://github.com/OpenCRS-Org/homebrew-tap"><img alt="Homebrew" src="https://img.shields.io/badge/brew-opencrs--org%2Ftap-121216?logo=homebrew&logoColor=white"></a>
|
|
26
|
+
<a href="https://github.com/OpenCRS-Org/opencrs/pkgs/container/opencrs"><img alt="Container" src="https://img.shields.io/badge/ghcr.io-opencrs--org%2Fopencrs-121216?logo=docker&logoColor=white"></a>
|
|
27
|
+
<a href="https://pkg.go.dev/opencrs.dev/go"><img alt="Go reference" src="https://pkg.go.dev/badge/opencrs.dev/go.svg"></a>
|
|
28
|
+
<br>
|
|
29
|
+
<img alt="Rust 1.95" src="https://img.shields.io/badge/rust-1.95-121216?logo=rust&logoColor=white">
|
|
30
|
+
<img alt="WebAssembly" src="https://img.shields.io/badge/webassembly-zero%20imports-654FF0?logo=webassembly&logoColor=white">
|
|
31
|
+
<a href="LICENSE"><img alt="Code: Apache 2.0" src="https://img.shields.io/badge/code-Apache%202.0-blue"></a>
|
|
32
|
+
<a href="LICENSE-SPEC"><img alt="Spec: CC BY 4.0" src="https://img.shields.io/badge/spec-CC%20BY%204.0-blue"></a>
|
|
33
|
+
</p>
|
|
34
|
+
|
|
35
|
+
<p align="center">
|
|
36
|
+
<a href="https://opencrs.dev/spec/0.1/"><b>Read the spec</b></a> ·
|
|
37
|
+
<a href="https://opencrs.dev/check/"><b>Try the online checker</b></a> ·
|
|
38
|
+
<a href="https://opencrs.dev/examples/"><b>Example files</b></a> ·
|
|
39
|
+
<a href="https://github.com/OpenCRS-Org/opencrs/issues"><b>Comment on the draft</b></a>
|
|
40
|
+
</p>
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
A media owner's spec sheet is a PDF. Every agency, studio and tool reads it by eye, and creative still comes back wrong: the logo sits under the screen's own branding, the legal line is too small to read from the street, the video is two seconds too long. OpenCRS turns the spec sheet into data that a publisher hosts once and every tool can check against.
|
|
45
|
+
|
|
46
|
+
```mermaid
|
|
47
|
+
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#F1EFFE','primaryBorderColor':'#5B4CF0','primaryTextColor':'#121216','lineColor':'#6B6B76','clusterBkg':'#F7F7F4','clusterBorder':'#D9D9E0','edgeLabelBackground':'#FFFFFF','fontFamily':'Inter, system-ui, sans-serif'}}}%%
|
|
48
|
+
flowchart LR
|
|
49
|
+
subgraph P["Publisher (media owner)"]
|
|
50
|
+
direction TB
|
|
51
|
+
IDX["<b>index</b><br/>/.well-known/opencrs.json"]
|
|
52
|
+
SCR["<b>screens.json</b><br/>formats · screens · safe areas<br/>viewing distances · rules"]
|
|
53
|
+
IDX --> SCR
|
|
54
|
+
end
|
|
55
|
+
subgraph C["Creative (agency, studio, tool)"]
|
|
56
|
+
direction TB
|
|
57
|
+
MAN["<b>creative.json</b><br/>which file is for<br/>which format or screen"]
|
|
58
|
+
FILES["PNG · JPEG · MP4"]
|
|
59
|
+
MAN --> FILES
|
|
60
|
+
end
|
|
61
|
+
RP[("<b>rule packs</b><br/>state signage rules")]
|
|
62
|
+
V{{"opencrs check"}}
|
|
63
|
+
SCR -- "fetched and trusted<br/>by domain" --> V
|
|
64
|
+
MAN --> V
|
|
65
|
+
FILES -- "pixels, bytes, duration<br/>read from the file" --> V
|
|
66
|
+
RP --> V
|
|
67
|
+
V --> R["Report per file and screen<br/><b>pass · warn · fail</b>"]
|
|
68
|
+
|
|
69
|
+
classDef accent fill:#5B4CF0,stroke:#5B4CF0,color:#fff
|
|
70
|
+
class V accent
|
|
71
|
+
```
|
|
2
72
|
|
|
3
|
-
|
|
73
|
+
## See it
|
|
4
74
|
|
|
5
|
-
|
|
75
|
+
```console
|
|
76
|
+
$ opencrs check --spec retail.screens.json creative.json
|
|
77
|
+
lunch-portrait.png → harbourline.example/retail/portrait-totem-75: FAIL
|
|
78
|
+
warning CRS-LEGIBILITY Legal text is 18 px; 16 px minimum at 2 m, ratio 150. Passes with little margin [HC-L1-001]
|
|
79
|
+
warning CRS-LEGIBILITY Headline text is 92 px; 77 px minimum at 10 m, ratio 150. Passes with little margin [HC-L1-002]
|
|
80
|
+
error CRS-LEGIBILITY Legal text is 18 px; 23 px minimum at 3 m, ratio 150 [HC-L1-002]
|
|
6
81
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
| `conformance/` | The conformance suite: test cases any validator can run to show it meets Core, Layout or Full |
|
|
14
|
-
| `crates/opencrs-cli/` | The `opencrs` command-line tool |
|
|
15
|
-
| `crates/opencrs-wasm/` | The validator compiled to WebAssembly, for the online checker at [opencrs.dev/check](https://opencrs.dev/check/) |
|
|
16
|
-
| `bindings/` | Python and npm packages over the Rust library |
|
|
17
|
-
| `js/` | Loader, conformance adapter and smoke test for the WebAssembly build |
|
|
18
|
-
| `opencrs.go` | The Go package (`opencrs.dev/go`): the validator's WebAssembly build (`opencrs.wasm`, embedded) behind a Go API |
|
|
82
|
+
lunch-portrait-logo-right.png → harbourline.example/retail/screen/HC-L1-001: FAIL
|
|
83
|
+
error CRS-SAFE-AREA Logo extends into the safe-area margin (top 120 px)
|
|
84
|
+
error CRS-BLOCKED-REGION Logo overlaps the network-logo area
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The same file passes on one totem and fails on its twin, because the second is seen from further away. That is the point of describing screens the way people see them. Try these files in the [online checker](https://opencrs.dev/check/?example=harbourline); nothing is uploaded.
|
|
19
88
|
|
|
20
89
|
## Install
|
|
21
90
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
scoop install opencrs
|
|
26
|
-
npx @opencrs/cli --help
|
|
27
|
-
docker run --rm -v "$PWD:/work" ghcr.io/opencrs-org/opencrs --help
|
|
28
|
-
|
|
91
|
+
| Platform | Command |
|
|
92
|
+
| --- | --- |
|
|
93
|
+
| **macOS, Linux** | `brew install opencrs-org/tap/opencrs` (with the man page and shell completions) |
|
|
94
|
+
| **Windows** | `scoop bucket add opencrs https://github.com/OpenCRS-Org/scoop-bucket` then `scoop install opencrs` |
|
|
95
|
+
| **Node.js** | `npx @opencrs/cli --help` |
|
|
96
|
+
| **Container** | `docker run --rm -v "$PWD:/work" ghcr.io/opencrs-org/opencrs --help` |
|
|
97
|
+
| **Script** | `curl --proto '=https' --tlsv1.2 -LsSf https://github.com/OpenCRS-Org/opencrs/releases/latest/download/opencrs-cli-installer.sh \| sh` |
|
|
98
|
+
| **Go** | `go get opencrs.dev/go` |
|
|
99
|
+
| **Source** | `cargo build --release -p opencrs-cli` (a single binary, no runtime) |
|
|
29
100
|
|
|
30
|
-
|
|
101
|
+
Every [release](https://github.com/OpenCRS-Org/opencrs/releases) has archives for macOS, Linux (glibc and static musl) and Windows, on Intel and Arm, with checksums and build attestations: `gh attestation verify $(which opencrs) --repo OpenCRS-Org/opencrs`.
|
|
31
102
|
|
|
32
|
-
|
|
33
|
-
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/OpenCRS-Org/opencrs/releases/latest/download/opencrs-cli-installer.sh | sh
|
|
34
|
-
```
|
|
103
|
+
## Commands
|
|
35
104
|
|
|
36
|
-
|
|
105
|
+
| Command | What it does |
|
|
106
|
+
| --- | --- |
|
|
107
|
+
| `opencrs check --spec SCREENS CREATIVE` | Checks each file a `creative.json` lists against every screen it targets. Repeat `--spec` for several publishers; `--json` prints reports in the spec's format. |
|
|
108
|
+
| `opencrs schema FILE…` | Checks documents against the JSON Schemas, plus screens that name a missing format (`CRS-REFERENCE`) and rules inheritance has made impossible (`CRS-RULE-CONFLICT`). |
|
|
109
|
+
| `opencrs resolve SCREENS REF` | Shows what one format or screen requires after inheritance, with minimum text sizes in mm and px and the word limit. |
|
|
110
|
+
| `opencrs fetch DOMAIN` | Reads a publisher's index, fetches its documents, follows delegates, and says which to trust and why. `--output DIR` saves the trusted ones. |
|
|
111
|
+
| `opencrs conformance` | Runs the conformance suite against this validator, or against any other with `--cmd`. |
|
|
112
|
+
| `opencrs completion SHELL` | Prints completions for bash, zsh, fish or PowerShell. |
|
|
37
113
|
|
|
38
|
-
|
|
114
|
+
`opencrs COMMAND --help` has examples for each, and `man opencrs` has the lot. Exit status is 0 when everything passes, 1 when something fails, and 2 for a usage or read error.
|
|
39
115
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
```
|
|
116
|
+
<details>
|
|
117
|
+
<summary><b>What gets checked</b></summary>
|
|
43
118
|
|
|
44
|
-
|
|
119
|
+
<br>
|
|
45
120
|
|
|
46
|
-
|
|
121
|
+
The validator reads each file's type, pixel size, byte size and SHA-256 (and duration, for MP4) from the file itself. Values the manifest declares are used only when the file isn't there (`--no-files`).
|
|
47
122
|
|
|
48
|
-
|
|
123
|
+
| Level | A publisher provides | The validator checks | Cases |
|
|
124
|
+
| --- | --- | --- | --- |
|
|
125
|
+
| **Core** | Formats with `pixels` and `media`, screens, an index | `CRS-PIXELS` `CRS-MEDIA-TYPE` `CRS-FILE-SIZE` `CRS-DURATION` `CRS-SPEC-STALE` | 16 |
|
|
126
|
+
| **Layout** | Core, plus safe areas, blocked regions and segments | Core, plus `CRS-SAFE-AREA` `CRS-BLOCKED-REGION` | 4 |
|
|
127
|
+
| **Full** | Layout, plus physical size, viewing context and rules | Everything: `CRS-LEGIBILITY` `CRS-MAX-WORDS` `CRS-REQUIRED-ELEMENT` `CRS-CATEGORY` `CRS-MOTION` and the rule packs | 27 |
|
|
49
128
|
|
|
50
|
-
|
|
51
|
-
opencrs schema examples/harbourline/retail.screens.json examples/harbourline/creative.json
|
|
52
|
-
```
|
|
129
|
+
Not yet implemented: segment checks for composite surfaces, and audio, codec and colour-space checks.
|
|
53
130
|
|
|
54
|
-
|
|
131
|
+
</details>
|
|
55
132
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
```
|
|
133
|
+
<details>
|
|
134
|
+
<summary><b>Regulatory rule packs</b></summary>
|
|
59
135
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
136
|
+
<br>
|
|
137
|
+
|
|
138
|
+
Rule packs are built into the validator (and the browser build) from [`rulepacks/`](rulepacks/). A screen that lists one, such as `"rule_packs": ["au-nsw-transport-corridor@2017-11"]`, is checked against it with no extra flags.
|
|
139
|
+
|
|
140
|
+
- **Creative rules** give `CRS-MOTION-PROHIBITED`, `CRS-TRAFFIC-DEVICE`, `CRS-GLANCE-TEXT` and `CRS-SEQUENCING`.
|
|
141
|
+
- **`CRS-TRAFFIC-DEVICE` needs a person:** whether a file looks like a traffic sign is `not_checked` until the manifest attests that someone reviewed that exact file (by SHA-256). Then it's `info`, naming the reviewer, and the file can pass.
|
|
142
|
+
- **Playback rules** (dwell, transition, failure state, luminance, school zones) appear as `CRS-PLAYBACK` info lines for the screen's speed and lighting zone, and never fail creative.
|
|
143
|
+
- A pack the validator doesn't know is reported as `CRS-RULE-PACK`, not checked.
|
|
144
|
+
|
|
145
|
+
| Pack | Status |
|
|
146
|
+
| --- | --- |
|
|
147
|
+
| `au-nsw-transport-corridor@2017-11` | draft |
|
|
148
|
+
| `au-qld-tmr-roadside-advertising@2022-12` | draft |
|
|
149
|
+
| `au-sa-dit-advertising-signs@2014-08` | draft |
|
|
150
|
+
| `au-vic-dtp-illuminated-signage@2023-10` | draft |
|
|
151
|
+
| `au-wa-mrwa-digital-signs@2025-05` | draft |
|
|
152
|
+
| `au-tas-spp-signs-code@2024-06` | unverified, until amendments after its June 2024 edition are checked |
|
|
153
|
+
|
|
154
|
+
Each is checked against the state's own guidelines or planning rules, with page or section citations, and its `notes` say what it leaves out. The NT and the ACT have no territory-wide rule for digital signs, so they have no pack.
|
|
66
155
|
|
|
67
|
-
|
|
156
|
+
</details>
|
|
68
157
|
|
|
69
|
-
|
|
158
|
+
<details>
|
|
159
|
+
<summary><b>Fetching and trust</b></summary>
|
|
70
160
|
|
|
71
|
-
|
|
161
|
+
<br>
|
|
72
162
|
|
|
73
163
|
```sh
|
|
74
|
-
opencrs fetch harbourline.example
|
|
75
|
-
opencrs fetch https://specs.cms-a.example/harbourline/airports.screens.json # does its publisher vouch for this
|
|
76
|
-
opencrs fetch --token harbourline.example=TOKEN --output specs harbourline.example
|
|
164
|
+
opencrs fetch harbourline.example # the index, every document, delegates
|
|
165
|
+
opencrs fetch https://specs.cms-a.example/harbourline/airports.screens.json # does its publisher vouch for this URL?
|
|
166
|
+
opencrs fetch --token harbourline.example=TOKEN --output specs harbourline.example # partner documents too, saved
|
|
77
167
|
```
|
|
78
168
|
|
|
79
|
-
Each document is marked `trusted`, `expired`, `rejected`, `skipped` (a partner document without credentials) or `failed`, with the reason. `--output` saves trusted documents byte
|
|
169
|
+
Each document is marked `trusted`, `expired`, `rejected`, `skipped` (a partner document without credentials) or `failed`, with the reason. `--output` saves trusted documents byte for byte, ready for `opencrs check --spec`; with partner documents it also writes a `merged.screens.json` and lists any conflicts.
|
|
80
170
|
|
|
81
|
-
`fetch` refuses
|
|
171
|
+
`fetch` refuses loopback, private, link-local, CGNAT, multicast, documentation and other internal addresses, checked after DNS resolution and again on every redirect. `--allow-local-http` is the opt-in for testing an index on `localhost` before you deploy it. `fetch` connects directly and ignores `HTTP(S)_PROXY`. Each document is at most 50 MiB, an index may list at most 1,000 documents and 1,000 delegates, and one run reads at most 512 MiB.
|
|
82
172
|
|
|
83
|
-
|
|
173
|
+
</details>
|
|
84
174
|
|
|
85
|
-
|
|
175
|
+
## One validator, everywhere
|
|
86
176
|
|
|
87
|
-
|
|
88
|
-
|
|
177
|
+
The checks are written once, in Rust, and every other way of running them uses that same code.
|
|
178
|
+
|
|
179
|
+
```mermaid
|
|
180
|
+
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#F1EFFE','primaryBorderColor':'#5B4CF0','primaryTextColor':'#121216','lineColor':'#6B6B76','clusterBkg':'#F7F7F4','clusterBorder':'#D9D9E0','edgeLabelBackground':'#FFFFFF','fontFamily':'Inter, system-ui, sans-serif'}}}%%
|
|
181
|
+
flowchart TB
|
|
182
|
+
CORE["<b>crates/opencrs</b><br/>schemas · inheritance<br/>file probing · checks<br/>reports · trust"]
|
|
183
|
+
CORE --> CLI["<b>opencrs</b> CLI<br/><i>crates/opencrs-cli</i>"]
|
|
184
|
+
CORE --> WASM["<b>opencrs.wasm</b><br/><i>crates/opencrs-wasm</i>"]
|
|
185
|
+
CORE --> NPM["npm binding<br/><i>bindings/npm</i>"]
|
|
186
|
+
CORE --> PY["Python binding<br/><i>bindings/python</i>"]
|
|
187
|
+
WASM --> WEB["Online checker<br/><i>opencrs.dev/check</i>"]
|
|
188
|
+
WASM --> GO["Go package<br/><i>opencrs.dev/go</i>"]
|
|
189
|
+
WASM --> JS["JS loader<br/><i>js/</i>"]
|
|
190
|
+
CLI --> CH["Homebrew · Scoop · npm<br/>container · installers"]
|
|
191
|
+
|
|
192
|
+
classDef accent fill:#5B4CF0,stroke:#5B4CF0,color:#fff
|
|
193
|
+
class CORE accent
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
**From Go**, the validator's WebAssembly build is embedded and run with [wazero](https://wazero.io), so there's no cgo:
|
|
197
|
+
|
|
198
|
+
```go
|
|
199
|
+
import opencrs "opencrs.dev/go"
|
|
200
|
+
|
|
201
|
+
root, err := os.OpenRoot("campaign")
|
|
202
|
+
if err != nil { /* … */ }
|
|
203
|
+
res, err := opencrs.CheckDir(root.FS(), []string{"retail.screens.json"}, "creative.json", time.Now())
|
|
204
|
+
if err != nil { /* … */ }
|
|
205
|
+
for _, r := range res.Reports {
|
|
206
|
+
fmt.Println(r.File, r.Target, r.Result) // pass, warn, fail or incomplete
|
|
207
|
+
}
|
|
89
208
|
```
|
|
90
209
|
|
|
91
|
-
|
|
210
|
+
**In the browser**, the [online checker](https://opencrs.dev/check/) runs the same module, so creative files never leave the machine. The npm (`@opencrs/opencrs`) and Python (`opencrs`) bindings are built and tested here, and not yet published.
|
|
92
211
|
|
|
93
|
-
|
|
212
|
+
## What's here
|
|
94
213
|
|
|
95
|
-
|
|
214
|
+
| Path | What's in it |
|
|
215
|
+
| --- | --- |
|
|
216
|
+
| [`OpenCRS 0.1 Specification.md`](OpenCRS%200.1%20Specification.md) | The specification |
|
|
217
|
+
| [`schema/0.1/`](schema/0.1/) | JSON Schemas (Draft 2020-12) for `index`, `screens`, `creative`, `report` and `rule-pack`, served at their `$id` on opencrs.dev |
|
|
218
|
+
| [`examples/`](examples/) | The spec's complete Harbourline example, verbatim, with the reports the validator writes, and starter files |
|
|
219
|
+
| [`conformance/`](conformance/) | 47 cases any validator can run to show it meets Core, Layout or Full ([how to write an adapter](conformance/README.md)) |
|
|
220
|
+
| [`rulepacks/`](rulepacks/) | Regulatory rule packs, embedded in the validator |
|
|
221
|
+
| [`crates/`](crates/) | The Rust library, CLI and WebAssembly module |
|
|
222
|
+
| [`bindings/`](bindings/) | npm and Python packages over the Rust library |
|
|
223
|
+
| [`opencrs.go`](opencrs.go) | The Go package |
|
|
96
224
|
|
|
97
|
-
|
|
225
|
+
## Development
|
|
98
226
|
|
|
99
227
|
```sh
|
|
100
|
-
|
|
101
|
-
|
|
228
|
+
cargo test --workspace # the Rust library and CLI
|
|
229
|
+
go test -race . # the Go package
|
|
230
|
+
cargo xtask generate # after changing the command line: man page and completions
|
|
102
231
|
```
|
|
103
232
|
|
|
104
|
-
|
|
233
|
+
The tests use the spec's own numbers as acceptance criteria: the worked legibility example (46 px and 16 px), text just below a minimum failing rather than rounding up to pass, restrictions a lower level can't loosen, the 8-word limit from a 4-second dwell, larger text on the further totem, and every JSON example in the spec passing its schema.
|
|
105
234
|
|
|
106
|
-
|
|
235
|
+
<details>
|
|
236
|
+
<summary><b>Building the WebAssembly module</b></summary>
|
|
107
237
|
|
|
108
|
-
|
|
238
|
+
<br>
|
|
109
239
|
|
|
110
240
|
```sh
|
|
111
241
|
scripts/build-wasm.sh /tmp/wasm # needs binaryen's wasm-opt; writes opencrs.wasm and opencrs.js
|
|
112
242
|
node js/smoke.mjs /tmp/wasm # the module must behave like the CLI
|
|
113
243
|
```
|
|
114
244
|
|
|
115
|
-
The committed `opencrs.wasm`
|
|
245
|
+
The committed `opencrs.wasm` is what the Go package embeds. rustc's output differs between hosts, so it's built in a pinned linux/amd64 container (Rust 1.95.0, binaryen 133) with `scripts/build-wasm-docker.sh OUT_DIR`, and CI rebuilds it there and compares byte for byte. Build on your own machine to test; commit the container's build.
|
|
116
246
|
|
|
117
|
-
|
|
247
|
+
</details>
|
|
118
248
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
go test -race . # the Go package
|
|
122
|
-
```
|
|
249
|
+
<details>
|
|
250
|
+
<summary><b>Checking a creative package from someone else</b></summary>
|
|
123
251
|
|
|
124
|
-
|
|
252
|
+
<br>
|
|
125
253
|
|
|
126
|
-
|
|
254
|
+
Every host (the CLI, the npm and Python bindings, and the Go package's `CheckDir`) reads only the files the manifest names, refuses names with `..` or an absolute path, follows symlinks only while they stay inside the package directory, and probes only regular files. In Go, pass `root.FS()` from `os.OpenRoot(dir)` rather than `os.DirFS(dir)`, so the opens themselves are confined too.
|
|
127
255
|
|
|
128
|
-
|
|
256
|
+
Two limits remain. A hard link inside the package can't be told from an ordinary file, so unpack untrusted archives without hard links (most extractors have an option, and Linux's `protected_hardlinks` blocks links to other users' files). And a concurrent writer to the directory could swap in a symlink between the check and the open, so check a copy no one else can write to.
|
|
257
|
+
|
|
258
|
+
</details>
|
|
129
259
|
|
|
130
|
-
|
|
131
|
-
- **Everything else**, including the JSON Schemas, examples and code: [Apache 2.0](LICENSE).
|
|
260
|
+
The validator was first written in Go. The [differential tests](crates/opencrs-cli/tests/differential/README.md) compare this CLI with that version, output for output.
|
|
132
261
|
|
|
133
|
-
|
|
262
|
+
## Contributing
|
|
134
263
|
|
|
135
|
-
|
|
264
|
+
OpenCRS is a draft, and it gets better with real spec sheets and real creative. [Open an issue](https://github.com/OpenCRS-Org/opencrs/issues) with what doesn't fit, or see [CONTRIBUTING.md](CONTRIBUTING.md) for proposals and pull requests. Commits are signed off under the [Developer Certificate of Origin](DCO). To report a security problem, see [SECURITY.md](SECURITY.md).
|
|
136
265
|
|
|
137
|
-
|
|
266
|
+
## Licence
|
|
138
267
|
|
|
139
|
-
|
|
268
|
+
The specification is [CC BY 4.0](LICENSE-SPEC). Everything else, including the JSON Schemas, examples and code, is [Apache 2.0](LICENSE). Anyone can implement OpenCRS, including competitors, as the spec's governance section intends.
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"hasInstallScript": true,
|
|
20
20
|
"license": "Apache-2.0",
|
|
21
21
|
"name": "@opencrs/cli",
|
|
22
|
-
"version": "0.1.
|
|
22
|
+
"version": "0.1.1"
|
|
23
23
|
},
|
|
24
24
|
"node_modules/detect-libc": {
|
|
25
25
|
"engines": {
|
|
@@ -48,5 +48,5 @@
|
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
50
|
"requires": true,
|
|
51
|
-
"version": "0.1.
|
|
51
|
+
"version": "0.1.1"
|
|
52
52
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"artifactDownloadUrls": [
|
|
3
|
-
"https://github.com/OpenCRS-Org/opencrs/releases/download/v0.1.
|
|
3
|
+
"https://github.com/OpenCRS-Org/opencrs/releases/download/v0.1.1"
|
|
4
4
|
],
|
|
5
5
|
"bin": {
|
|
6
6
|
"opencrs": "run-opencrs.js"
|
|
@@ -122,7 +122,7 @@
|
|
|
122
122
|
"zipExt": ".tar.xz"
|
|
123
123
|
}
|
|
124
124
|
},
|
|
125
|
-
"version": "0.1.
|
|
125
|
+
"version": "0.1.1",
|
|
126
126
|
"volta": {
|
|
127
127
|
"node": "18.14.1",
|
|
128
128
|
"npm": "9.5.0"
|