@nan0web/release 3.2.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.
Files changed (69) hide show
  1. package/bin/nan0release.js +33 -2
  2. package/bin/serve.js +73 -0
  3. package/package.json +45 -17
  4. package/src/Release/Document.js +1 -0
  5. package/src/Release/Scanner.js +3 -2
  6. package/src/Release.js +7 -7
  7. package/src/domain/App.js +31 -2
  8. package/src/domain/BumpCommand.js +10 -3
  9. package/src/domain/CheckCommand.js +504 -146
  10. package/src/domain/CheckCommand.story.js +92 -0
  11. package/src/domain/CloseCommand.js +13 -9
  12. package/src/domain/Dashboard/Dashboard.story.js +155 -0
  13. package/src/domain/Dashboard/DashboardModel.js +308 -0
  14. package/src/domain/Dashboard/ReleaseDiscovery.js +132 -0
  15. package/src/domain/Dashboard/ReleaseParser.js +226 -0
  16. package/src/domain/Dashboard/index.js +19 -0
  17. package/src/domain/DepsCommand.js +5 -2
  18. package/src/domain/InitCommand.js +18 -16
  19. package/src/domain/ListCommand.js +45 -0
  20. package/src/domain/PreviewCommand.js +39 -0
  21. package/src/domain/PublishCommand.js +7 -3
  22. package/src/domain/Registry/Registry.story.js +82 -0
  23. package/src/domain/Registry/RegistryModel.js +124 -0
  24. package/src/domain/ServeCommand.js +165 -0
  25. package/src/domain/ServeCommand.story.js +88 -0
  26. package/src/domain/SpecCommand.js +3 -1
  27. package/src/domain/StatusCommand.js +249 -3
  28. package/src/domain/ViewCommand.js +99 -0
  29. package/src/domain/WebCommand.js +140 -0
  30. package/src/domain/inspect/ReleaseAuditor.js +508 -0
  31. package/src/domain/inspect/ReleaseAuditor.story.js +136 -0
  32. package/src/domain/templates/release.html +34 -0
  33. package/src/domain/templates/release.html.template.js +34 -0
  34. package/src/index.js +6 -0
  35. package/src/inspectors/inspect-js.js +32 -0
  36. package/src/releases/1/0/v1.0.3/task.test.js +1 -1
  37. package/src/utils/nodejs/GitTelemetry.js +154 -0
  38. package/types/Release/Document.d.ts +4 -0
  39. package/types/Release/Scanner.d.ts +2 -2
  40. package/types/domain/App.d.ts +19 -3
  41. package/types/domain/BumpCommand.d.ts +9 -3
  42. package/types/domain/CheckCommand.d.ts +127 -15
  43. package/types/domain/CheckCommand.story.d.ts +1 -0
  44. package/types/domain/CloseCommand.d.ts +2 -1
  45. package/types/domain/Dashboard/Dashboard.story.d.ts +1 -0
  46. package/types/domain/Dashboard/DashboardModel.d.ts +273 -0
  47. package/types/domain/Dashboard/GitTelemetry.d.ts +23 -0
  48. package/types/domain/Dashboard/ReleaseDiscovery.d.ts +47 -0
  49. package/types/domain/Dashboard/ReleaseParser.d.ts +79 -0
  50. package/types/domain/Dashboard/index.d.ts +3 -0
  51. package/types/domain/DepsCommand.d.ts +4 -2
  52. package/types/domain/InitCommand.d.ts +2 -1
  53. package/types/domain/ListCommand.d.ts +18 -0
  54. package/types/domain/PreviewCommand.d.ts +6 -0
  55. package/types/domain/PublishCommand.d.ts +6 -3
  56. package/types/domain/Registry/Registry.story.d.ts +1 -0
  57. package/types/domain/Registry/RegistryModel.d.ts +61 -0
  58. package/types/domain/ServeCommand.d.ts +59 -0
  59. package/types/domain/ServeCommand.story.d.ts +1 -0
  60. package/types/domain/SpecCommand.d.ts +2 -1
  61. package/types/domain/StatusCommand.d.ts +39 -0
  62. package/types/domain/ViewCommand.d.ts +27 -0
  63. package/types/domain/WebCommand.d.ts +47 -0
  64. package/types/domain/inspect/ReleaseAuditor.d.ts +134 -0
  65. package/types/domain/inspect/ReleaseAuditor.story.d.ts +1 -0
  66. package/types/domain/templates/release.html.template.d.ts +2 -0
  67. package/types/index.d.ts +5 -0
  68. package/types/inspectors/inspect-js.d.ts +2 -0
  69. package/types/utils/nodejs/GitTelemetry.d.ts +23 -0
