@glossarist/concept-browser 0.7.64 → 0.7.66

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.64",
3
+ "version": "0.7.66",
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": {
@@ -31,7 +31,7 @@
31
31
  "autoprefixer": "^10.4.21",
32
32
  "d3": "^7.9.0",
33
33
  "favicons": "^7.2.0",
34
- "glossarist": "^0.4.10",
34
+ "glossarist": "^0.4.12",
35
35
  "js-yaml": "^4.1.0",
36
36
  "jszip": "^3.10.1",
37
37
  "pinia": "^2.3.1",
@@ -140,7 +140,7 @@ async function writeDatasetRdf(register, manifest, concepts, refMaps, opts) {
140
140
  fs.writeFileSync(path.join(DATA, register, `${register}.ttl`), ttl);
141
141
  }
142
142
 
143
- async function writeBuildActivity(conceptCount, datasetRegisters) {
143
+ async function writeBuildActivity(conceptCount, datasetRegisters, baseUri) {
144
144
  const runId = process.env.GITHUB_RUN_ID
145
145
  ? `${process.env.GITHUB_RUN_ID}-${process.env.GITHUB_RUN_ATTEMPT ?? '1'}`
146
146
  : `local-${new Date().toISOString().replace(/[:.]/g, '-')}`;
@@ -162,6 +162,7 @@ async function writeBuildActivity(conceptCount, datasetRegisters) {
162
162
  datasetRegisters,
163
163
  conceptCount,
164
164
  associatedAgentIri: agentIri,
165
+ baseUri,
165
166
  });
166
167
  const activityDir = path.join(DATA, 'activity');
167
168
  fs.mkdirSync(activityDir, { recursive: true });
@@ -1612,14 +1613,14 @@ for (const [id, count] of Object.entries(counts)) {
1612
1613
  console.log(` ${id}: ${count} concepts`);
1613
1614
  }
1614
1615
 
1615
- await writeBuildActivity(total, registry.map(r => r.id));
1616
+ await writeBuildActivity(total, registry.map(r => r.id), refMaps.uriBase);
1616
1617
 
1617
1618
  fs.writeFileSync(path.join(DATA, '_vocab.ttl'), await buildVocabularyTurtle());
1618
1619
  console.log('Emitted vocabulary graph: data/_vocab.ttl');
1619
1620
 
1620
1621
  const contributors = config.contributors ?? [];
1621
1622
  if (contributors.length > 0) {
1622
- fs.writeFileSync(path.join(DATA, 'agents.ttl'), await buildAgentsTurtle(contributors, refMaps.uriBase + '/agent'));
1623
+ fs.writeFileSync(path.join(DATA, 'agents.ttl'), await buildAgentsTurtle(contributors, refMaps.uriBase + '/agent', refMaps.uriBase + '/org'));
1623
1624
  console.log(`Emitted agents graph: data/agents.ttl (${contributors.length} contributors)`);
1624
1625
  }
1625
1626
 
@@ -19,9 +19,15 @@ function writerPrefixes() {
19
19
  };
20
20
  }
21
21
 
