Skip to content

Commit

Permalink
feat: working actions demo from astro core!
Browse files Browse the repository at this point in the history
  • Loading branch information
bholmesdev committed Apr 25, 2024
1 parent e50037b commit 038fa46
Show file tree
Hide file tree
Showing 7 changed files with 213 additions and 102 deletions.
7 changes: 6 additions & 1 deletion packages/astro/package.json
Expand Up @@ -53,6 +53,12 @@
"./client/*": "./dist/runtime/client/*",
"./components": "./components/index.ts",
"./components/*": "./components/*",
"./actions/config": {
"types": "./dist/actions/runtime/config.d.ts",
"default": "./dist/actions/runtime/config.js"
},
"./actions/runtime/route.js": "./dist/actions/runtime/route.js",
"./actions/runtime/middleware.js": "./dist/actions/runtime/middleware.js",
"./assets": "./dist/assets/index.js",
"./assets/utils": "./dist/assets/utils/index.js",
"./assets/endpoint/*": "./dist/assets/endpoint/*.js",
Expand Down Expand Up @@ -128,7 +134,6 @@
"@types/cookie": "^0.6.0",
"acorn": "^8.11.3",
"aria-query": "^5.3.0",
"astro-integration-kit": "^0.11.0",
"axobject-query": "^4.0.0",
"boxen": "^7.1.1",
"chokidar": "^3.6.0",
Expand Down
3 changes: 3 additions & 0 deletions packages/astro/src/actions/consts.ts
@@ -0,0 +1,3 @@
export const VIRTUAL_MODULE_ID = 'astro:actions';
export const RESOLVED_VIRTUAL_MODULE_ID = '\0' + VIRTUAL_MODULE_ID;
export const ACTIONS_TYPES_FILE = 'actions.d.ts';
77 changes: 50 additions & 27 deletions packages/astro/src/actions/index.ts
@@ -1,6 +1,8 @@
import { addDts, addVirtualImports } from 'astro-integration-kit';
import { readFile } from 'node:fs/promises';
import { existsSync } from 'node:fs';
import { mkdir, readFile, writeFile } from 'node:fs/promises';
import type { AstroIntegration } from '../@types/astro.js';
import { ACTIONS_TYPES_FILE, RESOLVED_VIRTUAL_MODULE_ID, VIRTUAL_MODULE_ID } from './consts.js';
import type { Plugin as VitePlugin } from 'vite';

const name = 'astro:actions';

Expand All @@ -17,43 +19,64 @@ export default function astroActions(): AstroIntegration {
define: {
'import.meta.env.ACTIONS_PATH': stringifiedActionsPath,
},
plugins: [vitePluginActions],
},
});

params.injectRoute({
pattern: '/_actions/[...path]',
entrypoint: 'astro/actions/internal/route.js',
entrypoint: 'astro/actions/runtime/route.js',
prerender: false,
});

params.addMiddleware({
entrypoint: 'astro/actions/internal/middleware.js',
entrypoint: 'astro/actions/runtime/middleware.js',
order: 'pre',
});
addDts(params as any, {
name,
content: `declare module "astro:actions" {
type Actions = typeof import(${stringifiedActionsPath})["default"];
export const actions: Actions;
}`,
});

const virtualModContent = await readFile(
new URL('../../actions-module.template.mjs', import.meta.url),
'utf-8'
);

addVirtualImports(params as any, {
name,
imports: [
{
id: 'astro:actions',
content: virtualModContent,
// @ts-expect-error bholmesdev accepts risk of being fired
__enableCorePowerDoNotUseOrYouWillBeFired: true,
},
],
await typegen({
stringifiedActionsPath,
root: params.config.root,
});
},
},
};
}

const vitePluginActions: VitePlugin = {
name: 'astro:actions',
enforce: 'pre',
resolveId(id) {
if (id === VIRTUAL_MODULE_ID) {
return RESOLVED_VIRTUAL_MODULE_ID;
}
},
async load(id) {
if (id !== RESOLVED_VIRTUAL_MODULE_ID) return;

const code = await readFile(
new URL('../../actions-module.template.mjs', import.meta.url),
'utf-8'
);
return code;
},
};

async function typegen({
stringifiedActionsPath,
root,
}: { stringifiedActionsPath: string; root: URL }) {
const content = `declare module "astro:actions" {
type Actions = typeof import(${stringifiedActionsPath})["default"];
export const actions: Actions;
}`;

const dotAstroDir = new URL('.astro/', root);

if (!existsSync(dotAstroDir)) {
await mkdir(dotAstroDir);
}

await writeFile(new URL(ACTIONS_TYPES_FILE, dotAstroDir), content);
}
1 change: 0 additions & 1 deletion packages/astro/src/actions/runtime/env.d.ts

This file was deleted.

13 changes: 10 additions & 3 deletions packages/astro/src/actions/runtime/middleware.ts
Expand Up @@ -2,8 +2,15 @@ import { defineMiddleware } from '../../core/middleware/index.js';
import { ApiContextStorage, formContentTypes, getAction } from './utils.js';
import { ActionError } from './virtual.js';

type Locals = {
getActionResult: <T extends (...args: any) => any>(
action: T
) => Promise<Awaited<ReturnType<T>> | undefined>;
};

export const onRequest = defineMiddleware(async (context, next) => {
context.locals.getActionResult = (action) => Promise.resolve(undefined);
const locals = context.locals as Locals;
locals.getActionResult = () => Promise.resolve(undefined);

const { request } = context;
const contentType = request.headers.get('Content-Type');
Expand All @@ -27,8 +34,8 @@ export const onRequest = defineMiddleware(async (context, next) => {
}
actionError = e;
}
context.locals.getActionResult = (action) => {
if (action.toString() !== actionPath) return Promise.resolve(undefined);
locals.getActionResult = (actionFn) => {
if (actionFn.toString() !== actionPath) return Promise.resolve(undefined);
if (actionError) return Promise.reject(actionError);
return Promise.resolve(result);
};
Expand Down
@@ -1,5 +1,5 @@
import { db, Comment, Likes, eq, sql } from "astro:db";
import { defineAction } from "@astrojs/actions/config";
import { defineAction } from "astro/actions/config";
import { z } from "zod";

export default {
Expand Down

0 comments on commit 038fa46

Please sign in to comment.