@@ -1,6 +1,37 @@
1
1
  #!/usr/bin/env node
2
-
2
+ import { existsSync } from 'node:fs'
3
+ import { resolve, dirname } from 'node:path'
3
4
  import { bootstrapApp } from '@nan0web/ui-cli'
5
+ import DBFS from '@nan0web/db-fs'
4
6
  import { ReleaseApp } from '../src/domain/App.js'
5
7
 
6
- bootstrapApp(ReleaseApp)
8
+ function findMonorepoRoot(startDir) {
9
+ let dir = resolve(startDir)
10
+ const markers = ['pnpm-workspace.yaml', 'releases.txt']
11
+ for (let i = 0; i < 10; i++) {
12
+ for (const marker of markers) {
13
+ if (existsSync(resolve(dir, marker))) {
14
+ return dir
15
+ }
16
+ }
17
+ const parent = dirname(dir)
18
+ if (parent === dir) break
19
+ dir = parent
20
+ }
21
+ return startDir
22
+ }
23
+
24
+ const startCwd = process.env.INIT_CWD || process.cwd()
25
+ process.env.RELEASE_CWD = startCwd
26
+ const root = findMonorepoRoot(startCwd)
27
+ if (process.cwd() !== root && existsSync(resolve(root, 'releases.txt'))) {
28
+ process.chdir(root)
29
+ }
30
+
31
+ const db = new DBFS()
32
+ await db.connect()
33
+
34
+ bootstrapApp(ReleaseApp, { db }).catch((err) => {
35
+ console.error(err)
36
+ process.exit(1)
37
+ })
package/bin/serve.js ADDED
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync } from 'node:fs'
3
+ import { resolve, dirname } from 'node:path'
4
+ import { bootstrapApp } from '@nan0web/ui-cli'
5
+ import DBFS from '@nan0web/db-fs'
6
+ import { ServeCommand } from '../src/domain/ServeCommand.js'
7
+
8
+ function findMonorepoRoot(startDir) {
9
+ let dir = resolve(startDir)
10
+ const markers = ['pnpm-workspace.yaml', 'releases.txt']
11
+ for (let i = 0; i < 10; i++) {
12
+ for (const marker of markers) {
13
+ if (existsSync(resolve(dir, marker))) {
14
+ return dir
15
+ }
16
+ }
17
+ const parent = dirname(dir)
18
+ if (parent === dir) break
19
+ dir = parent
20
+ }
21
+ return startDir
22
+ }
23
+
24
+ const startCwd = process.env.INIT_CWD || process.cwd()
25
+ process.env.RELEASE_CWD = startCwd
26
+ const root = findMonorepoRoot(startCwd)
27
+ if (process.cwd() !== root && existsSync(resolve(root, 'releases.txt'))) {
28
+ process.chdir(root)
29
+ }
30
+
31
+ const db = new DBFS()
32
+ await db.connect()
33
+
34
+ const res = await bootstrapApp(ServeCommand, { db, noExit: true }).catch((err) => {
35
+ console.error(err)
36
+ process.exit(1)
37
+ })
38
+
39
+ const resultIntent = res?.data || {}
40
+ const data = resultIntent?.data || resultIntent || {}
41
+ if (data.success && data.html) {
42
+ try {
43
+ const { createServer } = await import('node:http')
44
+ const port = data.port || 3131
45
+ const server = createServer((req, resHttp) => {
46
+ resHttp.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' })
47
+ resHttp.end(data.html)
48
+ })
49
+
50
+ server.listen(port, () => {
51
+ if (data.open) {
52
+ import('node:child_process')
53
+ .then(({ exec }) => exec(`open http://localhost:${port}`))
54
+ .catch(() => {})
55
+ }
56
+ })
57
+
58
+ const stopServer = () => {
59
+ server.close(() => {
60
+ process.exit(0)
61
+ })
62
+ }
63
+
64
+ process.on('SIGINT', stopServer)
65
+ process.on('SIGTERM', stopServer)
66
+ } catch (err) {
67
+ console.error(`Failed to start HTTP server: ${err.message}`)
68
+ process.exit(1)
69
+ }
70
+ } else if (data.success === false) {
71
+ process.exit(1)
72
+ }
73
+
package/package.json CHANGED
@@ -1,31 +1,58 @@
1
1
  {
2
2
  "name": "@nan0web/release",
3
- "version": "3.2.0",
3
+ "version": "3.4.0",
4
4
  "description": "Project Management as Code, Git-Native, GPG-Signed, Test-Driven",
5
5
  "main": "src/index.js",
6
6
  "types": "types/index.d.ts",
7
7
  "type": "module",
8
8
  "bin": {
9
9
  "nan0release": "./bin/nan0release.js",
10
- "release": "./bin/nan0release.js"
10
+ "release": "./bin/nan0release.js",
11
+ "serve": "./bin/serve.js"
12
+ },
13
+ "exports": {
14
+ ".": {
15
+ "import": "./src/index.js",
16
+ "types": "./types/index.d.ts"
17
+ },
18
+ "./domain/inspect/ReleaseAuditor": {
19
+ "import": "./src/domain/inspect/ReleaseAuditor.js",
20
+ "types": "./types/domain/inspect/ReleaseAuditor.d.ts"
21
+ },
22
+ "./domain/CheckCommand": {
23
+ "import": "./src/domain/CheckCommand.js",
24
+ "types": "./types/domain/CheckCommand.d.ts"
25
+ },
26
+ "./domain/StatusCommand": {
27
+ "import": "./src/domain/StatusCommand.js",
28
+ "types": "./types/domain/StatusCommand.d.ts"
29
+ },
30
+ "./domain/App": {
31
+ "import": "./src/domain/App.js",
32
+ "types": "./types/domain/App.d.ts"
33
+ },
34
+ "./domain/*": {
35
+ "import": "./src/domain/*.js"
36
+ }
11
37
  },
12
38
  "dependencies": {
13
- "@nan0web/co": "3.2.0",
14
- "@nan0web/db": "3.2.0",
15
- "@nan0web/ui": "3.2.0",
16
- "@nan0web/types": "3.2.0",
17
- "@nan0web/db-fs": "3.2.0",
18
- "@nan0web/log": "3.2.0",
19
- "@nan0web/markdown": "3.2.0",
20
- "@nan0web/changelog": "3.2.0",
21
- "@nan0web/ui-cli": "3.2.0",
22
- "@nan0web/logos": "3.2.0"
39
+ "@nan0web/changelog": "3.4.0",
40
+ "@nan0web/db": "3.4.0",
41
+ "@nan0web/log": "3.4.0",
42
+ "@nan0web/logos": "3.4.0",
43
+ "@nan0web/co": "3.4.0",
44
+ "@nan0web/inspect": "3.4.0",
45
+ "@nan0web/types": "3.4.0",
46
+ "@nan0web/ui": "3.4.0",
47
+ "@nan0web/ui-cli": "3.4.0",
48
+ "@nan0web/db-fs": "3.4.0",
49
+ "@nan0web/markdown": "3.4.0"
23
50
  },
24
51
  "devDependencies": {
25
52
  "@types/node": "^25.6.0",
26
53
  "husky": "^9.1.7",
27
- "knip": "^5.86.0",
28
- "@nan0web/test": "3.2.0"
54
+ "knip": "^5.88.1",
55
+ "@nan0web/test": "3.4.0"
29
56
  },
30
57
  "files": [
31
58
  "bin",
@@ -39,11 +66,12 @@
39
66
  "build": "tsc",
40
67
  "clean": "rm -rf .cache/ && rm -rf dist/",
41
68
  "clean:modules": "rm -rf node_modules",
42
- "test": "node --test \"src/**/*.test.js\"",
43
- "test1": "node --test \"src/**/*.test.js\" | nan0test parse --fail",
69
+ "test": "node --test \"src/**/*.{test,story}.js\"",
70
+ "test:stories": "node --test \"src/**/*.story.js\"",
71
+ "test1": "node --test \"src/**/*.{test,story}.js\" | nan0test parse --fail",
44
72
  "test:docs": "node --test \"src/README.md.js\"",
45
73
  "test:release": "node --test \"releases/**/*.test.js\"",
46
- "test:coverage": "node --experimental-test-coverage --test-coverage-include=\"src/**/*.js\" --test-coverage-exclude=\"src/**/*.test.js\" --test \"src/**/*.test.js\"",
74
+ "test:coverage": "node --experimental-test-coverage --test-coverage-include=\"src/**/*.js\" --test-coverage-exclude=\"src/**/*.{test,story}.js\" --test \"src/**/*.{test,story}.js\"",
47
75
  "test:coverage:collect": "nan0test coverage",
48
76
  "test:status": "nan0test status",
49
77
  "test:all": "npm run test && npm run test:docs && npm run build && npm run knip",
@@ -83,6 +83,7 @@ class ReleaseDocument extends Markdown {
83
83
  }
84
84
  }
85
85
 
86
+ this.sections = sections
86
87
  return result
87
88
  }
