@quasar/icongenie 4.0.0 → 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.
Files changed (61) hide show
  1. package/README.md +7 -1
  2. package/bin/icongenie.js +22 -22
  3. package/lib/cmd/generate.js +36 -41
  4. package/lib/cmd/help.js +1 -1
  5. package/lib/cmd/profile.js +34 -38
  6. package/lib/cmd/verify.js +18 -17
  7. package/lib/generators/icns.js +7 -3
  8. package/lib/generators/ico.js +7 -3
  9. package/lib/generators/index.js +0 -1
  10. package/lib/generators/png.js +7 -6
  11. package/lib/generators/splashscreen.js +6 -12
  12. package/lib/generators/svg.js +3 -4
  13. package/lib/modes/index.js +1 -8
  14. package/lib/modes/{quasar-app-v2 → v2}/bex.js +1 -2
  15. package/lib/modes/{quasar-app-v1 → v2}/capacitor.js +28 -35
  16. package/lib/modes/{quasar-app-v1 → v2}/cordova.js +40 -47
  17. package/lib/modes/v2/electron.js +32 -0
  18. package/lib/modes/{quasar-app-v1 → v2}/index.js +0 -1
  19. package/lib/modes/v2/pwa.js +71 -0
  20. package/lib/modes/{quasar-app-v2 → v2}/spa.js +1 -2
  21. package/lib/modes/{quasar-app-v1 → v2}/ssr.js +1 -2
  22. package/lib/mount/index.js +4 -7
  23. package/lib/mount/mount-cordova.js +71 -63
  24. package/lib/mount/mount-tag.js +3 -6
  25. package/lib/runner/generate.js +57 -55
  26. package/lib/runner/profile.js +18 -26
  27. package/lib/runner/verify.js +29 -27
  28. package/lib/utils/app-paths.js +8 -9
  29. package/lib/utils/default-params.js +0 -1
  30. package/lib/utils/filter-argv-params.js +3 -4
  31. package/lib/utils/get-argv.js +47 -0
  32. package/lib/utils/get-assets-files.js +9 -12
  33. package/lib/utils/get-compression.js +31 -19
  34. package/lib/utils/get-file-size.js +5 -6
  35. package/lib/utils/get-files-options.js +18 -21
  36. package/lib/utils/get-png-size.js +10 -12
  37. package/lib/utils/get-profile-content.js +3 -7
  38. package/lib/utils/get-profile-files.js +10 -13
  39. package/lib/utils/get-square-icon.js +5 -4
  40. package/lib/utils/logger.js +6 -7
  41. package/lib/utils/merge-objects.js +5 -6
  42. package/lib/utils/node-version-check.js +11 -11
  43. package/lib/utils/package-json.js +1 -5
  44. package/lib/utils/parse-argv.js +63 -74
  45. package/lib/utils/spawn-sync.js +8 -10
  46. package/lib/utils/validate-profile-object.js +34 -27
  47. package/package.json +46 -48
  48. package/samples/icongenie-profile.json +9 -17
  49. package/.editorconfig +0 -13
  50. package/.eslintignore +0 -1
  51. package/.eslintrc.cjs +0 -50
  52. package/lib/modes/quasar-app-v1/bex.js +0 -9
  53. package/lib/modes/quasar-app-v1/electron.js +0 -24
  54. package/lib/modes/quasar-app-v1/pwa.js +0 -74
  55. package/lib/modes/quasar-app-v1/spa.js +0 -17
  56. package/lib/modes/quasar-app-v2/capacitor.js +0 -155
  57. package/lib/modes/quasar-app-v2/cordova.js +0 -159
  58. package/lib/modes/quasar-app-v2/electron.js +0 -24
  59. package/lib/modes/quasar-app-v2/index.js +0 -45
  60. package/lib/modes/quasar-app-v2/pwa.js +0 -74
  61. package/lib/modes/quasar-app-v2/ssr.js +0 -4
@@ -1,8 +1,9 @@
1
+ // oxlint-disable new-cap
1
2
 
2
- import { readFileSync, writeFileSync, existsSync } from 'node:fs'
3
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs'
3
4
  import elementTree from 'elementtree'
