nuxt-files-sdk 0.0.4 → 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.
Files changed (74) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +44 -3
  3. package/dist/config/load.js +67 -0
  4. package/dist/config/load.js.map +1 -0
  5. package/dist/config/merge.d.ts +5 -0
  6. package/dist/config/merge.js +22 -0
  7. package/dist/config/merge.js.map +1 -0
  8. package/dist/config/prune.js +55 -0
  9. package/dist/config/prune.js.map +1 -0
  10. package/dist/config.d.ts +103 -91
  11. package/dist/config.js +1 -0
  12. package/dist/config.js.map +1 -1
  13. package/dist/devtools/auth.js +49 -0
  14. package/dist/devtools/auth.js.map +1 -0
  15. package/dist/devtools/client/app.js +8 -0
  16. package/dist/devtools/client/browser-agent-rpc-BXhoSh1z-DRoP5jHQ.js +1 -0
  17. package/dist/devtools/client/index.html +392 -72
  18. package/dist/devtools/devframe.js +66 -7
  19. package/dist/devtools/devframe.js.map +1 -1
  20. package/dist/devtools/diagnostics.d.ts +37 -0
  21. package/dist/devtools/diagnostics.js +39 -0
  22. package/dist/devtools/diagnostics.js.map +1 -0
  23. package/dist/devtools/enabled.d.ts +9 -0
  24. package/dist/devtools/enabled.js +3 -2
  25. package/dist/devtools/enabled.js.map +1 -1
  26. package/dist/devtools/files-read.d.ts +5 -0
  27. package/dist/devtools/files-read.js +7 -0
  28. package/dist/devtools/files-read.js.map +1 -0
  29. package/dist/devtools/files-write.d.ts +5 -0
  30. package/dist/devtools/files-write.js +7 -0
  31. package/dist/devtools/files-write.js.map +1 -0
  32. package/dist/devtools/files.js +51 -0
  33. package/dist/devtools/files.js.map +1 -0
  34. package/dist/devtools/index.js +30 -5
  35. package/dist/devtools/index.js.map +1 -1
  36. package/dist/devtools/nuxt-v3-handler.js +16 -4
  37. package/dist/devtools/nuxt-v3-handler.js.map +1 -1
  38. package/dist/devtools/nuxt-v3.js +1 -1
  39. package/dist/devtools/nuxt-v3.js.map +1 -1
  40. package/dist/devtools/nuxt-v4.js +37 -6
  41. package/dist/devtools/nuxt-v4.js.map +1 -1
  42. package/dist/devtools/snapshot.d.ts +12 -7
  43. package/dist/devtools/snapshot.js +15 -3
  44. package/dist/devtools/snapshot.js.map +1 -1
  45. package/dist/devtools/token.d.ts +14 -0
  46. package/dist/devtools/token.js +17 -0
  47. package/dist/devtools/token.js.map +1 -0
  48. package/dist/integration/nitro.d.ts +12 -1
  49. package/dist/integration/nitro.js +162 -41
  50. package/dist/integration/nitro.js.map +1 -1
  51. package/dist/module.d.ts +4 -6
  52. package/dist/module.js +37 -14
  53. package/dist/module.js.map +1 -1
  54. package/dist/nitro.d.ts +2 -4
  55. package/dist/nitro.js +2 -4
  56. package/dist/nitro.js.map +1 -1
  57. package/dist/package.js +1 -1
  58. package/dist/runtime/internal.d.ts +11 -0
  59. package/dist/runtime/internal.js +30 -0
  60. package/dist/runtime/internal.js.map +1 -0
  61. package/dist/runtime/normalize.js +29 -0
  62. package/dist/runtime/normalize.js.map +1 -0
  63. package/dist/runtime/provider-types.d.ts +53 -0
  64. package/dist/runtime/registry.d.ts +55 -8
  65. package/dist/runtime/registry.js +130 -63
  66. package/dist/runtime/registry.js.map +1 -1
  67. package/dist/runtime.d.ts +8 -9
  68. package/dist/runtime.js +8 -20
  69. package/dist/runtime.js.map +1 -1
  70. package/package.json +25 -19
  71. package/dist/plugins/versioning.d.ts +0 -3
  72. package/dist/plugins/versioning.js +0 -2
  73. package/dist/plugins.d.ts +0 -31
  74. package/dist/plugins.js +0 -16
@@ -1,31 +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
- import { mkdir, writeFile } from "node:fs/promises";
3
- import { getProvider } from "files-sdk/providers";
4
- import { createJiti } from "jiti";
5
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
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 isStorageConfig = (value) => Boolean(value && typeof value === "object" && "adapter" in value && typeof value.adapter === "string");
7
- const isStorageRecord = (value) => Boolean(value && typeof value === "object" && Object.values(value).every(isStorageConfig));
8
- const selectedAdapters = (config, development) => {
9
- const storage = config.storage;
10
- const devStorage = config.devStorage;
11
- if (!storage || !isStorageConfig(storage) && (!isStorageRecord(storage) || Object.keys(storage).length === 0)) throw new Error("[nuxt-files-sdk:invalid-config] At least one storage is required.");
12
- const selected = [];
13
- const single = isStorageConfig(storage);
14
- if (single) {
15
- if (devStorage && !isStorageConfig(devStorage)) throw new Error("[nuxt-files-sdk:invalid-config] A single storage requires a single devStorage override.");
16
- selected.push(development && isStorageConfig(devStorage) ? devStorage : storage);
17
- } else {
18
- if (devStorage && !isStorageRecord(devStorage)) throw new Error("[nuxt-files-sdk:invalid-config] Named storage requires named devStorage overrides.");
19
- for (const name of Object.keys(devStorage ?? {})) if (!Object.hasOwn(storage, name)) throw new Error(`[nuxt-files-sdk:unknown-storage] Unknown storage "${name}".`);
20
- for (const [name, namedStorage] of Object.entries(storage)) selected.push(development ? devStorage?.[name] ?? namedStorage : namedStorage);
21
- }
22
- const adapters = [...new Set(selected.map(({ adapter }) => adapter))].toSorted();
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();
23
37
  for (const adapter of adapters) if (!getProvider(adapter)) throw new Error(`[nuxt-files-sdk:unknown-adapter] Unknown adapter "${adapter}".`);
24
38
  return {
25
39
  adapters,
26
40
  single
27
41
  };
28
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
+ };
29
63
  const factoryName = (adapter) => adapter === "cloudinary" ? "cloudinaryAdapter" : adapter.replaceAll(/-([a-z0-9])/gu, (_, character) => character.toUpperCase());
30
64
  const providerCode = (adapters) => ({
31
65
  imports: adapters.map((adapter, index) => `import { ${factoryName(adapter)} as provider${index} } from ${JSON.stringify(`files-sdk/${adapter}`)}`).join("\n"),
@@ -40,56 +74,143 @@ declare module ${JSON.stringify(moduleName)} {
40
74
  }
41
75
  }
42
76
  `;
43
- const storageTypes = (configPath, nitroMajor, single) => `import type config from ${JSON.stringify(configPath)}
77
+ const storageTypes = (configPath, nitroMajor) => `import type config from ${JSON.stringify(configPath)}
44
78
  import type { SingleStorage, StorageRegistry } from 'nuxt-files-sdk/runtime'
45
79
 
46
80
  declare module 'nuxt-files-sdk/runtime' {
47
- ${single ? "interface NuxtFilesSingleStorage { value: SingleStorage<typeof config> }" : "interface NuxtFilesStorageRegistry extends StorageRegistry<typeof config> {}"}
81
+ interface NuxtFilesSingleStorage { value: SingleStorage<typeof config> }
82
+ interface NuxtFilesStorageRegistry extends StorageRegistry<typeof config> {}
48
83
  }
49
84
  ${hookTypes(nitroMajor >= 3 ? "nitro/types" : "nitropack/types")}
50
85
  export {}
51
86
  `;
52
87
  const setupNitroFilesIntegration = async (nitro, options) => {
53
88
  const configPath = options.configPath.replaceAll("\\", "/");
54
- const config = await createJiti(import.meta.url, {
55
- ...nitro.options.alias ? { alias: nitro.options.alias } : {},
56
- interopDefault: true,
57
- moduleCache: false
58
- }).import(configPath, { default: true });
59
- const { adapters, single } = selectedAdapters(config, options.development);
89
+ const config = await loadFilesConfig({
90
+ configPath,
91
+ environments: options.environments,
92
+ alias: nitro.options.alias,
93
+ injectImports: nitro.unimport?.injectImports.bind(nitro.unimport)
94
+ });
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("\\", "/")];
112
+ });
113
+ const routes = gatewayRoutes(config);
114
+ const { adapters } = selected;
60
115
  const providers = providerCode(adapters);
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
+ }
61
140
  nitro.unimport?.getInternalContext().addons.push({
62
141
  name: "nuxt-files-sdk-jsdoc",
63
- declaration: (declarations) => declarations.replace(/^(\s*)(const useServerFiles: typeof .*\.useServerFiles)$/mu, "$1/** Return the project's Files client, including its configured plugin extensions. */\n$1const useServerFiles: typeof import('nuxt-files-sdk/runtime').useServerFiles")
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}`)
64
143
  });
65
144
  const externals = nitro.options.externals ??= {};
66
145
  (externals.inline ??= []).push("nuxt-files-sdk");
67
146
  if (!nitro.options.dev) externals.inline.push("files-sdk");
68
- const directory = resolve(nitro.options.buildDir, "nuxt-files-sdk");
69
- const pluginPath = resolve(directory, options.development ? "plugin.dev.mjs" : "plugin.mjs");
70
- const typesPath = resolve(directory, "storage-registry.d.ts");
71
- externals.inline.push(pluginPath.replaceAll("\\", "/"), configPath);
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);
72
156
  nitro.options.plugins.push(pluginPath.replaceAll("\\", "/"));
73
- nitro.hooks.hook("types:extend", async (types) => {
157
+ writeRuntime = async () => {
74
158
  await mkdir(directory, { recursive: true });
75
- await Promise.all([writeFile(pluginPath, `import config from ${JSON.stringify(configPath)}
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("\\", "/"))}
76
167
  ${providers.imports}
