webhanger 1.0.1 → 1.0.4

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 CHANGED
@@ -1,26 +1,51 @@
1
- # webhanger
1
+ # WebHanger
2
2
 
3
- Component-as-a-Service platform. Bundle UI components once, deliver them securely across any website via edge CDN.
3
+ > **Component-as-a-Service (CaaS)** Bundle once. Encrypt with AES-256. Deliver via edge CDN. Load anywhere with zero code.
4
+
5
+ WebHanger is a secure, edge-delivered component distribution platform. Think of it as npm for UI components — but instead of installing packages, you deploy encrypted components to a CDN and load them into any website with a single HTML tag.
4
6
 
5
7
  ---
6
8
 
7
- ## Install
9
+ ## Packages
10
+
11
+ | Package | Install | Description |
12
+ |---|---|---|
13
+ | `webhanger` | `npm install -g webhanger` | CLI + Node.js library |
14
+ | `webhanger-front` | `npm install webhanger-front` | Browser SDK |
15
+
16
+ ---
17
+
18
+ ## Quick Start
8
19
 
9
20
  ```bash
10
- # CLI (global)
21
+ # 1. Install CLI
11
22
  npm install -g webhanger
12
23
 
13
- # Node.js library
14
- npm install webhanger
24
+ # 2. Setup your project (provisions S3 + CloudFront automatically)
25
+ wh init
26
+
27
+ # 3. Deploy all components, build site, zip for upload — one command
28
+ wh ship ./components ./docs 1.0.0 ./dist
29
+ ```
30
+
31
+ Load in any website — zero JS required:
32
+
33
+ ```html
34
+ <script src="https://unpkg.com/webhanger-front@latest/browser.min.js"></script>
35
+ <script>WebHangerFront.initialize("./wh-manifest.json");</script>
36
+
37
+ <wh-component name="navbar"></wh-component>
38
+ <wh-component name="hero"></wh-component>
39
+ <wh-component name="footer"></wh-component>
15
40
  ```
16
41
 
17
42
  ---
18
43
 
19
- ## CLI
44
+ ## CLI Reference
20
45
 
21
46
  ### `wh init`
22
47
 
23
- Interactive setup. Provisions your storage + CDN + database.
48
+ Interactive project setup. Provisions infrastructure automatically.
24
49
 
25
50
  ```bash
26
51
  wh init
@@ -30,147 +55,483 @@ Prompts:
30
55
  - Project name
31
56
  - Storage provider: `s3` | `r2` | `minio` | `local`
32
57
  - Database provider: `firebase` | `supabase` | `mongodb`
33
- - Credentials for each
58
+ - Credentials
59
+
60
+ For **S3**: automatically creates the bucket, configures CORS + versioning, spins up a CloudFront distribution. No AWS Console needed.
61
+
62
+ Optional: setup Cloudflare Edge Worker for token validation + geo routing at the edge.
63
+
64
+ Generates `webhanger.config.json`.
65
+
66
+ ---
67
+
68
+ ### `wh ship` ⭐ The main command
69
+
70
+ Deploy + build + zip in one shot.
71
+
72
+ ```bash
73
+ wh ship <components-dir> <site-dir> [version] [out-dir]
74
+ ```
75
+
76
+ ```bash
77
+ wh ship ./components ./docs 1.0.0 ./dist
78
+ ```
79
+
80
+ What it does:
81
+ 1. Deploys all components (bundle → AES encrypt → upload → sign → register)
82
+ 2. Resolves dependency graph
83
+ 3. Writes `wh-manifest.json` (no sensitive data in HTML)
84
+ 4. Production builds the site (minify HTML, inline CSS/JS)
85
+ 5. Zips output for direct upload
34
86
 
35
- For `s3` — automatically creates the S3 bucket, configures CORS, versioning, and spins up a CloudFront distribution. No manual AWS Console steps needed.
87
+ ```
88
+ 🚀 [1/4] Deploying components...
89
+ navbar@1.0.0... ✅
90
+ hero@1.0.0... ✅
91
+
92
+ 🔍 [2/4] Resolving dependency graph...
36
93
 