22
- export async function buildAgentsTurtle(contributors, agentBase) {
22
+ /**
23
+ * @param {Array} contributors
24
+ * @param {string} agentBase
25
+ * @param {string} orgBase
26
+ */
27
+ export async function buildAgentsTurtle(contributors, agentBase, orgBase) {
23
28
  if (!agentBase) throw new Error('buildAgentsTurtle requires agentBase');
29
+ if (!orgBase) throw new Error('buildAgentsTurtle requires orgBase');
24
30
  const agents = agentsFromContributors(contributors ?? [], agentBase);
25
- const quads = collectQuads(agentsToQuads(agents));
31
+ const quads = collectQuads(agentsToQuads(agents, { orgBase }));
26
32
  return writeTurtle(quads, { prefixes: writerPrefixes() });
27
33
  }
@@ -1,6 +1,8 @@
1
1
  import { describe, it, expect } from 'vitest';
2
2
  import { Parser, Store } from 'n3';
3
- import { buildAgentsTurtle } from '../../../scripts/lib/agents-turtle.mjs';
3
+ import { buildAgentsTurtle as _buildAgentsTurtle } from '../../../scripts/lib/agents-turtle.mjs';
4
+
5
+ const buildAgentsTurtle = _buildAgentsTurtle as unknown as (...args: any[]) => Promise<string>;
4
6
 
5
7
  function parse(turtle: string): Store {
6
8
  const parser = new Parser({ format: 'Turtle' });
@@ -16,13 +18,13 @@ const RDF_TYPE = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type';
16
18
 
17
19
  describe('buildAgentsTurtle (mjs)', () => {
18
20
  it('parses without errors', async () => {
19
- const ttl = await buildAgentsTurtle([{ name: 'Ada Lovelace' }], 'https://glossarist.org/agent');
21
+ const ttl = await buildAgentsTurtle([{ name: 'Ada Lovelace' }], 'https://glossarist.org/agent', 'https://glossarist.org/org');
20
22
  const store = parse(ttl);
21
23
  expect(store.size).toBeGreaterThan(0);
22
24
  });
23
25
 
24
26
  it('types each person as foaf:Person, prov:Person, prov:Agent', async () => {
25
- const ttl = await buildAgentsTurtle([{ name: 'Ada Lovelace' }], 'https://glossarist.org/agent');
27
+ const ttl = await buildAgentsTurtle([{ name: 'Ada Lovelace' }], 'https://glossarist.org/agent', 'https://glossarist.org/org');
26
28
  const store = parse(ttl);
27
29
  const types = store.getObjects('https://glossarist.org/agent/ada-lovelace', RDF_TYPE, null).map(q => q.value);
28
30
  expect(types).toContain(`${FOAF}Person`);
@@ -33,7 +35,7 @@ describe('buildAgentsTurtle (mjs)', () => {
33
35
  it('records name, mailto mbox, role, and seeAlso', async () => {
34
36
  const ttl = await buildAgentsTurtle([
35
37
  { name: 'Ada Lovelace', email: 'ada@example.org', role: 'Editor', url: 'https://example.org/ada' },
36
- ], 'https://glossarist.org/agent');
38
+ ], 'https://glossarist.org/agent', 'https://glossarist.org/org');
37
39
  const store = parse(ttl);
38
40
  const iri = 'https://glossarist.org/agent/ada-lovelace';
39
41
  expect(store.getObjects(iri, `${FOAF}name`, null).map(q => q.value)).toContain('Ada Lovelace');
@@ -46,7 +48,7 @@ describe('buildAgentsTurtle (mjs)', () => {
46
48
  const ttl = await buildAgentsTurtle([
47
49
  { name: 'Alice', organization: 'ISO' },
48
50
  { name: 'Bob', organization: 'ISO' },
49
- ], 'https://glossarist.org/agent');
51
+ ], 'https://glossarist.org/agent', 'https://glossarist.org/org');
50
52
  const store = parse(ttl);
51
53
  const types = store.getObjects('https://glossarist.org/org/iso', RDF_TYPE, null).map(q => q.value);
52
54
  expect(types).toContain(`${FOAF}Organization`);
@@ -54,8 +56,18 @@ describe('buildAgentsTurtle (mjs)', () => {
54
56
  });
55
57
 
56
58
  it('emits only prefix declarations for an empty input', async () => {
57
- const ttl = await buildAgentsTurtle([], 'https://glossarist.org/agent');
59
+ const ttl = await buildAgentsTurtle([], 'https://glossarist.org/agent', 'https://glossarist.org/org');
58
60
  expect(ttl).toContain('@prefix foaf:');
59
61
  expect(ttl).not.toContain('<https://glossarist.org/agent/');
60
62
  });
63
+
64
+ it('throws when agentBase is missing (no hardcoded default)', async () => {
65
+ await expect(buildAgentsTurtle([{ name: 'X' }])).rejects.toThrow('agentBase');
66
+ });
67
+
68
+ it('throws when orgBase is missing (no hardcoded default)', async () => {
69
+ await expect(
70
+ buildAgentsTurtle([{ name: 'X' }], 'https://example.org/agent'),
71
+ ).rejects.toThrow('orgBase');
72
+ });
61
73
  });
@@ -14,6 +14,7 @@ function makeInput(overrides: any = {}): any {
14
14
  datasetRegisters: ['iso-geodetic'],
15
15
  conceptCount: 1234,
16
16
  associatedAgentIri: 'https://glossarist.org/agent/ci-bot',
17
+ baseUri: 'https://glossarist.org',
17
18
  ...overrides,
18
19
  };
19
20
  }
@@ -72,4 +73,9 @@ describe('buildActivityTurtle (mjs)', () => {
72
73
  const agents = store.getObjects(ACTIVITY_IRI(input.runId), expand('prov:wasAssociatedWith'), null).map(q => q.value);
73
74
  expect(agents).toContain(input.associatedAgentIri);
74
75
  });
76
+
77
+ it('throws when baseUri is missing (no hardcoded default)', async () => {
78
+ const { baseUri, ...inputWithoutBaseUri } = makeInput();
79
+ await expect(buildActivityTurtle(inputWithoutBaseUri)).rejects.toThrow('baseUri');
80
+ });
75
81
  });
@@ -46,6 +46,7 @@ describe('WS F Layer 8 — build pipeline integration', () => {
46
46
  const out = runInline(`
47
47
  import { buildActivityTurtle } from './scripts/lib/build-activity-turtle.mjs';
48
48
  console.log(await buildActivityTurtle({
49
+ baseUri: 'https://glossarist.org',
49
50
  runId: 'test', startedAt: '2026-01-01T00:00:00Z', endedAt: '2026-01-01T00:05:00Z',
50
51
  toolId: 'cb', toolVersion: '0.7.52', datasetRegisters: [], conceptCount: 0,
51
52
  }));
@@ -61,7 +62,7 @@ describe('WS F Layer 8 — build pipeline integration', () => {
61
62
  it('agents-turtle.mjs produces parseable foaf:Person', () => {
62
63
  const out = runInline(`
63
64
  import { buildAgentsTurtle } from './scripts/lib/agents-turtle.mjs';
64
- console.log(await buildAgentsTurtle([{ name: 'Ada Lovelace', role: 'Editor', organization: 'Royal Society' }], 'https://glossarist.org/agent'));
65
+ console.log(await buildAgentsTurtle([{ name: 'Ada Lovelace', role: 'Editor', organization: 'Royal Society' }], 'https://glossarist.org/agent', 'https://glossarist.org/org'));
65
66
  `);
66
67
  const store = parseTurtle(out);
67
68
  const persons = [...store].filter(q =>
@@ -121,8 +122,8 @@ describe('WS F Layer 8 — build pipeline integration', () => {
121
122
  const parts = [
122
123
  await buildVocabularyTurtle(),
123
124
  await buildDatasetTurtle({ datasetIri: 'https://glossarist.org/test/', registerId: 'test', title: 't', modified: '2026-01-01', languages: ['eng'], distributions: [], topConceptUris: [], sections: [] }),
124
- await buildActivityTurtle({ runId: 'r', startedAt: '2026-01-01T00:00:00Z', endedAt: '2026-01-01T00:05:00Z', toolId: 'cb', toolVersion: '0', datasetRegisters: [], conceptCount: 0 }),
125
- await buildAgentsTurtle([{ name: 'Ada' }], 'https://glossarist.org/agent'),
125
+ await buildActivityTurtle({ baseUri: 'https://glossarist.org', runId: 'r', startedAt: '2026-01-01T00:00:00Z', endedAt: '2026-01-01T00:05:00Z', toolId: 'cb', toolVersion: '0', datasetRegisters: [], conceptCount: 0 }),
126
+ await buildAgentsTurtle([{ name: 'Ada' }], 'https://glossarist.org/agent', 'https://glossarist.org/org'),
126
127
  await buildBibliographyTurtle('test', { x: { reference: 'X' } }, 'https://glossarist.org'),
127
128
  await buildVersionHistoryTurtle({ registerId: 't', datasetIri: 'https://glossarist.org/t/', versions: [{ version: '1', generatedAt: '2026-01-01' }] }),
128
129
  ];