@symbo.ls/cli 2.10.274 → 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.
- package/bin/convert.js +180 -44
- 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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
121
|
+
// Resolve source file/dir
|
|
50
122
|
const srcPath = path.resolve(src || './src')
|
|
51
|
-
|
|
52
|
-
|
|
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
|
-
//
|
|
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
|
-
|
|
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
|
-
|
|
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 = `${
|
|
239
|
+
const destComponentDirPath = `${destDirPath}/${componentDir}`
|
|
83
240
|
await mkdirp(destComponentDirPath)
|
|
84
241
|
|
|
85
242
|
// Convert & append each exported domql object
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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 (
|
|
250
|
+
if (convertedStr.length > 0) {
|
|
115
251
|
const fh = await fs.promises
|
|
116
|
-
|
|
117
|
-
await fh.writeFile(
|
|
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.
|
|
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": "
|
|
30
|
+
"gitHead": "9d17c62d340b3ed3ecfba460d9f5656b324a5bbb"
|
|
31
31
|
}
|