react-native-varia 0.4.5 → 0.4.6
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/cli.js +320 -252
- package/lib/components/Select.tsx +0 -1
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -1,394 +1,462 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const {
|
|
4
|
-
const inquirer = require(
|
|
5
|
-
const path = require(
|
|
6
|
-
const fs = require(
|
|
3
|
+
const {program} = require('commander')
|
|
4
|
+
const inquirer = require('inquirer')
|
|
5
|
+
const path = require('path')
|
|
6
|
+
const fs = require('fs-extra')
|
|
7
7
|
|
|
8
8
|
const COMPONENT_DEPENDENCIES = {
|
|
9
|
-
Button: [
|
|
10
|
-
Field: [
|
|
11
|
-
Link: [
|
|
12
|
-
Modal: [
|
|
13
|
-
ReText: [
|
|
14
|
-
Select: [
|
|
15
|
-
}
|
|
9
|
+
Button: ['Spinner', 'IconWrapper'],
|
|
10
|
+
Field: ['Text'],
|
|
11
|
+
Link: ['Text'],
|
|
12
|
+
Modal: ['Text'],
|
|
13
|
+
ReText: ['Text'],
|
|
14
|
+
Select: ['Text'],
|
|
15
|
+
}
|
|
16
16
|
|
|
17
17
|
const ICON_DEPENDENCIES = {
|
|
18
|
-
NumberInput: [
|
|
19
|
-
}
|
|
18
|
+
NumberInput: ['Plus', 'Minus'],
|
|
19
|
+
}
|
|
20
20
|
|
|
21
21
|
const CONTEXT_DEPENDENCIES = {
|
|
22
|
-
Field: true
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function copyContextComponentIfNeeded(component, destComponents, overwrite = true) {
|
|
26
|
-
if (!CONTEXT_DEPENDENCIES[component]) return;
|
|
22
|
+
Field: true,
|
|
23
|
+
}
|
|
27
24
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
function copyContextComponentIfNeeded(
|
|
26
|
+
component,
|
|
27
|
+
destComponents,
|
|
28
|
+
overwrite = true,
|
|
29
|
+
) {
|
|
30
|
+
if (!CONTEXT_DEPENDENCIES[component]) return
|
|
31
|
+
|
|
32
|
+
const contextSrc = path.join(COMPONENTS_DIR, 'context', `${component}.tsx`)
|
|
33
|
+
const contextDest = path.join(
|
|
34
|
+
process.cwd(),
|
|
35
|
+
destComponents,
|
|
36
|
+
'context',
|
|
37
|
+
`${component}.tsx`,
|
|
38
|
+
)
|
|
39
|
+
copyFile(contextSrc, contextDest, `Context of "${component}"`, overwrite)
|
|
31
40
|
}
|
|
32
41
|
|
|
33
42
|
function resolveDependencies(component, seen = new Set()) {
|
|
34
|
-
if (seen.has(component)) return []
|
|
35
|
-
seen.add(component)
|
|
43
|
+
if (seen.has(component)) return []
|
|
44
|
+
seen.add(component)
|
|
36
45
|
|
|
37
|
-
const deps = COMPONENT_DEPENDENCIES[component] || []
|
|
38
|
-
let allDeps = [...deps]
|
|
46
|
+
const deps = COMPONENT_DEPENDENCIES[component] || []
|
|
47
|
+
let allDeps = [...deps]
|
|
39
48
|
|
|
40
49
|
for (const dep of deps) {
|
|
41
|
-
allDeps = [...allDeps, ...resolveDependencies(dep, seen)]
|
|
50
|
+
allDeps = [...allDeps, ...resolveDependencies(dep, seen)]
|
|
42
51
|
}
|
|
43
52
|
|
|
44
|
-
return [...new Set(allDeps)]
|
|
53
|
+
return [...new Set(allDeps)]
|
|
45
54
|
}
|
|
46
55
|
|
|
47
|
-
const COMPONENTS_DIR = path.join(__dirname,
|
|
48
|
-
const THEME_DIR = path.join(__dirname,
|
|
56
|
+
const COMPONENTS_DIR = path.join(__dirname, '../lib/components')
|
|
57
|
+
const THEME_DIR = path.join(__dirname, '../lib/theme')
|
|
49
58
|
|
|
50
59
|
function getAvailableComponents() {
|
|
51
|
-
if (!fs.existsSync(COMPONENTS_DIR)) return []
|
|
52
|
-
return fs.readdirSync(COMPONENTS_DIR).map(
|
|
60
|
+
if (!fs.existsSync(COMPONENTS_DIR)) return []
|
|
61
|
+
return fs.readdirSync(COMPONENTS_DIR).map(name => path.parse(name).name)
|
|
53
62
|
}
|
|
54
63
|
|
|
55
64
|
function copyFile(srcPath, destPath, label, overwrite = true) {
|
|
56
65
|
if (!fs.existsSync(srcPath)) {
|
|
57
|
-
console.warn(`⚠️ ${label}
|
|
58
|
-
return false
|
|
66
|
+
console.warn(`⚠️ ${label} not found: ${srcPath}`)
|
|
67
|
+
return false
|
|
59
68
|
}
|
|
60
69
|
try {
|
|
61
|
-
fs.ensureDirSync(path.dirname(destPath))
|
|
70
|
+
fs.ensureDirSync(path.dirname(destPath))
|
|
62
71
|
|
|
63
72
|
if (!overwrite && fs.existsSync(destPath)) {
|
|
64
|
-
console.log(`⏭️
|
|
65
|
-
return false
|
|
73
|
+
console.log(`⏭️ Skipping ${label}, already exists in ${destPath}`)
|
|
74
|
+
return false
|
|
66
75
|
}
|
|
67
76
|
|
|
68
|
-
fs.copySync(srcPath, destPath, {
|
|
69
|
-
console.log(`✅ ${label}
|
|
70
|
-
return true
|
|
77
|
+
fs.copySync(srcPath, destPath, {overwrite: true})
|
|
78
|
+
console.log(`✅ ${label} copied to: ${destPath}`)
|
|
79
|
+
return true
|
|
71
80
|
} catch (err) {
|
|
72
|
-
console.error(`❌
|
|
73
|
-
return false
|
|
81
|
+
console.error(`❌ Couldn't copy ${label}: ${err.message}`)
|
|
82
|
+
return false
|
|
74
83
|
}
|
|
75
84
|
}
|
|
76
85
|
|
|
77
|
-
function copyComponentAndRecipe(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const
|
|
84
|
-
|
|
86
|
+
function copyComponentAndRecipe(
|
|
87
|
+
component,
|
|
88
|
+
destComponents,
|
|
89
|
+
destTheme,
|
|
90
|
+
overwrite = true,
|
|
91
|
+
) {
|
|
92
|
+
const componentSrc = path.join(COMPONENTS_DIR, `${component}.tsx`)
|
|
93
|
+
const componentDest = path.join(
|
|
94
|
+
process.cwd(),
|
|
95
|
+
destComponents,
|
|
96
|
+
`${component}.tsx`,
|
|
97
|
+
)
|
|
98
|
+
copyFile(componentSrc, componentDest, `Componente "${component}"`, overwrite)
|
|
99
|
+
|
|
100
|
+
const recipeSrc = path.join(THEME_DIR, `${component}.recipe.tsx`)
|
|
101
|
+
const recipeDest = path.join(
|
|
102
|
+
process.cwd(),
|
|
103
|
+
destTheme,
|
|
104
|
+
`${component}.recipe.tsx`,
|
|
105
|
+
)
|
|
106
|
+
copyFile(recipeSrc, recipeDest, `Recipe of "${component}"`, overwrite)
|
|
85
107
|
}
|
|
86
108
|
|
|
87
109
|
async function confirmOverwrite(existingComponents) {
|
|
88
|
-
const {
|
|
110
|
+
const {overwrite} = await inquirer.prompt([
|
|
89
111
|
{
|
|
90
|
-
type:
|
|
91
|
-
name:
|
|
92
|
-
message: `
|
|
93
|
-
|
|
94
|
-
)}\
|
|
112
|
+
type: 'confirm',
|
|
113
|
+
name: 'overwrite',
|
|
114
|
+
message: `The following components already exist: ${existingComponents.join(
|
|
115
|
+
', ',
|
|
116
|
+
)}\nDo you want to overwrite them?`,
|
|
95
117
|
default: false,
|
|
96
118
|
},
|
|
97
|
-
])
|
|
98
|
-
return overwrite
|
|
119
|
+
])
|
|
120
|
+
return overwrite
|
|
99
121
|
}
|
|
100
122
|
|
|
101
123
|
program
|
|
102
|
-
.name(
|
|
103
|
-
.description(
|
|
104
|
-
.version(
|
|
124
|
+
.name('varia')
|
|
125
|
+
.description('CLI for installing components from react-native-varia')
|
|
126
|
+
.version('1.0.0')
|
|
105
127
|
|
|
106
128
|
program
|
|
107
|
-
.command(
|
|
108
|
-
.description(
|
|
129
|
+
.command('setup')
|
|
130
|
+
.description(
|
|
131
|
+
'Copy the varia and patterns folders to the project (src/style/varia y src/patterns)',
|
|
132
|
+
)
|
|
109
133
|
.action(() => {
|
|
110
|
-
const variaSrc = path.join(__dirname,
|
|
111
|
-
const variaDest = path.join(process.cwd(),
|
|
134
|
+
const variaSrc = path.join(__dirname, '../lib/varia')
|
|
135
|
+
const variaDest = path.join(process.cwd(), 'src/style/varia')
|
|
112
136
|
|
|
113
|
-
const patternsSrc = path.join(__dirname,
|
|
114
|
-
const patternsDest = path.join(process.cwd(),
|
|
137
|
+
const patternsSrc = path.join(__dirname, '../lib/patterns')
|
|
138
|
+
const patternsDest = path.join(process.cwd(), 'src/patterns')
|
|
115
139
|
|
|
116
140
|
try {
|
|
117
|
-
fs.ensureDirSync(path.dirname(variaDest))
|
|
118
|
-
fs.copySync(variaSrc, variaDest, {
|
|
119
|
-
console.log(`✅
|
|
141
|
+
fs.ensureDirSync(path.dirname(variaDest))
|
|
142
|
+
fs.copySync(variaSrc, variaDest, {overwrite: true})
|
|
143
|
+
console.log(`✅ Directory "varia" copied to ${variaDest}`)
|
|
120
144
|
|
|
121
|
-
fs.ensureDirSync(path.dirname(patternsDest))
|
|
122
|
-
fs.copySync(patternsSrc, patternsDest, {
|
|
123
|
-
console.log(`✅
|
|
145
|
+
fs.ensureDirSync(path.dirname(patternsDest))
|
|
146
|
+
fs.copySync(patternsSrc, patternsDest, {overwrite: true})
|
|
147
|
+
console.log(`✅ Directory "patterns" copied to ${patternsDest}`)
|
|
124
148
|
} catch (err) {
|
|
125
|
-
console.error(`❌ Error
|
|
149
|
+
console.error(`❌ Error during setup: ${err.message}`)
|
|
126
150
|
}
|
|
127
|
-
})
|
|
128
|
-
|
|
151
|
+
})
|
|
129
152
|
|
|
130
153
|
program
|
|
131
|
-
.command(
|
|
132
|
-
.description(
|
|
154
|
+
.command('add-patterns')
|
|
155
|
+
.description('Copy the lib/patterns folder to src/patterns')
|
|
133
156
|
.action(() => {
|
|
134
|
-
const sourceDir = path.join(__dirname,
|
|
135
|
-
const destDir = path.join(process.cwd(),
|
|
157
|
+
const sourceDir = path.join(__dirname, '../lib/patterns')
|
|
158
|
+
const destDir = path.join(process.cwd(), 'src/patterns')
|
|
136
159
|
|
|
137
160
|
try {
|
|
138
|
-
fs.ensureDirSync(destDir)
|
|
139
|
-
fs.copySync(sourceDir, destDir, {
|
|
140
|
-
console.log(
|
|
161
|
+
fs.ensureDirSync(destDir)
|
|
162
|
+
fs.copySync(sourceDir, destDir, {overwrite: true})
|
|
163
|
+
console.log('✅ Patterns folder copied to src/patterns')
|
|
141
164
|
} catch (err) {
|
|
142
|
-
console.error(`❌ Error
|
|
165
|
+
console.error(`❌ Error copying patterns: ${err.message}`)
|
|
166
|
+
}
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
program
|
|
170
|
+
.command('update')
|
|
171
|
+
.description('Update all previously copied components in your project')
|
|
172
|
+
.option(
|
|
173
|
+
'-d, --dest <path>',
|
|
174
|
+
'Destination path for components',
|
|
175
|
+
'src/components',
|
|
176
|
+
)
|
|
177
|
+
.option('-t, --theme <path>', 'Destination path for recipes', 'src/theme')
|
|
178
|
+
.option('-i, --icons <path>', 'Destination path for icons', 'src/icons')
|
|
179
|
+
.action(async options => {
|
|
180
|
+
const destComponentsDir = path.join(process.cwd(), options.dest)
|
|
181
|
+
|
|
182
|
+
if (!fs.existsSync(destComponentsDir)) {
|
|
183
|
+
console.log(`❌ Destination folder does not exist: ${destComponentsDir}`)
|
|
184
|
+
return
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const existingFiles = fs.readdirSync(destComponentsDir)
|
|
188
|
+
const existingComponents = existingFiles
|
|
189
|
+
.filter(f => f.endsWith('.tsx'))
|
|
190
|
+
.map(f => path.parse(f).name)
|
|
191
|
+
.filter(name => name !== 'IconWrapper' && name !== 'context') // excluimos context y wrapper
|
|
192
|
+
|
|
193
|
+
if (existingComponents.length === 0) {
|
|
194
|
+
console.log('No components found to update.')
|
|
195
|
+
return
|
|
143
196
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
// }
|
|
177
|
-
|
|
178
|
-
// // 🔹 Preparar instalación
|
|
179
|
-
// for (const mainComponent of componentsCapitalized) {
|
|
180
|
-
// const componentPath = path.join(process.cwd(), options.dest, `${mainComponent}.tsx`);
|
|
181
|
-
// let overwriteMain = true;
|
|
182
|
-
|
|
183
|
-
// // Preguntar solo si el componente principal existe
|
|
184
|
-
// if (fs.existsSync(componentPath)) {
|
|
185
|
-
// const { overwrite } = await inquirer.prompt([
|
|
186
|
-
// {
|
|
187
|
-
// type: "confirm",
|
|
188
|
-
// name: "overwrite",
|
|
189
|
-
// message: `El componente "${mainComponent}" ya existe. ¿Deseas sobrescribirlo?`,
|
|
190
|
-
// default: false,
|
|
191
|
-
// },
|
|
192
|
-
// ]);
|
|
193
|
-
|
|
194
|
-
// overwriteMain = overwrite;
|
|
195
|
-
// if (!overwriteMain) {
|
|
196
|
-
// console.log(`⏭️ Componente "${mainComponent}" no sobrescrito.`);
|
|
197
|
-
// }
|
|
198
|
-
// }
|
|
199
|
-
|
|
200
|
-
// // 🔹 Copiar componente principal
|
|
201
|
-
// copyComponentAndRecipe(mainComponent, options.dest, options.theme, overwriteMain);
|
|
202
|
-
|
|
203
|
-
// // 🔹 Copiar dependencias (sin sobrescribir si existen)
|
|
204
|
-
// const deps = componentToDeps[mainComponent] || [];
|
|
205
|
-
// for (const dep of deps) {
|
|
206
|
-
// const depPath = path.join(process.cwd(), options.dest, `${dep}.tsx`);
|
|
207
|
-
// const exists = fs.existsSync(depPath);
|
|
208
|
-
// if (exists) {
|
|
209
|
-
// console.log(`⏭️ Dependencia "${dep}" ya existe. No se sobrescribe.`);
|
|
210
|
-
// continue;
|
|
211
|
-
// }
|
|
212
|
-
// copyComponentAndRecipe(dep, options.dest, options.theme, true);
|
|
213
|
-
// }
|
|
214
|
-
// }
|
|
215
|
-
// });
|
|
197
|
+
|
|
198
|
+
const {confirmUpdate} = await inquirer.prompt([
|
|
199
|
+
{
|
|
200
|
+
type: 'confirm',
|
|
201
|
+
name: 'confirmUpdate',
|
|
202
|
+
message: `Found the following components: ${existingComponents.join(
|
|
203
|
+
', ',
|
|
204
|
+
)}\nDo you want to update them?`,
|
|
205
|
+
default: false,
|
|
206
|
+
},
|
|
207
|
+
])
|
|
208
|
+
|
|
209
|
+
if (!confirmUpdate) {
|
|
210
|
+
console.log('⏭️ Update cancelled.')
|
|
211
|
+
return
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
for (const component of existingComponents) {
|
|
215
|
+
copyComponentAndRecipe(component, options.dest, options.theme, true)
|
|
216
|
+
copyContextComponentIfNeeded(component, options.dest, true)
|
|
217
|
+
|
|
218
|
+
const iconDeps = ICON_DEPENDENCIES[component] || []
|
|
219
|
+
if (iconDeps.length > 0) {
|
|
220
|
+
for (const iconName of iconDeps) {
|
|
221
|
+
copyIconTemplate(iconName, options.icons)
|
|
222
|
+
}
|
|
223
|
+
ensureIconWrapper(options.dest, options.theme)
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
console.log('✅ Components updated successfully.')
|
|
228
|
+
})
|
|
216
229
|
|
|
217
230
|
program
|
|
218
|
-
.command(
|
|
219
|
-
.description(
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
.option(
|
|
231
|
+
.command('add <components...>')
|
|
232
|
+
.description(
|
|
233
|
+
'Copies one or more components and their recipes from the library to your project',
|
|
234
|
+
)
|
|
235
|
+
.option(
|
|
236
|
+
'-d, --dest <path>',
|
|
237
|
+
'Destination path for components',
|
|
238
|
+
'src/components',
|
|
239
|
+
)
|
|
240
|
+
.option('-t, --theme <path>', 'Destination path for recipes', 'src/theme')
|
|
241
|
+
.option('-i, --icons <path>', 'Destination path for icons', 'src/icons')
|
|
223
242
|
.action(async (components, options) => {
|
|
224
|
-
const available = getAvailableComponents()
|
|
243
|
+
const available = getAvailableComponents()
|
|
225
244
|
const componentsCapitalized = components.map(
|
|
226
|
-
|
|
227
|
-
)
|
|
245
|
+
c => c.charAt(0).toUpperCase() + c.slice(1),
|
|
246
|
+
)
|
|
228
247
|
|
|
229
|
-
const allComponents = new Set()
|
|
230
|
-
const componentToDeps = {}
|
|
248
|
+
const allComponents = new Set()
|
|
249
|
+
const componentToDeps = {}
|
|
231
250
|
for (const c of componentsCapitalized) {
|
|
232
|
-
const deps = resolveDependencies(c)
|
|
233
|
-
componentToDeps[c] = deps
|
|
234
|
-
allComponents.add(c)
|
|
235
|
-
deps.forEach(
|
|
251
|
+
const deps = resolveDependencies(c)
|
|
252
|
+
componentToDeps[c] = deps
|
|
253
|
+
allComponents.add(c)
|
|
254
|
+
deps.forEach(d => allComponents.add(d))
|
|
236
255
|
}
|
|
237
256
|
|
|
238
|
-
const allComponentsArray = Array.from(allComponents)
|
|
257
|
+
const allComponentsArray = Array.from(allComponents)
|
|
239
258
|
|
|
240
|
-
const notFound = allComponentsArray.filter(
|
|
259
|
+
const notFound = allComponentsArray.filter(c => !available.includes(c))
|
|
241
260
|
if (notFound.length > 0) {
|
|
242
|
-
console.error(
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
261
|
+
console.error(
|
|
262
|
+
`❌ The following components do not exist: ${notFound.join(', ')}`,
|
|
263
|
+
)
|
|
264
|
+
console.log('\n📦 Available components:')
|
|
265
|
+
available.forEach(name => console.log(` - ${name}`))
|
|
266
|
+
process.exit(1)
|
|
246
267
|
}
|
|
247
268
|
|
|
248
|
-
function copyContextComponentIfNeeded(
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
269
|
+
function copyContextComponentIfNeeded(
|
|
270
|
+
component,
|
|
271
|
+
destComponents,
|
|
272
|
+
overwrite = true,
|
|
273
|
+
) {
|
|
274
|
+
if (!CONTEXT_DEPENDENCIES[component]) return
|
|
275
|
+
|
|
276
|
+
const contextSrc = path.join(
|
|
277
|
+
COMPONENTS_DIR,
|
|
278
|
+
'context',
|
|
279
|
+
`${component}.tsx`,
|
|
280
|
+
)
|
|
281
|
+
const contextDest = path.join(
|
|
282
|
+
process.cwd(),
|
|
283
|
+
destComponents,
|
|
284
|
+
'context',
|
|
285
|
+
`${component}.tsx`,
|
|
286
|
+
)
|
|
287
|
+
copyFile(contextSrc, contextDest, `Context for "${component}"`, overwrite)
|
|
254
288
|
}
|
|
255
289
|
|
|
256
290
|
for (const mainComponent of componentsCapitalized) {
|
|
257
|
-
const componentPath = path.join(
|
|
258
|
-
|
|
291
|
+
const componentPath = path.join(
|
|
292
|
+
process.cwd(),
|
|
293
|
+
options.dest,
|
|
294
|
+
`${mainComponent}.tsx`,
|
|
295
|
+
)
|
|
296
|
+
let overwriteMain = true
|
|
259
297
|
|
|
260
298
|
if (fs.existsSync(componentPath)) {
|
|
261
|
-
const {
|
|
299
|
+
const {overwrite} = await inquirer.prompt([
|
|
262
300
|
{
|
|
263
|
-
type:
|
|
264
|
-
name:
|
|
265
|
-
message: `
|
|
301
|
+
type: 'confirm',
|
|
302
|
+
name: 'overwrite',
|
|
303
|
+
message: `Component "${mainComponent}" exists. Do you want to overwrite it?`,
|
|
266
304
|
default: false,
|
|
267
305
|
},
|
|
268
|
-
])
|
|
306
|
+
])
|
|
269
307
|
|
|
270
|
-
overwriteMain = overwrite
|
|
308
|
+
overwriteMain = overwrite
|
|
271
309
|
if (!overwriteMain) {
|
|
272
|
-
console.log(`⏭️
|
|
310
|
+
console.log(`⏭️ Component "${mainComponent}" not overwritten.`)
|
|
273
311
|
}
|
|
274
312
|
}
|
|
275
313
|
|
|
276
|
-
copyComponentAndRecipe(
|
|
314
|
+
copyComponentAndRecipe(
|
|
315
|
+
mainComponent,
|
|
316
|
+
options.dest,
|
|
317
|
+
options.theme,
|
|
318
|
+
overwriteMain,
|
|
319
|
+
)
|
|
277
320
|
|
|
278
|
-
copyContextComponentIfNeeded(mainComponent, options.dest, overwriteMain)
|
|
321
|
+
copyContextComponentIfNeeded(mainComponent, options.dest, overwriteMain)
|
|
279
322
|
|
|
280
|
-
const deps = componentToDeps[mainComponent] || []
|
|
323
|
+
const deps = componentToDeps[mainComponent] || []
|
|
281
324
|
for (const dep of deps) {
|
|
282
|
-
const depPath = path.join(process.cwd(), options.dest, `${dep}.tsx`)
|
|
283
|
-
const exists = fs.existsSync(depPath)
|
|
325
|
+
const depPath = path.join(process.cwd(), options.dest, `${dep}.tsx`)
|
|
326
|
+
const exists = fs.existsSync(depPath)
|
|
284
327
|
if (exists) {
|
|
285
|
-
console.log(
|
|
286
|
-
|
|
328
|
+
console.log(
|
|
329
|
+
`⏭️ Dependency "${dep}" already exists. It does not overwrite.`,
|
|
330
|
+
)
|
|
331
|
+
continue
|
|
287
332
|
}
|
|
288
|
-
copyComponentAndRecipe(dep, options.dest, options.theme, true)
|
|
333
|
+
copyComponentAndRecipe(dep, options.dest, options.theme, true)
|
|
289
334
|
}
|
|
290
335
|
|
|
291
|
-
const iconDeps = ICON_DEPENDENCIES[mainComponent] || []
|
|
336
|
+
const iconDeps = ICON_DEPENDENCIES[mainComponent] || []
|
|
292
337
|
if (iconDeps.length > 0) {
|
|
293
|
-
console.log(
|
|
338
|
+
console.log(
|
|
339
|
+
`🎨 Adding icons required by "${mainComponent}": ${iconDeps.join(
|
|
340
|
+
', ',
|
|
341
|
+
)}`,
|
|
342
|
+
)
|
|
294
343
|
|
|
295
344
|
for (const iconName of iconDeps) {
|
|
296
|
-
const destIconPath = path.join(
|
|
345
|
+
const destIconPath = path.join(
|
|
346
|
+
process.cwd(),
|
|
347
|
+
options.icons,
|
|
348
|
+
`${iconName}.tsx`,
|
|
349
|
+
)
|
|
297
350
|
if (fs.existsSync(destIconPath)) {
|
|
298
|
-
console.log(
|
|
299
|
-
|
|
351
|
+
console.log(
|
|
352
|
+
`⏭️ Icon "${iconName}" already exists. It does not overwrite.`,
|
|
353
|
+
)
|
|
354
|
+
continue
|
|
300
355
|
}
|
|
301
|
-
copyIconTemplate(iconName, options.icons)
|
|
356
|
+
copyIconTemplate(iconName, options.icons)
|
|
302
357
|
}
|
|
303
358
|
|
|
304
|
-
ensureIconWrapper(options.dest, options.theme)
|
|
359
|
+
ensureIconWrapper(options.dest, options.theme)
|
|
305
360
|
}
|
|
306
361
|
}
|
|
307
|
-
})
|
|
308
|
-
|
|
362
|
+
})
|
|
309
363
|
|
|
310
364
|
function copyIconTemplate(iconName, dest) {
|
|
311
|
-
const srcPath = path.join(COMPONENTS_DIR,
|
|
312
|
-
const destPath = path.join(process.cwd(), dest, `${iconName}.tsx`)
|
|
365
|
+
const srcPath = path.join(COMPONENTS_DIR, 'Icon.tsx')
|
|
366
|
+
const destPath = path.join(process.cwd(), dest, `${iconName}.tsx`)
|
|
313
367
|
|
|
314
368
|
if (!fs.existsSync(srcPath)) {
|
|
315
|
-
console.error(`❌
|
|
316
|
-
return false
|
|
369
|
+
console.error(`❌ Icon template not found in: ${srcPath}`)
|
|
370
|
+
return false
|
|
317
371
|
}
|
|
318
372
|
|
|
319
373
|
try {
|
|
320
|
-
let content = fs.readFileSync(srcPath,
|
|
321
|
-
content = content.replace(/\bIconName\b/g, iconName)
|
|
374
|
+
let content = fs.readFileSync(srcPath, 'utf-8')
|
|
375
|
+
content = content.replace(/\bIconName\b/g, iconName)
|
|
322
376
|
|
|
323
|
-
fs.ensureDirSync(path.dirname(destPath))
|
|
324
|
-
fs.writeFileSync(destPath, content)
|
|
377
|
+
fs.ensureDirSync(path.dirname(destPath))
|
|
378
|
+
fs.writeFileSync(destPath, content)
|
|
325
379
|
|
|
326
|
-
console.log(`✅
|
|
327
|
-
return true
|
|
380
|
+
console.log(`✅ Icon "${iconName}" copied to: ${destPath}`)
|
|
381
|
+
return true
|
|
328
382
|
} catch (err) {
|
|
329
|
-
console.error(`❌
|
|
330
|
-
return false
|
|
383
|
+
console.error(`❌ Could not copy icon "${iconName}": ${err.message}`)
|
|
384
|
+
return false
|
|
331
385
|
}
|
|
332
386
|
}
|
|
333
387
|
|
|
334
388
|
function ensureIconWrapper(destComponents, destTheme) {
|
|
335
|
-
const wrapperComponentDest = path.join(
|
|
336
|
-
|
|
389
|
+
const wrapperComponentDest = path.join(
|
|
390
|
+
process.cwd(),
|
|
391
|
+
destComponents,
|
|
392
|
+
'IconWrapper.tsx',
|
|
393
|
+
)
|
|
394
|
+
const wrapperRecipeDest = path.join(
|
|
395
|
+
process.cwd(),
|
|
396
|
+
destTheme,
|
|
397
|
+
'IconWrapper.recipe.tsx',
|
|
398
|
+
)
|
|
337
399
|
|
|
338
400
|
if (fs.existsSync(wrapperComponentDest)) {
|
|
339
|
-
return
|
|
401
|
+
return
|
|
340
402
|
}
|
|
341
403
|
|
|
342
|
-
const wrapperComponentSrc = path.join(COMPONENTS_DIR,
|
|
343
|
-
const wrapperRecipeSrc = path.join(THEME_DIR,
|
|
404
|
+
const wrapperComponentSrc = path.join(COMPONENTS_DIR, 'IconWrapper.tsx')
|
|
405
|
+
const wrapperRecipeSrc = path.join(THEME_DIR, 'IconWrapper.recipe.tsx')
|
|
344
406
|
|
|
345
407
|
if (fs.existsSync(wrapperComponentSrc)) {
|
|
346
|
-
fs.ensureDirSync(path.dirname(wrapperComponentDest))
|
|
347
|
-
fs.copySync(wrapperComponentSrc, wrapperComponentDest, {
|
|
348
|
-
console.log(`✅ IconWrapper
|
|
408
|
+
fs.ensureDirSync(path.dirname(wrapperComponentDest))
|
|
409
|
+
fs.copySync(wrapperComponentSrc, wrapperComponentDest, {overwrite: true})
|
|
410
|
+
console.log(`✅ IconWrapper copied to: ${wrapperComponentDest}`)
|
|
349
411
|
}
|
|
350
412
|
|
|
351
413
|
if (fs.existsSync(wrapperRecipeSrc)) {
|
|
352
|
-
fs.ensureDirSync(path.dirname(wrapperRecipeDest))
|
|
353
|
-
fs.copySync(wrapperRecipeSrc, wrapperRecipeDest, {
|
|
354
|
-
console.log(`✅ IconWrapper recipe
|
|
414
|
+
fs.ensureDirSync(path.dirname(wrapperRecipeDest))
|
|
415
|
+
fs.copySync(wrapperRecipeSrc, wrapperRecipeDest, {overwrite: true})
|
|
416
|
+
console.log(`✅ IconWrapper recipe copied to: ${wrapperRecipeDest}`)
|
|
355
417
|
}
|
|
356
418
|
}
|
|
357
419
|
|
|
358
420
|
program
|
|
359
|
-
.command(
|
|
360
|
-
.description(
|
|
361
|
-
.option(
|
|
362
|
-
.option(
|
|
363
|
-
.option(
|
|
364
|
-
|
|
421
|
+
.command('add-icon [iconName]')
|
|
422
|
+
.description('Copies an icon based on the Icon.tsx template')
|
|
423
|
+
.option('-n, --name <iconName>', 'Icon name')
|
|
424
|
+
.option('-d, --dest <path>', 'Destination path for icons', 'src/icons')
|
|
425
|
+
.option(
|
|
426
|
+
'-c, --components <path>',
|
|
427
|
+
'Destination path for components',
|
|
428
|
+
'src/components',
|
|
429
|
+
)
|
|
430
|
+
.option('-t, --theme <path>', 'Destination path for recipes', 'src/theme')
|
|
365
431
|
.action(async (iconNameArg, options) => {
|
|
366
|
-
const rawName = iconNameArg || options.name
|
|
432
|
+
const rawName = iconNameArg || options.name
|
|
367
433
|
if (!rawName) {
|
|
368
|
-
console.error(
|
|
369
|
-
|
|
434
|
+
console.error(
|
|
435
|
+
'❌ You must specify the icon name as an argument or with --name',
|
|
436
|
+
)
|
|
437
|
+
process.exit(1)
|
|
370
438
|
}
|
|
371
439
|
|
|
372
|
-
const finalName = rawName.charAt(0).toUpperCase() + rawName.slice(1)
|
|
373
|
-
const destPath = path.join(process.cwd(), options.dest, `${finalName}.tsx`)
|
|
440
|
+
const finalName = rawName.charAt(0).toUpperCase() + rawName.slice(1)
|
|
441
|
+
const destPath = path.join(process.cwd(), options.dest, `${finalName}.tsx`)
|
|
374
442
|
|
|
375
443
|
if (fs.existsSync(destPath)) {
|
|
376
|
-
const {
|
|
444
|
+
const {overwrite} = await inquirer.prompt([
|
|
377
445
|
{
|
|
378
|
-
type:
|
|
379
|
-
name:
|
|
380
|
-
message: `
|
|
446
|
+
type: 'confirm',
|
|
447
|
+
name: 'overwrite',
|
|
448
|
+
message: `The icon "${finalName}" already exists. Do you want to overwrite it?`,
|
|
381
449
|
default: false,
|
|
382
450
|
},
|
|
383
|
-
])
|
|
451
|
+
])
|
|
384
452
|
if (!overwrite) {
|
|
385
|
-
console.log(
|
|
386
|
-
return
|
|
453
|
+
console.log('⏭️ Icon not overwritten.')
|
|
454
|
+
return
|
|
387
455
|
}
|
|
388
456
|
}
|
|
389
457
|
|
|
390
|
-
copyIconTemplate(finalName, options.dest)
|
|
391
|
-
ensureIconWrapper(options.components, options.theme)
|
|
392
|
-
})
|
|
458
|
+
copyIconTemplate(finalName, options.dest)
|
|
459
|
+
ensureIconWrapper(options.components, options.theme)
|
|
460
|
+
})
|
|
393
461
|
|
|
394
|
-
program.parse(process.argv)
|
|
462
|
+
program.parse(process.argv)
|