spec-up-t 1.6.2 → 1.6.3

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.
Files changed (40) hide show
  1. package/.github/copilot-instructions.md +2 -0
  2. package/README.md +1 -0
  3. package/assets/compiled/body.js +10 -7
  4. package/assets/compiled/head.css +6 -5
  5. package/assets/css/adjust-font-size.css +0 -4
  6. package/assets/css/download-pdf-docx.css +19 -20
  7. package/assets/css/header-navbar.css +0 -4
  8. package/assets/css/index.css +36 -0
  9. package/assets/css/terms-and-definitions.css +0 -1
  10. package/assets/css/validate-external-refs.css +564 -0
  11. package/assets/js/add-href-to-snapshot-link.js +11 -5
  12. package/assets/js/download-pdf-docx.js +20 -9
  13. package/assets/js/edit-term-buttons.js +71 -68
  14. package/assets/js/github-issues.js +27 -27
  15. package/assets/js/insert-irefs.js +1 -1
  16. package/assets/js/validate-external-refs.js +1113 -0
  17. package/assets/js/validate-external-refs.test.js +577 -0
  18. package/config/asset-map.json +2 -0
  19. package/package.json +3 -3
  20. package/src/add-remove-xref-source.js +0 -5
  21. package/src/collect-external-references.test.js +98 -0
  22. package/src/install-from-boilerplate/boilerplate/gitignore +2 -2
  23. package/src/install-from-boilerplate/boilerplate/menu-wrapper.sh +19 -0
  24. package/src/install-from-boilerplate/boilerplate/spec/terms-definitions/composability.md +4 -2
  25. package/src/install-from-boilerplate/boilerplate/spec/terms-definitions/dormancy.md +5 -0
  26. package/src/install-from-boilerplate/boilerplate/spec/terms-definitions/greenhouse.md +5 -0
  27. package/src/install-from-boilerplate/boilerplate/spec/terms-definitions/soil.md +4 -2
  28. package/src/install-from-boilerplate/boilerplate/specs.json +7 -22
  29. package/src/install-from-boilerplate/config-scripts-keys.js +1 -1
  30. package/src/install-from-boilerplate/config-system-files.js +1 -0
  31. package/src/pipeline/references/collect-external-references.js +12 -0
  32. package/src/pipeline/references/external-references-service.js +12 -4
  33. package/src/pipeline/rendering/render-spec-document.js +5 -1
  34. package/templates/template.html +43 -10
  35. package/src/health-check/destination-gitignore-checker.js +0 -414
  36. package/src/health-check/external-specs-checker.js +0 -287
  37. package/src/health-check/specs-configuration-checker.js +0 -387
  38. package/src/health-check/term-references-checker.js +0 -270
  39. package/src/health-check/terms-intro-checker.js +0 -82
  40. package/src/health-check/tref-term-checker.js +0 -549
@@ -155,6 +155,104 @@ That's all about these references.`,
155
155
  });
156
156
  });
157
157
 
