dolphin-client 1.0.5 → 1.0.9

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.
@@ -0,0 +1,558 @@
1
+ {
2
+ "version": 1.1,
3
+ "tags": [
4
+ {
5
+ "name": "dolphin-accordion",
6
+ "description": "Dolphin CLI Component"
7
+ },
8
+ {
9
+ "name": "dolphin-avatar",
10
+ "description": "Dolphin CLI Component"
11
+ },
12
+ {
13
+ "name": "dolphin-checkbox",
14
+ "description": "Dolphin CLI Component"
15
+ },
16
+ {
17
+ "name": "dolphin-tabs",
18
+ "description": "Dolphin CLI Component"
19
+ },
20
+ {
21
+ "name": "dolphin-login",
22
+ "description": "Dolphin CLI Component"
23
+ },
24
+ {
25
+ "name": "dolphin-register",
26
+ "description": "Dolphin CLI Component"
27
+ },
28
+ {
29
+ "name": "dolphin-form-floating",
30
+ "description": "Dolphin CLI Component"
31
+ },
32
+ {
33
+ "name": "dolphin-form-standard",
34
+ "description": "Dolphin CLI Component"
35
+ },
36
+ {
37
+ "name": "dolphin-table",
38
+ "description": "Dolphin CLI Component"
39
+ },
40
+ {
41
+ "name": "dolphin-toast",
42
+ "description": "Dolphin CLI Component"
43
+ },
44
+ {
45
+ "name": "dolphin-modal",
46
+ "description": "Dolphin CLI Component"
47
+ },
48
+ {
49
+ "name": "dolphin-button",
50
+ "description": "Dolphin CLI Component"
51
+ },
52
+ {
53
+ "name": "dolphin-card",
54
+ "description": "Dolphin CLI Component"
55
+ },
56
+ {
57
+ "name": "dolphin-navbar",
58
+ "description": "Dolphin CLI Component"
59
+ },
60
+ {
61
+ "name": "dolphin-alert",
62
+ "description": "Dolphin CLI Component"
63
+ },
64
+ {
65
+ "name": "dolphin-badge",
66
+ "description": "Dolphin CLI Component"
67
+ },
68
+ {
69
+ "name": "dolphin-header",
70
+ "description": "Dolphin CLI Component"
71
+ },
72
+ {
73
+ "name": "dolphin-footer",
74
+ "description": "Dolphin CLI Component"
75
+ },
76
+ {
77
+ "name": "dolphin-grid",
78
+ "description": "Dolphin CLI Component"
79
+ },
80
+ {
81
+ "name": "dolphin-dashboard",
82
+ "description": "Dolphin CLI Component"
83
+ },
84
+ {
85
+ "name": "dolphin-switch",
86
+ "description": "Dolphin CLI Component"
87
+ },
88
+ {
89
+ "name": "dolphin-tooltip",
90
+ "description": "Dolphin CLI Component"
91
+ },
92
+ {
93
+ "name": "dolphin-slider",
94
+ "description": "Dolphin CLI Component"
95
+ },
96
+ {
97
+ "name": "dolphin-dropdown",
98
+ "description": "Dolphin CLI Component"
99
+ },
100
+ {
101
+ "name": "dolphin-popover",
102
+ "description": "Dolphin CLI Component"
103
+ },
104
+ {
105
+ "name": "dolphin-skeleton",
106
+ "description": "Dolphin CLI Component"
107
+ },
108
+ {
109
+ "name": "dolphin-progress",
110
+ "description": "Dolphin CLI Component"
111
+ },
112
+ {
113
+ "name": "dolphin-theme-bar",
114
+ "description": "Dolphin CLI Component"
115
+ },
116
+ {
117
+ "name": "dolphin-drawer",
118
+ "description": "Dolphin CLI Component"
119
+ },
120
+ {
121
+ "name": "dolphin-breadcrumbs",
122
+ "description": "Dolphin CLI Component"
123
+ },
124
+ {
125
+ "name": "dolphin-pagination",
126
+ "description": "Dolphin CLI Component"
127
+ },
128
+ {
129
+ "name": "dolphin-steps",
130
+ "description": "Dolphin CLI Component"
131
+ },
132
+ {
133
+ "name": "dolphin-hero",
134
+ "description": "Dolphin CLI Component"
135
+ },
136
+ {
137
+ "name": "dolphin-pricing",
138
+ "description": "Dolphin CLI Component"
139
+ },
140
+ {
141
+ "name": "dolphin-carousel",
142
+ "description": "Dolphin CLI Component"
143
+ },
144
+ {
145
+ "name": "dolphin-timeline",
146
+ "description": "Dolphin CLI Component"
147
+ },
148
+ {
149
+ "name": "dolphin-dropzone",
150
+ "description": "Dolphin CLI Component"
151
+ },
152
+ {
153
+ "name": "dolphin-chat",
154
+ "description": "Dolphin CLI Component"
155
+ },
156
+ {
157
+ "name": "dolphin-rating",
158
+ "description": "Dolphin CLI Component"
159
+ }
160
+ ],
161
+ "globalAttributes": [
162
+ {
163
+ "name": "class",
164
+ "valueSet": "dolphin-classes"
165
+ },
166
+ {
167
+ "name": "className",
168
+ "valueSet": "dolphin-classes"
169
+ },
170
+ {
171
+ "name": "data-import",
172
+ "description": "Imports an HTML fragment recursively from the specified relative path or URL."
173
+ },
174
+ {
175
+ "name": "data-api-get",
176
+ "description": "Performs a GET request to the specified API URL and renders it."
177
+ },
178
+ {
179
+ "name": "data-rt-template",
180
+ "description": "Specifies the CSS selector of the template to use (e.g., #product)."
181
+ },
182
+ {
183
+ "name": "data-rt-bind",
184
+ "description": "Binds the HTML content or properties to a specific state or API response."
185
+ },
186
+ {
187
+ "name": "data-store-write",
188
+ "description": "Binds input changes to write to the specified store state (e.g., store.property)."
189
+ },
190
+ {
191
+ "name": "data-store-read",
192
+ "description": "Binds element to read/display state from the specified store state (e.g., store.property)."
193
+ },
194
+ {
195
+ "name": "data-rt-validate",
196
+ "description": "Specifies validation rules for the input (e.g., required, email)."
197
+ },
198
+ {
199
+ "name": "data-api-submit",
200
+ "description": "Submits form data to the specified API URL (e.g., POST /api/submit)."
201
+ },
202
+ {
203
+ "name": "data-api-result",
204
+ "description": "Saves the API submission result to the specified state path."
205
+ },
206
+ {
207
+ "name": "data-api-redirect",
208
+ "description": "URL to redirect the user to after a successful API submission."
209
+ },
210
+ {
211
+ "name": "data-api-reload",
212
+ "description": "Reloads the page after a successful API submission."
213
+ },
214
+ {
215
+ "name": "data-rt-type",
216
+ "description": "Specifies the rendering type, such as 'context'."
217
+ },
218
+ {
219
+ "name": "data-rt-payload",
220
+ "description": "Payload JSON string to pass with events (e.g., '{{id}}')."
221
+ },
222
+ {
223
+ "name": "data-api-payload",
224
+ "description": "Payload JSON string to send with API events."
225
+ },
226
+ {
227
+ "name": "data-rt-debounce",
228
+ "description": "Time in milliseconds to debounce inputs before triggering an action."
229
+ },
230
+ {
231
+ "name": "data-rt-click",
232
+ "description": "Publishes a custom Dolphin event on click."
233
+ },
234
+ {
235
+ "name": "data-rt-change",
236
+ "description": "Publishes a custom Dolphin event on change."
237
+ },
238
+ {
239
+ "name": "data-rt-submit",
240
+ "description": "Publishes a custom Dolphin event on form submit."
241
+ },
242
+ {
243
+ "name": "data-rt-input",
244
+ "description": "Publishes a custom Dolphin event on input."
245
+ },
246
+ {
247
+ "name": "data-rt-keydown",
248
+ "description": "Publishes a custom Dolphin event on keydown."
249
+ },
250
+ {
251
+ "name": "data-rt-keyup",
252
+ "description": "Publishes a custom Dolphin event on keyup."
253
+ },
254
+ {
255
+ "name": "data-rt-dblclick",
256
+ "description": "Publishes a custom Dolphin event on double click."
257
+ },
258
+ {
259
+ "name": "data-rt-focus",
260
+ "description": "Publishes a custom Dolphin event on focus."
261
+ },
262
+ {
263
+ "name": "data-rt-blur",
264
+ "description": "Publishes a custom Dolphin event on blur."
265
+ },
266
+ {
267
+ "name": "data-rt-mouseenter",
268
+ "description": "Publishes a custom Dolphin event on mouse enter."
269
+ },
270
+ {
271
+ "name": "data-rt-mouseleave",
272
+ "description": "Publishes a custom Dolphin event on mouse leave."
273
+ },
274
+ {
275
+ "name": "data-api-click",
276
+ "description": "Performs an API request on click (e.g., POST /api/like)."
277
+ },
278
+ {
279
+ "name": "data-api-change",
280
+ "description": "Performs an API request on change."
281
+ },
282
+ {
283
+ "name": "data-api-input",
284
+ "description": "Performs an API request on input."
285
+ },
286
+ {
287
+ "name": "data-api-keydown",
288
+ "description": "Performs an API request on keydown."
289
+ },
290
+ {
291
+ "name": "data-api-keyup",
292
+ "description": "Performs an API request on keyup."
293
+ },
294
+ {
295
+ "name": "data-api-dblclick",
296
+ "description": "Performs an API request on double click."
297
+ },
298
+ {
299
+ "name": "data-api-focus",
300
+ "description": "Performs an API request on focus."
301
+ },
302
+ {
303
+ "name": "data-api-blur",
304
+ "description": "Performs an API request on blur."
305
+ },
306
+ {
307
+ "name": "data-api-mouseenter",
308
+ "description": "Performs an API request on mouse enter."
309
+ },
310
+ {
311
+ "name": "data-api-mouseleave",
312
+ "description": "Performs an API request on mouse leave."
313
+ },
314
+ {
315
+ "name": "data-store-click",
316
+ "description": "Runs a Dolphin store action expression on click (e.g., app.count++)."
317
+ },
318
+ {
319
+ "name": "data-store-change",
320
+ "description": "Runs a Dolphin store action expression on change."
321
+ },
322
+ {
323
+ "name": "data-store-submit",
324
+ "description": "Runs a Dolphin store action expression on submit."
325
+ },
326
+ {
327
+ "name": "data-store-input",
328
+ "description": "Runs a Dolphin store action expression on input."
329
+ },
330
+ {
331
+ "name": "data-store-keydown",
332
+ "description": "Runs a Dolphin store action expression on keydown."
333
+ },
334
+ {
335
+ "name": "data-store-keyup",
336
+ "description": "Runs a Dolphin store action expression on keyup."
337
+ },
338
+ {
339
+ "name": "data-store-dblclick",
340
+ "description": "Runs a Dolphin store action expression on double click."
341
+ },
342
+ {
343
+ "name": "data-store-focus",
344
+ "description": "Runs a Dolphin store action expression on focus."
345
+ },
346
+ {
347
+ "name": "data-store-blur",
348
+ "description": "Runs a Dolphin store action expression on blur."
349
+ },
350
+ {
351
+ "name": "data-store-mouseenter",
352
+ "description": "Runs a Dolphin store action expression on mouse enter."
353
+ },
354
+ {
355
+ "name": "data-store-mouseleave",
356
+ "description": "Runs a Dolphin store action expression on mouse leave."
357
+ },
358
+ {
359
+ "name": "data-rt-text",
360
+ "description": "Binds text content to a property in the closest rendering context."
361
+ },
362
+ {
363
+ "name": "data-rt-html",
364
+ "description": "Binds HTML content to a property in the closest rendering context."
365
+ },
366
+ {
367
+ "name": "data-rt-attr",
368
+ "description": "Binds attributes dynamically (e.g., src:imageUrl, href:linkUrl)."
369
+ },
370
+ {
371
+ "name": "data-rt-class",
372
+ "description": "Binds CSS classes conditionally (e.g., active:isActive)."
373
+ },
374
+ {
375
+ "name": "data-rt-if",
376
+ "description": "Shows the element only if the specified context property is truthy."
377
+ },
378
+ {
379
+ "name": "data-rt-hide",
380
+ "description": "Hides the element if the specified context property is truthy."
381
+ },
382
+ {
383
+ "name": "data-rt-filter",
384
+ "description": "Filters the rendered data array (e.g., status==completed)."
385
+ },
386
+ {
387
+ "name": "data-rt-search",
388
+ "description": "Searches the rendered data array (e.g., title==searchQuery)."
389
+ },
390
+ {
391
+ "name": "data-rt-sort",
392
+ "description": "Sorts the rendered data array (e.g., price.asc or popular)."
393
+ }
394
+ ],
395
+ "valueSets": [
396
+ {
397
+ "name": "dolphin-classes",
398
+ "values": [
399
+ {
400
+ "name": "dolphin-accordion",
401
+ "description": "Dolphin CLI Component (dolphin-accordion.html)"
402
+ },
403
+ {
404
+ "name": "dolphin-avatar",
405
+ "description": "Dolphin CLI Component (dolphin-avatar.html)"
406
+ },
407
+ {
408
+ "name": "dolphin-checkbox",
409
+ "description": "Dolphin CLI Component (dolphin-checkbox.html)"
410
+ },
411
+ {
412
+ "name": "dolphin-tabs",
413
+ "description": "Dolphin CLI Component (dolphin-tabs.html)"
414
+ },
415
+ {
416
+ "name": "dolphin-login",
417
+ "description": "Dolphin CLI Component (dolphin-login.html)"
418
+ },
419
+ {
420
+ "name": "dolphin-register",
421
+ "description": "Dolphin CLI Component (dolphin-register.html)"
422
+ },
423
+ {
424
+ "name": "dolphin-form-floating",
425
+ "description": "Dolphin CLI Component (dolphin-form-floating.html)"
426
+ },
427
+ {
428
+ "name": "dolphin-form-standard",
429
+ "description": "Dolphin CLI Component (dolphin-form-standard.html)"
430
+ },
431
+ {
432
+ "name": "dolphin-table",
433
+ "description": "Dolphin CLI Component (dolphin-table.html)"
434
+ },
435
+ {
436
+ "name": "dolphin-toast",
437
+ "description": "Dolphin CLI Component (dolphin-toast.html)"
438
+ },
439
+ {
440
+ "name": "dolphin-modal",
441
+ "description": "Dolphin CLI Component (dolphin-modal.html)"
442
+ },
443
+ {
444
+ "name": "dolphin-button",
445
+ "description": "Dolphin CLI Component (dolphin-button.html)"
446
+ },
447
+ {
448
+ "name": "dolphin-card",
449
+ "description": "Dolphin CLI Component (dolphin-card.html)"
450
+ },
451
+ {
452
+ "name": "dolphin-navbar",
453
+ "description": "Dolphin CLI Component (dolphin-navbar.html)"
454
+ },
455
+ {
456
+ "name": "dolphin-alert",
457
+ "description": "Dolphin CLI Component (dolphin-alert.html)"
458
+ },
459
+ {
460
+ "name": "dolphin-badge",
461
+ "description": "Dolphin CLI Component (dolphin-badge.html)"
462
+ },
463
+ {
464
+ "name": "dolphin-header",
465
+ "description": "Dolphin CLI Component (dolphin-header.html)"
466
+ },
467
+ {
468
+ "name": "dolphin-footer",
469
+ "description": "Dolphin CLI Component (dolphin-footer.html)"
470
+ },
471
+ {
472
+ "name": "dolphin-grid",
473
+ "description": "Dolphin CLI Component (dolphin-grid.html)"
474
+ },
475
+ {
476
+ "name": "dolphin-dashboard",
477
+ "description": "Dolphin CLI Component (dolphin-dashboard.html)"
478
+ },
479
+ {
480
+ "name": "dolphin-switch",
481
+ "description": "Dolphin CLI Component (dolphin-switch.html)"
482
+ },
483
+ {
484
+ "name": "dolphin-tooltip",
485
+ "description": "Dolphin CLI Component (dolphin-tooltip.html)"
486
+ },
487
+ {
488
+ "name": "dolphin-slider",
489
+ "description": "Dolphin CLI Component (dolphin-slider.html)"
490
+ },
491
+ {
492
+ "name": "dolphin-dropdown",
493
+ "description": "Dolphin CLI Component (dolphin-dropdown.html)"
494
+ },
495
+ {
496
+ "name": "dolphin-popover",
497
+ "description": "Dolphin CLI Component (dolphin-popover.html)"
498
+ },
499
+ {
500
+ "name": "dolphin-skeleton",
501
+ "description": "Dolphin CLI Component (dolphin-skeleton.html)"
502
+ },
503
+ {
504
+ "name": "dolphin-progress",
505
+ "description": "Dolphin CLI Component (dolphin-progress.html)"
506
+ },
507
+ {
508
+ "name": "dolphin-theme-bar",
509
+ "description": "Dolphin CLI Component (dolphin-theme-bar.html)"
510
+ },
511
+ {
512
+ "name": "dolphin-drawer",
513
+ "description": "Dolphin CLI Component (dolphin-drawer.html)"
514
+ },
515
+ {
516
+ "name": "dolphin-breadcrumbs",
517
+ "description": "Dolphin CLI Component (dolphin-breadcrumbs.html)"
518
+ },
519
+ {
520
+ "name": "dolphin-pagination",
521
+ "description": "Dolphin CLI Component (dolphin-pagination.html)"
522
+ },
523
+ {
524
+ "name": "dolphin-steps",
525
+ "description": "Dolphin CLI Component (dolphin-steps.html)"
526
+ },
527
+ {
528
+ "name": "dolphin-hero",
529
+ "description": "Dolphin CLI Component (dolphin-hero.html)"
530
+ },
531
+ {
532
+ "name": "dolphin-pricing",
533
+ "description": "Dolphin CLI Component (dolphin-pricing.html)"
534
+ },
535
+ {
536
+ "name": "dolphin-carousel",
537
+ "description": "Dolphin CLI Component (dolphin-carousel.html)"
538
+ },
539
+ {
540
+ "name": "dolphin-timeline",
541
+ "description": "Dolphin CLI Component (dolphin-timeline.html)"
542
+ },
543
+ {
544
+ "name": "dolphin-dropzone",
545
+ "description": "Dolphin CLI Component (dolphin-dropzone.html)"
546
+ },
547
+ {
548
+ "name": "dolphin-chat",
549
+ "description": "Dolphin CLI Component (dolphin-chat.html)"
550
+ },
551
+ {
552
+ "name": "dolphin-rating",
553
+ "description": "Dolphin CLI Component (dolphin-rating.html)"
554
+ }
555
+ ]
556
+ }
557
+ ]
558
+ }
package/README.md CHANGED
@@ -29,13 +29,17 @@ By breathing life back into standard HTML, we have resurrected the simplicity of
29
29
 
