@symbo.ls/cli 2.11.125 → 2.11.128

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 +160 -118
  2. package/package.json +7 -5
package/bin/convert.js CHANGED
@@ -3,12 +3,17 @@
3
3
  import * as esbuild from 'esbuild'
4
4
  import { program } from './program.js'
5
5
  import { convert } from 'kalduna'
6
+ import { parse } from 'globusa'
6
7
  import fs from 'fs'
7
8
  import path from 'path'
8
- import { JSDOM } from 'jsdom'
9
9
 
10
- const l = (n) => console.log(`mark${n}`) // eslint-disable-line no-unused-vars
10
+ // Set up webpack
11
+ import syncWebpack from 'webpack'
12
+ import { promisify } from 'util'
13
+ const webpack = promisify(syncWebpack)
11
14
 
15
+ // Set up jsdom
16
+ import { JSDOM } from 'jsdom'
12
17
  const jsdom = new JSDOM('<html><head></head><body></body></html>')
13
18
  global.window = jsdom.window
14
19
  global.document = window.document
@@ -54,68 +59,145 @@ async function mkdirp (dir) {
54
59
  return null
55
60
  }
56
61
 
57
- async function importDomqlModule (modulePath) {
58
- console.log(`importing ${modulePath}`)
59
- return (await import(modulePath)).default
60
- }
61
-
62
- function convertDomqlModule (domqlModule, desiredFormat, options) {
62
+ // Returns a string
63
+ function convertDomqlModule(domqlModule, globusaStruct, desiredFormat, options) {
63
64
  let convertedStr = ''
64
65
  const whitelist = (options.only ? options.only.split(',') : null)
65
66
 
66
67
  console.group()
68
+ const exports = Object.keys(domqlModule)
69
+ .filter(exportName => {
70
+ if (!whitelist) return true
71
+ if (whitelist.includes(exportName)) {
72
+ console.log(`Skipping ${exportName} component due to whitelist exclusion`)
73
+ return false
74
+ }
75
+ return true
76
+ })
77
+ .filter(exportName => {
78
+ if (!options.internalUikit) return true
79
+ if (EXCLUDED_FROM_INTERNAL_UIKIT.includes(exportName)) {
80
+ console.log(`Skipping ${exportName} component due to internal uikit exclusion`)
81
+ return false
82
+ }
83
+ return true
84
+ })
85
+
86
+ const isSingleComponent = (exports.length === 1)
67
87
  const uniqueImports = []
68
- const first = true
69
- let currentExportIdx = 0
70
- const exportCount = Object.keys(domqlModule).length
71
- for (const key in domqlModule) {
72
- // Skip if not found in whitelist
73
- if (whitelist && !whitelist.includes(key)) { continue }
74
-
75
- // Skip some components if converting smbls uikit
76
- if (options.internalUikit &&
77
- EXCLUDED_FROM_INTERNAL_UIKIT.includes(key)) {
78
- console.log(`Skipping ${key} component due to exclusion`)
79
- continue
88
+ for (const idx in exports) {
89
+ const exportName = exports[idx]
90
+
91
+ const dobj = domqlModule[exportName]
92
+
93
+ // Set component name (if not present)
94
+ if (!dobj.__name) {
95
+ dobj.__name = exportName
80
96
  }
81
97
 
82
- if (convert) {
83
- console.group()
84
- const component = domqlModule[key]
85
- component.__name = key
86
- console.log(key) // NOTE: @nikoloza don't remove this (again)
87
-
88
- const isSingleComponent = exportCount === 1
89
- const isFirst = currentExportIdx === 0
90
- const isLast = currentExportIdx === exportCount - 1
91
-
92
- const out = convert(component, desiredFormat, {
93
- verbose: false,
94
- exportDefault: isSingleComponent,
95
- returnMitosisIR: true,
96
- importsToRemove: uniqueImports,
97
- removeReactImport: !isFirst
98
- })
98
+ console.group()
99
+ console.log(dobj.__name) // NOTE(Nikaoto): @nikoloza, don't remove this
99
100
 
100
- convertedStr = convertedStr + out.str
101
- if (options.trailingNewLine && !isLast) {
102
- convertedStr += '\n'
103
- }
101
+ const isFirst = (idx == 0)
102
+ const isLast = (idx == (exports.length - 1)) // NOTE: Don't use '===' here!
103
+
104
+ const kaldunaOpts = {
105
+ verbose: false,
106
+ returnMitosisIR: true,
107
+ exportDefault: isSingleComponent,
108
+ importsToRemove: uniqueImports,
109
+
110
+ /* NOTE: The option below prevents a name collision bug. For example:
111
+ export const A = { ... }
112
+ export const B = { extends: A }
104
113
 
105
- uniqueImports.push(...out.mitosisIR.imports)
106
- console.groupEnd()
107
- currentExportIdx++
114
+ Normally, converting component B will generate an import for A like:
115
+ 'import { A } from @symbo.ls/react'
116
+ But, in this case, because A is in local scope as one of the exports,
117
+ the component import will be ignored, preventing the collision.
118
+ */
119
+ componentImportsToIgnore: exports,
120
+ }
121
+
122
+ let out = null
123
+ if (isFirst) {
124
+ out = convert(dobj, desiredFormat, {
125
+ ...kaldunaOpts,
126
+ removeReactImport: false,
127
+ importsToInclude: globusaStruct.imports,
128
+ declarationsToInclude: globusaStruct.declarations,
129
+ })
108
130
  } else {
109
- throw new Error(
110
- 'Convert from `domql-to-mitosis` is not defined. Try to install' +
111
- '`domql-to-mitosis` and run this command again.')
131
+ out = convert(dobj, desiredFormat, {
132
+ ...kaldunaOpts,
133
+ removeReactImport: true,
134
+ })
112
135
  }
136
+
137
+ convertedStr = convertedStr + out.str
138
+ if (!isLast) {
139
+ convertedStr += '\n'
140
+ }
141
+ uniqueImports.push(...out.mitosisIR.imports)
142
+ console.groupEnd()
113
143
  }
114
144
  console.groupEnd()
115
145
 
116
146
  return convertedStr
117
147
  }
118
148
 
149
+ // Takes a source file, then bundles, parses and converts it and writes the
150
+ // result to the destination. The tmpDirPath is used as a working directory for
151
+ // temporary files.
152
+ async function convertFile(srcPath, tmpDirPath, destPath,
153
+ desiredFormat, options) {
154
+ // Parse with globusa
155
+ console.log(`Parsing components in ${srcPath}`)
156
+ const fileContent = await fs.promises.readFile(srcPath, 'utf8')
157
+ const globusaStruct = parse(fileContent)
158
+
159
+ // Bundle with webpack
160
+ const libraryName = 'banunu' // This can literally be anything
161
+ const fileName = path.basename(srcPath)
162
+ const bundledFilePath = path.resolve(tmpDirPath, fileName)
163
+ console.log(`Webpack ${srcPath} -> ${bundledFilePath}`)
164
+ await webpack({
165
+ entry: srcPath,
166
+ output: {
167
+ path: tmpDirPath,
168
+ filename: fileName,
169
+ chunkFormat: 'commonjs',
170
+ library: { name: libraryName,
171
+ type: 'commonjs-static' },
172
+ },
173
+ target: 'node',
174
+ mode: 'development'
175
+ })
176
+
177
+ // Import the bundled module to obtain exported domql objects
178
+ console.log(`Importing ${bundledFilePath}`)
179
+ const domqlModule = (await import(bundledFilePath))[libraryName]
180
+
181
+ // Convert it/them with kalduna
182
+ console.log(`Converting components in ${bundledFilePath}:`)
183
+ const convertedModuleStr = convertDomqlModule(
184
+ domqlModule,
185
+ globusaStruct,
186
+ desiredFormat,
187
+ options
188
+ )
189
+
190
+ // Create dest dir
191
+ await mkdirp(path.dirname(destPath))
192
+
193
+ // Write file
194
+ if (convertedModuleStr && convertedModuleStr.length > 0) {
195
+ const fh = await fs.promises.open(destPath, 'w')
196
+ await fh.writeFile(convertedModuleStr, 'utf8')
197
+ await fh.close()
198
+ }
199
+ }
200
+
119
201
  program
120
202
  .command('convert')
121
203
  .description('Convert and copy all DomQL components under a directory')
@@ -137,6 +219,18 @@ program
137
219
  '(For internal use only). ' +
138
220
  'Excludes particular components from the conversion')
139
221
  .action(async (src, dest, options) => {
222
+ if (!convert) {
223
+ throw new Error(
224
+ 'convert() from `kalduna` is not defined. Try to install ' +
225
+ '`kalduna` and run this command again.')
226
+ }
227
+
228
+ if (!parse) {
229
+ throw new Error(
230
+ 'parse() from `globusa` is not defined. Try to install ' +
231
+ '`globusa` and run this command again.')
232
+ }
233
+
140
234
  // Desired format
141
235
  let desiredFormat = 'react'
142
236
  if (options.angular) {
@@ -191,41 +285,18 @@ program
191
285
  destFilePath = path.join(destDir, path.basename(srcPath))
192
286
  }
193
287
 
194
- const bundledFilePath = path.join(tmpDirPath, path.basename(srcPath))
195
- console.log(`ESbuild ${srcPath} -> ${bundledFilePath}`)
196
-
197
- // Bundle the component
198
- await esbuild.build({
199
- entryPoints: [srcPath],
200
- bundle: true,
201
- sourcemap: true,
202
- target: 'node12',
203
- format: 'cjs',
204
- outfile: bundledFilePath
205
- })
206
-
207
- // Import the module
208
- const domqlModule = await importDomqlModule(bundledFilePath, options)
209
-
210
- // Convert & append each exported domql object
211
- console.log(`Converting modules in ${bundledFilePath}:`)
212
- const convertedModuleStr = convertDomqlModule(
213
- domqlModule,
288
+ await convertFile(
289
+ srcPath,
290
+ tmpDirPath,
291
+ destFilePath,
214
292
  desiredFormat,
215
293
  options
216
294
  )
217
295
 
218
- // Write file
219
- if (convertedModuleStr.length > 0) {
220
- const fh = await fs.promises.open(destFilePath, 'w')
221
- await fh.writeFile(convertedModuleStr, 'utf8')
222
- await fh.close()
223
- }
224
-
225
296
  return 0
226
297
  }
227
298
 
228
- // We're converting multiple files (in a directory)
299
+ // We're converting multiple files (in a directory).
229
300
  // Determine destDirPath & create it if needed
230
301
  if (!dest) dest = path.resolve(desiredFormat)
231
302
  let destDirPath
@@ -239,52 +310,23 @@ program
239
310
  } else {
240
311
  // dest exists and is not a directory.
241
312
  console.error(
242
- `The destination ('${path.resolve(dest)}') must be a directory when` +
313
+ `The destination ('${path.resolve(dest)}') must be a directory when ` +
243
314
  `the source ('${srcPath}') is a directory`)
244
315
  return 1
245
316
  }
246
317
 
247
- const origFiles = (await fs.promises.readdir(srcPath))
248
- .filter(file => !IGNORED_FILES.includes(file))
249
-
250
- // Bundle components
251
- await esbuild.build({
252
- entryPoints: origFiles.map(file =>
253
- path.join(srcPath, file,'./index.js')),
254
- bundle: true,
255
- sourcemap: true,
256
- target: 'node12',
257
- format: 'cjs',
258
- outdir: tmpDirPath
259
- })
260
-
261
- // Convert components
262
- const componentDirs = await fs.promises.readdir(tmpDirPath)
263
- for (const componentDir of componentDirs) {
264
- const importDir = path.join(tmpDirPath, componentDir)
265
- if ((await fs.promises.stat(importDir)).isDirectory()) {
266
- // Import the module
267
- const importPath = `${importDir}/index.js`
268
- const domqlModule = await importDomqlModule(importPath)
269
-
270
- // Create directory for component in dest dir
271
- const destComponentDirPath = `${destDirPath}/${componentDir}`
272
- await mkdirp(destComponentDirPath)
273
-
274
- // Convert & append each exported domql object
275
- const convertedStr = convertDomqlModule(
276
- domqlModule,
277
- desiredFormat,
278
- { ...options, trailingNewLine: true }
279
- )
280
-
281
- // Write file
282
- if (convertedStr.length > 0) {
283
- const fh = await fs.promises
284
- .open(`${destComponentDirPath}/index.js`, 'w')
285
- await fh.writeFile(convertedStr, 'utf8')
286
- await fh.close()
287
- }
288
- }
318
+ const sourceFileNames = (await fs.promises.readdir(srcPath))
319
+ .filter(file => !IGNORED_FILES.includes(file))
320
+
321
+ for (const file of sourceFileNames) {
322
+ const indexFilePath = path.join(srcPath, file, 'index.js')
323
+
324
+ await convertFile(
325
+ indexFilePath,
326
+ path.join(tmpDirPath, file),
327
+ path.join(destDirPath, file, 'index.js'),
328
+ desiredFormat,
329
+ options
330
+ )
289
331
  }
290
332
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@symbo.ls/cli",
3
- "version": "2.11.125",
3
+ "version": "2.11.128",
4
4
  "description": "Fetch your Symbols configuration",
5
5
  "main": "bin/fetch.js",
6
6
  "author": "Symbols",
@@ -16,16 +16,18 @@
16
16
  },
17
17
  "dependencies": {
18
18
  "@symbo.ls/init": "latest",
19
+ "@symbo.ls/react": "latest",
19
20
  "@symbo.ls/socket": "latest",
20
21
  "chalk": "^5.0.0",
21
22
  "commander": "latest",
22
23
  "esbuild": "latest",
24
+ "globusa": "latest",
23
25
  "jsdom": "^21.1.0",
24
26
  "node-fetch": "^3.1.0",
25
27
  "v8-compile-cache": "^2.3.0"
26
28
  },
27
- "peerDependencies": {
28
- "kalduna": "latest"
29
- },
30
- "gitHead": "baa36f3a07d4ea577fe641432ab3ca0432fb4915"
29
+ "gitHead": "a80004b78547611d5e422bb1fb4e6b1dd5358105",
30
+ "devDependencies": {
31
+ "webpack": "^5.88.2"
32
+ }
31
33
  }