37
- Generates `webhanger.config.json` in your project root.
94
+ 🏗️ [3/4] Building ./docs ./dist...
95
+ index.html 4.2 kB
96
+
97
+ 📦 [4/4] Zipping ./dist...
98
+
99
+ ✅ Ship complete!
100
+ Deploy zip: ./deploy.zip (12.4 kB)
101
+ ```
102
+
103
+ Upload `deploy.zip` to Netlify, S3, cPanel, or any static host.
38
104
 
39
105
  ---
40
106
 
41
107
  ### `wh deploy`
42
108
 
43
- Bundle and deploy a component.
109
+ Deploy a single component.
44
110
 
45
111
  ```bash
46
112
  wh deploy <component-dir> <name> <version>
113
+ wh deploy ./components/navbar navbar 1.0.0
47
114
  ```
48
115
 
116
+ Prompts for token (auto-generate or custom) and expiry (never or seconds).
117
+
118
+ ---
119
+
120
+ ### `wh graph-deploy`
121
+
122
+ Deploy all components in a directory and resolve the dependency graph.
123
+
49
124
  ```bash
50
- wh deploy ./components/navbar navbar 1.0.0
125
+ wh graph-deploy <components-dir> [version] [out-dir]
126
+ wh graph-deploy ./components 1.0.0 ./output
51
127
  ```
52
128
 
53
- Your component folder should contain any of:
54
- - `index.html` — markup
55
- - `style.css` — styles
56
- - `script.js` — behaviour
129
+ ---
57
130
 
58
- All three are bundled into a single encrypted payload, uploaded to your storage, and registered in your database.
131
+ ### `wh build`
59
132
 
60
- You'll be asked:
61
- - Custom token? (or auto-generate)
62
- - Set expiry? (or never expire)
133
+ Production build — minifies HTML, inlines local CSS/JS.
63
134
 
64
- Output:
135
+ ```bash
136
+ wh build <src-dir> [out-dir]
137
+ wh build ./docs ./dist
65
138
  ```
66
- ✅ Deployed successfully!
67
- 📦 CDN URL : https://xxx.cloudfront.net/components/navbar@1.0.0.js
68
- 🔐 Token : abc123...
69
- ⏱ Expires : 0 (never)
139
+
140
+ ---
141
+
142
+ ### `wh zip`
143
+
144
+ Zip a directory for deployment.
145
+
146
+ ```bash
147
+ wh zip <src-dir> [out-file]
148
+ wh zip ./dist ./deploy.zip
70
149
  ```
71
150
 
72
151
  ---
73
152
 
74
- ## Node.js API
153
+ ### `wh analyze`
154
+
155
+ Detect framework, styling approach, and CDN dependencies automatically.
156
+
157
+ ```bash
158
+ wh analyze ./components/navbar
159
+ ```
160
+
161
+ ```
162
+ 🔍 Component Analysis
163
+
164
+ Framework : vanilla
165
+ Styling : tailwind
166
+ Imports : gsap, axios
167
+ CDN Assets:
168
+ [script] https://cdn.tailwindcss.com
169
+ [script] https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js
170
+ ```
171
+
172
+ ---
173
+
174
+ ### `wh convert`
175
+
176
+ Convert a vanilla HTML/CSS/JS component to any framework.
177
+
178
+ ```bash
179
+ wh convert <dir> <name> <target> [out-dir]
180
+ wh convert ./components/navbar navbar react ./output
181
+ ```
182
+
183
+ Supported targets: `react` `vue` `svelte` `next` `angular` `astro`
184
+
185
+ ---
186
+
187
+ ### `wh access`
188
+
189
+ Role-based access control for teams.
190
+
191
+ ```bash
192
+ wh access grant # generate API key with role
193
+ wh access revoke <key> # revoke a key
194
+ wh access list # list all keys
195
+ ```
196
+
197
+ Roles:
198
+
199
+ | Role | deploy | read | delete | manage_access |
200
+ |---|---|---|---|---|
201
+ | owner | ✅ | ✅ | ✅ | ✅ |
202
+ | admin | ✅ | ✅ | ✅ | ✅ |
203
+ | deployer | ✅ | ✅ | ❌ | ❌ |
204
+ | viewer | ❌ | ✅ | ❌ | ❌ |
205
+
206
+ ---
207
+
208
+ ### `wh edge-init`
209
+
210
+ Setup Cloudflare Edge Worker for production-grade delivery.
211
+
212
+ ```bash
213
+ wh edge-init
214
+ # then:
215
+ cd edge && wrangler deploy
216
+ ```
217
+
218
+ ---
219
+
220
+ ## Component Structure
221
+
222
+ ```
223
+ components/
224
+ navbar/
225
+ index.html ← markup
226
+ style.css ← styles
227
+ script.js ← behaviour
228
+ webhanger.component.json ← assets + dependencies
229
+ ```
230
+
231
+ ### `webhanger.component.json`
232
+
233
+ ```json
234
+ {
235
+ "assets": [
236
+ { "type": "script", "url": "https://cdn.tailwindcss.com" },
237
+ { "type": "script", "url": "https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js" }
238
+ ],
239
+ "dependencies": ["navbar@1.0.0", "chart@2.0.0"]
240
+ }
241
+ ```
242
+
243
+ CDN assets are auto-detected by `wh analyze` and merged automatically on deploy.
244
+
245
+ ---
246
+
247
+ ## Dependency Graph
248
+
249
+ npm-like dependency resolution for UI components.
250
+
251
+ ```
252
+ dashboard@1.0.0
253
+ ├── navbar@1.0.0
254
+ └── statsbar@1.0.0
255
+ └── chart@1.0.0
256
+ ```
257
+
258
+ - Depth-first resolution
259
+ - Circular dependency detection with full chain error
260
+ - Deps load before parent component
261
+ - Stored in Firestore per project
262
+
263
+ ```bash
264
+ wh graph-deploy ./components 1.0.0 ./output
265
+ ```
266
+
267
+ Programmatic:
75
268
 
76
269
  ```js