4
5
  import { relative } from 'node:path'
5
- import { red, green } from 'kolorist'
6
+ import { green, red } from 'kolorist'
6
7
 
7
8
  import { resolveDir } from '../utils/app-paths.js'
8
9
  import { log, warn } from '../utils/logger.js'
@@ -11,26 +12,25 @@ import { spawnSync } from '../utils/spawn-sync.js'
11
12
  const cordovaConfigXml = resolveDir('src-cordova/config.xml')
12
13
  const srcCordovaDir = resolveDir('src-cordova')
13
14
 
14
- const platformList = [ 'cordova-android', 'cordova-ios' ]
15
- const generatorList = [ 'png', 'splashscreen' ]
15
+ const platformList = ['cordova-android', 'cordova-ios']
16
+ const generatorList = ['png', 'splashscreen']
16
17
 
17
- function getNode (root, tag, selector) {
18
- return (
19
- root.find(`${ tag }${ selector }`)
20
- || elementTree.SubElement(root, tag)
21
- )
18
+ function getNode(root, tag, selector) {
19
+ return root.find(`${tag}${selector}`) || elementTree.SubElement(root, tag)
22
20
  }
23
21
 
24
- function hasNode (root, tag, selector) {
25
- return root.find(`${ tag }${ selector }`)
22
+ function hasNode(root, tag, selector) {
23
+ return root.find(`${tag}${selector}`)
26
24
  }
27
25
 
28
- export function isCordovaFile (file) {
29
- return platformList.includes(file.platform)
30
- && generatorList.includes(file.generator)
26
+ export function isCordovaFile(file) {
27
+ return (
28
+ platformList.includes(file.platform) &&
29
+ generatorList.includes(file.generator)
30
+ )
31
31
  }
32
32
 
33
- function getCordovaFiles (files) {
33
+ function getCordovaFiles(files) {
34
34
  const cordovaFiles = []
35
35
 
36
36
  files.forEach(file => {
@@ -42,11 +42,15 @@ function getCordovaFiles (files) {
42
42
  return cordovaFiles
43
43
  }
44
44
 
45
- function updateConfigXml (cordovaFiles, hasSplashscreen) {
46
- const doc = elementTree.parse(readFileSync(cordovaConfigXml, 'utf-8'))
45
+ function updateConfigXml(cordovaFiles, hasSplashscreen) {
46
+ const doc = elementTree.parse(readFileSync(cordovaConfigXml, 'utf8'))
47
47
  const rootNode = doc.getroot()
48
48
 
49
- if (hasSplashscreen && !rootNode.find('preference[@name="SplashMaintainAspectRatio"]')) {
49
+ if (
50
+ hasSplashscreen &&
51
+ // oxlint-disable-next-line unicorn/prefer-array-some
52
+ !rootNode.find('preference[@name="SplashMaintainAspectRatio"]')
53
+ ) {
50
54
  const prefNode = elementTree.SubElement(rootNode, 'preference')
51
55
  prefNode.set('name', 'SplashMaintainAspectRatio')
52
56
  prefNode.set('value', 'true')
@@ -65,8 +69,7 @@ function updateConfigXml (cordovaFiles, hasSplashscreen) {
65
69
  cordovaFiles.forEach(file => {
66
70
  const isAndroid = file.platform === 'cordova-android'
67
71
  const node = isAndroid ? androidNode : iosNode
68
- const src = relative(srcCordovaDir, file.absoluteName)
69
- .replace(/\\/g, '/') // Windows support
72
+ const src = relative(srcCordovaDir, file.absoluteName).replaceAll('\\', '/') // Windows support
70
73
 
71
74
  if (file.generator === 'splashscreen') {
72
75
  // <splash src="res/screen/android/splash-land-hdpi.png" density="land-hdpi"/>
@@ -75,7 +78,7 @@ function updateConfigXml (cordovaFiles, hasSplashscreen) {
75
78
  const entry = getNode(
76
79
  node,
77
80
  'splash',
78
- isAndroid ? `[@density="${ file.density }"]` : `[@src="${ src }"]`
81
+ isAndroid ? `[@density="${file.density}"]` : `[@src="${src}"]`
79
82
  )
80
83
 
81
84
  entry.set('src', src)
@@ -83,8 +86,7 @@ function updateConfigXml (cordovaFiles, hasSplashscreen) {
83
86
  if (isAndroid) {
84
87
  entry.set('density', file.density)
85
88
  }
86
- }
87
- else if (file.generator === 'png') {
89
+ } else if (file.generator === 'png') {
88
90
  // <icon src="res/android/ldpi.png" density="ldpi" />
89
91
  // <icon src="res/ios/icon-60@3x.png" width="180" height="180" />
90
92
 
@@ -92,32 +94,31 @@ function updateConfigXml (cordovaFiles, hasSplashscreen) {
92
94
  node,
93
95
  'icon',
94
96
  isAndroid
95
- ? `[@density="${ file.density }"]`
96
- : `[@width="${ file.width }"][@height="${ file.height }"]`
97
+ ? `[@density="${file.density}"]`
98
+ : `[@width="${file.width}"][@height="${file.height}"]`
97
99
  )
98
100
 
99
101
  entry.set('src', src)
100
102
 
101
103
  if (isAndroid) {
102
104
  entry.set('density', file.density)
103
- }
104
- else {
105
+ } else {
105
106
  entry.set('width', file.width)
106
107
  entry.set('height', file.height)
107
108
  }
108
109
  }
109
110
  })
110
111
 
111
- writeFileSync(cordovaConfigXml, doc.write({ indent: 4 }), 'utf-8')
112
+ writeFileSync(cordovaConfigXml, doc.write({ indent: 4 }), 'utf8')
112
113
  log(`Updated src-cordova/config.xml`)
113
114
  }
114
115
 
115
- function hasDeepProp (target /* , param1, param2, ... */) {
116
+ function hasDeepProp(target, ...args) {
116
117
  let obj = target
117
118
 
118
- for (let i = 1; i < arguments.length; i++) {
119
- const prop = arguments[ i ]
120
- obj = obj[ prop ]
119
+ for (let i = 0; i < args.length; i++) {
120
+ const prop = args[i]
121
+ obj = obj[prop]
121
122
 
122
123
  if (obj === void 0) {
123
124
  return false
@@ -127,45 +128,52 @@ function hasDeepProp (target /* , param1, param2, ... */) {
127
128
  return true
128
129
  }
129
130
 
130
- function installSplashscreenPlugin () {
131
+ function installSplashscreenPlugin() {
131
132
  const pkgPath = resolveDir('src-cordova/package.json')
132
133
 
133
- if (!existsSync(pkgPath)) {
134
- // malformed /src-cordova...
135
- return
136
- }
134
+ // malformed /src-cordova...
135
+ if (!existsSync(pkgPath)) return
137
136
 
138
- const pkg = JSON.parse(
139
- readFileSync(pkgPath, 'utf8')
140
- )
137
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'))
141
138
 
142
139
  if (
143
- hasDeepProp(pkg, 'dependencies', 'cordova-plugin-splashscreen')
144
- || hasDeepProp(pkg, 'cordova', 'plugins', 'cordova-plugin-splashscreen')
145
- ) {
146
140
  // it's already installed, so nothing to do
141
+ hasDeepProp(pkg, 'dependencies', 'cordova-plugin-splashscreen') ||
142
+ hasDeepProp(pkg, 'cordova', 'plugins', 'cordova-plugin-splashscreen')
143
+ ) {
147
144
  return
148
145
  }
149
146
 
150
147
  log(`Installing cordova-plugin-splashscreen...`)
151
148
 
152
- spawnSync('cordova', [ 'plugin', 'add', 'cordova-plugin-splashscreen' ], {
153
- cwd: srcCordovaDir
154
- }, () => {
155
- warn()
156
- warn('Failed to install cordova-plugin-splashscreen. Please do it manually.')
157
- console.log(' -> /src-cordova: $ cordova plugin add cordova-plugin-splashscreen\n')
158
- })
149
+ spawnSync(
150
+ 'cordova',
151
+ ['plugin', 'add', 'cordova-plugin-splashscreen'],
152
+ {
153
+ cwd: srcCordovaDir
154
+ },
155
+ () => {
156
+ warn()
157
+ warn(
158
+ 'Failed to install cordova-plugin-splashscreen. Please do it manually.'
159
+ )
160
+ console.log(
161
+ ' -> /src-cordova: $ cordova plugin add cordova-plugin-splashscreen\n'
162
+ )
163
+ }
164
+ )
159
165
 
160
166
  console.log()
161
167
  }
162
168
 
163
- export function mountCordova (files) {
169
+ export function mountCordova(files) {
164
170
  if (existsSync(cordovaConfigXml)) {
165
171
  const cordovaFiles = getCordovaFiles(files)
166
172
 
167
- if (cordovaFiles.length > 0) {
168
- const hasSplashscreen = cordovaFiles.some(file => file.generator === 'splashscreen')
173
+ if (cordovaFiles.length !== 0) {
174
+ const hasSplashscreen = cordovaFiles.some(
175
+ file => file.generator === 'splashscreen'
176
+ )
169
177
 
170
178
  if (hasSplashscreen) {
171
179
  installSplashscreenPlugin()
@@ -176,13 +184,14 @@ export function mountCordova (files) {
176
184
  }
177
185
  }
178
186
 
179
- export function verifyCordova (file) {
187
+ export function verifyCordova(file) {
180
188
  if (isCordovaFile(file) && existsSync(cordovaConfigXml)) {
181
- const doc = elementTree.parse(readFileSync(cordovaConfigXml, 'utf-8'))
189
+ const doc = elementTree.parse(readFileSync(cordovaConfigXml, 'utf8'))
182
190
  const isAndroid = file.platform === 'cordova-android'
183
191
 
184
- const node = doc.getroot()
185
- .find(`platform[@name="${ isAndroid ? 'android' : 'ios' }"]`)
192
+ const node = doc
193
+ .getroot()
194
+ .find(`platform[@name="${isAndroid ? 'android' : 'ios'}"]`)
186
195
 
187
196
  // verify that the platform is installed
188
197
  if (!node) {
@@ -193,17 +202,16 @@ export function verifyCordova (file) {
193
202
 
194
203
  if (file.generator === 'splashscreen') {
195
204
  const selector = isAndroid
196
- ? `[@density="${ file.density }"]`
197
- : `[@src="${ src }"]`
205
+ ? `[@density="${file.density}"]`
206
+ : `[@src="${src}"]`
198
207
 
199
208
  if (!hasNode(node, 'splash', selector)) {
200
209
  return red('ERROR: no entry for it in src-cordova/config.xml')
201
210
  }
202
- }
203
- else {
211
+ } else {
204
212
  const selector = isAndroid
205
- ? `[@density="${ file.density }"]`
206
- : `[@width="${ file.width }"][@height="${ file.height }"]`
213
+ ? `[@density="${file.density}"]`
214
+ : `[@width="${file.width}"][@height="${file.height}"]`
207
215
 
208
216
  if (!hasNode(node, 'icon', selector)) {
209
217
  return red('ERROR: no entry for it in src-cordova/config.xml')
@@ -1,15 +1,12 @@
1
-
2
1
  import { log } from '../utils/logger.js'
3
2
 
4
- export function mountTag (files) {
3
+ export function mountTag(files) {
5
4
  const tagFiles = files.filter(file => file.tag)
6
5
 
7
- if (tagFiles.length === 0) {
8
- return
9
- }
6
+ if (tagFiles.length === 0) return
10
7
 
11
8
  console.log()
12
- log(`You will need the following tags in your /index.html or /src/index.template.html:\n`)
9
+ log(`You will need the following tags in your /index.html:\n`)
13
10
  tagFiles.forEach(file => {
14
11
  console.log(file.tag)
15
12
  })
@@ -1,7 +1,6 @@
1
-
2
1
  import { existsSync } from 'node:fs'
3
2
  import { ensureFileSync } from 'fs-extra'
4
- import { green, gray } from 'kolorist'
3
+ import { gray, green } from 'kolorist'
5
4
 
6
5
  import { appDir, resolveDir } from '../utils/app-paths.js'
7
6
  import { log, warn } from '../utils/logger.js'
@@ -18,45 +17,43 @@ import { getProfileContent } from '../utils/get-profile-content.js'
18
17
  import { getFileSize } from '../utils/get-file-size.js'
19
18
  import { validateProfileObject } from '../utils/validate-profile-object.js'
20
19
 
21
- function printBanner (assetsOf, params) {
20
+ function printBanner(assetsOf, params) {
22
21
  console.log(` Generating files with the following options:
23
22
  ==========================
24
- Quasar project folder..... ${ green(appDir) }
25
- ${ green(`Quality level............. ${ params.quality }/12`) }
26
- Icon source file.......... ${ green(params.icon) }
27
- Icon trimming............. ${ params.skipTrim ? 'no' : green('yes') }
28
- Icon padding.............. ${ green(`horizontal: ${ params.padding[ 0 ] }; vertical: ${ params.padding[ 1 ] }`) }
29
- Background source file.... ${ params.background ? green(params.background) : 'none' }
30
- Assets of................. ${ green(assetsOf) }
31
- Generator filter.......... ${ params.filter ? green(params.filter) : 'none' }
32
- Svg color................. ${ green(params.svgColor) }
33
- Png color................. ${ green(params.pngColor) }
34
- Splashscreen color........ ${ green(params.splashscreenColor) }
35
- Splashscreen icon ratio... ${ green(params.splashscreenIconRatio) }%
23
+ Quasar project folder..... ${green(appDir)}
24
+ ${green(`Quality level............. ${params.quality}/12`)}
25
+ Icon source file.......... ${green(params.icon)}
26
+ Icon trimming............. ${params.skipTrim ? 'no' : green('yes')}
27
+ Icon padding.............. ${green(`horizontal: ${params.padding[0]}; vertical: ${params.padding[1]}`)}
28
+ Background source file.... ${params.background ? green(params.background) : 'none'}
29
+ Assets of................. ${green(assetsOf)}
30
+ Generator filter.......... ${params.filter ? green(params.filter) : 'none'}
31
+ Svg color................. ${green(params.svgColor)}
32
+ Png color................. ${green(params.pngColor)}
33
+ Splashscreen color........ ${green(params.splashscreenColor)}
34
+ Splashscreen icon ratio... ${green(params.splashscreenIconRatio)}%
36
35
  ==========================
37
36
  `)
38
37
  }
39
38
 
40
- function parseAssets (assets, include) {
41
- let files = []
42
- let assetsOf = []
39
+ function parseAssets(assets, include) {
40
+ const files = []
41
+ const assetsOf = []
43
42
 
44
43
  if (include) {
45
- const embeddedModes = include.filter(
46
- mode => existsSync(resolveDir(modes[ mode ].folder))
44
+ const embeddedModes = include.filter(mode =>
45
+ existsSync(resolveDir(modes[mode].folder))
47
46
  )
48
47
 
49
48
  embeddedModes.forEach(mode => {
50
- files = files.concat(
51
- getAssetsFiles(modes[ mode ].assets)
52
- )
49
+ files.push(...getAssetsFiles(modes[mode].assets))
53
50
  })
54
51
 
55
- assetsOf = assetsOf.concat(embeddedModes)
52
+ assetsOf.push(...embeddedModes)
56
53
  }
57
54
 
58
- if (assets && assets.length > 0) {
59
- files = files.concat(getAssetsFiles(assets))
55
+ if (assets && assets.length !== 0) {
56
+ files.push(...getAssetsFiles(assets))
60
57
  assetsOf.push('profile')
61
58
  }
62
59
 
@@ -66,13 +63,13 @@ function parseAssets (assets, include) {
66
63
  }
67
64
  }
68
65
 
69
- function getUniqueFiles (files) {
66
+ function getUniqueFiles(files) {
70
67
  const filePaths = {}
71
68
  const uniqueFiles = []
72
69
 
73
70
  files.forEach(file => {
74
- if (filePaths[ file.absoluteName ] === void 0) {
75
- filePaths[ file.absoluteName ] = true
71
+ if (filePaths[file.absoluteName] === void 0) {
72
+ filePaths[file.absoluteName] = true
76
73
  uniqueFiles.push(file)
77
74
  }
78
75
  })
@@ -80,23 +77,23 @@ function getUniqueFiles (files) {
80
77
  return uniqueFiles
81
78
  }
82
79
 
83
- function generateFile (file, opts) {
80
+ function generateFile(file, opts) {
84
81
  // ensure that the file (and its folder) exists
85
82
  ensureFileSync(file.absoluteName)
86
83
 
87
84
  return new Promise(resolve => {
88
85
  // use the appropriate generator to handle the file creation
89
- generators[ file.generator ](file, opts, () => {
90
- const size = `(${ getFileSize(file.absoluteName) })`
86
+ generators[file.generator](file, opts, () => {
87
+ const size = `(${getFileSize(file.absoluteName)})`
91
88
  const type = (file.generator + ':').padEnd(13, ' ')
92
89
 
93
- log(`Generated ${ type } ${ green(file.relativeName) } ${ gray(size) }`)
90
+ log(`Generated ${type} ${green(file.relativeName)} ${gray(size)}`)
94
91
  resolve()
95
92
  })
96
93
  })
97
94
  }
98
95
 
99
- async function generateFromProfile (profile) {
96
+ async function generateFromProfile(profile) {
100
97
  const params = profile.params
101
98
  const { assetsOf, files } = parseAssets(profile.assets, params.include)
102
99
 
@@ -104,32 +101,33 @@ async function generateFromProfile (profile) {
104
101
  let uniqueFiles = getUniqueFiles(files)
105
102
 
106
103
  if (params.filter) {
107
- uniqueFiles = uniqueFiles.filter(
108
- file => file.generator === params.filter
109
- )
104
+ uniqueFiles = uniqueFiles.filter(file => file.generator === params.filter)
110
105
  }
111
106
 
112
107
  if (uniqueFiles.length === 0) {
113
- warn(`No assets to generate! No mode/include specified, filter too specific or the respective Quasar mode(s) are not installed`)
114
- return Promise.resolve(0)
108
+ warn(
109
+ `No assets to generate! No mode/include specified, filter too specific or the respective Quasar mode(s) are not installed`
110
+ )
111
+ return 0
115
112
  }
116
113
 
117
114
  printBanner(assetsOf, params)
118
115
 
119
- return Promise
120
- .all(uniqueFiles.map(file => generateFile(file, fileOptions)))
121
- .then(() => { mount(uniqueFiles) })
116
+ return Promise.all(uniqueFiles.map(file => generateFile(file, fileOptions)))
117
+ .then(() => {
118
+ mount(uniqueFiles)
119
+ })
122
120
  .then(() => uniqueFiles.length)
123
121
  }
124
122
 
125
- export function generate (argv) {
123
+ export function generate(argv) {
126
124
  const profile = {
127
125
  params: {},
128
126
  assets: []
129
127
  }
130
128
 
131
129
  if (argv.profile) {
132
- parseArgv(argv, [ 'profile' ])
130
+ parseArgv(argv, ['profile'])
133
131
 
134
132
  const userProfile = getProfileContent(argv.profile)
135
133
 
@@ -137,14 +135,13 @@ export function generate (argv) {
137
135
  const { profile: _, ...params } = argv
138
136
 
139
137
  profile.params = mergeObjects(userProfile.params, params)
140
- parseArgv(profile.params, [ 'include' ])
138
+ parseArgv(profile.params, ['include'])
141
139
  }
142
140
  if (userProfile.assets) {
143
141
  profile.assets = userProfile.assets
144
142
  }
145
- }
146
- else {
147
- parseArgv(argv, [ 'mode' ])
143
+ } else {
144
+ parseArgv(argv, ['mode'])
148
145
 
149
146
  const { mode, ...params } = argv
150
147
 
@@ -155,18 +152,23 @@ export function generate (argv) {
155
152
  profile.params = mergeObjects({}, profile.params)
156
153
 
157
154
  parseArgv(profile.params, [
158
- 'quality', 'filter', 'padding',
159
- 'icon', 'background',
155
+ 'quality',
156
+ 'filter',
157
+ 'padding',
158
+ 'icon',
159
+ 'background',
160
160
  'splashscreenIconRatio',
161
161
  // order matters:
162
- 'themeColor', 'pngColor', 'splashscreenColor', 'svgColor'
162
+ 'themeColor',
163
+ 'pngColor',
164
+ 'splashscreenColor',
165
+ 'svgColor'
163
166
  ])
164
167
 
165
168
  // final thorough validation
166
169
  validateProfileObject(profile)
167
170
 
168
- return generateFromProfile(profile)
169
- .then(numberOfFiles => {
170
- console.log(`\n Task done - generated ${ numberOfFiles } file(s)!\n`)
171
- })
171
+ return generateFromProfile(profile).then(numberOfFiles => {
172
+ console.log(`\n Task done - generated ${numberOfFiles} file(s)!\n`)
173
+ })
172
174
  }
@@ -1,5 +1,4 @@
1
-
2
- import { resolve, dirname, basename, isAbsolute, relative } from 'node:path'
1
+ import { basename, dirname, isAbsolute, relative, resolve } from 'node:path'
3
2
  import { writeFileSync } from 'node:fs'
4
3
  import { ensureDir } from 'fs-extra'
5
4
 
@@ -8,7 +7,7 @@ import { modes } from '../modes/index.js'
8
7
  import { validateProfileObject } from '../utils/validate-profile-object.js'
9
8
  import { appDir } from '../utils/app-paths.js'
10
9
 
11
- function getParams ({ include, ...props }) {
10
+ function getParams({ include, ...props }) {
12
11
  if (include) {
13
12
  props.include = include.split(',')
14
13
  }
@@ -16,44 +15,37 @@ function getParams ({ include, ...props }) {
16
15
  return props
17
16
  }
18
17
 
19
- function getAssets (assets) {
20
- let list = []
21
-
22
- assets.forEach(name => {
23
- list = list.concat(modes[ name ].assets)
24
- })
25
-
26
- return list
18
+ function getAssets(assets) {
19
+ return assets.reduce((acc, name) => {
20
+ acc.push(...modes[name].assets)
21
+ return acc
22
+ }, [])
27
23
  }
28
24
 
29
- function getTargetFilepath (output) {
25
+ function getTargetFilepath(output) {
30
26
  const folder = dirname(output)
31
27
  const name = basename(output)
32
28
 
33
- const prefix = name.startsWith('icongenie-')
34
- ? ''
35
- : 'icongenie-'
29
+ const prefix = name.startsWith('icongenie-') ? '' : 'icongenie-'
36
30
 
37
- const suffix = name.endsWith('.json')
38
- ? ''
39
- : '.json'
31
+ const suffix = name.endsWith('.json') ? '' : '.json'
40
32
 
41
- const filename = `${ prefix }${ name }${ suffix }`
33
+ const filename = `${prefix}${name}${suffix}`
42
34
  return resolve(process.cwd(), folder || '', filename)
43
35
  }
44
36
 
45
- export function profile ({ output, assets, ...params }) {
46
- const profile = {
37
+ export function profile({ output, assets, ...params }) {
38
+ const acc = {
47
39
  params: getParams(params),
48
40
  assets: getAssets(assets)
49
41
  }
50
42
 
51
- validateProfileObject(profile, true)
43
+ validateProfileObject(acc, true)
52
44
 
53
- if (profile.params.icon && isAbsolute(profile.params.icon) === false) {
45
+ if (acc.params.icon && !isAbsolute(acc.params.icon)) {
54
46
  // generate icon path relative to app root
55
47
  // so it won't matter from where the profile file is run
56
- profile.params.icon = relative(appDir, profile.params.icon)
48
+ acc.params.icon = relative(appDir, acc.params.icon)
57
49
  }
58
50
 
59
51
  const targetFile = getTargetFilepath(output)
@@ -63,8 +55,8 @@ export function profile ({ output, assets, ...params }) {
63
55
  ensureDir(folderName)
64
56
  }
65
57
 
66
- writeFileSync(targetFile, JSON.stringify(profile, null, 2), 'utf-8')
58
+ writeFileSync(targetFile, JSON.stringify(acc, null, 2), 'utf8')
67
59
 
68
60
  console.log(` Generated Icon Genie profile file:`)
69
- log(`${ targetFile }\n`)
61
+ log(`${targetFile}\n`)
70
62
  }