30
30
  ## Features
31
31
 
32
+ - **Universal Backend Compatibility**: Native out-of-the-box support for PHP (Laravel, CakePHP, WordPress) and Node.js (Express, NestJS, Fastify). Auto-extracts/injects CSRF tokens and nonces, normalizes multi-format validation error payloads directly into reactive forms, and supports HTTP method spoofing (`_method`) and subfolder base URLs automatically.
33
+ - **HTML Component Imports (`data-import`)**: Declaratively import reusable layouts (e.g. `header.html`, `footer.html`) dynamically in pure HTML with robust concurrent promise caching, nested rendering, and circular dependency checks.
34
+ - **Instant SPA Viewport Router (`data-spa`)**: Converts static pages into highly responsive Single Page Applications (SPAs) with zero manual JS. High-jacks links, swaps viewports dynamically with smooth fading transitions, and updates page titles and history navigation (`popstate`).
32
35
  - **Hookless Reactivity**: Bind topics to DOM elements via HTML data attributes—no React, Vue, or Angular state management required.
33
36
  - **Svelte-Style Templates Compiler**: Native browser compiler supporting Svelte-style loop blocks (`{#each ... as ...}`), multi-level nested conditionals (`{#if} / {:else if} / {:else}`), loop indices (`index`), optional chaining, and dynamic attribute interpolation.
