@openuji/vocab-build 0.1.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.
@@ -0,0 +1,281 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>{{ title }}</title>
8
+ <style>
9
+ * {
10
+ margin: 0;
11
+ padding: 0;
12
+ box-sizing: border-box;
13
+ }
14
+
15
+ body {
16
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
17
+ line-height: 1.6;
18
+ color: #333;
19
+ max-width: 1200px;
20
+ margin: 0 auto;
21
+ padding: 2rem;
22
+ background: #f9f9f9;
23
+ }
24
+
25
+ header {
26
+ background: white;
27
+ padding: 2rem;
28
+ border-radius: 8px;
29
+ margin-bottom: 2rem;
30
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
31
+ }
32
+
33
+ h1 {
34
+ color: #2c3e50;
35
+ margin-bottom: 0.5rem;
36
+ font-size: 2rem;
37
+ }
38
+
39
+ .meta {
40
+ display: flex;
41
+ gap: 1rem;
42
+ margin-top: 1rem;
43
+ flex-wrap: wrap;
44
+ }
45
+
46
+ .badge {
47
+ display: inline-block;
48
+ padding: 0.25rem 0.75rem;
49
+ border-radius: 4px;
50
+ font-size: 0.875rem;
51
+ font-weight: 600;
52
+ }
53
+
54
+ .badge-tr {
55
+ background: #27ae60;
56
+ color: white;
57
+ }
58
+
59
+ .badge-ed {
60
+ background: #f39c12;
61
+ color: white;
62
+ }
63
+
64
+ .badge-deprecated {
65
+ background: #e74c3c;
66
+ color: white;
67
+ font-size: 0.75rem;
68
+ }
69
+
70
+ main {
71
+ background: white;
72
+ padding: 2rem;
73
+ border-radius: 8px;
74
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
75
+ }
76
+
77
+ section {
78
+ margin-bottom: 3rem;
79
+ }
80
+
81
+ h2 {
82
+ color: #2c3e50;
83
+ border-bottom: 2px solid #3498db;
84
+ padding-bottom: 0.5rem;
85
+ margin-bottom: 1.5rem;
86
+ }
87
+
88
+ table {
89
+ width: 100%;
90
+ border-collapse: collapse;
91
+ margin-top: 1rem;
92
+ }
93
+
94
+ th,
95
+ td {
96
+ text-align: left;
97
+ padding: 0.75rem;
98
+ border-bottom: 1px solid #e0e0e0;
99
+ }
100
+
101
+ th {
102
+ background: #f5f5f5;
103
+ font-weight: 600;
104
+ color: #2c3e50;
105
+ }
106
+
107
+ tr:hover {
108
+ background: #f9f9f9;
109
+ }
110
+
111
+ .term-id {
112
+ font-family: 'Courier New', monospace;
113
+ font-weight: 600;
114
+ color: #3498db;
115
+ }
116
+
117
+ .term-iri {
118
+ font-family: 'Courier New', monospace;
119
+ font-size: 0.875rem;
120
+ color: #7f8c8d;
121
+ margin-top: 0.25rem;
122
+ }
123
+
124
+ .copy-btn {
125
+ cursor: pointer;
126
+ color: #3498db;
127
+ font-size: 0.75rem;
128
+ margin-left: 0.5rem;
129
+ text-decoration: underline;
130
+ }
131
+
132
+ .copy-btn:hover {
133
+ color: #2980b9;
134
+ }
135
+
136
+ code {
137
+ background: #f5f5f5;
138
+ padding: 0.125rem 0.25rem;
139
+ border-radius: 3px;
140
+ font-family: 'Courier New', monospace;
141
+ font-size: 0.9em;
142
+ }
143
+
144
+ @media (max-width: 768px) {
145
+ body {
146
+ padding: 1rem;
147
+ }
148
+
149
+ table {
150
+ font-size: 0.875rem;
151
+ }
152
+
153
+ th,
154
+ td {
155
+ padding: 0.5rem;
156
+ }
157
+ }
158
+ </style>
159
+ </head>
160
+
161
+ <body>
162
+ <header>
163
+ <h1>{{ title }}</h1>
164
+ <p>{{ description }}</p>
165
+ <div class="meta">
166
+ {% if mode == 'TR' %}
167
+ <span class="badge badge-tr">Technical Report v{{ version }}</span>
168
+ {% else %}
169
+ <span class="badge badge-ed">Editor's Draft</span>
170
+ {% if updated %}
171
+ <span>Last Updated: {{ updated }}</span>
172
+ {% endif %}
173
+ {% endif %}
174
+ <span>Namespace: <code>{{ namespace }}</code></span>
175
+ </div>
176
+ </header>
177
+
178
+ <main>
179
+ {% if classes.length > 0 %}
180
+ <section id="classes">
181
+ <h2>Classes</h2>
182
+ <table>
183
+ <thead>
184
+ <tr>
185
+ <th>Term</th>
186
+ <th>Label</th>
187
+ <th>Description</th>
188
+ </tr>
189
+ </thead>
190
+ <tbody>
191
+ {% for term in classes %}
192
+ <tr id="{{ term.id }}">
193
+ <td>
194
+ <div class="term-id">{{ term.id }}</div>
195
+ <div class="term-iri">
196
+ {{ namespace }}{{ term.id }}
197
+ <span class="copy-btn"
198
+ onclick="copyToClipboard('{{ namespace }}{{ term.id }}')">copy</span>
199
+ </div>
200
+ {% if term.deprecated %}
201
+ <span class="badge badge-deprecated">DEPRECATED</span>
202
+ {% endif %}
203
+ </td>
204
+ <td>{{ term.label }}</td>
205
+ <td>
206
+ {{ term.comment }}
207
+ {% if term.seeAlso %}
208
+ <div style="margin-top: 0.5rem; font-size: 0.875rem;">
209
+ See also:
210
+ {% for url in term.seeAlso %}
211
+ <a href="{{ url }}" target="_blank">{{ url }}</a>{% if not loop.last %}, {% endif %}
212
+ {% endfor %}
213
+ </div>
214
+ {% endif %}
215
+ </td>
216
+ </tr>
217
+ {% endfor %}
218
+ </tbody>
219
+ </table>
220
+ </section>
221
+ {% endif %}
222
+
223
+ {% if properties.length > 0 %}
224
+ <section id="properties">
225
+ <h2>Properties</h2>
226
+ <table>
227
+ <thead>
228
+ <tr>
229
+ <th>Term</th>
230
+ <th>Label</th>
231
+ <th>Description</th>
232
+ <th>Domain</th>
233
+ <th>Range</th>
234
+ </tr>
235
+ </thead>
236
+ <tbody>
237
+ {% for term in properties %}
238
+ <tr id="{{ term.id }}">
239
+ <td>
240
+ <div class="term-id">{{ term.id }}</div>
241
+ <div class="term-iri">
242
+ {{ namespace }}{{ term.id }}
243
+ <span class="copy-btn"
244
+ onclick="copyToClipboard('{{ namespace }}{{ term.id }}')">copy</span>
245
+ </div>
246
+ {% if term.deprecated %}
247
+ <span class="badge badge-deprecated">DEPRECATED</span>
248
+ {% endif %}
249
+ </td>
250
+ <td>{{ term.label }}</td>
251
+ <td>
252
+ {{ term.comment }}
253
+ {% if term.seeAlso %}
254
+ <div style="margin-top: 0.5rem; font-size: 0.875rem;">
255
+ See also:
256
+ {% for url in term.seeAlso %}
257
+ <a href="{{ url }}" target="_blank">{{ url }}</a>{% if not loop.last %}, {% endif %}
258
+ {% endfor %}
259
+ </div>
260
+ {% endif %}
261
+ </td>
262
+ <td>{{ term.domain or '—' }}</td>
263
+ <td>{{ term.range or '—' }}</td>
264
+ </tr>
265
+ {% endfor %}
266
+ </tbody>
267
+ </table>
268
+ </section>
269
+ {% endif %}
270
+ </main>
271
+
272
+ <script>
273
+ function copyToClipboard(text) {
274
+ navigator.clipboard.writeText(text).then(() => {
275
+ alert('Copied: ' + text);
276
+ });
277
+ }
278
+ </script>
279
+ </body>
280
+
281
+ </html>
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@openuji/vocab-build",
3
+ "version": "0.1.0",
4
+ "description": "Generate publishable semantic web vocabulary assets from JSON-LD schema source files",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "vocab-build": "dist/cli.js"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "README.md"
20
+ ],
21
+ "keywords": [
22
+ "vocabulary",
23
+ "jsonld",
24
+ "rdf",
25
+ "turtle",
26
+ "semantic-web",
27
+ "ontology"
28
+ ],
29
+ "license": "MIT",
30
+ "dependencies": {
31
+ "commander": "^12.0.0",
32
+ "n3": "^1.17.0",
33
+ "nunjucks": "^3.2.4",
34
+ "prettier": "^3.1.0",
35
+ "zod": "^3.22.0"
36
+ },
37
+ "devDependencies": {
38
+ "@types/n3": "^1.26.1",
39
+ "@types/node": "^20.10.0",
40
+ "@types/nunjucks": "^3.2.6",
41
+ "typescript": "^5.3.0",
42
+ "vitest": "^1.0.0"
43
+ },
44
+ "scripts": {
45
+ "build": "tsc && npm run postbuild",
46
+ "postbuild": "cp -r src/templates dist/",
47
+ "dev": "tsc --watch",
48
+ "test": "vitest run",
49
+ "test:watch": "vitest",
50
+ "typecheck": "tsc --noEmit"
51
+ }
52
+ }