@nan0web/release 3.3.0 → 3.4.0
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/bin/nan0release.js +33 -2
- package/bin/serve.js +73 -0
- package/package.json +45 -17
- package/src/Release/Document.js +1 -0
- package/src/Release/Scanner.js +3 -2
- package/src/Release.js +7 -7
- package/src/domain/App.js +31 -2
- package/src/domain/BumpCommand.js +10 -3
- package/src/domain/CheckCommand.js +504 -146
- package/src/domain/CheckCommand.story.js +92 -0
- package/src/domain/CloseCommand.js +13 -9
- package/src/domain/Dashboard/Dashboard.story.js +155 -0
- package/src/domain/Dashboard/DashboardModel.js +308 -0
- package/src/domain/Dashboard/ReleaseDiscovery.js +132 -0
- package/src/domain/Dashboard/ReleaseParser.js +226 -0
- package/src/domain/Dashboard/index.js +19 -0
- package/src/domain/DepsCommand.js +5 -2
- package/src/domain/InitCommand.js +18 -16
- package/src/domain/ListCommand.js +45 -0
- package/src/domain/PreviewCommand.js +39 -0
- package/src/domain/PublishCommand.js +7 -3
- package/src/domain/Registry/Registry.story.js +82 -0
- package/src/domain/Registry/RegistryModel.js +124 -0
- package/src/domain/ServeCommand.js +165 -0
- package/src/domain/ServeCommand.story.js +88 -0
- package/src/domain/SpecCommand.js +3 -1
- package/src/domain/StatusCommand.js +249 -3
- package/src/domain/ViewCommand.js +99 -0
- package/src/domain/WebCommand.js +140 -0
- package/src/domain/inspect/ReleaseAuditor.js +508 -0
- package/src/domain/inspect/ReleaseAuditor.story.js +136 -0
- package/src/domain/templates/release.html +34 -0
- package/src/domain/templates/release.html.template.js +34 -0
- package/src/index.js +6 -0
- package/src/inspectors/inspect-js.js +32 -0
- package/src/releases/1/0/v1.0.3/task.test.js +1 -1
- package/src/utils/nodejs/GitTelemetry.js +154 -0
- package/types/Release/Document.d.ts +24 -27
- package/types/Release/MarkdownToTest.d.ts +1 -1
- package/types/Release/Person.d.ts +9 -7
- package/types/Release/Scanner.d.ts +41 -41
- package/types/Release.d.ts +42 -42
- package/types/architecture/ProjectManagementAsCode.d.ts +59 -64
- package/types/domain/App.d.ts +24 -7
- package/types/domain/BumpCommand.d.ts +11 -6
- package/types/domain/CheckCommand.d.ts +128 -16
- package/types/domain/CheckCommand.story.d.ts +1 -0
- package/types/domain/CloseCommand.d.ts +4 -6
- package/types/domain/Dashboard/Dashboard.story.d.ts +1 -0
- package/types/domain/Dashboard/DashboardModel.d.ts +273 -0
- package/types/domain/Dashboard/GitTelemetry.d.ts +23 -0
- package/types/domain/Dashboard/ReleaseDiscovery.d.ts +47 -0
- package/types/domain/Dashboard/ReleaseParser.d.ts +79 -0
- package/types/domain/Dashboard/index.d.ts +3 -0
- package/types/domain/DepsCommand.d.ts +6 -6
- package/types/domain/InitCommand.d.ts +4 -6
- package/types/domain/ListCommand.d.ts +18 -0
- package/types/domain/PreviewCommand.d.ts +6 -0
- package/types/domain/PublishCommand.d.ts +8 -6
- package/types/domain/Registry/Registry.story.d.ts +1 -0
- package/types/domain/Registry/RegistryModel.d.ts +61 -0
- package/types/domain/ServeCommand.d.ts +59 -0
- package/types/domain/ServeCommand.story.d.ts +1 -0
- package/types/domain/SpecCommand.d.ts +4 -6
- package/types/domain/StatusCommand.d.ts +38 -3
- package/types/domain/ViewCommand.d.ts +27 -0
- package/types/domain/WebCommand.d.ts +47 -0
- package/types/domain/inspect/ReleaseAuditor.d.ts +134 -0
- package/types/domain/inspect/ReleaseAuditor.story.d.ts +1 -0
- package/types/domain/templates/release.html.template.d.ts +2 -0
- package/types/index.d.ts +18 -10
- package/types/inspectors/inspect-js.d.ts +2 -0
- package/types/utils/nodejs/GitTelemetry.d.ts +23 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export default `<!DOCTYPE html>
|
|
2
|
+
<html lang="uk" data-bs-theme="dark">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>Releases Catalog — NaN•Web</title>
|
|
7
|
+
<style>
|
|
8
|
+
:root {
|
|
9
|
+
--bg: #0f172a;
|
|
10
|
+
--surface: #1e293b;
|
|
11
|
+
--accent: #38bdf8;
|
|
12
|
+
--text: #f8fafc;
|
|
13
|
+
--text-dim: #94a3b8;
|
|
14
|
+
--border: #334155;
|
|
15
|
+
}
|
|
16
|
+
body { font-family: system-ui, -apple-system, sans-serif; background: var(--bg); color: var(--text); margin: 0; padding: 2.5rem 1.5rem; display: flex; justify-content: center; line-height: 1.6; }
|
|
17
|
+
.container { max-width: 880px; width: 100%; }
|
|
18
|
+
h1, h2, h3 { color: #fff; font-weight: 700; margin-top: 1.5rem; }
|
|
19
|
+
h1 { font-size: 2rem; border-bottom: 1px solid var(--border); padding-bottom: 0.8rem; }
|
|
20
|
+
a { color: var(--accent); text-decoration: none; }
|
|
21
|
+
a:hover { text-decoration: underline; }
|
|
22
|
+
table { width: 100%; border-collapse: collapse; margin: 1.5rem 0; background: var(--surface); border-radius: 8px; overflow: hidden; }
|
|
23
|
+
th, td { padding: 0.85rem 1rem; text-align: left; border-bottom: 1px solid var(--border); }
|
|
24
|
+
th { background: rgba(0,0,0,0.2); font-weight: 600; color: var(--accent); }
|
|
25
|
+
pre { background: var(--surface); padding: 1rem; border-radius: 8px; border: 1px solid var(--border); overflow-x: auto; color: #a5b4fc; font-family: monospace; }
|
|
26
|
+
blockquote { border-left: 4px solid var(--accent); margin: 1rem 0; padding: 0.5rem 1rem; background: var(--surface); border-radius: 0 8px 8px 0; }
|
|
27
|
+
</style>
|
|
28
|
+
</head>
|
|
29
|
+
<body>
|
|
30
|
+
<div class="container">
|
|
31
|
+
{{CONTENT}}
|
|
32
|
+
</div>
|
|
33
|
+
</body>
|
|
34
|
+
</html>`
|
package/src/index.js
CHANGED
|
@@ -30,3 +30,9 @@ export { default as DepsCommand } from './domain/DepsCommand.js'
|
|
|
30
30
|
export { default as PublishCommand } from './domain/PublishCommand.js'
|
|
31
31
|
export { default as SpecCommand } from './domain/SpecCommand.js'
|
|
32
32
|
export { default as StatusCommand } from './domain/StatusCommand.js'
|
|
33
|
+
export { default as WebCommand } from './domain/WebCommand.js'
|
|
34
|
+
export { default as PreviewCommand } from './domain/PreviewCommand.js'
|
|
35
|
+
export { RegistryModel } from './domain/Registry/RegistryModel.js'
|
|
36
|
+
export { DashboardModel } from './domain/Dashboard/DashboardModel.js'
|
|
37
|
+
export { ReleaseAuditor } from './domain/inspect/ReleaseAuditor.js'
|
|
38
|
+
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Inspector: checks JavaScript/TypeScript files for syntax errors using `node --check`.
|
|
3
|
+
// Uses git to obtain list of changed files in the current HEAD.
|
|
4
|
+
const { execSync } = require('child_process');
|
|
5
|
+
|
|
6
|
+
function getChangedFiles() {
|
|
7
|
+
try {
|
|
8
|
+
const output = execSync('git diff --name-only --diff-filter=ACM HEAD', { encoding: 'utf8' });
|
|
9
|
+
return output.split(/\n/).filter(f => f.match(/\.(js|ts)$/));
|
|
10
|
+
} catch (e) {
|
|
11
|
+
console.error('Failed to obtain changed files:', e.message);
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function checkFile(file) {
|
|
17
|
+
console.log(`🔎 Checking ${file}`);
|
|
18
|
+
try {
|
|
19
|
+
execSync(`node --check ${file}`, { stdio: 'inherit' });
|
|
20
|
+
} catch (e) {
|
|
21
|
+
console.error(`❌ Syntax error in ${file}`);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const files = getChangedFiles();
|
|
27
|
+
if (files.length === 0) {
|
|
28
|
+
console.log('✅ No JavaScript/TypeScript files changed.');
|
|
29
|
+
process.exit(0);
|
|
30
|
+
}
|
|
31
|
+
files.forEach(checkFile);
|
|
32
|
+
process.exit(0);
|
|
@@ -9,7 +9,7 @@ describe('Release v3.0.0 - Dependency Alignment', () => {
|
|
|
9
9
|
const pkgPath = join(process.cwd(), 'package.json')
|
|
10
10
|
const pkg = JSON.parse(await readFile(pkgPath, 'utf8'))
|
|
11
11
|
|
|
12
|
-
assert.ok(/^3
|
|
12
|
+
assert.ok(/^3\.\d+\.\d+$/.test(pkg.version), 'Version should start with 3.x')
|
|
13
13
|
assert.ok(/^(\^1\.8\.0|workspace:\*)$/.test(pkg.dependencies['@nan0web/ui']), '@nan0web/ui should be ^1.8.0 or workspace:*')
|
|
14
14
|
assert.ok(/^(\^2\.9\.0|workspace:\*)$/.test(pkg.dependencies['@nan0web/ui-cli']), '@nan0web/ui-cli should be ^2.9.0 or workspace:*')
|
|
15
15
|
})
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
import { execSync } from 'node:child_process'
|
|
3
|
+
|
|
4
|
+
let rootGitStatusCache = null
|
|
5
|
+
let rootGitBranchCache = null
|
|
6
|
+
const gitInfoCache = new Map()
|
|
7
|
+
const gitTelemetryCache = new Map()
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Reset internal Git caches (useful for testing or cache invalidation)
|
|
11
|
+
*/
|
|
12
|
+
export function resetGitCache() {
|
|
13
|
+
rootGitStatusCache = null
|
|
14
|
+
rootGitBranchCache = null
|
|
15
|
+
gitInfoCache.clear()
|
|
16
|
+
gitTelemetryCache.clear()
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Retrieve git branch and workspace status (clean / dirty)
|
|
21
|
+
* @param {string} [projectDir]
|
|
22
|
+
* @returns {{ branch: string, gitStatus: 'clean' | 'dirty' }}
|
|
23
|
+
*/
|
|
24
|
+
export function getGitInfo(projectDir) {
|
|
25
|
+
const key = projectDir || process.cwd()
|
|
26
|
+
const isMonorepoInternal =
|
|
27
|
+
!projectDir ||
|
|
28
|
+
projectDir === '.' ||
|
|
29
|
+
(!projectDir.startsWith('../') && !projectDir.startsWith('/'))
|
|
30
|
+
|
|
31
|
+
if (isMonorepoInternal) {
|
|
32
|
+
if (rootGitStatusCache === null) {
|
|
33
|
+
try {
|
|
34
|
+
rootGitBranchCache =
|
|
35
|
+
execSync('git rev-parse --abbrev-ref HEAD', {
|
|
36
|
+
cwd: process.cwd(),
|
|
37
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
38
|
+
encoding: 'utf8',
|
|
39
|
+
}).trim() || 'main'
|
|
40
|
+
rootGitStatusCache = execSync('git status --porcelain', {
|
|
41
|
+
cwd: process.cwd(),
|
|
42
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
43
|
+
encoding: 'utf8',
|
|
44
|
+
}).trim()
|
|
45
|
+
} catch {
|
|
46
|
+
rootGitBranchCache = 'main'
|
|
47
|
+
rootGitStatusCache = ''
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const normPrefix =
|
|
51
|
+
projectDir && projectDir !== '.'
|
|
52
|
+
? `${projectDir.replace(/\/+$/, '')}/`
|
|
53
|
+
: ''
|
|
54
|
+
const isDirty = normPrefix
|
|
55
|
+
? rootGitStatusCache
|
|
56
|
+
.split('\n')
|
|
57
|
+
.some((line) => line.slice(3).trim().startsWith(normPrefix))
|
|
58
|
+
: rootGitStatusCache.length > 0
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
branch: rootGitBranchCache,
|
|
62
|
+
gitStatus: isDirty ? 'dirty' : 'clean',
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (gitInfoCache.has(key)) return gitInfoCache.get(key)
|
|
67
|
+
if (fs.existsSync && !fs.existsSync(key)) {
|
|
68
|
+
const res = { branch: 'main', gitStatus: 'clean' }
|
|
69
|
+
gitInfoCache.set(key, res)
|
|
70
|
+
return res
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
const branch = execSync('git rev-parse --abbrev-ref HEAD', {
|
|
75
|
+
cwd: key,
|
|
76
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
77
|
+
encoding: 'utf8',
|
|
78
|
+
}).trim()
|
|
79
|
+
const statusOutput = execSync('git status --porcelain', {
|
|
80
|
+
cwd: key,
|
|
81
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
82
|
+
encoding: 'utf8',
|
|
83
|
+
}).trim()
|
|
84
|
+
const res = {
|
|
85
|
+
branch: branch || 'main',
|
|
86
|
+
gitStatus: statusOutput.length > 0 ? 'dirty' : 'clean',
|
|
87
|
+
}
|
|
88
|
+
gitInfoCache.set(key, res)
|
|
89
|
+
return res
|
|
90
|
+
} catch {
|
|
91
|
+
const res = { branch: 'main', gitStatus: 'clean' }
|
|
92
|
+
gitInfoCache.set(key, res)
|
|
93
|
+
return res
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Retrieve development hours and iterations from git commit log
|
|
99
|
+
* @param {string} [projectDir]
|
|
100
|
+
* @param {string} [releasePath]
|
|
101
|
+
* @returns {{ hours: number, iterations: number }}
|
|
102
|
+
*/
|
|
103
|
+
export function getGitCommitTelemetry(projectDir, releasePath) {
|
|
104
|
+
const targetDir = releasePath || projectDir
|
|
105
|
+
if (!targetDir) return { hours: 0, iterations: 0 }
|
|
106
|
+
if (gitTelemetryCache.has(targetDir)) return gitTelemetryCache.get(targetDir)
|
|
107
|
+
if (fs.existsSync && !fs.existsSync(targetDir)) {
|
|
108
|
+
const res = { hours: 0, iterations: 0 }
|
|
109
|
+
gitTelemetryCache.set(targetDir, res)
|
|
110
|
+
return res
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
const logOutput = execSync(
|
|
115
|
+
`git log --format="%at" -n 50 -- "${targetDir}"`,
|
|
116
|
+
{
|
|
117
|
+
cwd: process.cwd(),
|
|
118
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
119
|
+
encoding: 'utf8',
|
|
120
|
+
}
|
|
121
|
+
).trim()
|
|
122
|
+
|
|
123
|
+
if (!logOutput) {
|
|
124
|
+
const res = { hours: 0, iterations: 0 }
|
|
125
|
+
gitTelemetryCache.set(targetDir, res)
|
|
126
|
+
return res
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const timestamps = logOutput
|
|
130
|
+
.split('\n')
|
|
131
|
+
.map((t) => parseInt(t.trim(), 10))
|
|
132
|
+
.filter((t) => !isNaN(t))
|
|
133
|
+
|
|
134
|
+
if (timestamps.length < 2) {
|
|
135
|
+
const res = { hours: 0.5, iterations: timestamps.length }
|
|
136
|
+
gitTelemetryCache.set(targetDir, res)
|
|
137
|
+
return res
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const minT = Math.min(...timestamps)
|
|
141
|
+
const maxT = Math.max(...timestamps)
|
|
142
|
+
const diffHours = Math.round(((maxT - minT) / 3600) * 10) / 10
|
|
143
|
+
const hours = diffHours > 0 ? diffHours : 0.5
|
|
144
|
+
const iterations = timestamps.length
|
|
145
|
+
|
|
146
|
+
const res = { hours, iterations }
|
|
147
|
+
gitTelemetryCache.set(targetDir, res)
|
|
148
|
+
return res
|
|
149
|
+
} catch {
|
|
150
|
+
const res = { hours: 0, iterations: 0 }
|
|
151
|
+
gitTelemetryCache.set(targetDir, res)
|
|
152
|
+
return res
|
|
153
|
+
}
|
|
154
|
+
}
|
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
import Person from './Person.js';
|
|
1
|
+
export default ReleaseDocument;
|
|
3
2
|
declare class ReleaseDocument extends Markdown {
|
|
4
|
-
/**
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
version: string;
|
|
10
|
-
/** @type {Date | undefined} */
|
|
11
|
-
date: Date | undefined;
|
|
3
|
+
/**
|
|
4
|
+
* @param {*} input
|
|
5
|
+
* @returns {ReleaseDocument}
|
|
6
|
+
*/
|
|
7
|
+
static from(input: any): ReleaseDocument;
|
|
12
8
|
/**
|
|
13
9
|
* @param {Object} options
|
|
14
10
|
* @param {Array} [options.team] - Release team members
|
|
@@ -17,22 +13,23 @@ declare class ReleaseDocument extends Markdown {
|
|
|
17
13
|
* @param {string} [options.date] - Release date
|
|
18
14
|
*/
|
|
19
15
|
constructor(options?: {
|
|
20
|
-
team?: any[];
|
|
21
|
-
roles?: Map<any, any> |
|
|
22
|
-
version?: string;
|
|
23
|
-
date?: string;
|
|
16
|
+
team?: any[] | undefined;
|
|
17
|
+
roles?: any[] | Map<any, any> | undefined;
|
|
18
|
+
version?: string | undefined;
|
|
19
|
+
date?: string | undefined;
|
|
24
20
|
});
|
|
25
|
-
/**
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
21
|
+
/** @type {Person[]} */
|
|
22
|
+
team: Person[];
|
|
23
|
+
/** @type {Map<string, Person[]>} */
|
|
24
|
+
roles: Map<string, Person[]>;
|
|
25
|
+
/** @type {string} */
|
|
26
|
+
version: string;
|
|
27
|
+
/** @type {Date | undefined} */
|
|
28
|
+
date: Date | undefined;
|
|
29
|
+
sections: {
|
|
30
|
+
title: string;
|
|
31
|
+
tasks: any[];
|
|
32
|
+
}[] | undefined;
|
|
37
33
|
}
|
|
38
|
-
|
|
34
|
+
import Markdown from '@nan0web/markdown';
|
|
35
|
+
import Person from './Person.js';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export default MarkdownToTest;
|
|
1
2
|
/**
|
|
2
3
|
* MarkdownToTest - generates node:test code from markdown release notes
|
|
3
4
|
* Enables writing release notes first, then generating executable tests
|
|
@@ -44,4 +45,3 @@ declare class MarkdownToTest {
|
|
|
44
45
|
tasks: any[];
|
|
45
46
|
}>): string;
|
|
46
47
|
}
|
|
47
|
-
export default MarkdownToTest;
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import { HumanName, HumanContact, HumanGender } from '@nan0web/logos';
|
|
2
1
|
export default class Person {
|
|
2
|
+
/**
|
|
3
|
+
* @param {*} input
|
|
4
|
+
* @returns {Person}
|
|
5
|
+
*/
|
|
6
|
+
static from(input: any): Person;
|
|
7
|
+
constructor(input?: {});
|
|
3
8
|
/** @type {HumanName} */
|
|
4
9
|
name: HumanName;
|
|
5
10
|
/** @type {HumanGender} */
|
|
6
11
|
gender: HumanGender;
|
|
7
12
|
/** @type {HumanContact[]} */
|
|
8
13
|
contacts: HumanContact[];
|
|
9
|
-
constructor(input?: {});
|
|
10
|
-
/**
|
|
11
|
-
* @param {*} input
|
|
12
|
-
* @returns {Person}
|
|
13
|
-
*/
|
|
14
|
-
static from(input: any): Person;
|
|
15
14
|
}
|
|
15
|
+
import { HumanName } from '@nan0web/logos';
|
|
16
|
+
import { HumanGender } from '@nan0web/logos';
|
|
17
|
+
import { HumanContact } from '@nan0web/logos';
|
|
@@ -1,39 +1,3 @@
|
|
|
1
|
-
export type ContractEntry = {
|
|
2
|
-
/**
|
|
3
|
-
* - Release version (e.g. "v1.0.0")
|
|
4
|
-
*/
|
|
5
|
-
version: string;
|
|
6
|
-
/**
|
|
7
|
-
* - Absolute path to the contract file
|
|
8
|
-
*/
|
|
9
|
-
path: string;
|
|
10
|
-
/**
|
|
11
|
-
* - "spec" or "test"
|
|
12
|
-
*/
|
|
13
|
-
type: string;
|
|
14
|
-
/**
|
|
15
|
-
* - Directory containing the contract
|
|
16
|
-
*/
|
|
17
|
-
dir: string;
|
|
18
|
-
};
|
|
19
|
-
export type VersionStatus = {
|
|
20
|
-
/**
|
|
21
|
-
* - Release version
|
|
22
|
-
*/
|
|
23
|
-
version: string;
|
|
24
|
-
/**
|
|
25
|
-
* - Version state
|
|
26
|
-
*/
|
|
27
|
-
state: 'wip' | 'closed' | 'mixed';
|
|
28
|
-
/**
|
|
29
|
-
* - Paths to spec files
|
|
30
|
-
*/
|
|
31
|
-
specs: string[];
|
|
32
|
-
/**
|
|
33
|
-
* - Paths to test files
|
|
34
|
-
*/
|
|
35
|
-
tests: string[];
|
|
36
|
-
};
|
|
37
1
|
/**
|
|
38
2
|
* @typedef {Object} ContractEntry
|
|
39
3
|
* @property {string} version - Release version (e.g. "v1.0.0")
|
|
@@ -54,13 +18,12 @@ export type VersionStatus = {
|
|
|
54
18
|
* та плоску: releases/v{version}/
|
|
55
19
|
*/
|
|
56
20
|
export default class Scanner {
|
|
57
|
-
#private;
|
|
58
|
-
/** @type {string} */
|
|
59
|
-
root: string;
|
|
60
21
|
/**
|
|
61
|
-
* @param {string} root - Root directory of the project
|
|
22
|
+
* @param {string} [root] - Root directory of the project
|
|
62
23
|
*/
|
|
63
|
-
constructor(root
|
|
24
|
+
constructor(root?: string);
|
|
25
|
+
/** @type {string} */
|
|
26
|
+
root: string;
|
|
64
27
|
/**
|
|
65
28
|
* Find all .spec.js files (WIP contracts)
|
|
66
29
|
* @param {string} [version] - Optional version filter
|
|
@@ -87,4 +50,41 @@ export default class Scanner {
|
|
|
87
50
|
closed: number;
|
|
88
51
|
files: string[];
|
|
89
52
|
};
|
|
53
|
+
#private;
|
|
90
54
|
}
|
|
55
|
+
export type ContractEntry = {
|
|
56
|
+
/**
|
|
57
|
+
* - Release version (e.g. "v1.0.0")
|
|
58
|
+
*/
|
|
59
|
+
version: string;
|
|
60
|
+
/**
|
|
61
|
+
* - Absolute path to the contract file
|
|
62
|
+
*/
|
|
63
|
+
path: string;
|
|
64
|
+
/**
|
|
65
|
+
* - "spec" or "test"
|
|
66
|
+
*/
|
|
67
|
+
type: string;
|
|
68
|
+
/**
|
|
69
|
+
* - Directory containing the contract
|
|
70
|
+
*/
|
|
71
|
+
dir: string;
|
|
72
|
+
};
|
|
73
|
+
export type VersionStatus = {
|
|
74
|
+
/**
|
|
75
|
+
* - Release version
|
|
76
|
+
*/
|
|
77
|
+
version: string;
|
|
78
|
+
/**
|
|
79
|
+
* - Version state
|
|
80
|
+
*/
|
|
81
|
+
state: "wip" | "closed" | "mixed";
|
|
82
|
+
/**
|
|
83
|
+
* - Paths to spec files
|
|
84
|
+
*/
|
|
85
|
+
specs: string[];
|
|
86
|
+
/**
|
|
87
|
+
* - Paths to test files
|
|
88
|
+
*/
|
|
89
|
+
tests: string[];
|
|
90
|
+
};
|
package/types/Release.d.ts
CHANGED
|
@@ -1,39 +1,3 @@
|
|
|
1
|
-
import ReleaseDocument from './Release/Document.js';
|
|
2
|
-
import Logger from '@nan0web/log';
|
|
3
|
-
export type ReleaseConfig = {
|
|
4
|
-
/**
|
|
5
|
-
* - Release version
|
|
6
|
-
*/
|
|
7
|
-
version?: string;
|
|
8
|
-
/**
|
|
9
|
-
* -
|
|
10
|
-
*/
|
|
11
|
-
createdAt?: string | number | Date | undefined;
|
|
12
|
-
/**
|
|
13
|
-
* - Alias for createdAt
|
|
14
|
-
*/
|
|
15
|
-
date?: string | number | Date | undefined;
|
|
16
|
-
/**
|
|
17
|
-
* -
|
|
18
|
-
*/
|
|
19
|
-
startAt?: string | number | Date | undefined;
|
|
20
|
-
/**
|
|
21
|
-
* -
|
|
22
|
-
*/
|
|
23
|
-
planAt?: string | number | Date | undefined;
|
|
24
|
-
/**
|
|
25
|
-
* -
|
|
26
|
-
*/
|
|
27
|
-
completeAt?: string | number | Date | undefined;
|
|
28
|
-
/**
|
|
29
|
-
* -
|
|
30
|
-
*/
|
|
31
|
-
document?: string | ReleaseDocument;
|
|
32
|
-
/**
|
|
33
|
-
* - Task map with test functions
|
|
34
|
-
*/
|
|
35
|
-
tasks?: Map<string, Function>;
|
|
36
|
-
};
|
|
37
1
|
/**
|
|
38
2
|
* @typedef {Object} ReleaseConfig
|
|
39
3
|
* @property {string} [version] - Release version
|
|
@@ -49,6 +13,11 @@ export type ReleaseConfig = {
|
|
|
49
13
|
* Release management class that coordinates task validation and release execution
|
|
50
14
|
*/
|
|
51
15
|
export default class Release {
|
|
16
|
+
/**
|
|
17
|
+
* Creates a Release instance
|
|
18
|
+
* @param {ReleaseConfig} config - Release configuration
|
|
19
|
+
*/
|
|
20
|
+
constructor(config?: ReleaseConfig);
|
|
52
21
|
/** @type {string} */
|
|
53
22
|
version: string;
|
|
54
23
|
/** @type {Date} */
|
|
@@ -65,11 +34,6 @@ export default class Release {
|
|
|
65
34
|
document: ReleaseDocument;
|
|
66
35
|
/** @type {Logger} */
|
|
67
36
|
logger: Logger;
|
|
68
|
-
/**
|
|
69
|
-
* Creates a Release instance
|
|
70
|
-
* @param {ReleaseConfig} config - Release configuration
|
|
71
|
-
*/
|
|
72
|
-
constructor(config?: ReleaseConfig);
|
|
73
37
|
get path(): string;
|
|
74
38
|
/**
|
|
75
39
|
* Validate release by running all task tests
|
|
@@ -83,7 +47,7 @@ export default class Release {
|
|
|
83
47
|
* @returns {Promise<boolean>} Release success status
|
|
84
48
|
*/
|
|
85
49
|
execute(options?: {
|
|
86
|
-
ignoreFailTests?: boolean;
|
|
50
|
+
ignoreFailTests?: boolean | undefined;
|
|
87
51
|
}): Promise<boolean>;
|
|
88
52
|
/**
|
|
89
53
|
* Get release progress statistics
|
|
@@ -91,3 +55,39 @@ export default class Release {
|
|
|
91
55
|
*/
|
|
92
56
|
getProgress(): Promise<any>;
|
|
93
57
|
}
|
|
58
|
+
export type ReleaseConfig = {
|
|
59
|
+
/**
|
|
60
|
+
* - Release version
|
|
61
|
+
*/
|
|
62
|
+
version?: string | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* -
|
|
65
|
+
*/
|
|
66
|
+
createdAt?: string | number | Date | undefined;
|
|
67
|
+
/**
|
|
68
|
+
* - Alias for createdAt
|
|
69
|
+
*/
|
|
70
|
+
date?: string | number | Date | undefined;
|
|
71
|
+
/**
|
|
72
|
+
* -
|
|
73
|
+
*/
|
|
74
|
+
startAt?: string | number | Date | undefined;
|
|
75
|
+
/**
|
|
76
|
+
* -
|
|
77
|
+
*/
|
|
78
|
+
planAt?: string | number | Date | undefined;
|
|
79
|
+
/**
|
|
80
|
+
* -
|
|
81
|
+
*/
|
|
82
|
+
completeAt?: string | number | Date | undefined;
|
|
83
|
+
/**
|
|
84
|
+
* -
|
|
85
|
+
*/
|
|
86
|
+
document?: string | ReleaseDocument | undefined;
|
|
87
|
+
/**
|
|
88
|
+
* - Task map with test functions
|
|
89
|
+
*/
|
|
90
|
+
tasks?: Map<string, Function> | undefined;
|
|
91
|
+
};
|
|
92
|
+
import ReleaseDocument from './Release/Document.js';
|
|
93
|
+
import Logger from '@nan0web/log';
|