@symbo.ls/cli 2.11.5 → 2.11.16

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 (2) hide show
  1. package/bin/convert.js +180 -44
  2. package/package.json +2 -2
package/bin/convert.js CHANGED
@@ -7,13 +7,41 @@ import fs from 'fs'
7
7
  import path from 'path'
8
8
  import { JSDOM } from 'jsdom'
9
9
 
10
- const jsdom = new JSDOM('<html><head></head><body></body></html>')
10
+ const l = (n) => console.log(`mark${n}`)
11
+
12
+ const jsdom = new JSDOM(`<html><head></head><body></body></html>`)
11
13
  global.window = jsdom.window
12
14
  global.document = window.document
13
15
 
14
- const TMP_DIR_NAME = '.smbls_convert_tmp'
16
+ const IGNORED_FILES = ['index.js', 'package.json', 'node_modules', 'dist']
17
+ const EXCLUDED_FROM_INTERNAL_UIKIT = [
18
+ 'Svg',
19
+ 'keySetters',
20
+ 'getSystemTheme',
21
+ 'splitTransition',
22
+ 'transformDuration',
23
+ 'transformShadow',
24
+ 'transformTransition'
25
+ ]
26
+ const TMP_DIR_NAME = ".smbls_convert_tmp"
27
+ const TMP_DIR_PACKAGE_JSON_STR = JSON.stringify({
28
+ "name": "smbls_convert_tmp",
29
+ "version": "1.0.0",
30
+ //"main": "index.js",
31
+ "license": "ISC"
32
+ });
33
+
34
+ function isDirectory(dir) {
35
+ if (!fs.existsSync(dir)) return false
15
36
 
16
- async function mkdirp (dir) {
37
+ const stat = fs.statSync(dir)
38
+ if (!stat) return false
39
+
40
+ return stat.isDirectory()
41
+ }
42
+
43
+ // Essentially does 'mkdir -P'
44
+ async function mkdirp(dir) {
17
45
  try {
18
46
  return await fs.promises.mkdir(dir)
19
47
  } catch (err) {
@@ -24,17 +52,61 @@ async function mkdirp (dir) {
24
52
  return null
25
53
  }
26
54
 
27
- const IGNORED_FILES = ['index.js', 'package.json', 'node_modules', 'dist']
55
+ async function importDomqlModule(modulePath) {
56
+ console.log(`importing ${modulePath}`)
57
+ return (await import(modulePath)).default
58
+ }
59
+
60
+ function convertDomqlModule(domqlModule, desiredFormat, options) {
61
+ let convertedStr = ""
62
+
63
+ console.group()
64
+ const uniqueImports = []
65
+ let first = true
66
+ let removeUseContextImport = false
67
+ const exportCount = Object.keys(domqlModule).length
68
+ for (const key in domqlModule) {
69
+ if (options.internalUikit &&
70
+ EXCLUDED_FROM_INTERNAL_UIKIT.includes(key)) {
71
+ console.log(`Skipping ${key} component due to exclusion`)
72
+ continue
73
+ }
74
+ console.log(key)
75
+ console.group()
76
+ const component = domqlModule[key]
77
+ component.__name = key
78
+ const out = convert(component, desiredFormat, {
79
+ verbose: false,
80
+ exportDefault: exportCount === 1,
81
+ returnMitosisIR: true,
82
+ importsToRemove: uniqueImports,
83
+ removeReactImport: !first,
84
+ removeUseContextImport: removeUseContextImport,
85
+ })
86
+
87
+ convertedStr = convertedStr + out.str + '\n'
88
+ uniqueImports.push(...out.mitosisIR.imports)
89
+ first = false
90
+ if (out.mitosisIR._useContext)
91
+ removeUseContextImport = true
92
+ console.groupEnd()
93
+ }
94
+ console.groupEnd()
95
+
96
+ return convertedStr
97
+ }
28
98
 
29
99
  program
30
100
  .command('convert')
31
101
  .description('Recursively convert and copy all DomQL components under a directory')
32
- .argument('[src]', 'Source directory. By default, it is "src/"')
33
- .argument('[dest]', 'Destination directory. By default, it becomes the name of the desired format')
102
+ .argument('[src]', 'Source directory/file. By default, it is "src/"')
103
+ .argument('[dest]', 'Destination directory/file. Will be overwritten. By default, it becomes the name of the desired format')
34
104
  .option('--react', 'Convert all DomQL components to React')
35
105
  .option('--angular', 'Convert all DomQL components to Angular')
36
106
  .option('--vue2', 'Convert all DomQL components to Vue2')
37
107
  .option('--vue3', 'Convert all DomQL components to Vue3')
108
+ .option('--internal-uikit', '(For internal use only). Excludes particular components from the conversion')
109
+ .option('--tmp-dir', `Use this directory for storing intermediate & build files instead of the default (dest/${TMP_DIR_NAME})`)
38
110
  .action(async (src, dest, options) => {
39
111
  // Desired format
40
112
  let desiredFormat = 'react'
@@ -46,16 +118,102 @@ program
46
118
  desiredFormat = 'vue3'
47
119
  }
48
120
 
49
- // Resolve source & destination directories
121
+ // Resolve source file/dir
50
122
  const srcPath = path.resolve(src || './src')
51
- const destPath = path.resolve(dest || desiredFormat)
52
- const tmpDirPath = path.resolve(path.dirname(destPath), TMP_DIR_NAME)
123
+ if (!fs.existsSync(srcPath)) {
124
+ console.erorr(`Source directory/file ('${srcPath}') does not exist`)
125
+ return 1;
126
+ }
127
+ const srcIsDir = fs.statSync(srcPath).isDirectory()
53
128
 
54
- // Make tmp and dist directories
129
+ // Resolve & create tmp dir
130
+ const tmpDirPath = options.tmpDir ??
131
+ path.resolve(path.dirname(srcPath), TMP_DIR_NAME)
55
132
  await mkdirp(tmpDirPath)
56
- await mkdirp(destPath)
57
133
 
58
- const origFiles = await (await fs.promises.readdir(srcPath)).filter(file => !IGNORED_FILES.includes(file))
134
+ // Put a package.json file so that when we import() the modules from the
135
+ // directory, node doesn't recognize them as ES modules (in case the parent
136
+ // directory of the tmp dir has "type": "module" in its package.json
137
+ const pj = await fs.promises.open(path.resolve(tmpDirPath, 'package.json'), 'w')
138
+ await pj.writeFile(TMP_DIR_PACKAGE_JSON_STR, 'utf8')
139
+ await pj.close()
140
+
141
+ // Convert single file. Output will also be a single file.
142
+ if (!srcIsDir) {
143
+ // Determine destFilePath and create it if needed
144
+ let destFilePath;
145
+ if (dest) {
146
+ // dest is given.
147
+ if (!fs.existsSync(dest)) {
148
+ // dest doesn't exist. That's the output file we'll create.
149
+ destFilePath = path.resolve(dest)
150
+ } else if (fs.statSync(dest).isDirectory()) {
151
+ // dest exists and is a directory. Create our output file inside it.
152
+ destFilePath = path.join(path.resolve(dest), path.basename(srcPath))
153
+ } else {
154
+ // dest exists and is not a directory. Overwrite the file.
155
+ destFilePath = path.resolve(dest)
156
+ }
157
+ } else {
158
+ // dest not given. Use default (desiredFormat as directory).
159
+ const destDir = path.resolve(desiredFormat)
160
+ await mkdirp(destDir)
161
+ destFilePath = path.join(destDir, path.basename(srcPath))
162
+ }
163
+
164
+ const bundledFilePath = path.join(tmpDirPath, path.basename(srcPath))
165
+ console.log(`ESbuild ${srcPath} -> ${bundledFilePath}`)
166
+
167
+ // Bundle the component
168
+ await esbuild.build({
169
+ entryPoints: [srcPath],
170
+ bundle: true,
171
+ sourcemap: true,
172
+ target: 'node12',
173
+ format: 'cjs',
174
+ outfile: bundledFilePath,
175
+ })
176
+
177
+ // Import the module
178
+ const domqlModule = await importDomqlModule(bundledFilePath, options)
179
+
180
+ // Convert & append each exported domql object
181
+ console.log(`Converting modules in ${bundledFilePath}:`)
182
+ const convertedModuleStr = convertDomqlModule(
183
+ domqlModule,
184
+ desiredFormat,
185
+ options
186
+ )
187
+
188
+ // Write file
189
+ if (convertedModuleStr.length > 0) {
190
+ const fh = await fs.promises.open(destFilePath, 'w')
191
+ await fh.writeFile(convertedModuleStr, 'utf8')
192
+ await fh.close()
193
+ }
194
+
195
+ return 0;
196
+ }
197
+
198
+ // We're converting multiple files (in a directory)
199
+ // Determine destDirPath & create it if needed
200
+ if (!dest) dest = path.resolve(desiredFormat)
201
+ let destDirPath;
202
+ if (!fs.existsSync(dest)) {
203
+ // dest doesn't exist. Create it.
204
+ destDirPath = path.resolve(dest)
205
+ await mkdirp(destDirPath)
206
+ } else if (fs.statSync(dest).isDirectory()) {
207
+ // dest exists and is a directory.
208
+ destDirPath = path.resolve(dest)
209
+ } else {
210
+ // dest exists and is not a directory.
211
+ console.error(`The destination ('${path.resolve(dest)}') must be a directory when the source ('${srcPath}') is a directory`)
212
+ return 1;
213
+ }
214
+
215
+ const origFiles = (await fs.promises.readdir(srcPath))
216
+ .filter(file => !IGNORED_FILES.includes(file))
59
217
 
60
218
  // Bundle components
61
219
  await esbuild.build({
@@ -75,46 +233,24 @@ program
75
233
  if ((await fs.promises.stat(importDir)).isDirectory()) {
76
234
  // Import the module
77
235
  const importPath = `${importDir}/index.js`
78
- console.log(`importing ${componentDir}/`)
79
- const domqlModule = (await import(importPath)).default
236
+ const domqlModule = await importDomqlModule(importPath)
80
237
 
81
238
  // Create directory for component in dest dir
82
- const destComponentDirPath = `${destPath}/${componentDir}`
239
+ const destComponentDirPath = `${destDirPath}/${componentDir}`
83
240
  await mkdirp(destComponentDirPath)
84
241
 
85
242
  // Convert & append each exported domql object
86
- console.log(`Converting modules in ${componentDir}:`)
87
- console.group()
88
- const uniqueImports = []
89
- let fileContents = ''
90
- let first = true
91
- const exportCount = Object.keys(domqlModule).length
92
- for (const key in domqlModule) {
93
- console.log(key)
94
- console.group()
95
- const component = domqlModule[key]
96
- component.__name = key
97
- const out = convert(component, desiredFormat, {
98
- verbose: false,
99
- exportDefault: exportCount === 1,
100
- returnMitosisIR: true,
101
- importsToRemove: uniqueImports,
102
- removeReactImport: !first
103
- })
104
-
105
- fileContents = fileContents + out.str + '\n'
106
- uniqueImports.push(...out.mitosisIR.imports)
107
- first = false
108
- console.groupEnd()
109
- }
110
-
111
- console.groupEnd()
243
+ const convertedStr = convertDomqlModule(
244
+ domqlModule,
245
+ desiredFormat,
246
+ options
247
+ )
112
248
 
113
249
  // Write file
114
- if (fileContents.length > 0) {
250
+ if (convertedStr.length > 0) {
115
251
  const fh = await fs.promises
116
- .open(`${destComponentDirPath}/index.js`, 'w')
117
- await fh.writeFile(fileContents, 'utf8')
252
+ .open(`${destComponentDirPath}/index.js`, 'w')
253
+ await fh.writeFile(convertedStr, 'utf8')
118
254
  await fh.close()
119
255
  }
120
256
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@symbo.ls/cli",
3
- "version": "2.11.5",
3
+ "version": "2.11.16",
4
4
  "description": "Fetch your Symbols configuration",
5
5
  "main": "bin/fetch.js",
6
6
  "author": "Symbols",
@@ -27,5 +27,5 @@
27
27
  "peerDependencies": {
28
28
  "domql-to-mitosis": "latest"
29
29
  },
30
- "gitHead": "d5256e4c77123737a42641919ddbddb5acb6615c"
30
+ "gitHead": "9d17c62d340b3ed3ecfba460d9f5656b324a5bbb"
31
31
  }