spec-up-t 0.11.30 → 0.11.31

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/index.js CHANGED
@@ -7,6 +7,9 @@ module.exports = function(options = {}) {
7
7
  findExternalSpecByKey
8
8
  } = require('./references.js');
9
9
 
10
+ const { runJsonKeyValidatorSync } = require('./src/json-key-validator.js');
11
+ runJsonKeyValidatorSync();
12
+
10
13
  const { processMarkdownFiles } = require('./src/fix-markdown-files.js');
11
14
  processMarkdownFiles('./spec');
12
15
 
package/package.json CHANGED
@@ -1,17 +1,12 @@
1
1
  {
2
2
  "name": "spec-up-t",
3
- "version": "0.11.30",
3
+ "version": "0.11.31",
4
4
  "description": "Technical specification drafting tool that generates rich specification documents from markdown. Forked from https://github.com/decentralized-identity/spec-up by Daniel Buchner (https://github.com/csuwildcat)",
5
5
  "main": "./index",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/blockchainbird/spec-up-t.git"
9
9
  },
10
- "scripts": {
11
- "edit": "node -e \"require('./index')()\"",
12
- "render": "node -e \"require('./index')({ nowatch: true })\"",
13
- "dev": "node -e \"require('./index')({ dev: true })\""
14
- },
15
10
  "keywords": [
16
11
  "spec",
17
12
  "specs",
@@ -56,6 +51,7 @@
56
51
  "merge-stream": "2.0.0",
57
52
  "pkg-dir": "4.2.0",
58
53
  "prismjs": ">=1.24.0",
54
+ "readline-sync": "^1.4.10",
59
55
  "yargs": "16.2.0"
60
56
  }
61
- }
57
+ }
@@ -5,25 +5,26 @@
5
5
  * @since 2024-06-09
6
6
  */
7
7
 
8
- // Get the current working directory
9
-
10
8
  const fs = require('fs-extra');
11
9
  const config = fs.readJsonSync('specs.json');
12
- const specDirectories = config.specs.map(spec => spec.spec_directory + '/' + spec.spec_terms_directory);
10
+
11
+ // Collect all directories that contain files with a term and definition
12
+ const specTermsDirectories = config.specs.map(spec => spec.spec_directory + '/' + spec.spec_terms_directory);
13
13
 
14
14
  // Create directory named “output” in the project root if it does not yet exist
15
15
  if (!fs.existsSync('output')) {
16
16
  fs.mkdirSync('output');
17
17
  }
18
18
 
19
- // Create directory named “output/xrefs” in the project root if it does not yet exist
19
+ // Create directory named “output/xrefs-history” in the project root if it does not yet exist
20
20
  if (!fs.existsSync('output/xrefs-history')) {
21
21
  fs.mkdirSync('output/xrefs-history');
22
22
  }
23
23
 
24
24
  // Create a path for the output file in the project root
25
- const outputPath = 'output/xrefs-data.js';
26
- const outputPathTimeStamped = 'output/xrefs-history/xrefs-data-' + Date.now() + '.js';
25
+ const outputPathJSON = 'output/xrefs-data.json';
26
+ const outputPathJS = 'output/xrefs-data.js';
27
+ const outputPathJSTimeStamped = 'output/xrefs-history/xrefs-data-' + Date.now() + '.js';
27
28
 
