@vibecuting/component-project-helper 0.1.13 → 0.1.15
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/package.json +1 -1
- package/scripts/discover-components.mjs +4 -0
- package/scripts/postinstall.mjs +39 -13
- package/scripts/preuninstall.mjs +11 -3
- package/src/discovery/index.test.ts +33 -0
- package/src/discovery/index.ts +4 -0
- package/src/lifecycle/postinstall.ts +43 -12
- package/src/lifecycle/preuninstall.ts +14 -2
package/package.json
CHANGED
package/scripts/postinstall.mjs
CHANGED
|
@@ -11,6 +11,16 @@ import {
|
|
|
11
11
|
import { renderComponentProjectMarkdown } from './render-markdown.mjs'
|
|
12
12
|
import { ComponentProjectGeneratedManifestSchema } from './schemas.mjs'
|
|
13
13
|
|
|
14
|
+
const supportsColor =
|
|
15
|
+
Boolean(process.stdout.isTTY) && process.env.NO_COLOR !== '1' && process.env.CI !== 'true'
|
|
16
|
+
|
|
17
|
+
const color = {
|
|
18
|
+
cyan: (value) => (supportsColor ? `\u001b[36m${value}\u001b[0m` : value),
|
|
19
|
+
green: (value) => (supportsColor ? `\u001b[32m${value}\u001b[0m` : value),
|
|
20
|
+
yellow: (value) => (supportsColor ? `\u001b[33m${value}\u001b[0m` : value),
|
|
21
|
+
dim: (value) => (supportsColor ? `\u001b[2m${value}\u001b[0m` : value),
|
|
22
|
+
}
|
|
23
|
+
|
|
14
24
|
async function ensureDirectory(dir) {
|
|
15
25
|
await fs.mkdir(dir, { recursive: true })
|
|
16
26
|
}
|
|
@@ -34,14 +44,16 @@ export async function runComponentProjectPostinstall(projectRoot = resolveCompon
|
|
|
34
44
|
const manifestPath = resolveComponentProjectGeneratedManifestPath(projectRoot)
|
|
35
45
|
const components = await discoverComponentProjectComponents(projectRoot)
|
|
36
46
|
|
|
37
|
-
console.log('[component-project-helper] postinstall start')
|
|
38
|
-
console.log(`[component-project-helper] project root: ${projectRoot}`)
|
|
39
|
-
console.log(`[component-project-helper] docs dir: ${docsDir}`)
|
|
40
|
-
console.log(`[component-project-helper] manifest path: ${manifestPath}`)
|
|
47
|
+
console.log(color.cyan('[component-project-helper] postinstall start'))
|
|
48
|
+
console.log(color.dim(`[component-project-helper] project root: ${projectRoot}`))
|
|
49
|
+
console.log(color.dim(`[component-project-helper] docs dir: ${docsDir}`))
|
|
50
|
+
console.log(color.dim(`[component-project-helper] manifest path: ${manifestPath}`))
|
|
41
51
|
console.log(
|
|
42
|
-
|
|
52
|
+
color.green(
|
|
53
|
+
`[component-project-helper] discovered ${components.length} component(s): ${
|
|
43
54
|
components.map((component) => component.name).join(', ') || '(none)'
|
|
44
|
-
|
|
55
|
+
}`,
|
|
56
|
+
),
|
|
45
57
|
)
|
|
46
58
|
|
|
47
59
|
await ensureDirectory(docsDir)
|
|
@@ -52,19 +64,23 @@ export async function runComponentProjectPostinstall(projectRoot = resolveCompon
|
|
|
52
64
|
await fs.writeFile(filePath, renderComponentProjectMarkdown(component), 'utf8')
|
|
53
65
|
files.push(filePath)
|
|
54
66
|
console.log(
|
|
55
|
-
|
|
67
|
+
color.green(
|
|
68
|
+
`[component-project-helper] wrote ${path.relative(projectRoot, filePath)} <- ${component.sourceFile}`,
|
|
69
|
+
),
|
|
56
70
|
)
|
|
57
71
|
}
|
|
58
72
|
|
|
59
73
|
console.log(
|
|
60
|
-
|
|
74
|
+
color.yellow(
|
|
75
|
+
`[component-project-helper] cleaning stale docs relative to manifest ${path.relative(
|
|
61
76
|
projectRoot,
|
|
62
77
|
manifestPath,
|
|
63
|
-
|
|
78
|
+
)}`,
|
|
79
|
+
),
|
|
64
80
|
)
|
|
65
81
|
await removeStaleGeneratedFiles(manifestPath, files)
|
|
66
82
|
await ensureComponentProjectSkillsScript(projectRoot)
|
|
67
|
-
console.log('[component-project-helper] ensured update-component-skills script')
|
|
83
|
+
console.log(color.green('[component-project-helper] ensured update-component-skills script'))
|
|
68
84
|
console.log('[component-project-helper] ensured stale docs cleaned')
|
|
69
85
|
|
|
70
86
|
const manifest = ComponentProjectGeneratedManifestSchema.parse({
|
|
@@ -75,12 +91,22 @@ export async function runComponentProjectPostinstall(projectRoot = resolveCompon
|
|
|
75
91
|
})
|
|
76
92
|
await fs.writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`, 'utf8')
|
|
77
93
|
console.log(
|
|
78
|
-
|
|
94
|
+
color.cyan(
|
|
95
|
+
`[component-project-helper] postinstall complete, manifest files: ${files.length}`,
|
|
96
|
+
),
|
|
79
97
|
)
|
|
80
98
|
}
|
|
81
99
|
|
|
82
|
-
|
|
100
|
+
async function isDirectRun() {
|
|
101
|
+
if (!process.argv[1]) {
|
|
102
|
+
return false
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const entryPath = await fs.realpath(process.argv[1])
|
|
106
|
+
const currentPath = await fs.realpath(new URL(import.meta.url).pathname)
|
|
107
|
+
return entryPath === currentPath
|
|
108
|
+
}
|
|
83
109
|
|
|
84
|
-
if (isDirectRun) {
|
|
110
|
+
if (await isDirectRun()) {
|
|
85
111
|
await runComponentProjectPostinstall()
|
|
86
112
|
}
|
package/scripts/preuninstall.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import fs from 'node:fs/promises'
|
|
2
|
-
import
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
3
|
|
|
4
4
|
import { resolveComponentProjectGeneratedManifestPath } from './runtime-root.mjs'
|
|
5
5
|
import { ComponentProjectGeneratedManifestSchema } from './schemas.mjs'
|
|
@@ -30,8 +30,16 @@ export async function runComponentProjectPreuninstall(
|
|
|
30
30
|
await removeComponentProjectSkillsScript(projectRoot)
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
async function isDirectRun() {
|
|
34
|
+
if (!process.argv[1]) {
|
|
35
|
+
return false
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const entryPath = await fs.realpath(process.argv[1])
|
|
39
|
+
const currentPath = await fs.realpath(fileURLToPath(import.meta.url))
|
|
40
|
+
return entryPath === currentPath
|
|
41
|
+
}
|
|
34
42
|
|
|
35
|
-
if (isDirectRun) {
|
|
43
|
+
if (await isDirectRun()) {
|
|
36
44
|
await runComponentProjectPreuninstall()
|
|
37
45
|
}
|
|
@@ -151,3 +151,36 @@ test('discovers decorated components from installed video-project-core', async (
|
|
|
151
151
|
},
|
|
152
152
|
])
|
|
153
153
|
})
|
|
154
|
+
|
|
155
|
+
test('ignores test files from installed packages', async () => {
|
|
156
|
+
const projectRoot = await fs.mkdtemp(path.join(tmpdir(), 'component-project-helper-tests-'))
|
|
157
|
+
const packageTestDir = path.join(
|
|
158
|
+
projectRoot,
|
|
159
|
+
'node_modules',
|
|
160
|
+
'@vibecuting',
|
|
161
|
+
'video-project-helper',
|
|
162
|
+
'src',
|
|
163
|
+
)
|
|
164
|
+
await fs.mkdir(packageTestDir, { recursive: true })
|
|
165
|
+
|
|
166
|
+
await fs.writeFile(
|
|
167
|
+
path.join(packageTestDir, 'index.test.ts'),
|
|
168
|
+
`
|
|
169
|
+
@VideoComponent({
|
|
170
|
+
name: 'ShouldBeIgnored',
|
|
171
|
+
description: 'This fixture lives in a test file and must not be discovered',
|
|
172
|
+
sourceFile: 'node_modules/@vibecuting/video-project-helper/src/index.test.ts',
|
|
173
|
+
aspectRatio: '16:9',
|
|
174
|
+
sceneType: 'scene',
|
|
175
|
+
tags: ['test'],
|
|
176
|
+
propsTypeName: 'ShouldBeIgnoredProps',
|
|
177
|
+
})
|
|
178
|
+
export const ShouldBeIgnored = () => null
|
|
179
|
+
`,
|
|
180
|
+
'utf8',
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
const discovered = await discoverComponentProjectComponents(projectRoot)
|
|
184
|
+
|
|
185
|
+
expect(discovered).toEqual([])
|
|
186
|
+
})
|
package/src/discovery/index.ts
CHANGED
|
@@ -12,6 +12,16 @@ import {
|
|
|
12
12
|
} from '../runtime'
|
|
13
13
|
import { ensureComponentProjectSkillsScript } from './package-json'
|
|
14
14
|
|
|
15
|
+
const supportsColor =
|
|
16
|
+
Boolean(process.stdout.isTTY) && process.env.NO_COLOR !== '1' && process.env.CI !== 'true'
|
|
17
|
+
|
|
18
|
+
const color = {
|
|
19
|
+
cyan: (value: string): string => (supportsColor ? `\u001b[36m${value}\u001b[0m` : value),
|
|
20
|
+
green: (value: string): string => (supportsColor ? `\u001b[32m${value}\u001b[0m` : value),
|
|
21
|
+
yellow: (value: string): string => (supportsColor ? `\u001b[33m${value}\u001b[0m` : value),
|
|
22
|
+
dim: (value: string): string => (supportsColor ? `\u001b[2m${value}\u001b[0m` : value),
|
|
23
|
+
}
|
|
24
|
+
|
|
15
25
|
async function ensureDirectory(dir: string): Promise<void> {
|
|
16
26
|
await fs.mkdir(dir, { recursive: true })
|
|
17
27
|
}
|
|
@@ -40,14 +50,16 @@ export async function runComponentProjectPostinstall(
|
|
|
40
50
|
const manifestPath = resolveComponentProjectGeneratedManifestPath(projectRoot)
|
|
41
51
|
const components = await discoverComponentProjectComponents(projectRoot)
|
|
42
52
|
|
|
43
|
-
console.log('[component-project-helper] postinstall start')
|
|
44
|
-
console.log(`[component-project-helper] project root: ${projectRoot}`)
|
|
45
|
-
console.log(`[component-project-helper] docs dir: ${docsDir}`)
|
|
46
|
-
console.log(`[component-project-helper] manifest path: ${manifestPath}`)
|
|
53
|
+
console.log(color.cyan('[component-project-helper] postinstall start'))
|
|
54
|
+
console.log(color.dim(`[component-project-helper] project root: ${projectRoot}`))
|
|
55
|
+
console.log(color.dim(`[component-project-helper] docs dir: ${docsDir}`))
|
|
56
|
+
console.log(color.dim(`[component-project-helper] manifest path: ${manifestPath}`))
|
|
47
57
|
console.log(
|
|
48
|
-
|
|
58
|
+
color.green(
|
|
59
|
+
`[component-project-helper] discovered ${components.length} component(s): ${
|
|
49
60
|
components.map((component) => component.name).join(', ') || '(none)'
|
|
50
|
-
|
|
61
|
+
}`,
|
|
62
|
+
),
|
|
51
63
|
)
|
|
52
64
|
|
|
53
65
|
await ensureDirectory(docsDir)
|
|
@@ -60,19 +72,23 @@ export async function runComponentProjectPostinstall(
|
|
|
60
72
|
await fs.writeFile(filePath, markdown, 'utf8')
|
|
61
73
|
files.push(filePath)
|
|
62
74
|
console.log(
|
|
63
|
-
|
|
75
|
+
color.green(
|
|
76
|
+
`[component-project-helper] wrote ${path.relative(projectRoot, filePath)} <- ${component.sourceFile}`,
|
|
77
|
+
),
|
|
64
78
|
)
|
|
65
79
|
}
|
|
66
80
|
|
|
67
81
|
console.log(
|
|
68
|
-
|
|
82
|
+
color.yellow(
|
|
83
|
+
`[component-project-helper] cleaning stale docs relative to manifest ${path.relative(
|
|
69
84
|
projectRoot,
|
|
70
85
|
manifestPath,
|
|
71
|
-
|
|
86
|
+
)}`,
|
|
87
|
+
),
|
|
72
88
|
)
|
|
73
89
|
await removeStaleGeneratedFiles(manifestPath, files)
|
|
74
90
|
await ensureComponentProjectSkillsScript(projectRoot)
|
|
75
|
-
console.log('[component-project-helper] ensured update-component-skills script')
|
|
91
|
+
console.log(color.green('[component-project-helper] ensured update-component-skills script'))
|
|
76
92
|
|
|
77
93
|
const manifest = ComponentProjectGeneratedManifestSchema.parse({
|
|
78
94
|
projectRoot,
|
|
@@ -83,14 +99,29 @@ export async function runComponentProjectPostinstall(
|
|
|
83
99
|
|
|
84
100
|
await fs.writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`, 'utf8')
|
|
85
101
|
console.log(
|
|
86
|
-
|
|
102
|
+
color.cyan(
|
|
103
|
+
`[component-project-helper] postinstall complete, manifest files: ${files.length}`,
|
|
104
|
+
),
|
|
87
105
|
)
|
|
88
106
|
}
|
|
89
107
|
|
|
108
|
+
async function isDirectRun(): Promise<boolean> {
|
|
109
|
+
if (!process.argv[1]) {
|
|
110
|
+
return false
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const [entryPath, currentPath] = await Promise.all([
|
|
114
|
+
fs.realpath(process.argv[1]),
|
|
115
|
+
fs.realpath(fileURLToPath(import.meta.url)),
|
|
116
|
+
])
|
|
117
|
+
|
|
118
|
+
return entryPath === currentPath
|
|
119
|
+
}
|
|
120
|
+
|
|
90
121
|
async function main(): Promise<void> {
|
|
91
122
|
await runComponentProjectPostinstall()
|
|
92
123
|
}
|
|
93
124
|
|
|
94
|
-
if (
|
|
125
|
+
if (await isDirectRun()) {
|
|
95
126
|
await main()
|
|
96
127
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import fs from 'node:fs/promises'
|
|
2
|
-
import path from 'node:path'
|
|
3
2
|
import { fileURLToPath } from 'node:url'
|
|
4
3
|
|
|
5
4
|
import { ComponentProjectGeneratedManifestSchema } from '../schemas'
|
|
@@ -37,6 +36,19 @@ async function main(): Promise<void> {
|
|
|
37
36
|
await runComponentProjectPreuninstall()
|
|
38
37
|
}
|
|
39
38
|
|
|
40
|
-
|
|
39
|
+
async function isDirectRun(): Promise<boolean> {
|
|
40
|
+
if (!process.argv[1]) {
|
|
41
|
+
return false
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const [entryPath, currentPath] = await Promise.all([
|
|
45
|
+
fs.realpath(process.argv[1]),
|
|
46
|
+
fs.realpath(fileURLToPath(import.meta.url)),
|
|
47
|
+
])
|
|
48
|
+
|
|
49
|
+
return entryPath === currentPath
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (await isDirectRun()) {
|
|
41
53
|
await main()
|
|
42
54
|
}
|