158
+ describe('Cleanup of deleted files from sourceFiles array', () => {
159
+
160
+ // Test: Are deleted files removed from sourceFiles arrays?
161
+ it('should remove deleted files from sourceFiles array when files no longer exist', () => {
162
+ // Setup: Create an allXTrefs structure with multiple source files
163
+ const allXTrefs = {
164
+ xtrefs: [
165
+ {
166
+ externalSpec: 'ExtRef1',
167
+ term: 'greenhouse',
168
+ trefAliases: [],
169
+ xrefAliases: [],
170
+ sourceFiles: [
171
+ { file: 'composability.md', type: 'tref' },
172
+ { file: 'greenhouse.md', type: 'tref' },
173
+ { file: 'soil.md', type: 'xref' }
174
+ ]
175
+ },
176
+ {
177
+ externalSpec: 'ExtRef2',
178
+ term: 'propagation',
179
+ trefAliases: [],
180
+ xrefAliases: [],
181
+ sourceFiles: [
182
+ { file: 'composability.md', type: 'xref' },
183
+ { file: 'greenhouse.md', type: 'xref' },
184
+ { file: 'soil.md', type: 'xref' }
185
+ ]
186
+ }
187
+ ]
188
+ };
189
+
190
+ // Simulate: composability.md has been deleted
191
+ const fileContents = new Map([
192
+ ['greenhouse.md', '[[tref:ExtRef1,greenhouse]] [[xref:ExtRef2,propagation]]'],
193
+ ['soil.md', '[[xref:ExtRef1,greenhouse]] [[xref:ExtRef2,propagation]]']
194
+ ]);
195
+
196
+ // Filter out xtrefs that don't exist in any file (none should be removed)
197
+ allXTrefs.xtrefs = allXTrefs.xtrefs.filter(xtref =>
198
+ require('./pipeline/references/xtref-utils').isXTrefInAnyFile(xtref, fileContents)
199
+ );
200
+
201
+ // Clean up sourceFiles arrays to remove deleted files
202
+ allXTrefs.xtrefs.forEach(xtref => {
203
+ if (xtref.sourceFiles && Array.isArray(xtref.sourceFiles)) {
204
+ const currentFiles = Array.from(fileContents.keys());
205
+ xtref.sourceFiles = xtref.sourceFiles.filter(sf =>
206
+ currentFiles.includes(sf.file)
207
+ );
208
+ }
209
+ });
210
+
211
+ // Verify: composability.md should be removed from all sourceFiles arrays
212
+ expect(allXTrefs.xtrefs.length).toBe(2);
213
+
214
+ expect(allXTrefs.xtrefs[0].sourceFiles).toEqual([
215
+ { file: 'greenhouse.md', type: 'tref' },
216
+ { file: 'soil.md', type: 'xref' }
217
+ ]);
218
+
219
+ expect(allXTrefs.xtrefs[1].sourceFiles).toEqual([
220
+ { file: 'greenhouse.md', type: 'xref' },
221
+ { file: 'soil.md', type: 'xref' }
222
+ ]);
223
+ });
224
+
225
+ it('should handle case where all files are deleted for a term', () => {
226
+ // Setup: Create a term with only one source file
227
+ const allXTrefs = {
228
+ xtrefs: [
229
+ {
230
+ externalSpec: 'ExtRef1',
231
+ term: 'orphan-term',
232
+ trefAliases: [],
233
+ xrefAliases: [],
234
+ sourceFiles: [
235
+ { file: 'deleted-file.md', type: 'tref' }
236
+ ]
237
+ }
238
+ ]
239
+ };
240
+
241
+ // Simulate: All files deleted
242
+ const fileContents = new Map([
243
+ ['other-file.md', 'Some content without the orphan term']
244
+ ]);
245
+
246
+ // Filter out xtrefs that don't exist in any file
247
+ allXTrefs.xtrefs = allXTrefs.xtrefs.filter(xtref =>
248
+ require('./pipeline/references/xtref-utils').isXTrefInAnyFile(xtref, fileContents)
249
+ );
250
+
251
+ // This xtref should be completely removed since it doesn't exist in any file
252
+ expect(allXTrefs.xtrefs.length).toBe(0);
253
+ });
254
+ });
255
+
158
256
 
159
257
  // Tests for extracting and collecting external references from markdown
