@qumra/cli 2.4.13 → 2.4.14

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/dist/cli.js CHANGED
@@ -278807,59 +278807,65 @@ const ansiRegex$2 = ansiRegex$3;
278807
278807
 
278808
278808
  var stripAnsi$4 = string => typeof string === 'string' ? string.replace(ansiRegex$2(), '') : string;
278809
278809
 
278810
- var isFullwidthCodePoint$2 = {exports: {}};
278810
+ var isFullwidthCodePoint$1 = {exports: {}};
278811
278811
 
278812
278812
  /* eslint-disable yoda */
278813
278813
 
278814
- const isFullwidthCodePoint$1 = codePoint => {
278815
- if (Number.isNaN(codePoint)) {
278816
- return false;
278817
- }
278814
+ var hasRequiredIsFullwidthCodePoint;
278818
278815
 
278819
- // Code points are derived from:
278820
- // http://www.unix.org/Public/UNIDATA/EastAsianWidth.txt
278821
- if (
278822
- codePoint >= 0x1100 && (
278823
- codePoint <= 0x115F || // Hangul Jamo
278824
- codePoint === 0x2329 || // LEFT-POINTING ANGLE BRACKET
278825
- codePoint === 0x232A || // RIGHT-POINTING ANGLE BRACKET
278826
- // CJK Radicals Supplement .. Enclosed CJK Letters and Months
278827
- (0x2E80 <= codePoint && codePoint <= 0x3247 && codePoint !== 0x303F) ||
278828
- // Enclosed CJK Letters and Months .. CJK Unified Ideographs Extension A
278829
- (0x3250 <= codePoint && codePoint <= 0x4DBF) ||
278830
- // CJK Unified Ideographs .. Yi Radicals
278831
- (0x4E00 <= codePoint && codePoint <= 0xA4C6) ||
278832
- // Hangul Jamo Extended-A
278833
- (0xA960 <= codePoint && codePoint <= 0xA97C) ||
278834
- // Hangul Syllables
278835
- (0xAC00 <= codePoint && codePoint <= 0xD7A3) ||
278836
- // CJK Compatibility Ideographs
278837
- (0xF900 <= codePoint && codePoint <= 0xFAFF) ||
278838
- // Vertical Forms
278839
- (0xFE10 <= codePoint && codePoint <= 0xFE19) ||
278840
- // CJK Compatibility Forms .. Small Form Variants
278841
- (0xFE30 <= codePoint && codePoint <= 0xFE6B) ||
278842
- // Halfwidth and Fullwidth Forms
278843
- (0xFF01 <= codePoint && codePoint <= 0xFF60) ||
278844
- (0xFFE0 <= codePoint && codePoint <= 0xFFE6) ||
278845
- // Kana Supplement
278846
- (0x1B000 <= codePoint && codePoint <= 0x1B001) ||
278847
- // Enclosed Ideographic Supplement
278848
- (0x1F200 <= codePoint && codePoint <= 0x1F251) ||
278849
- // CJK Unified Ideographs Extension B .. Tertiary Ideographic Plane
278850
- (0x20000 <= codePoint && codePoint <= 0x3FFFD)
278851
- )
278852
- ) {
278853
- return true;
278854
- }
278816
+ function requireIsFullwidthCodePoint () {
278817
+ if (hasRequiredIsFullwidthCodePoint) return isFullwidthCodePoint$1.exports;
278818
+ hasRequiredIsFullwidthCodePoint = 1;
278855
278819
 
278856
- return false;
278857
- };
278820
+ const isFullwidthCodePoint = codePoint => {
278821
+ if (Number.isNaN(codePoint)) {
278822
+ return false;
278823
+ }
278858
278824
 
278859
- isFullwidthCodePoint$2.exports = isFullwidthCodePoint$1;
278860
- isFullwidthCodePoint$2.exports.default = isFullwidthCodePoint$1;
278825
+ // Code points are derived from:
278826
+ // http://www.unix.org/Public/UNIDATA/EastAsianWidth.txt
278827
+ if (
278828
+ codePoint >= 0x1100 && (
278829
+ codePoint <= 0x115F || // Hangul Jamo
278830
+ codePoint === 0x2329 || // LEFT-POINTING ANGLE BRACKET
278831
+ codePoint === 0x232A || // RIGHT-POINTING ANGLE BRACKET
278832
+ // CJK Radicals Supplement .. Enclosed CJK Letters and Months
278833
+ (0x2E80 <= codePoint && codePoint <= 0x3247 && codePoint !== 0x303F) ||
278834
+ // Enclosed CJK Letters and Months .. CJK Unified Ideographs Extension A
278835
+ (0x3250 <= codePoint && codePoint <= 0x4DBF) ||
278836
+ // CJK Unified Ideographs .. Yi Radicals
278837
+ (0x4E00 <= codePoint && codePoint <= 0xA4C6) ||
278838
+ // Hangul Jamo Extended-A
278839
+ (0xA960 <= codePoint && codePoint <= 0xA97C) ||
278840
+ // Hangul Syllables
278841
+ (0xAC00 <= codePoint && codePoint <= 0xD7A3) ||
278842
+ // CJK Compatibility Ideographs
278843
+ (0xF900 <= codePoint && codePoint <= 0xFAFF) ||
278844
+ // Vertical Forms
278845
+ (0xFE10 <= codePoint && codePoint <= 0xFE19) ||
278846
+ // CJK Compatibility Forms .. Small Form Variants
278847
+ (0xFE30 <= codePoint && codePoint <= 0xFE6B) ||
278848
+ // Halfwidth and Fullwidth Forms
278849
+ (0xFF01 <= codePoint && codePoint <= 0xFF60) ||
278850
+ (0xFFE0 <= codePoint && codePoint <= 0xFFE6) ||
278851
+ // Kana Supplement
278852
+ (0x1B000 <= codePoint && codePoint <= 0x1B001) ||
278853
+ // Enclosed Ideographic Supplement
278854
+ (0x1F200 <= codePoint && codePoint <= 0x1F251) ||
278855
+ // CJK Unified Ideographs Extension B .. Tertiary Ideographic Plane
278856
+ (0x20000 <= codePoint && codePoint <= 0x3FFFD)
278857
+ )
278858
+ ) {
278859
+ return true;
278860
+ }
278861
278861
 
278862
- var isFullwidthCodePointExports = isFullwidthCodePoint$2.exports;
278862
+ return false;
278863
+ };
278864
+
278865
+ isFullwidthCodePoint$1.exports = isFullwidthCodePoint;
278866
+ isFullwidthCodePoint$1.exports.default = isFullwidthCodePoint;
278867
+ return isFullwidthCodePoint$1.exports;
278868
+ }
278863
278869
 
