@symbo.ls/cli 2.11.515 → 2.11.516

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/fetch.js CHANGED
@@ -8,7 +8,6 @@ import * as fetch from '@symbo.ls/fetch'
8
8
  import * as utils from '@domql/utils'
9
9
  import { convertFromCli } from './convert.js'
10
10
  import { createFs } from './fs.js'
11
- import { fs2js } from './fs2.js'
12
11
  const { isObjectLike } = (utils.default || utils)
13
12
  const { fetchRemote } = (fetch.default || fetch)
14
13
 
@@ -145,5 +144,3 @@ program
145
144
  .option('--verbose-code', 'Verbose errors and warnings')
146
145
  .option('--dist-dir', 'Directory to import files to.')
147
146
  .action(fetchFromCli)
148
-
149
- program.command('push').description('Push changes to platform').action(fs2js)
package/bin/index.js CHANGED
@@ -10,6 +10,8 @@ import './sync.js'
10
10
  import './clean.js'
11
11
  import './convert.js'
12
12
  import './create.js'
13
+ import './login.js'
14
+ import './push.js'
13
15
  import './link-packages.js'
14
16
 
15
17
  const args = process.argv
@@ -1,27 +1,27 @@
1
1
  export default [
2
- 'attrs-in-props',
3
2
  'create-smbls',
3
+ '@symbo.ls/fetch',
4
+ 'attrs-in-props',
5
+ '@symbo.ls/feather-icons',
6
+ '@symbo.ls/fluent-icons',
4
7
  '@symbo.ls/emotion',
5
8
  '@symbo.ls/default-icons',
6
- '@symbo.ls/feather-icons',
7
- '@symbo.ls/fetch',
8
- '@symbo.ls/material-icons',
9
9
  '@symbo.ls/preview',
10
+ '@symbo.ls/material-icons',
10
11
  '@symbo.ls/utils',
11
- '@symbo.ls/fluent-icons',
12
12
  '@symbo.ls/default-config',
13
13
  '@symbo.ls/scratch',
14
14
  '@symbo.ls/init',
15
15
  '@symbo.ls/atoms',
16
16
  '@symbo.ls/socket',
17
- '@symbo.ls/icon',
18
17
  'css-in-props',
19
- '@symbo.ls/box',
20
- '@symbo.ls/notification',
18
+ '@symbo.ls/icon',
21
19
  '@symbo.ls/input',
22
- '@symbo.ls/tooltip',
20
+ '@symbo.ls/box',
23
21
  '@symbo.ls/link',
24
22
  '@symbo.ls/select',
23
+ '@symbo.ls/notification',
24
+ '@symbo.ls/tooltip',
25
25
  '@symbo.ls/cli',
26
26
  '@symbo.ls/button',
27
27
  '@symbo.ls/avatar',
package/bin/login.js CHANGED
@@ -1,18 +1,114 @@
1
1
  'use strict'
2
2
 
3
- const { program } = require('./program')
4
- const API_URL = 'https://api.symbols.dev/' // eslint-disable-line
3
+ import inquirer from 'inquirer'
4
+ import fs from 'fs'
5
+ import path from 'path'
6
+ import os from 'os'
7
+ import chalk from 'chalk'
8
+ import { program } from './program.js'
9
+ import { getApiUrl } from '../helpers/config.js'
10
+
11
+ const RC_FILE = '.smblsrc'
12
+
13
+ // Helper to manage credentials
14
+ export class CredentialManager {
15
+ constructor () {
16
+ this.rcPath = path.join(os.homedir(), RC_FILE)
17
+ }
18
+
19
+ // Load credentials from rc file
20
+ loadCredentials () {
21
+ try {
22
+ const data = fs.readFileSync(this.rcPath, 'utf8')
23
+ return JSON.parse(data)
24
+ } catch (err) {
25
+ return {}
26
+ }
27
+ }
28
+
29
+ // Save credentials to rc file
30
+ saveCredentials (credentials) {
31
+ try {
32
+ fs.writeFileSync(this.rcPath, JSON.stringify(credentials, null, 2))
33
+ return true
34
+ } catch (err) {
35
+ console.error('Failed to save credentials:', err)
36
+ return false
37
+ }
38
+ }
39
+
40
+ // Get stored auth token
41
+ getAuthToken () {
42
+ const creds = this.loadCredentials()
43
+ return creds.authToken
44
+ }
45
+
46
+ // Clear stored credentials
47
+ clearCredentials () {
48
+ try {
49
+ fs.unlinkSync(this.rcPath)
50
+ return true
51
+ } catch (err) {
52
+ return false
53
+ }
54
+ }
55
+ }
5
56
 
6
57
  program
7
- .command('login [destination]')
58
+ .command('login')
8
59
  .description('Sign in to Symbols')
9
- .argument('<username>', 'user to login')
10
- .argument('[password]', 'password for user, if required', 'no password given')
11
- .action(async (username, password) => {
12
- console.log('username:', username)
13
- console.log('password:', password)
14
-
15
- const response = await fetch(API_URL)
16
- const body = await response.json()
17
- console.log(body)
60
+ .action(async () => {
61
+ console.log('yo login')
62
+
63
+ console.log(getApiUrl())
64
+
65
+ // Prompt for credentials
66
+ const answers = await inquirer.prompt([
67
+ {
68
+ type: 'input',
69
+ name: 'email',
70
+ message: 'Enter your email:',
71
+ validate: input => input.includes('@') || 'Please enter a valid email'
72
+ },
73
+ {
74
+ type: 'password',
75
+ name: 'password',
76
+ message: 'Enter your password:',
77
+ validate: input => input.length >= 6 || 'Password must be at least 6 characters'
78
+ }
79
+ ])
80
+
81
+ try {
82
+ // Make login request
83
+ const response = await fetch(`${getApiUrl()}/auth/login`, {
84
+ method: 'POST',
85
+ headers: {
86
+ 'Content-Type': 'application/json'
87
+ },
88
+ body: JSON.stringify({
89
+ email: answers.email,
90
+ password: answers.password
91
+ })
92
+ })
93
+
94
+ const data = await response.json()
95
+
96
+ if (!response.ok) {
97
+ throw new Error(data.error || 'Authentication failed')
98
+ }
99
+
100
+ // Save credentials
101
+ const credManager = new CredentialManager()
102
+ credManager.saveCredentials({
103
+ authToken: data.token,
104
+ userId: data.userId,
105
+ email: answers.email
106
+ })
107
+
108
+ console.log(chalk.green('\nSuccessfully logged in!'))
109
+ console.log(chalk.dim(`Credentials saved to ${credManager.rcPath}`))
110
+ } catch (error) {
111
+ console.error(chalk.red('\nLogin failed:'), error.message)
112
+ process.exit(1)
113
+ }
18
114
  })
package/bin/push.js ADDED
@@ -0,0 +1,185 @@
1
+ 'use strict'
2
+
3
+ import path from 'path'
4
+ import chalk from 'chalk'
5
+ import inquirer from 'inquirer'
6
+ import { loadModule } from './require.js'
7
+ import { program } from './program.js'
8
+ import { CredentialManager } from './login.js'
9
+ import { buildDirectory } from '../helpers/fileUtils.js'
10
+ import { showDiffPager } from '../helpers/diffUtils.js'
11
+ import { normalizeKeys, generateChanges } from '../helpers/compareUtils.js'
12
+ import {
13
+ getServerProjectData,
14
+ updateProjectOnServer
15
+ } from '../helpers/apiUtils.js'
16
+
17
+ const RC_PATH = process.cwd() + '/symbols.json'
18
+ const CREATE_PROJECT_URL = 'https://symbols.app/create'
19
+
20
+ function printProjectNotFoundGuidance (appKey) {
21
+ console.error(chalk.bold.red('\nProject not found or access denied.'))
22
+ console.error(chalk.bold.yellow('\nPossible reasons:'))
23
+ console.error(chalk.gray('1. The project does not exist'))
24
+ console.error(chalk.gray("2. You don't have access to this project"))
25
+ console.error(chalk.gray('3. The app key in symbols.json might be incorrect'))
26
+
27
+ console.error(chalk.bold.yellow('\nTo resolve this:'))
28
+ console.error(
29
+ chalk.white(
30
+ `1. Visit ${chalk.cyan.underline(
31
+ CREATE_PROJECT_URL
32
+ )} to create a new project`
33
+ )
34
+ )
35
+ console.error(
36
+ chalk.white(
37
+ '2. After creating the project, update your symbols.json with the correct information:'
38
+ )
39
+ )
40
+ console.error(chalk.gray(` - Verify the app key: ${chalk.cyan(appKey)}`))
41
+ console.error(chalk.gray(' - Make sure you have the correct permissions'))
42
+
43
+ console.error(chalk.bold.yellow('\nThen try again:'))
44
+ console.error(chalk.cyan('$ smbls push'))
45
+ }
46
+
47
+ async function loadProjectConfiguration () {
48
+ try {
49
+ const config = await loadModule(RC_PATH)
50
+ if (!config.key) {
51
+ throw new Error('Missing app key in symbols.json')
52
+ }
53
+ return config
54
+ } catch (e) {
55
+ if (e.message.includes('Missing app key')) {
56
+ console.error(chalk.bold.red('\nInvalid symbols.json configuration:'))
57
+ console.error(chalk.white('The file must contain a valid app key.'))
58
+ console.error(chalk.bold.yellow('\nExample symbols.json:'))
59
+ console.error(
60
+ chalk.cyan(JSON.stringify({ key: 'your.app.key' }, null, 2))
61
+ )
62
+ } else {
63
+ console.error(
64
+ chalk.bold.red('Please include symbols.json in your repository root')
65
+ )
66
+ }
67
+ process.exit(1)
68
+ }
69
+ }
70
+
71
+ async function buildLocalProject () {
72
+ const distDir = path.join(process.cwd(), 'smbls')
73
+ const outputDirectory = path.join(distDir, 'dist')
74
+
75
+ await buildDirectory(distDir, outputDirectory)
76
+ const outputFile = path.join(outputDirectory, 'index.js')
77
+ return normalizeKeys(await loadModule(outputFile))
78
+ }
79
+
80
+ async function confirmChanges (changes) {
81
+ if (changes.length === 0) {
82
+ console.log(chalk.bold.yellow('No changes detected'))
83
+ return false
84
+ }
85
+
86
+ console.log(chalk.bold.white('\nDetected changes:'))
87
+ const changesByType = changes.reduce((acc, [type, path]) => {
88
+ acc[type] = (acc[type] || 0) + 1
89
+ return acc
90
+ }, {})
91
+
92
+ Object.entries(changesByType).forEach(([type, count]) => {
93
+ console.log(chalk.gray(`- ${type}: ${chalk.cyan(count)} changes`))
94
+ })
95
+
96
+ const { proceed } = await inquirer.prompt([
97
+ {
98
+ type: 'confirm',
99
+ name: 'proceed',
100
+ message: 'Proceed with these changes?',
101
+ default: false
102
+ }
103
+ ])
104
+
105
+ return proceed
106
+ }
107
+
108
+ export async function pushProjectChanges () {
109
+ const credManager = new CredentialManager()
110
+ const authToken = credManager.getAuthToken()
111
+
112
+ if (!authToken) {
113
+ console.error(chalk.red('Please login first using: smbls login'))
114
+ process.exit(1)
115
+ }
116
+
117
+ try {
118
+ const config = await loadProjectConfiguration()
119
+ const { key: appKey } = config
120
+
121
+ // Build and load local project
122
+ console.log(chalk.dim('Building local project...'))
123
+ const projectData = await buildLocalProject()
124
+ console.log(chalk.gray('Local project built and loaded successfully'))
125
+
126
+ // Get server data
127
+ try {
128
+ console.log(chalk.dim('Fetching server data...'))
129
+ const serverProjectData = await getServerProjectData(appKey, authToken)
130
+
131
+ if (!serverProjectData) {
132
+ throw new Error('Failed to fetch server data: Empty response')
133
+ }
134
+
135
+ const normalizedServerData = normalizeKeys(serverProjectData)
136
+ console.log(chalk.gray('Server data fetched successfully'))
137
+
138
+ // Compare and get changes
139
+ const { changes, diffs } = generateChanges(
140
+ normalizedServerData,
141
+ projectData
142
+ )
143
+
144
+ // Show changes and confirm
145
+ if (changes.length > 0) {
146
+ console.log('\nDetailed changes:')
147
+ await showDiffPager(diffs)
148
+ }
149
+
150
+ const shouldProceed = await confirmChanges(changes)
151
+ if (!shouldProceed) {
152
+ console.log(chalk.yellow('Operation cancelled'))
153
+ return
154
+ }
155
+
156
+ // Update server
157
+ console.log(chalk.dim('Updating server...'))
158
+ await updateProjectOnServer(appKey, authToken, changes, projectData)
159
+
160
+ console.log(chalk.bold.green('\nProject updated successfully!'))
161
+ console.log(
162
+ chalk.gray(`Total changes applied: ${chalk.cyan(changes.length)}`)
163
+ )
164
+ } catch (error) {
165
+ if (
166
+ error.message.includes('Failed to fetch server data') ||
167
+ (error.response && error.response.status === 404) ||
168
+ Object.keys(error.response?.data || {}).length === 0
169
+ ) {
170
+ printProjectNotFoundGuidance(appKey)
171
+ } else {
172
+ throw error // Re-throw other errors to be caught by outer catch block
173
+ }
174
+ process.exit(1)
175
+ }
176
+ } catch (error) {
177
+ console.error(chalk.bold.red('\nPush failed:'), chalk.white(error.message))
178
+ process.exit(1)
179
+ }
180
+ }
181
+
182
+ program
183
+ .command('push')
184
+ .description('Push changes to platform')
185
+ .action(pushProjectChanges)
@@ -0,0 +1,73 @@
1
+ import { getApiUrl } from './config.js'
2
+ import { ALLOWED_FIELDS } from './compareUtils.js'
3
+
4
+ export async function getServerProjectData (appKey, authToken) {
5
+ try {
6
+ const response = await fetch(`${getApiUrl()}/get/`, {
7
+ method: 'GET',
8
+ headers: {
9
+ 'X-AppKey': appKey,
10
+ Authorization: `Bearer ${authToken}`
11
+ }
12
+ })
13
+
14
+ const data = await response.json()
15
+
16
+ if (!response.ok) {
17
+ const error = new Error(`Failed to fetch server data: ${response.statusText}`)
18
+ error.response = {
19
+ status: response.status,
20
+ data
21
+ }
22
+ throw error
23
+ }
24
+
25
+ // Check if response is empty object
26
+ if (data && Object.keys(data).length === 0) {
27
+ const error = new Error('Project not found')
28
+ error.response = {
29
+ status: 404,
30
+ data
31
+ }
32
+ throw error
33
+ }
34
+
35
+ return data
36
+ } catch (error) {
37
+ if (!error.response) {
38
+ error.response = {
39
+ status: 500,
40
+ data: {}
41
+ }
42
+ }
43
+ throw error
44
+ }
45
+ }
46
+
47
+ export async function updateProjectOnServer (appKey, authToken, changes, projectData) {
48
+ // Validate changes before sending
49
+ const validChanges = changes.filter(([type, path]) => {
50
+ const normalizedPath = path[0].toLowerCase()
51
+ return ALLOWED_FIELDS.includes(normalizedPath)
52
+ })
53
+
54
+ const response = await fetch(`${getApiUrl()}/auth/project/update`, {
55
+ method: 'POST',
56
+ headers: {
57
+ 'Content-Type': 'application/json',
58
+ Authorization: `Bearer ${authToken}`
59
+ },
60
+ body: JSON.stringify({
61
+ appKey,
62
+ changes: validChanges,
63
+ projectUpdates: projectData
64
+ })
65
+ })
66
+
67
+ if (!response.ok) {
68
+ const error = await response.json()
69
+ throw new Error(error.error || 'Failed to update project')
70
+ }
71
+
72
+ return response
73
+ }
@@ -0,0 +1,135 @@
1
+ import { generateDiffDisplay } from './diffUtils.js'
2
+
3
+ export const ALLOWED_FIELDS = [
4
+ 'designsystem',
5
+ 'functions',
6
+ 'files',
7
+ 'components',
8
+ 'dependencies',
9
+ 'pages',
10
+ 'snippets'
11
+ ]
12
+
13
+ export function normalizeKeys (obj) {
14
+ if (!obj || typeof obj !== 'object') return obj
15
+
16
+ if (Array.isArray(obj)) {
17
+ return obj.map(item => normalizeKeys(item))
18
+ }
19
+
20
+ return Object.entries(obj).reduce((acc, [key, value]) => {
21
+ const normalizedKey = key.toLowerCase()
22
+ acc[normalizedKey] = value
23
+ return acc
24
+ }, {})
25
+ }
26
+
27
+ export function generateChanges (oldData, newData) {
28
+ const changes = []
29
+ const diffs = []
30
+
31
+ if (!oldData || !newData) {
32
+ throw new Error('Both oldData and newData must be provided')
33
+ }
34
+
35
+ // Filter out non-allowed top-level fields before comparison
36
+ const filteredOldData = Object.keys(oldData)
37
+ .filter(key => ALLOWED_FIELDS.includes(key.toLowerCase()))
38
+ .reduce((obj, key) => {
39
+ obj[key] = oldData[key]
40
+ return obj
41
+ }, {})
42
+
43
+ const filteredNewData = Object.keys(newData)
44
+ .filter(key => ALLOWED_FIELDS.includes(key.toLowerCase()))
45
+ .reduce((obj, key) => {
46
+ obj[key] = newData[key]
47
+ return obj
48
+ }, {})
49
+
50
+ compareObjects(filteredOldData, filteredNewData, [], changes, diffs)
51
+
52
+ return { changes, diffs }
53
+ }
54
+
55
+ function isEqual (val1, val2) {
56
+ if (val1 === val2) return true
57
+ if (!val1 && !val2) return true
58
+ if (!val1 || !val2) return false
59
+
60
+ if (typeof val1 === 'function' || typeof val2 === 'function') {
61
+ const str1 = typeof val1 === 'function' ? val1.toString() : val1
62
+ const str2 = typeof val2 === 'function' ? val2.toString() : val2
63
+ return str1 === str2
64
+ }
65
+
66
+ if (Array.isArray(val1) && Array.isArray(val2)) {
67
+ if (val1.length !== val2.length) return false
68
+ return val1.every((item, index) => isEqual(item, val2[index]))
69
+ }
70
+
71
+ if (typeof val1 !== 'object' || val1 === null || val2 === null) {
72
+ if (typeof val1 === 'number' && typeof val2 === 'number') {
73
+ return val1.toString() === val2.toString()
74
+ }
75
+ return Object.is(val1, val2)
76
+ }
77
+
78
+ const keys1 = Object.keys(val1).sort()
79
+ const keys2 = Object.keys(val2).sort()
80
+
81
+ if (keys1.length !== keys2.length) return false
82
+ if (!keys1.every((key, index) => key === keys2[index])) return false
83
+
84
+ return keys1.every(key => isEqual(val1[key], val2[key]))
85
+ }
86
+
87
+ function compareObjects (oldObj, newObj, currentPath, changes, diffs) {
88
+ oldObj = oldObj || {}
89
+ newObj = newObj || {}
90
+
91
+ if (isEqual(oldObj, newObj)) return
92
+
93
+ if (
94
+ typeof oldObj !== 'object' ||
95
+ typeof newObj !== 'object' ||
96
+ oldObj === null ||
97
+ newObj === null
98
+ ) {
99
+ changes.push(['update', currentPath, typeof newObj === 'function' ? newObj.toString() : newObj])
100
+ diffs.push(generateDiffDisplay('update', currentPath, oldObj, newObj))
101
+ return
102
+ }
103
+
104
+ handleDeletions(oldObj, newObj, currentPath, changes, diffs)
105
+ handleAdditionsAndUpdates(oldObj, newObj, currentPath, changes, diffs)
106
+ }
107
+
108
+ function handleDeletions (oldObj, newObj, currentPath, changes, diffs) {
109
+ const oldKeys = Object.keys(oldObj)
110
+ const newKeys = Object.keys(newObj)
111
+
112
+ for (const key of oldKeys) {
113
+ if (!newKeys.includes(key)) {
114
+ changes.push(['delete', [...currentPath, key]])
115
+ diffs.push(generateDiffDisplay('delete', [...currentPath, key], oldObj[key]))
116
+ }
117
+ }
118
+ }
119
+
120
+ function handleAdditionsAndUpdates (oldObj, newObj, currentPath, changes, diffs) {
121
+ const oldKeys = Object.keys(oldObj)
122
+ const newKeys = Object.keys(newObj)
123
+
124
+ for (const key of newKeys) {
125
+ const newValue = newObj[key]
126
+ const oldValue = oldObj[key]
127
+
128
+ if (!oldKeys.includes(key)) {
129
+ changes.push(['update', [...currentPath, key], typeof newValue === 'function' ? newValue.toString() : newValue])
130
+ diffs.push(generateDiffDisplay('add', [...currentPath, key], undefined, newValue))
131
+ } else if (!isEqual(oldValue, newValue)) {
132
+ compareObjects(oldValue, newValue, [...currentPath, key], changes, diffs)
133
+ }
134
+ }
135
+ }
@@ -0,0 +1,27 @@
1
+ import fs from 'fs'
2
+ import path from 'path'
3
+
4
+ export const getApiUrl = () => {
5
+ if (process.env.SMBLS_API_URL) {
6
+ return process.env.SMBLS_API_URL
7
+ }
8
+
9
+ const configPath = path.join(process.cwd(), '.smblsrc.json')
10
+ if (fs.existsSync(configPath)) {
11
+ try {
12
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'))
13
+ if (config.apiUrl) return config.apiUrl
14
+ } catch (err) {
15
+ // Silently fail and use defaults if config file is invalid
16
+ }
17
+ }
18
+
19
+ switch (process.env.NODE_ENV) {
20
+ case 'production':
21
+ return 'https://api.symbols.app'
22
+ case 'staging':
23
+ return 'https://api-staging.symbols.app'
24
+ default:
25
+ return 'http://localhost:13335'
26
+ }
27
+ }
@@ -0,0 +1,55 @@
1
+ import chalk from 'chalk'
2
+ import { spawn } from 'child_process'
3
+
4
+ export function formatValue (value) {
5
+ if (typeof value === 'object' && value !== null) {
6
+ return JSON.stringify(value, null, 2)
7
+ }
8
+ return String(value)
9
+ }
10
+
11
+ export function generateDiffDisplay (type, path, oldValue, newValue) {
12
+ const pathStr = path.join('.')
13
+ let output = chalk.dim(`@ ${pathStr}\n`)
14
+
15
+ switch (type) {
16
+ case 'update':
17
+ if (oldValue !== undefined) {
18
+ output += chalk.red(`- ${formatValue(oldValue)}\n`)
19
+ }
20
+ output += chalk.green(`+ ${formatValue(newValue)}\n`)
21
+ break
22
+ case 'delete':
23
+ output += chalk.red(`- ${formatValue(oldValue)}\n`)
24
+ break
25
+ default:
26
+ output += chalk.green(`+ ${formatValue(newValue)}\n`)
27
+ }
28
+
29
+ return output
30
+ }
31
+
32
+ export async function showDiffPager (diffs) {
33
+ return new Promise((resolve, reject) => {
34
+ const formattedDiffs = diffs.join('\n' + chalk.dim('---') + '\n')
35
+
36
+ const less = spawn('less', ['-R'], {
37
+ stdio: ['pipe', process.stdout, process.stderr]
38
+ })
39
+
40
+ less.stdin.on('error', (error) => {
41
+ if (error.code === 'EPIPE') {
42
+ resolve()
43
+ return
44
+ }
45
+ reject(error)
46
+ })
47
+
48
+ less.on('close', () => {
49
+ resolve()
50
+ })
51
+
52
+ less.stdin.write(formattedDiffs)
53
+ less.stdin.end()
54
+ })
55
+ }
@@ -1,43 +1,23 @@
1
1
  import fs from 'fs'
2
2
  import path from 'path'
3
3
  import { build } from 'esbuild'
4
- import { loadModule } from './require.js'
5
4
 
6
- const RC_PATH = process.cwd() + '/symbols.json'
7
-
8
- let rc = {}
9
- try {
10
- rc = loadModule(RC_PATH); // eslint-disable-line
11
- } catch (e) {
12
- console.error('Please include symbols.json to your root of respository')
13
- }
14
-
15
- export async function fs2js (
16
- distDir = path.join(process.cwd(), 'smbls')
17
- ) {
18
- const directoryPath = distDir
19
- const outputDirectory = distDir + '/dist'
20
- buildDirectory(directoryPath, outputDirectory)
21
- .then(() => {
22
- console.log('All files built successfully')
23
- })
24
- .catch((error) => {
25
- console.error('Error:', error)
26
- })
27
- const data = await import(process.cwd() + '/toko/dist/index.js')
28
- console.log(JSON.stringify(data))
29
- }
30
-
31
- async function buildDirectory (directoryPath, outputDirectory) {
5
+ export async function buildDirectory (directoryPath, outputDirectory) {
32
6
  try {
33
7
  const files = await getFilesRecursively(directoryPath)
34
8
  const buildPromises = files.map(async (filePath) => {
35
9
  const relativePath = path.relative(directoryPath, filePath)
36
10
  const outputFile = path.join(outputDirectory, relativePath)
11
+
12
+ // Ensure output subdirectories exist
13
+ const outputDir = path.dirname(outputFile)
14
+ if (!fs.existsSync(outputDir)) {
15
+ fs.mkdirSync(outputDir, { recursive: true })
16
+ }
17
+
37
18
  await buildFromFile(filePath, outputFile)
38
19
  })
39
20
  await Promise.all(buildPromises)
40
- console.log('All files built successfully')
41
21
  } catch (error) {
42
22
  console.error('Error building directory:', error)
43
23
  throw error
@@ -46,7 +26,7 @@ async function buildDirectory (directoryPath, outputDirectory) {
46
26
 
47
27
  async function buildFromFile (inputFilePath, outputFilePath) {
48
28
  try {
49
- const fileContents = await fs.readFileSync(inputFilePath, 'utf8')
29
+ const fileContents = fs.readFileSync(inputFilePath, 'utf8')
50
30
  await build({
51
31
  stdin: {
52
32
  contents: fileContents,
@@ -58,7 +38,10 @@ async function buildFromFile (inputFilePath, outputFilePath) {
58
38
  outfile: outputFilePath,
59
39
  target: 'node14',
60
40
  platform: 'node',
61
- format: 'cjs'
41
+ format: 'cjs',
42
+ bundle: true,
43
+ mainFields: ['module', 'main'],
44
+ external: ['esbuild']
62
45
  })
63
46
  } catch (error) {
64
47
  console.error('Error building file:', error)
@@ -69,11 +52,10 @@ async function buildFromFile (inputFilePath, outputFilePath) {
69
52
  async function getFilesRecursively (directoryPath) {
70
53
  const files = []
71
54
  async function traverseDirectory (currentPath) {
72
- const entries = await fs.readdirSync(currentPath, { withFileTypes: true })
55
+ const entries = fs.readdirSync(currentPath, { withFileTypes: true })
73
56
  for (const entry of entries) {
74
- if (entry.name.startsWith('dist')) {
75
- continue
76
- }
57
+ if (entry.name === 'dist' || entry.name === 'node_modules') continue
58
+
77
59
  const fullPath = path.join(currentPath, entry.name)
78
60
  if (entry.isDirectory()) {
79
61
  await traverseDirectory(fullPath)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@symbo.ls/cli",
3
- "version": "2.11.515",
3
+ "version": "2.11.516",
4
4
  "description": "Fetch your Symbols configuration",
5
5
  "main": "bin/fetch.js",
6
6
  "author": "Symbols",
@@ -26,5 +26,5 @@
26
26
  "node-fetch": "^3.1.0",
27
27
  "v8-compile-cache": "^2.3.0"
28
28
  },
29
- "gitHead": "020a244e20deb7740662e1e500f30bc118c07846"
29
+ "gitHead": "7f3d850309dfb9de15ef9ad33eca25e5a2c94073"
30
30
  }