diff --git a/.changeset/hip-kids-ring.md b/.changeset/hip-kids-ring.md new file mode 100644 index 000000000000..5dc22c5b8ea3 --- /dev/null +++ b/.changeset/hip-kids-ring.md @@ -0,0 +1,5 @@ +--- +'@astrojs/db': patch +--- + +Fixes the publishing of the package diff --git a/.changeset/spicy-guests-protect.md b/.changeset/spicy-guests-protect.md new file mode 100644 index 000000000000..5f77d5ee0100 --- /dev/null +++ b/.changeset/spicy-guests-protect.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Trailing slash support for actions diff --git a/packages/astro/src/actions/plugins.ts b/packages/astro/src/actions/plugins.ts index 77cbddca15af..f5bd074dfcca 100644 --- a/packages/astro/src/actions/plugins.ts +++ b/packages/astro/src/actions/plugins.ts @@ -1,5 +1,6 @@ import type fsMod from 'node:fs'; import type { Plugin as VitePlugin } from 'vite'; +import { shouldAppendForwardSlash } from '../core/build/util.js'; import type { AstroSettings } from '../types/astro.js'; import { NOOP_ACTIONS, @@ -84,6 +85,12 @@ export function vitePluginActions({ code += `\nexport * from 'astro/actions/runtime/virtual/server.js';`; } else { code += `\nexport * from 'astro/actions/runtime/virtual/client.js';`; + code = code.replace( + "'/** @TRAILING_SLASH@ **/'", + JSON.stringify( + shouldAppendForwardSlash(settings.config.trailingSlash, settings.config.build.format), + ), + ); } return code; }, diff --git a/packages/astro/src/actions/runtime/virtual/server.ts b/packages/astro/src/actions/runtime/virtual/server.ts index 47decf18e5d4..10624134b2cb 100644 --- a/packages/astro/src/actions/runtime/virtual/server.ts +++ b/packages/astro/src/actions/runtime/virtual/server.ts @@ -1,6 +1,10 @@ import { z } from 'zod'; +import type { Pipeline } from '../../../core/base-pipeline.js'; +import { shouldAppendForwardSlash } from '../../../core/build/util.js'; import { ActionCalledFromServerError } from '../../../core/errors/errors-data.js'; import { AstroError } from '../../../core/errors/errors.js'; +import { removeTrailingForwardSlash } from '../../../core/path.js'; +import { apiContextRoutesSymbol } from '../../../core/render-context.js'; import type { APIContext } from '../../../types/public/index.js'; import { ACTION_RPC_ROUTE_PATTERN } from '../../consts.js'; import { @@ -279,7 +283,15 @@ export function getActionContext(context: APIContext): ActionMiddlewareContext { calledFrom: callerInfo.from, name: callerInfo.name, handler: async () => { - const baseAction = await getAction(callerInfo.name); + const pipeline: Pipeline = Reflect.get(context, apiContextRoutesSymbol); + const callerInfoName = shouldAppendForwardSlash( + pipeline.manifest.trailingSlash, + pipeline.manifest.buildFormat, + ) + ? removeTrailingForwardSlash(callerInfo.name) + : callerInfo.name; + + const baseAction = await getAction(callerInfoName); let input; try { input = await parseRequestBody(context.request); diff --git a/packages/astro/src/actions/runtime/virtual/shared.ts b/packages/astro/src/actions/runtime/virtual/shared.ts index 459e135a472c..36269eb4c41b 100644 --- a/packages/astro/src/actions/runtime/virtual/shared.ts +++ b/packages/astro/src/actions/runtime/virtual/shared.ts @@ -3,6 +3,7 @@ import type { z } from 'zod'; import { REDIRECT_STATUS_CODES } from '../../../core/constants.js'; import { ActionsReturnedInvalidDataError } from '../../../core/errors/errors-data.js'; import { AstroError } from '../../../core/errors/errors.js'; +import { appendForwardSlash as _appendForwardSlash } from '../../../core/path.js'; import { ACTION_QUERY_PARAMS as _ACTION_QUERY_PARAMS } from '../../consts.js'; import type { ErrorInferenceObject, @@ -14,6 +15,8 @@ import type { ActionClient } from './server.js'; export type ActionAPIContext = _ActionAPIContext; export const ACTION_QUERY_PARAMS = _ACTION_QUERY_PARAMS; +export const appendForwardSlash = _appendForwardSlash; + export const ACTION_ERROR_CODES = [ 'BAD_REQUEST', 'UNAUTHORIZED', diff --git a/packages/astro/templates/actions.mjs b/packages/astro/templates/actions.mjs index fd14dee68bc7..9b9415ea7d37 100644 --- a/packages/astro/templates/actions.mjs +++ b/packages/astro/templates/actions.mjs @@ -2,6 +2,7 @@ import { ActionError, deserializeActionResult, getActionQueryString, + appendForwardSlash, getActionPath, } from 'astro:actions'; @@ -100,6 +101,19 @@ async function handleAction(param, path, context) { headers, }, ); + + const shouldAppendTrailingSlash = '/** @TRAILING_SLASH@ **/'; + let actionPath = import.meta.env.BASE_URL.replace(/\/$/, '') + '/_actions/' + path; + + if (shouldAppendTrailingSlash) { + actionPath = appendForwardSlash(actionPath); + } + + const rawResult = await fetch(actionPath, { + method: 'POST', + body, + headers, + }); if (rawResult.status === 204) { return deserializeActionResult({ type: 'empty', status: 204 }); } diff --git a/packages/astro/test/actions.test.js b/packages/astro/test/actions.test.js index 05a9ae0f3437..407ff1c005d0 100644 --- a/packages/astro/test/actions.test.js +++ b/packages/astro/test/actions.test.js @@ -564,6 +564,30 @@ it('Base path should be used', async () => { await devServer.stop(); }); +it('Should support trailing slash', async () => { + const fixture = await loadFixture({ + root: './fixtures/actions/', + adapter: testAdapter(), + trailingSlash: 'always', + }); + const devServer = await fixture.startDevServer(); + const formData = new FormData(); + formData.append('channel', 'bholmesdev'); + formData.append('comment', 'Hello, World!'); + const res = await fixture.fetch('/_actions/comment/', { + method: 'POST', + body: formData, + }); + + assert.equal(res.ok, true); + assert.equal(res.headers.get('Content-Type'), 'application/json+devalue'); + + const data = devalue.parse(await res.text()); + assert.equal(data.channel, 'bholmesdev'); + assert.equal(data.comment, 'Hello, World!'); + await devServer.stop(); +}); + it('getActionPath() should return the right path', async () => { const fixture = await loadFixture({ root: './fixtures/actions/', diff --git a/packages/db/package.json b/packages/db/package.json index 7bac47649a82..16b9b17216f7 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -1,6 +1,6 @@ { "name": "@astrojs/db", - "version": "0.14.1", + "version": "0.14.3", "description": "Add libSQL and Astro Studio support to your Astro site", "license": "MIT", "repository": {