278864
278870
  var emojiRegex$3 = function () {
278865
278871
  // https://mths.be/emoji
@@ -278867,7 +278873,7 @@ var emojiRegex$3 = function () {
278867
278873
  };
278868
278874
 
278869
278875
  const stripAnsi$3 = stripAnsi$4;
278870
- const isFullwidthCodePoint = isFullwidthCodePointExports;
278876
+ const isFullwidthCodePoint = requireIsFullwidthCodePoint();
278871
278877
  const emojiRegex$2 = emojiRegex$3;
278872
278878
 
278873
278879
  const stringWidth$3 = string => {
@@ -279155,7 +279161,7 @@ function requireStringWidth () {
279155
279161
  if (hasRequiredStringWidth) return stringWidth$1.exports;
279156
279162
  hasRequiredStringWidth = 1;
279157
279163
  const stripAnsi = requireStripAnsi();
279158
- const isFullwidthCodePoint = isFullwidthCodePointExports;
279164
+ const isFullwidthCodePoint = requireIsFullwidthCodePoint();
279159
279165
  const emojiRegex = requireEmojiRegex();
279160
279166
 
279161
279167
  const stringWidth = string => {
@@ -304360,7 +304366,7 @@ class SectionBuilder {
304360
304366
  }
304361
304367
  }
304362
304368
 
304363
- var version$2 = "2.4.13";
304369
+ var version$2 = "2.4.14";
304364
304370
  var pkg = {
304365
304371
  version: version$2};
304366
304372
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qumra/cli",
3
- "version": "2.4.13",
3
+ "version": "2.4.14",
4
4
  "description": "Professional CLI tool for Qumra Cloud - Shopify competitor",
5
5
  "main": "dist/cli.js",
6
6
  "bin": {
@@ -21,7 +21,19 @@
21
21
  "release:major": "npm run build && npm version major && npm publish",
22
22
  "prepublishOnly": "npm run build"
23
23
  },
24
- "author": "",
24
+ "homepage": "https://docs.qumra.cloud/docs/cli/intro",
25
+ "files": [
26
+ "dist"
27
+ ],
28
+ "keywords": [
29
+ "qumra",
30
+ "sdk",
31
+ "api",
32
+ "graphql",
33
+ "ecommerce",
34
+ "admin"
35
+ ],
36
+ "author": "Qumra",
25
37
  "license": "MIT",
26
38
  "dependencies": {
27
39
  "@inquirer/search": "^4.1.0",
@@ -1,36 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(tree:*)",
5
- "Bash(npm install:*)",
6
- "Bash(npx ts-node:*)",
7
- "Bash(node --loader ts-node/esm --experimental-specifier-resolution=node -r ts-node/register src/main.ts:*)",
8
- "Bash(node -r ts-node/register src/main.ts:*)",
9
- "Bash(npx tsx:*)",
10
- "Bash(npm run build:*)",
11
- "Bash(npx rollup:*)",
12
- "Bash(npm uninstall:*)",
13
- "Bash(./dist/cli.js:*)",
14
- "Bash(node:*)",
15
- "Bash(npm run start:*)",
16
- "Bash(npm run dev:*)",
17
- "Bash(npx tsc:*)",
18
- "Bash(sudo rm:*)",
19
- "Bash(npm ls:*)",
20
- "Bash(ls:*)",
21
- "Bash(npm run release:minor:*)",
22
- "Bash(git add:*)",
23
- "Bash(git commit -m \"$\\(cat <<''EOF''\nfeat: Replace qumra-engine with local proxy server\n\n- Add ThemeProxyService for proxying requests to store URL\n- Add ThemeHotReloadService for WebSocket-based live reload\n- Add ThemeAssetMapperService for mapping CDN URLs to local files\n- Update ThemeWatcherService with file change callback\n- Remove qumra-engine dependency\n- Add http-proxy-middleware and cheerio dependencies\n\nThis implements a Shopify-style development experience where:\n- Local assets \\(CSS, JS, images\\) are served from the theme folder\n- HTML responses are rewritten to use local asset URLs\n- CSS changes are hot-swapped without full page reload\n- Other changes trigger full page reload\n- All files are still uploaded to server for SSR\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")",
24
- "Bash(npm version:*)",
25
- "Bash(npm publish)",
26
- "Bash(npm publish:*)",
27
- "Bash(DEBUG=*)",
28
- "Bash(npm link:*)",
29
- "Bash(git commit:*)",
30
- "Bash(git checkout:*)",
31
- "Bash(git clean:*)",
32
- "Bash(git merge:*)",
33
- "Bash(git branch:*)"
34
- ]
35
- }
36
- }
package/CLAUDE.md DELETED
@@ -1,239 +0,0 @@
1
- # CLAUDE.md
2
-
3
- This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
-
5
- ## Project Overview
6
-
7
- Qumra CLI is a command-line tool for Qumra Cloud (e-commerce platform). Built with NestJS and nest-commander, bundled with Rollup, distributed as an npm package (`qumra-cloud`).
8
-
9
- ## Common Commands
10
-
11
- ```bash
12
- npm run dev # Run source directly with tsx (recommended for development)
13
- npm run dev:watch # Watch mode with tsx
14
- npm run build # Clean and build with Rollup into dist/cli.js
15
- npm run build:watch # Watch mode for Rollup builds
16
- npm run link # Build and link globally for local testing
17
- npm start # Run pre-built dist/cli.js
18
- ```
19
-
20
- No lint or test commands are configured.
21
-
22
- ## Architecture
23
-
24
- ```
25
- src/
26
- ├── main.ts # CLI bootstrap with nest-commander CommandFactory
27
- ├── app.module.ts # Root module importing all feature modules
28
- ├── common/ # Global shared services (@Global module)
29
- │ ├── auth/ # AuthService - token storage via StorageService
30
- │ ├── config/ # ConfigService - project-level .qumra/qumra.config.json
31
- │ ├── storage/ # StorageService - user-level ~/.config/qumra-cli/
32
- │ ├── logger/ # LoggerService - formatted console output with chalk
33
- │ │ └── blessed-ui.ts # BlessedUI - Terminal UI with panels and shortcuts
34
- │ ├── graphql/ # GraphqlService - graphql-request wrapper with auth
35
- │ ├── tunnel/ # TunnelService - cloudflared tunnel management
36
- │ └── constants.ts # API endpoints and constants
37
- └── modules/ # Feature modules
38
- ├── user/ # login, logout, info commands
39
- ├── theme/ # init, dev, publish, bundle, patch/minor/major commands
40
- ├── app/ # init, dev, deploy commands
41
- └── generate/ # widget scaffolding command
42
- ```
43
-
44
- ## Key Patterns
45
-
46
- **Command Structure**: Commands extend `CommandRunner` from nest-commander. Commands are thin wrappers that delegate to services for business logic.
47
-
48
- **Service Injection**: All services use constructor injection with `@Injectable()`. CommonModule is `@Global()` so its services (Logger, Auth, Config, Storage, GraphQL, Tunnel) are available everywhere.
49
-
50
- **Configuration**:
51
- - Project config: `.qumra/qumra.config.json` (via ConfigService)
52
- - User config: `~/.config/qumra-cli/` (via StorageService using `conf` package)
53
-
54
- **API Communication**: GraphqlService wraps graphql-request and auto-injects auth token from AuthService.
55
-
56
- **File Watching**: ThemeWatcherService uses chokidar for live sync during `theme dev`.
57
-
58
- ## External Services
59
-
60
- - GraphQL API: `https://api.qumra.cloud/graphql`
61
- - REST Upload API: `https://api.qumra.cloud/v1/upload`
62
- - Realtime WebSocket: `wss://realtime.qumra.cloud`
63
- - Login Portal: `https://app.qumra.cloud/auth/login`
64
- - Theme Editor: `https://app.qumra.cloud/store/{subdomain}/themes/{appThemeId}`
65
-
66
- ## Build Configuration
67
-
68
- Rollup bundles `src/main.ts` into `dist/cli.js` as CommonJS with shebang. External packages: qumra-engine, NestJS packages, fsevents.
69
-
70
- ---
71
-
72
- ## Theme Dev Command (`qumra theme dev`)
73
-
74
- ### Overview
75
-
76
- The theme dev command starts a local development server for theme development with:
77
- - Proxy server to forward requests to the store
78
- - Hot reload for live updates
79
- - File watcher for syncing changes
80
- - BlessedUI for terminal interface
81
-
82
- ### Flow
83
-
84
- 1. Load `qumra.config.json` to get `themeVersionId`
85
- 2. Show store selection (inquirer prompt)
86
- 3. Install theme on store via `installTheme` mutation → returns `appTheme._id`
87
- 4. Start hot reload WebSocket server
88
- 5. Start proxy server
89
- 6. Start BlessedUI terminal interface
90
- 7. Start file watcher
91
-
92
- ### Key IDs
93
-
94
- - `themeId` - The theme's unique ID (from qumra.config.json)
95
- - `themeVersionId` - The specific version ID (from qumra.config.json)
96
- - `appTheme._id` - Returned from `installTheme` mutation, used for:
97
- - Proxy header: `X-Qumra-App-Theme`
98
- - Theme Editor URL
99
- - File sync operations
100
-
101
- ### Services Architecture
102
-
103
- #### ThemeProxyService (`theme-proxy.service.ts`)
104
-
105
- Express server that:
106
- - Serves local `/assets` from theme folder
107
- - Proxies all other requests to store URL
108
- - Adds headers:
109
- - `X-Qumra-Dev-Mode: true`
110
- - `X-Qumra-App-Theme: {appTheme._id}`
111
- - Injects hot reload script into HTML responses
112
- - Adds dev mode indicator badge
113
-
114
- **Important**: Don't rewrite asset URLs in HTML - just serve `/assets` locally and let backend URLs pass through unchanged.
115
-
116
- #### ThemeWatcherService (`theme-watcher.service.ts`)
117
-
118
- File watcher using chokidar with different sync handlers per folder:
119
-
120
- | Folder | File Type | Sync Method | Endpoint |
121
- |--------|-----------|-------------|----------|
122
- | `assets` | all | CDN Presigned URL | GraphQL `CdnPresignedUrl` → upload to presigned URL |
123
- | `layouts` | `.njk` | REST Upload | `POST /v1/upload` |
124
- | `templates` | `.njk` | REST Upload | `POST /v1/upload` |
125
- | `ui` | `.njk`, `.css` | REST Upload | `POST /v1/upload` |
126
- | `locales` | `.json` | REST Upload | `POST /v1/upload` |
127
- | `widgets` | `.njk` | REST Upload | `POST /v1/upload` |
128
- | `widgets` | `.json` | GraphQL | `SyncWidget` mutation |
129
- | `pages` | `.json` | GraphQL | `SyncThemePage` mutation |
130
- | `settings` | `.json` | GraphQL | `UpdateThemeVersionSettings` mutation |
131
-
132
- **Features**:
133
- - 300ms debounce to prevent rapid consecutive syncs
134
- - No initial sync on startup (only watches for changes)
135
- - Different handlers based on file type and folder
136
-
137
- #### ThemeHotReloadService (`theme-hot-reload.service.ts`)
138
-
139
- WebSocket server (Socket.IO) for live reload:
140
- - Listens for file changes from watcher
141
- - Notifies connected browsers
142
- - CSS changes: hot swap without page reload
143
- - Other changes: full page reload
144
-
145
- **Client Script**: Injected into HTML before `</body>`:
146
- ```html
147
- <script src="https://cdn.socket.io/4.6.0/socket.io.min.js"></script>
148
- <script>
149
- (function() {
150
- var socket = io('http://localhost:{port}');
151
- socket.on('file-change', function(event) {
152
- if (event.type === 'css') {
153
- // Hot swap CSS
154
- } else {
155
- window.location.reload();
156
- }
157
- });
158
- })();
159
- </script>
160
- ```
161
-
162
- **Important**: Socket.IO library must be loaded BEFORE the client script that uses it.
163
-
164
- ### BlessedUI (`blessed-ui.ts`)
165
-
166
- Terminal UI using `blessed` library:
167
- - Info box with theme/store details and URLs
168
- - Log panel for sync/proxy activity
169
- - Footer with keyboard shortcuts (q: quit, o: open browser, s: open store, e: theme editor)
170
-
171
- **Gotchas**:
172
- - Must set `mouse: false` to prevent click-exit issues
173
- - Don't use `console.log` after BlessedUI starts (interferes with terminal control)
174
- - Wait ~100ms after inquirer prompt before starting BlessedUI (stdin release)
175
-
176
- ### GraphQL Mutations
177
-
178
- ```graphql
179
- # Install theme on store
180
- mutation InstallTheme($input: InstallThemeInput!) {
181
- installTheme(input: $input) {
182
- _id # This is appTheme._id
183
- }
184
- }
185
-
186
- # Sync page
187
- mutation SyncThemePage($input: SyncThemePageInput!) {
188
- syncThemePage(input: $input) { success message }
189
- }
190
-
191
- # Sync widget schema
192
- mutation SyncWidget($input: SyncWidgetInput!) {
193
- syncWidget(input: $input) { success message }
194
- }
195
-
196
- # Update settings
197
- mutation UpdateThemeVersionSettings($input: UpdateThemeVersionSettingsInput!) {
198
- updateThemeVersionSettings(input: $input) { success message }
199
- }
200
-
201
- # Get CDN presigned URL for assets
202
- mutation CdnPresignedUrl($cdnPresignedInput: CdnPresignedInput!) {
203
- cdnPresignedUrl(cdnPresignedInput: $cdnPresignedInput) {
204
- success message presignedUrl
205
- }
206
- }
207
- ```
208
-
209
- ### Settings Files
210
-
211
- The `settings/` folder has specific JSON files:
212
- - `settings-schema.json` - Theme settings schema
213
- - `settings-data.json` - Theme settings values
214
- - `header-schema.json` - Header settings schema
215
- - `header-data.json` - Header settings values
216
- - `footer-schema.json` - Footer settings schema
217
- - `footer-data.json` - Footer settings values
218
- - `templates-settings.json` - Templates configuration
219
-
220
- ---
221
-
222
- ## App Dev Command (`qumra app dev`)
223
-
224
- Similar to theme dev but:
225
- - Uses cloudflared tunnel for HTTPS
226
- - Spawns `npx react-router dev` child process
227
- - Updates app's `developmentUrl` on backend
228
-
229
- ---
230
-
231
- ## Reference: Old CLI (`../qumra-cli`)
232
-
233
- The new NestJS CLI should match the old CLI's behavior. Key reference files:
234
- - `src/services/themes/watcher/` - File sync handlers
235
- - `src/utils/uploadFileToServer.ts` - REST upload to `/v1/upload`
236
- - `src/utils/uploadFileToCdnPresignedUrl.ts` - CDN upload via presigned URL
237
- - `src/utils/syncThemePage.ts` - GraphQL page sync
238
- - `src/utils/syncWidgetSchema.ts` - GraphQL widget sync
239
- - `src/utils/syncThemeVersionSettings.ts` - GraphQL settings sync
package/tsconfig.dev.json DELETED
@@ -1,20 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2019",
4
- "module": "CommonJS",
5
- "moduleResolution": "Node",
6
- "outDir": "dist",
7
- "rootDir": "src",
8
- "esModuleInterop": true,
9
- "forceConsistentCasingInFileNames": true,
10
- "strict": true,
11
- "skipLibCheck": true,
12
- "allowSyntheticDefaultImports": true,
13
- "experimentalDecorators": true,
14
- "emitDecoratorMetadata": true
15
- },
16
- "include": ["src/**/*"],
17
- "ts-node": {
18
- "esm": false
19
- }
20
- }