160
258
  describe('addNewXTrefsFromMarkdown', () => {
@@ -1,4 +1,4 @@
1
- node_modules
1
+ node_modules/
2
2
  *.log
3
3
  dist
4
4
  *.bak
@@ -7,5 +7,5 @@ dist
7
7
  .env
8
8
  coverage
9
9
  build
10
- .history
10
+ .history/
11
11
  /.cache/
@@ -0,0 +1,19 @@
1
+ #!/bin/bash
2
+
3
+ # This wrapper script checks if node_modules exists before attempting to run the menu
4
+ # This ensures users get a helpful error message if they forgot to run npm install
5
+
6
+ if [ ! -d "node_modules" ]; then
7
+ echo -e "\n⚠️ ERROR: node_modules directory not found."
8
+ echo -e " Please run 'npm install' first to install dependencies.\n"
9
+ exit 1
10
+ fi
11
+
12
+ if [ ! -d "node_modules/spec-up-t" ]; then
13
+ echo -e "\n⚠️ ERROR: spec-up-t package not found in node_modules."
14
+ echo -e " Please run 'npm install' to install dependencies.\n"
15
+ exit 1
16
+ fi
17
+
18
+ # Run the actual menu script
19
+ bash ./node_modules/spec-up-t/src/install-from-boilerplate/menu.sh "$@"
@@ -1,3 +1,5 @@
1
- [[tref: KERISuite, composability ]]
1
+ [[tref: ExtRef1, greenhouse]]
2
2
 
3
- ~ Note: composability is not the same as compostability.
3
+ ~ Note: This is a tref example. The term "greenhouse" is imported from the ExtRef1 external glossary (focused on greenhouse and irrigation concepts).
4
+
5
+ ~ See also: [[xref: ExtRef2, propagation]] for plant propagation from ExtRef2.
@@ -0,0 +1,5 @@
1
+ [[tref: ExtRef2, dormancy]]
2
+
3
+ ~ Note: This is a tref example. The term "dormancy" is imported from the ExtRef2 external glossary (focused on plant lifecycle and propagation concepts).
4
+
5
+ ~ See also: [[xref: ExtRef1, perennial]] for perennial plants from ExtRef1.
@@ -0,0 +1,5 @@
1
+ [[tref: ExtRef1, greenhouse]]
2
+
3
+ ~ Note: This is a tref example. The term "greenhouse" is imported from the ExtRef1 external glossary (focused on greenhouse and irrigation concepts).
4
+
5
+ ~ See also: [[xref: ExtRef2, propagation]] for plant propagation from ExtRef2.
@@ -4,8 +4,10 @@
4
4
 
5
5
  ~ Refs examples: [[ref: Compost]], [[ref: Mulch]], [[ref: Fertilizer]].
6
6
 
7
- ~ Xref example: [[xref: KERISuite, composability ]]
7
+ ~ Xref examples from external gardening glossaries:
8
+ ~ - From ExtRef1 (greenhouse focus): [[xref: ExtRef1, greenhouse]], [[xref: ExtRef1, irrigation]]
9
+ ~ - From ExtRef2 (lifecycle focus): [[xref: ExtRef2, dormancy]], [[xref: ExtRef2, propagation]]
8
10
 
9
- ~ This Xref example does not work: [[xref: does-not-exist, Foo]]
11
+ ~ Note: The term "soil" exists in ExtRef1 and ExtRef2 with different definitions focused on their respective themes.
10
12
 
11
13
  ~ Soil quality affects water retention, nutrient availability, and plant health. Amending soil with compost or mulch can improve its structure and fertility. Fertilizer may be added to supplement nutrients as needed.
@@ -19,33 +19,18 @@
19
19
  "source": {
20
20
  "host": "github",
21
21
  "account": "trustoverip",
22
- "repo": "spec-up-t-starter-pack",
23
- "branch": "main"
22
+ "repo": "spec-up-t-starter-pack"
24
23
  },
25
24
  "external_specs": [
26
25
  {
27
- "external_spec": "vLEI",
28
- "gh_page": "https://henkvancann.github.io/vlei-glossary/",
29
- "url": "https://github.com/henkvancann/vlei-glossary",
30
- "terms_dir": "spec/terms-definitions"
26
+ "external_spec": "ExtRef1",
27
+ "gh_page": "https://trustoverip.github.io/spec-up-t-demo-external-ref-1/",
28
+ "url": "https://github.com/trustoverip/spec-up-t-demo-external-ref-1"
31
29
  },
32
30
  {
33
- "external_spec": "KERISuite",
34
- "gh_page": "https://weboftrust.github.io/kerisuite-glossary/",
35
- "url": "https://github.com/weboftrust/kerisuite-glossary",
36
- "terms_dir": "spec/terms-definitions"
37
- },
38
- {
39
- "external_spec": "ToIP",
40
- "gh_page": "https://glossary.trustoverip.org/",
41
- "url": "https://github.com/trustoverip/ctwg-main-glossary",
42
- "terms_dir": "spec/terms-definitions"
43
- },
44
- {
45
- "external_spec": "GenIT",
46
- "gh_page": "https://trustoverip.github.io/ctwg-general-glossary/",
47
- "url": "https://github.com/trustoverip/ctwg-general-glossary",
48
- "terms_dir": "spec/terms-definitions"
31
+ "external_spec": "ExtRef2",
32
+ "gh_page": "https://trustoverip.github.io/spec-up-t-demo-external-ref-2/",
33
+ "url": "https://github.com/trustoverip/spec-up-t-demo-external-ref-2"
49
34
  }
50
35
  ],
51
36
  "katex": false,
@@ -8,7 +8,7 @@ const configScriptsKeys = {
8
8
  "freeze": "node -e \"require('spec-up-t/src/freeze-spec-data.js')\"",
9
9
  "references": "node -e \"require('spec-up-t/src/pipeline/references/external-references-service.js')\"",
10
10
  "help": "cat ./node_modules/spec-up-t/src/install-from-boilerplate/help.txt",
11
- "menu": "bash ./node_modules/spec-up-t/src/install-from-boilerplate/menu.sh",
11
+ "menu": "bash ./menu-wrapper.sh",
12
12
  "addremovexrefsource": "node --no-warnings -e \"require('spec-up-t/src/add-remove-xref-source.js')\"",
13
13
  "configure": "node --no-warnings -e \"require('spec-up-t/src/configure.js')\"",
14
14
  "healthCheck": "node --no-warnings ./node_modules/spec-up-t/src/health-check.js",
@@ -1,6 +1,7 @@
1
1
  const systemFiles = [
2
2
  'README.md',
3
3
  '.env.example',
4
+ 'menu-wrapper.sh',
4
5
  '.github/workflows/menu.yml',
5
6
  '.github/workflows/set-gh-pages.yml',
6
7
  'assets/test.json',
@@ -253,10 +253,22 @@ function processExternalReferences(config, GITHUB_API_TOKEN) {
253
253
  });
254
254
  });
255
255
 
256
+ // Filter out xtrefs that don't exist in any current file
256
257
  allXTrefs.xtrefs = allXTrefs.xtrefs.filter(existingXTref =>
257
258
  isXTrefInAnyFile(existingXTref, fileContents)
258
259
  );
259
260
 
261
+ // Clean up sourceFiles arrays to remove deleted files
262
+ // This ensures that if a file is deleted, its entry is removed from all sourceFiles arrays
263
+ allXTrefs.xtrefs.forEach(xtref => {
264
+ if (xtref.sourceFiles && Array.isArray(xtref.sourceFiles)) {
265
+ const currentFiles = Array.from(fileContents.keys());
266
+ xtref.sourceFiles = xtref.sourceFiles.filter(sf =>
267
+ currentFiles.includes(sf.file)
268
+ );
269
+ }
270
+ });
271
+
260
272
  fileContents.forEach((content, filename) => {
261
273
  addNewXTrefsFromMarkdown(content, allXTrefs, filename, processXTrefObject, externalSpecsRepos);
262
274
  });
@@ -19,7 +19,7 @@ function validateReferences(references, definitions, render) {
19
19
  if (unresolvedRefs.length > 0) {
20
20
  Logger.warn(`Unresolved References: ${unresolvedRefs.join(',')}`, {
21
21
  context: 'These terms are referenced in your spec but not defined',
22
- hint: 'Add [[def: term]] definitions for these terms in your terminology files, or check for typos in [[ref: term]] references',
22
+ hint: 'Add [[def: term]] definitions or [[tref: repo, term]] transclusion for these terms or alter existing definitions, optionally by adding aliases, in your terminology files, or check for typos in [[ref: term]] references',
23
23
  details: `Count: ${unresolvedRefs.length} unresolved term(s)`
24
24
  });
25
25
  }
@@ -281,10 +281,18 @@ function extractTermsFromHtml(externalSpec, html) {
281
281
  const classArray = dtClasses ? dtClasses.split(/\s+/).filter(Boolean) : [];
282
282
  const termClasses = classArray.filter(cls => cls === 'term-local' || cls === 'term-external');
283
283
 
284
- const dd = $termElement.next('dd');
284
+ // Extract ALL consecutive <dd> elements following this <dt>
285
+ // Terms can have multiple <dd> blocks for extended definitions
286
+ const ddElements = [];
287
+ let nextElement = $termElement.next();
288
+ while (nextElement.length > 0 && nextElement[0].tagName === 'dd') {
289
+ ddElements.push(nextElement);
290
+ nextElement = nextElement.next();
291
+ }
285
292
 
286
- if (dd.length > 0) {
287
- const ddContent = $.html(dd); // Store the complete DD content once
293
+ if (ddElements.length > 0) {
294
+ // Combine all <dd> elements into a single HTML string
295
+ const ddContent = ddElements.map(dd => $.html(dd)).join('\n'); // Store the complete DD content
288
296
 
289
297
  // Create a term object for each ID found in this dt element
290
298
  // This handles cases where one term definition has multiple aliases
@@ -10,7 +10,7 @@ const path = require('path');
10
10
  const { fetchExternalSpecs, validateReferences, mergeXrefTermsIntoAllXTrefs } = require('../references/external-references-service.js');
11
11
  const { processEscapedTags, restoreEscapedTags } = require('../preprocessing/escape-placeholder-utils.js');
12
12
  const { sortDefinitionTermsInHtml, fixDefinitionListStructure } = require('../postprocessing/definition-list-postprocessor.js');
13
- const { getGithubRepoInfo } = require('../../utils/git-info.js');
13
+ const { getGithubRepoInfo, getCurrentBranch } = require('../../utils/git-info.js');
14
14
  const { templateTags } = require('../../utils/regex-patterns.js');
15
15
 
16
16
  const { createScriptElementWithXTrefDataForEmbeddingInHtml, applyReplacers } = require('./render-utils.js');
@@ -37,6 +37,9 @@ async function render(spec, assets, sharedVars, config, template, assetsGlobal,
37
37
  // Add universal timestamp in ISO 8601 format for template injection
38
38
  const universalTimestamp = date.toISOString();
39
39
 
40
+ // Get the branch name from which the index.html was generated
41
+ const buildBranch = getCurrentBranch();
42
+
40
43
  // Read all markdown files into an array
41
44
  const docs = await Promise.all(
42
45
  (spec.markdown_paths || ['spec.md']).map(_path =>
@@ -162,6 +165,7 @@ async function render(spec, assets, sharedVars, config, template, assetsGlobal,
162
165
  externalSpecsList: externalSpecsList,
163
166
  currentDate: currentDate,
164
167
  universalTimestamp: universalTimestamp,
168
+ buildBranch: buildBranch,
165
169
  githubRepoInfo: getGithubRepoInfo(spec)
166
170
  });
167
171
 
@@ -137,15 +137,6 @@
137
137
  <!-- Right-aligned elements -->
138
138
  <div class="d-flex align-items-center service-menu d-print-none">
139
139
 
140
- <!-- Settings side menu -->
141
- <button id="repo_settings" class="btn btn-sm btn-outline-secondary ms-2" type="button"
142
- data-bs-toggle="offcanvas" data-bs-target="#offcanvasSettings" aria-controls="offcanvasSettings">
143
- <svg class="bi" width="1em" height="1em" aria-hidden="true">
144
- <use href="#gear-wide-connected"></use>
145
- </svg>
146
- <span class="visually-hidden">Settings</span>
147
- </button>
148
-
149
140
  <!-- Dark / Light theme selector -->
150
141
  <div class="dropdown bd-mode-toggle">
151
142
  <button
@@ -247,6 +238,16 @@
247
238
  </div>
248
239
  </div>
249
240
 
241
+ <!-- Menu toggle button - hamburger icon fixed at right edge for slide-in panel -->
242
+ <button id="repo_settings" class="btn btn-sm btn-outline-secondary menu-toggle-btn d-print-none" type="button"
243
+ data-bs-toggle="offcanvas" data-bs-target="#offcanvasSettings" aria-controls="offcanvasSettings"
244
+ title="Open menu">
245
+ <svg class="bi" width="1.25em" height="1.25em" aria-hidden="true">
246
+ <use href="#list"></use>
247
+ </svg>
248
+ <span class="visually-hidden">Open menu</span>
249
+ </button>
250
+
250
251
  <div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvasSettings" aria-labelledby="offcanvasSettingsLabel">
251
252
  <div class="offcanvas-header">
252
253
  <h5 class="offcanvas-title mt-0" id="offcanvasSettingsLabel">Settings</h5>
@@ -293,7 +294,39 @@
293
294
  ${externalSpecsList}
294
295
  </div>
295
296
  <hr>
296
- <p class="ps-3 pe-3" id="w3c-state">W3C Recommendation, ${currentDate}</p>
297
+ <!-- External Reference Changes Report Section -->
298
+ <div class="ps-3 pe-3" id="external-ref-changes-section" style="display: none;">
299
+ <div class="d-flex justify-content-between align-items-center mb-2">
300
+ <p class="mb-0 fw-bold">External Reference Changes:</p>
301
+ <span id="external-ref-changes-badge" class="badge bg-warning text-dark">0</span>
302
+ </div>
303
+ <p class="small text-muted mb-2">Terms whose definitions have changed since the last build:</p>
304
+ <div id="external-ref-changes-container" class="external-ref-changes-report">
305
+ <!-- Report table will be populated by JavaScript -->
306
+ </div>
307
+ <div id="external-ref-validation-status" class="small text-muted mt-2">
308
+ <i class="bi bi-hourglass-split me-1"></i>
309
+ Validating external references...
310
+ </div>
311
+ </div>
312
+ <hr id="external-ref-changes-divider" style="display: none;">
313
+ <p class="d-none ps-3 pe-3" id="w3c-state">W3C Recommendation, ${currentDate}</p>
314
+ <!-- Build Information Section -->
315
+ <div class="ps-3 pe-3">
316
+ <p class="mb-2 fw-bold">Build Information:</p>
317
+ <div id="build-info" class="small text-muted">
318
+ <div class="d-flex align-items-center mb-1">
319
+ <i class="bi bi-calendar-event me-2"></i>
320
+ <time class="timestamp" datetime="${universalTimestamp}">
321
+ Generated: ${universalTimestamp}
322
+ </time>
323
+ </div>
324
+ <div class="d-flex align-items-center mb-1">
325
+ <i class="bi bi-signpost-split me-2"></i>
326
+ <span>Source branch: <strong>${buildBranch}</strong></span>
327
+ </div>
328
+ </div>
329
+ </div>
297
330
  </div>
298
331
  </div>
299
332