nuxt-files-sdk 0.1.0 → 0.2.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/dist/config/evaluate.js +149 -0
- package/dist/config/load.js +22 -40
- package/dist/config/merge.d.ts +1 -2
- package/dist/config/merge.js +0 -2
- package/dist/config/prepare.js +58 -0
- package/dist/config/prune.js +14 -13
- package/dist/config.d.ts +11 -6
- package/dist/config.js +0 -2
- package/dist/devtools/auth.js +0 -2
- package/dist/devtools/client/app.js +2 -2
- package/dist/devtools/client/index.html +4 -0
- package/dist/devtools/devframe.js +1 -3
- package/dist/devtools/diagnostics.d.ts +1 -2
- package/dist/devtools/diagnostics.js +0 -2
- package/dist/devtools/enabled.d.ts +1 -2
- package/dist/devtools/enabled.js +0 -2
- package/dist/devtools/files-read.d.ts +2 -3
- package/dist/devtools/files-read.js +0 -2
- package/dist/devtools/files-write.d.ts +2 -3
- package/dist/devtools/files-write.js +0 -2
- package/dist/devtools/files.js +7 -10
- package/dist/devtools/index.js +24 -26
- package/dist/devtools/nuxt-v3-handler.d.ts +1 -2
- package/dist/devtools/nuxt-v3-handler.js +0 -2
- package/dist/devtools/nuxt-v3.js +1 -3
- package/dist/devtools/nuxt-v4.js +4 -7
- package/dist/devtools/paths.js +8 -0
- package/dist/devtools/snapshot.d.ts +5 -14
- package/dist/devtools/snapshot.js +2 -9
- package/dist/devtools/token.d.ts +1 -2
- package/dist/devtools/token.js +0 -2
- package/dist/integration/capabilities.js +17 -0
- package/dist/integration/dependencies.d.ts +12 -0
- package/dist/integration/dependencies.js +67 -0
- package/dist/integration/diagnostics.d.ts +9 -0
- package/dist/integration/diagnostics.js +80 -0
- package/dist/integration/imports.js +83 -0
- package/dist/integration/nitro-dev-close.js +13 -0
- package/dist/integration/nitro-event.d.ts +7 -0
- package/dist/integration/nitro-event.js +24 -0
- package/dist/integration/nitro.d.ts +9 -2
- package/dist/integration/nitro.js +171 -92
- package/dist/integration/nuxt-diagnostics.js +23 -0
- package/dist/integration/nuxt.js +235 -0
- package/dist/integration/resolve.d.ts +1 -0
- package/dist/integration/resolve.js +113 -0
- package/dist/integration/terminal.js +20 -0
- package/dist/integration/update.js +59 -0
- package/dist/meta.js +8 -0
- package/dist/module.d.ts +1 -8
- package/dist/module.js +74 -59
- package/dist/module.json +8 -0
- package/dist/nitro.d.ts +1 -2
- package/dist/nitro.js +7 -7
- package/dist/package.js +1 -3
- package/dist/runtime/development.d.ts +5 -0
- package/dist/runtime/development.js +14 -0
- package/dist/runtime/gateway-secret.d.ts +4 -0
- package/dist/runtime/gateway-secret.js +10 -0
- package/dist/runtime/internal.d.ts +1 -2
- package/dist/runtime/internal.js +1 -2
- package/dist/runtime/normalize.d.ts +1 -0
- package/dist/runtime/normalize.js +0 -2
- package/dist/runtime/provider-types.d.ts +1 -2
- package/dist/runtime/registry.d.ts +9 -22
- package/dist/runtime/registry.js +23 -28
- package/dist/runtime.d.ts +1 -2
- package/dist/runtime.js +0 -2
- package/package.json +248 -14
- package/dist/config/load.js.map +0 -1
- package/dist/config/merge.js.map +0 -1
- package/dist/config/prune.js.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/devtools/auth.js.map +0 -1
- package/dist/devtools/devframe.js.map +0 -1
- package/dist/devtools/diagnostics.js.map +0 -1
- package/dist/devtools/enabled.js.map +0 -1
- package/dist/devtools/files-read.js.map +0 -1
- package/dist/devtools/files-write.js.map +0 -1
- package/dist/devtools/files.js.map +0 -1
- package/dist/devtools/index.js.map +0 -1
- package/dist/devtools/nuxt-v3-handler.js.map +0 -1
- package/dist/devtools/nuxt-v3.js.map +0 -1
- package/dist/devtools/nuxt-v4.js.map +0 -1
- package/dist/devtools/snapshot.js.map +0 -1
- package/dist/devtools/token.js.map +0 -1
- package/dist/integration/nitro.js.map +0 -1
- package/dist/module.js.map +0 -1
- package/dist/nitro.js.map +0 -1
- package/dist/package.js.map +0 -1
- package/dist/runtime/internal.js.map +0 -1
- package/dist/runtime/normalize.js.map +0 -1
- package/dist/runtime/registry.js.map +0 -1
- package/dist/runtime.js.map +0 -1
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
1
|
+
import { fileHash } from "../runtime/development.js";
|
|
2
|
+
import { registerSdkAliases, resolveOwnedSdk, resolvePackage, sdkTypePaths } from "./resolve.js";
|
|
3
|
+
import { prepareFilesConfig } from "../config/prepare.js";
|
|
4
|
+
import { deploymentTarget, storageDependencies } from "./dependencies.js";
|
|
5
|
+
import { dependencySession, diagnoseDependencies, reportDependencyIssues } from "./diagnostics.js";
|
|
6
|
+
import { configSources, subpathDependencies } from "./imports.js";
|
|
7
|
+
import { watchFiles, writeChanged } from "./update.js";
|
|
8
|
+
import { basename, resolve } from "node:path";
|
|
9
|
+
import { mkdir } from "node:fs/promises";
|
|
10
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
11
|
+
import { getProvider } from "files-sdk/providers";
|
|
9
12
|
//#region src/integration/nitro.ts
|
|
10
13
|
const AWS_CORE_DEPENDENCIES = [
|
|
11
14
|
"@aws-sdk/client-s3",
|
|
@@ -29,48 +32,38 @@ const optionalAwsSdkDependencies = (adapters, options) => {
|
|
|
29
32
|
if (s3Adapters.length === 0) return [];
|
|
30
33
|
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
34
|
};
|
|
32
|
-
const
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
for (const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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 });
|
|
35
|
+
const missingAwsSdkShim = (dependency) => `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`;
|
|
36
|
+
const awsVirtualId = (dependency) => `virtual:nuxt-files-sdk/optional/${dependency.replaceAll(/[^a-z0-9]+/giu, "-")}`;
|
|
37
|
+
/** Apply the retained Nitro 2 workerd compatibility after native preset resolution. */
|
|
38
|
+
const wireNuxtNitroAwsOptions = (value, options) => {
|
|
39
|
+
const nitro = value;
|
|
40
|
+
const aliases = nitro.options.alias ??= {};
|
|
41
|
+
for (const dependency of [...AWS_CORE_DEPENDENCIES, AWS_MULTIPART_DEPENDENCY]) {
|
|
42
|
+
const id = awsVirtualId(dependency);
|
|
43
|
+
if (aliases[dependency] === id && nitro.options.virtual?.[id] === missingAwsSdkShim(dependency)) {
|
|
44
|
+
delete aliases[dependency];
|
|
45
|
+
delete nitro.options.virtual[id];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const missing = optionalAwsSdkDependencies(options.adapters, {
|
|
49
|
+
nitroMajor: options.nitroMajor,
|
|
50
|
+
preset: nitro.options.preset,
|
|
51
|
+
resolvable: (dependency) => Object.hasOwn(aliases, dependency) || resolvePackage(dependency, pathToFileURL(options.sdk.manifestPath)).status === "resolved"
|
|
52
|
+
});
|
|
53
|
+
for (const dependency of missing) {
|
|
54
|
+
const id = awsVirtualId(dependency);
|
|
55
|
+
aliases[dependency] = id;
|
|
56
|
+
(nitro.options.virtual ??= {})[id] = missingAwsSdkShim(dependency);
|
|
60
57
|
}
|
|
61
|
-
return
|
|
58
|
+
return missing;
|
|
62
59
|
};
|
|
63
|
-
const
|
|
64
|
-
const providerCode = (adapters) => ({
|
|
65
|
-
imports: adapters.map((adapter, index) => `import { ${factoryName(adapter)} as provider${index} } from ${JSON.stringify(`files-sdk/${adapter}`)}`).join("\n"),
|
|
66
|
-
factories: adapters.map((adapter, index) => `${JSON.stringify(adapter)}: provider${index}`).join(", ")
|
|
67
|
-
});
|
|
60
|
+
const nitroMajorVersion = (nitro) => nitro.meta?.majorVersion ?? ("routing" in nitro ? 3 : 2);
|
|
68
61
|
const hookTypes = (moduleName) => `
|
|
69
62
|
declare module ${JSON.stringify(moduleName)} {
|
|
70
63
|
interface NitroRuntimeHooks {
|
|
71
|
-
'files:action': (payload: { event: import('files-sdk').FilesActionEvent; storage?: string }) => void | Promise<void>
|
|
72
|
-
'files:error': (payload: { event: import('files-sdk').FilesErrorEvent; storage?: string }) => void | Promise<void>
|
|
73
|
-
'files:retry': (payload: { event: import('files-sdk').FilesRetryEvent; storage?: string }) => void | Promise<void>
|
|
64
|
+
'files:action': (payload: { event: import('#files-sdk').FilesActionEvent; storage?: string }) => void | Promise<void>
|
|
65
|
+
'files:error': (payload: { event: import('#files-sdk').FilesErrorEvent; storage?: string }) => void | Promise<void>
|
|
66
|
+
'files:retry': (payload: { event: import('#files-sdk').FilesRetryEvent; storage?: string }) => void | Promise<void>
|
|
74
67
|
}
|
|
75
68
|
}
|
|
76
69
|
`;
|
|
@@ -81,25 +74,77 @@ declare module 'nuxt-files-sdk/runtime' {
|
|
|
81
74
|
interface NuxtFilesSingleStorage { value: SingleStorage<typeof config> }
|
|
82
75
|
interface NuxtFilesStorageRegistry extends StorageRegistry<typeof config> {}
|
|
83
76
|
}
|
|
84
|
-
${hookTypes(nitroMajor >= 3 ? "nitro/types" : "nitropack/types")}
|
|
77
|
+
${nitroMajor === 0 ? "" : hookTypes(nitroMajor >= 3 ? "nitro/types" : "nitropack/types")}
|
|
85
78
|
export {}
|
|
86
79
|
`;
|
|
87
80
|
const setupNitroFilesIntegration = async (nitro, options) => {
|
|
81
|
+
const sdk = resolveOwnedSdk();
|
|
82
|
+
for (const dependency of [...AWS_CORE_DEPENDENCIES, AWS_MULTIPART_DEPENDENCY]) {
|
|
83
|
+
const shim = resolve(nitro.options.rootDir, nitro.options.buildDir, "nuxt-files-sdk", `${dependency.replaceAll(/[^a-z0-9]+/giu, "-")}.mjs`).replaceAll("\\", "/");
|
|
84
|
+
if (nitro.options.alias?.[dependency]?.replaceAll("\\", "/") === shim) delete nitro.options.alias[dependency];
|
|
85
|
+
}
|
|
86
|
+
nitro.options.alias = registerSdkAliases(nitro.options.alias ?? {}, sdk);
|
|
88
87
|
const configPath = options.configPath.replaceAll("\\", "/");
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
88
|
+
const graph = configSources(configPath, nitro.options.alias);
|
|
89
|
+
const inputHashes = Object.fromEntries(graph.files.map((path) => [path, fileHash(path)]));
|
|
90
|
+
let prepared;
|
|
91
|
+
try {
|
|
92
|
+
prepared = await prepareFilesConfig({
|
|
93
|
+
configPath,
|
|
94
|
+
environments: options.environments,
|
|
95
|
+
alias: nitro.options.alias,
|
|
96
|
+
injectImports: nitro.unimport?.injectImports.bind(nitro.unimport)
|
|
97
|
+
});
|
|
98
|
+
} catch (error) {
|
|
99
|
+
try {
|
|
100
|
+
const requirements = graph.sdkImports.flatMap((subpath) => subpathDependencies(sdk, subpath));
|
|
101
|
+
reportDependencyIssues(diagnoseDependencies(sdk, requirements, nitro.options.alias), dependencySession(nitro.options.rootDir), (message) => nitro.logger?.warn(message));
|
|
102
|
+
} catch {}
|
|
103
|
+
throw error;
|
|
104
|
+
}
|
|
105
|
+
if (Object.entries(inputHashes).some(([path, hash]) => fileHash(path) !== hash)) throw new Error("[nuxt-files-sdk:config-changed] Files configuration changed during preparation. Retry preparation.");
|
|
106
|
+
let watcher;
|
|
107
|
+
if (nitro.options.dev) {
|
|
108
|
+
const roots = /* @__PURE__ */ new Set([
|
|
109
|
+
nitro.options.rootDir,
|
|
110
|
+
nitro.options.workspaceDir ?? nitro.options.rootDir,
|
|
111
|
+
...graph.files.map((path) => resolve(path, ".."))
|
|
112
|
+
]);
|
|
113
|
+
const watched = [
|
|
114
|
+
...graph.files,
|
|
115
|
+
sdk.manifestPath,
|
|
116
|
+
...[...roots].flatMap((root) => [
|
|
117
|
+
"package.json",
|
|
118
|
+
"bun.lock",
|
|
119
|
+
"package-lock.json",
|
|
120
|
+
"pnpm-lock.yaml",
|
|
121
|
+
"yarn.lock",
|
|
122
|
+
"node_modules/.package-lock.json"
|
|
123
|
+
].map((name) => resolve(root, name)))
|
|
124
|
+
];
|
|
125
|
+
watcher = watchFiles(watched, async () => {
|
|
126
|
+
watcher?.add(configSources(configPath, nitro.options.alias).files);
|
|
127
|
+
await prepareFilesConfig({
|
|
128
|
+
configPath,
|
|
129
|
+
environments: options.environments,
|
|
130
|
+
alias: nitro.options.alias,
|
|
131
|
+
injectImports: nitro.unimport?.injectImports.bind(nitro.unimport)
|
|
132
|
+
});
|
|
133
|
+
await (options.restart ? options.restart() : nitro.hooks.callHook?.("restart"));
|
|
134
|
+
}, (error) => nitro.logger?.warn(error instanceof Error ? error.message : String(error)));
|
|
135
|
+
nitro.hooks.hook("close", () => watcher?.close());
|
|
136
|
+
}
|
|
137
|
+
if (!prepared) return false;
|
|
97
138
|
const directory = resolve(nitro.options.rootDir, nitro.options.buildDir, "nuxt-files-sdk");
|
|
98
139
|
const typesPath = resolve(directory, "storage-registry.d.ts");
|
|
99
140
|
let writeRuntime;
|
|
100
141
|
const writeTypes = async () => {
|
|
101
142
|
await mkdir(directory, { recursive: true });
|
|
102
|
-
await
|
|
143
|
+
await writeChanged(typesPath, storageTypes(configPath, nitroMajorVersion(nitro)));
|
|
144
|
+
await writeChanged(resolve(directory, "tsconfig.json"), JSON.stringify({
|
|
145
|
+
compilerOptions: { paths: sdkTypePaths(sdk) },
|
|
146
|
+
include: [typesPath.replaceAll("\\", "/")]
|
|
147
|
+
}, null, 2));
|
|
103
148
|
};
|
|
104
149
|
await writeTypes();
|
|
105
150
|
nitro.hooks.hook("types:extend", async (types) => {
|
|
@@ -108,28 +153,29 @@ const setupNitroFilesIntegration = async (nitro, options) => {
|
|
|
108
153
|
const tsConfig = types.tsConfig ??= {};
|
|
109
154
|
(tsConfig.include ??= []).push(typesPath);
|
|
110
155
|
const paths = (tsConfig.compilerOptions ??= {}).paths ??= {};
|
|
111
|
-
paths
|
|
156
|
+
Object.assign(paths, sdkTypePaths(sdk));
|
|
112
157
|
});
|
|
113
|
-
const routes =
|
|
114
|
-
const { adapters } = selected;
|
|
115
|
-
const providers = providerCode(adapters);
|
|
158
|
+
const { routes, adapters, providers, environment } = prepared;
|
|
116
159
|
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
160
|
const aliases = nitro.options.alias ?? {};
|
|
120
|
-
const
|
|
161
|
+
const awsShims = optionalAwsSdkDependencies(adapters, {
|
|
121
162
|
nitroMajor: nitroMajorVersion(nitro),
|
|
122
163
|
preset: nitro.options.preset,
|
|
123
164
|
resolvable: (dependency) => {
|
|
124
165
|
if (Object.hasOwn(aliases, dependency)) return true;
|
|
125
|
-
|
|
126
|
-
require.resolve(dependency);
|
|
127
|
-
return true;
|
|
128
|
-
} catch {
|
|
129
|
-
return false;
|
|
130
|
-
}
|
|
166
|
+
return resolvePackage(dependency, pathToFileURL(sdk.manifestPath)).status === "resolved";
|
|
131
167
|
}
|
|
132
|
-
})
|
|
168
|
+
});
|
|
169
|
+
const adapterDependencies = new Map(prepared.adapters.map((adapter) => [adapter, subpathDependencies(sdk, `files-sdk/${adapter}`)]));
|
|
170
|
+
const requirements = [...prepared.entries.values()].flatMap((entry) => storageDependencies(entry, deploymentTarget(nitro.options.preset), typeof entry.storage.adapter === "string" ? adapterDependencies.get(entry.storage.adapter) : []));
|
|
171
|
+
for (const subpath of graph.sdkImports) requirements.push(...subpathDependencies(sdk, subpath));
|
|
172
|
+
const dependencyDiagnostics = diagnoseDependencies(sdk, requirements, aliases, awsShims);
|
|
173
|
+
watcher?.add(requirements.flatMap(({ dependency, conditions }) => {
|
|
174
|
+
const result = resolvePackage(dependency, pathToFileURL(sdk.manifestPath), conditions);
|
|
175
|
+
return result.status === "missing" ? [] : [result.package.manifestPath];
|
|
176
|
+
}));
|
|
177
|
+
reportDependencyIssues(dependencyDiagnostics, dependencySession(nitro.options.rootDir), (message) => nitro.logger?.warn(message));
|
|
178
|
+
const shimFiles = awsShims.map((dependency) => ({
|
|
133
179
|
dependency,
|
|
134
180
|
path: resolve(directory, `${dependency.replaceAll(/[^a-z0-9]+/giu, "-")}.mjs`)
|
|
135
181
|
}));
|
|
@@ -139,7 +185,7 @@ const setupNitroFilesIntegration = async (nitro, options) => {
|
|
|
139
185
|
}
|
|
140
186
|
nitro.unimport?.getInternalContext().addons.push({
|
|
141
187
|
name: "nuxt-files-sdk-jsdoc",
|
|
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
|
|
188
|
+
declaration: (declarations) => declarations.replace(/^([ \t]*)const (defineFilesConfig|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/${name === "defineFilesConfig" ? "config" : "runtime"}').${name}`)
|
|
143
189
|
});
|
|
144
190
|
const externals = nitro.options.externals ??= {};
|
|
145
191
|
(externals.inline ??= []).push("nuxt-files-sdk");
|
|
@@ -156,18 +202,17 @@ const setupNitroFilesIntegration = async (nitro, options) => {
|
|
|
156
202
|
nitro.options.plugins.push(pluginPath.replaceAll("\\", "/"));
|
|
157
203
|
writeRuntime = async () => {
|
|
158
204
|
await mkdir(directory, { recursive: true });
|
|
159
|
-
await Promise.all(shimFiles.map(({ dependency, path }) =>
|
|
160
|
-
|
|
161
|
-
const importedSource = nitro.unimport ? (await nitro.unimport.injectImports(originalSource, configPath)).code : originalSource;
|
|
162
|
-
await writeFile(selectedPath, pruneFilesConfigSource(importedSource, configPath, options.environments));
|
|
205
|
+
await Promise.all(shimFiles.map(({ dependency, path }) => writeChanged(path, missingAwsSdkShim(dependency))));
|
|
206
|
+
await writeChanged(selectedPath, prepared.source);
|
|
163
207
|
const mergePath = fileURLToPath(new URL("../config/merge.js", import.meta.url)).replaceAll("\\", "/");
|
|
164
208
|
const selectedBranches = options.environments.flatMap((name) => [`raw[${JSON.stringify(`$${name}`)}]`, `raw.$env?.[${JSON.stringify(name)}]`]).toReversed();
|
|
165
|
-
await
|
|
166
|
-
await
|
|
209
|
+
await writeChanged(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`);
|
|
210
|
+
await writeChanged(pluginPath, `import config from ${JSON.stringify(resolvedPath.replaceAll("\\", "/"))}
|
|
167
211
|
${providers.imports}
|
|
168
212
|
import { configureFiles } from ${JSON.stringify(internalPath)}
|
|
169
213
|
|
|
170
214
|
export default (nitroApp) => configureFiles(config, {
|
|
215
|
+
${nitro.options.dev ? `dependencies: ${JSON.stringify(dependencyDiagnostics)},` : ""}
|
|
171
216
|
factories: { ${providers.factories} },
|
|
172
217
|
environment: ${JSON.stringify(environment)},
|
|
173
218
|
hooks: {
|
|
@@ -179,20 +224,18 @@ export default (nitroApp) => configureFiles(config, {
|
|
|
179
224
|
`);
|
|
180
225
|
await Promise.all(routePaths.map((path, index) => {
|
|
181
226
|
const route = routes[index];
|
|
182
|
-
const
|
|
183
|
-
return
|
|
184
|
-
import { createFilesRouter } from 'files-sdk/api'
|
|
185
|
-
${nitroMajorVersion(nitro) >= 3 ? "" : "import {
|
|
227
|
+
const request = nitroMajorVersion(nitro) >= 3 ? "event.req" : "toWebRequest(event)";
|
|
228
|
+
return writeChanged(path, `import config from ${JSON.stringify(resolvedPath.replaceAll("\\", "/"))}
|
|
229
|
+
import { createFilesRouter } from '#files-sdk/api'
|
|
230
|
+
${nitroMajorVersion(nitro) >= 3 ? "" : "import { toWebRequest } from 'h3'"}
|
|
231
|
+
import { nitroRequestEvent, nitroResponse } from ${JSON.stringify(fileURLToPath(new URL("./nitro-event.js", import.meta.url)).replaceAll("\\", "/"))}
|
|
186
232
|
import { getFiles } from ${JSON.stringify(internalPath)}
|
|
233
|
+
import { resolveGatewaySecret } from ${JSON.stringify(fileURLToPath(new URL("../runtime/gateway-secret.js", import.meta.url)).replaceAll("\\", "/"))}
|
|
234
|
+
${nitro.options.dev ? `import { developmentConfigCurrent } from ${JSON.stringify(fileURLToPath(new URL("../runtime/development.js", import.meta.url)).replaceAll("\\", "/"))}\nconst inputHashes = ${JSON.stringify(inputHashes)}` : ""}
|
|
187
235
|
|
|
188
236
|
const route = config.routes[${index}]
|
|
189
237
|
const environmentSecret = typeof process === 'undefined' ? undefined : process.env?.FILES_API_SECRET
|
|
190
|
-
const secret = route.
|
|
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
|
-
}
|
|
238
|
+
const secret = await resolveGatewaySecret(route.secret, environmentSecret)
|
|
196
239
|
let sharedRouter
|
|
197
240
|
const makeRouter = (event) => createFilesRouter({
|
|
198
241
|
...route,
|
|
@@ -200,9 +243,11 @@ const makeRouter = (event) => createFilesRouter({
|
|
|
200
243
|
secret,
|
|
201
244
|
authorize: route.authorize && ((context) => route.authorize({ ...context, event })),
|
|
202
245
|
})
|
|
203
|
-
export default (event) => {
|
|
204
|
-
|
|
205
|
-
|
|
246
|
+
export default async (event) => {
|
|
247
|
+
${nitro.options.dev ? `if (!developmentConfigCurrent(inputHashes)) return new Response('Files configuration is being updated.', { status: 503 })` : ""}
|
|
248
|
+
const portable = nitroRequestEvent(${request}, event.context)
|
|
249
|
+
const router = route.authorize ? makeRouter(portable) : (sharedRouter ??= makeRouter(portable))
|
|
250
|
+
return nitroResponse(await router.handle(portable.req), portable)
|
|
206
251
|
}
|
|
207
252
|
`);
|
|
208
253
|
}));
|
|
@@ -210,7 +255,41 @@ export default (event) => {
|
|
|
210
255
|
await writeRuntime();
|
|
211
256
|
return true;
|
|
212
257
|
};
|
|
258
|
+
/** Preserve TypeScript compilation when Nuxt places its build directory inside node_modules. */
|
|
259
|
+
const selectedSourcePlugin = (options) => {
|
|
260
|
+
const selected = options.selected.replaceAll("\\", "/");
|
|
261
|
+
const id = `nuxt-files-sdk:${basename(selected)}`;
|
|
262
|
+
return {
|
|
263
|
+
name: "nuxt-files-sdk-selected-source",
|
|
264
|
+
resolveId(source, importer) {
|
|
265
|
+
if (source.replaceAll("\\", "/") === selected) return id;
|
|
266
|
+
if (importer === id) return this.resolve(source, options.configPath, { skipSelf: true });
|
|
267
|
+
return null;
|
|
268
|
+
},
|
|
269
|
+
load(source) {
|
|
270
|
+
return source === id ? options.source : null;
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
};
|
|
274
|
+
/** Preserve Nuxt's runtime inline rules when Nitro 2 receives native Windows resolver paths. */
|
|
275
|
+
const inlineNuxtRuntime = (id) => id.includes("\\") && /^(?:nuxt|nuxt3|nuxt-nightly)\/dist\//u.test(id.replaceAll("\\", "/").split("node_modules/").at(-1));
|
|
276
|
+
/** Native bundle settings stay in the Nitro adapter, including Nuxt's Nitro-backed path. */
|
|
277
|
+
const wireNuxtNitroOptions = (value, options) => {
|
|
278
|
+
const config = value;
|
|
279
|
+
config.alias = registerSdkAliases({
|
|
280
|
+
...config.alias,
|
|
281
|
+
"nuxt-files-sdk/runtime": options.runtime,
|
|
282
|
+
"#nuxt-files-sdk/registry": options.registry
|
|
283
|
+
}, options.sdk);
|
|
284
|
+
const inline = (config.externals ??= {}).inline ??= [];
|
|
285
|
+
inline.push("nuxt-files-sdk", options.runtime, options.registry, options.resolved, options.selected);
|
|
286
|
+
inline.push(inlineNuxtRuntime);
|
|
287
|
+
if (!options.development) inline.push("files-sdk");
|
|
288
|
+
((config.rollupConfig ??= {}).plugins ??= []).push(selectedSourcePlugin({
|
|
289
|
+
selected: options.selected,
|
|
290
|
+
source: options.selectedSource,
|
|
291
|
+
configPath: options.configPath
|
|
292
|
+
}));
|
|
293
|
+
};
|
|
213
294
|
//#endregion
|
|
214
|
-
export {
|
|
215
|
-
|
|
216
|
-
//# sourceMappingURL=nitro.js.map
|
|
295
|
+
export { inlineNuxtRuntime, optionalAwsSdkDependencies, selectedSourcePlugin, setupNitroFilesIntegration, storageTypes, wireNuxtNitroAwsOptions, wireNuxtNitroOptions };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { reportDependencyIssues } from "./diagnostics.js";
|
|
2
|
+
import { getAddDependencyCommand } from "@nuxt/kit";
|
|
3
|
+
//#region src/integration/nuxt-diagnostics.ts
|
|
4
|
+
/** Advice only: Nuxt's installer cannot guarantee zero prompts/installs on every host. */
|
|
5
|
+
const reportNuxtDependencyIssues = async (diagnostics, previous, logger, root) => {
|
|
6
|
+
let message;
|
|
7
|
+
reportDependencyIssues(diagnostics, previous, (value) => {
|
|
8
|
+
message = value;
|
|
9
|
+
});
|
|
10
|
+
if (!message) return;
|
|
11
|
+
const packages = [...new Set(diagnostics.filter((entry) => entry.necessity === "required" && (entry.status === "missing" || entry.status === "incompatible")).map((entry) => {
|
|
12
|
+
const name = entry.dependency.split("/").slice(0, entry.dependency.startsWith("@") ? 2 : 1).join("/");
|
|
13
|
+
return entry.range ? `${name}@${entry.range}` : name;
|
|
14
|
+
}))];
|
|
15
|
+
if (!packages.length) {
|
|
16
|
+
logger.warn(message);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const command = await getAddDependencyCommand(packages, root, { dev: false }).catch(() => void 0);
|
|
20
|
+
logger.warn(`${message}\n${command ? `Run: ${command}` : `Add production dependencies: ${packages.join(", ")}`}`);
|
|
21
|
+
};
|
|
22
|
+
//#endregion
|
|
23
|
+
export { reportNuxtDependencyIssues };
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { filesBuilderCapabilities, requireFilesGateway } from "./capabilities.js";
|
|
2
|
+
import { fileHash } from "../runtime/development.js";
|
|
3
|
+
import { registerSdkAliases, resolveOwnedSdk, resolvePackage, sdkTypePaths } from "./resolve.js";
|
|
4
|
+
import { prepareFilesConfig } from "../config/prepare.js";
|
|
5
|
+
import { deploymentTarget, storageDependencies } from "./dependencies.js";
|
|
6
|
+
import { dependencySession, diagnoseDependencies } from "./diagnostics.js";
|
|
7
|
+
import { configSources, subpathDependencies } from "./imports.js";
|
|
8
|
+
import { watchFiles } from "./update.js";
|
|
9
|
+
import { optionalAwsSdkDependencies, storageTypes, wireNuxtNitroAwsOptions, wireNuxtNitroOptions } from "./nitro.js";
|
|
10
|
+
import { stopNitroDevReloadOnClose } from "./nitro-dev-close.js";
|
|
11
|
+
import { reportNuxtDependencyIssues } from "./nuxt-diagnostics.js";
|
|
12
|
+
import { withFilesTask } from "./terminal.js";
|
|
13
|
+
import { dirname, resolve } from "node:path";
|
|
14
|
+
import { addServerHandler, addTemplate, addTypeTemplate, resolveServerVariant, useLogger, useTerminal } from "@nuxt/kit";
|
|
15
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
16
|
+
import { parseSync } from "oxc-parser";
|
|
17
|
+
//#region src/integration/nuxt.ts
|
|
18
|
+
const normalized = (path) => path.replaceAll("\\", "/");
|
|
19
|
+
const runtimeFile = (path) => normalized(fileURLToPath(new URL(path, import.meta.url)));
|
|
20
|
+
/** Supply the module's configuration helper without evaluating any runtime resolver. */
|
|
21
|
+
const injectConfigImports = async (source, filename) => {
|
|
22
|
+
return { code: parseSync(filename ?? "files.config.ts", source, { lang: "ts" }).program.body.some((node) => node.type === "ImportDeclaration" ? node.specifiers.some((specifier) => specifier.local.name === "defineFilesConfig") : node.type === "FunctionDeclaration" ? node.id?.name === "defineFilesConfig" : node.type === "VariableDeclaration" && node.declarations.some((declaration) => declaration.id.type === "Identifier" && declaration.id.name === "defineFilesConfig")) ? source : `import { defineFilesConfig } from ${JSON.stringify(runtimeFile("../config.js"))}\n${source}` };
|
|
23
|
+
};
|
|
24
|
+
/** Generate one runtime import graph; Nuxt never initializes Files through a Nitro startup plugin. */
|
|
25
|
+
const setupNuxtFilesIntegration = async (nuxt, options) => {
|
|
26
|
+
const logger = useLogger("nuxt-files-sdk");
|
|
27
|
+
const terminal = useTerminal();
|
|
28
|
+
const configPath = normalized(options.configPath);
|
|
29
|
+
const sdk = resolveOwnedSdk();
|
|
30
|
+
nuxt.options.alias = registerSdkAliases(nuxt.options.alias, sdk, ["browser", "import"]);
|
|
31
|
+
const preparationAliases = () => {
|
|
32
|
+
const native = nuxt.options.nitro;
|
|
33
|
+
const aliases = "alias" in native && native.alias && typeof native.alias === "object" ? native.alias : {};
|
|
34
|
+
return registerSdkAliases({
|
|
35
|
+
...nuxt.options.alias,
|
|
36
|
+
...Object.fromEntries(Object.entries(aliases).filter((entry) => typeof entry[1] === "string"))
|
|
37
|
+
}, sdk, ["node", "import"]);
|
|
38
|
+
};
|
|
39
|
+
const graph = configSources(configPath, preparationAliases());
|
|
40
|
+
const inputHashes = Object.fromEntries(graph.files.map((path) => [path, fileHash(path)]));
|
|
41
|
+
const environments = nuxt.options.nitro.static ? ["production", "prerender"] : [nuxt.options.envName || (nuxt.options.dev ? "development" : "production")];
|
|
42
|
+
const prepare = () => prepareFilesConfig({
|
|
43
|
+
configPath,
|
|
44
|
+
environments,
|
|
45
|
+
alias: preparationAliases(),
|
|
46
|
+
injectImports: injectConfigImports
|
|
47
|
+
});
|
|
48
|
+
let prepared;
|
|
49
|
+
try {
|
|
50
|
+
prepared = await withFilesTask(terminal, "Preparing Files configuration", prepare);
|
|
51
|
+
} catch (error) {
|
|
52
|
+
try {
|
|
53
|
+
await reportNuxtDependencyIssues(diagnoseDependencies(sdk, graph.sdkImports.flatMap((subpath) => subpathDependencies(sdk, subpath)), preparationAliases()), dependencySession(nuxt.options.rootDir), logger, nuxt.options.rootDir);
|
|
54
|
+
} catch {}
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
if (Object.entries(inputHashes).some(([path, hash]) => fileHash(path) !== hash)) throw new Error("[nuxt-files-sdk:config-changed] Files configuration changed during preparation. Retry preparation.");
|
|
58
|
+
let watcher;
|
|
59
|
+
if (nuxt.options.dev) {
|
|
60
|
+
const roots = /* @__PURE__ */ new Set([
|
|
61
|
+
nuxt.options.rootDir,
|
|
62
|
+
nuxt.options.workspaceDir,
|
|
63
|
+
...graph.files.map(dirname)
|
|
64
|
+
]);
|
|
65
|
+
watcher = watchFiles([
|
|
66
|
+
...graph.files,
|
|
67
|
+
sdk.manifestPath,
|
|
68
|
+
...[...roots].flatMap((root) => [
|
|
69
|
+
"package.json",
|
|
70
|
+
"bun.lock",
|
|
71
|
+
"package-lock.json",
|
|
72
|
+
"pnpm-lock.yaml",
|
|
73
|
+
"yarn.lock",
|
|
74
|
+
"node_modules/.package-lock.json"
|
|
75
|
+
].map((name) => resolve(root, name)))
|
|
76
|
+
], async () => {
|
|
77
|
+
watcher?.add(configSources(configPath, preparationAliases()).files);
|
|
78
|
+
await withFilesTask(terminal, "Updating Files configuration", prepare);
|
|
79
|
+
await nuxt.callHook("restart");
|
|
80
|
+
}, (error) => logger.warn(error instanceof Error ? error.message : String(error)));
|
|
81
|
+
nuxt.hook("close", () => watcher?.close());
|
|
82
|
+
}
|
|
83
|
+
if (!prepared) return false;
|
|
84
|
+
const major = resolveServerVariant({
|
|
85
|
+
nitro2: 2,
|
|
86
|
+
nitro3: 3,
|
|
87
|
+
nuxt: 0
|
|
88
|
+
}) ?? 0;
|
|
89
|
+
if (nuxt.options.dev && major === 2) nuxt.hook("nitro:init", stopNitroDevReloadOnClose);
|
|
90
|
+
let awsShims = [];
|
|
91
|
+
if (major === 2 && optionalAwsSdkDependencies(prepared.adapters, {
|
|
92
|
+
nitroMajor: major,
|
|
93
|
+
preset: "cloudflare-module",
|
|
94
|
+
resolvable: () => false
|
|
95
|
+
}).length) nuxt.hook("nitro:init", (nitro) => {
|
|
96
|
+
awsShims = wireNuxtNitroAwsOptions(nitro, {
|
|
97
|
+
sdk,
|
|
98
|
+
adapters: prepared.adapters,
|
|
99
|
+
nitroMajor: major
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
const capabilities = filesBuilderCapabilities(major === 2 ? "nitro2" : major === 3 ? "nitro3" : "nuxt");
|
|
103
|
+
requireFilesGateway(prepared.routes.length > 0, capabilities.gateway);
|
|
104
|
+
const mode = nuxt.options.dev ? ".dev" : "";
|
|
105
|
+
const template = (name, contents) => normalized(addTemplate({
|
|
106
|
+
filename: `nuxt-files-sdk/${name}${mode}.mjs`,
|
|
107
|
+
write: true,
|
|
108
|
+
getContents: () => contents
|
|
109
|
+
}).dst);
|
|
110
|
+
const selected = normalized(addTemplate({
|
|
111
|
+
filename: `nuxt-files-sdk/selected${mode}.ts`,
|
|
112
|
+
write: true,
|
|
113
|
+
getContents: () => prepared.source
|
|
114
|
+
}).dst);
|
|
115
|
+
const branches = environments.flatMap((name) => [`raw[${JSON.stringify(`$${name}`)}]`, `raw.$env?.[${JSON.stringify(name)}]`]).toReversed();
|
|
116
|
+
const resolved = template("resolved", `import raw from ${JSON.stringify(selected)}\nimport { mergeFilesConfig } from ${JSON.stringify(runtimeFile("../config/merge.js"))}\nconst resolved = mergeFilesConfig(${[...branches, "raw"].join(", ")})\nexport default { storage: resolved.storage, routes: resolved.routes }\n`);
|
|
117
|
+
const adapterDependencies = new Map(prepared.adapters.map((adapter) => [adapter, subpathDependencies(sdk, `files-sdk/${adapter}`)]));
|
|
118
|
+
const requirementsFor = (preset) => [...prepared.entries.values()].flatMap((entry) => storageDependencies(entry, deploymentTarget(preset), typeof entry.storage.adapter === "string" ? adapterDependencies.get(entry.storage.adapter) : []));
|
|
119
|
+
const requirements = requirementsFor("preset" in nuxt.options.nitro && typeof nuxt.options.nitro.preset === "string" ? nuxt.options.nitro.preset : void 0);
|
|
120
|
+
for (const subpath of graph.sdkImports) requirements.push(...subpathDependencies(sdk, subpath));
|
|
121
|
+
const diagnostics = diagnoseDependencies(sdk, requirements, preparationAliases());
|
|
122
|
+
const previous = dependencySession(nuxt.options.rootDir);
|
|
123
|
+
if (!major) await reportNuxtDependencyIssues(diagnostics, previous, logger, nuxt.options.rootDir);
|
|
124
|
+
if (major && requirements.length) nuxt.hook("nitro:init", async (value) => {
|
|
125
|
+
const native = value;
|
|
126
|
+
const resolvedRequirements = requirementsFor(native.options.preset);
|
|
127
|
+
for (const subpath of graph.sdkImports) resolvedRequirements.push(...subpathDependencies(sdk, subpath));
|
|
128
|
+
await reportNuxtDependencyIssues(diagnoseDependencies(sdk, resolvedRequirements, native.options.alias, awsShims), previous, logger, nuxt.options.rootDir);
|
|
129
|
+
});
|
|
130
|
+
watcher?.add(requirements.flatMap(({ dependency, conditions }) => {
|
|
131
|
+
const result = resolvePackage(dependency, pathToFileURL(sdk.manifestPath), conditions);
|
|
132
|
+
return result.status === "missing" ? [] : [result.package.manifestPath];
|
|
133
|
+
}));
|
|
134
|
+
const hooksImport = major === 2 ? "import { useNitroApp } from 'nitropack/runtime'" : major === 3 ? "import { useNitroHooks } from 'nitro/app'" : "";
|
|
135
|
+
const callHook = major === 2 ? "useNitroApp().hooks.callHook" : "useNitroHooks().callHook";
|
|
136
|
+
const registry = template("registry", `import config from ${JSON.stringify(resolved)}\n${prepared.providers.imports}\nimport { configureFiles } from ${JSON.stringify(runtimeFile("../runtime/internal.js"))}\n${hooksImport}\n\nexport const registry = configureFiles(config, {\n factories: { ${prepared.providers.factories} },\n environment: ${JSON.stringify(prepared.environment)},\n ${nuxt.options.dev ? `dependencies: ${JSON.stringify(diagnostics)},` : ""}\n ${major ? `hooks: {\n onAction: (event, storage) => ${callHook}('files:action', { event, storage }),\n onError: (event, storage) => ${callHook}('files:error', { event, storage }),\n onRetry: (event, storage) => ${callHook}('files:retry', { event, storage }),\n },` : ""}\n})\n`);
|
|
137
|
+
const runtime = template("runtime", `import { registry } from '#nuxt-files-sdk/registry'
|
|
138
|
+
import { sync, transfer } from '#files-sdk'
|
|
139
|
+
export const useServerFiles = name => name === undefined ? registry.get() : registry.get(name)
|
|
140
|
+
const files = value => typeof value === 'string' ? registry.get(value) : value
|
|
141
|
+
export const syncFiles = (source, destination, options) => sync(files(source), files(destination), options)
|
|
142
|
+
export const transferFiles = (source, destination, options) => transfer(files(source), files(destination), options)
|
|
143
|
+
`);
|
|
144
|
+
addTypeTemplate({
|
|
145
|
+
filename: `nuxt-files-sdk/runtime${mode}.d.ts`,
|
|
146
|
+
getContents: () => `export * from ${JSON.stringify(runtimeFile("../runtime.js"))}\n`
|
|
147
|
+
}, { nuxt: false });
|
|
148
|
+
nuxt.options.alias["nuxt-files-sdk/runtime"] = runtime;
|
|
149
|
+
nuxt.options.alias["#nuxt-files-sdk/registry"] = registry;
|
|
150
|
+
nuxt.hook("nitro:config", (config) => wireNuxtNitroOptions(config, {
|
|
151
|
+
sdk,
|
|
152
|
+
runtime,
|
|
153
|
+
registry,
|
|
154
|
+
resolved,
|
|
155
|
+
selected,
|
|
156
|
+
selectedSource: prepared.source,
|
|
157
|
+
configPath,
|
|
158
|
+
development: nuxt.options.dev
|
|
159
|
+
}));
|
|
160
|
+
const declarations = addTypeTemplate({
|
|
161
|
+
filename: "nuxt-files-sdk/storage-registry.d.ts",
|
|
162
|
+
getContents: () => storageTypes(configPath, major) + `
|
|
163
|
+
declare global {
|
|
164
|
+
/** Return the project's Files client, including its configured plugin extensions. */
|
|
165
|
+
const useServerFiles: typeof import('nuxt-files-sdk/runtime').useServerFiles
|
|
166
|
+
/** Delegate a mirror operation to the native Files SDK. */
|
|
167
|
+
const syncFiles: typeof import('nuxt-files-sdk/runtime').syncFiles
|
|
168
|
+
/** Delegate a transfer operation to the native Files SDK. */
|
|
169
|
+
const transferFiles: typeof import('nuxt-files-sdk/runtime').transferFiles
|
|
170
|
+
}
|
|
171
|
+
`
|
|
172
|
+
}, {
|
|
173
|
+
nuxt: true,
|
|
174
|
+
nitro: true,
|
|
175
|
+
shared: true
|
|
176
|
+
});
|
|
177
|
+
nuxt.hook("prepare:types", ({ references, nodeReferences, sharedReferences, serverReferences, tsConfig, nodeTsConfig, sharedTsConfig, serverTsConfig }) => {
|
|
178
|
+
for (const values of [
|
|
179
|
+
references,
|
|
180
|
+
nodeReferences,
|
|
181
|
+
sharedReferences,
|
|
182
|
+
serverReferences
|
|
183
|
+
]) if (!values.some((entry) => "path" in entry && entry.path === declarations.dst)) values.push({ path: declarations.dst });
|
|
184
|
+
for (const config of [
|
|
185
|
+
tsConfig,
|
|
186
|
+
nodeTsConfig,
|
|
187
|
+
sharedTsConfig,
|
|
188
|
+
serverTsConfig
|
|
189
|
+
]) {
|
|
190
|
+
(config.include ??= []).push(configPath);
|
|
191
|
+
Object.assign((config.compilerOptions ??= {}).paths ??= {}, sdkTypePaths(sdk), { "nuxt-files-sdk/runtime": [runtimeFile("../runtime.d.ts")] });
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
for (const [index, route] of prepared.routes.entries()) {
|
|
195
|
+
const handler = template(`gateway-${index}`, `import { defineEventHandler, deriveSecret } from 'nuxt/server'
|
|
196
|
+
import config from ${JSON.stringify(resolved)}
|
|
197
|
+
import { createFilesRouter } from '#files-sdk/api'
|
|
198
|
+
import { useServerFiles } from 'nuxt-files-sdk/runtime'
|
|
199
|
+
import { resolveGatewaySecret } from ${JSON.stringify(runtimeFile("../runtime/gateway-secret.js"))}
|
|
200
|
+
${nuxt.options.dev ? `import { developmentConfigCurrent } from ${JSON.stringify(runtimeFile("../runtime/development.js"))}\nconst inputHashes = ${JSON.stringify(inputHashes)}` : ""}
|
|
201
|
+
const route = config.routes[${index}]
|
|
202
|
+
let secretPromise
|
|
203
|
+
const gatewaySecret = () => secretPromise ??= resolveGatewaySecret(
|
|
204
|
+
route.secret,
|
|
205
|
+
typeof process === 'undefined' ? undefined : process.env?.FILES_API_SECRET,
|
|
206
|
+
() => deriveSecret(${JSON.stringify(`nuxt-files-sdk:gateway:${route.path}`)}),
|
|
207
|
+
).catch(error => {
|
|
208
|
+
secretPromise = undefined
|
|
209
|
+
throw error
|
|
210
|
+
})
|
|
211
|
+
let sharedRouter
|
|
212
|
+
const makeRouter = (event, secret) => createFilesRouter({
|
|
213
|
+
...route,
|
|
214
|
+
files: () => useServerFiles(${route.storage === void 0 ? "" : JSON.stringify(route.storage)}),
|
|
215
|
+
secret,
|
|
216
|
+
authorize: route.authorize && ((context) => route.authorize({ ...context, event })),
|
|
217
|
+
})
|
|
218
|
+
export default defineEventHandler(async event => {
|
|
219
|
+
${nuxt.options.dev ? "if (!developmentConfigCurrent(inputHashes)) return new Response('Files configuration is being updated.', { status: 503 })" : ""}
|
|
220
|
+
const secret = await gatewaySecret()
|
|
221
|
+
const router = route.authorize
|
|
222
|
+
? makeRouter(event, secret)
|
|
223
|
+
: (sharedRouter ??= makeRouter(event, secret))
|
|
224
|
+
return router.handle(event.req)
|
|
225
|
+
})
|
|
226
|
+
`);
|
|
227
|
+
addServerHandler({
|
|
228
|
+
route: route.path,
|
|
229
|
+
handler: { nuxt: handler }
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
return true;
|
|
233
|
+
};
|
|
234
|
+
//#endregion
|
|
235
|
+
export { setupNuxtFilesIntegration };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { getPackageInfoSync } from "local-pkg";
|