nuxt-files-sdk 0.0.3 → 0.0.5

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.
Files changed (48) hide show
  1. package/README.md +17 -2
  2. package/dist/config.d.ts +15 -1
  3. package/dist/config.js +2 -1
  4. package/dist/config.js.map +1 -1
  5. package/dist/devtools/client/app.js +6 -0
  6. package/dist/devtools/client/index.html +389 -72
  7. package/dist/devtools/devframe.js +60 -7
  8. package/dist/devtools/devframe.js.map +1 -1
  9. package/dist/devtools/diagnostics.d.ts +37 -0
  10. package/dist/devtools/diagnostics.js +39 -0
  11. package/dist/devtools/diagnostics.js.map +1 -0
  12. package/dist/devtools/enabled.d.ts +9 -0
  13. package/dist/devtools/enabled.js +3 -2
  14. package/dist/devtools/enabled.js.map +1 -1
  15. package/dist/devtools/files-read.d.ts +5 -0
  16. package/dist/devtools/files-read.js +7 -0
  17. package/dist/devtools/files-read.js.map +1 -0
  18. package/dist/devtools/files-write.d.ts +5 -0
  19. package/dist/devtools/files-write.js +7 -0
  20. package/dist/devtools/files-write.js.map +1 -0
  21. package/dist/devtools/files.js +48 -0
  22. package/dist/devtools/files.js.map +1 -0
  23. package/dist/devtools/index.js +10 -3
  24. package/dist/devtools/index.js.map +1 -1
  25. package/dist/devtools/nuxt-v3-handler.js +16 -4
  26. package/dist/devtools/nuxt-v3-handler.js.map +1 -1
  27. package/dist/devtools/nuxt-v4.js +37 -6
  28. package/dist/devtools/nuxt-v4.js.map +1 -1
  29. package/dist/devtools/snapshot.d.ts +4 -5
  30. package/dist/devtools/snapshot.js +3 -1
  31. package/dist/devtools/snapshot.js.map +1 -1
  32. package/dist/integration/nitro.d.ts +6 -1
  33. package/dist/integration/nitro.js +38 -14
  34. package/dist/integration/nitro.js.map +1 -1
  35. package/dist/module.d.ts +4 -3
  36. package/dist/module.js +15 -3
  37. package/dist/module.js.map +1 -1
  38. package/dist/package.js +1 -1
  39. package/dist/runtime/registry.d.ts +4 -4
  40. package/dist/runtime/registry.js +46 -15
  41. package/dist/runtime/registry.js.map +1 -1
  42. package/dist/runtime.js +13 -8
  43. package/dist/runtime.js.map +1 -1
  44. package/package.json +7 -12
  45. package/dist/plugins/versioning.d.ts +0 -3
  46. package/dist/plugins/versioning.js +0 -2
  47. package/dist/plugins.d.ts +0 -31
  48. package/dist/plugins.js +0 -16
@@ -6,22 +6,127 @@
6
6
  <title>Files</title>
7
7
  <style>
8
8
  :root {
9
- color-scheme: light dark;
10
- font-family: system-ui, sans-serif;
9
+ color-scheme: light;
10
+ font-family:
11
+ Inter,
12
+ ui-sans-serif,
13
+ system-ui,
14
+ -apple-system,
15
+ BlinkMacSystemFont,
16
+ 'Segoe UI',
17
+ sans-serif;
18
+ --background: #fafafa;
19
+ --surface: #ffffff;
20
+ --surface-muted: #f4f4f5;
21
+ --border: #e4e4e7;
22
+ --text: #18181b;
23
+ --muted: #71717a;
24
+ --accent: #00a96e;
25
+ --accent-soft: #e6f8f1;
26
+ --warning: #b45309;
27
+ --warning-soft: #fff7ed;
28
+ --error: #dc2626;
29
+ --error-soft: #fef2f2;
30
+ }
31
+ @media (prefers-color-scheme: dark) {
32
+ :root {
33
+ color-scheme: dark;
34
+ --background: #09090b;
35
+ --surface: #18181b;
36
+ --surface-muted: #27272a;
37
+ --border: #27272a;
38
+ --text: #f4f4f5;
39
+ --muted: #a1a1aa;
40
+ --accent: #00dc82;
41
+ --accent-soft: #0b3328;
42
+ --warning: #fbbf24;
43
+ --warning-soft: #3a2a12;
44
+ --error: #f87171;
45
+ --error-soft: #3b171c;
46
+ }
47
+ }
48
+ * {
49
+ box-sizing: border-box;
11
50
  }
