@heyputer/shell 2.1.0 → 3.0.0
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/.github/workflows/npm-build.yml +0 -2
- package/.github/workflows/npm-publish.yml +0 -4
- package/bin/index.js +22 -202
- package/package.json +3 -5
- package/src/commands/auth.js +7 -12
- package/src/commands/files.js +16 -18
- package/src/commands/shell.js +5 -3
- package/src/commons.js +81 -256
- package/src/executor.js +12 -129
- package/src/modules/ErrorModule.js +62 -1
- package/src/modules/ProfileModule.js +154 -38
- package/src/utils.js +0 -91
- package/tests/ErrorModule.test.js +73 -1
- package/tests/ProfileModule.test.js +58 -44
- package/tests/commons.test.js +66 -124
- package/tests/executor.test.js +8 -0
- package/tests/files.test.js +23 -3
- package/tests/shell.test.js +2 -1
- package/tests/utils.test.js +1 -141
- package/src/commands/apps.js +0 -356
- package/src/commands/deploy.js +0 -54
- package/src/commands/init.js +0 -322
- package/src/commands/sites.js +0 -169
- package/src/commands/subdomains.js +0 -95
- package/tests/apps.test.js +0 -194
- package/tests/deploy.test.js +0 -84
- package/tests/sites.test.js +0 -67
- package/tests/subdomains.test.js +0 -90
package/src/commands/apps.js
DELETED
|
@@ -1,356 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import fetch from 'node-fetch';
|
|
4
|
-
import Table from 'cli-table3';
|
|
5
|
-
import { displayNonNullValues, formatDate } from '../utils.js';
|
|
6
|
-
import { API_BASE, getHeaders, getDefaultHomePage, isValidAppName, resolvePath } from '../commons.js';
|
|
7
|
-
import { createSubdomain, getSubdomains } from './subdomains.js';
|
|
8
|
-
import { deleteSite } from './sites.js';
|
|
9
|
-
import { copyFile, createFile, listRemoteFiles, pathExists, removeFileOrDirectory } from './files.js';
|
|
10
|
-
import { getCurrentDirectory } from './auth.js';
|
|
11
|
-
import crypto from '../crypto.js';
|
|
12
|
-
import { getPuter } from '../modules/PuterModule.js';
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* List all apps
|
|
16
|
-
*
|
|
17
|
-
* @param {object} options
|
|
18
|
-
* ```json
|
|
19
|
-
* {
|
|
20
|
-
* statsPeriod: [all (default), today, yesterday, 7d, 30d, this_month, last_month, this_year, last_year, month_to_date, year_to_date, last_12_months],
|
|
21
|
-
* iconSize: [16, 32, 64, 128, 256, 512]
|
|
22
|
-
* }
|
|
23
|
-
* ```
|
|
24
|
-
*/
|
|
25
|
-
export async function listApps({ statsPeriod = 'all', iconSize = 64 } = {}) {
|
|
26
|
-
console.log(chalk.green(`Listing of apps during period "${chalk.cyan(statsPeriod)}" (try also: today, yesterday, 7d, 30d, this_month, last_month):\n`));
|
|
27
|
-
const puter = getPuter();
|
|
28
|
-
try {
|
|
29
|
-
const result = await puter.apps.list({
|
|
30
|
-
icon_size: iconSize,
|
|
31
|
-
stats_period: statsPeriod
|
|
32
|
-
});
|
|
33
|
-
if (result) {
|
|
34
|
-
// Create a new table instance
|
|
35
|
-
const table = new Table({
|
|
36
|
-
head: [
|
|
37
|
-
chalk.cyan('#'),
|
|
38
|
-
chalk.cyan('Title'),
|
|
39
|
-
chalk.cyan('Name'),
|
|
40
|
-
chalk.cyan('Created'),
|
|
41
|
-
chalk.cyan('Subdomain'),
|
|
42
|
-
// chalk.cyan('Description'),
|
|
43
|
-
chalk.cyan('#Open'),
|
|
44
|
-
chalk.cyan('#User')
|
|
45
|
-
],
|
|
46
|
-
colWidths: [5, 20, 30, 25, 35, 8, 8],
|
|
47
|
-
wordWrap: false
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
// Populate the table with app data
|
|
51
|
-
let i = 0;
|
|
52
|
-
for (const app of result) {
|
|
53
|
-
table.push([
|
|
54
|
-
i++,
|
|
55
|
-
app['title'],
|
|
56
|
-
app['name'],
|
|
57
|
-
formatDate(app['created_at']),
|
|
58
|
-
app['index_url']?app['index_url'].split('.')[0].split('//')[1]:'<NO_URL>',
|
|
59
|
-
// app['description'].slice(0, 10) || 'N/A',
|
|
60
|
-
app['stats']['open_count'],
|
|
61
|
-
app['stats']['user_count']
|
|
62
|
-
]);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Display the table
|
|
66
|
-
console.log(table.toString());
|
|
67
|
-
console.log(chalk.green(`You have in total: ${chalk.cyan(result.length)} application(s).`));
|
|
68
|
-
} else {
|
|
69
|
-
console.error(chalk.red('Unable to list your apps. Please check your credentials.'));
|
|
70
|
-
}
|
|
71
|
-
} catch (error) {
|
|
72
|
-
console.error(chalk.red(`Failed to list apps. Error: ${error.message}`));
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Get app informations
|
|
78
|
-
*
|
|
79
|
-
* @param {Array} List of options (only "name" is supported at the moment)
|
|
80
|
-
* @example:
|
|
81
|
-
* ```json
|
|
82
|
-
* const data = await appInfo("app name");
|
|
83
|
-
* ```
|
|
84
|
-
*/
|
|
85
|
-
export async function appInfo(args = []) {
|
|
86
|
-
if (!args || args.length == 0){
|
|
87
|
-
console.log(chalk.red('Usage: app <name>'));
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
const appName = args[0].trim()
|
|
91
|
-
console.log(chalk.green(`Looking for "${chalk.dim(appName)}" app informations:\n`));
|
|
92
|
-
const puter = getPuter();
|
|
93
|
-
try {
|
|
94
|
-
const result = await puter.apps.get(appName);
|
|
95
|
-
if (result) {
|
|
96
|
-
// Display the informations
|
|
97
|
-
displayNonNullValues(result);
|
|
98
|
-
} else {
|
|
99
|
-
console.error(chalk.red('Could not find this app.'));
|
|
100
|
-
}
|
|
101
|
-
} catch (error) {
|
|
102
|
-
console.error(chalk.red(`Failed to get app info. Error: ${error.message}`));
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Create a new web application
|
|
108
|
-
* @param {string} name The name of the App
|
|
109
|
-
* @param {string} directory Optional directory path
|
|
110
|
-
* @param {string} description A description of the App
|
|
111
|
-
* @param {string} url A default coming-soon URL
|
|
112
|
-
* @returns {Promise<Object>} Output JSON data
|
|
113
|
-
*/
|
|
114
|
-
export async function createApp(args) {
|
|
115
|
-
const name = args.name; // App name (required)
|
|
116
|
-
if (!name || !isValidAppName(name)) {
|
|
117
|
-
console.log(chalk.red('Usage: app:create <name> <directory>'));
|
|
118
|
-
console.log(chalk.yellow('Example: app:create myApp .'));
|
|
119
|
-
console.log(chalk.yellow('Example: app:create myApp ./myApp'));
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
// Use the default home page if the root directory if none specified
|
|
123
|
-
const localDir = args.directory ? resolvePath(getCurrentDirectory(), args.directory) : '';
|
|
124
|
-
// Optional description
|
|
125
|
-
const description = args.description || '';
|
|
126
|
-
const url = args.url || '';
|
|
127
|
-
|
|
128
|
-
console.log(chalk.green(`Creating app "${name}"...`));
|
|
129
|
-
console.log(chalk.dim(`Directory: ${localDir || '[default]'}`));
|
|
130
|
-
console.log(chalk.dim(`Description: ${description}`));
|
|
131
|
-
console.log(chalk.dim(`URL: ${url}`));
|
|
132
|
-
|
|
133
|
-
const puter = getPuter();
|
|
134
|
-
try {
|
|
135
|
-
// Step 1: Create the app
|
|
136
|
-
const createAppData = await puter.apps.create({
|
|
137
|
-
name: name,
|
|
138
|
-
indexURL: url,
|
|
139
|
-
title: name,
|
|
140
|
-
description: description,
|
|
141
|
-
maximizeOnStart: false,
|
|
142
|
-
dedupeName: true
|
|
143
|
-
});
|
|
144
|
-
if (!createAppData) {
|
|
145
|
-
console.error(chalk.red(`Failed to create app "${name}"`));
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
const appUid = createAppData.uid;
|
|
149
|
-
const appName = createAppData.name;
|
|
150
|
-
const username = createAppData.owner.username;
|
|
151
|
-
console.log(chalk.green(`App "${chalk.dim(name)}" created successfully!`));
|
|
152
|
-
console.log(chalk.cyan(`AppName: ${chalk.dim(appName)}\nUID: ${chalk.dim(appUid)}\nUsername: ${chalk.dim(username)}`));
|
|
153
|
-
|
|
154
|
-
// Step 2: Create a directory for the app
|
|
155
|
-
const uid = crypto.randomUUID();
|
|
156
|
-
const appDir = `/${username}/AppData/${appUid}`;
|
|
157
|
-
console.log(chalk.green(`Creating directory...\nPath: ${chalk.dim(appDir)}\nApp: ${chalk.dim(name)}\nUID: ${chalk.dim(uid)}\n`));
|
|
158
|
-
const createDirData = await puter.fs.mkdir(`${appDir}/app-${uid}`, {
|
|
159
|
-
overwrite: true,
|
|
160
|
-
dedupeName: false,
|
|
161
|
-
createMissingParents: true,
|
|
162
|
-
})
|
|
163
|
-
if (!createDirData || !createDirData.uid) {
|
|
164
|
-
console.error(chalk.red(`Failed to create directory for app "${name}"`));
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
const dirUid = createDirData.uid;
|
|
168
|
-
console.log(chalk.green(`Directory created successfully!`));
|
|
169
|
-
console.log(chalk.cyan(`Directory UID: ${chalk.dim(dirUid)}`));
|
|
170
|
-
|
|
171
|
-
// Step 3: Create a subdomain for the app
|
|
172
|
-
const subdomainName = `${name}-${uid.split('-')[0]}`;
|
|
173
|
-
const remoteDir = `${appDir}/${createDirData.name}`;
|
|
174
|
-
console.log(chalk.green(`Linking to subdomain...\nSubdomain: "${chalk.dim(subdomainName)}"\nPath: ${chalk.dim(remoteDir)}\n`));
|
|
175
|
-
const subdomainResult = await createSubdomain(subdomainName, remoteDir);
|
|
176
|
-
if (!subdomainResult) {
|
|
177
|
-
console.error(chalk.red(`Failed to create subdomain: "${subdomainName}"`));
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
console.log(chalk.green(`Subdomain created successfully!`));
|
|
181
|
-
console.log(chalk.cyan(`Subdomain: ${chalk.dim(subdomainName)}`));
|
|
182
|
-
|
|
183
|
-
// Step 4: Create a home page
|
|
184
|
-
if (localDir.length > 0){
|
|
185
|
-
// List files in the current "localDir" then copy them to the "remoteDir"
|
|
186
|
-
const files = await listRemoteFiles(localDir);
|
|
187
|
-
if (Array.isArray(files) && files.length > 0) {
|
|
188
|
-
console.log(chalk.cyan(`Copying ${chalk.dim(files.length)} files from: ${chalk.dim(localDir)}`));
|
|
189
|
-
console.log(chalk.cyan(`To destination: ${chalk.dim(remoteDir)}`));
|
|
190
|
-
for (const file of files) {
|
|
191
|
-
const fileSource = path.join(localDir, file.name);
|
|
192
|
-
await copyFile([fileSource, remoteDir]);
|
|
193
|
-
}
|
|
194
|
-
} else {
|
|
195
|
-
console.log(chalk.yellow("We could not find any file in the specified directory!"));
|
|
196
|
-
}
|
|
197
|
-
} else {
|
|
198
|
-
const homePageResult = await createFile([path.join(remoteDir, 'index.html'), getDefaultHomePage(appName)]);
|
|
199
|
-
if (!homePageResult){
|
|
200
|
-
console.log(chalk.yellow("We could not create the home page file!"));
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// Step 5: Update the app's index_url to point to the subdomain
|
|
205
|
-
console.log(chalk.green(`Set "${chalk.dim(subdomainName)}" as a subdomain for app: "${chalk.dim(appName)}"...\n`));
|
|
206
|
-
const updateAppData = await puter.apps.update(appName, {
|
|
207
|
-
indexURL: `https://${subdomainName}.puter.site`,
|
|
208
|
-
title: name
|
|
209
|
-
})
|
|
210
|
-
if (!updateAppData) {
|
|
211
|
-
console.error(chalk.red(`Failed to update app "${name}" with new subdomain`));
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
console.log(chalk.green(`App deployed successfully at:`));
|
|
215
|
-
console.log(chalk.cyanBright(`https://${subdomainName}.puter.site`));
|
|
216
|
-
} catch (error) {
|
|
217
|
-
console.error(chalk.red(`Failed to create app "${name}".\nError: ${error.message}`));
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Update an application from the directory
|
|
223
|
-
* @param {string} name The name of the App
|
|
224
|
-
* @param {string} remote_dir The remote directory
|
|
225
|
-
*/
|
|
226
|
-
export async function updateApp(args = []) {
|
|
227
|
-
if (args.length < 1) {
|
|
228
|
-
console.log(chalk.red('Usage: app:update <valid_name_app> [<remote_dir>]'));
|
|
229
|
-
console.log(chalk.yellow('Example: app:create myapp'));
|
|
230
|
-
console.log(chalk.yellow('Example: app:create myapp ./myapp'));
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
const name = args[0]; // App name (required)
|
|
234
|
-
// Fix: Properly handle absolute paths by checking if the path starts with '/'
|
|
235
|
-
let remoteDir;
|
|
236
|
-
if (args[1] && args[1].startsWith('/')) {
|
|
237
|
-
remoteDir = args[1]; // Use the absolute path as-is
|
|
238
|
-
} else {
|
|
239
|
-
remoteDir = resolvePath(getCurrentDirectory(), args[1] || '.');
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
const remoteDirExists = await pathExists(remoteDir);
|
|
243
|
-
|
|
244
|
-
if (!remoteDirExists){
|
|
245
|
-
console.log(chalk.red(`Cannot find directory: ${chalk.dim(remoteDir)}...\n`));
|
|
246
|
-
return;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
const puter = getPuter();
|
|
250
|
-
console.log(chalk.green(`Updating app: "${chalk.dim(name)}" from directory: ${chalk.dim(remoteDir)}\n`));
|
|
251
|
-
try {
|
|
252
|
-
// Step 1: Get the app info
|
|
253
|
-
const data = await puter.apps.get(name);
|
|
254
|
-
if (!data) {
|
|
255
|
-
console.error(chalk.red(`Failed to find app: "${name}"`));
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
258
|
-
const appUid = data.uid;
|
|
259
|
-
const appName = data.name;
|
|
260
|
-
const username = data.owner.username;
|
|
261
|
-
const indexUrl = data.index_url;
|
|
262
|
-
const appDir = `/${username}/AppData/${appUid}`;
|
|
263
|
-
console.log(chalk.cyan(`AppName: ${chalk.dim(appName)}\nUID: ${chalk.dim(appUid)}\nUsername: ${chalk.dim(username)}`));
|
|
264
|
-
|
|
265
|
-
// Step 2: Find the path from subdomain
|
|
266
|
-
const subdomains = await getSubdomains();
|
|
267
|
-
const appSubdomain = subdomains.find(sd => sd.root_dir?.dirname?.endsWith(appUid));
|
|
268
|
-
if (!appSubdomain){
|
|
269
|
-
console.error(chalk.red(`Sorry! We could not find the subdomain for ${chalk.cyan(name)} application.`));
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
const subdomainDir = appSubdomain['root_dir']['path'];
|
|
273
|
-
if (!subdomainDir){
|
|
274
|
-
console.error(chalk.red(`Sorry! We could not find the path for ${chalk.cyan(name)} application.`));
|
|
275
|
-
return;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
// Step 3: List files in the current "remoteDir" then copy them to the "subdomainDir"
|
|
279
|
-
const files = await listRemoteFiles(remoteDir);
|
|
280
|
-
if (Array.isArray(files) && files.length > 0) {
|
|
281
|
-
console.log(chalk.cyan(`Copying ${chalk.dim(files.length)} files from: ${chalk.dim(remoteDir)}`));
|
|
282
|
-
console.log(chalk.cyan(`To destination: ${chalk.dim(subdomainDir)}`));
|
|
283
|
-
for (const file of files) {
|
|
284
|
-
const fileSource = path.join(remoteDir, file.name);
|
|
285
|
-
const fileDest = path.join(subdomainDir, file.name);
|
|
286
|
-
if ((await pathExists(fileDest))){
|
|
287
|
-
await removeFileOrDirectory([fileDest, '-f']);
|
|
288
|
-
}
|
|
289
|
-
await copyFile([fileSource, subdomainDir]);
|
|
290
|
-
}
|
|
291
|
-
} else {
|
|
292
|
-
console.log(chalk.red("We could not find any file in the specified directory!"));
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
console.log(chalk.green(`App updated successfully at:`));
|
|
296
|
-
console.log(chalk.dim(indexUrl));
|
|
297
|
-
} catch (error) {
|
|
298
|
-
console.error(chalk.red(`Failed to update app "${name}".\nError: ${error.message}`));
|
|
299
|
-
console.error(error);
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
* Delete an app by its name
|
|
305
|
-
* @param {string} name The name of the app to delete
|
|
306
|
-
* @returns a boolean success value
|
|
307
|
-
*/
|
|
308
|
-
export async function deleteApp(name) {
|
|
309
|
-
if (!name || name.length == 0){
|
|
310
|
-
console.log(chalk.red('Usage: app:delete <name>'));
|
|
311
|
-
return false;
|
|
312
|
-
}
|
|
313
|
-
const puter = getPuter();
|
|
314
|
-
console.log(chalk.green(`Checking app "${name}"...\n`));
|
|
315
|
-
try {
|
|
316
|
-
// Step 1: Read app details
|
|
317
|
-
const readData = await puter.apps.get(name);
|
|
318
|
-
|
|
319
|
-
if (!readData) {
|
|
320
|
-
console.log(chalk.red(`App "${chalk.bold(name)}" not found.`));
|
|
321
|
-
return false;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
// Show app details and confirm deletion
|
|
325
|
-
console.log(chalk.cyan('\nApp Details:'));
|
|
326
|
-
console.log(chalk.dim('----------------------------------------'));
|
|
327
|
-
console.log(chalk.dim(`Name: ${chalk.cyan(readData.name)}`));
|
|
328
|
-
console.log(chalk.dim(`Title: ${chalk.cyan(readData.title)}`));
|
|
329
|
-
console.log(chalk.dim(`Created: ${chalk.cyan(formatDate(readData.created_at))}`));
|
|
330
|
-
console.log(chalk.dim(`URL: ${readData.index_url}`));
|
|
331
|
-
console.log(chalk.dim('----------------------------------------'));
|
|
332
|
-
|
|
333
|
-
// Step 2: Delete the app
|
|
334
|
-
console.log(chalk.green(`Deleting app "${chalk.red(name)}"...`));
|
|
335
|
-
|
|
336
|
-
const deleteData = await puter.apps.delete(name);
|
|
337
|
-
if (!deleteData) {
|
|
338
|
-
console.error(chalk.red(`Failed to delete app "${name}".\nP.S. Make sure to provide the 'name' attribute not the 'title'.`));
|
|
339
|
-
return false;
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
// Lookup subdomainUID then delete it
|
|
343
|
-
const subdomains = await getSubdomains();
|
|
344
|
-
const appSubdomain = subdomains.find(sd => sd.root_dir?.dirname?.endsWith(readData.uid));
|
|
345
|
-
const subdomainDeleted = await deleteSite([appSubdomain.uid]);
|
|
346
|
-
if (subdomainDeleted){
|
|
347
|
-
console.log(chalk.green(`Subdomain: ${chalk.dim(appSubdomain.uid)} deleted.`));
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
console.log(chalk.green(`App "${chalk.dim(name)}" deleted successfully!`));
|
|
351
|
-
} catch (error) {
|
|
352
|
-
console.error(chalk.red(`Failed to delete app "${name}".\nError: ${error.message}`));
|
|
353
|
-
return false;
|
|
354
|
-
}
|
|
355
|
-
return true;
|
|
356
|
-
}
|
package/src/commands/deploy.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import { generateAppName } from '../commons.js';
|
|
3
|
-
import { syncDirectory } from './files.js';
|
|
4
|
-
import { createSite } from './sites.js';
|
|
5
|
-
import { getPuter } from '../modules/PuterModule.js';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Deploy a local web project to Puter.
|
|
9
|
-
* @param {string[]} args - Command-line arguments (e.g., <local_dir> [--subdomain=<subdomain>]).
|
|
10
|
-
*/
|
|
11
|
-
export async function deploy(args = []) {
|
|
12
|
-
if (args.length < 1) {
|
|
13
|
-
console.log(chalk.red('Usage: site:deploy <local_dir> [--subdomain=<subdomain>]'));
|
|
14
|
-
console.log(chalk.yellow('Example: site:deploy .'));
|
|
15
|
-
console.log(chalk.yellow('Example: site:deploy ./dist'));
|
|
16
|
-
console.log(chalk.yellow('Example: site:deploy ./dist --subdomain=my-app-new'));
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
const puter = getPuter();
|
|
20
|
-
|
|
21
|
-
const sourceDirArg = args.find(arg => !arg.startsWith('--'));
|
|
22
|
-
const sourceDir = sourceDirArg || '.';
|
|
23
|
-
|
|
24
|
-
let subdomain = args.find(arg => arg.startsWith('--subdomain='))?.split('=')[1];
|
|
25
|
-
if (!subdomain) {
|
|
26
|
-
subdomain = generateAppName();
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const remoteDir = `~/sites/${subdomain}/deployment`;
|
|
30
|
-
|
|
31
|
-
// this will handle the increments
|
|
32
|
-
const directory = await puter.fs.mkdir(remoteDir, {
|
|
33
|
-
dedupeName: true,
|
|
34
|
-
createMissingParents: true
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
console.log(chalk.cyan(`Deploying '${sourceDir}' to '${subdomain}.puter.site'...`));
|
|
38
|
-
|
|
39
|
-
try {
|
|
40
|
-
// 1. Upload files
|
|
41
|
-
await syncDirectory([sourceDir, directory.path, '--delete', '-r', '--overwrite']);
|
|
42
|
-
|
|
43
|
-
// 2. Create the site
|
|
44
|
-
const site = await createSite([subdomain, directory.path, `--subdomain=${subdomain}`]);
|
|
45
|
-
|
|
46
|
-
if (site) {
|
|
47
|
-
console.log(chalk.green('Deployment successful!'));
|
|
48
|
-
} else {
|
|
49
|
-
console.log(chalk.yellow('Deployment successfuly updated!'));
|
|
50
|
-
}
|
|
51
|
-
} catch (error) {
|
|
52
|
-
console.error(chalk.red(`Deployment failed: ${error.message}`));
|
|
53
|
-
}
|
|
54
|
-
}
|