tiendu 0.6.1 → 0.8.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/README.md +116 -41
- package/bin/tiendu.js +134 -57
- package/lib/api.mjs +18 -16
- package/lib/archive.mjs +2 -1
- package/lib/build.mjs +259 -135
- package/lib/config.mjs +68 -12
- package/lib/dev.mjs +30 -32
- package/lib/init.mjs +116 -106
- package/lib/preview.mjs +63 -42
- package/lib/publish.mjs +15 -17
- package/lib/pull.mjs +9 -6
- package/lib/push.mjs +19 -15
- package/lib/stores.mjs +91 -0
- package/lib/ui.mjs +138 -0
- package/lib/update-check.mjs +8 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -24,16 +24,18 @@ npm install -g tiendu
|
|
|
24
24
|
|
|
25
25
|
## Quick start
|
|
26
26
|
|
|
27
|
-
###
|
|
27
|
+
### Simple theme
|
|
28
28
|
|
|
29
29
|
```bash
|
|
30
30
|
mkdir my-theme && cd my-theme
|
|
31
31
|
tiendu init
|
|
32
|
+
tiendu stores list
|
|
33
|
+
tiendu stores set <store-id>
|
|
32
34
|
tiendu pull
|
|
33
35
|
tiendu dev
|
|
34
36
|
```
|
|
35
37
|
|
|
36
|
-
###
|
|
38
|
+
### Pipeline-enabled theme
|
|
37
39
|
|
|
38
40
|
Clone the default theme template, connect to your store, and start developing:
|
|
39
41
|
|
|
@@ -41,10 +43,22 @@ Clone the default theme template, connect to your store, and start developing:
|
|
|
41
43
|
git clone <default-theme-repo> my-theme && cd my-theme
|
|
42
44
|
npm install
|
|
43
45
|
tiendu init
|
|
46
|
+
tiendu stores list
|
|
47
|
+
tiendu stores set <store-id>
|
|
44
48
|
tiendu dev
|
|
45
49
|
```
|
|
46
50
|
|
|
47
|
-
|
|
51
|
+
### Agent-friendly setup
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
tiendu init <api-key> [base-url] --non-interactive
|
|
55
|
+
tiendu stores list --non-interactive
|
|
56
|
+
tiendu stores set <store-id> --non-interactive
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
When `--non-interactive` is passed, the CLI avoids prompts and prints plain text output.
|
|
60
|
+
|
|
61
|
+
`tiendu dev` creates a remote preview, builds or stages your theme into `dist/`, runs an initial push from that prepared output, and then watches for changes. It prints a local live-preview URL first, plus a sharable preview URL like:
|
|
48
62
|
|
|
49
63
|
```
|
|
50
64
|
http://preview-xxxxxxxxxxxx.tiendu.uy/
|
|
@@ -59,24 +73,54 @@ It also starts a local live-preview URL that proxies the preview and auto-reload
|
|
|
59
73
|
|
|
60
74
|
## Commands
|
|
61
75
|
|
|
62
|
-
### `tiendu init`
|
|
76
|
+
### `tiendu init [apiKey] [baseUrl]`
|
|
77
|
+
|
|
78
|
+
Initializes a theme project in the current directory.
|
|
63
79
|
|
|
64
|
-
|
|
80
|
+
- With no arguments, it runs the interactive setup wizard.
|
|
81
|
+
- With `apiKey` and optional `baseUrl`, it reinitializes the saved config without prompts.
|
|
82
|
+
- If only one store is available, it is selected automatically.
|
|
83
|
+
- If multiple stores are available, leave the store unset and use `tiendu stores list` plus `tiendu stores set <id>`.
|
|
65
84
|
|
|
66
85
|
```bash
|
|
67
86
|
tiendu init
|
|
87
|
+
tiendu init <api-key>
|
|
88
|
+
tiendu init <api-key> https://tiendu.uy --non-interactive
|
|
68
89
|
```
|
|
69
90
|
|
|
70
91
|
> Add `.cli/` to your `.gitignore` if you version-control your theme — it contains your API key.
|
|
71
92
|
|
|
72
93
|
---
|
|
73
94
|
|
|
95
|
+
### `tiendu stores list`
|
|
96
|
+
|
|
97
|
+
Lists all stores available for the configured API key and highlights the active one when present.
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
tiendu stores list
|
|
101
|
+
tiendu stores list --non-interactive
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
### `tiendu stores set <storeId>`
|
|
107
|
+
|
|
108
|
+
Validates the store against the configured API key and saves it as the active store.
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
tiendu stores set 123
|
|
112
|
+
tiendu stores set 123 --non-interactive
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
74
117
|
### `tiendu pull`
|
|
75
118
|
|
|
76
|
-
Downloads the current live theme from your store
|
|
119
|
+
Downloads the current live theme from your store into `dist/`.
|
|
77
120
|
|
|
78
|
-
-
|
|
79
|
-
-
|
|
121
|
+
- `pull` clears `dist/` first.
|
|
122
|
+
- The downloaded archive is then extracted into `dist/`.
|
|
123
|
+
- Your source files, including `src/`, are left untouched.
|
|
80
124
|
|
|
81
125
|
```bash
|
|
82
126
|
tiendu pull
|
|
@@ -86,19 +130,26 @@ tiendu pull
|
|
|
86
130
|
|
|
87
131
|
### `tiendu build`
|
|
88
132
|
|
|
89
|
-
Builds
|
|
133
|
+
Builds or stages the current theme into its deployable output directory (`dist/`).
|
|
134
|
+
|
|
135
|
+
- Theme files and assets are always prepared into `dist/`.
|
|
136
|
+
- Optional pipeline steps are enabled through `tiendu.config.json`.
|
|
137
|
+
- With no config file, or with no enabled pipeline steps, `build` just stages the theme files into `dist/`.
|
|
90
138
|
|
|
91
139
|
```bash
|
|
92
140
|
tiendu build
|
|
141
|
+
tiendu build --skip-instances
|
|
93
142
|
```
|
|
94
143
|
|
|
144
|
+
- Use `--skip-instances` to omit template JSON, section group JSON, and `config/settings_data.json` from `dist/`. This is useful when you want to preserve the existing page/section instances on the preview.
|
|
145
|
+
|
|
95
146
|
The build:
|
|
96
147
|
|
|
97
|
-
1. Copies theme files from `src/layout/`, `src/templates/`, and `src/
|
|
148
|
+
1. Copies theme files from `src/layout/`, `src/templates/`, `src/sections/`, `src/blocks/`, `src/snippets/`, and `src/config/` to `dist/`
|
|
98
149
|
2. Flattens static files from `src/assets/` into `dist/assets/`
|
|
99
|
-
3.
|
|
100
|
-
4.
|
|
101
|
-
5.
|
|
150
|
+
3. Optionally discovers script and style entry points in `src/layout/` and `src/templates/`
|
|
151
|
+
4. Optionally compiles JS/TS and CSS into `dist/assets/`
|
|
152
|
+
5. Optionally runs project PostCSS plugins for compiled CSS entries
|
|
102
153
|
|
|
103
154
|
For TypeScript source, extensionless relative imports such as `import { initHeaderCart } from '../lib/scripts/cart'` are supported and recommended.
|
|
104
155
|
|
|
@@ -114,13 +165,15 @@ Entry naming convention:
|
|
|
114
165
|
|
|
115
166
|
The main development command.
|
|
116
167
|
|
|
117
|
-
-
|
|
118
|
-
-
|
|
168
|
+
- Runs `tiendu build` in watch mode first.
|
|
169
|
+
- Watches `dist/` and syncs changes to the preview.
|
|
119
170
|
|
|
120
171
|
```bash
|
|
121
172
|
tiendu dev
|
|
173
|
+
tiendu dev --skip-instances
|
|
122
174
|
```
|
|
123
175
|
|
|
176
|
+
- Use `--skip-instances` to sync everything except template JSON, section group JSON, and `config/settings_data.json`. Existing instances on the preview are preserved.
|
|
124
177
|
- Prints the preview URL on start
|
|
125
178
|
- Re-syncs the full local theme to the preview on startup
|
|
126
179
|
- Syncs file creates, edits and deletes
|
|
@@ -133,17 +186,19 @@ tiendu dev
|
|
|
133
186
|
|
|
134
187
|
### `tiendu push`
|
|
135
188
|
|
|
136
|
-
Zips and uploads
|
|
189
|
+
Zips and uploads `dist/` to the active preview, replacing its content entirely.
|
|
137
190
|
|
|
138
|
-
-
|
|
139
|
-
-
|
|
191
|
+
- By default it runs `tiendu build` first.
|
|
192
|
+
- Use `--skip-build` to upload the existing `dist/` artifact without rebuilding.
|
|
140
193
|
|
|
141
194
|
```bash
|
|
142
195
|
tiendu push
|
|
143
196
|
tiendu push --skip-build
|
|
197
|
+
tiendu push --skip-build --non-interactive
|
|
198
|
+
tiendu push --skip-instances
|
|
144
199
|
```
|
|
145
200
|
|
|
146
|
-
Use `--skip-
|
|
201
|
+
- Use `--skip-instances` to upload everything except template JSON, section group JSON, and `config/settings_data.json`. Existing instances on the preview are preserved.
|
|
147
202
|
|
|
148
203
|
---
|
|
149
204
|
|
|
@@ -151,15 +206,19 @@ Use `--skip-build` to upload the existing `dist/` output without rebuilding.
|
|
|
151
206
|
|
|
152
207
|
Publishes the active preview to the live storefront. Visitors will see the new theme immediately. All previews for the store are removed after publishing.
|
|
153
208
|
|
|
154
|
-
-
|
|
155
|
-
-
|
|
209
|
+
- By default it runs `tiendu build`, uploads `dist/` to the preview, and then publishes it.
|
|
210
|
+
- Use `--skip-build` to publish after syncing the existing `dist/` output.
|
|
156
211
|
|
|
157
212
|
```bash
|
|
158
213
|
tiendu publish
|
|
159
214
|
tiendu publish --skip-build
|
|
215
|
+
tiendu publish --skip-build --non-interactive
|
|
216
|
+
tiendu publish --skip-instances
|
|
160
217
|
```
|
|
161
218
|
|
|
162
|
-
Use `--skip-
|
|
219
|
+
- Use `--skip-instances` to publish everything except template JSON, section group JSON, and `config/settings_data.json`. Existing instances on the preview are preserved.
|
|
220
|
+
|
|
221
|
+
In non-interactive mode, the publish confirmation is skipped.
|
|
163
222
|
|
|
164
223
|
---
|
|
165
224
|
|
|
@@ -211,6 +270,7 @@ Deletes the active preview (both remotely and from your local config).
|
|
|
211
270
|
|
|
212
271
|
```bash
|
|
213
272
|
tiendu preview delete
|
|
273
|
+
tiendu preview delete --non-interactive
|
|
214
274
|
```
|
|
215
275
|
|
|
216
276
|
---
|
|
@@ -227,23 +287,27 @@ tiendu preview open
|
|
|
227
287
|
|
|
228
288
|
## Typical workflow
|
|
229
289
|
|
|
230
|
-
###
|
|
290
|
+
### Standard
|
|
231
291
|
|
|
232
292
|
```
|
|
233
|
-
tiendu init # one time: connect to your
|
|
234
|
-
tiendu
|
|
293
|
+
tiendu init # one time: connect to your Tiendu account
|
|
294
|
+
tiendu stores list # one time: see available stores
|
|
295
|
+
tiendu stores set # one time: select the store to work on
|
|
296
|
+
tiendu pull # one time: refresh dist/ from the live theme
|
|
235
297
|
|
|
236
|
-
tiendu dev # develop:
|
|
298
|
+
tiendu dev # develop: build/stage into dist/, sync preview updates live
|
|
237
299
|
|
|
238
300
|
tiendu publish # when ready: push to the live storefront
|
|
239
301
|
```
|
|
240
302
|
|
|
241
|
-
###
|
|
303
|
+
### Pipeline-enabled
|
|
242
304
|
|
|
243
305
|
```
|
|
244
306
|
git clone <template-repo> my-theme
|
|
245
307
|
cd my-theme && npm install
|
|
246
|
-
tiendu init # one time: connect to your
|
|
308
|
+
tiendu init # one time: connect to your Tiendu account
|
|
309
|
+
tiendu stores list # one time: see available stores
|
|
310
|
+
tiendu stores set # one time: select the store to work on
|
|
247
311
|
|
|
248
312
|
tiendu dev # develop: builds src/, watches dist/, syncs to preview
|
|
249
313
|
|
|
@@ -264,9 +328,13 @@ A **theme preview** is a remote copy of your theme hosted by Tiendu. It renders
|
|
|
264
328
|
|
|
265
329
|
---
|
|
266
330
|
|
|
267
|
-
##
|
|
331
|
+
## Pipeline-enabled themes
|
|
332
|
+
|
|
333
|
+
All themes are staged into `dist/` before upload.
|
|
268
334
|
|
|
269
|
-
|
|
335
|
+
`tiendu.config.json` can optionally enable extra pipeline steps such as script compilation, style compilation, and PostCSS processing.
|
|
336
|
+
|
|
337
|
+
When pipeline steps are enabled, a theme can use:
|
|
270
338
|
|
|
271
339
|
- npm packages via a local `package.json`
|
|
272
340
|
- TypeScript (`.ts`) for browser code
|
|
@@ -277,7 +345,7 @@ A **built theme** is a theme that uses `tiendu.config.json` to enable the build
|
|
|
277
345
|
|
|
278
346
|
```
|
|
279
347
|
my-theme/
|
|
280
|
-
├── tiendu.config.json #
|
|
348
|
+
├── tiendu.config.json # optional pipeline flags
|
|
281
349
|
├── package.json # npm dependencies
|
|
282
350
|
├── .gitignore
|
|
283
351
|
├── src/
|
|
@@ -293,21 +361,21 @@ my-theme/
|
|
|
293
361
|
│ ├── assets/ # source assets → flattened into dist/assets/
|
|
294
362
|
│ ├── lib/ # shared modules (bundled into entries, not served)
|
|
295
363
|
│ └── css/ # shared CSS (imported by entry CSS)
|
|
296
|
-
└── dist/ #
|
|
364
|
+
└── dist/ # staged upload artifact (gitignored, uploaded to Tiendu)
|
|
297
365
|
```
|
|
298
366
|
|
|
299
367
|
### How it works
|
|
300
368
|
|
|
301
|
-
1.
|
|
302
|
-
2.
|
|
303
|
-
3.
|
|
304
|
-
4.
|
|
369
|
+
1. Theme files and static assets are staged into `dist/`
|
|
370
|
+
2. Script entries are compiled only when `pipeline.compileScripts` is enabled
|
|
371
|
+
3. Style entries are compiled only when `pipeline.compileStyles` is enabled
|
|
372
|
+
4. PostCSS runs only when `pipeline.postcss` is enabled
|
|
305
373
|
5. `dist/` is what gets uploaded — it looks like a normal Tiendu theme
|
|
306
|
-
6. Liquid templates reference bundles and assets via `asset_url`
|
|
374
|
+
6. Liquid templates reference bundles and assets via `asset_url` when compiled entries are used
|
|
307
375
|
|
|
308
376
|
### Tailwind v4
|
|
309
377
|
|
|
310
|
-
|
|
378
|
+
Pipeline-enabled themes can use Tailwind v4 in CSS entry files when `pipeline.compileStyles` and `pipeline.postcss` are enabled.
|
|
311
379
|
|
|
312
380
|
Install it in your theme project:
|
|
313
381
|
|
|
@@ -338,15 +406,22 @@ export default {
|
|
|
338
406
|
|
|
339
407
|
### tiendu.config.json
|
|
340
408
|
|
|
341
|
-
|
|
409
|
+
Config is optional. When present, you can enable pipeline steps explicitly:
|
|
342
410
|
|
|
343
411
|
```json
|
|
344
412
|
{
|
|
345
|
-
"
|
|
346
|
-
|
|
413
|
+
"pipeline": {
|
|
414
|
+
"compileScripts": true,
|
|
415
|
+
"compileStyles": true,
|
|
416
|
+
"postcss": true
|
|
417
|
+
}
|
|
347
418
|
}
|
|
348
419
|
```
|
|
349
420
|
|
|
421
|
+
Without enabled pipeline steps, the CLI still stages the theme into `dist/`, but it skips compilation and PostCSS.
|
|
422
|
+
|
|
423
|
+
With no `tiendu.config.json`, the behavior is the same as having all pipeline steps disabled.
|
|
424
|
+
|
|
350
425
|
---
|
|
351
426
|
|
|
352
427
|
## License
|
package/bin/tiendu.js
CHANGED
|
@@ -15,80 +15,140 @@ import {
|
|
|
15
15
|
previewAttach,
|
|
16
16
|
previewDetach,
|
|
17
17
|
} from "../lib/preview.mjs";
|
|
18
|
+
import { storesList, storesSet } from "../lib/stores.mjs";
|
|
18
19
|
import {
|
|
19
20
|
checkForUpdates,
|
|
20
21
|
checkForUpdatesNow,
|
|
21
22
|
getCurrentVersion,
|
|
22
23
|
} from "../lib/update-check.mjs";
|
|
24
|
+
import { configureUi } from "../lib/ui.mjs";
|
|
23
25
|
|
|
24
26
|
const HELP = `
|
|
25
27
|
tiendu — Tiendu theme development CLI
|
|
26
28
|
|
|
27
29
|
Usage:
|
|
28
|
-
tiendu init [
|
|
29
|
-
|
|
30
|
-
tiendu
|
|
30
|
+
tiendu init [apiKey] [baseUrl] [--dir <path>]
|
|
31
|
+
Initialize interactively, or reset config with direct credentials
|
|
32
|
+
tiendu stores list List stores available for the configured API key
|
|
33
|
+
tiendu stores set <storeId> Select the active store
|
|
34
|
+
tiendu pull [previewKey] Download the live theme or a preview into dist/
|
|
35
|
+
tiendu build Build or stage the current theme into dist/
|
|
31
36
|
tiendu push [previewKey] [--skip-build]
|
|
32
|
-
|
|
33
|
-
tiendu dev
|
|
37
|
+
Upload dist/ to the attached or specified preview
|
|
38
|
+
tiendu dev Start dev mode: auto-sync changes to a live preview URL
|
|
34
39
|
tiendu publish [previewKey] [--skip-build]
|
|
35
|
-
|
|
40
|
+
Build/sync dist/ and publish the preview live
|
|
36
41
|
|
|
37
|
-
tiendu preview
|
|
42
|
+
tiendu preview Show the attached preview details
|
|
38
43
|
tiendu preview create [name]
|
|
39
|
-
|
|
40
|
-
tiendu preview list
|
|
41
|
-
tiendu preview attach [key]
|
|
42
|
-
|
|
43
|
-
tiendu preview
|
|
44
|
-
tiendu preview
|
|
45
|
-
Delete a preview (defaults to the attached one)
|
|
46
|
-
tiendu preview open Open the attached preview URL in your browser
|
|
44
|
+
Create a new preview (and attach to it)
|
|
45
|
+
tiendu preview list List all previews for your store
|
|
46
|
+
tiendu preview attach [key] Attach to an existing preview by its key
|
|
47
|
+
tiendu preview detach Detach from the current preview (without deleting it)
|
|
48
|
+
tiendu preview delete [key] Delete a preview (defaults to the attached one)
|
|
49
|
+
tiendu preview open Open the attached preview URL in your browser
|
|
47
50
|
|
|
48
|
-
tiendu check-updates
|
|
49
|
-
tiendu version
|
|
51
|
+
tiendu check-updates Check npm for a newer CLI version
|
|
52
|
+
tiendu version Show the current CLI version
|
|
50
53
|
|
|
51
|
-
|
|
52
|
-
|
|
54
|
+
Global options:
|
|
55
|
+
--non-interactive Disable prompts, print plain text output, and skip confirmations
|
|
56
|
+
--dir <path> Create the project inside a new directory during init
|
|
57
|
+
--skip-build Reuse the existing dist/ output for push or publish
|
|
58
|
+
--skip-instances Skip template/section group JSON and settings_data.json (preserves existing instances on the preview)
|
|
59
|
+
--help, -h Show this help message
|
|
60
|
+
--version, -v Show the current CLI version
|
|
61
|
+
|
|
62
|
+
Init behavior:
|
|
63
|
+
tiendu init Interactive setup wizard
|
|
64
|
+
tiendu init <apiKey> Reset saved config and connect using the default base URL
|
|
65
|
+
tiendu init <apiKey> <url> Reset saved config and connect using a custom base URL
|
|
66
|
+
The default base URL points to the Tiendu platform and rarely needs to change.
|
|
67
|
+
If exactly one store is available, it is selected automatically.
|
|
68
|
+
If multiple stores are available, run tiendu stores list and tiendu stores set <id>.
|
|
69
|
+
|
|
70
|
+
Agent-friendly setup:
|
|
71
|
+
tiendu init <apiKey> [baseUrl] --non-interactive
|
|
72
|
+
tiendu stores list --non-interactive
|
|
73
|
+
tiendu stores set <id> --non-interactive
|
|
74
|
+
tiendu pull --non-interactive
|
|
75
|
+
tiendu push --non-interactive
|
|
76
|
+
tiendu publish --non-interactive
|
|
77
|
+
|
|
78
|
+
Push and pull behavior:
|
|
79
|
+
build always prepares dist/ as the local deploy artifact.
|
|
80
|
+
push sends a zip of dist/ to the target preview.
|
|
81
|
+
pull resets dist/ and extracts the downloaded theme there.
|
|
82
|
+
pull does not delete src/ files.
|
|
83
|
+
|
|
84
|
+
Pipeline behavior:
|
|
85
|
+
tiendu.config.json can enable optional pipeline steps.
|
|
86
|
+
pipeline.compileScripts enables JS/TS entry compilation.
|
|
87
|
+
pipeline.compileStyles enables CSS entry compilation.
|
|
88
|
+
pipeline.postcss enables PostCSS for compiled style entries.
|
|
89
|
+
With no config file, or with no enabled pipeline steps, build just stages theme files into dist/.
|
|
53
90
|
|
|
54
91
|
Typical workflow:
|
|
55
|
-
tiendu init
|
|
56
|
-
|
|
57
|
-
tiendu
|
|
58
|
-
tiendu
|
|
59
|
-
tiendu dev
|
|
60
|
-
tiendu publish
|
|
92
|
+
tiendu init Connect to Tiendu and save your credentials
|
|
93
|
+
tiendu stores list See available stores
|
|
94
|
+
tiendu stores set <id> Select the store you want to work on
|
|
95
|
+
tiendu pull Refresh dist/ from the current live theme
|
|
96
|
+
tiendu dev Edit locally — preview updates in real time
|
|
97
|
+
tiendu publish Ship to the live storefront when ready
|
|
61
98
|
`;
|
|
62
99
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
100
|
+
const parseArgv = (argv) => {
|
|
101
|
+
const flags = new Set();
|
|
102
|
+
const values = new Map();
|
|
103
|
+
const positionals = [];
|
|
104
|
+
|
|
105
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
106
|
+
const arg = argv[index];
|
|
107
|
+
|
|
108
|
+
if (!arg.startsWith("--")) {
|
|
109
|
+
positionals.push(arg);
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (arg === "--dir") {
|
|
114
|
+
const value = argv[index + 1];
|
|
115
|
+
if (!value || value.startsWith("--")) {
|
|
116
|
+
console.error("Missing value for --dir.");
|
|
117
|
+
process.exit(1);
|
|
118
|
+
}
|
|
119
|
+
values.set("dir", value);
|
|
120
|
+
index += 1;
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
flags.add(arg);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return { flags, values, positionals };
|
|
128
|
+
};
|
|
70
129
|
|
|
71
130
|
const main = async () => {
|
|
72
|
-
const
|
|
73
|
-
const
|
|
74
|
-
const
|
|
75
|
-
const
|
|
76
|
-
const skipBuild =
|
|
131
|
+
const argv = process.argv.slice(2);
|
|
132
|
+
const { flags, values, positionals } = parseArgv(argv);
|
|
133
|
+
const command = positionals[0];
|
|
134
|
+
const subcommand = positionals[1];
|
|
135
|
+
const skipBuild = flags.has("--skip-build");
|
|
136
|
+
const skipInstances = flags.has("--skip-instances");
|
|
137
|
+
const nonInteractive =
|
|
138
|
+
flags.has("--non-interactive") || !process.stdin.isTTY || !process.stdout.isTTY;
|
|
139
|
+
|
|
140
|
+
configureUi({ nonInteractive });
|
|
77
141
|
|
|
78
142
|
if (
|
|
79
143
|
command === "version" ||
|
|
80
|
-
|
|
81
|
-
|
|
144
|
+
argv.includes("--version") ||
|
|
145
|
+
argv.includes("-v")
|
|
82
146
|
) {
|
|
83
147
|
console.log(getCurrentVersion());
|
|
84
148
|
process.exit(0);
|
|
85
149
|
}
|
|
86
150
|
|
|
87
|
-
if (
|
|
88
|
-
!command ||
|
|
89
|
-
command === "--help" ||
|
|
90
|
-
command === "-h"
|
|
91
|
-
) {
|
|
151
|
+
if (!command || argv.includes("--help") || argv.includes("-h")) {
|
|
92
152
|
console.log(HELP.trim());
|
|
93
153
|
process.exit(0);
|
|
94
154
|
}
|
|
@@ -98,40 +158,57 @@ const main = async () => {
|
|
|
98
158
|
return;
|
|
99
159
|
}
|
|
100
160
|
|
|
101
|
-
// Check for updates at most once per day (non-blocking)
|
|
102
161
|
await checkForUpdates();
|
|
103
162
|
|
|
104
163
|
if (command === "init") {
|
|
105
|
-
|
|
164
|
+
const initArgs = positionals.slice(1);
|
|
165
|
+
await init({
|
|
166
|
+
dirArg: values.get("dir"),
|
|
167
|
+
apiKeyArg: initArgs[0],
|
|
168
|
+
baseUrlArg: initArgs[1],
|
|
169
|
+
});
|
|
106
170
|
return;
|
|
107
171
|
}
|
|
108
172
|
|
|
173
|
+
if (command === "stores") {
|
|
174
|
+
if (subcommand === "list") {
|
|
175
|
+
await storesList();
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (subcommand === "set") {
|
|
180
|
+
await storesSet(positionals[2]);
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
console.error(`Unknown subcommand: stores ${subcommand ?? "(none)"}`);
|
|
185
|
+
console.log(HELP.trim());
|
|
186
|
+
process.exit(1);
|
|
187
|
+
}
|
|
188
|
+
|
|
109
189
|
if (command === "pull") {
|
|
110
|
-
|
|
111
|
-
await pull({ previewKey });
|
|
190
|
+
await pull({ previewKey: positionals[1] });
|
|
112
191
|
return;
|
|
113
192
|
}
|
|
114
193
|
|
|
115
194
|
if (command === "build") {
|
|
116
|
-
const result = await build();
|
|
195
|
+
const result = await build({ skipInstances });
|
|
117
196
|
if (!result.ok) process.exit(1);
|
|
118
197
|
return;
|
|
119
198
|
}
|
|
120
199
|
|
|
121
200
|
if (command === "push") {
|
|
122
|
-
|
|
123
|
-
await push({ skipBuild, previewKey });
|
|
201
|
+
await push({ skipBuild, previewKey: positionals[1], skipInstances });
|
|
124
202
|
return;
|
|
125
203
|
}
|
|
126
204
|
|
|
127
205
|
if (command === "dev") {
|
|
128
|
-
await dev();
|
|
206
|
+
await dev({ skipInstances });
|
|
129
207
|
return;
|
|
130
208
|
}
|
|
131
209
|
|
|
132
210
|
if (command === "publish") {
|
|
133
|
-
|
|
134
|
-
await publish({ skipBuild, previewKey });
|
|
211
|
+
await publish({ skipBuild, previewKey: positionals[1], skipInstances });
|
|
135
212
|
return;
|
|
136
213
|
}
|
|
137
214
|
|
|
@@ -141,7 +218,7 @@ const main = async () => {
|
|
|
141
218
|
return;
|
|
142
219
|
}
|
|
143
220
|
if (subcommand === "create") {
|
|
144
|
-
await previewCreate(
|
|
221
|
+
await previewCreate(positionals[2]);
|
|
145
222
|
return;
|
|
146
223
|
}
|
|
147
224
|
if (subcommand === "list") {
|
|
@@ -149,7 +226,7 @@ const main = async () => {
|
|
|
149
226
|
return;
|
|
150
227
|
}
|
|
151
228
|
if (subcommand === "attach") {
|
|
152
|
-
await previewAttach(
|
|
229
|
+
await previewAttach(positionals[2]);
|
|
153
230
|
return;
|
|
154
231
|
}
|
|
155
232
|
if (subcommand === "detach") {
|
|
@@ -157,7 +234,7 @@ const main = async () => {
|
|
|
157
234
|
return;
|
|
158
235
|
}
|
|
159
236
|
if (subcommand === "delete") {
|
|
160
|
-
await previewDelete(
|
|
237
|
+
await previewDelete(positionals[2]);
|
|
161
238
|
return;
|
|
162
239
|
}
|
|
163
240
|
if (subcommand === "open") {
|
package/lib/api.mjs
CHANGED
|
@@ -219,23 +219,25 @@ export const downloadPreviewArchive = async (
|
|
|
219
219
|
* @returns {Promise<{ ok: true } | { ok: false, error: string, retriable?: boolean }>}
|
|
220
220
|
*/
|
|
221
221
|
export const uploadPreviewZip = async (
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
222
|
+
apiBaseUrl,
|
|
223
|
+
apiKey,
|
|
224
|
+
storeId,
|
|
225
|
+
previewKey,
|
|
226
|
+
zipBuffer,
|
|
227
|
+
preserveInstances = false,
|
|
227
228
|
) => {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
229
|
+
try {
|
|
230
|
+
const query = preserveInstances ? "?preserveInstances=true" : "";
|
|
231
|
+
const response = await apiFetch(
|
|
232
|
+
apiBaseUrl,
|
|
233
|
+
apiKey,
|
|
234
|
+
`/api/admin/stores/${storeId}/theme-previews/${previewKey}/upload${query}`,
|
|
235
|
+
{
|
|
236
|
+
method: "POST",
|
|
237
|
+
body: zipBuffer,
|
|
238
|
+
contentType: "application/zip",
|
|
239
|
+
},
|
|
240
|
+
);
|
|
239
241
|
|
|
240
242
|
if (!response.ok) {
|
|
241
243
|
const body = await response.text().catch(() => "");
|
package/lib/archive.mjs
CHANGED
|
@@ -13,7 +13,7 @@ export const listAllFiles = async (rootDir) => listFilesRecursive(rootDir);
|
|
|
13
13
|
* @param {string} rootDir
|
|
14
14
|
* @returns {Promise<Buffer>}
|
|
15
15
|
*/
|
|
16
|
-
export const createZipFromDirectory = async (rootDir) => {
|
|
16
|
+
export const createZipFromDirectory = async (rootDir, shouldInclude) => {
|
|
17
17
|
const absoluteFiles = await listAllFiles(rootDir);
|
|
18
18
|
/** @type {Record<string, Uint8Array>} */
|
|
19
19
|
const entries = {};
|
|
@@ -23,6 +23,7 @@ export const createZipFromDirectory = async (rootDir) => {
|
|
|
23
23
|
.relative(rootDir, absolutePath)
|
|
24
24
|
.split(path.sep)
|
|
25
25
|
.join("/");
|
|
26
|
+
if (shouldInclude && !shouldInclude(relativePath)) continue;
|
|
26
27
|
entries[relativePath] = new Uint8Array(await readFile(absolutePath));
|
|
27
28
|
}
|
|
28
29
|
|