@by-association-only/theme-backup 1.0.0 → 1.0.1
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-publish.yml +20 -0
- package/README.md +3 -15
- package/index.js +76 -2
- package/package.json +1 -1
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: Publish package to npm
|
|
2
|
+
on:
|
|
3
|
+
release:
|
|
4
|
+
types: [published]
|
|
5
|
+
jobs:
|
|
6
|
+
build:
|
|
7
|
+
runs-on: ubuntu-latest
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
id-token: write
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
- uses: actions/setup-node@v4
|
|
14
|
+
with:
|
|
15
|
+
node-version: '20.x'
|
|
16
|
+
registry-url: 'https://registry.npmjs.org'
|
|
17
|
+
- run: npm ci
|
|
18
|
+
- run: npm publish --access public
|
|
19
|
+
env:
|
|
20
|
+
NODE_AUTH_TOKEN: ${{ secrets.npm_token }}
|
package/README.md
CHANGED
|
@@ -16,19 +16,7 @@ This tool helps you create backups of Shopify themes across multiple stores in y
|
|
|
16
16
|
|
|
17
17
|
## Setup
|
|
18
18
|
|
|
19
|
-
1)
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
npm i @by-association-only/theme-backup --save-dev
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
or
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
yarn add @by-association-only/theme-backup --save-dev
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
2) Add a config file in the root: `.bao-stores` (or use existing `.bao-translation-checker`)
|
|
19
|
+
1) Add a config file in the root: `.bao-stores` (or use existing `.bao-translation-checker`)
|
|
32
20
|
|
|
33
21
|
List each store name on a separate line (the part before .myshopify.com).
|
|
34
22
|
|
|
@@ -43,10 +31,10 @@ acmestore
|
|
|
43
31
|
acmestore-us
|
|
44
32
|
```
|
|
45
33
|
|
|
46
|
-
|
|
34
|
+
2) Run the backup tool:
|
|
47
35
|
|
|
48
36
|
```bash
|
|
49
|
-
|
|
37
|
+
npx @by-association-only/theme-backup
|
|
50
38
|
```
|
|
51
39
|
|
|
52
40
|
## Usage
|
package/index.js
CHANGED
|
@@ -410,7 +410,16 @@ async function deleteThemes(store, themes) {
|
|
|
410
410
|
async function backupTheme(store, theme) {
|
|
411
411
|
const date = new Date()
|
|
412
412
|
const today = `${String(date.getDate()).padStart(2, '0')}/${String(date.getMonth() + 1).padStart(2, '0')}/${date.getFullYear()}` // DD/MM/YYYY
|
|
413
|
-
|
|
413
|
+
let backupName = `${theme.name} (Backup ${today})`
|
|
414
|
+
|
|
415
|
+
// Check if name exceeds Shopify's 50 character limit
|
|
416
|
+
if (backupName.length > 50) {
|
|
417
|
+
console.log(chalk.yellow(`\n⚠ Generated backup name is too long (${backupName.length} characters)`))
|
|
418
|
+
console.log(chalk.gray(` Original: "${backupName}"`))
|
|
419
|
+
console.log(chalk.yellow('\nPlease enter a custom name for this backup:'))
|
|
420
|
+
backupName = await promptTextInput('Enter custom backup name', 50)
|
|
421
|
+
}
|
|
422
|
+
|
|
414
423
|
const tempPath = path.join(process.cwd(), '.temp-backup')
|
|
415
424
|
|
|
416
425
|
try {
|
|
@@ -446,6 +455,64 @@ async function backupTheme(store, theme) {
|
|
|
446
455
|
}
|
|
447
456
|
}
|
|
448
457
|
|
|
458
|
+
// Function to prompt user for text input
|
|
459
|
+
async function promptTextInput(message, maxLength = 50) {
|
|
460
|
+
process.stdin.setRawMode(true)
|
|
461
|
+
process.stdin.resume()
|
|
462
|
+
|
|
463
|
+
let input = ''
|
|
464
|
+
|
|
465
|
+
const updateDisplay = () => {
|
|
466
|
+
process.stdout.write('\x1B[2J\x1B[H') // Clear screen
|
|
467
|
+
console.log(chalk.yellow(`\n${message}`))
|
|
468
|
+
console.log(chalk.gray(`(Max ${maxLength} characters)`))
|
|
469
|
+
console.log(chalk.cyan(`\n> ${input}`))
|
|
470
|
+
if (input.length > maxLength) {
|
|
471
|
+
console.log(chalk.red(`\n⚠ Name is too long (${input.length}/${maxLength} characters)`))
|
|
472
|
+
}
|
|
473
|
+
console.log(chalk.gray('\nPress Enter to confirm, Ctrl+C to cancel'))
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
updateDisplay()
|
|
477
|
+
|
|
478
|
+
return new Promise((resolve) => {
|
|
479
|
+
const handleKey = (key) => {
|
|
480
|
+
if (key === '\x03') { // Ctrl+C
|
|
481
|
+
process.stdin.setRawMode(false)
|
|
482
|
+
process.stdin.pause()
|
|
483
|
+
console.log(chalk.yellow('\nCancelled...'))
|
|
484
|
+
process.exit(0)
|
|
485
|
+
return
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
if (key === '\r') { // Enter
|
|
489
|
+
if (input.length === 0) {
|
|
490
|
+
updateDisplay()
|
|
491
|
+
return
|
|
492
|
+
}
|
|
493
|
+
if (input.length > maxLength) {
|
|
494
|
+
updateDisplay()
|
|
495
|
+
return
|
|
496
|
+
}
|
|
497
|
+
process.stdin.setRawMode(false)
|
|
498
|
+
process.stdin.pause()
|
|
499
|
+
resolve(input.trim())
|
|
500
|
+
return
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
if (key === '\x7F') { // Backspace
|
|
504
|
+
input = input.slice(0, -1)
|
|
505
|
+
} else if (key.length === 1 && key >= ' ' && key <= '~') { // Printable characters
|
|
506
|
+
input += key
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
updateDisplay()
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
process.stdin.on('data', handleKey)
|
|
513
|
+
})
|
|
514
|
+
}
|
|
515
|
+
|
|
449
516
|
// Function to prompt user for yes/no
|
|
450
517
|
async function promptYesNo(message) {
|
|
451
518
|
process.stdin.setRawMode(true)
|
|
@@ -517,7 +584,14 @@ async function runBackup() {
|
|
|
517
584
|
console.log(chalk.green('✓ Authentication verified\n'))
|
|
518
585
|
}
|
|
519
586
|
|
|
520
|
-
for (
|
|
587
|
+
for (let i = 0; i < stores.length; i++) {
|
|
588
|
+
const store = stores[i]
|
|
589
|
+
|
|
590
|
+
// Clear screen before processing each store (except the first)
|
|
591
|
+
if (i > 0) {
|
|
592
|
+
process.stdout.write('\x1B[2J\x1B[H')
|
|
593
|
+
}
|
|
594
|
+
|
|
521
595
|
console.log(chalk.bold(`\nProcessing ${store}:`))
|
|
522
596
|
|
|
523
597
|
// Get all themes
|