diff --git a/playground/app/pages/cached.vue b/playground/app/pages/cached.vue new file mode 100644 index 00000000..a32d7668 --- /dev/null +++ b/playground/app/pages/cached.vue @@ -0,0 +1,7 @@ + + + diff --git a/playground/nuxt.config.ts b/playground/nuxt.config.ts index a48ff6b9..6d30235e 100644 --- a/playground/nuxt.config.ts +++ b/playground/nuxt.config.ts @@ -37,6 +37,10 @@ export default defineNuxtConfig({ // projectUrl: ({ branch }) => branch === 'main' ? 'https://playground.nuxt.dev' : `https://${encodeHost(branch).replace(/\//g, '-')}.playground-to39.pages.dev` }, + routeRules: { + '/cached': { prerender: true } + }, + basicAuth: { enabled: process.env.NODE_ENV === 'production', allowedRoutes: ['/api/_hub/'], diff --git a/src/features.ts b/src/features.ts index a4c46d5a..95ea6e71 100644 --- a/src/features.ts +++ b/src/features.ts @@ -1,6 +1,7 @@ import { execSync } from 'node:child_process' import { resolvePath } from 'mlly' import type { Nuxt } from '@nuxt/schema' +import { join } from 'pathe' import { logger, addImportsDir, addServerImportsDir, addServerScanDir, createResolver } from '@nuxt/kit' import { joinURL } from 'ufo' import { defu } from 'defu' @@ -169,6 +170,15 @@ export async function setupCache(nuxt: Nuxt) { } } }) + nuxt.hooks.hook('nitro:init', (nitro) => { + nitro.hooks.hook('prerender:config', (config) => { + config.devStorage ||= {} + config.devStorage.cache = { + driver: 'fs', + base: join(nuxt.options.rootDir, '.data/cache') + } + }) + }) // Add Server scanning addServerScanDir(resolve('./runtime/cache/server')) diff --git a/src/runtime/blob/server/api/_hub/blob/multipart/[action]/[...pathname].ts b/src/runtime/blob/server/api/_hub/blob/multipart/[action]/[...pathname].ts index d3f6cc39..dfbf4197 100644 --- a/src/runtime/blob/server/api/_hub/blob/multipart/[action]/[...pathname].ts +++ b/src/runtime/blob/server/api/_hub/blob/multipart/[action]/[...pathname].ts @@ -7,8 +7,15 @@ export default eventHandler(async (event) => { await requireNuxtHubAuthorization(event) requireNuxtHubFeature('blob') - const query = getQuery(event) + const options = { ...getQuery(event) } + if (typeof options.customMetadata === 'string') { + try { + options.customMetadata = JSON.parse(options.customMetadata) + } catch (e) { + options.customMetadata = {} + } + } return await hubBlob().handleMultipartUpload(event, { - ...query + ...options }) }) diff --git a/src/runtime/blob/server/utils/blob.ts b/src/runtime/blob/server/utils/blob.ts index a781bd10..939ef495 100644 --- a/src/runtime/blob/server/utils/blob.ts +++ b/src/runtime/blob/server/utils/blob.ts @@ -396,9 +396,9 @@ export function proxyHubBlob(projectUrl: string, secretKey?: string): HubBlob { return }, async createMultipartUpload(pathname: string, options: BlobMultipartOptions = {}) { - return await blobAPI(`/multipart/${decodeURI(pathname)}`, { + return await blobAPI(`/multipart/create/${decodeURI(pathname)}`, { method: 'POST', - body: options + query: options }) }, resumeMultipartUpload(pathname: string, uploadId: string): BlobMultipartUpload { @@ -406,7 +406,7 @@ export function proxyHubBlob(projectUrl: string, secretKey?: string): HubBlob { pathname, uploadId, async uploadPart(partNumber: number, body: string | ReadableStream | ArrayBuffer | ArrayBufferView | Blob): Promise { - return await blobAPI(`/multipart/${decodeURI(pathname)}`, { + return await blobAPI(`/multipart/upload/${decodeURI(pathname)}`, { method: 'PUT', query: { uploadId, @@ -416,7 +416,7 @@ export function proxyHubBlob(projectUrl: string, secretKey?: string): HubBlob { }) }, async abort(): Promise { - await blobAPI(`/multipart/${decodeURI(pathname)}`, { + await blobAPI(`/multipart/abort/${decodeURI(pathname)}`, { method: 'DELETE', query: { uploadId @@ -424,10 +424,9 @@ export function proxyHubBlob(projectUrl: string, secretKey?: string): HubBlob { }) }, async complete(parts: BlobUploadedPart[]): Promise { - return await blobAPI('/multipart/complete', { + return await blobAPI(`/multipart/complete/${decodeURI(pathname)}`, { method: 'POST', query: { - pathname, uploadId }, body: {