12
51
  body {
13
52
  margin: 0;
14
- padding: 20px;
15
- background: Canvas;
16
- color: CanvasText;
53
+ min-width: 320px;
54
+ min-height: 100vh;
55
+ background: var(--background);
56
+ color: var(--text);
57
+ font-size: 14px;
58
+ line-height: 1.5;
59
+ -webkit-font-smoothing: antialiased;
60
+ }
61
+ .page-header {
62
+ display: flex;
63
+ align-items: center;
64
+ gap: 12px;
65
+ min-height: 64px;
66
+ padding: 12px 20px;
67
+ border-bottom: 1px solid var(--border);
68
+ background: color-mix(in srgb, var(--surface) 92%, transparent);
69
+ }
70
+ .app-icon {
71
+ display: grid;
72
+ flex: 0 0 auto;
73
+ width: 36px;
74
+ height: 36px;
75
+ place-items: center;
76
+ border: 1px solid color-mix(in srgb, var(--accent) 25%, var(--border));
77
+ border-radius: 9px;
78
+ background: var(--accent-soft);
79
+ color: var(--accent);
80
+ }
81
+ .app-icon svg {
82
+ width: 20px;
83
+ height: 20px;
17
84
  }
18
85
  h1 {
19
- margin: 0 0 4px;
20
- font-size: 20px;
86
+ margin: 0;
87
+ font-size: 15px;
88
+ font-weight: 600;
89
+ letter-spacing: -0.01em;
21
90
  }
22
91
  #summary {
23
- margin: 0 0 20px;
24
- color: GrayText;
92
+ margin: 2px 0 0;
93
+ color: var(--muted);
94
+ font-size: 12px;
95
+ }
96
+ .content {
97
+ display: grid;
98
+ gap: 16px;
99
+ padding: 20px;
100
+ }
101
+ .panel {
102
+ overflow: hidden;
103
+ border: 1px solid var(--border);
104
+ border-radius: 10px;
105
+ background: var(--surface);
106
+ }
107
+ .panel-header {
108
+ display: flex;
109
+ align-items: center;
110
+ justify-content: space-between;
111
+ gap: 12px;
112
+ padding: 12px 14px;
113
+ border-bottom: 1px solid var(--border);
114
+ }
115
+ .panel-title {
116
+ min-width: 0;
117
+ }
118
+ h2 {
119
+ margin: 0;
120
+ font-size: 13px;
121
+ font-weight: 600;
122
+ }
123
+ .panel-description {
124
+ margin: 2px 0 0;
125
+ color: var(--muted);
126
+ font-size: 12px;
127
+ }
128
+ .table-scroll {
129
+ overflow-x: auto;
25
130
  }
26
131
  table {
27
132
  width: 100%;
@@ -29,85 +134,297 @@
29
134
  }
30
135
  th,
31
136
  td {
32
- padding: 10px;
33
- border-bottom: 1px solid color-mix(in srgb, CanvasText 18%, transparent);
137
+ padding: 10px 14px;
138
+ border-bottom: 1px solid var(--border);
34
139
  text-align: left;
140
+ white-space: nowrap;
35
141
  }
36
142
  th {
143
+ background: var(--surface-muted);
144
+ color: var(--muted);
145
+ font-size: 11px;
146
+ font-weight: 500;
147
+ }
148
+ tbody tr:last-child td {
149
+ border-bottom: 0;
150
+ }
151
+ tbody tr:hover {
152
+ background: color-mix(in srgb, var(--surface-muted) 55%, transparent);
153
+ }
154
+ td:nth-child(2),
155
+ td:nth-child(3) {
156
+ font-family: ui-monospace, SFMono-Regular, Consolas, 'Liberation Mono', monospace;
37
157
  font-size: 12px;
38
- color: GrayText;
39
- text-transform: uppercase;
40
158
  }
