spec-up-t 1.2.3 → 1.2.4
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/.sonarlint/connectedMode.json +5 -0
- package/assets/compiled/body.js +31 -31
- package/assets/compiled/head.css +5 -5
- package/assets/compiled/head.js +3 -3
- package/assets/css/adjust-font-size.css +6 -11
- package/assets/css/backToTop.css +0 -1
- package/assets/css/index.css +1 -2
- package/assets/css/pdf-styles.css +23 -27
- package/assets/css/repo-issues.css +0 -6
- package/assets/css/search.css +0 -1
- package/assets/css/sidebar-toc.css +13 -12
- package/assets/css/terms-and-definitions.css +43 -37
- package/assets/js/add-href-to-snapshot-link.js +2 -1
- package/assets/js/addAnchorsToTerms.js +0 -1
- package/assets/js/adjust-font-size.js +0 -9
- package/assets/js/create-alphabet-index.js +1 -1
- package/assets/js/custom-elements.js +13 -18
- package/assets/js/declare-markdown-it.js +1 -1
- package/assets/js/highlightMenuItems.js +3 -3
- package/assets/js/index.js +1 -5
- package/assets/js/insert-trefs.js +2 -2
- package/assets/js/modal.js +3 -3
- package/assets/js/search.js +3 -3
- package/assets/js/utils.js +2 -3
- package/index.js +5 -15
- package/package.json +2 -2
- package/src/add-remove-xref-source.js +0 -2
- package/src/collect-external-references.js +187 -179
- package/src/collectExternalReferences/fetchTermsFromIndex.js +2 -1
- package/src/create-external-specs-list.js +1 -1
- package/src/fix-markdown-files.js +152 -90
- package/src/health-check/external-specs-checker.js +173 -94
- package/src/health-check/output-gitignore-checker.js +327 -191
- package/src/health-check/specs-configuration-checker.js +288 -210
- package/src/health-check/term-references-checker.js +200 -123
- package/src/health-check/tref-term-checker.js +264 -179
- package/src/health-check.js +51 -35
- package/src/init.js +0 -3
- package/src/install-from-boilerplate/boilerplate/gitignore +2 -1
- package/src/install-from-boilerplate/config-system-files.js +9 -1
- package/src/install-from-boilerplate/copy-system-files.js +1 -1
- package/src/markdown-it-extensions.js +199 -106
- package/src/references.js +1 -2
- package/src/utils/doesUrlExist.js +7 -5
- package/templates/template.html +1 -2
- package/assets/js/insert-xrefs.js +0 -370
- package/src/create-term-relations.js +0 -131
- package/src/prepare-tref.js +0 -174
|
@@ -2,99 +2,161 @@ const fs = require('fs');
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const { shouldProcessFile } = require('./utils/file-filter');
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
previousLineWasEmpty = false;
|
|
49
|
-
} else if (!previousLineWasEmpty) {
|
|
50
|
-
newLines.push(''); // Add exactly one blank line
|
|
51
|
-
previousLineWasEmpty = true;
|
|
52
|
-
} else {
|
|
53
|
-
modified = true; // Skip additional blank lines
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Prepend `~ ` to lines that do not start with `[[def:`, `[[tref:`, are not blank, do not already start with `~ `, and are not HTML comments
|
|
58
|
-
for (let i = 0; i < newLines.length; i++) {
|
|
59
|
-
if (
|
|
60
|
-
!newLines[i].startsWith('[[def:') &&
|
|
61
|
-
!newLines[i].startsWith('[[tref:') &&
|
|
62
|
-
newLines[i].trim() !== '' &&
|
|
63
|
-
!newLines[i].startsWith('~ ') &&
|
|
64
|
-
!newLines[i].trim().startsWith('<!--')
|
|
65
|
-
) {
|
|
66
|
-
newLines[i] = `~ ${newLines[i]}`;
|
|
67
|
-
modified = true;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Ensure there is exactly one blank line at the end of the file
|
|
72
|
-
if (newLines[newLines.length - 1] !== '') {
|
|
73
|
-
newLines.push('');
|
|
74
|
-
modified = true;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Join the lines back into a single string
|
|
78
|
-
if (modified) {
|
|
79
|
-
data = newLines.join('\n');
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Write the modified content back to the file synchronously if there were any changes
|
|
83
|
-
if (modified) {
|
|
84
|
-
fs.writeFileSync(itemPath, data, 'utf8');
|
|
85
|
-
}
|
|
86
|
-
} catch (err) {
|
|
87
|
-
console.error(`❌ Error while trying to fix the markdown in file ${item.name}: ${err}`);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
} catch (err) {
|
|
92
|
-
console.error(`❌ Error reading directory: ${err}`);
|
|
5
|
+
/**
|
|
6
|
+
* Handles specific functionality for `[[def:` lines
|
|
7
|
+
* @param {string[]} lines - Array of file lines
|
|
8
|
+
* @returns {object} - Object containing modified lines and modification status
|
|
9
|
+
*/
|
|
10
|
+
function processDefLines(lines) {
|
|
11
|
+
const result = [...lines];
|
|
12
|
+
let modified = false;
|
|
13
|
+
|
|
14
|
+
for (let i = 0; i < result.length; i++) {
|
|
15
|
+
if (result[i].startsWith('[[def:')) {
|
|
16
|
+
// Ensure a blank line immediately follows `[[def:` lines
|
|
17
|
+
if (i + 1 < result.length && result[i + 1].trim() !== '') {
|
|
18
|
+
result.splice(i + 1, 0, ''); // Insert blank line
|
|
19
|
+
modified = true;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return { lines: result, modified };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Ensures there is exactly one blank line between paragraphs
|
|
29
|
+
* @param {string[]} lines - Array of file lines
|
|
30
|
+
* @returns {object} - Object containing modified lines and modification status
|
|
31
|
+
*/
|
|
32
|
+
function normalizeParagraphSpacing(lines) {
|
|
33
|
+
let newLines = [];
|
|
34
|
+
let previousLineWasEmpty = false;
|
|
35
|
+
let modified = false;
|
|
36
|
+
|
|
37
|
+
for (const line of lines) {
|
|
38
|
+
const isCurrentLineEmpty = line.trim() === '';
|
|
39
|
+
|
|
40
|
+
if (!isCurrentLineEmpty) {
|
|
41
|
+
newLines.push(line); // Add non-empty lines
|
|
42
|
+
previousLineWasEmpty = false;
|
|
43
|
+
} else if (!previousLineWasEmpty) {
|
|
44
|
+
newLines.push(''); // Add exactly one blank line
|
|
45
|
+
previousLineWasEmpty = true;
|
|
46
|
+
} else {
|
|
47
|
+
modified = true; // Skip additional blank lines
|
|
93
48
|
}
|
|
94
49
|
}
|
|
95
50
|
|
|
96
|
-
|
|
97
|
-
|
|
51
|
+
return { lines: newLines, modified };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Prepends `~ ` to appropriate lines
|
|
56
|
+
* @param {string[]} lines - Array of file lines
|
|
57
|
+
* @returns {object} - Object containing modified lines and modification status
|
|
58
|
+
*/
|
|
59
|
+
function prependTildeToLines(lines) {
|
|
60
|
+
const result = [...lines];
|
|
61
|
+
let modified = false;
|
|
62
|
+
|
|
63
|
+
for (let i = 0; i < result.length; i++) {
|
|
64
|
+
if (
|
|
65
|
+
!result[i].startsWith('[[def:') &&
|
|
66
|
+
!result[i].startsWith('[[tref:') &&
|
|
67
|
+
result[i].trim() !== '' &&
|
|
68
|
+
!result[i].startsWith('~ ') &&
|
|
69
|
+
!result[i].trim().startsWith('<!--')
|
|
70
|
+
) {
|
|
71
|
+
result[i] = `~ ${result[i]}`;
|
|
72
|
+
modified = true;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return { lines: result, modified };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Ensures there is exactly one blank line at the end of the file
|
|
81
|
+
* @param {string[]} lines - Array of file lines
|
|
82
|
+
* @returns {object} - Object containing modified lines and modification status
|
|
83
|
+
*/
|
|
84
|
+
function ensureTrailingNewline(lines) {
|
|
85
|
+
const result = [...lines];
|
|
86
|
+
let modified = false;
|
|
87
|
+
|
|
88
|
+
if (result[result.length - 1] !== '') {
|
|
89
|
+
result.push('');
|
|
90
|
+
modified = true;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return { lines: result, modified };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Processes a single markdown file and applies formatting rules
|
|
98
|
+
* @param {string} filePath - Path to the markdown file
|
|
99
|
+
* @returns {void}
|
|
100
|
+
*/
|
|
101
|
+
function processMarkdownFile(filePath, fileName) {
|
|
102
|
+
try {
|
|
103
|
+
// Read the file synchronously
|
|
104
|
+
let data = fs.readFileSync(filePath, 'utf8');
|
|
105
|
+
|
|
106
|
+
// Split the content into lines
|
|
107
|
+
let lines = data.split('\n');
|
|
108
|
+
let modified = false;
|
|
109
|
+
|
|
110
|
+
// Apply each processing function in sequence
|
|
111
|
+
const defResult = processDefLines(lines);
|
|
112
|
+
lines = defResult.lines;
|
|
113
|
+
modified = modified || defResult.modified;
|
|
114
|
+
|
|
115
|
+
const spacingResult = normalizeParagraphSpacing(lines);
|
|
116
|
+
lines = spacingResult.lines;
|
|
117
|
+
modified = modified || spacingResult.modified;
|
|
118
|
+
|
|
119
|
+
const tildeResult = prependTildeToLines(lines);
|
|
120
|
+
lines = tildeResult.lines;
|
|
121
|
+
modified = modified || tildeResult.modified;
|
|
122
|
+
|
|
123
|
+
const newlineResult = ensureTrailingNewline(lines);
|
|
124
|
+
lines = newlineResult.lines;
|
|
125
|
+
modified = modified || newlineResult.modified;
|
|
126
|
+
|
|
127
|
+
// Write the modified content back to the file synchronously if there were any changes
|
|
128
|
+
if (modified) {
|
|
129
|
+
const newData = lines.join('\n');
|
|
130
|
+
fs.writeFileSync(filePath, newData, 'utf8');
|
|
131
|
+
}
|
|
132
|
+
} catch (err) {
|
|
133
|
+
console.error(`❌ Error while trying to fix the markdown in file ${fileName}: ${err}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Processes markdown files in a directory recursively
|
|
139
|
+
* @param {string} directory - The directory to process
|
|
140
|
+
* @returns {void}
|
|
141
|
+
*/
|
|
142
|
+
function fixMarkdownFiles(directory) {
|
|
143
|
+
try {
|
|
144
|
+
// Read the contents of the directory synchronously
|
|
145
|
+
const items = fs.readdirSync(directory, { withFileTypes: true });
|
|
146
|
+
|
|
147
|
+
// Loop through each item in the directory
|
|
148
|
+
items.forEach(item => {
|
|
149
|
+
const itemPath = path.join(directory, item.name);
|
|
150
|
+
if (item.isDirectory()) {
|
|
151
|
+
// If the item is a directory, call fixMarkdownFiles recursively
|
|
152
|
+
fixMarkdownFiles(itemPath);
|
|
153
|
+
} else if (item.isFile() && shouldProcessFile(item.name)) {
|
|
154
|
+
processMarkdownFile(itemPath, item.name);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
} catch (err) {
|
|
158
|
+
console.error(`❌ Error reading directory: ${err}`);
|
|
159
|
+
}
|
|
98
160
|
}
|
|
99
161
|
|
|
100
162
|
module.exports = {
|
|
@@ -17,6 +17,7 @@ function isValidGitHubPagesUrl(urlStr) {
|
|
|
17
17
|
parsedUrl.hostname.endsWith('.github.io')
|
|
18
18
|
);
|
|
19
19
|
} catch (error) {
|
|
20
|
+
console.error(`❌ Error validating GitHub Pages URL: ${error.message}`);
|
|
20
21
|
return false;
|
|
21
22
|
}
|
|
22
23
|
}
|
|
@@ -34,6 +35,7 @@ function isValidGitHubRepoUrl(urlStr) {
|
|
|
34
35
|
parsedUrl.pathname.split('/').filter(Boolean).length >= 2
|
|
35
36
|
);
|
|
36
37
|
} catch (error) {
|
|
38
|
+
console.error(`❌ Error validating GitHub repo URL: ${error.message}`);
|
|
37
39
|
return false;
|
|
38
40
|
}
|
|
39
41
|
}
|
|
@@ -69,131 +71,208 @@ function urlExists(urlStr) {
|
|
|
69
71
|
|
|
70
72
|
req.end();
|
|
71
73
|
} catch (error) {
|
|
74
|
+
console.error(`❌ URL Format Error: Invalid URL format for ${urlStr} - ${error.message}`);
|
|
72
75
|
resolve(false);
|
|
73
76
|
}
|
|
74
77
|
});
|
|
75
78
|
}
|
|
76
79
|
|
|
77
80
|
/**
|
|
78
|
-
* Check
|
|
81
|
+
* Check if specs.json file exists and read it
|
|
79
82
|
* @param {string} projectRoot - Root directory of the project
|
|
80
|
-
* @returns {
|
|
83
|
+
* @returns {Object} - Object containing results and specs data if found
|
|
81
84
|
*/
|
|
82
|
-
|
|
83
|
-
const
|
|
85
|
+
function checkAndReadSpecsFile(projectRoot) {
|
|
86
|
+
const specsPath = path.join(projectRoot, 'specs.json');
|
|
84
87
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
// Check if specs.json exists
|
|
89
|
-
if (!fs.existsSync(specsPath)) {
|
|
90
|
-
return [{
|
|
88
|
+
if (!fs.existsSync(specsPath)) {
|
|
89
|
+
return {
|
|
90
|
+
results: [{
|
|
91
91
|
name: 'Find specs.json file',
|
|
92
92
|
success: false,
|
|
93
93
|
details: 'specs.json file not found in project root'
|
|
94
|
-
}]
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
details: 'specs.json file found'
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
// Read specs.json
|
|
94
|
+
}],
|
|
95
|
+
specs: null
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
try {
|
|
104
100
|
const specsContent = fs.readFileSync(specsPath, 'utf8');
|
|
105
101
|
const specs = JSON.parse(specsContent);
|
|
106
102
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
103
|
+
return {
|
|
104
|
+
results: [{
|
|
105
|
+
name: 'Find specs.json file',
|
|
106
|
+
success: true,
|
|
107
|
+
details: 'specs.json file found'
|
|
108
|
+
}],
|
|
109
|
+
specs
|
|
110
|
+
};
|
|
111
|
+
} catch (error) {
|
|
112
|
+
return {
|
|
113
|
+
results: [{
|
|
114
|
+
name: 'Parse specs.json file',
|
|
115
|
+
success: false,
|
|
116
|
+
details: `❌ Error parsing specs.json: ${error.message}`
|
|
117
|
+
}],
|
|
118
|
+
specs: null
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Extract external specs from specs data
|
|
125
|
+
* @param {Object} specs - Specs data
|
|
126
|
+
* @returns {Object} - Object containing results and external specs if found
|
|
127
|
+
*/
|
|
128
|
+
function extractExternalSpecs(specs) {
|
|
129
|
+
if (!specs.specs || !Array.isArray(specs.specs) || !specs.specs.some(spec => spec.external_specs)) {
|
|
130
|
+
return {
|
|
131
|
+
results: [{
|
|
110
132
|
name: 'Find external_specs in specs.json',
|
|
111
133
|
success: false,
|
|
112
134
|
details: 'external_specs key not found in specs.json'
|
|
113
|
-
}
|
|
114
|
-
|
|
135
|
+
}],
|
|
136
|
+
externalSpecs: []
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const externalSpecs = [];
|
|
141
|
+
|
|
142
|
+
specs.specs.forEach(spec => {
|
|
143
|
+
if (spec.external_specs && Array.isArray(spec.external_specs)) {
|
|
144
|
+
externalSpecs.push(...spec.external_specs);
|
|
115
145
|
}
|
|
116
|
-
|
|
117
|
-
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
results: [{
|
|
118
150
|
name: 'Find external_specs in specs.json',
|
|
119
151
|
success: true,
|
|
120
152
|
details: 'external_specs key found in specs.json'
|
|
153
|
+
}],
|
|
154
|
+
externalSpecs
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Check GitHub Pages URL for an external spec
|
|
160
|
+
* @param {Object} spec - External spec object
|
|
161
|
+
* @returns {Promise<Array>} - Array of check results
|
|
162
|
+
*/
|
|
163
|
+
async function checkGitHubPagesUrl(spec) {
|
|
164
|
+
const results = [];
|
|
165
|
+
|
|
166
|
+
if (!spec.gh_page) {
|
|
167
|
+
results.push({
|
|
168
|
+
name: `Check "${spec.external_spec}" gh_page URL`,
|
|
169
|
+
success: false,
|
|
170
|
+
details: 'gh_page URL is missing'
|
|
121
171
|
});
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
172
|
+
return results;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const isValidGhPage = isValidGitHubPagesUrl(spec.gh_page);
|
|
176
|
+
results.push({
|
|
177
|
+
name: `Check "${spec.external_spec}" gh_page URL structure`,
|
|
178
|
+
success: isValidGhPage,
|
|
179
|
+
details: isValidGhPage
|
|
180
|
+
? 'Valid GitHub Pages URL structure'
|
|
181
|
+
: `Invalid GitHub Pages URL structure: ${spec.gh_page}`
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
if (isValidGhPage) {
|
|
185
|
+
const ghPageExists = await urlExists(spec.gh_page);
|
|
186
|
+
results.push({
|
|
187
|
+
name: `Check "${spec.external_spec}" gh_page URL exists`,
|
|
188
|
+
success: ghPageExists,
|
|
189
|
+
details: ghPageExists
|
|
190
|
+
? 'GitHub Pages URL is accessible'
|
|
191
|
+
: `GitHub Pages URL is not accessible: ${spec.gh_page}`
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return results;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Check repository URL for an external spec
|
|
200
|
+
* @param {Object} spec - External spec object
|
|
201
|
+
* @returns {Promise<Array>} - Array of check results
|
|
202
|
+
*/
|
|
203
|
+
async function checkRepositoryUrl(spec) {
|
|
204
|
+
const results = [];
|
|
205
|
+
|
|
206
|
+
if (!spec.url) {
|
|
207
|
+
results.push({
|
|
208
|
+
name: `Check "${spec.external_spec}" repo URL`,
|
|
209
|
+
success: false,
|
|
210
|
+
details: 'Repository URL is missing'
|
|
129
211
|
});
|
|
212
|
+
return results;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const isValidRepoUrl = isValidGitHubRepoUrl(spec.url);
|
|
216
|
+
results.push({
|
|
217
|
+
name: `Check "${spec.external_spec}" repo URL structure`,
|
|
218
|
+
success: isValidRepoUrl,
|
|
219
|
+
details: isValidRepoUrl
|
|
220
|
+
? 'Valid GitHub repository URL structure'
|
|
221
|
+
: `Invalid GitHub repository URL structure: ${spec.url}`
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
if (isValidRepoUrl) {
|
|
225
|
+
const repoUrlExists = await urlExists(spec.url);
|
|
226
|
+
results.push({
|
|
227
|
+
name: `Check "${spec.external_spec}" repo URL exists`,
|
|
228
|
+
success: repoUrlExists,
|
|
229
|
+
details: repoUrlExists
|
|
230
|
+
? 'GitHub repository URL is accessible'
|
|
231
|
+
: `GitHub repository URL is not accessible: ${spec.url}`
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return results;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Check external specs in a specs.json file
|
|
240
|
+
* @param {string} projectRoot - Root directory of the project
|
|
241
|
+
* @returns {Promise<Array>} - Array of check results
|
|
242
|
+
*/
|
|
243
|
+
async function checkExternalSpecs(projectRoot) {
|
|
244
|
+
try {
|
|
245
|
+
// Check for and read specs.json file
|
|
246
|
+
const { results, specs } = checkAndReadSpecsFile(projectRoot);
|
|
247
|
+
|
|
248
|
+
if (!specs) {
|
|
249
|
+
return results;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Extract external specs from specs data
|
|
253
|
+
const { results: extractResults, externalSpecs } = extractExternalSpecs(specs);
|
|
254
|
+
|
|
255
|
+
// Combine results
|
|
256
|
+
const allResults = [...results, ...extractResults];
|
|
257
|
+
|
|
258
|
+
if (externalSpecs.length === 0) {
|
|
259
|
+
return allResults;
|
|
260
|
+
}
|
|
130
261
|
|
|
131
262
|
// Check each external spec
|
|
132
263
|
for (const spec of externalSpecs) {
|
|
133
|
-
// Check
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
results.push({
|
|
137
|
-
name: `Check "${spec.external_spec}" gh_page URL structure`,
|
|
138
|
-
success: isValidGhPage,
|
|
139
|
-
details: isValidGhPage
|
|
140
|
-
? 'Valid GitHub Pages URL structure'
|
|
141
|
-
: `Invalid GitHub Pages URL structure: ${spec.gh_page}`
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
// Check if gh_page exists
|
|
145
|
-
if (isValidGhPage) {
|
|
146
|
-
const ghPageExists = await urlExists(spec.gh_page);
|
|
147
|
-
results.push({
|
|
148
|
-
name: `Check "${spec.external_spec}" gh_page URL exists`,
|
|
149
|
-
success: ghPageExists,
|
|
150
|
-
details: ghPageExists
|
|
151
|
-
? 'GitHub Pages URL is accessible'
|
|
152
|
-
: `GitHub Pages URL is not accessible: ${spec.gh_page}`
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
} else {
|
|
156
|
-
results.push({
|
|
157
|
-
name: `Check "${spec.external_spec}" gh_page URL`,
|
|
158
|
-
success: false,
|
|
159
|
-
details: 'gh_page URL is missing'
|
|
160
|
-
});
|
|
161
|
-
}
|
|
264
|
+
// Check GitHub Pages URL
|
|
265
|
+
const ghPageResults = await checkGitHubPagesUrl(spec);
|
|
266
|
+
allResults.push(...ghPageResults);
|
|
162
267
|
|
|
163
|
-
// Check
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
results.push({
|
|
167
|
-
name: `Check "${spec.external_spec}" repo URL structure`,
|
|
168
|
-
success: isValidRepoUrl,
|
|
169
|
-
details: isValidRepoUrl
|
|
170
|
-
? 'Valid GitHub repository URL structure'
|
|
171
|
-
: `Invalid GitHub repository URL structure: ${spec.url}`
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
// Check if url exists
|
|
175
|
-
if (isValidRepoUrl) {
|
|
176
|
-
const repoUrlExists = await urlExists(spec.url);
|
|
177
|
-
results.push({
|
|
178
|
-
name: `Check "${spec.external_spec}" repo URL exists`,
|
|
179
|
-
success: repoUrlExists,
|
|
180
|
-
details: repoUrlExists
|
|
181
|
-
? 'GitHub repository URL is accessible'
|
|
182
|
-
: `GitHub repository URL is not accessible: ${spec.url}`
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
} else {
|
|
186
|
-
results.push({
|
|
187
|
-
name: `Check "${spec.external_spec}" repo URL`,
|
|
188
|
-
success: false,
|
|
189
|
-
details: 'Repository URL is missing'
|
|
190
|
-
});
|
|
191
|
-
}
|
|
268
|
+
// Check repository URL
|
|
269
|
+
const repoUrlResults = await checkRepositoryUrl(spec);
|
|
270
|
+
allResults.push(...repoUrlResults);
|
|
192
271
|
}
|
|
193
272
|
|
|
194
|
-
return
|
|
273
|
+
return allResults;
|
|
195
274
|
} catch (error) {
|
|
196
|
-
console.error('Error checking external specs:', error);
|
|
275
|
+
console.error('❌ Error checking external specs:', error);
|
|
197
276
|
return [{
|
|
198
277
|
name: 'External specs check',
|
|
199
278
|
success: false,
|