28
29
  function getXrefsData() {
29
30
  let allXrefs = {};
@@ -62,7 +63,7 @@ function getXrefsData() {
62
63
 
63
64
  console.log(`Github API request for the term “${match.term}” was successful`);
64
65
 
65
- // Extract JSON data from the response
66
+ // Extract JSON data from the response, see https://blockchainbird.github.io/spec-up-t-website/docs/various-roles/developers-guide/#example-of-api-response for example response
66
67
  const data = await response.json();
67
68
 
68
69
  // Check if there are any commits
@@ -85,9 +86,15 @@ function getXrefsData() {
85
86
  }
86
87
  }
87
88
 
89
+ async function fetchLatestCommitHashes() {
90
+ for (const xref of allXrefs.xrefs) {
91
+ xref.commitHash = await fetchLatestCommitHash(xref);
92
+ }
93
+ }
94
+
88
95
  // Go through all directories that contain files with a term and definition
89
- console.log('All “spec_directory” found in specs.json: ', specDirectories);
90
- specDirectories.forEach(specDirectory => {
96
+ console.log("All “spec_directory”'s found in specs.json: ", specTermsDirectories);
97
+ specTermsDirectories.forEach(specDirectory => {
91
98
  console.log(`Current spec_directory: `, specDirectory);
92
99
  // read directory
93
100
  fs.readdirSync(specDirectory).forEach(file => {
@@ -101,7 +108,7 @@ function getXrefsData() {
101
108
  const xrefs = markdown.match(regex);
102
109
  xrefs.forEach(xref => {
103
110
  console.log(`Xref found in ${file}: `, xref);
104
- // example of xref: [[xref: PE, Holder]]
111
+ // example of xref: [xref: test-1, Aal]
105
112
  allXrefs.xrefs.add(xref);
106
113
  });
107
114
  }
@@ -113,26 +120,28 @@ function getXrefsData() {
113
120
 
114
121
  // Example output:
115
122
  // allXrefs.xrefs: [
116
- // '[[xref: PE, Holder]]',
117
123
  // '[[xref: test-1, Aal]]',
118
124
  // '[[xref: test-2, Abac]]'
119
125
  // ]
120
126
 
121
- // remove[[xref:” from the beginning of every value in allMatches
127
+ // The following steps create an array of objects with the keys externalSpec” and “term” for each xref by splitting the xref string on the comma and removing the “[[xref:” and “]]” parts
128
+
129
+ // Step 1: remove “[[xref:” from the beginning of every value in allMatches
122
130
  allXrefs.xrefs = allXrefs.xrefs.map(xref => {
123
131
  return xref.replace(/\[\[xref:/, '');
124
132
  });
125
- // remove “]]” from the end of every value in allMatches
133
+
134
+ // Step 2: remove “]]” from the end of every value in allMatches
126
135
  allXrefs.xrefs = allXrefs.xrefs.map(xref => {
127
136
  return xref.replace(/\]\]/, '');
128
137
  });
129
138
 
130
- // trim every entry of allMatches
139
+ // Step 3: trim every entry of allMatches
131
140
  allXrefs.xrefs = allXrefs.xrefs.map(xref => {
132
141
  return xref.trim();
133
142
  });
134
143
 
135
- // split every entry of allMatches on the first comma, replace the entry with an object that has two keys: one that contains everything before the comma and one that contains everything after the comma
144
+ // Step 4: split every entry of allMatches on the first comma, replace the entry with an object that has two keys: one that contains everything before the comma and one that contains everything after the comma
136
145
  allXrefs.xrefs = allXrefs.xrefs.map(xref => {
137
146
  let [externalSpec, term] = xref.split(/,/, 2);
138
147
  return {
@@ -143,12 +152,11 @@ function getXrefsData() {
143
152
 
144
153
  // Example output:
145
154
  // allXrefs.xrefs: [
146
- // { externalSpec: 'PE', term: 'Holder' },
147
155
  // { externalSpec: 'test-1', term: 'Aal' },
148
156
  // { externalSpec: 'test-2', term: 'Abac' }
149
157
  // ]
150
158
 
151
-
159
+ // Step 5: add the url and the dir where the terms are, to the xref object
152
160
  allXrefs.xrefs.forEach(xref => {
153
161
  config.specs.forEach(spec => {
154
162
  spec.external_specs_repos.forEach(repo => {
@@ -156,8 +164,8 @@ function getXrefsData() {
156
164
  // Example external_specs_repos:
157
165
  // "external_specs_repos": [
158
166
  // {
159
- // "external_spec": "PE",
160
- // "url": "https://github.com/decentralized-identity/presentation-exchange",
167
+ // "external_spec": "test-1",
168
+ // "url": "https://github.com/blockchainbird/spec-up-xref-test-1",
161
169
  // "terms_dir": "spec"
162
170
  // },
163
171
  // …
@@ -170,6 +178,7 @@ function getXrefsData() {
170
178
  });
171
179
  });
172
180
 
181
+ // Step 6: add the owner and repo to the xref object
173
182
  allXrefs.xrefs.forEach(xref => {
174
183
  if (xref.repoUrl === undefined) {
175
184
  console.log('match.repoUrl is undefined');
@@ -181,15 +190,16 @@ function getXrefsData() {
181
190
  xref.repo = urlParts[2];
182
191
  });
183
192
 
193
+ // Step 7: add the site to the xref object
184
194
  allXrefs.xrefs.forEach(xref => {
185
195
  // loop through array of specs in config
186
196
  config.specs.forEach(spec => {
187
197
  if (spec.external_specs) {
188
198
  // Example external_specs:
189
199
  // "external_specs": [
190
- // {
191
- // "PE": "https://identity.foundation/presentation-exchange"
192
- // },
200
+ // {
201
+ // "test-1": "https://blockchainbird.github.io/spec-up-xref-test-1/"
202
+ // }
193
203
  // …
194
204
  // ]
195
205
  spec.external_specs.forEach(externalSpec => {
@@ -217,23 +227,21 @@ function getXrefsData() {
217
227
  ]
218
228
  }
219
229
  */
220
- async function fetchLatestCommitHashes() {
221
- for (const xref of allXrefs.xrefs) {
222
- xref.commitHash = await fetchLatestCommitHash(xref);
223
- }
224
- }
225
230
 
226
231
  // Call the function and wait for it to complete before writing to the file
227
232
  fetchLatestCommitHashes().then(() => {
228
233
  // Convert allXrefsStr to a JSON string with indentation
229
234
  const allXrefsStr = JSON.stringify(allXrefs, null, 2);
230
235
 
236
+ // // Write the JSON code to a .json file
237
+ fs.writeFileSync(outputPathJSON, allXrefsStr, 'utf8');
238
+
231
239
  // Create the JS code for the assignment
232
240
  const stringReadyForFileWrite = `const allXrefs = ${allXrefsStr};`;
233
241
 
234
242
  // Write the JS code to a .js file
235
- fs.writeFileSync(outputPath, stringReadyForFileWrite, 'utf8');
236
- fs.writeFileSync(outputPathTimeStamped, stringReadyForFileWrite, 'utf8');
243
+ fs.writeFileSync(outputPathJS, stringReadyForFileWrite, 'utf8');
244
+ fs.writeFileSync(outputPathJSTimeStamped, stringReadyForFileWrite, 'utf8');
237
245
  });
238
246
  }
239
247
 
@@ -0,0 +1,94 @@
1
+ const fs = require('fs');
2
+ const readlineSync = require('readline-sync');
3
+
4
+ let errorFound = false;
5
+
6
+ // Function to pause the script and wait for the ENTER key synchronously
7
+ function pauseForEnterSync() {
8
+ readlineSync.question('Press ENTER to continue...');
9
+ }
10
+
11
+ function loadData() {
12
+ return JSON.parse(fs.readFileSync('./specs.json', 'utf8'));
13
+ }
14
+
15
+ function checkKeysSync(object, expectedKeys, parentKey = '') {
16
+ for (let key of expectedKeys) {
17
+ if (Array.isArray(object)) {
18
+ for (let [index, item] of object.entries()) {
19
+ checkKeysSync(item, expectedKeys, `${parentKey}[${index}]`);
20
+ }
21
+ } else if (typeof object === 'object') {
22
+ if (!(key in object)) {
23
+ console.error(` Error: Missing key '${key}' in ${parentKey}\n We cannot guarantee that Spec-Up-T will work properly.\n Here is an example specs.json file:\n https://github.com/blockchainbird/spec-up-t-starter-pack/blob/main/spec-up-t-starterpack/specs.json`);
24
+ errorFound = true;
25
+ pauseForEnterSync(); // Pause synchronously
26
+ }
27
+ if (typeof expectedKeys[key] === 'object' && object[key]) {
28
+ checkKeysSync(object[key], expectedKeys[key], `${parentKey}.${key}`);
29
+ }
30
+ }
31
+ }
32
+ }
33
+
34
+ function runJsonKeyValidatorSync() {
35
+ const data = loadData();
36
+ const expectedKeys = {
37
+ specs: [
38
+ "title",
39
+ "spec_directory",
40
+ "spec_terms_directory",
41
+ "output_path",
42
+ "markdown_paths",
43
+ "logo",
44
+ "logo_link",
45
+ "source",
46
+ "external_specs",
47
+ "external_specs_repos",
48
+ "assets",
49
+ "katex",
50
+ "searchHighlightStyle"
51
+ ],
52
+ source: [
53
+ "host",
54
+ "account",
55
+ "repo"
56
+ ],
57
+ external_specs_repos: [
58
+ "external_spec",
59
+ "url",
60
+ "terms_dir"
61
+ ],
62
+ assets: [
63
+ "path",
64
+ "inject",
65
+ "module"
66
+ ]
67
+ };
68
+
69
+ for (let [index, spec] of data.specs.entries()) {
70
+ console.log(` Checking spec #${index + 1}`);
71
+ checkKeysSync(spec, expectedKeys.specs, `specs[${index}]`);
72
+
73
+ if (spec.source) {
74
+ checkKeysSync(spec.source, expectedKeys.source, `specs[${index}].source`);
75
+ }
76
+
77
+ if (spec.external_specs_repos) {
78
+ checkKeysSync(spec.external_specs_repos, expectedKeys.external_specs_repos, `specs[${index}].external_specs_repos`);
79
+ }
80
+
81
+ // if (spec.assets) {
82
+ // checkKeysSync(spec.assets, expectedKeys.assets, `specs[${index}].assets`);
83
+ // }
84
+ }
85
+
86
+ if (!errorFound) {
87
+ console.log(' All keys are present. No errors found. Continue…');
88
+ }
89
+ }
90
+
91
+ // Export the function to be used in other scripts
92
+ module.exports = {
93
+ runJsonKeyValidatorSync
94
+ };