77
- import { WebHanger } from "webhanger";
270
+ import { resolveGraph } from "webhanger";
271
+ const graph = await resolveGraph(config.db, projectId, "dashboard", "1.0.0");
272
+ // Returns: [chart, navbar, statsbar, dashboard] — deps first
273
+ ```
274
+
275
+ ---
276
+
277
+ ## Security
278
+
279
+ ### AES-256-GCM Encryption
280
+
281
+ Every component chunk (HTML/CSS/JS) is encrypted before upload.
282
+
283
+ ```
284
+ Key = SHA-256(projectId + salt)
285
+ Payload = iv:tag:ciphertext (base64)
286
+ Salts = "::html" | "::css" | "::js"
287
+ ```
288
+
289
+ ### HMAC-SHA256 Signed URLs
78
290
 
79
- const wh = new WebHanger();
80
291
  ```
292
+ token = HMAC-SHA256(projectId:componentPath:expires, secretKey)
293
+ ```
294
+
295
+ ### Integrity Check
296
+
297
+ SHA-256 hash of raw content stored in payload. Verified after decryption — detects tampering.
81
298
 
82
- ### `wh.deploy(componentDir, name, version, options?)`
299
+ ### Domain Restriction
83
300
 
84
301
  ```js
85
- const result = await wh.deploy("./components/navbar", "navbar", "1.0.0", {
86
- expiresInSeconds: 86400, // optional — omit for no expiry
87
- token: "my-custom-token", // optional — omit to auto-generate
88
- dependencies: ["sidebar@1.0.0"] // optional
302
+ WebHangerFront.load(url, pid, token, 0, "[data-wh]", null, [], {
303
+ allowedDomains: ["mysite.com", "app.io"]
89
304
  });
305
+ ```
306
+
307
+ ### Token Expiry
90
308
 
91
- // result: { cdnUrl, token, expires }
309
+ ```js
310
+ // Never expires
311
+ wh.deploy("./navbar", "navbar", "1.0.0");
312
+
313
+ // Expires in 24 hours
314
+ wh.deploy("./navbar", "navbar", "1.0.0", { expiresInSeconds: 86400 });
92
315
  ```
93
316
 
94
- ### `wh.resolve(name, version?)`
317
+ ### Manifest-based Delivery
95
318
 
96
- Fetch component metadata and verify token.
319
+ Tokens, projectId, and CDN URLs never appear in HTML. Fetched at runtime from `wh-manifest.json`.
97
320
 
98
- ```js
99
- const component = await wh.resolve("navbar", "1.0.0");
100
- // { cdnUrl, token, expires, dependencies }
321
+ ---
322
+
323
+ ## Edge Worker (Cloudflare Workers)
324
+
325
+ Runs at the edge before S3:
326
+
327
+ - HMAC token validation
328
+ - Version resolution (`latest` → `1.2.0` from KV)
329
+ - Geo-based routing (India → ap-south-1, Europe → eu-west-1)
330
+ - Rate limiting (100 req/min per IP)
331
+
332
+ ```bash
333
+ wh init # answer yes to edge worker setup
334
+ cd edge && wrangler deploy
101
335
  ```
102
336
 
103
- ### `wh.resign(name, version, options?)`
337
+ Update `cdn.url` in `webhanger.config.json` to your worker URL — all requests now go through the edge.
338
+
339
+ ---
104
340
 
105
- Rotate token without redeploying the component.
341
+ ## Multi-CDN Failover
342
+
343
+ ```json
344
+ {
345
+ "cdn": {
346
+ "url": "https://primary.cloudfront.net",
347
+ "fallbacks": [
348
+ "https://fallback.r2.dev",
349
+ "https://backup.b-cdn.net"
350
+ ]
351
+ }
352
+ }
353
+ ```
354
+
355
+ SDK tries each URL in order. If primary fails, automatically falls back — zero code changes needed.
356
+
357
+ ---
358
+
359
+ ## Browser SDK
360
+
361
+ ### Zero-code (recommended)
362
+
363
+ ```html
364
+ <script src="https://unpkg.com/webhanger-front@latest/browser.min.js"></script>
365
+ <script>WebHangerFront.initialize("./wh-manifest.json");</script>
366
+
367
+ <wh-component name="navbar"></wh-component>
368
+ <wh-component name="hero"></wh-component>
369
+ <wh-component name="footer" sandbox></wh-component>
370
+ ```
371
+
372
+ ### Manual load
106
373
 
107
374
  ```js
108
- const result = await wh.resign("navbar", "1.0.0", {
109
- expiresInSeconds: 3600
375
+ WebHangerFront.load(
376
+ cdnUrl, // string or array (multi-CDN)
377
+ projectId, // decrypt key
378
+ token, // HMAC token
379
+ expires, // unix timestamp, 0 = never
380
+ selector, // CSS selector, default "[data-wh]"
381
+ onSignal, // optional signal callback
382
+ deps, // optional pre-resolved deps array
383
+ options // optional options object
384
+ );
385
+ ```
386
+
387
+ ### Lifecycle hooks
388
+
389
+ ```js
390
+ WebHangerFront.load(url, pid, token, 0, "[data-wh]", null, [], {
391
+ beforeMount: ({ html }) => showSpinner(),
392
+ afterMount: ({ target }) => hideSpinner(),
393
+ onError: (err) => showFallback(err),
394
+ sandbox: true, // Shadow DOM isolation
395
+ allowedDomains: ["mysite.com"] // domain restriction
110
396
  });
111
- // { cdnUrl, token, expires }
112
397
  ```
113
398
 
114
- ### `wh.remove(name, version)`
399
+ ### Signal callback
115
400
 
116
- Delete a component from storage.
401
+ ```js
402
+ WebHangerFront.load(url, pid, token, 0, "[data-wh]", ({ stage, ...detail }) => {
403
+ // stages: start → fetching → assets → deps → injecting → done | error
404
+ console.log(stage, detail.time, detail.source);
405
+ });
406
+ ```
407
+
408
+ ### Plugin system
117
409
 
118
410
  ```js
119
- await wh.remove("navbar", "1.0.0");
411
+ WebHangerFront.use({
412
+ install({ on, emit }) {
413
+ on("load", ({ time, source }) => analytics.track("load", { time, source }));
414
+ on("error", ({ message }) => errorTracker.capture(message));
415
+ on("metric", ({ name, value }) => dashboard.update(name, value));
416
+ }
417
+ });
120
418
  ```
121
419
 
122
- ### `wh.getConfig()`
420
+ ### Observability
123
421
 
124
- Returns the loaded `webhanger.config.json`.
422
+ ```js
423
+ WebHangerFront.on("load", ({ time, source }) => console.log(time, source));
424
+ WebHangerFront.on("metric", ({ name, value }) => console.log(name, value));
425
+
426
+ console.log(WebHangerFront.metrics);
427
+ // { loads: 5, cacheHits: 3, errors: 0, totalTime: 420 }
428
+ ```
429
+
430
+ ### Hard flush
125
431
 
126
432
  ```js
127
- const config = wh.getConfig();
433
+ await WebHangerFront.clearCache();
434
+ // Clears: localStorage, IndexedDB, SW caches, sessionStorage, unregisters SW
128
435
  ```
129
436
 
130
437
  ---
131
438
 
132
- ## Named exports
439
+ ## Caching
440
+
441
+ | Layer | Used for |
442
+ |---|---|
443
+ | `localStorage` | Components < 50KB |
444
+ | `IndexedDB` | Components ≥ 50KB |
445
+ | Service Worker | Offline fallback |
446
+
447
+ **Stale-while-revalidate** — returns cached version instantly, refreshes in background.
133
448
 
134
- Use individual functions directly without instantiation.
449
+ ---
450
+
451
+ ## Node.js API
452
+
453
+ ```js
454
+ import { WebHanger } from "webhanger";
455
+ const wh = new WebHanger();
456
+
457
+ // Deploy
458
+ const result = await wh.deploy("./components/navbar", "navbar", "1.0.0", {
459
+ expiresInSeconds: 86400, // optional
460
+ token: "custom-token", // optional
461
+ dependencies: ["chart@1.0.0"]
462
+ });
463
+ // { cdnUrl, cdnUrls, token, expires, dependencies }
464
+
465
+ // Resolve
466
+ const comp = await wh.resolve("navbar", "1.0.0");
467
+
468
+ // Rotate token without redeploying
469
+ await wh.resign("navbar", "1.0.0", { expiresInSeconds: 3600 });
470
+
471
+ // Delete from storage
472
+ await wh.remove("navbar", "1.0.0");
473
+
474
+ // Get config
475
+ const config = wh.getConfig();
476
+ ```
477
+
478
+ ### Named exports
135
479
 
136
480
  ```js
137
481
  import {
138
- bundle,
139
- signUrl,
140
- verifyToken,
141
- generateSecretKey,
142
- upload,
143
- remove,
144
- registerComponent,
145
- getComponent,
146
- provisionBucket,
147
- provisionCloudFront,
148
- deploy,
482
+ bundle, encrypt, decrypt, integrityHash,
483
+ signUrl, verifyToken, generateSecretKey,
484
+ upload, remove,
485
+ registerComponent, getComponent,
486
+ deploy, resolveGraph,
487
+ convert, analyzeComponent,
488
+ build,
489
+ grantAccess, revokeAccess, checkPermission, listAccess, generateApiKey,
490
+ provisionBucket, provisionCloudFront,
149
491
  loadConfig
150
492
  } from "webhanger";
151
493
  ```
152
494
 
153
495
  ---
154
496
 
155
- ## webhanger.config.json
497
+ ## Storage Providers
156
498
 
157
- Generated by `wh init`. Keep this file private — never commit it.
499
+ | Provider | Notes |
500
+ |---|---|
501
+ | `s3` | AWS S3 — auto-provisions bucket + CloudFront |
502
+ | `r2` | Cloudflare R2 — zero egress fees |
503
+ | `minio` | Self-hosted MinIO — S3-compatible |
504
+ | `local` | Local disk — dev/testing only |
505
+
506
+ ## Database Providers
507
+
508
+ | Provider | Notes |
509
+ |---|---|
510
+ | `firebase` | Firebase Firestore — free tier, real-time |
511
+ | `supabase` | Supabase Postgres — open source |
512
+ | `mongodb` | MongoDB Atlas — flexible documents |
513
+
514
+ ---
515
+
516
+ ## `webhanger.config.json`
158
517
 
159
518
  ```json
160
519
  {
161
520
  "project": "my-app",
162
521
  "projectId": "wh_1234567890",
163
- "secretKey": "your-secret-key",
522
+ "secretKey": "64-char-hex-secret",
164
523
  "webHangerVersion": "1.0.0",
165
524
  "storage": {
166
525
  "provider": "s3",
167
526
  "accessKey": "...",
168
527
  "secretKey": "...",
169
528
  "bucket": "my-bucket",
170
- "region": "ap-south-1"
529
+ "region": "ap-south-1",
530
+ "distributionId": "EXXXXX"
171
531
  },
172
532
  "cdn": {
173
- "url": "https://xxx.cloudfront.net"
533
+ "url": "https://primary.cloudfront.net",
534
+ "fallbacks": ["https://fallback.r2.dev"]
174
535
  },
175
536
  "db": {
176
537
  "provider": "firebase",
@@ -179,26 +540,55 @@ Generated by `wh init`. Keep this file private — never commit it.
179
540
  }
180
541
  ```
181
542
 
543
+ > Keep this file private. Never commit it. Add to `.gitignore`.
544
+
182
545
  ---
183
546
 
184
- ## Component folder structure
547
+ ## Architecture
185
548
 
186
549
  ```
187
- components/
188
- navbar/
189
- index.html
190
- style.css
191
- script.js
550
+ Developer
551
+ └── wh ship ./components ./docs
552
+ ├── wh analyze → detect Tailwind, GSAP, deps
553
+ ├── wh bundle → html + css + js → single payload
554
+ ├── AES-256-GCM → encrypt each chunk (SHA-256 key)
555
+ ├── SHA-256 hash → integrity fingerprint
556
+ ├── S3 upload → store encrypted payload
557
+ ├── HMAC sign → project-scoped signed URL
558
+ ├── Firestore → register metadata + dep graph
559
+ ├── wh build → minify HTML, inline assets
560
+ └── wh zip → deploy.zip ready for upload
561
+
562
+ Browser
563
+ └── <wh-component name="navbar">
564
+ ├── fetch wh-manifest.json
565
+ ├── check token expiry
566
+ ├── stale-while-revalidate cache
567
+ ├── fetch from CloudFront (or Edge Worker)
568
+ │ └── Edge: validate token + geo route + rate limit
569
+ ├── multi-CDN failover if primary fails
570
+ ├── load CDN assets (Tailwind, GSAP, etc.)
571
+ ├── resolve + load dependency graph
572
+ ├── AES-256-GCM decrypt in memory
573
+ ├── SHA-256 integrity verify
574
+ ├── domain restriction check
575
+ ├── inject CSS → HTML → JS (or Shadow DOM)
576
+ ├── fire lifecycle hooks
577
+ └── emit metrics + plugin events
192
578
  ```
193
579
 
194
- All files are optional except at least one of `index.html` or `script.js`.
580
+ ---
581
+
582
+ ## Real-World Use Cases
583
+
584
+ - **Enterprise micro-frontends** — shared UI across 50+ apps, update once
585
+ - **Education platforms** — push UI updates to all school sites instantly
586
+ - **Low-bandwidth regions** — cache once, serve offline via Service Worker
587
+ - **Security platforms** — inject warnings/banners dynamically across sites
588
+ - **White-label SaaS** — per-tenant component customization
195
589
 
196
590
  ---
197
591
 
198
- ## Security
592
+ ## License
199
593
 
200
- - Every component is encrypted using XOR cipher with `projectId` as the key
201
- - Each chunk (html/css/js) uses a different salt — `::html`, `::css`, `::js`
202
- - CDN URLs are HMAC-SHA256 signed and scoped to your project
203
- - Tokens can carry expiry or be permanent — your choice
204
- - CloudFront forces HTTPS only
594
+ ISC