41
- code {
42
- font-family: ui-monospace, monospace;
159
+ button,
160
+ select,
161
+ .upload-button {
162
+ min-height: 30px;
163
+ border: 1px solid var(--border);
164
+ border-radius: 7px;
165
+ background: var(--surface);
166
+ color: var(--text);
167
+ font: inherit;
168
+ }
169
+ button,
170
+ .upload-button {
171
+ padding: 5px 9px;
172
+ cursor: pointer;
173
+ }
174
+ button:hover,
175
+ .upload-button:hover {
176
+ background: var(--surface-muted);
177
+ }
178
+ button:focus-visible,
179
+ select:focus-visible,
180
+ .upload-button:focus-within {
181
+ outline: 2px solid var(--accent);
182
+ outline-offset: 2px;
183
+ }
184
+ select {
185
+ padding: 4px 28px 4px 9px;
186
+ }
187
+ .browser-actions,
188
+ .actions {
189
+ display: flex;
190
+ align-items: center;
191
+ gap: 8px;
192
+ }
193
+ .upload-button {
194
+ display: inline-flex;
195
+ align-items: center;
196
+ background: var(--accent);
197
+ color: #fff;
198
+ border-color: var(--accent);
199
+ }
200
+ .upload-button:hover {
201
+ background: color-mix(in srgb, var(--accent) 85%, #000);
202
+ }
203
+ .upload-button[hidden] {
204
+ display: none;
205
+ }
206
+ .upload-button input {
207
+ position: absolute;
208
+ width: 1px;
209
+ height: 1px;
210
+ overflow: hidden;
211
+ clip: rect(0, 0, 0, 0);
212
+ }
213
+ .browser-toolbar {
214
+ display: flex;
215
+ align-items: center;
216
+ justify-content: space-between;
217
+ gap: 12px;
218
+ min-height: 44px;
219
+ padding: 6px 14px;
220
+ border-bottom: 1px solid var(--border);
221
+ background: var(--surface-muted);
222
+ }
223
+ #breadcrumbs {
224
+ display: flex;
225
+ align-items: center;
226
+ gap: 6px;
227
+ min-width: 0;
228
+ overflow-x: auto;
229
+ color: var(--muted);
230
+ }
231
+ .breadcrumb,
232
+ .folder,
233
+ .row-action {
234
+ min-height: auto;
235
+ padding: 2px 5px;
236
+ border: 0;
237
+ background: transparent;
238
+ }
239
+ .breadcrumb,
240
+ .folder {
241
+ color: var(--text);
242
+ }
243
+ .folder {
244
+ padding: 0;
245
+ font-weight: 500;
246
+ }
247
+ .row-action {
248
+ color: var(--accent);
249
+ font-size: 12px;
250
+ }
251
+ .file-name {
252
+ max-width: 360px;
253
+ overflow: hidden;
254
+ text-overflow: ellipsis;
255
+ }
256
+ .folder-detail,
257
+ #browser-status {
258
+ color: var(--muted);
259
+ font-size: 12px;
260
+ }
261
+ #browser-status {
262
+ margin: 0;
263
+ padding: 8px 14px;
264
+ border-top: 1px solid var(--border);
265
+ }
266
+ .error-text {
267
+ color: var(--error) !important;
268
+ }
269
+ .access-badge {
270
+ padding: 2px 8px;
271
+ border-radius: 999px;
272
+ background: var(--surface-muted);
273
+ color: var(--muted);
274
+ font-size: 11px;
275
+ white-space: nowrap;
276
+ }
277
+ .access-badge.write {
278
+ background: var(--accent-soft);
279
+ color: var(--accent);
280
+ }
281
+ .status {
282
+ display: inline-flex;
283
+ align-items: center;
284
+ gap: 6px;
285
+ padding: 2px 8px;
286
+ border-radius: 999px;
287
+ font-size: 11px;
288
+ font-weight: 500;
289
+ }
290
+ .status::before {
291
+ width: 6px;
292
+ height: 6px;
293
+ border-radius: 999px;
294
+ background: currentColor;
295
+ content: '';
296
+ }
297
+ .status.success {
298
+ background: var(--accent-soft);
299
+ color: var(--accent);
300
+ }
301
+ .status.idle {
302
+ background: var(--surface-muted);
303
+ color: var(--muted);
304
+ }
305
+ #diagnostics {
306
+ padding: 14px;
307
+ }
308
+ .empty-state {
309
+ color: var(--muted);
310
+ font-size: 12px;
43
311
  }
44
312
  .warning,
45
313
  .error {
46
- padding: 10px;
47
- border-radius: 6px;
48
- background: color-mix(in srgb, orange 16%, Canvas);
314
+ margin: 0 0 8px;
315
+ padding: 10px 12px;
316
+ border: 1px solid color-mix(in srgb, var(--warning) 30%, transparent);
317
+ border-radius: 8px;
318
+ background: var(--warning-soft);
319
+ color: var(--warning);
49
320
  }
50
321
  .error {
51
- background: color-mix(in srgb, red 16%, Canvas);
322
+ border-color: color-mix(in srgb, var(--error) 30%, transparent);
323
+ background: var(--error-soft);
324
+ color: var(--error);
325
+ }
326
+ .warning:last-child,
327
+ .error:last-child {
328
+ margin-bottom: 0;
329
+ }
330
+ @media (max-width: 640px) {
331
+ .page-header,
332
+ .content {
333
+ padding-right: 14px;
334
+ padding-left: 14px;
335
+ }
336
+ .panel-header,
337
+ .browser-toolbar {
338
+ align-items: flex-start;
339
+ flex-direction: column;
340
+ }
341
+ .browser-actions {
342
+ width: 100%;
343
+ flex-wrap: wrap;
344
+ }
52
345
  }