34
37
  - **Unified Event Binding**: Loop-based browser event handling for values (`data-rt-push`) and actions (`data-rt-[event]` / `data-api-[event]`).
35
38
  - **Context API/Prop drilling in Pure DOM**: Crawls up the DOM tree (`getClosestContext`) to fetch parent contexts and inject parameters.
36
39
  - **REST API + Realtime Hybrid Support**: Evaluates templates (`data-rt-template`) on initial HTTP fetches (`data-api-get`) and transitions seamlessly to real-time WebSockets on connection.
37
40
  - **WebRTC Intercom Signaling**: Built-in methods to handle peer connections, track negotiation, ICE candidates, and signaling.
38
- - **Ultralight weight**: Zero external dependencies, pure browser-native runtime APIs (~39KB compressed bundle!).
41
+ - **DolphinStore JS API & React Integration**: Programmatic store query, filtering (`where`), sorting (`orderBy`), and live collection syncing with auto-REST/WS fallback. Integrates seamlessly with React (class or hook components) using native external store subscriptions.
42
+ - **Ultralight weight**: Zero external dependencies, pure browser-native runtime APIs (~47KB compressed bundle!).
39
43
 
40
44
  ---
41
45
 
@@ -90,6 +94,30 @@ Inside your HTML, simply link them locally:
90
94
 
