@glossarist/concept-browser 0.7.45 → 0.7.47

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glossarist/concept-browser",
3
- "version": "0.7.45",
3
+ "version": "0.7.47",
4
4
  "description": "Vue SPA for browsing Glossarist terminology datasets with cross-reference resolution, graph visualization, and multi-language support",
5
5
  "type": "module",
6
6
  "bin": {
@@ -11,6 +11,9 @@
11
11
  "build": "vue-tsc --noEmit && vite build",
12
12
  "postbuild": "node scripts/generate-404.js",
13
13
  "preview": "vite preview",
14
+ "check:scripts": "node scripts/check-syntax.mjs",
15
+ "pretest": "node scripts/check-syntax.mjs",
16
+ "prebuild": "node scripts/check-syntax.mjs",
14
17
  "fetch-datasets": "node scripts/fetch-datasets.mjs",
15
18
  "generate-data": "node scripts/generate-data.mjs",
16
19
  "generate-ontology": "node scripts/generate-ontology-data.mjs && node scripts/generate-ontology-schema.mjs",
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env node
2
+ import { spawnSync } from "node:child_process";
3
+ import { readdirSync, statSync } from "node:fs";
4
+ import path from "node:path";
5
+ import process from "node:process";
6
+
7
+ const ROOT = path.resolve(path.dirname(new URL(import.meta.url).pathname), "..");
8
+
9
+ const TARGET_DIRS = ["scripts", "cli"];
10
+ const EXTENSIONS = new Set([".mjs", ".js", ".cjs"]);
11
+ const SKIP_DIRS = new Set(["__tests__", "node_modules"]);
12
+
13
+ function walk(dir) {
14
+ const out = [];
15
+ for (const entry of readdirSync(dir)) {
16
+ if (SKIP_DIRS.has(entry)) continue;
17
+ const full = path.join(dir, entry);
18
+ const st = statSync(full);
19
+ if (st.isDirectory()) {
20
+ out.push(...walk(full));
21
+ } else if (EXTENSIONS.has(path.extname(entry))) {
22
+ out.push(full);
23
+ }
24
+ }
25
+ return out;
26
+ }
27
+
28
+ export function checkAllScripts({ root = ROOT } = {}) {
29
+ const files = [];
30
+ for (const sub of TARGET_DIRS) {
31
+ const dir = path.join(root, sub);
32
+ try {
33
+ statSync(dir);
34
+ } catch {
35
+ continue;
36
+ }
37
+ files.push(...walk(dir));
38
+ }
39
+ files.sort();
40
+
41
+ const failures = [];
42
+ for (const file of files) {
43
+ const result = spawnSync(process.execPath, ["--check", file], {
44
+ encoding: "utf8",
45
+ });
46
+ if (result.status !== 0) {
47
+ failures.push({
48
+ file: path.relative(root, file),
49
+ stderr: result.stderr || "",
50
+ });
51
+ }
52
+ }
53
+
54
+ return { files, failures };
55
+ }
56
+
57
+ function main() {
58
+ const { files, failures } = checkAllScripts();
59
+ if (failures.length === 0) {
60
+ process.stdout.write(`syntax OK: ${files.length} file(s) checked\n`);
61
+ return;
62
+ }
63
+ process.stderr.write(
64
+ `syntax check failed: ${failures.length} of ${files.length} file(s)\n\n`,
65
+ );
66
+ for (const { file, stderr } of failures) {
67
+ process.stderr.write(`--- ${file} ---\n${stderr}\n`);
68
+ }
69
+ process.exit(1);
70
+ }
71
+
72
+ const isDirectEntry = process.argv[1] &&
73
+ path.resolve(process.argv[1]) ===
74
+ path.resolve(new URL(import.meta.url).pathname);
75
+
76
+ if (isDirectEntry) {
77
+ main();
78
+ }
@@ -783,7 +783,7 @@ ${bodyEntries}
783
783
  `;
784
784
  }
785
785
 
786
- function processDataset(dir, register, opts) {
786
+ async function processDataset(dir, register, opts) {
787
787
  const files = fs.readdirSync(dir).filter(f => f.endsWith('.yaml')).sort((a, b) => naturalSort(a.replace('.yaml', ''), b.replace('.yaml', '')));
788
788
 
789
789
  console.log(`Processing ${register}: ${files.length} files`);
@@ -1095,7 +1095,7 @@ for (let i = 0; i < config.datasets.length; i++) {
1095
1095
  // Resolve title: site-config override, then ref from register
1096
1096
  const resolvedTitle = ds.title || reg?.ref || ds.id;
1097
1097
 
1098
- counts[ds.id] = processDataset(dir, ds.id, {
1098
+ counts[ds.id] = await processDataset(dir, ds.id, {
1099
1099
  title: resolvedTitle,
1100
1100
  description: resolvedDescription,
1101
1101
  owner: ds.owner || reg?.owner,
@@ -0,0 +1,28 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { spawnSync } from 'node:child_process';
3
+ import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+
6
+ const repoRoot = path.resolve(
7
+ path.dirname(fileURLToPath(import.meta.url)),
8
+ '../..',
9
+ );
10
+
11
+ describe('scripts syntax gate', () => {
12
+ it('`npm run check:scripts` exits 0 (every .mjs/.js/.cjs in scripts/ and cli/ parses)', () => {
13
+ const result = spawnSync(
14
+ process.execPath,
15
+ [path.join(repoRoot, 'scripts', 'check-syntax.mjs')],
16
+ { encoding: 'utf8' },
17
+ );
18
+
19
+ if (result.status !== 0) {
20
+ throw new Error(
21
+ `check-syntax.mjs failed (exit ${result.status}):\n${result.stdout || ''}${result.stderr || ''}`,
22
+ );
23
+ }
24
+
25
+ expect(result.status).toBe(0);
26
+ expect(result.stdout).toMatch(/syntax OK:/);
27
+ });
28
+ });