53
346
  </style>
54
347
  </head>
55
348
  <body>
56
- <main>
57
- <h1>Files</h1>
58
- <p id="summary" aria-live="polite">Loading resolved configuration…</p>
59
- <section aria-labelledby="storages-heading">
60
- <h2 id="storages-heading">Storages</h2>
61
- <table>
62
- <thead>
63
- <tr>
64
- <th>Name</th>
65
- <th>Adapter</th>
66
- <th>Plugins</th>
67
- <th>Source</th>
68
- <th>Status</th>
69
- </tr>
70
- </thead>
71
- <tbody id="storages"></tbody>
72
- </table>
349
+ <header class="page-header">
350
+ <span class="app-icon" aria-hidden="true">
351
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75">
352
+ <path
353
+ d="M3.75 6.75A1.75 1.75 0 0 1 5.5 5h4l2 2h7A1.75 1.75 0 0 1 20.25 8.75v8.75a1.75 1.75 0 0 1-1.75 1.75h-13a1.75 1.75 0 0 1-1.75-1.75V6.75Z"
354
+ />
355
+ </svg>
356
+ </span>
357
+ <div>
358
+ <h1>Files</h1>
359
+ <p id="summary" aria-live="polite">Loading resolved configuration…</p>
360
+ </div>
361
+ </header>
362
+ <main class="content">
363
+ <section class="panel" aria-labelledby="browser-heading">
364
+ <header class="panel-header">
365
+ <div class="panel-title">
366
+ <h2 id="browser-heading">File browser</h2>
367
+ <p class="panel-description">Browse and manage the selected development storage.</p>
368
+ </div>
369
+ <div class="browser-actions">
370
+ <span id="access-badge" class="access-badge" hidden></span>
371
+ <select id="storage-select" aria-label="Storage" hidden></select>
372
+ <button id="refresh" type="button">Refresh</button>
373
+ <label class="upload-button" hidden>
374
+ Upload
375
+ <input id="upload" type="file" />
376
+ </label>
377
+ </div>
378
+ </header>
379
+ <nav id="breadcrumbs" class="browser-toolbar" aria-label="Current folder"></nav>
380
+ <div class="table-scroll">
381
+ <table>
382
+ <thead>
383
+ <tr>
384
+ <th>Name</th>
385
+ <th>Size</th>
386
+ <th>Type</th>
387
+ <th>Modified</th>
388
+ <th>Actions</th>
389
+ </tr>
390
+ </thead>
391
+ <tbody id="files"></tbody>
392
+ </table>
393
+ </div>
394
+ <p id="browser-status" aria-live="polite">Loading…</p>
395
+ </section>
396
+ <section class="panel" aria-labelledby="storages-heading">
397
+ <header class="panel-header">
398
+ <div class="panel-title">
399
+ <h2 id="storages-heading">Storages</h2>
400
+ <p class="panel-description">Resolved adapters and runtime initialization status.</p>
401
+ </div>
402
+ </header>
403
+ <div class="table-scroll">
404
+ <table>
405
+ <thead>
406
+ <tr>
407
+ <th>Name</th>
408
+ <th>Adapter</th>
409
+ <th>Plugins</th>
410
+ <th>Source</th>
411
+ <th>Status</th>
412
+ </tr>
413
+ </thead>
414
+ <tbody id="storages"></tbody>
415
+ </table>
416
+ </div>
73
417
  </section>
74
- <section aria-labelledby="diagnostics-heading">
75
- <h2 id="diagnostics-heading">Diagnostics</h2>
76
- <div id="diagnostics"></div>
418
+ <section class="panel" aria-labelledby="diagnostics-heading">
419
+ <header class="panel-header">
420
+ <div class="panel-title">
421
+ <h2 id="diagnostics-heading">Diagnostics</h2>
422
+ <p class="panel-description">Integration issues detected by the current development server.</p>
423
+ </div>
424
+ </header>
425
+ <div id="diagnostics" class="empty-state"></div>
77
426
  </section>
78
427
  </main>