91
95
  ---
92
96
 
97
+ ## 🧠 VS Code Autocomplete (IntelliSense)
98
+
99
+ Get instant HTML attribute suggestions for all Dolphin Client attributes (`data-api-get`, `data-rt-click`, `data-store-write`, etc.) directly inside VS Code!
100
+
101
+ ### For NPM Users
102
+ Autocomplete is set up **automatically** when you install:
103
+ ```bash
104
+ npm install dolphin-client
105
+ ```
106
+ That's it! Reload VS Code window (`Ctrl + Shift + P` → `Developer: Reload Window`) and start typing `data-` to see suggestions.
107
+
108
+ ### For CDN / Direct Download Users
109
+ Run this **one-time command** inside your project folder:
110
+ ```bash
111
+ npx dolphin-client
112
+ ```
113
+
114
+ This will automatically generate `.vscode/settings.json` and `.vscode/dolphin-tags.json` in your project, enabling full HTML attribute autocomplete in VS Code.
115
+
116
+ > [!TIP]
117
+ > After running the command, reload VS Code (`Ctrl + Shift + P` → `Developer: Reload Window`) to activate autocomplete. You only need to run this **once per project**!
118
+
119
+ ---
120
+
93
121
  ## Interactive Examples Guide
94
122
 
95
123
  Below are clean, ready-to-use HTML examples for the core features of Dolphin Client. Because Dolphin supports **Zero-Configuration Auto-Initialization**, these will run instantly!
