nuxt-files-sdk 0.0.5 → 0.1.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/LICENSE +1 -1
- package/README.md +35 -9
- package/dist/config/load.js +67 -0
- package/dist/config/load.js.map +1 -0
- package/dist/config/merge.d.ts +5 -0
- package/dist/config/merge.js +22 -0
- package/dist/config/merge.js.map +1 -0
- package/dist/config/prune.js +55 -0
- package/dist/config/prune.js.map +1 -0
- package/dist/config.d.ts +101 -103
- package/dist/config.js +2 -2
- package/dist/config.js.map +1 -1
- package/dist/devtools/auth.js +49 -0
- package/dist/devtools/auth.js.map +1 -0
- package/dist/devtools/client/app.js +6 -4
- package/dist/devtools/client/browser-agent-rpc-BXhoSh1z-DRoP5jHQ.js +1 -0
- package/dist/devtools/client/index.html +4 -1
- package/dist/devtools/devframe.js +7 -1
- package/dist/devtools/devframe.js.map +1 -1
- package/dist/devtools/diagnostics.d.ts +1 -1
- package/dist/devtools/diagnostics.js +1 -1
- package/dist/devtools/diagnostics.js.map +1 -1
- package/dist/devtools/files-read.d.ts +1 -1
- package/dist/devtools/files-write.d.ts +1 -1
- package/dist/devtools/files.js +7 -4
- package/dist/devtools/files.js.map +1 -1
- package/dist/devtools/index.js +24 -6
- package/dist/devtools/index.js.map +1 -1
- package/dist/devtools/nuxt-v3-handler.js +1 -1
- package/dist/devtools/nuxt-v3-handler.js.map +1 -1
- package/dist/devtools/nuxt-v3.js +1 -1
- package/dist/devtools/nuxt-v3.js.map +1 -1
- package/dist/devtools/nuxt-v4.js.map +1 -1
- package/dist/devtools/snapshot.d.ts +8 -2
- package/dist/devtools/snapshot.js +13 -3
- package/dist/devtools/snapshot.js.map +1 -1
- package/dist/devtools/token.d.ts +14 -0
- package/dist/devtools/token.js +17 -0
- package/dist/devtools/token.js.map +1 -0
- package/dist/integration/nitro.d.ts +6 -0
- package/dist/integration/nitro.js +160 -63
- package/dist/integration/nitro.js.map +1 -1
- package/dist/module.d.ts +1 -4
- package/dist/module.js +31 -20
- package/dist/module.js.map +1 -1
- package/dist/nitro.d.ts +2 -4
- package/dist/nitro.js +2 -4
- package/dist/nitro.js.map +1 -1
- package/dist/package.js +1 -1
- package/dist/runtime/internal.d.ts +11 -0
- package/dist/runtime/internal.js +30 -0
- package/dist/runtime/internal.js.map +1 -0
- package/dist/runtime/normalize.js +29 -0
- package/dist/runtime/normalize.js.map +1 -0
- package/dist/runtime/provider-types.d.ts +53 -0
- package/dist/runtime/registry.d.ts +55 -8
- package/dist/runtime/registry.js +125 -89
- package/dist/runtime/registry.js.map +1 -1
- package/dist/runtime.d.ts +8 -9
- package/dist/runtime.js +8 -25
- package/dist/runtime.js.map +1 -1
- package/package.json +25 -14
package/dist/devtools/files.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { inspectFiles
|
|
1
|
+
import { inspectFiles } from "../runtime/internal.js";
|
|
2
|
+
import { useServerFiles } from "../runtime.js";
|
|
3
|
+
import { authorizeFilesDevtoolsRequest } from "./auth.js";
|
|
2
4
|
import { FILES_DEVTOOLS_MAX_UPLOAD_SIZE } from "./snapshot.js";
|
|
3
5
|
import { createFilesRouter } from "files-sdk/api";
|
|
4
6
|
import { createRouteHandler } from "files-sdk/nitro";
|
|
@@ -33,12 +35,13 @@ const createFilesDevtoolsHandler = (write) => {
|
|
|
33
35
|
maxUploadSize: FILES_DEVTOOLS_MAX_UPLOAD_SIZE,
|
|
34
36
|
secret: crypto.randomUUID()
|
|
35
37
|
}));
|
|
36
|
-
return (event) => {
|
|
38
|
+
return async (event, secret) => {
|
|
39
|
+
if (!await authorizeFilesDevtoolsRequest(event.node.req, secret)) return new Response(null, { status: 401 });
|
|
37
40
|
const url = new URL(event.node.req.url ?? "/", "http://nuxt-files-sdk.local");
|
|
38
|
-
if (event.node.req.method === "GET" && url.searchParams.get("op") === "devtools") return
|
|
41
|
+
if (event.node.req.method === "GET" && url.searchParams.get("op") === "devtools") return Response.json({
|
|
39
42
|
write,
|
|
40
43
|
maxUploadSize: FILES_DEVTOOLS_MAX_UPLOAD_SIZE
|
|
41
|
-
})
|
|
44
|
+
});
|
|
42
45
|
return handleFiles(event);
|
|
43
46
|
};
|
|
44
47
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"files.js","names":[],"sources":["../../src/devtools/files.ts"],"sourcesContent":["import type { Files } from 'files-sdk'\nimport { createFilesRouter, type FilesOperation } from 'files-sdk/api'\nimport { createRouteHandler } from 'files-sdk/nitro'\n\nimport {
|
|
1
|
+
{"version":3,"file":"files.js","names":[],"sources":["../../src/devtools/files.ts"],"sourcesContent":["import type { Files } from 'files-sdk'\nimport { createFilesRouter, type FilesOperation } from 'files-sdk/api'\nimport { createRouteHandler } from 'files-sdk/nitro'\n\nimport { useServerFiles } from '../runtime'\nimport { inspectFiles } from '../runtime/internal'\nimport { authorizeFilesDevtoolsRequest } from './auth'\nimport { FILES_DEVTOOLS_MAX_UPLOAD_SIZE } from './snapshot'\n\nconst readOperations = ['capabilities', 'list', 'exists', 'download'] as const satisfies readonly FilesOperation[]\nconst writeOperations = [...readOperations, 'upload', 'delete'] as const satisfies readonly FilesOperation[]\nexport const filesDevtoolsOperations = (write: boolean): readonly FilesOperation[] =>\n write ? writeOperations : readOperations\nconst getFiles: (name?: string) => Files = useServerFiles\n\nconst resolveFiles = (request: Request): Files => {\n const requested = new URL(request.url).searchParams.get('storage') ?? undefined\n const storages = inspectFiles().storages\n if (storages.length === 1 && storages[0]?.name === undefined) {\n if (requested !== undefined) throw new Error(`[nuxt-files-sdk:unknown-storage] Unknown storage \"${requested}\".`)\n return getFiles()\n }\n if (requested === undefined || !storages.some(({ name }) => name === requested)) {\n throw new Error('[nuxt-files-sdk:unknown-storage] Select a configured storage.')\n }\n return getFiles(requested)\n}\n\nexport const createFilesDevtoolsHandler = (write: boolean) => {\n const handleFiles = createRouteHandler(\n createFilesRouter({\n files: resolveFiles,\n operations: filesDevtoolsOperations(write),\n maxUploadSize: FILES_DEVTOOLS_MAX_UPLOAD_SIZE,\n secret: crypto.randomUUID(),\n }),\n )\n return async (event: Parameters<typeof handleFiles>[0], secret: string): Promise<Response> => {\n if (!(await authorizeFilesDevtoolsRequest(event.node.req, secret))) {\n return new Response(null, { status: 401 })\n }\n const url = new URL(event.node.req.url ?? '/', 'http://nuxt-files-sdk.local')\n if (event.node.req.method === 'GET' && url.searchParams.get('op') === 'devtools') {\n return Response.json({ write, maxUploadSize: FILES_DEVTOOLS_MAX_UPLOAD_SIZE })\n }\n return handleFiles(event)\n }\n}\n"],"mappings":";;;;;;;AASA,MAAM,iBAAiB;CAAC;CAAgB;CAAQ;CAAU;AAAU;AACpE,MAAM,kBAAkB;CAAC,GAAG;CAAgB;CAAU;AAAQ;AAC9D,MAAa,2BAA2B,UACpC,QAAQ,kBAAkB;AAC9B,MAAM,WAAqC;AAE3C,MAAM,gBAAgB,YAA4B;CAC9C,MAAM,YAAY,IAAI,IAAI,QAAQ,GAAG,CAAC,CAAC,aAAa,IAAI,SAAS,KAAK,KAAA;CACtE,MAAM,WAAW,aAAa,CAAC,CAAC;CAChC,IAAI,SAAS,WAAW,KAAK,SAAS,EAAE,EAAE,SAAS,KAAA,GAAW;EAC1D,IAAI,cAAc,KAAA,GAAW,MAAM,IAAI,MAAM,qDAAqD,UAAU,GAAG;EAC/G,OAAO,SAAS;CACpB;CACA,IAAI,cAAc,KAAA,KAAa,CAAC,SAAS,MAAM,EAAE,WAAW,SAAS,SAAS,GAC1E,MAAM,IAAI,MAAM,+DAA+D;CAEnF,OAAO,SAAS,SAAS;AAC7B;AAEA,MAAa,8BAA8B,UAAmB;CAC1D,MAAM,cAAc,mBAChB,kBAAkB;EACd,OAAO;EACP,YAAY,wBAAwB,KAAK;EACzC,eAAe;EACf,QAAQ,OAAO,WAAW;CAC9B,CAAC,CACL;CACA,OAAO,OAAO,OAA0C,WAAsC;EAC1F,IAAI,CAAE,MAAM,8BAA8B,MAAM,KAAK,KAAK,MAAM,GAC5D,OAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,IAAI,CAAC;EAE7C,MAAM,MAAM,IAAI,IAAI,MAAM,KAAK,IAAI,OAAO,KAAK,6BAA6B;EAC5E,IAAI,MAAM,KAAK,IAAI,WAAW,SAAS,IAAI,aAAa,IAAI,IAAI,MAAM,YAClE,OAAO,SAAS,KAAK;GAAE;GAAO,eAAe;EAA+B,CAAC;EAEjF,OAAO,YAAY,KAAK;CAC5B;AACJ"}
|
package/dist/devtools/index.js
CHANGED
|
@@ -1,24 +1,42 @@
|
|
|
1
|
-
import { FILES_DEVTOOLS_MAX_UPLOAD_SIZE, FILES_DEVTOOLS_PATH, FILES_GATEWAY_PATH, FILES_SNAPSHOT_PATH } from "./snapshot.js";
|
|
1
|
+
import { FILES_DEVTOOLS_MAX_UPLOAD_SIZE, FILES_DEVTOOLS_PATH, FILES_GATEWAY_PATH, FILES_SNAPSHOT_PATH, FILES_TOKEN_PATH } from "./snapshot.js";
|
|
2
2
|
import nuxt_v3_handler_default from "./nuxt-v3-handler.js";
|
|
3
|
+
import token_default from "./token.js";
|
|
3
4
|
import { setupNuxtV3Devtools } from "./nuxt-v3.js";
|
|
4
5
|
import { setupNuxtV4Devtools } from "./nuxt-v4.js";
|
|
5
|
-
import { addDevServerHandler, addServerHandler } from "@nuxt/kit";
|
|
6
|
+
import { addDevServerHandler, addServerHandler, addServerTemplate } from "@nuxt/kit";
|
|
6
7
|
import { fileURLToPath } from "node:url";
|
|
7
8
|
//#region src/devtools/index.ts
|
|
8
|
-
const
|
|
9
|
+
const authenticatedHandler = (name, path, arguments_) => {
|
|
10
|
+
const filename = `#nuxt-files-sdk/${name}`;
|
|
11
|
+
addServerTemplate({
|
|
12
|
+
filename,
|
|
13
|
+
getContents: () => `import handler from ${JSON.stringify(path.replaceAll("\\", "/"))}\nexport default event => handler(event, ${arguments_.map((value) => JSON.stringify(value)).join(", ")})\n`
|
|
14
|
+
});
|
|
15
|
+
return filename;
|
|
16
|
+
};
|
|
17
|
+
const setupFilesDevtools = (nuxt, version, write, secrets) => {
|
|
9
18
|
addServerHandler({
|
|
10
19
|
route: FILES_SNAPSHOT_PATH,
|
|
11
|
-
handler: fileURLToPath(new URL("./snapshot.js", import.meta.url))
|
|
20
|
+
handler: authenticatedHandler("snapshot", fileURLToPath(new URL("./snapshot.js", import.meta.url)), [secrets.token])
|
|
12
21
|
});
|
|
13
22
|
addServerHandler({
|
|
14
23
|
route: FILES_GATEWAY_PATH,
|
|
15
|
-
handler: fileURLToPath(new URL(write ? "./files-write.js" : "./files-read.js", import.meta.url))
|
|
24
|
+
handler: authenticatedHandler("files", fileURLToPath(new URL(write ? "./files-write.js" : "./files-read.js", import.meta.url)), [secrets.token])
|
|
16
25
|
});
|
|
17
26
|
if (Number.parseInt(version) >= 4) setupNuxtV4Devtools(nuxt, {
|
|
18
27
|
write,
|
|
19
|
-
maxUploadSize: FILES_DEVTOOLS_MAX_UPLOAD_SIZE
|
|
28
|
+
maxUploadSize: FILES_DEVTOOLS_MAX_UPLOAD_SIZE,
|
|
29
|
+
tokenSecret: secrets.token
|
|
20
30
|
});
|
|
21
31
|
else {
|
|
32
|
+
addDevServerHandler({
|
|
33
|
+
route: FILES_TOKEN_PATH,
|
|
34
|
+
handler: (event) => token_default(event, secrets.token, async (token) => {
|
|
35
|
+
const host = "devtools" in nuxt ? nuxt.devtools : void 0;
|
|
36
|
+
if (!host || typeof host !== "object" || !("ensureDevAuthToken" in host) || typeof host.ensureDevAuthToken !== "function") throw new Error("Nuxt DevTools authentication is unavailable.");
|
|
37
|
+
await host.ensureDevAuthToken(token);
|
|
38
|
+
})
|
|
39
|
+
});
|
|
22
40
|
addDevServerHandler({
|
|
23
41
|
route: FILES_DEVTOOLS_PATH,
|
|
24
42
|
handler: nuxt_v3_handler_default
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["uiHandler"],"sources":["../../src/devtools/index.ts"],"sourcesContent":["import { fileURLToPath } from 'node:url'\n\nimport { addDevServerHandler, addServerHandler } from '@nuxt/kit'\nimport type { Nuxt } from '@nuxt/schema'\n\nimport { setupNuxtV3Devtools } from './nuxt-v3'\nimport uiHandler from './nuxt-v3-handler'\nimport { setupNuxtV4Devtools } from './nuxt-v4'\nimport {\n FILES_DEVTOOLS_MAX_UPLOAD_SIZE,\n FILES_DEVTOOLS_PATH,\n FILES_GATEWAY_PATH,\n FILES_SNAPSHOT_PATH,\n} from './snapshot'\n\nexport const setupFilesDevtools = (nuxt: Nuxt, version: string, write: boolean): void => {\n // Snapshot must run inside Nitro's worker, where the runtime registry lives.\n addServerHandler({\n route: FILES_SNAPSHOT_PATH,\n handler: fileURLToPath(new URL('./snapshot.js', import.meta.url)),\n })\n addServerHandler({\n route: FILES_GATEWAY_PATH,\n handler: fileURLToPath(new URL(write ? './files-write.js' : './files-read.js', import.meta.url)),\n })\n if (Number.parseInt(version) >= 4) {\n setupNuxtV4Devtools(nuxt, {
|
|
1
|
+
{"version":3,"file":"index.js","names":["tokenHandler","uiHandler"],"sources":["../../src/devtools/index.ts"],"sourcesContent":["import { fileURLToPath } from 'node:url'\n\nimport { addDevServerHandler, addServerHandler, addServerTemplate } from '@nuxt/kit'\nimport type { Nuxt } from '@nuxt/schema'\n\nimport { setupNuxtV3Devtools } from './nuxt-v3'\nimport uiHandler from './nuxt-v3-handler'\nimport { setupNuxtV4Devtools } from './nuxt-v4'\nimport {\n FILES_DEVTOOLS_MAX_UPLOAD_SIZE,\n FILES_DEVTOOLS_PATH,\n FILES_GATEWAY_PATH,\n FILES_SNAPSHOT_PATH,\n FILES_TOKEN_PATH,\n} from './snapshot'\nimport tokenHandler from './token'\n\nconst authenticatedHandler = (name: string, path: string, arguments_: string[]): string => {\n const filename = `#nuxt-files-sdk/${name}`\n addServerTemplate({\n filename,\n getContents: () =>\n `import handler from ${JSON.stringify(path.replaceAll('\\\\', '/'))}\\nexport default event => handler(event, ${arguments_.map((value) => JSON.stringify(value)).join(', ')})\\n`,\n })\n return filename\n}\n\nexport const setupFilesDevtools = (nuxt: Nuxt, version: string, write: boolean, secrets: { token: string }): void => {\n // Snapshot must run inside Nitro's worker, where the runtime registry lives.\n addServerHandler({\n route: FILES_SNAPSHOT_PATH,\n handler: authenticatedHandler('snapshot', fileURLToPath(new URL('./snapshot.js', import.meta.url)), [\n secrets.token,\n ]),\n })\n addServerHandler({\n route: FILES_GATEWAY_PATH,\n handler: authenticatedHandler(\n 'files',\n fileURLToPath(new URL(write ? './files-write.js' : './files-read.js', import.meta.url)),\n [secrets.token],\n ),\n })\n if (Number.parseInt(version) >= 4) {\n setupNuxtV4Devtools(nuxt, {\n write,\n maxUploadSize: FILES_DEVTOOLS_MAX_UPLOAD_SIZE,\n tokenSecret: secrets.token,\n })\n } else {\n addDevServerHandler({\n route: FILES_TOKEN_PATH,\n handler: (event) =>\n tokenHandler(event, secrets.token, async (token) => {\n const host = 'devtools' in nuxt ? nuxt.devtools : undefined\n if (\n !host ||\n typeof host !== 'object' ||\n !('ensureDevAuthToken' in host) ||\n typeof host.ensureDevAuthToken !== 'function'\n ) {\n throw new Error('Nuxt DevTools authentication is unavailable.')\n }\n await host.ensureDevAuthToken(token)\n }),\n })\n addDevServerHandler({\n route: FILES_DEVTOOLS_PATH,\n handler: uiHandler,\n })\n setupNuxtV3Devtools(nuxt)\n }\n}\n"],"mappings":";;;;;;;;AAiBA,MAAM,wBAAwB,MAAc,MAAc,eAAiC;CACvF,MAAM,WAAW,mBAAmB;CACpC,kBAAkB;EACd;EACA,mBACI,uBAAuB,KAAK,UAAU,KAAK,WAAW,MAAM,GAAG,CAAC,EAAE,2CAA2C,WAAW,KAAK,UAAU,KAAK,UAAU,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE;CACjL,CAAC;CACD,OAAO;AACX;AAEA,MAAa,sBAAsB,MAAY,SAAiB,OAAgB,YAAqC;CAEjH,iBAAiB;EACb,OAAO;EACP,SAAS,qBAAqB,YAAY,cAAc,IAAI,IAAI,iBAAiB,YAAY,GAAG,CAAC,GAAG,CAChG,QAAQ,KACZ,CAAC;CACL,CAAC;CACD,iBAAiB;EACb,OAAO;EACP,SAAS,qBACL,SACA,cAAc,IAAI,IAAI,QAAQ,qBAAqB,mBAAmB,YAAY,GAAG,CAAC,GACtF,CAAC,QAAQ,KAAK,CAClB;CACJ,CAAC;CACD,IAAI,OAAO,SAAS,OAAO,KAAK,GAC5B,oBAAoB,MAAM;EACtB;EACA,eAAe;EACf,aAAa,QAAQ;CACzB,CAAC;MACE;EACH,oBAAoB;GAChB,OAAO;GACP,UAAU,UACNA,cAAa,OAAO,QAAQ,OAAO,OAAO,UAAU;IAChD,MAAM,OAAO,cAAc,OAAO,KAAK,WAAW,KAAA;IAClD,IACI,CAAC,QACD,OAAO,SAAS,YAChB,EAAE,wBAAwB,SAC1B,OAAO,KAAK,uBAAuB,YAEnC,MAAM,IAAI,MAAM,8CAA8C;IAElE,MAAM,KAAK,mBAAmB,KAAK;GACvC,CAAC;EACT,CAAC;EACD,oBAAoB;GAChB,OAAO;GACP,SAASC;EACb,CAAC;EACD,oBAAoB,IAAI;CAC5B;AACJ"}
|
|
@@ -13,7 +13,7 @@ const assets = /* @__PURE__ */ new Map([
|
|
|
13
13
|
}]
|
|
14
14
|
]);
|
|
15
15
|
var nuxt_v3_handler_default = async (event) => {
|
|
16
|
-
const asset = assets.get(event.path);
|
|
16
|
+
const asset = assets.get(new URL(event.path, "http://localhost").pathname);
|
|
17
17
|
if (!asset) return void 0;
|
|
18
18
|
event.node.res.setHeader("content-type", asset.contentType);
|
|
19
19
|
return asset.content;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nuxt-v3-handler.js","names":[],"sources":["../../src/devtools/nuxt-v3-handler.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises'\n\nconst html = {\n contentType: 'text/html; charset=utf-8',\n content: readFile(new URL('./client/index.html', import.meta.url), 'utf8'),\n}\nconst assets = new Map([\n ['/', html],\n ['/index.html', html],\n [\n '/app.js',\n {\n contentType: 'text/javascript; charset=utf-8',\n content: readFile(new URL('./client/app.js', import.meta.url), 'utf8'),\n },\n ],\n])\n\nexport default async (event: { path: string; node: { res: { setHeader(name: string, value: string): void } } }) => {\n const asset = assets.get(event.path)\n if (!asset) return undefined\n event.node.res.setHeader('content-type', asset.contentType)\n return asset.content\n}\n"],"mappings":";;AAEA,MAAM,OAAO;CACT,aAAa;CACb,SAAS,SAAS,IAAI,IAAI,uBAAuB,YAAY,GAAG,GAAG,MAAM;AAC7E;AACA,MAAM,yBAAS,IAAI,IAAI;CACnB,CAAC,KAAK,IAAI;CACV,CAAC,eAAe,IAAI;CACpB,CACI,WACA;EACI,aAAa;EACb,SAAS,SAAS,IAAI,IAAI,mBAAmB,YAAY,GAAG,GAAG,MAAM;CACzE,CACJ;AACJ,CAAC;AAED,IAAA,0BAAe,OAAO,UAA6F;CAC/G,MAAM,QAAQ,OAAO,IAAI,MAAM,
|
|
1
|
+
{"version":3,"file":"nuxt-v3-handler.js","names":[],"sources":["../../src/devtools/nuxt-v3-handler.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises'\n\nconst html = {\n contentType: 'text/html; charset=utf-8',\n content: readFile(new URL('./client/index.html', import.meta.url), 'utf8'),\n}\nconst assets = new Map([\n ['/', html],\n ['/index.html', html],\n [\n '/app.js',\n {\n contentType: 'text/javascript; charset=utf-8',\n content: readFile(new URL('./client/app.js', import.meta.url), 'utf8'),\n },\n ],\n])\n\nexport default async (event: { path: string; node: { res: { setHeader(name: string, value: string): void } } }) => {\n const asset = assets.get(new URL(event.path, 'http://localhost').pathname)\n if (!asset) return undefined\n event.node.res.setHeader('content-type', asset.contentType)\n return asset.content\n}\n"],"mappings":";;AAEA,MAAM,OAAO;CACT,aAAa;CACb,SAAS,SAAS,IAAI,IAAI,uBAAuB,YAAY,GAAG,GAAG,MAAM;AAC7E;AACA,MAAM,yBAAS,IAAI,IAAI;CACnB,CAAC,KAAK,IAAI;CACV,CAAC,eAAe,IAAI;CACpB,CACI,WACA;EACI,aAAa;EACb,SAAS,SAAS,IAAI,IAAI,mBAAmB,YAAY,GAAG,GAAG,MAAM;CACzE,CACJ;AACJ,CAAC;AAED,IAAA,0BAAe,OAAO,UAA6F;CAC/G,MAAM,QAAQ,OAAO,IAAI,IAAI,IAAI,MAAM,MAAM,kBAAkB,CAAC,CAAC,QAAQ;CACzE,IAAI,CAAC,OAAO,OAAO,KAAA;CACnB,MAAM,KAAK,IAAI,UAAU,gBAAgB,MAAM,WAAW;CAC1D,OAAO,MAAM;AACjB"}
|
package/dist/devtools/nuxt-v3.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nuxt-v3.js","names":[],"sources":["../../src/devtools/nuxt-v3.ts"],"sourcesContent":["import type { Nuxt } from '@nuxt/schema'\n\nimport { FILES_DEVTOOLS_PATH } from './snapshot'\n\ninterface CustomTab {\n name: string\n title: string\n icon: string\n view: { type: 'iframe'; src: string }\n}\n\ndeclare module '@nuxt/schema' {\n interface NuxtHooks {\n 'devtools:customTabs': (tabs: CustomTab[]) => void\n }\n}\n\nexport const setupNuxtV3Devtools = (nuxt: Nuxt): void => {\n nuxt.hook('devtools:customTabs', (tabs) => {\n tabs.push({\n name: 'nuxt-files-sdk',\n title: 'Files',\n icon: 'ph:files-duotone',\n view: { type: 'iframe', src: FILES_DEVTOOLS_PATH },\n })\n })\n}\n"],"mappings":";;AAiBA,MAAa,uBAAuB,SAAqB;CACrD,KAAK,KAAK,wBAAwB,SAAS;EACvC,KAAK,KAAK;GACN,MAAM;GACN,OAAO;GACP,MAAM;GACN,MAAM;IAAE,MAAM;IAAU,KAAK;
|
|
1
|
+
{"version":3,"file":"nuxt-v3.js","names":[],"sources":["../../src/devtools/nuxt-v3.ts"],"sourcesContent":["import type { Nuxt } from '@nuxt/schema'\n\nimport { FILES_DEVTOOLS_PATH } from './snapshot'\n\ninterface CustomTab {\n name: string\n title: string\n icon: string\n view: { type: 'iframe'; src: string }\n}\n\ndeclare module '@nuxt/schema' {\n interface NuxtHooks {\n 'devtools:customTabs': (tabs: CustomTab[]) => void\n }\n}\n\nexport const setupNuxtV3Devtools = (nuxt: Nuxt): void => {\n nuxt.hook('devtools:customTabs', (tabs) => {\n tabs.push({\n name: 'nuxt-files-sdk',\n title: 'Files',\n icon: 'ph:files-duotone',\n view: { type: 'iframe', src: `${FILES_DEVTOOLS_PATH}?host=nuxt-v3` },\n })\n })\n}\n"],"mappings":";;AAiBA,MAAa,uBAAuB,SAAqB;CACrD,KAAK,KAAK,wBAAwB,SAAS;EACvC,KAAK,KAAK;GACN,MAAM;GACN,OAAO;GACP,MAAM;GACN,MAAM;IAAE,MAAM;IAAU,KAAK,GAAG,oBAAoB;GAAe;EACvE,CAAC;CACL,CAAC;AACL"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nuxt-v4.js","names":[],"sources":["../../src/devtools/nuxt-v4.ts"],"sourcesContent":["import { NUXT_DEVTOOLS_GROUP_ID, onDevtoolsReady } from '@nuxt/devtools-kit'\nimport type { Nuxt } from '@nuxt/schema'\nimport { createEmbedded } from 'devframe/adapters/embedded'\n\nimport { createFilesDevframe } from './devframe'\nimport { FILES_DEVTOOLS_PATH } from './snapshot'\n\nexport const setupNuxtV4Devtools = (nuxt: Nuxt
|
|
1
|
+
{"version":3,"file":"nuxt-v4.js","names":[],"sources":["../../src/devtools/nuxt-v4.ts"],"sourcesContent":["import { NUXT_DEVTOOLS_GROUP_ID, onDevtoolsReady } from '@nuxt/devtools-kit'\nimport type { Nuxt } from '@nuxt/schema'\nimport { createEmbedded } from 'devframe/adapters/embedded'\n\nimport { createFilesDevframe } from './devframe'\nimport { FILES_DEVTOOLS_PATH } from './snapshot'\n\nexport const setupNuxtV4Devtools = (\n nuxt: Nuxt,\n options: { write: boolean; maxUploadSize: number; tokenSecret: string },\n): void => {\n onDevtoolsReady(async (context) => {\n await createEmbedded(\n createFilesDevframe({\n ...options,\n notifyFailure: (message) => context.messages.add(message),\n }),\n { ctx: context },\n )\n context.docks.register({\n id: 'nuxt-files-sdk',\n title: 'Files',\n icon: 'ph:files-duotone',\n type: 'iframe',\n url: FILES_DEVTOOLS_PATH,\n groupId: NUXT_DEVTOOLS_GROUP_ID,\n })\n\n const broadcast = (method: 'refresh' | 'copy-diagnostics') =>\n context.scope('nuxt-files-sdk').rpc.broadcast({ method, args: [], optional: true, event: true })\n context.commands.register({\n id: 'nuxt-files-sdk:open',\n title: 'Files: Open',\n icon: 'ph:files-duotone',\n category: 'tools',\n handler: () => context.docks.activate('nuxt-files-sdk'),\n })\n context.commands.register({\n id: 'nuxt-files-sdk:refresh',\n title: 'Files: Refresh',\n icon: 'ph:arrow-clockwise-duotone',\n category: 'tools',\n handler: () => broadcast('refresh'),\n })\n context.commands.register({\n id: 'nuxt-files-sdk:copy-diagnostics',\n title: 'Files: Copy Diagnostics',\n icon: 'ph:copy-duotone',\n category: 'tools',\n handler: () => broadcast('copy-diagnostics'),\n })\n }, nuxt)\n}\n"],"mappings":";;;;;AAOA,MAAa,uBACT,MACA,YACO;CACP,gBAAgB,OAAO,YAAY;EAC/B,MAAM,eACF,oBAAoB;GAChB,GAAG;GACH,gBAAgB,YAAY,QAAQ,SAAS,IAAI,OAAO;EAC5D,CAAC,GACD,EAAE,KAAK,QAAQ,CACnB;EACA,QAAQ,MAAM,SAAS;GACnB,IAAI;GACJ,OAAO;GACP,MAAM;GACN,MAAM;GACN,KAAK;GACL,SAAS;EACb,CAAC;EAED,MAAM,aAAa,WACf,QAAQ,MAAM,gBAAgB,CAAC,CAAC,IAAI,UAAU;GAAE;GAAQ,MAAM,CAAC;GAAG,UAAU;GAAM,OAAO;EAAK,CAAC;EACnG,QAAQ,SAAS,SAAS;GACtB,IAAI;GACJ,OAAO;GACP,MAAM;GACN,UAAU;GACV,eAAe,QAAQ,MAAM,SAAS,gBAAgB;EAC1D,CAAC;EACD,QAAQ,SAAS,SAAS;GACtB,IAAI;GACJ,OAAO;GACP,MAAM;GACN,UAAU;GACV,eAAe,UAAU,SAAS;EACtC,CAAC;EACD,QAAQ,SAAS,SAAS;GACtB,IAAI;GACJ,OAAO;GACP,MAAM;GACN,UAAU;GACV,eAAe,UAAU,kBAAkB;EAC/C,CAAC;CACL,GAAG,IAAI;AACX"}
|
|
@@ -5,7 +5,6 @@ export interface FilesDevtoolsSnapshot {
|
|
|
5
5
|
name?: string;
|
|
6
6
|
adapter: string;
|
|
7
7
|
plugins: string[];
|
|
8
|
-
source: 'storage' | 'devStorage';
|
|
9
8
|
initialized: boolean;
|
|
10
9
|
}>;
|
|
11
10
|
diagnostics: FilesDevtoolsDiagnostic[];
|
|
@@ -13,8 +12,15 @@ export interface FilesDevtoolsSnapshot {
|
|
|
13
12
|
export declare const FILES_DEVTOOLS_PATH = "/__nuxt-files-sdk/";
|
|
14
13
|
export declare const FILES_SNAPSHOT_PATH = "/__nuxt-files-sdk/snapshot";
|
|
15
14
|
export declare const FILES_GATEWAY_PATH = "/__nuxt-files-sdk/files";
|
|
15
|
+
export declare const FILES_TOKEN_PATH = "/__nuxt-files-sdk/token";
|
|
16
16
|
export declare const FILES_DEVTOOLS_MAX_UPLOAD_SIZE: number;
|
|
17
|
-
declare function _default(
|
|
17
|
+
declare function _default(event: {
|
|
18
|
+
node: {
|
|
19
|
+
req: {
|
|
20
|
+
headers: Headers;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
}, secret: string): Promise<Response>;
|
|
18
24
|
//#endregion
|
|
19
25
|
export { _default as default };
|
|
20
26
|
//# sourceMappingURL=snapshot.d.ts.map
|
|
@@ -1,11 +1,21 @@
|
|
|
1
|
-
import { inspectFiles } from "../runtime.js";
|
|
1
|
+
import { inspectFiles } from "../runtime/internal.js";
|
|
2
|
+
import { authorizeFilesDevtoolsRequest } from "./auth.js";
|
|
3
|
+
import { createFilesDevtoolsDiagnostic } from "./diagnostics.js";
|
|
2
4
|
//#region src/devtools/snapshot.ts
|
|
3
5
|
const FILES_DEVTOOLS_PATH = "/__nuxt-files-sdk/";
|
|
4
6
|
const FILES_SNAPSHOT_PATH = `${FILES_DEVTOOLS_PATH}snapshot`;
|
|
5
7
|
const FILES_GATEWAY_PATH = `${FILES_DEVTOOLS_PATH}files`;
|
|
8
|
+
const FILES_TOKEN_PATH = `${FILES_DEVTOOLS_PATH}token`;
|
|
6
9
|
const FILES_DEVTOOLS_MAX_UPLOAD_SIZE = 10485760;
|
|
7
|
-
var snapshot_default = () =>
|
|
10
|
+
var snapshot_default = async (event, secret) => {
|
|
11
|
+
if (!await authorizeFilesDevtoolsRequest(event.node.req, secret)) return new Response(null, { status: 401 });
|
|
12
|
+
const snapshot = inspectFiles();
|
|
13
|
+
return Response.json({
|
|
14
|
+
...snapshot,
|
|
15
|
+
diagnostics: snapshot.diagnostics.map(({ code, name, adapter }) => createFilesDevtoolsDiagnostic(code, adapter ? `${name === void 0 ? "The single storage" : `Storage "${name}"`} (${adapter}) could not be initialized.` : void 0))
|
|
16
|
+
});
|
|
17
|
+
};
|
|
8
18
|
//#endregion
|
|
9
|
-
export { FILES_DEVTOOLS_MAX_UPLOAD_SIZE, FILES_DEVTOOLS_PATH, FILES_GATEWAY_PATH, FILES_SNAPSHOT_PATH, snapshot_default as default };
|
|
19
|
+
export { FILES_DEVTOOLS_MAX_UPLOAD_SIZE, FILES_DEVTOOLS_PATH, FILES_GATEWAY_PATH, FILES_SNAPSHOT_PATH, FILES_TOKEN_PATH, snapshot_default as default };
|
|
10
20
|
|
|
11
21
|
//# sourceMappingURL=snapshot.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.js","names":[],"sources":["../../src/devtools/snapshot.ts"],"sourcesContent":["import { inspectFiles } from '../runtime'\nimport
|
|
1
|
+
{"version":3,"file":"snapshot.js","names":[],"sources":["../../src/devtools/snapshot.ts"],"sourcesContent":["import { inspectFiles } from '../runtime/internal'\nimport { authorizeFilesDevtoolsRequest } from './auth'\nimport { createFilesDevtoolsDiagnostic, type FilesDevtoolsDiagnostic } from './diagnostics'\n\nexport interface FilesDevtoolsSnapshot {\n storages: Array<{\n name?: string\n adapter: string\n plugins: string[]\n initialized: boolean\n }>\n diagnostics: FilesDevtoolsDiagnostic[]\n}\n\nexport const FILES_DEVTOOLS_PATH = '/__nuxt-files-sdk/'\nexport const FILES_SNAPSHOT_PATH = `${FILES_DEVTOOLS_PATH}snapshot`\nexport const FILES_GATEWAY_PATH = `${FILES_DEVTOOLS_PATH}files`\nexport const FILES_TOKEN_PATH = `${FILES_DEVTOOLS_PATH}token`\nexport const FILES_DEVTOOLS_MAX_UPLOAD_SIZE = 10 * 1024 * 1024\n\nexport default async (event: { node: { req: { headers: Headers } } }, secret: string) => {\n if (!(await authorizeFilesDevtoolsRequest(event.node.req, secret))) {\n return new Response(null, { status: 401 })\n }\n const snapshot = inspectFiles()\n return Response.json({\n ...snapshot,\n diagnostics: snapshot.diagnostics.map(({ code, name, adapter }) =>\n createFilesDevtoolsDiagnostic(\n code,\n adapter\n ? `${name === undefined ? 'The single storage' : `Storage \"${name}\"`} (${adapter}) could not be initialized.`\n : undefined,\n ),\n ),\n })\n}\n"],"mappings":";;;;AAcA,MAAa,sBAAsB;AACnC,MAAa,sBAAsB,GAAG,oBAAoB;AAC1D,MAAa,qBAAqB,GAAG,oBAAoB;AACzD,MAAa,mBAAmB,GAAG,oBAAoB;AACvD,MAAa,iCAAiC;AAE9C,IAAA,mBAAe,OAAO,OAAgD,WAAmB;CACrF,IAAI,CAAE,MAAM,8BAA8B,MAAM,KAAK,KAAK,MAAM,GAC5D,OAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,IAAI,CAAC;CAE7C,MAAM,WAAW,aAAa;CAC9B,OAAO,SAAS,KAAK;EACjB,GAAG;EACH,aAAa,SAAS,YAAY,KAAK,EAAE,MAAM,MAAM,cACjD,8BACI,MACA,UACM,GAAG,SAAS,KAAA,IAAY,uBAAuB,YAAY,KAAK,GAAG,IAAI,QAAQ,+BAC/E,KAAA,CACV,CACJ;CACJ,CAAC;AACL"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/devtools/token.d.ts
|
|
2
|
+
declare function _default(event: {
|
|
3
|
+
node: {
|
|
4
|
+
req: {
|
|
5
|
+
headers: {
|
|
6
|
+
get?: (name: string) => string | null | undefined;
|
|
7
|
+
[key: string]: unknown;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
}, secret: string, authorize: (token: string) => Promise<void>): Promise<Response>;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { _default as default };
|
|
14
|
+
//# sourceMappingURL=token.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createFilesDevtoolsToken } from "./auth.js";
|
|
2
|
+
//#region src/devtools/token.ts
|
|
3
|
+
var token_default = async (event, secret, authorize) => {
|
|
4
|
+
const headers = event.node.req.headers;
|
|
5
|
+
const received = headers.get?.("x-nuxt-devtools-token") ?? headers["x-nuxt-devtools-token"];
|
|
6
|
+
if (typeof received !== "string" || !received) return new Response(null, { status: 401 });
|
|
7
|
+
try {
|
|
8
|
+
await authorize(received);
|
|
9
|
+
} catch {
|
|
10
|
+
return new Response(null, { status: 401 });
|
|
11
|
+
}
|
|
12
|
+
return Response.json(await createFilesDevtoolsToken(secret), { headers: { "cache-control": "no-store" } });
|
|
13
|
+
};
|
|
14
|
+
//#endregion
|
|
15
|
+
export { token_default as default };
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.js","names":[],"sources":["../../src/devtools/token.ts"],"sourcesContent":["import { createFilesDevtoolsToken } from './auth'\n\nexport default async (\n event: {\n node: { req: { headers: { get?: (name: string) => string | null | undefined; [key: string]: unknown } } }\n },\n secret: string,\n authorize: (token: string) => Promise<void>,\n) => {\n const headers = event.node.req.headers\n const received = headers.get?.('x-nuxt-devtools-token') ?? headers['x-nuxt-devtools-token']\n if (typeof received !== 'string' || !received) return new Response(null, { status: 401 })\n try {\n await authorize(received)\n } catch {\n return new Response(null, { status: 401 })\n }\n return Response.json(await createFilesDevtoolsToken(secret), { headers: { 'cache-control': 'no-store' } })\n}\n"],"mappings":";;AAEA,IAAA,gBAAe,OACX,OAGA,QACA,cACC;CACD,MAAM,UAAU,MAAM,KAAK,IAAI;CAC/B,MAAM,WAAW,QAAQ,MAAM,uBAAuB,KAAK,QAAQ;CACnE,IAAI,OAAO,aAAa,YAAY,CAAC,UAAU,OAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,IAAI,CAAC;CACxF,IAAI;EACA,MAAM,UAAU,QAAQ;CAC5B,QAAQ;EACJ,OAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,IAAI,CAAC;CAC7C;CACA,OAAO,SAAS,KAAK,MAAM,yBAAyB,MAAM,GAAG,EAAE,SAAS,EAAE,iBAAiB,WAAW,EAAE,CAAC;AAC7G"}
|
|
@@ -8,7 +8,13 @@ export interface NitroIntegration {
|
|
|
8
8
|
rootDir: string;
|
|
9
9
|
buildDir: string;
|
|
10
10
|
dev?: boolean;
|
|
11
|
+
static?: boolean;
|
|
12
|
+
preset?: string;
|
|
11
13
|
plugins: string[];
|
|
14
|
+
handlers?: {
|
|
15
|
+
route: string;
|
|
16
|
+
handler: string;
|
|
17
|
+
}[];
|
|
12
18
|
alias?: Record<string, string>;
|
|
13
19
|
externals?: {
|
|
14
20
|
inline?: unknown[];
|
|
@@ -1,40 +1,65 @@
|
|
|
1
|
+
import { normalizeFilesConfig } from "../runtime/normalize.js";
|
|
2
|
+
import { loadFilesConfig } from "../config/load.js";
|
|
3
|
+
import { pruneFilesConfigSource } from "../config/prune.js";
|
|
1
4
|
import { resolve } from "node:path";
|
|
2
5
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
6
|
+
import { createRequire } from "node:module";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
import { getProvider, listEnvVars } from "files-sdk/providers";
|
|
5
9
|
//#region src/integration/nitro.ts
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
10
|
+
const AWS_CORE_DEPENDENCIES = [
|
|
11
|
+
"@aws-sdk/client-s3",
|
|
12
|
+
"@aws-sdk/s3-presigned-post",
|
|
13
|
+
"@aws-sdk/s3-request-presigner"
|
|
14
|
+
];
|
|
15
|
+
const AWS_MULTIPART_DEPENDENCY = "@aws-sdk/lib-storage";
|
|
16
|
+
const FETCH_CAPABLE_S3_ADAPTERS = /* @__PURE__ */ new Set([
|
|
17
|
+
"minio",
|
|
18
|
+
"r2",
|
|
19
|
+
"rustfs"
|
|
20
|
+
]);
|
|
21
|
+
const WORKERD_PRESETS = /* @__PURE__ */ new Set([
|
|
22
|
+
"cloudflare-module",
|
|
23
|
+
"cloudflare-durable",
|
|
24
|
+
"cloudflare-pages"
|
|
25
|
+
]);
|
|
26
|
+
const optionalAwsSdkDependencies = (adapters, options) => {
|
|
27
|
+
if (options.nitroMajor >= 3 || !options.preset || !WORKERD_PRESETS.has(options.preset)) return [];
|
|
28
|
+
const s3Adapters = adapters.filter((adapter) => getProvider(adapter)?.peerDeps.includes("@aws-sdk/client-s3"));
|
|
29
|
+
if (s3Adapters.length === 0) return [];
|
|
30
|
+
return (s3Adapters.every((adapter) => FETCH_CAPABLE_S3_ADAPTERS.has(adapter)) ? [...AWS_CORE_DEPENDENCIES, AWS_MULTIPART_DEPENDENCY] : [AWS_MULTIPART_DEPENDENCY]).filter((dependency) => !options.resolvable(dependency));
|
|
31
|
+
};
|
|
32
|
+
const nitroMajorVersion = (nitro) => nitro.meta?.majorVersion ?? ("routing" in nitro ? 3 : 2);
|
|
33
|
+
const selectedAdapters = (config) => {
|
|
34
|
+
const entries = normalizeFilesConfig(config);
|
|
35
|
+
const single = entries.has(void 0);
|
|
36
|
+
const adapters = [...new Set([...entries.values()].map(({ storage }) => storage.adapter).filter((adapter) => typeof adapter === "string"))].toSorted();
|
|
32
37
|
for (const adapter of adapters) if (!getProvider(adapter)) throw new Error(`[nuxt-files-sdk:unknown-adapter] Unknown adapter "${adapter}".`);
|
|
33
38
|
return {
|
|
34
39
|
adapters,
|
|
35
40
|
single
|
|
36
41
|
};
|
|
37
42
|
};
|
|
43
|
+
const gatewayRoutes = (config) => {
|
|
44
|
+
const routes = config && typeof config === "object" && "routes" in config ? config.routes : void 0;
|
|
45
|
+
if (routes === void 0) return [];
|
|
46
|
+
if (!Array.isArray(routes)) throw new Error("[nuxt-files-sdk:invalid-route] routes must be an array.");
|
|
47
|
+
const storages = normalizeFilesConfig(config);
|
|
48
|
+
const paths = /* @__PURE__ */ new Set();
|
|
49
|
+
const selected = [];
|
|
50
|
+
for (const route of routes) {
|
|
51
|
+
if (!route || typeof route !== "object" || !("path" in route) || typeof route.path !== "string" || !/^\/(?:[\w.~-]+(?:\/[\w.~-]+)*)?$/u.test(route.path)) throw new Error("[nuxt-files-sdk:invalid-route] Each route needs a static absolute path.");
|
|
52
|
+
if (paths.has(route.path)) throw new Error(`[nuxt-files-sdk:duplicate-route] Duplicate route "${route.path}".`);
|
|
53
|
+
paths.add(route.path);
|
|
54
|
+
const name = "storage" in route ? route.storage : void 0;
|
|
55
|
+
if (storages.has(void 0) ? name !== void 0 : typeof name !== "string" || !storages.has(name)) throw new Error(`[nuxt-files-sdk:unknown-storage] Invalid storage for route "${route.path}".`);
|
|
56
|
+
selected.push(typeof name === "string" ? {
|
|
57
|
+
path: route.path,
|
|
58
|
+
storage: name
|
|
59
|
+
} : { path: route.path });
|
|
60
|
+
}
|
|
61
|
+
return selected;
|
|
62
|
+
};
|
|
38
63
|
const factoryName = (adapter) => adapter === "cloudinary" ? "cloudinaryAdapter" : adapter.replaceAll(/-([a-z0-9])/gu, (_, character) => character.toUpperCase());
|
|
39
64
|
const providerCode = (adapters) => ({
|
|
40
65
|
imports: adapters.map((adapter, index) => `import { ${factoryName(adapter)} as provider${index} } from ${JSON.stringify(`files-sdk/${adapter}`)}`).join("\n"),
|
|
@@ -49,71 +74,143 @@ declare module ${JSON.stringify(moduleName)} {
|
|
|
49
74
|
}
|
|
50
75
|
}
|
|
51
76
|
`;
|
|
52
|
-
const storageTypes = (configPath, nitroMajor
|
|
77
|
+
const storageTypes = (configPath, nitroMajor) => `import type config from ${JSON.stringify(configPath)}
|
|
53
78
|
import type { SingleStorage, StorageRegistry } from 'nuxt-files-sdk/runtime'
|
|
54
79
|
|
|
55
80
|
declare module 'nuxt-files-sdk/runtime' {
|
|
56
|
-
|
|
81
|
+
interface NuxtFilesSingleStorage { value: SingleStorage<typeof config> }
|
|
82
|
+
interface NuxtFilesStorageRegistry extends StorageRegistry<typeof config> {}
|
|
57
83
|
}
|
|
58
84
|
${hookTypes(nitroMajor >= 3 ? "nitro/types" : "nitropack/types")}
|
|
59
85
|
export {}
|
|
60
86
|
`;
|
|
61
87
|
const setupNitroFilesIntegration = async (nitro, options) => {
|
|
62
88
|
const configPath = options.configPath.replaceAll("\\", "/");
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
89
|
+
const config = await loadFilesConfig({
|
|
90
|
+
configPath,
|
|
91
|
+
environments: options.environments,
|
|
92
|
+
alias: nitro.options.alias,
|
|
93
|
+
injectImports: nitro.unimport?.injectImports.bind(nitro.unimport)
|
|
67
94
|
});
|
|
68
|
-
|
|
69
|
-
const
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
95
|
+
if (!config) return false;
|
|
96
|
+
const selected = selectedAdapters(config);
|
|
97
|
+
const directory = resolve(nitro.options.rootDir, nitro.options.buildDir, "nuxt-files-sdk");
|
|
98
|
+
const typesPath = resolve(directory, "storage-registry.d.ts");
|
|
99
|
+
let writeRuntime;
|
|
100
|
+
const writeTypes = async () => {
|
|
101
|
+
await mkdir(directory, { recursive: true });
|
|
102
|
+
await writeFile(typesPath, storageTypes(configPath, nitroMajorVersion(nitro)));
|
|
103
|
+
};
|
|
104
|
+
await writeTypes();
|
|
105
|
+
nitro.hooks.hook("types:extend", async (types) => {
|
|
106
|
+
await writeTypes();
|
|
107
|
+
await writeRuntime?.();
|
|
108
|
+
const tsConfig = types.tsConfig ??= {};
|
|
109
|
+
(tsConfig.include ??= []).push(typesPath);
|
|
110
|
+
const paths = (tsConfig.compilerOptions ??= {}).paths ??= {};
|
|
111
|
+
paths["files-sdk"] ??= [resolve(nitro.options.rootDir, "node_modules/files-sdk").replaceAll("\\", "/")];
|
|
73
112
|
});
|
|
74
|
-
const
|
|
75
|
-
const
|
|
76
|
-
if (!selected) return;
|
|
77
|
-
const { adapters, single } = selected;
|
|
113
|
+
const routes = gatewayRoutes(config);
|
|
114
|
+
const { adapters } = selected;
|
|
78
115
|
const providers = providerCode(adapters);
|
|
79
|
-
const
|
|
116
|
+
const internalPath = fileURLToPath(new URL("../runtime/internal.js", import.meta.url)).replaceAll("\\", "/");
|
|
117
|
+
const environment = Object.fromEntries(adapters.map((adapter) => [adapter, listEnvVars(adapter).filter((variable) => variable.readBy === "files-sdk").map((variable) => [variable.key, ...variable.aliases ?? []])]));
|
|
118
|
+
const require = createRequire(resolve(nitro.options.rootDir, "package.json"));
|
|
119
|
+
const aliases = nitro.options.alias ?? {};
|
|
120
|
+
const shimFiles = optionalAwsSdkDependencies(adapters, {
|
|
121
|
+
nitroMajor: nitroMajorVersion(nitro),
|
|
122
|
+
preset: nitro.options.preset,
|
|
123
|
+
resolvable: (dependency) => {
|
|
124
|
+
if (Object.hasOwn(aliases, dependency)) return true;
|
|
125
|
+
try {
|
|
126
|
+
require.resolve(dependency);
|
|
127
|
+
return true;
|
|
128
|
+
} catch {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}).map((dependency) => ({
|
|
133
|
+
dependency,
|
|
134
|
+
path: resolve(directory, `${dependency.replaceAll(/[^a-z0-9]+/giu, "-")}.mjs`)
|
|
135
|
+
}));
|
|
136
|
+
if (shimFiles.length > 0) {
|
|
137
|
+
nitro.options.alias = aliases;
|
|
138
|
+
for (const { dependency, path } of shimFiles) aliases[dependency] = path.replaceAll("\\", "/");
|
|
139
|
+
}
|
|
80
140
|
nitro.unimport?.getInternalContext().addons.push({
|
|
81
141
|
name: "nuxt-files-sdk-jsdoc",
|
|
82
|
-
declaration: (declarations) => declarations.replace(/^(\
|
|
142
|
+
declaration: (declarations) => declarations.replace(/^([ \t]*)const (useServerFiles|syncFiles|transferFiles): typeof .*\.\2$/gmu, (_, indent, name) => `${name === "useServerFiles" ? `${indent}/** Return the project's Files client, including its configured plugin extensions. */\n` : ""}${indent}const ${name}: typeof import('nuxt-files-sdk/runtime').${name}`)
|
|
83
143
|
});
|
|
84
144
|
const externals = nitro.options.externals ??= {};
|
|
85
145
|
(externals.inline ??= []).push("nuxt-files-sdk");
|
|
86
146
|
if (!nitro.options.dev) externals.inline.push("files-sdk");
|
|
87
|
-
const
|
|
88
|
-
const
|
|
89
|
-
const
|
|
90
|
-
const
|
|
91
|
-
|
|
147
|
+
const pluginPath = resolve(directory, nitro.options.dev ? "plugin.dev.mjs" : "plugin.mjs");
|
|
148
|
+
const resolvedPath = resolve(directory, nitro.options.dev ? "resolved.dev.mjs" : "resolved.mjs");
|
|
149
|
+
const selectedPath = resolve(directory, nitro.options.dev ? "selected.dev.ts" : "selected.ts");
|
|
150
|
+
const routePaths = routes.map((_, index) => resolve(directory, `gateway-${index}${nitro.options.dev ? ".dev" : ""}.mjs`).replaceAll("\\", "/"));
|
|
151
|
+
for (const [index, route] of routes.entries()) (nitro.options.handlers ??= []).push({
|
|
152
|
+
route: route.path,
|
|
153
|
+
handler: routePaths[index]
|
|
154
|
+
});
|
|
155
|
+
externals.inline.push(pluginPath.replaceAll("\\", "/"), resolvedPath.replaceAll("\\", "/"), selectedPath.replaceAll("\\", "/"), ...routePaths);
|
|
92
156
|
nitro.options.plugins.push(pluginPath.replaceAll("\\", "/"));
|
|
93
|
-
|
|
157
|
+
writeRuntime = async () => {
|
|
94
158
|
await mkdir(directory, { recursive: true });
|
|
95
|
-
await Promise.all(
|
|
159
|
+
await Promise.all(shimFiles.map(({ dependency, path }) => writeFile(path, `throw new Error(${JSON.stringify(`[nuxt-files-sdk:missing-optional-dependency] ${dependency} is required for this Files SDK operation. Install it or select the provider's fetch client.`)})\n`)));
|
|
160
|
+
const originalSource = await readFile(configPath, "utf8");
|
|
161
|
+
const importedSource = nitro.unimport ? (await nitro.unimport.injectImports(originalSource, configPath)).code : originalSource;
|
|
162
|
+
await writeFile(selectedPath, pruneFilesConfigSource(importedSource, configPath, options.environments));
|
|
163
|
+
const mergePath = fileURLToPath(new URL("../config/merge.js", import.meta.url)).replaceAll("\\", "/");
|
|
164
|
+
const selectedBranches = options.environments.flatMap((name) => [`raw[${JSON.stringify(`$${name}`)}]`, `raw.$env?.[${JSON.stringify(name)}]`]).toReversed();
|
|
165
|
+
await writeFile(resolvedPath, `import raw from ${JSON.stringify(selectedPath.replaceAll("\\", "/"))}\nimport { mergeFilesConfig } from ${JSON.stringify(mergePath)}\nconst resolved = mergeFilesConfig(${[...selectedBranches, "raw"].join(", ")})\nexport default { storage: resolved.storage, routes: resolved.routes }\n`);
|
|
166
|
+
await writeFile(pluginPath, `import config from ${JSON.stringify(resolvedPath.replaceAll("\\", "/"))}
|
|
96
167
|
${providers.imports}
|
|
97
|
-
import { configureFiles } from
|
|
168
|
+
import { configureFiles } from ${JSON.stringify(internalPath)}
|
|
98
169
|
|
|
99
|
-
export default (nitroApp) => configureFiles(
|
|
100
|
-
development: ${JSON.stringify(options.development)},
|
|
170
|
+
export default (nitroApp) => configureFiles(config, {
|
|
101
171
|
factories: { ${providers.factories} },
|
|
172
|
+
environment: ${JSON.stringify(environment)},
|
|
102
173
|
hooks: {
|
|
103
174
|
onAction: (event, storage) => nitroApp.hooks.callHook('files:action', { event, storage }),
|
|
104
175
|
onError: (event, storage) => nitroApp.hooks.callHook('files:error', { event, storage }),
|
|
105
176
|
onRetry: (event, storage) => nitroApp.hooks.callHook('files:retry', { event, storage }),
|
|
106
177
|
},
|
|
107
178
|
})
|
|
108
|
-
`)
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
179
|
+
`);
|
|
180
|
+
await Promise.all(routePaths.map((path, index) => {
|
|
181
|
+
const route = routes[index];
|
|
182
|
+
const handler = nitroMajorVersion(nitro) >= 3 ? "router.handle(event.req)" : "createRouteHandler(router)(event)";
|
|
183
|
+
return writeFile(path, `import config from ${JSON.stringify(resolvedPath.replaceAll("\\", "/"))}
|
|
184
|
+
import { createFilesRouter } from 'files-sdk/api'
|
|
185
|
+
${nitroMajorVersion(nitro) >= 3 ? "" : "import { createRouteHandler } from 'files-sdk/nitro'"}
|
|
186
|
+
import { getFiles } from ${JSON.stringify(internalPath)}
|
|
187
|
+
|
|
188
|
+
const route = config.routes[${index}]
|
|
189
|
+
const environmentSecret = typeof process === 'undefined' ? undefined : process.env?.FILES_API_SECRET
|
|
190
|
+
const secret = route.authorize
|
|
191
|
+
? route.secret || environmentSecret || crypto.randomUUID() + crypto.randomUUID()
|
|
192
|
+
: route.secret
|
|
193
|
+
if (route.authorize && !route.secret && !environmentSecret) {
|
|
194
|
+
console.warn('[nuxt-files-sdk:gateway-secret] Set FILES_API_SECRET for upload tokens shared across processes.')
|
|
195
|
+
}
|
|
196
|
+
let sharedRouter
|
|
197
|
+
const makeRouter = (event) => createFilesRouter({
|
|
198
|
+
...route,
|
|
199
|
+
files: () => getFiles(${route.storage === void 0 ? "" : JSON.stringify(route.storage)}),
|
|
200
|
+
secret,
|
|
201
|
+
authorize: route.authorize && ((context) => route.authorize({ ...context, event })),
|
|
202
|
+
})
|
|
203
|
+
export default (event) => {
|
|
204
|
+
const router = route.authorize ? makeRouter(event) : (sharedRouter ??= makeRouter(event))
|
|
205
|
+
return ${handler}
|
|
206
|
+
}
|
|
207
|
+
`);
|
|
208
|
+
}));
|
|
209
|
+
};
|
|
210
|
+
await writeRuntime();
|
|
211
|
+
return true;
|
|
115
212
|
};
|
|
116
213
|
//#endregion
|
|
117
|
-
export { providerCode, selectedAdapters, setupNitroFilesIntegration, storageTypes };
|
|
214
|
+
export { gatewayRoutes, optionalAwsSdkDependencies, providerCode, selectedAdapters, setupNitroFilesIntegration, storageTypes };
|
|
118
215
|
|
|
119
216
|
//# sourceMappingURL=nitro.js.map
|