@popina/cli 5.0.1-20260204192447Z โ†’ 5.0.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@popina/cli",
3
- "version": "5.0.1-20260204192447Z",
3
+ "version": "5.0.1",
4
4
  "description": "Popina CLI",
5
5
  "repository": {
6
6
  "type": "git",
@@ -20,8 +20,8 @@
20
20
  "author": "Franรงois Veauvy",
21
21
  "devDependencies": {
22
22
  "eslint": "^9.19.0",
23
- "@pragma/config": "3.0.0",
24
- "@pragma/eslint": "1.3.5",
23
+ "@pragma/config": "3.1.0",
24
+ "@pragma/eslint": "1.3.6",
25
25
  "@pragma/tsconfig": "1.0.2"
26
26
  },
27
27
  "dependencies": {
@@ -1,12 +1,23 @@
1
1
  import fs from 'fs'
2
+ import { createRequire } from 'module'
2
3
  import path from 'path'
3
4
  import type { PlopTypes } from '@turbo/gen'
4
5
 
6
+ const require = createRequire(import.meta.url)
7
+
5
8
  export const generatorIcon = (plop: PlopTypes.NodePlopAPI) => {
9
+ const absoluteUiIconsPath = path.resolve(
10
+ plop.getDestBasePath(),
11
+ '../../packages/ui/src/icons',
12
+ )
13
+ const absoluteUiPackageRoot = path.resolve(
14
+ plop.getDestBasePath(),
15
+ '../../packages/ui',
16
+ )
17
+
6
18
  plop.setGenerator('icon', {
7
19
  description: 'Create a new icon in @pragma/ui',
8
20
  prompts: [
9
- // Prompt the user to choose how to create the icon
10
21
  {
11
22
  type: 'list',
12
23
  name: 'iconSource',
@@ -16,7 +27,6 @@ export const generatorIcon = (plop: PlopTypes.NodePlopAPI) => {
16
27
  '๐Ÿ”น Create Custom SVG',
17
28
  ],
18
29
  },
19
- // Prompt to enter the name of the Lucide icon to import (if chosen)
20
30
  {
21
31
  type: 'input',
22
32
  name: 'importedIconName',
@@ -25,67 +35,50 @@ export const generatorIcon = (plop: PlopTypes.NodePlopAPI) => {
25
35
  answers.iconSource ===
26
36
  '๐Ÿ”ธ Import Lucide React from "https://lucide.dev/icons/"',
27
37
  validate: (input) => {
28
- if (!input) {
29
- return 'Icon name is required.'
30
- }
38
+ if (!input) return 'Icon name is required.'
31
39
 
32
- // Trim and convert the icon name to PascalCase
33
40
  const importedIconName = input.trim()
34
41
  const pascalCaseImportedIconName =
35
42
  importedIconName[0].toUpperCase() + importedIconName.slice(1)
36
43
  const importedIconFileName = `${importedIconName}.js`
37
44
 
38
- // Build file paths
39
- const importedIconFilePath = path.join(
40
- plop.getDestBasePath(),
41
- '/node_modules/lucide-react/dist/esm/icons/' + importedIconFileName,
42
- )
43
- const iconIndexFilePath = path.join(
44
- plop.getDestBasePath(),
45
- 'packages/ui/src/icons/index.tsx',
46
- )
45
+ const iconIndexFilePath = path.join(absoluteUiIconsPath, 'index.tsx')
47
46
 
48
- // Check if the Lucide icon file exists
49
- if (!fs.existsSync(importedIconFilePath)) {
50
- return `The icon ${importedIconName} is not found in the Lucide React list. Please choose a different name or verify the icon exists. Refer to the website: ๐Ÿ‘‰ https://lucide.dev/icons/ ๐Ÿ‘ˆ`
47
+ try {
48
+ require.resolve(
49
+ `lucide-react/dist/esm/icons/${importedIconFileName}`,
50
+ {
51
+ paths: [absoluteUiPackageRoot],
52
+ },
53
+ )
54
+ } catch (error) {
55
+ return `The icon "${importedIconName}" is not found in Lucide React. Verify: https://lucide.dev/icons/`
51
56
  }
52
57
 
53
- // Check if the Lucide icon name already exists in the index.tsx file
54
58
  if (fs.existsSync(iconIndexFilePath)) {
55
59
  const iconIndexContent = fs.readFileSync(iconIndexFilePath, 'utf-8')
56
60
  const iconIndexPattern = new RegExp(
57
61
  `\\b${pascalCaseImportedIconName}\\b`,
58
62
  )
59
-
60
63
  if (iconIndexPattern.test(iconIndexContent)) {
61
- return `The icon name "${pascalCaseImportedIconName}" already exists in the index.tsx file. Please choose a different name.`
64
+ return `The icon name "${pascalCaseImportedIconName}" already exists in index.tsx.`
62
65
  }
63
66
  }
64
-
65
67
  return true
66
68
  },
67
69
  },
68
- // Prompt to enter the name of the custom SVG icon (if chosen)
69
70
  {
70
71
  type: 'input',
71
72
  name: 'customIconName',
72
73
  message: 'What is the name of the icon you want to create?',
73
74
  when: (answers) => answers.iconSource === '๐Ÿ”น Create Custom SVG',
74
75
  validate: (input) => {
75
- if (!input) {
76
- return 'Icon name is required.'
77
- }
76
+ if (!input) return 'Icon name is required.'
78
77
 
79
- // Trim and convert the icon name to PascalCase
80
78
  const pascalCaseCustomIconName = plop.getHelper('pascalCase')(input)
81
79
 
82
- // Build the file path for the custom SVG icon
83
- const customIconFilePath = path.join(
84
- plop.getDestBasePath(),
85
- 'packages/ui/src/icons/index.tsx',
86
- )
80
+ const customIconFilePath = path.join(absoluteUiIconsPath, 'index.tsx')
87
81
 
88
- // Check if the custom SVG icon file already exists
89
82
  if (fs.existsSync(customIconFilePath)) {
90
83
  const iconIndexContent = fs.readFileSync(
91
84
  customIconFilePath,
@@ -94,12 +87,10 @@ export const generatorIcon = (plop: PlopTypes.NodePlopAPI) => {
94
87
  const iconIndexPattern = new RegExp(
95
88
  `\\b${pascalCaseCustomIconName}\\b`,
96
89
  )
97
-
98
90
  if (iconIndexPattern.test(iconIndexContent)) {
99
- return `The icon name "${pascalCaseCustomIconName}" already exists in the index.tsx file. Please choose a different name.`
91
+ return `The icon name "${pascalCaseCustomIconName}" already exists in index.tsx.`
100
92
  }
101
93
  }
102
-
103
94
  return true
104
95
  },
105
96
  },
@@ -112,16 +103,15 @@ export const generatorIcon = (plop: PlopTypes.NodePlopAPI) => {
112
103
  const camelCaseCustomName = plop.getHelper('camelCase')(iconName)
113
104
  const customIconFileName = `${iconName}.tsx`
114
105
  const importStatement = `import { ${iconName} } from './${iconName}'`
115
- const customIconFilePath = path.join(
116
- plop.getDestBasePath(),
117
- 'packages/ui/src/icons/' + customIconFileName,
106
+ const finalCustomIconPath = path.join(
107
+ absoluteUiIconsPath,
108
+ customIconFileName,
118
109
  )
119
110
 
120
- // Add actions for '๐Ÿ”น Create Custom SVG'
121
111
  actions.push(
122
112
  {
123
113
  type: 'add',
124
- path: customIconFilePath,
114
+ path: finalCustomIconPath,
125
115
  templateFile: 'templates/icon/icon-react.hbs',
126
116
  },
127
117
  {
@@ -139,41 +129,38 @@ export const generatorIcon = (plop: PlopTypes.NodePlopAPI) => {
139
129
  )
140
130
  }
141
131
 
142
- if (
143
- answers &&
144
- answers.iconSource ===
145
- '๐Ÿ”ธ Import Lucide React from "https://lucide.dev/icons/"'
146
- ) {
132
+ if (answers && answers.iconSource.includes('Import Lucide React')) {
147
133
  const importedIconName = answers.importedIconName
148
-
149
134
  let pascalCaseImportedIconName: string
150
135
 
151
136
  if (importedIconName.includes('-')) {
152
- const splittedAnswer: string[] = answers.importedIconName.split('-') // ['air', 'vent']
153
-
137
+ const splittedAnswer: string[] = answers.importedIconName.split('-')
154
138
  pascalCaseImportedIconName = splittedAnswer.reduce<string>(
155
- (acc, word) => {
156
- return acc + word[0].toUpperCase() + word.slice(1)
157
- },
139
+ (acc, word) => acc + word[0].toUpperCase() + word.slice(1),
158
140
  '',
159
141
  )
160
- console.log(pascalCaseImportedIconName)
161
142
  } else {
162
143
  pascalCaseImportedIconName =
163
144
  importedIconName[0].toUpperCase() + importedIconName.slice(1)
164
145
  }
165
146
 
166
147
  const importedIconFileName = `${importedIconName}.js`
167
- const importedIconFilePath = path.join(
168
- plop.getDestBasePath(),
169
- '/node_modules/lucide-react/dist/esm/icons/' + importedIconFileName,
170
- )
171
148
 
172
- if (fs.existsSync(importedIconFilePath)) {
173
- const importKey = `${pascalCaseImportedIconName[0].toLowerCase()}${pascalCaseImportedIconName.slice(
174
- 1,
175
- )}`
176
- // Add actions for '๐Ÿ”ธ Import Lucide React since "https://lucide.dev/icons/"'
149
+ let iconExists = false
150
+ try {
151
+ require.resolve(
152
+ `lucide-react/dist/esm/icons/${importedIconFileName}`,
153
+ {
154
+ paths: [absoluteUiPackageRoot],
155
+ },
156
+ )
157
+ iconExists = true
158
+ } catch (e) {
159
+ iconExists = false
160
+ }
161
+
162
+ if (iconExists) {
163
+ const importKey = `${pascalCaseImportedIconName[0].toLowerCase()}${pascalCaseImportedIconName.slice(1)}`
177
164
  actions.push(
178
165
  {
179
166
  type: 'modify',
@@ -188,10 +175,6 @@ export const generatorIcon = (plop: PlopTypes.NodePlopAPI) => {
188
175
  template: `\n ${importKey}: ${pascalCaseImportedIconName},`,
189
176
  },
190
177
  )
191
- } else {
192
- console.error(
193
- `The file "${importedIconFileName}" doesn't exist in the specified path.`,
194
- )
195
178
  }
196
179
  }
197
180
 
@@ -5,15 +5,14 @@ interface {{pascalCase customIconName}}Props extends React.SVGProps<SVGSVGElemen
5
5
  }
6
6
 
7
7
  export const {{pascalCase customIconName}} =
8
- ({ ref, className, ...props }: {{pascalCase customIconName}}Props) => {
8
+ ({ ref, className }: {{pascalCase customIconName}}Props) => {
9
9
  return (
10
10
  <svg
11
11
  xmlns="http://www.w3.org/2000/svg"
12
12
  width="24"
13
13
  height="24"
14
14
  viewBox="0 0 24 24"
15
- fill="none"
16
- stroke="#f62992"
15
+ fill="currentColor"
17
16
  strokeWidth="2"
18
17
  strokeLinecap="round"
19
18
  strokeLinejoin="round">
@@ -27,6 +26,6 @@ export const {{pascalCase customIconName}} =
27
26
  /**
28
27
  * TODO: Then add in svg
29
28
  * ref={ref}
30
- * className={props.className}
29
+ * className={className}
31
30
  * fill="currentColor"
32
31
  */