77
- import { configureFiles } from 'nuxt-files-sdk/runtime'
168
+ import { configureFiles } from ${JSON.stringify(internalPath)}
78
169
 
79
170
  export default (nitroApp) => configureFiles(config, {
80
- development: ${JSON.stringify(options.development)},
81
171
  factories: { ${providers.factories} },
172
+ environment: ${JSON.stringify(environment)},
82
173
  hooks: {
83
174
  onAction: (event, storage) => nitroApp.hooks.callHook('files:action', { event, storage }),
84
175
  onError: (event, storage) => nitroApp.hooks.callHook('files:error', { event, storage }),
85
176
  onRetry: (event, storage) => nitroApp.hooks.callHook('files:retry', { event, storage }),
86
177
  },
87
178
  })
88
- `), writeFile(typesPath, storageTypes(configPath, nitro.meta?.majorVersion ?? ("routing" in nitro ? 3 : 2), single))]);
89
- types.tsConfig?.include?.push(typesPath);
90
- });
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;
91
212
  };
92
213
  //#endregion
93
- export { providerCode, selectedAdapters, setupNitroFilesIntegration, storageTypes };
214
+ export { gatewayRoutes, optionalAwsSdkDependencies, providerCode, selectedAdapters, setupNitroFilesIntegration, storageTypes };
94
215
 
95
216
  //# sourceMappingURL=nitro.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"nitro.js","names":[],"sources":["../../src/integration/nitro.ts"],"sourcesContent":["import { mkdir, writeFile } from 'node:fs/promises'\nimport { resolve } from 'node:path'\n\nimport type { ProviderSlug } from 'files-sdk'\nimport { getProvider } from 'files-sdk/providers'\nimport { createJiti } from 'jiti'\n\nimport type { FilesConfig, StorageConfig } from '../config'\n\nexport interface NitroIntegration {\n meta?: { majorVersion?: number }\n options: {\n rootDir: string\n buildDir: string\n dev?: boolean\n plugins: string[]\n alias?: Record<string, string>\n externals?: { inline?: unknown[] }\n }\n unimport?: {\n getInternalContext(): {\n addons: {\n name?: string\n declaration?: (declarations: string) => string\n }[]\n }\n }\n hooks: {\n hook(\n name: 'types:extend',\n callback: (types: { tsConfig?: { include?: string[] } }) => void | Promise<void>,\n ): void\n }\n}\n\nexport interface NitroFilesIntegrationOptions {\n configPath: string\n development: boolean\n}\n\nconst isStorageConfig = (value: unknown): value is StorageConfig =>\n Boolean(value && typeof value === 'object' && 'adapter' in value && typeof value.adapter === 'string')\nconst isStorageRecord = (value: unknown): value is Record<string, StorageConfig> =>\n Boolean(value && typeof value === 'object' && Object.values(value).every(isStorageConfig))\n\nexport const selectedAdapters = (\n config: FilesConfig,\n development: boolean,\n): { adapters: ProviderSlug[]; single: boolean } => {\n const storage = config.storage\n const devStorage = config.devStorage\n if (!storage || (!isStorageConfig(storage) && (!isStorageRecord(storage) || Object.keys(storage).length === 0))) {\n throw new Error('[nuxt-files-sdk:invalid-config] At least one storage is required.')\n }\n const selected: StorageConfig[] = []\n const single = isStorageConfig(storage)\n if (single) {\n if (devStorage && !isStorageConfig(devStorage)) {\n throw new Error('[nuxt-files-sdk:invalid-config] A single storage requires a single devStorage override.')\n }\n selected.push(development && isStorageConfig(devStorage) ? devStorage : storage)\n } else {\n if (devStorage && !isStorageRecord(devStorage)) {\n throw new Error('[nuxt-files-sdk:invalid-config] Named storage requires named devStorage overrides.')\n }\n for (const name of Object.keys(devStorage ?? {})) {\n if (!Object.hasOwn(storage, name)) {\n throw new Error(`[nuxt-files-sdk:unknown-storage] Unknown storage \"${name}\".`)\n }\n }\n for (const [name, namedStorage] of Object.entries(storage)) {\n selected.push(development ? (devStorage?.[name] ?? namedStorage) : namedStorage)\n }\n }\n const adapters = [...new Set(selected.map(({ adapter }) => adapter))].toSorted()\n for (const adapter of adapters) {\n if (!getProvider(adapter)) {\n throw new Error(`[nuxt-files-sdk:unknown-adapter] Unknown adapter \"${adapter}\".`)\n }\n }\n return { adapters, single }\n}\n\nconst factoryName = (adapter: ProviderSlug): string =>\n adapter === 'cloudinary'\n ? 'cloudinaryAdapter'\n : adapter.replaceAll(/-([a-z0-9])/gu, (_, character: string) => character.toUpperCase())\n\nexport const providerCode = (adapters: ProviderSlug[]): { imports: string; factories: string } => ({\n imports: adapters\n .map(\n (adapter, index) =>\n `import { ${factoryName(adapter)} as provider${index} } from ${JSON.stringify(`files-sdk/${adapter}`)}`,\n )\n .join('\\n'),\n factories: adapters.map((adapter, index) => `${JSON.stringify(adapter)}: provider${index}`).join(', '),\n})\n\nconst hookTypes = (moduleName: 'nitropack/types' | 'nitro/types'): string => `\ndeclare module ${JSON.stringify(moduleName)} {\n interface NitroRuntimeHooks {\n 'files:action': (payload: { event: import('files-sdk').FilesActionEvent; storage?: string }) => void | Promise<void>\n 'files:error': (payload: { event: import('files-sdk').FilesErrorEvent; storage?: string }) => void | Promise<void>\n 'files:retry': (payload: { event: import('files-sdk').FilesRetryEvent; storage?: string }) => void | Promise<void>\n }\n}\n`\n\nexport const storageTypes = (\n configPath: string,\n nitroMajor: number,\n single: boolean,\n): string => `import type config from ${JSON.stringify(configPath)}\nimport type { SingleStorage, StorageRegistry } from 'nuxt-files-sdk/runtime'\n\ndeclare module 'nuxt-files-sdk/runtime' {\n ${single ? 'interface NuxtFilesSingleStorage { value: SingleStorage<typeof config> }' : 'interface NuxtFilesStorageRegistry extends StorageRegistry<typeof config> {}'}\n}\n${hookTypes(nitroMajor >= 3 ? 'nitro/types' : 'nitropack/types')}\nexport {}\n`\n\nexport const setupNitroFilesIntegration = async (\n nitro: NitroIntegration,\n options: NitroFilesIntegrationOptions,\n): Promise<void> => {\n const configPath = options.configPath.replaceAll('\\\\', '/')\n const config = await createJiti(import.meta.url, {\n ...(nitro.options.alias ? { alias: nitro.options.alias } : {}),\n interopDefault: true,\n moduleCache: false,\n }).import<FilesConfig>(configPath, { default: true })\n const { adapters, single } = selectedAdapters(config, options.development)\n const providers = providerCode(adapters)\n nitro.unimport?.getInternalContext().addons.push({\n name: 'nuxt-files-sdk-jsdoc',\n declaration: (declarations) =>\n declarations.replace(\n /^(\\s*)(const useServerFiles: typeof .*\\.useServerFiles)$/mu,\n \"$1/** Return the project's Files client, including its configured plugin extensions. */\\n$1const useServerFiles: typeof import('nuxt-files-sdk/runtime').useServerFiles\",\n ),\n })\n // Inline both packages so installed consumers also tree-shake the plugin barrel.\n const externals = (nitro.options.externals ??= {})\n ;(externals.inline ??= []).push('nuxt-files-sdk')\n // Nitro's single-file dev build would eagerly import every native provider SDK.\n if (!nitro.options.dev) externals.inline.push('files-sdk')\n const directory = resolve(nitro.options.buildDir, 'nuxt-files-sdk')\n const pluginPath = resolve(directory, options.development ? 'plugin.dev.mjs' : 'plugin.mjs')\n const typesPath = resolve(directory, 'storage-registry.d.ts')\n // Development also externalizes local .mjs files unless explicitly inlined.\n externals.inline.push(pluginPath.replaceAll('\\\\', '/'), configPath)\n nitro.options.plugins.push(pluginPath.replaceAll('\\\\', '/'))\n nitro.hooks.hook('types:extend', async (types) => {\n await mkdir(directory, { recursive: true })\n await Promise.all([\n writeFile(\n pluginPath,\n `import config from ${JSON.stringify(configPath)}\n${providers.imports}\nimport { configureFiles } from 'nuxt-files-sdk/runtime'\n\nexport default (nitroApp) => configureFiles(config, {\n development: ${JSON.stringify(options.development)},\n factories: { ${providers.factories} },\n hooks: {\n onAction: (event, storage) => nitroApp.hooks.callHook('files:action', { event, storage }),\n onError: (event, storage) => nitroApp.hooks.callHook('files:error', { event, storage }),\n onRetry: (event, storage) => nitroApp.hooks.callHook('files:retry', { event, storage }),\n },\n})\n`,\n ),\n // Older v2 and current v3 omit meta; only v3 exposes the routing API.\n writeFile(\n typesPath,\n storageTypes(configPath, nitro.meta?.majorVersion ?? ('routing' in nitro ? 3 : 2), single),\n ),\n ])\n types.tsConfig?.include?.push(typesPath)\n })\n}\n"],"mappings":";;;;;AAwCA,MAAM,mBAAmB,UACrB,QAAQ,SAAS,OAAO,UAAU,YAAY,aAAa,SAAS,OAAO,MAAM,YAAY,QAAQ;AACzG,MAAM,mBAAmB,UACrB,QAAQ,SAAS,OAAO,UAAU,YAAY,OAAO,OAAO,KAAK,CAAC,CAAC,MAAM,eAAe,CAAC;AAE7F,MAAa,oBACT,QACA,gBACgD;CAChD,MAAM,UAAU,OAAO;CACvB,MAAM,aAAa,OAAO;CAC1B,IAAI,CAAC,WAAY,CAAC,gBAAgB,OAAO,MAAM,CAAC,gBAAgB,OAAO,KAAK,OAAO,KAAK,OAAO,CAAC,CAAC,WAAW,IACxG,MAAM,IAAI,MAAM,mEAAmE;CAEvF,MAAM,WAA4B,CAAC;CACnC,MAAM,SAAS,gBAAgB,OAAO;CACtC,IAAI,QAAQ;EACR,IAAI,cAAc,CAAC,gBAAgB,UAAU,GACzC,MAAM,IAAI,MAAM,yFAAyF;EAE7G,SAAS,KAAK,eAAe,gBAAgB,UAAU,IAAI,aAAa,OAAO;CACnF,OAAO;EACH,IAAI,cAAc,CAAC,gBAAgB,UAAU,GACzC,MAAM,IAAI,MAAM,oFAAoF;EAExG,KAAK,MAAM,QAAQ,OAAO,KAAK,cAAc,CAAC,CAAC,GAC3C,IAAI,CAAC,OAAO,OAAO,SAAS,IAAI,GAC5B,MAAM,IAAI,MAAM,qDAAqD,KAAK,GAAG;EAGrF,KAAK,MAAM,CAAC,MAAM,iBAAiB,OAAO,QAAQ,OAAO,GACrD,SAAS,KAAK,cAAe,aAAa,SAAS,eAAgB,YAAY;CAEvF;CACA,MAAM,WAAW,CAAC,GAAG,IAAI,IAAI,SAAS,KAAK,EAAE,cAAc,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS;CAC/E,KAAK,MAAM,WAAW,UAClB,IAAI,CAAC,YAAY,OAAO,GACpB,MAAM,IAAI,MAAM,qDAAqD,QAAQ,GAAG;CAGxF,OAAO;EAAE;EAAU;CAAO;AAC9B;AAEA,MAAM,eAAe,YACjB,YAAY,eACN,sBACA,QAAQ,WAAW,kBAAkB,GAAG,cAAsB,UAAU,YAAY,CAAC;AAE/F,MAAa,gBAAgB,cAAsE;CAC/F,SAAS,SACJ,KACI,SAAS,UACN,YAAY,YAAY,OAAO,EAAE,cAAc,MAAM,UAAU,KAAK,UAAU,aAAa,SAAS,GAC5G,CAAC,CACA,KAAK,IAAI;CACd,WAAW,SAAS,KAAK,SAAS,UAAU,GAAG,KAAK,UAAU,OAAO,EAAE,YAAY,OAAO,CAAC,CAAC,KAAK,IAAI;AACzG;AAEA,MAAM,aAAa,eAA0D;iBAC5D,KAAK,UAAU,UAAU,EAAE;;;;;;;;AAS5C,MAAa,gBACT,YACA,YACA,WACS,2BAA2B,KAAK,UAAU,UAAU,EAAE;;;;IAI/D,SAAS,6EAA6E,+EAA+E;;EAEvK,UAAU,cAAc,IAAI,gBAAgB,iBAAiB,EAAE;;;AAIjE,MAAa,6BAA6B,OACtC,OACA,YACgB;CAChB,MAAM,aAAa,QAAQ,WAAW,WAAW,MAAM,GAAG;CAC1D,MAAM,SAAS,MAAM,WAAW,YAAY,KAAK;EAC7C,GAAI,MAAM,QAAQ,QAAQ,EAAE,OAAO,MAAM,QAAQ,MAAM,IAAI,CAAC;EAC5D,gBAAgB;EAChB,aAAa;CACjB,CAAC,CAAC,CAAC,OAAoB,YAAY,EAAE,SAAS,KAAK,CAAC;CACpD,MAAM,EAAE,UAAU,WAAW,iBAAiB,QAAQ,QAAQ,WAAW;CACzE,MAAM,YAAY,aAAa,QAAQ;CACvC,MAAM,UAAU,mBAAmB,CAAC,CAAC,OAAO,KAAK;EAC7C,MAAM;EACN,cAAc,iBACV,aAAa,QACT,8DACA,yKACJ;CACR,CAAC;CAED,MAAM,YAAa,MAAM,QAAQ,cAAc,CAAC;CAC/C,CAAC,UAAU,WAAW,CAAC,EAAA,CAAG,KAAK,gBAAgB;CAEhD,IAAI,CAAC,MAAM,QAAQ,KAAK,UAAU,OAAO,KAAK,WAAW;CACzD,MAAM,YAAY,QAAQ,MAAM,QAAQ,UAAU,gBAAgB;CAClE,MAAM,aAAa,QAAQ,WAAW,QAAQ,cAAc,mBAAmB,YAAY;CAC3F,MAAM,YAAY,QAAQ,WAAW,uBAAuB;CAE5D,UAAU,OAAO,KAAK,WAAW,WAAW,MAAM,GAAG,GAAG,UAAU;CAClE,MAAM,QAAQ,QAAQ,KAAK,WAAW,WAAW,MAAM,GAAG,CAAC;CAC3D,MAAM,MAAM,KAAK,gBAAgB,OAAO,UAAU;EAC9C,MAAM,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;EAC1C,MAAM,QAAQ,IAAI,CACd,UACI,YACA,sBAAsB,KAAK,UAAU,UAAU,EAAE;EAC/D,UAAU,QAAQ;;;;iBAIH,KAAK,UAAU,QAAQ,WAAW,EAAE;iBACpC,UAAU,UAAU;;;;;;;CAQzB,GAEA,UACI,WACA,aAAa,YAAY,MAAM,MAAM,iBAAiB,aAAa,QAAQ,IAAI,IAAI,MAAM,CAC7F,CACJ,CAAC;EACD,MAAM,UAAU,SAAS,KAAK,SAAS;CAC3C,CAAC;AACL"}
