Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/adapter-next/src/runtime.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { initializeHolo, type CreateHoloOptions } from '@holo-js/core'
import { initializeHolo, type CreateHoloOptions } from '@holo-js/core/runtime'
import type { DotPath, HoloConfigMap, LoadedHoloConfig, ValueAtPath } from '@holo-js/config'
import { getCurrentNextRequest, type NextRequestLike } from './request-context'
export { runWithNextRequest, type NextRequestLike } from './request-context'
Expand Down
1 change: 1 addition & 0 deletions packages/adapter-next/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"paths": {
"@holo-js/config": ["../config/src/index.ts"],
"@holo-js/core/errors": ["../core/src/errors.ts"],
"@holo-js/core/runtime": ["../core/src/portable/index.ts"],
"@holo-js/core": ["../core/src/index.ts"],
"@holo-js/forms": ["../forms/src/index.ts"],
"@holo-js/forms/internal/client": ["../forms/src/internal/client.ts"],
Expand Down
1 change: 1 addition & 0 deletions packages/adapter-next/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export default defineConfig({
alias: {
'@holo-js/config': resolve(__dirname, '../config/src/index.ts'),
'@holo-js/core/errors': resolve(__dirname, '../core/src/errors.ts'),
'@holo-js/core/runtime': resolve(__dirname, '../core/src/portable/index.ts'),
'@holo-js/core': resolve(__dirname, '../core/src/index.ts'),
'@holo-js/db': resolve(__dirname, '../db/src/index.ts'),
'@holo-js/db-mysql': resolve(__dirname, '../db-mysql/src/index.ts'),
Expand Down
5 changes: 3 additions & 2 deletions packages/core/tests/adapter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1020,16 +1020,18 @@ export default {
displayName: 'Test',
})
const root = await createProjectRoot()
const remoteObjects = new Map<string, string>()
const fetchMock = vi.fn(async (input: FetchInput) => {
const request = input instanceof Request ? input : new Request(input)
const key = decodeURIComponent(new URL(request.url).pathname.replace(/^\/+/, ''))

if (request.method === 'PUT') {
remoteObjects.set(request.url, await request.text())
return new Response(null, { status: 200 })
}

if (request.method === 'GET') {
return new Response(JSON.stringify({ ok: true, key }), { status: 200 })
return new Response(remoteObjects.get(request.url) ?? JSON.stringify({ ok: true, key }), { status: 200 })
}

if (request.method === 'HEAD') {
Expand Down Expand Up @@ -1110,7 +1112,6 @@ export default defineStorageConfig({
await expect(mediaStorage.setItem('remote:payload.json', { ok: true })).resolves.toBeUndefined()
await expect(mediaStorage.getItem('remote:payload.json')).resolves.toEqual({
ok: true,
key: 'remote/payload.json',
})
await expect(mediaStorage.getMeta('remote:payload.json')).resolves.toEqual({})
await expect(mediaStorage.hasItem('remote:payload.json')).resolves.toBe(true)
Expand Down
44 changes: 30 additions & 14 deletions packages/storage/tests/s3Driver.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,10 +286,20 @@ describe('custom s3 storage driver', () => {
expect(await readRequestBody(fetchMock.mock.calls[0]?.[0] as Request)).toBe('shared-ok')
})

it('returns null for missing raw objects and stores plain string values as JSON', async () => {
it('returns null for missing raw objects and round-trips plain string values', async () => {
const objects = new Map<string, string>()
fetchMock
.mockResolvedValueOnce(new Response(null, { status: 404 }))
.mockResolvedValueOnce(new Response(null, { status: 200 }))
.mockImplementation(async (input: string | URL | Request) => {
const request = input instanceof Request ? input : new Request(input)

if (request.method === 'PUT') {
objects.set(request.url, await request.text())
return new Response(null, { status: 200 })
}

return new Response(objects.get(request.url) ?? '', { status: 200 })
})

const createDriver = await loadDriver()
const driver = createDriver({
Expand All @@ -303,7 +313,7 @@ describe('custom s3 storage driver', () => {
await expect(driver.getItemRaw('reports:missing.bin')).resolves.toBeNull()
await driver.setItem('reports:plain.txt', 'plain-text')

expect(await readRequestBody(fetchMock.mock.calls[1]?.[0] as Request)).toBe('"plain-text"')
await expect(driver.getItem('reports:plain.txt')).resolves.toBe('plain-text')
})

it('returns null metadata for missing objects', async () => {
Expand All @@ -321,10 +331,18 @@ describe('custom s3 storage driver', () => {
await expect(driver.getMeta('reports:missing.txt')).resolves.toBeNull()
})

it('stringifies structured values and preserves raw payloads on writes', async () => {
fetchMock
.mockResolvedValueOnce(new Response(null, { status: 200 }))
.mockResolvedValueOnce(new Response(null, { status: 200 }))
it('round-trips structured values and preserves raw payloads on writes', async () => {
const objects = new Map<string, string>()
fetchMock.mockImplementation(async (input: string | URL | Request) => {
const request = input instanceof Request ? input : new Request(input)

if (request.method === 'PUT') {
objects.set(request.url, await request.text())
return new Response(null, { status: 200 })
}

return new Response(objects.get(request.url) ?? '', { status: 200 })
})

const createDriver = await loadDriver()
const driver = createDriver({
Expand All @@ -338,11 +356,12 @@ describe('custom s3 storage driver', () => {
await driver.setItem('reports:summary.json', { ok: true })
await driver.setItemRaw('reports:archive.bin', new TextEncoder().encode('raw-data').buffer)

expect(await readRequestBody(fetchMock.mock.calls[0]?.[0] as Request)).toBe('{"ok":true}')
expect(await readRequestBody(fetchMock.mock.calls[1]?.[0] as Request)).toBe('raw-data')
await expect(driver.getItem('reports:summary.json')).resolves.toEqual({ ok: true })
const rawUpload = fetchMock.mock.calls[1]?.[0] as Request
expect(objects.get(rawUpload.url)).toBe('raw-data')
})

it('parses structured JSON payloads back through getItem', async () => {
it('preserves legacy raw JSON payloads as text through getItem', async () => {
fetchMock.mockResolvedValueOnce(new Response('{"ok":true,"count":2}', { status: 200 }))

const createDriver = await loadDriver()
Expand All @@ -354,10 +373,7 @@ describe('custom s3 storage driver', () => {
secretAccessKey: 'supersecretkey',
})

await expect(driver.getItem('reports:summary.json')).resolves.toEqual({
ok: true,
count: 2,
})
await expect(driver.getItem('reports:summary.json')).resolves.toBe('{"ok":true,"count":2}')
})

it('lists keys with prefixes and follows continuation tokens', async () => {
Expand Down