@@ -177,7 +205,26 @@ Manage local stores and run complex calculations, conditions, and toggles **dire
177
205
  <button data-store-click="app.darkMode = !app.darkMode">Toggle Dark Mode</button>
178
206
  ```
179
207
 
180
- ### 5. Silent Zero-Configuration Auto-Initialization
208
+ ### 5. JavaScript Store API & React Integration
209
+ Query and filter dynamic collections programmatically in JS or sync them with React without state hooks:
210
+
211
+ ```javascript
212
+ // Access the reactive store (auto-fetches GET /users and subscribes to WS db:sync/users)
213
+ const users = dolphin.store.users;
214
+
215
+ // Dynamic client-side filtering and sorting
216
+ const activeAdmins = users.where(u => u.active && u.role === 'admin').orderBy('name', 'asc');
217
+
218
+ // Subscribe to store changes manually
219
+ const unsubscribe = dolphin.store.subscribe(() => {
220
+ console.log("Updated admin count:", activeAdmins.items.length);
221
+ });
222
+
223
+ // Clean up when no longer needed to prevent memory leaks
224
+ dolphin.store.destroy();
225
+ ```
226
+
227
+ ### 6. Silent Zero-Configuration Auto-Initialization
181
228
  When loaded via a standard `<script>` tag in browser environments, Dolphin Client automatically boots up a default client instance as `window.dolphin` on `DOMContentLoaded`.
182
229
 
183
230
  For debugging, pass `data-debug="true"` on your script tag to turn on gorgeous, color-coded logging in your developer console for all API calls, WebSocket events, and Store updates:
package/bin/cli.cjs ADDED
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ // This CLI runs when users execute: npx dolphin-client
7
+ // It sets up the VS Code HTML Custom Data configurations for autocomplete automatically!
8
+
9
+ try {
10
+ const hostRoot = process.cwd();
11
+ const vscodeDir = path.join(hostRoot, '.vscode');
12
+
13
+ console.log('🐬 [Dolphin Client CLI] Setting up VS Code autocomplete...');
14
+
15
+ // 1. Ensure .vscode directory exists in user's current directory
16
+ if (!fs.existsSync(vscodeDir)) {
17
+ fs.mkdirSync(vscodeDir, { recursive: true });
18
+ console.log(' - Created .vscode directory.');
19
+ }
20
+
21
+ // 2. Copy the dolphin-tags.json file from the npm package to the user's project
22
+ const sourceTags = path.resolve(__dirname, '../.vscode/dolphin-tags.json');
23
+ const destTags = path.join(vscodeDir, 'dolphin-tags.json');
24
+
25
+ if (fs.existsSync(sourceTags)) {
26
+ fs.copyFileSync(sourceTags, destTags);
27
+ console.log(' - Copied dolphin-tags.json config.');
28
+ } else {
29
+ console.warn(' ⚠️ Warning: dolphin-tags.json source file not found.');
30
+ }
31
+
32
+ // 3. Register the path in the user's project settings.json
33
+ const settingsPath = path.join(vscodeDir, 'settings.json');
34
+ let settings = {};
35
+ if (fs.existsSync(settingsPath)) {
36
+ try {
37
+ settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
38
+ } catch (e) {
39
+ settings = {};
40
+ }
41
+ }
42
+
43
+ if (!settings['html.customData']) {
44
+ settings['html.customData'] = [];
45
+ }
46
+
47
+ const relativePath = '.vscode/dolphin-tags.json';
48
+ if (!settings['html.customData'].includes(relativePath)) {
49
+ settings['html.customData'].push(relativePath);
50
+ fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
51
+ console.log(' - Registered custom HTML data in settings.json.');
52
+ } else {
53
+ console.log(' - dolphin-tags.json was already registered.');
54
+ }
55
+
56
+ console.log('\n\x1b[36m%s\x1b[0m', '✅ [Success] VS Code autocomplete successfully set up for Dolphin Client!');
57
+ console.log('\x1b[33m%s\x1b[0m', '👉 Tip: Run "Developer: Reload Window" in VS Code to activate autocomplete.');
58
+ } catch (err) {
59
+ console.error('❌ [Error] Failed to set up VS Code autocomplete:', err.message);
60
+ }