88
89
 
@@ -27,10 +27,11 @@ export default class Scanner {
27
27
  root
28
28
 
29
29
  /**
30
- * @param {string} root - Root directory of the project
30
+ * @param {string} [root] - Root directory of the project
31
31
  */
32
32
  constructor(root) {
33
- this.root = resolve(root)
33
+ const targetRoot = root || process.env.INIT_CWD || process.cwd()
34
+ this.root = resolve(targetRoot)
34
35
  }
35
36
 
36
37
  /**
package/src/Release.js CHANGED
@@ -18,21 +18,21 @@ import Logger from '@nan0web/log'
18
18
  */
19
19
  export default class Release {
20
20
  /** @type {string} */
21
- version
21
+ version = '0.0.0'
22
22
  /** @type {Date} */
23
- createdAt
23
+ createdAt = new Date()
24
24
  /** @type {Date?} */
25
- startAt
25
+ startAt = null
26
26
  /** @type {Date?} */
27
- planAt
27
+ planAt = null
28
28
  /** @type {Date?} */
29
- completeAt
29
+ completeAt = null
30
30
  /** @type {Map<string, Function>} */
31
- tasks
31
+ tasks = new Map()
32
32
  /** @type {ReleaseDocument} */
33
33
  document
34
34
  /** @type {Logger} */
35
- logger
35
+ logger = new Logger()
36
36
 
37
37
  /**
38
38
  * Creates a Release instance
package/src/domain/App.js CHANGED
@@ -7,8 +7,19 @@ import PublishCommand from './PublishCommand.js'
7
7
  import SpecCommand from './SpecCommand.js'
8
8
  import StatusCommand from './StatusCommand.js'
9
9
  import BumpCommand from './BumpCommand.js'
10
+ import WebCommand from './WebCommand.js'
11
+ import PreviewCommand from './PreviewCommand.js'
12
+ import ViewCommand from './ViewCommand.js'
13
+ import ListCommand from './ListCommand.js'
14
+ import ServeCommand from './ServeCommand.js'
10
15
 
11
16
  export class ReleaseApp extends ModelAsApp {
17
+ static alias = 'release'
18
+
19
+ static UI = {
20
+ title: 'PM-as-Code Release Protocol (nan0release)',
21
+ }
22
+
12
23
  static command = {
13
24
  help: 'Subcommand to run',
14
25
  options: [
@@ -20,9 +31,14 @@ export class ReleaseApp extends ModelAsApp {
20
31
  SpecCommand,
21
32
  StatusCommand,
22
33
  BumpCommand,
34
+ WebCommand,
35
+ PreviewCommand,
36
+ ViewCommand,
37
+ ListCommand,
38
+ ServeCommand,
23
39
  ],
24
40
  positional: true,
25
- default: null,
41
+ default: ViewCommand,
26
42
  }
27
43
 
28
44
  /**
@@ -31,6 +47,19 @@ export class ReleaseApp extends ModelAsApp {
31
47
  */
32
48
  constructor(data = {}, options = {}) {
33
49
  super(data, options)
34
- /** @type {ModelAsApp} Subcommand to run */ this.command
50
+ }
51
+
52
+ /**
53
+ * Run the main controller logic.
54
+ * @returns {AsyncGenerator<import('@nan0web/ui').Intent, any, any>}
55
+ */
56
+ async *run() {
57
+ if (this.help || !this.command || typeof this.command.run !== 'function') {
58
+ return yield* super.run()
59
+ }
60
+ return yield* this.command.run()
35
61
  }
36
62
  }
63
+
64
+ export default ReleaseApp
65
+
@@ -3,8 +3,18 @@ import { runSpawn } from '@nan0web/test'
3
3
 
4
4
  /**
5
5
  * Command to bump the version of changed packages in the monorepo.
6
+ * @property {string} version Target version to set
7
+ * @property {string} since Git reference to diff against
8
+ * @property {boolean} dryRun Run the command without making any changes
6
9
  */
7
10
  export default class BumpCommand extends ModelAsApp {
11
+ /** @type {string} Target version */
12
+ version = '3.1.1'
13
+ /** @type {string} Git reference to diff against */
14
+ since = 'v3.1.0'
15
+ /** @type {boolean} Run without making changes */
16
+ dryRun = false
17
+
8
18
  static version = {
9
19
  help: 'Target version to set',
10
20
  default: '3.1.1',
@@ -38,9 +48,6 @@ export default class BumpCommand extends ModelAsApp {
38
48
  */
39
49
  constructor(data = {}, options = {}) {
40
50
  super(data, options)
41
- /** @type {string} Target version */ this.version
42
- /** @type {string} Since reference */ this.since
43
- /** @type {boolean} Dry run */ this.dryRun
44
51
  }
45
52
 
46
53
  /**