79
- <script type="module">
80
- const snapshot = await fetch('./snapshot').then((response) => response.json())
81
- document.querySelector('#summary').textContent =
82
- `${snapshot.storages.length} configured storage${snapshot.storages.length === 1 ? '' : 's'}`
83
- document.querySelector('#storages').replaceChildren(
84
- ...snapshot.storages.map((storage) => {
85
- const row = document.createElement('tr')
86
- for (const value of [
87
- storage.name ?? 'Single storage',
88
- storage.adapter,
89
- storage.plugins.join(', ') || '—',
90
- storage.source,
91
- storage.initialized ? 'Initialized' : 'Not initialized',
92
- ]) {
93
- const cell = document.createElement('td')
94
- cell.textContent = value
95
- row.append(cell)
96
- }
97
- return row
98
- }),
99
- )
100
- const diagnostics = document.querySelector('#diagnostics')
101
- if (!snapshot.diagnostics.length) diagnostics.textContent = 'No integration diagnostics.'
102
- else
103
- diagnostics.replaceChildren(
104
- ...snapshot.diagnostics.map((item) => {
105
- const message = document.createElement('p')
106
- message.className = item.level
107
- message.textContent = `${item.code}: ${item.message}`
108
- return message
109
- }),
110
- )
111
- </script>
428
+ <script type="module" src="./app.js"></script>
112
429
  </body>
113
430
  </html>
@@ -1,9 +1,17 @@
1
+ import { FILES_DEVTOOLS_DIAGNOSTICS, createFilesDevtoolsDiagnostic, isFilesDevtoolsDiagnostic, isFilesDevtoolsFailure } from "./diagnostics.js";
1
2
  import { FILES_DEVTOOLS_PATH } from "./snapshot.js";
2
3
  import { version } from "../package.js";
3
4
  import { fileURLToPath } from "node:url";
4
- import { defineDevframe } from "devframe";
5
+ import { defineDevframe, defineRpcFunction } from "devframe";
5
6
  //#region src/devtools/devframe.ts