1
+ {"version":3,"file":"nitro.js","names":[],"sources":["../../src/integration/nitro.ts"],"sourcesContent":["import { mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { createRequire } from 'node:module'\nimport { resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nimport type { ProviderSlug } from 'files-sdk'\nimport { getProvider, listEnvVars } from 'files-sdk/providers'\n\nimport { loadFilesConfig } from '../config/load'\nimport { pruneFilesConfigSource } from '../config/prune'\nimport { normalizeFilesConfig } from '../runtime/normalize'\n\nexport interface NitroIntegration {\n meta?: { majorVersion?: number }\n options: {\n rootDir: string\n buildDir: string\n dev?: boolean\n static?: boolean\n preset?: string\n plugins: string[]\n handlers?: { route: string; handler: string }[]\n alias?: Record<string, string>\n externals?: { inline?: unknown[] }\n }\n unimport?: {\n injectImports(code: string, id?: string): Promise<{ code: string }>\n getInternalContext(): {\n addons: {\n name?: string\n declaration?: (declarations: string) => string\n }[]\n }\n }\n hooks: {\n hook(\n name: 'types:extend',\n callback: (types: {\n tsConfig?: {\n include?: string[]\n compilerOptions?: { paths?: Record<string, string[]> }\n }\n }) => void | Promise<void>,\n ): void\n }\n}\n\nexport interface NitroFilesIntegrationOptions {\n configPath: string\n environments: readonly string[]\n}\n\nconst AWS_CORE_DEPENDENCIES = [\n '@aws-sdk/client-s3',\n '@aws-sdk/s3-presigned-post',\n '@aws-sdk/s3-request-presigner',\n] as const\nconst AWS_MULTIPART_DEPENDENCY = '@aws-sdk/lib-storage'\nconst FETCH_CAPABLE_S3_ADAPTERS = new Set<ProviderSlug>(['minio', 'r2', 'rustfs'])\nconst WORKERD_PRESETS = new Set(['cloudflare-module', 'cloudflare-durable', 'cloudflare-pages'])\n\nexport const optionalAwsSdkDependencies = (\n adapters: ProviderSlug[],\n options: { nitroMajor: number; preset?: string | undefined; resolvable: (dependency: string) => boolean },\n): string[] => {\n if (options.nitroMajor >= 3 || !options.preset || !WORKERD_PRESETS.has(options.preset)) return []\n const s3Adapters = adapters.filter((adapter) => getProvider(adapter)?.peerDeps.includes('@aws-sdk/client-s3'))\n if (s3Adapters.length === 0) return []\n const optional = s3Adapters.every((adapter) => FETCH_CAPABLE_S3_ADAPTERS.has(adapter))\n ? [...AWS_CORE_DEPENDENCIES, AWS_MULTIPART_DEPENDENCY]\n : [AWS_MULTIPART_DEPENDENCY]\n return optional.filter((dependency) => !options.resolvable(dependency))\n}\n\nconst nitroMajorVersion = (nitro: NitroIntegration): number => nitro.meta?.majorVersion ?? ('routing' in nitro ? 3 : 2)\n\nexport const selectedAdapters = (config: unknown): { adapters: ProviderSlug[]; single: boolean } => {\n const entries = normalizeFilesConfig(config)\n const single = entries.has(undefined)\n const adapters = [\n ...new Set(\n [...entries.values()]\n .map(({ storage }) => storage.adapter)\n .filter((adapter): adapter is ProviderSlug => typeof adapter === 'string'),\n ),\n ].toSorted()\n for (const adapter of adapters) {\n if (!getProvider(adapter)) {\n throw new Error(`[nuxt-files-sdk:unknown-adapter] Unknown adapter \"${adapter}\".`)\n }\n }\n return { adapters, single }\n}\n\nexport const gatewayRoutes = (config: unknown): { path: string; storage?: string }[] => {\n const routes = config && typeof config === 'object' && 'routes' in config ? config.routes : undefined\n if (routes === undefined) return []\n if (!Array.isArray(routes)) throw new Error('[nuxt-files-sdk:invalid-route] routes must be an array.')\n const storages = normalizeFilesConfig(config)\n const paths = new Set<string>()\n const selected: { path: string; storage?: string }[] = []\n for (const route of routes as unknown[]) {\n if (\n !route ||\n typeof route !== 'object' ||\n !('path' in route) ||\n typeof route.path !== 'string' ||\n !/^\\/(?:[\\w.~-]+(?:\\/[\\w.~-]+)*)?$/u.test(route.path)\n ) {\n throw new Error('[nuxt-files-sdk:invalid-route] Each route needs a static absolute path.')\n }\n if (paths.has(route.path)) throw new Error(`[nuxt-files-sdk:duplicate-route] Duplicate route \"${route.path}\".`)\n paths.add(route.path)\n const name = 'storage' in route ? route.storage : undefined\n if (storages.has(undefined) ? name !== undefined : typeof name !== 'string' || !storages.has(name)) {\n throw new Error(`[nuxt-files-sdk:unknown-storage] Invalid storage for route \"${route.path}\".`)\n }\n selected.push(typeof name === 'string' ? { path: route.path, storage: name } : { path: route.path })\n }\n return selected\n}\n\nconst factoryName = (adapter: ProviderSlug): string =>\n adapter === 'cloudinary'\n ? 'cloudinaryAdapter'\n : adapter.replaceAll(/-([a-z0-9])/gu, (_, character: string) => character.toUpperCase())\n\nexport const providerCode = (adapters: ProviderSlug[]): { imports: string; factories: string } => ({\n imports: adapters\n .map(\n (adapter, index) =>\n `import { ${factoryName(adapter)} as provider${index} } from ${JSON.stringify(`files-sdk/${adapter}`)}`,\n )\n .join('\\n'),\n factories: adapters.map((adapter, index) => `${JSON.stringify(adapter)}: provider${index}`).join(', '),\n})\n\nconst hookTypes = (moduleName: 'nitropack/types' | 'nitro/types'): string => `\ndeclare module ${JSON.stringify(moduleName)} {\n interface NitroRuntimeHooks {\n 'files:action': (payload: { event: import('files-sdk').FilesActionEvent; storage?: string }) => void | Promise<void>\n 'files:error': (payload: { event: import('files-sdk').FilesErrorEvent; storage?: string }) => void | Promise<void>\n 'files:retry': (payload: { event: import('files-sdk').FilesRetryEvent; storage?: string }) => void | Promise<void>\n }\n}\n`\n\nexport const storageTypes = (\n configPath: string,\n nitroMajor: number,\n): string => `import type config from ${JSON.stringify(configPath)}\nimport type { SingleStorage, StorageRegistry } from 'nuxt-files-sdk/runtime'\n\ndeclare module 'nuxt-files-sdk/runtime' {\n interface NuxtFilesSingleStorage { value: SingleStorage<typeof config> }\n interface NuxtFilesStorageRegistry extends StorageRegistry<typeof config> {}\n}\n${hookTypes(nitroMajor >= 3 ? 'nitro/types' : 'nitropack/types')}\nexport {}\n`\n\nexport const setupNitroFilesIntegration = async (\n nitro: NitroIntegration,\n options: NitroFilesIntegrationOptions,\n): Promise<boolean> => {\n const configPath = options.configPath.replaceAll('\\\\', '/')\n const config = await loadFilesConfig({\n configPath,\n environments: options.environments,\n alias: nitro.options.alias,\n injectImports: nitro.unimport?.injectImports.bind(nitro.unimport),\n })\n if (!config) return false\n const selected = selectedAdapters(config)\n const directory = resolve(nitro.options.rootDir, nitro.options.buildDir, 'nuxt-files-sdk')\n const typesPath = resolve(directory, 'storage-registry.d.ts')\n let writeRuntime: (() => Promise<void>) | undefined\n const writeTypes = async (): Promise<void> => {\n await mkdir(directory, { recursive: true })\n await writeFile(typesPath, storageTypes(configPath, nitroMajorVersion(nitro)))\n }\n await writeTypes()\n nitro.hooks.hook('types:extend', async (types) => {\n await writeTypes()\n await writeRuntime?.()\n const tsConfig = (types.tsConfig ??= {})\n ;(tsConfig.include ??= []).push(typesPath)\n const paths = ((tsConfig.compilerOptions ??= {}).paths ??= {})\n paths['files-sdk'] ??= [resolve(nitro.options.rootDir, 'node_modules/files-sdk').replaceAll('\\\\', '/')]\n })\n const routes = gatewayRoutes(config)\n const { adapters } = selected\n const providers = providerCode(adapters)\n const internalPath = fileURLToPath(new URL('../runtime/internal.js', import.meta.url)).replaceAll('\\\\', '/')\n const environment = Object.fromEntries(\n adapters.map((adapter) => [\n adapter,\n listEnvVars(adapter)\n .filter((variable) => variable.readBy === 'files-sdk')\n .map((variable) => [variable.key, ...(variable.aliases ?? [])]),\n ]),\n )\n const require = createRequire(resolve(nitro.options.rootDir, 'package.json'))\n const aliases = nitro.options.alias ?? {}\n const awsShims = optionalAwsSdkDependencies(adapters, {\n nitroMajor: nitroMajorVersion(nitro),\n preset: nitro.options.preset,\n resolvable: (dependency) => {\n if (Object.hasOwn(aliases, dependency)) return true\n try {\n require.resolve(dependency)\n return true\n } catch {\n return false\n }\n },\n })\n const shimFiles = awsShims.map((dependency) => ({\n dependency,\n path: resolve(directory, `${dependency.replaceAll(/[^a-z0-9]+/giu, '-')}.mjs`),\n }))\n if (shimFiles.length > 0) {\n nitro.options.alias = aliases\n for (const { dependency, path } of shimFiles) aliases[dependency] = path.replaceAll('\\\\', '/')\n }\n nitro.unimport?.getInternalContext().addons.push({\n name: 'nuxt-files-sdk-jsdoc',\n declaration: (declarations) =>\n declarations.replace(\n /^([ \\t]*)const (useServerFiles|syncFiles|transferFiles): typeof .*\\.\\2$/gmu,\n (_, indent: string, name: string) =>\n `${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}`,\n ),\n })\n // Inline both packages so installed consumers also tree-shake the plugin barrel.\n const externals = (nitro.options.externals ??= {})\n ;(externals.inline ??= []).push('nuxt-files-sdk')\n // Nitro's single-file dev build would eagerly import every native provider SDK.\n if (!nitro.options.dev) externals.inline.push('files-sdk')\n const pluginPath = resolve(directory, nitro.options.dev ? 'plugin.dev.mjs' : 'plugin.mjs')\n const resolvedPath = resolve(directory, nitro.options.dev ? 'resolved.dev.mjs' : 'resolved.mjs')\n const selectedPath = resolve(directory, nitro.options.dev ? 'selected.dev.ts' : 'selected.ts')\n const routePaths = routes.map((_, index) =>\n resolve(directory, `gateway-${index}${nitro.options.dev ? '.dev' : ''}.mjs`).replaceAll('\\\\', '/'),\n )\n for (const [index, route] of routes.entries()) {\n ;(nitro.options.handlers ??= []).push({ route: route.path, handler: routePaths[index]! })\n }\n // Development also externalizes local .mjs files unless explicitly inlined.\n externals.inline.push(\n pluginPath.replaceAll('\\\\', '/'),\n resolvedPath.replaceAll('\\\\', '/'),\n selectedPath.replaceAll('\\\\', '/'),\n ...routePaths,\n )\n nitro.options.plugins.push(pluginPath.replaceAll('\\\\', '/'))\n writeRuntime = async (): Promise<void> => {\n await mkdir(directory, { recursive: true })\n await Promise.all(\n shimFiles.map(({ dependency, path }) =>\n writeFile(\n path,\n `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`,\n ),\n ),\n )\n const originalSource = await readFile(configPath, 'utf8')\n const importedSource = nitro.unimport\n ? (await nitro.unimport.injectImports(originalSource, configPath)).code\n : originalSource\n await writeFile(selectedPath, pruneFilesConfigSource(importedSource, configPath, options.environments))\n const mergePath = fileURLToPath(new URL('../config/merge.js', import.meta.url)).replaceAll('\\\\', '/')\n const selectedBranches = options.environments\n .flatMap((name) => [`raw[${JSON.stringify(`$${name}`)}]`, `raw.$env?.[${JSON.stringify(name)}]`])\n .toReversed()\n await writeFile(\n resolvedPath,\n `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`,\n )\n await writeFile(\n pluginPath,\n `import config from ${JSON.stringify(resolvedPath.replaceAll('\\\\', '/'))}\n${providers.imports}\nimport { configureFiles } from ${JSON.stringify(internalPath)}\n\nexport default (nitroApp) => configureFiles(config, {\n factories: { ${providers.factories} },\n environment: ${JSON.stringify(environment)},\n hooks: {\n onAction: (event, storage) => nitroApp.hooks.callHook('files:action', { event, storage }),\n onError: (event, storage) => nitroApp.hooks.callHook('files:error', { event, storage }),\n onRetry: (event, storage) => nitroApp.hooks.callHook('files:retry', { event, storage }),\n },\n})\n`,\n )\n await Promise.all(\n routePaths.map((path, index) => {\n const route = routes[index]!\n const handler =\n nitroMajorVersion(nitro) >= 3 ? 'router.handle(event.req)' : 'createRouteHandler(router)(event)'\n return writeFile(\n path,\n `import config from ${JSON.stringify(resolvedPath.replaceAll('\\\\', '/'))}\nimport { createFilesRouter } from 'files-sdk/api'\n${nitroMajorVersion(nitro) >= 3 ? '' : \"import { createRouteHandler } from 'files-sdk/nitro'\"}\nimport { getFiles } from ${JSON.stringify(internalPath)}\n\nconst route = config.routes[${index}]\nconst environmentSecret = typeof process === 'undefined' ? undefined : process.env?.FILES_API_SECRET\nconst secret = route.authorize\n ? route.secret || environmentSecret || crypto.randomUUID() + crypto.randomUUID()\n : route.secret\nif (route.authorize && !route.secret && !environmentSecret) {\n console.warn('[nuxt-files-sdk:gateway-secret] Set FILES_API_SECRET for upload tokens shared across processes.')\n}\nlet sharedRouter\nconst makeRouter = (event) => createFilesRouter({\n ...route,\n files: () => getFiles(${route.storage === undefined ? '' : JSON.stringify(route.storage)}),\n secret,\n authorize: route.authorize && ((context) => route.authorize({ ...context, event })),\n})\nexport default (event) => {\n const router = route.authorize ? makeRouter(event) : (sharedRouter ??= makeRouter(event))\n return ${handler}\n}\n`,\n )\n }),\n )\n }\n await writeRuntime()\n return true\n}\n"],"mappings":"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"}
package/dist/module.d.ts CHANGED
@@ -1,7 +1,5 @@
1
+ import { FilesDevtoolsOptions } from "./devtools/enabled.js";
1
2
  import { NitroIntegration } from "./integration/nitro.js";