6
- var devframe_default = defineDevframe({
7
+ const clientAssets = fileURLToPath(new URL("./client", import.meta.url));
8
+ const messageTitles = {
9
+ upload: "Files upload failed",
10
+ delete: "Files delete failed",
11
+ initialization: "Files storage initialization failed",
12
+ gateway: "Files DevTools gateway failed"
13
+ };
14
+ const createFilesDevframe = ({ write, maxUploadSize, notifyFailure }) => defineDevframe({
7
15
  id: "nuxt-files-sdk",
8
16
  name: "Files",
9
17
  version,
@@ -12,13 +20,58 @@ var devframe_default = defineDevframe({
12
20
  homepage: "https://github.com/liria24/nuxt-files-sdk",
13
21
  description: "Files SDK storage and integration diagnostics for Nuxt.",
14
22
  icon: "ph:files-duotone",
15
- basePath: FILES_DEVTOOLS_PATH,
16
- cli: { distDir: fileURLToPath(new URL("./client", import.meta.url)) },
17
- setup(context) {
18
- context.views.hostStatic(FILES_DEVTOOLS_PATH, fileURLToPath(new URL("./client", import.meta.url)));
23
+ clientAssets,
24
+ async setup(context) {
25
+ await context.host.mountConnectionMeta?.(FILES_DEVTOOLS_PATH);
26
+ context.views.hostStatic(FILES_DEVTOOLS_PATH, clientAssets);
27
+ const definitions = Object.fromEntries(Object.entries(FILES_DEVTOOLS_DIAGNOSTICS).map(([code, diagnostic]) => [code, {
28
+ why: ({ message }) => message ?? diagnostic.message,
29
+ fix: diagnostic.hint,
30
+ docs: diagnostic.docs
31
+ }]));
32
+ const diagnostics = context.diagnostics.defineDiagnostics({ codes: definitions });
33
+ context.diagnostics.register(diagnostics);
34
+ const reported = /* @__PURE__ */ new Set();
35
+ const reportDiagnostic = (diagnostic, cause) => {
36
+ const key = `${diagnostic.code}:${diagnostic.message}`;
37
+ if (reported.has(key)) return;
38
+ reported.add(key);
39
+ diagnostics[diagnostic.code]?.({
40
+ message: diagnostic.message,
41
+ ...cause === void 0 ? {} : { cause }
42
+ }, { method: diagnostic.level === "info" ? "log" : diagnostic.level === "warning" ? "warn" : "error" });
43
+ };
44
+ const scoped = context.scope("nuxt-files-sdk");
45
+ scoped.rpc.register(defineRpcFunction({
46
+ name: "report-diagnostics",
47
+ type: "event",
48
+ handler(value) {
49
+ if (Array.isArray(value)) value.filter(isFilesDevtoolsDiagnostic).forEach((item) => reportDiagnostic(item));
50
+ }
51
+ }));
52
+ scoped.rpc.register(defineRpcFunction({
53
+ name: "report-failure",
54
+ type: "event",
55
+ handler(value) {
56
+ if (!isFilesDevtoolsFailure(value)) return;
57
+ if (!write && (value.kind === "upload" || value.kind === "delete")) return;
58
+ const description = value.kind === "upload" ? `${value.message}\nMaximum upload size: ${maxUploadSize} bytes.` : value.message;
59
+ notifyFailure({
60
+ id: `nuxt-files-sdk:${value.kind}:${value.target ?? "default"}`,
61
+ message: messageTitles[value.kind],
62
+ level: "error",
63
+ description,
64
+ category: "nuxt-files-sdk",
65
+ labels: ["nuxt-files-sdk", value.kind],
66
+ notify: true
67
+ });
68
+ if (value.kind === "initialization") reportDiagnostic(createFilesDevtoolsDiagnostic("NUXT_FILES_ADAPTER_INIT_FAILED"), value.message);
69
+ else if (value.kind === "gateway") reportDiagnostic(createFilesDevtoolsDiagnostic("NUXT_FILES_GATEWAY_FAILED"), value.message);
70
+ }
71
+ }));
19
72
  }
20
73
  });
21
74
  //#endregion
22
- export { devframe_default as default };
75
+ export { createFilesDevframe };
23
76
 
24
77
  //# sourceMappingURL=devframe.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"devframe.js","names":[],"sources":["../../src/devtools/devframe.ts"],"sourcesContent":["import { fileURLToPath } from 'node:url'\n\nimport { defineDevframe } from 'devframe'\n\nimport { version } from '../../package.json'\nimport { FILES_DEVTOOLS_PATH } from './snapshot'\n\nexport default defineDevframe({\n id: 'nuxt-files-sdk',\n name: 'Files',\n version,\n packageName: 'nuxt-files-sdk',\n importMetaUrl: import.meta.url,\n homepage: 'https://github.com/liria24/nuxt-files-sdk',\n description: 'Files SDK storage and integration diagnostics for Nuxt.',\n icon: 'ph:files-duotone',\n basePath: FILES_DEVTOOLS_PATH,\n cli: { distDir: fileURLToPath(new URL('./client', import.meta.url)) },\n setup(context) {\n context.views.hostStatic(FILES_DEVTOOLS_PATH, fileURLToPath(new URL('./client', import.meta.url)))\n },\n})\n"],"mappings":";;;;;AAOA,IAAA,mBAAe,eAAe;CAC1B,IAAI;CACJ,MAAM;CACN;CACA,aAAa;CACb,eAAe,YAAY;CAC3B,UAAU;CACV,aAAa;CACb,MAAM;CACN,UAAU;CACV,KAAK,EAAE,SAAS,cAAc,IAAI,IAAI,YAAY,YAAY,GAAG,CAAC,EAAE;CACpE,MAAM,SAAS;EACX,QAAQ,MAAM,WAAW,qBAAqB,cAAc,IAAI,IAAI,YAAY,YAAY,GAAG,CAAC,CAAC;CACrG;AACJ,CAAC"}
1
+ {"version":3,"file":"devframe.js","names":[],"sources":["../../src/devtools/devframe.ts"],"sourcesContent":["import { fileURLToPath } from 'node:url'\n\nimport { defineDevframe, defineRpcFunction } from 'devframe'\n\nimport { version } from '../../package.json'\nimport {\n createFilesDevtoolsDiagnostic,\n FILES_DEVTOOLS_DIAGNOSTICS,\n isFilesDevtoolsDiagnostic,\n isFilesDevtoolsFailure,\n type FilesDevtoolsDiagnostic,\n} from './diagnostics'\nimport { FILES_DEVTOOLS_PATH } from './snapshot'\n\ninterface FilesDevframeMessage {\n id: string\n message: string\n level: 'error'\n description: string\n category: string\n labels: string[]\n notify: true\n}\n\nexport interface FilesDevframeOptions {\n write: boolean\n maxUploadSize: number\n notifyFailure: (message: FilesDevframeMessage) => unknown\n}\n\nconst clientAssets = fileURLToPath(new URL('./client', import.meta.url))\nconst messageTitles = {\n upload: 'Files upload failed',\n delete: 'Files delete failed',\n initialization: 'Files storage initialization failed',\n gateway: 'Files DevTools gateway failed',\n} as const\n\nexport const createFilesDevframe = ({ write, maxUploadSize, notifyFailure }: FilesDevframeOptions) =>\n defineDevframe({\n id: 'nuxt-files-sdk',\n name: 'Files',\n version,\n packageName: 'nuxt-files-sdk',\n importMetaUrl: import.meta.url,\n homepage: 'https://github.com/liria24/nuxt-files-sdk',\n description: 'Files SDK storage and integration diagnostics for Nuxt.',\n icon: 'ph:files-duotone',\n clientAssets,\n async setup(context) {\n await context.host.mountConnectionMeta?.(FILES_DEVTOOLS_PATH)\n context.views.hostStatic(FILES_DEVTOOLS_PATH, clientAssets)\n\n const definitions = Object.fromEntries(\n Object.entries(FILES_DEVTOOLS_DIAGNOSTICS).map(([code, diagnostic]) => [\n code,\n {\n why: ({ message }: { message?: string }) => message ?? diagnostic.message,\n fix: diagnostic.hint,\n docs: diagnostic.docs,\n },\n ]),\n )\n const diagnostics = context.diagnostics.defineDiagnostics({ codes: definitions })\n context.diagnostics.register(diagnostics)\n const reported = new Set<string>()\n const reportDiagnostic = (diagnostic: FilesDevtoolsDiagnostic, cause?: unknown): void => {\n const key = `${diagnostic.code}:${diagnostic.message}`\n if (reported.has(key)) return\n reported.add(key)\n diagnostics[diagnostic.code]?.(\n { message: diagnostic.message, ...(cause === undefined ? {} : { cause }) },\n { method: diagnostic.level === 'info' ? 'log' : diagnostic.level === 'warning' ? 'warn' : 'error' },\n )\n }\n\n const scoped = context.scope('nuxt-files-sdk')\n scoped.rpc.register(\n defineRpcFunction({\n name: 'report-diagnostics',\n type: 'event',\n handler(value: unknown) {\n if (Array.isArray(value))\n value.filter(isFilesDevtoolsDiagnostic).forEach((item) => reportDiagnostic(item))\n },\n }),\n )\n scoped.rpc.register(\n defineRpcFunction({\n name: 'report-failure',\n type: 'event',\n handler(value: unknown) {\n if (!isFilesDevtoolsFailure(value)) return\n if (!write && (value.kind === 'upload' || value.kind === 'delete')) return\n const description =\n value.kind === 'upload'\n ? `${value.message}\\nMaximum upload size: ${maxUploadSize} bytes.`\n : value.message\n void notifyFailure({\n id: `nuxt-files-sdk:${value.kind}:${value.target ?? 'default'}`,\n message: messageTitles[value.kind],\n level: 'error',\n description,\n category: 'nuxt-files-sdk',\n labels: ['nuxt-files-sdk', value.kind],\n notify: true,\n })\n if (value.kind === 'initialization') {\n reportDiagnostic(\n createFilesDevtoolsDiagnostic('NUXT_FILES_ADAPTER_INIT_FAILED'),\n value.message,\n )\n } else if (value.kind === 'gateway') {\n reportDiagnostic(createFilesDevtoolsDiagnostic('NUXT_FILES_GATEWAY_FAILED'), value.message)\n }\n },\n }),\n )\n },\n })\n"],"mappings":";;;;;;AA8BA,MAAM,eAAe,cAAc,IAAI,IAAI,YAAY,YAAY,GAAG,CAAC;AACvE,MAAM,gBAAgB;CAClB,QAAQ;CACR,QAAQ;CACR,gBAAgB;CAChB,SAAS;AACb;AAEA,MAAa,uBAAuB,EAAE,OAAO,eAAe,oBACxD,eAAe;CACX,IAAI;CACJ,MAAM;CACN;CACA,aAAa;CACb,eAAe,YAAY;CAC3B,UAAU;CACV,aAAa;CACb,MAAM;CACN;CACA,MAAM,MAAM,SAAS;EACjB,MAAM,QAAQ,KAAK,sBAAsB,mBAAmB;EAC5D,QAAQ,MAAM,WAAW,qBAAqB,YAAY;EAE1D,MAAM,cAAc,OAAO,YACvB,OAAO,QAAQ,0BAA0B,CAAC,CAAC,KAAK,CAAC,MAAM,gBAAgB,CACnE,MACA;GACI,MAAM,EAAE,cAAoC,WAAW,WAAW;GAClE,KAAK,WAAW;GAChB,MAAM,WAAW;EACrB,CACJ,CAAC,CACL;EACA,MAAM,cAAc,QAAQ,YAAY,kBAAkB,EAAE,OAAO,YAAY,CAAC;EAChF,QAAQ,YAAY,SAAS,WAAW;EACxC,MAAM,2BAAW,IAAI,IAAY;EACjC,MAAM,oBAAoB,YAAqC,UAA0B;GACrF,MAAM,MAAM,GAAG,WAAW,KAAK,GAAG,WAAW;GAC7C,IAAI,SAAS,IAAI,GAAG,GAAG;GACvB,SAAS,IAAI,GAAG;GAChB,YAAY,WAAW,KAAK,GACxB;IAAE,SAAS,WAAW;IAAS,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;GAAG,GACzE,EAAE,QAAQ,WAAW,UAAU,SAAS,QAAQ,WAAW,UAAU,YAAY,SAAS,QAAQ,CACtG;EACJ;EAEA,MAAM,SAAS,QAAQ,MAAM,gBAAgB;EAC7C,OAAO,IAAI,SACP,kBAAkB;GACd,MAAM;GACN,MAAM;GACN,QAAQ,OAAgB;IACpB,IAAI,MAAM,QAAQ,KAAK,GACnB,MAAM,OAAO,yBAAyB,CAAC,CAAC,SAAS,SAAS,iBAAiB,IAAI,CAAC;GACxF;EACJ,CAAC,CACL;EACA,OAAO,IAAI,SACP,kBAAkB;GACd,MAAM;GACN,MAAM;GACN,QAAQ,OAAgB;IACpB,IAAI,CAAC,uBAAuB,KAAK,GAAG;IACpC,IAAI,CAAC,UAAU,MAAM,SAAS,YAAY,MAAM,SAAS,WAAW;IACpE,MAAM,cACF,MAAM,SAAS,WACT,GAAG,MAAM,QAAQ,yBAAyB,cAAc,WACxD,MAAM;IAChB,cAAmB;KACf,IAAI,kBAAkB,MAAM,KAAK,GAAG,MAAM,UAAU;KACpD,SAAS,cAAc,MAAM;KAC7B,OAAO;KACP;KACA,UAAU;KACV,QAAQ,CAAC,kBAAkB,MAAM,IAAI;KACrC,QAAQ;IACZ,CAAC;IACD,IAAI,MAAM,SAAS,kBACf,iBACI,8BAA8B,gCAAgC,GAC9D,MAAM,OACV;SACG,IAAI,MAAM,SAAS,WACtB,iBAAiB,8BAA8B,2BAA2B,GAAG,MAAM,OAAO;GAElG;EACJ,CAAC,CACL;CACJ;AACJ,CAAC"}
@@ -0,0 +1,37 @@
1
+ //#region src/devtools/diagnostics.d.ts
2
+ export interface FilesDevtoolsDiagnostic {
3
+ code: FilesDevtoolsDiagnosticCode;
4
+ level: 'info' | 'warning' | 'error';
5
+ message: string;
6
+ hint?: string;
7
+ docs?: string;
8
+ }
9
+ export declare const FILES_DEVTOOLS_DIAGNOSTICS: {
10
+ readonly NUXT_FILES_NOT_CONFIGURED: {
11
+ readonly level: 'warning';
12
+ readonly message: 'The Files registry has not been configured.';
13
+ readonly hint: 'Check that files.config.ts is loaded by the Nuxt or Nitro integration.';
14
+ readonly docs: "https://github.com/liria24/nuxt-files-sdk/blob/main/docs/content/4.reference/4.troubleshooting.md";
15
+ };
16
+ readonly NUXT_FILES_INVALID_CONFIG: {
17
+ readonly level: 'error';
18
+ readonly message: 'The Files registry rejected the storage configuration.';
19
+ readonly hint: 'Check the storage and devStorage shapes in files.config.ts.';
20
+ readonly docs: "https://github.com/liria24/nuxt-files-sdk/blob/main/docs/content/4.reference/4.troubleshooting.md";
21
+ };
22
+ readonly NUXT_FILES_ADAPTER_INIT_FAILED: {
23
+ readonly level: 'error';
24
+ readonly message: 'A configured storage adapter could not be initialized.';
25
+ readonly hint: 'Check the provider package, runtime support, and required configuration.';
26
+ readonly docs: "https://github.com/liria24/nuxt-files-sdk/blob/main/docs/content/4.reference/4.troubleshooting.md";
27
+ };
28
+ readonly NUXT_FILES_GATEWAY_FAILED: {
29
+ readonly level: 'error';
30
+ readonly message: 'The Files DevTools gateway could not complete a request.';
31
+ readonly hint: 'Check the Nitro development server and the Files registry diagnostics.';
32
+ readonly docs: "https://github.com/liria24/nuxt-files-sdk/blob/main/docs/content/4.reference/4.troubleshooting.md";
33
+ };
34
+ };
35
+ export type FilesDevtoolsDiagnosticCode = keyof typeof FILES_DEVTOOLS_DIAGNOSTICS;
36
+ //#endregion
37
+ //# sourceMappingURL=diagnostics.d.ts.map