2
- import { FilesForStorage, FilesProviderFactories, FilesProviderFactory, FilesRegistry, FilesRuntimeHooks, SingleStorage, StorageRegistry } from "./runtime/registry.js";
3
- import { NuxtFilesSingleStorage, NuxtFilesStorageRegistry, configureFiles, inspectFiles, useServerFiles } from "./runtime.js";
4
- export * from "files-sdk";
5
3
  //#region src/module.d.ts
6
4
  declare module '@nuxt/schema' {
7
5
  interface NuxtHooks {
@@ -12,11 +10,11 @@ declare module '@nuxt/schema' {
12
10
  export interface ModuleOptions {
13
11
  /** Path to the Files configuration module, relative to the Nuxt root directory. */
14
12
  config: string;
15
- /** Enable Files SDK development diagnostics when Nuxt DevTools is available. */
16
- devtools: boolean;
13
+ /** Enable Files SDK development tools. File writes are enabled unless explicitly disabled. */
14
+ devtools: boolean | FilesDevtoolsOptions;
17
15
  }
18
16
  /** Install Files SDK storage configuration, server utilities, Vue composables, and development diagnostics in Nuxt. */
19
17
  declare const _default: import("@nuxt/schema").NuxtModule<ModuleOptions, ModuleOptions, false>;
20
18
  //#endregion
21
- export { type FilesForStorage, type FilesProviderFactories, type FilesProviderFactory, FilesRegistry, type FilesRuntimeHooks, NuxtFilesSingleStorage, NuxtFilesStorageRegistry, type SingleStorage, type StorageRegistry, configureFiles, _default as default, inspectFiles, useServerFiles };
19
+ export { type FilesDevtoolsOptions, _default as default };
22
20
  //# sourceMappingURL=module.d.ts.map
package/dist/module.js CHANGED
@@ -1,10 +1,8 @@
1
- import { shouldEnableFilesDevtools } from "./devtools/enabled.js";
1
+ import { filesDevtoolsWriteEnabled, shouldEnableFilesDevtools } from "./devtools/enabled.js";
2
2
  import { setupNitroFilesIntegration } from "./integration/nitro.js";
3
- import { FilesRegistry } from "./runtime/registry.js";
4
- import { configureFiles, inspectFiles, useServerFiles } from "./runtime.js";
3
+ import { randomUUID } from "node:crypto";
5
4
  import { resolve } from "node:path";
6
5
  import { addImports, addServerImports, defineNuxtModule, getNuxtModuleVersion } from "@nuxt/kit";
7
- export * from "files-sdk";
8
6
  //#region src/module.ts
9
7
  /** Install Files SDK storage configuration, server utilities, Vue composables, and development diagnostics in Nuxt. */
10
8
  var module_default = defineNuxtModule({
@@ -19,16 +17,40 @@ var module_default = defineNuxtModule({
19
17
  },
20
18
  async setup(options, nuxt) {
21
19
  const configPath = resolve(nuxt.options.rootDir, options.config);
22
- nuxt.hook("nitro:init", (nitro) => setupNitroFilesIntegration(nitro, {
23
- configPath,
24
- development: nuxt.options.dev
25
- }));
20
+ (nuxt.options.typescript.tsConfig.include ??= []).push(configPath);
21
+ const paths = (nuxt.options.typescript.tsConfig.compilerOptions ??= {}).paths ??= {};
22
+ paths["files-sdk"] ??= [resolve(nuxt.options.rootDir, "node_modules/files-sdk").replaceAll("\\", "/")];
23
+ let active = false;
24
+ nuxt.hook("nitro:init", async (nitro) => {
25
+ active = await setupNitroFilesIntegration(nitro, {
26
+ configPath,
27
+ environments: nitro.options.static ? ["production", "prerender"] : [nuxt.options.envName || (nuxt.options.dev ? "development" : "production")]
28
+ });
29
+ });
26
30
  nuxt.hook("prepare:types", ({ references }) => {
27
- references.push({ path: resolve(nuxt.options.buildDir, "nuxt-files-sdk/storage-registry.d.ts") });
31
+ if (active) references.push({ path: resolve(nuxt.options.buildDir, "nuxt-files-sdk/storage-registry.d.ts") });
28
32
  });
29
- addServerImports({
30
- name: "useServerFiles",
31
- from: "nuxt-files-sdk/runtime"
33
+ addServerImports([
34
+ {
35
+ name: "defineFilesConfig",
36
+ from: "nuxt-files-sdk/config"
37
+ },
38
+ {
39
+ name: "useServerFiles",
40
+ from: "nuxt-files-sdk/runtime"
41
+ },
42
+ {
43
+ name: "syncFiles",
44
+ from: "nuxt-files-sdk/runtime"
45
+ },
46
+ {
47
+ name: "transferFiles",
48
+ from: "nuxt-files-sdk/runtime"
49
+ }
50
+ ]);
51
+ addImports({
52
+ name: "defineFilesConfig",
53
+ from: "nuxt-files-sdk/config"
32
54
  });
33
55
  for (const name of [
34
56
  "useFiles",
@@ -42,11 +64,12 @@ var module_default = defineNuxtModule({
42
64
  if (shouldEnableFilesDevtools(nuxt.options.dev, options.devtools, nuxt.options.devtools)) {
43
65
  const version = await getNuxtModuleVersion("@nuxt/devtools", nuxt);
44
66
  const { setupFilesDevtools } = await import("./devtools/index.js");
45
- setupFilesDevtools(nuxt, version || "3");
67
+ const secrets = { token: randomUUID() };
68
+ setupFilesDevtools(nuxt, version || "3", filesDevtoolsWriteEnabled(options.devtools), secrets);
46
69
  }
47
70
  }
48
71
  });
49
72
  //#endregion
50
- export { FilesRegistry, configureFiles, module_default as default, inspectFiles, useServerFiles };
73
+ export { module_default as default };
51
74
 
52
75
  //# sourceMappingURL=module.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"module.js","names":[],"sources":["../src/module.ts"],"sourcesContent":["import { resolve } from 'node:path'\n\nimport { addImports, addServerImports, defineNuxtModule, getNuxtModuleVersion } from '@nuxt/kit'\nimport type { Nuxt } from '@nuxt/schema'\n\nimport { shouldEnableFilesDevtools } from './devtools/enabled'\nimport { setupNitroFilesIntegration, type NitroIntegration } from './integration/nitro'\n\ndeclare module '@nuxt/schema' {\n interface NuxtHooks {\n 'nitro:init': (nitro: NitroIntegration) => void | Promise<void>\n }\n}\n\n/** Options for the Nuxt Files SDK module. */\nexport interface ModuleOptions {\n /** Path to the Files configuration module, relative to the Nuxt root directory. */\n config: string\n /** Enable Files SDK development diagnostics when Nuxt DevTools is available. */\n devtools: boolean\n}\n\n/** Install Files SDK storage configuration, server utilities, Vue composables, and development diagnostics in Nuxt. */\nexport default defineNuxtModule<ModuleOptions>({\n meta: {\n name: 'nuxt-files-sdk',\n configKey: 'files',\n compatibility: { nuxt: '^4.0.0 || ^5.0.0' },\n },\n defaults: {\n config: 'files.config.ts',\n devtools: true,\n },\n async setup(options, nuxt: Nuxt) {\n const configPath = resolve(nuxt.options.rootDir, options.config)\n nuxt.hook('nitro:init', (nitro) =>\n setupNitroFilesIntegration(nitro, {\n configPath,\n development: nuxt.options.dev,\n }),\n )\n nuxt.hook('prepare:types', ({ references }) => {\n references.push({ path: resolve(nuxt.options.buildDir, 'nuxt-files-sdk/storage-registry.d.ts') })\n })\n\n addServerImports({ name: 'useServerFiles', from: 'nuxt-files-sdk/runtime' })\n for (const name of ['useFiles', 'useFile', 'useList', 'useSearch']) {\n addImports({ name, from: 'files-sdk/vue' })\n }\n\n if (shouldEnableFilesDevtools(nuxt.options.dev, options.devtools, nuxt.options.devtools)) {\n const version = await getNuxtModuleVersion('@nuxt/devtools', nuxt)\n const { setupFilesDevtools } = await import('./devtools')\n setupFilesDevtools(nuxt, version || '3')\n }\n },\n})\n\nexport * from 'files-sdk'\nexport * from './runtime'\n"],"mappings":";;;;;;;;;AAuBA,IAAA,iBAAe,iBAAgC;CAC3C,MAAM;EACF,MAAM;EACN,WAAW;EACX,eAAe,EAAE,MAAM,mBAAmB;CAC9C;CACA,UAAU;EACN,QAAQ;EACR,UAAU;CACd;CACA,MAAM,MAAM,SAAS,MAAY;EAC7B,MAAM,aAAa,QAAQ,KAAK,QAAQ,SAAS,QAAQ,MAAM;EAC/D,KAAK,KAAK,eAAe,UACrB,2BAA2B,OAAO;GAC9B;GACA,aAAa,KAAK,QAAQ;EAC9B,CAAC,CACL;EACA,KAAK,KAAK,kBAAkB,EAAE,iBAAiB;GAC3C,WAAW,KAAK,EAAE,MAAM,QAAQ,KAAK,QAAQ,UAAU,sCAAsC,EAAE,CAAC;EACpG,CAAC;EAED,iBAAiB;GAAE,MAAM;GAAkB,MAAM;EAAyB,CAAC;EAC3E,KAAK,MAAM,QAAQ;GAAC;GAAY;GAAW;GAAW;EAAW,GAC7D,WAAW;GAAE;GAAM,MAAM;EAAgB,CAAC;EAG9C,IAAI,0BAA0B,KAAK,QAAQ,KAAK,QAAQ,UAAU,KAAK,QAAQ,QAAQ,GAAG;GACtF,MAAM,UAAU,MAAM,qBAAqB,kBAAkB,IAAI;GACjE,MAAM,EAAE,uBAAuB,MAAM,OAAO;GAC5C,mBAAmB,MAAM,WAAW,GAAG;EAC3C;CACJ;AACJ,CAAC"}
1
+ {"version":3,"file":"module.js","names":[],"sources":["../src/module.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto'\nimport { resolve } from 'node:path'\n\nimport { addImports, addServerImports, defineNuxtModule, getNuxtModuleVersion } from '@nuxt/kit'\nimport type { Nuxt } from '@nuxt/schema'\n\nimport { filesDevtoolsWriteEnabled, shouldEnableFilesDevtools, type FilesDevtoolsOptions } from './devtools/enabled'\nimport { setupNitroFilesIntegration, type NitroIntegration } from './integration/nitro'\n\ndeclare module '@nuxt/schema' {\n interface NuxtHooks {\n 'nitro:init': (nitro: NitroIntegration) => void | Promise<void>\n }\n}\n\n/** Options for the Nuxt Files SDK module. */\nexport interface ModuleOptions {\n /** Path to the Files configuration module, relative to the Nuxt root directory. */\n config: string\n /** Enable Files SDK development tools. File writes are enabled unless explicitly disabled. */\n devtools: boolean | FilesDevtoolsOptions\n}\n\n/** Install Files SDK storage configuration, server utilities, Vue composables, and development diagnostics in Nuxt. */\nexport default defineNuxtModule<ModuleOptions>({\n meta: {\n name: 'nuxt-files-sdk',\n configKey: 'files',\n compatibility: { nuxt: '^4.0.0 || ^5.0.0' },\n },\n defaults: {\n config: 'files.config.ts',\n devtools: true,\n },\n async setup(options, nuxt: Nuxt) {\n const configPath = resolve(nuxt.options.rootDir, options.config)\n ;(nuxt.options.typescript.tsConfig.include ??= []).push(configPath)\n const paths = ((nuxt.options.typescript.tsConfig.compilerOptions ??= {}).paths ??= {})\n paths['files-sdk'] ??= [resolve(nuxt.options.rootDir, 'node_modules/files-sdk').replaceAll('\\\\', '/')]\n let active = false\n nuxt.hook('nitro:init', async (nitro) => {\n active = await setupNitroFilesIntegration(nitro, {\n configPath,\n environments: nitro.options.static\n ? ['production', 'prerender']\n : [nuxt.options.envName || (nuxt.options.dev ? 'development' : 'production')],\n })\n })\n nuxt.hook('prepare:types', ({ references }) => {\n if (active)\n references.push({ path: resolve(nuxt.options.buildDir, 'nuxt-files-sdk/storage-registry.d.ts') })\n })\n\n addServerImports([\n { name: 'defineFilesConfig', from: 'nuxt-files-sdk/config' },\n { name: 'useServerFiles', from: 'nuxt-files-sdk/runtime' },\n { name: 'syncFiles', from: 'nuxt-files-sdk/runtime' },\n { name: 'transferFiles', from: 'nuxt-files-sdk/runtime' },\n ])\n addImports({ name: 'defineFilesConfig', from: 'nuxt-files-sdk/config' })\n for (const name of ['useFiles', 'useFile', 'useList', 'useSearch']) {\n addImports({ name, from: 'files-sdk/vue' })\n }\n\n if (shouldEnableFilesDevtools(nuxt.options.dev, options.devtools, nuxt.options.devtools)) {\n const version = await getNuxtModuleVersion('@nuxt/devtools', nuxt)\n const { setupFilesDevtools } = await import('./devtools')\n const secrets = { token: randomUUID() }\n setupFilesDevtools(nuxt, version || '3', filesDevtoolsWriteEnabled(options.devtools), secrets)\n }\n },\n})\n\nexport type { FilesDevtoolsOptions } from './devtools/enabled'\n"],"mappings":";;;;;;;AAwBA,IAAA,iBAAe,iBAAgC;CAC3C,MAAM;EACF,MAAM;EACN,WAAW;EACX,eAAe,EAAE,MAAM,mBAAmB;CAC9C;CACA,UAAU;EACN,QAAQ;EACR,UAAU;CACd;CACA,MAAM,MAAM,SAAS,MAAY;EAC7B,MAAM,aAAa,QAAQ,KAAK,QAAQ,SAAS,QAAQ,MAAM;EAC9D,CAAC,KAAK,QAAQ,WAAW,SAAS,YAAY,CAAC,EAAA,CAAG,KAAK,UAAU;EAClE,MAAM,QAAS,CAAC,KAAK,QAAQ,WAAW,SAAS,oBAAoB,CAAC,EAAA,CAAG,UAAU,CAAC;EACpF,MAAM,iBAAiB,CAAC,QAAQ,KAAK,QAAQ,SAAS,wBAAwB,CAAC,CAAC,WAAW,MAAM,GAAG,CAAC;EACrG,IAAI,SAAS;EACb,KAAK,KAAK,cAAc,OAAO,UAAU;GACrC,SAAS,MAAM,2BAA2B,OAAO;IAC7C;IACA,cAAc,MAAM,QAAQ,SACtB,CAAC,cAAc,WAAW,IAC1B,CAAC,KAAK,QAAQ,YAAY,KAAK,QAAQ,MAAM,gBAAgB,aAAa;GACpF,CAAC;EACL,CAAC;EACD,KAAK,KAAK,kBAAkB,EAAE,iBAAiB;GAC3C,IAAI,QACA,WAAW,KAAK,EAAE,MAAM,QAAQ,KAAK,QAAQ,UAAU,sCAAsC,EAAE,CAAC;EACxG,CAAC;EAED,iBAAiB;GACb;IAAE,MAAM;IAAqB,MAAM;GAAwB;GAC3D;IAAE,MAAM;IAAkB,MAAM;GAAyB;GACzD;IAAE,MAAM;IAAa,MAAM;GAAyB;GACpD;IAAE,MAAM;IAAiB,MAAM;GAAyB;EAC5D,CAAC;EACD,WAAW;GAAE,MAAM;GAAqB,MAAM;EAAwB,CAAC;EACvE,KAAK,MAAM,QAAQ;GAAC;GAAY;GAAW;GAAW;EAAW,GAC7D,WAAW;GAAE;GAAM,MAAM;EAAgB,CAAC;EAG9C,IAAI,0BAA0B,KAAK,QAAQ,KAAK,QAAQ,UAAU,KAAK,QAAQ,QAAQ,GAAG;GACtF,MAAM,UAAU,MAAM,qBAAqB,kBAAkB,IAAI;GACjE,MAAM,EAAE,uBAAuB,MAAM,OAAO;GAC5C,MAAM,UAAU,EAAE,OAAO,WAAW,EAAE;GACtC,mBAAmB,MAAM,WAAW,KAAK,0BAA0B,QAAQ,QAAQ,GAAG,OAAO;EACjG;CACJ;AACJ,CAAC"}
package/dist/nitro.d.ts CHANGED
@@ -1,6 +1,4 @@
1
1
  import { NitroIntegration } from "./integration/nitro.js";
2
- import { FilesForStorage, FilesProviderFactories, FilesProviderFactory, FilesRegistry, FilesRuntimeHooks, SingleStorage, StorageRegistry } from "./runtime/registry.js";
3
- import { NuxtFilesSingleStorage, NuxtFilesStorageRegistry, configureFiles, inspectFiles, useServerFiles } from "./runtime.js";
4
2
  //#region src/nitro.d.ts
5
3
  /**
6
4
  * A structurally compatible Nitro v2/v3 module. Nitro loads this export
@@ -8,8 +6,8 @@ import { NuxtFilesSingleStorage, NuxtFilesStorageRegistry, configureFiles, inspe
8
6
  */
9
7
  declare const _default: {
10
8
  name: string;
11
- setup: (nitro: NitroIntegration) => Promise<void>;
9
+ setup: (nitro: NitroIntegration) => Promise<boolean>;
12
10
  };
13
11
  //#endregion
14
- export { type FilesForStorage, type FilesProviderFactories, type FilesProviderFactory, FilesRegistry, type FilesRuntimeHooks, NuxtFilesSingleStorage, NuxtFilesStorageRegistry, type SingleStorage, type StorageRegistry, configureFiles, _default as default, inspectFiles, useServerFiles };
12
+ export { _default as default };
15
13
  //# sourceMappingURL=nitro.d.ts.map
package/dist/nitro.js CHANGED
@@ -1,6 +1,4 @@
1
1
  import { setupNitroFilesIntegration } from "./integration/nitro.js";
2
- import { FilesRegistry } from "./runtime/registry.js";
3
- import { configureFiles, inspectFiles, useServerFiles } from "./runtime.js";
4
2
  import { resolve } from "node:path";
5
3
  //#region src/nitro.ts
6
4
  /**
@@ -11,10 +9,10 @@ var nitro_default = {
11
9
  name: "nuxt-files-sdk",
12
10
  setup: (nitro) => setupNitroFilesIntegration(nitro, {
13
11
  configPath: resolve(nitro.options.rootDir, "files.config.ts"),
14
- development: Boolean(nitro.options.dev)
12
+ environments: nitro.options.static ? ["production", "prerender"] : [nitro.options.dev ? "development" : "production"]
15
13
  })
16
14
  };
17
15
  //#endregion
18
- export { FilesRegistry, configureFiles, nitro_default as default, inspectFiles, useServerFiles };
16
+ export { nitro_default as default };
19
17
 
20
18
  //# sourceMappingURL=nitro.js.map
package/dist/nitro.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"nitro.js","names":[],"sources":["../src/nitro.ts"],"sourcesContent":["import { resolve } from 'node:path'\n\nimport { setupNitroFilesIntegration, type NitroIntegration } from './integration/nitro'\n\n/**\n * A structurally compatible Nitro v2/v3 module. Nitro loads this export\n * directly from `modules: ['nuxt-files-sdk/nitro']`.\n */\nexport default {\n name: 'nuxt-files-sdk',\n setup: (nitro: NitroIntegration) =>\n setupNitroFilesIntegration(nitro, {\n configPath: resolve(nitro.options.rootDir, 'files.config.ts'),\n development: Boolean(nitro.options.dev),\n }),\n}\n\nexport * from './runtime'\n"],"mappings":";;;;;;;;;AAQA,IAAA,gBAAe;CACX,MAAM;CACN,QAAQ,UACJ,2BAA2B,OAAO;EAC9B,YAAY,QAAQ,MAAM,QAAQ,SAAS,iBAAiB;EAC5D,aAAa,QAAQ,MAAM,QAAQ,GAAG;CAC1C,CAAC;AACT"}
1
+ {"version":3,"file":"nitro.js","names":[],"sources":["../src/nitro.ts"],"sourcesContent":["import { resolve } from 'node:path'\n\nimport { setupNitroFilesIntegration, type NitroIntegration } from './integration/nitro'\n\n/**\n * A structurally compatible Nitro v2/v3 module. Nitro loads this export\n * directly from `modules: ['nuxt-files-sdk/nitro']`.\n */\nexport default {\n name: 'nuxt-files-sdk',\n setup: (nitro: NitroIntegration) =>\n setupNitroFilesIntegration(nitro, {\n configPath: resolve(nitro.options.rootDir, 'files.config.ts'),\n environments: nitro.options.static\n ? ['production', 'prerender']\n : [nitro.options.dev ? 'development' : 'production'],\n }),\n}\n"],"mappings":";;;;;;;AAQA,IAAA,gBAAe;CACX,MAAM;CACN,QAAQ,UACJ,2BAA2B,OAAO;EAC9B,YAAY,QAAQ,MAAM,QAAQ,SAAS,iBAAiB;EAC5D,cAAc,MAAM,QAAQ,SACtB,CAAC,cAAc,WAAW,IAC1B,CAAC,MAAM,QAAQ,MAAM,gBAAgB,YAAY;CAC3D,CAAC;AACT"}
package/dist/package.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "0.0.4";
2
+ var version = "0.1.0";
3
3
  //#endregion
4
4
  export { version };
5
5
 
@@ -0,0 +1,11 @@
1
+ import { FilesConfig } from "../config.js";
2
+ import { FilesRegistry } from "./registry.js";
3
+ import { Files } from "files-sdk";
4
+ //#region src/runtime/internal.d.ts
5
+ /** Configure the process-local Files registry used by {@link useServerFiles}. */
6
+ export declare const configureFiles: <const C extends FilesConfig>(config: C, options: ConstructorParameters<typeof FilesRegistry<C>>[1]) => FilesRegistry<C>;
7
+ /** Return secret-free diagnostics for the configured process-local Files registry. */
8
+ export declare const inspectFiles: () => ReturnType<FilesRegistry['inspect']>;
9
+ export declare const getFiles: (name?: string) => Files;
10
+ //#endregion
11
+ //# sourceMappingURL=internal.d.ts.map
@@ -0,0 +1,30 @@
1
+ import { FilesRegistry } from "./registry.js";
2
+ //#region src/runtime/internal.ts
3
+ let registry;
4
+ let registryDiagnostic;
5
+ /** Configure the process-local Files registry used by {@link useServerFiles}. */
6
+ const configureFiles = (config, options) => {
7
+ try {
8
+ const value = new FilesRegistry(config, options);
9
+ registry = value;
10
+ registryDiagnostic = void 0;
11
+ return value;
12
+ } catch (error) {
13
+ registry = void 0;
14
+ registryDiagnostic = { code: "NUXT_FILES_INVALID_CONFIG" };
15
+ throw error;
16
+ }
17
+ };
18
+ /** Return secret-free diagnostics for the configured process-local Files registry. */
19
+ const inspectFiles = () => registry?.inspect() ?? {
20
+ storages: [],
21
+ diagnostics: [registryDiagnostic ?? { code: "NUXT_FILES_NOT_CONFIGURED" }]
22
+ };
23
+ const getFiles = (name) => {
24
+ if (!registry) throw new Error("[nuxt-files-sdk:not-configured] The Files registry has not been configured.");
25
+ return name === void 0 ? registry.get() : registry.get(name);
26
+ };
27
+ //#endregion
28
+ export { configureFiles, getFiles, inspectFiles };
29
+
30
+ //# sourceMappingURL=internal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal.js","names":[],"sources":["../../src/runtime/internal.ts"],"sourcesContent":["import type { Files } from 'files-sdk'\n\nimport type { FilesConfig } from '../config'\nimport { FilesRegistry, type RegistryDiagnostic } from './registry'\n\nlet registry: FilesRegistry | undefined\nlet registryDiagnostic: RegistryDiagnostic | undefined\n\n/** Configure the process-local Files registry used by {@link useServerFiles}. */\nexport const configureFiles = <const C extends FilesConfig>(\n config: C,\n options: ConstructorParameters<typeof FilesRegistry<C>>[1],\n): FilesRegistry<C> => {\n try {\n const value = new FilesRegistry(config, options)\n registry = value\n registryDiagnostic = undefined\n return value\n } catch (error) {\n registry = undefined\n registryDiagnostic = { code: 'NUXT_FILES_INVALID_CONFIG' }\n throw error\n }\n}\n\n/** Return secret-free diagnostics for the configured process-local Files registry. */\nexport const inspectFiles = (): ReturnType<FilesRegistry['inspect']> =>\n registry?.inspect() ?? {\n storages: [],\n diagnostics: [registryDiagnostic ?? { code: 'NUXT_FILES_NOT_CONFIGURED' }],\n }\n\nexport const getFiles = (name?: string): Files => {\n if (!registry) throw new Error('[nuxt-files-sdk:not-configured] The Files registry has not been configured.')\n return name === undefined ? registry.get() : (registry.get as (storage: string) => Files)(name)\n}\n"],"mappings":";;AAKA,IAAI;AACJ,IAAI;;AAGJ,MAAa,kBACT,QACA,YACmB;CACnB,IAAI;EACA,MAAM,QAAQ,IAAI,cAAc,QAAQ,OAAO;EAC/C,WAAW;EACX,qBAAqB,KAAA;EACrB,OAAO;CACX,SAAS,OAAO;EACZ,WAAW,KAAA;EACX,qBAAqB,EAAE,MAAM,4BAA4B;EACzD,MAAM;CACV;AACJ;;AAGA,MAAa,qBACT,UAAU,QAAQ,KAAK;CACnB,UAAU,CAAC;CACX,aAAa,CAAC,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAC7E;AAEJ,MAAa,YAAY,SAAyB;CAC9C,IAAI,CAAC,UAAU,MAAM,IAAI,MAAM,6EAA6E;CAC5G,OAAO,SAAS,KAAA,IAAY,SAAS,IAAI,IAAK,SAAS,IAAmC,IAAI;AAClG"}
@@ -0,0 +1,29 @@
1
+ //#region src/runtime/normalize.ts
2
+ const isObject = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
3
+ const isStorage = (value) => isObject(value) && (typeof value.adapter === "string" || typeof value.adapter === "function");
4
+ /** Validate one resolved config without selecting an environment or evaluating provider options. */
5
+ const normalizeFilesConfig = (config) => {
6
+ if (!isObject(config)) throw new Error("[nuxt-files-sdk:invalid-config] Files configuration must be an object.");
7
+ const { storage } = config;
8
+ if (!isObject(storage)) throw new Error("[nuxt-files-sdk:invalid-config] At least one storage is required.");
9
+ const entries = /* @__PURE__ */ new Map();
10
+ if (isStorage(storage)) entries.set(void 0, {
11
+ name: void 0,
12
+ storage
13
+ });
14
+ else {
15
+ if (!Object.keys(storage).length) throw new Error("[nuxt-files-sdk:invalid-config] At least one storage is required.");
16
+ for (const [name, value] of Object.entries(storage)) {
17
+ if (!isStorage(value)) throw new Error(`[nuxt-files-sdk:invalid-config] Invalid storage "${name}".`);
18
+ entries.set(name, {
19
+ name,
20
+ storage: value
21
+ });
22
+ }
23
+ }
24
+ return entries;
25
+ };
26
+ //#endregion
27
+ export { normalizeFilesConfig };
28
+
29
+ //# sourceMappingURL=normalize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.js","names":[],"sources":["../../src/runtime/normalize.ts"],"sourcesContent":["import type { StorageConfig } from '../config'\n\nexport interface StorageEntry {\n name: string | undefined\n storage: StorageConfig\n}\n\nconst isObject = (value: unknown): value is Record<string, unknown> =>\n value !== null && typeof value === 'object' && !Array.isArray(value)\nconst isStorage = (value: unknown): value is StorageConfig =>\n isObject(value) && (typeof value.adapter === 'string' || typeof value.adapter === 'function')\n\n/** Validate one resolved config without selecting an environment or evaluating provider options. */\nexport const normalizeFilesConfig = (config: unknown): Map<string | undefined, StorageEntry> => {\n if (!isObject(config)) throw new Error('[nuxt-files-sdk:invalid-config] Files configuration must be an object.')\n const { storage } = config\n if (!isObject(storage)) throw new Error('[nuxt-files-sdk:invalid-config] At least one storage is required.')\n const entries = new Map<string | undefined, StorageEntry>()\n if (isStorage(storage)) {\n entries.set(undefined, { name: undefined, storage })\n } else {\n if (!Object.keys(storage).length)\n throw new Error('[nuxt-files-sdk:invalid-config] At least one storage is required.')\n for (const [name, value] of Object.entries(storage)) {\n if (!isStorage(value)) throw new Error(`[nuxt-files-sdk:invalid-config] Invalid storage \"${name}\".`)\n entries.set(name, { name, storage: value })\n }\n }\n return entries\n}\n"],"mappings":";AAOA,MAAM,YAAY,UACd,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AACvE,MAAM,aAAa,UACf,SAAS,KAAK,MAAM,OAAO,MAAM,YAAY,YAAY,OAAO,MAAM,YAAY;;AAGtF,MAAa,wBAAwB,WAA2D;CAC5F,IAAI,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,MAAM,wEAAwE;CAC/G,MAAM,EAAE,YAAY;CACpB,IAAI,CAAC,SAAS,OAAO,GAAG,MAAM,IAAI,MAAM,mEAAmE;CAC3G,MAAM,0BAAU,IAAI,IAAsC;CAC1D,IAAI,UAAU,OAAO,GACjB,QAAQ,IAAI,KAAA,GAAW;EAAE,MAAM,KAAA;EAAW;CAAQ,CAAC;MAChD;EACH,IAAI,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,QACtB,MAAM,IAAI,MAAM,mEAAmE;EACvF,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,OAAO,GAAG;GACjD,IAAI,CAAC,UAAU,KAAK,GAAG,MAAM,IAAI,MAAM,oDAAoD,KAAK,GAAG;GACnG,QAAQ,IAAI,MAAM;IAAE;IAAM,SAAS;GAAM,CAAC;EAC9C;CACJ;CACA,OAAO;AACX"}