@elurjs/kit 2.4.4

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.
Files changed (255) hide show
  1. package/CHANGELOG.md +874 -0
  2. package/LICENSE +21 -0
  3. package/README.md +1330 -0
  4. package/bin/elur-kit.js +54 -0
  5. package/dist/lib/action/define.d.cts +72 -0
  6. package/dist/lib/action/define.d.ts +72 -0
  7. package/dist/lib/action/error-store.d.cts +29 -0
  8. package/dist/lib/action/error-store.d.ts +29 -0
  9. package/dist/lib/action/index.cjs +1 -0
  10. package/dist/lib/action/index.d.cts +64 -0
  11. package/dist/lib/action/index.d.ts +64 -0
  12. package/dist/lib/action/index.js +2 -0
  13. package/dist/lib/action/origin.d.cts +20 -0
  14. package/dist/lib/action/origin.d.ts +20 -0
  15. package/dist/lib/action/scan.d.cts +28 -0
  16. package/dist/lib/action/scan.d.ts +28 -0
  17. package/dist/lib/action/server.d.cts +30 -0
  18. package/dist/lib/action/server.d.ts +30 -0
  19. package/dist/lib/action-BB6N5yD-.js +111 -0
  20. package/dist/lib/action-BB6N5yD-.js.map +1 -0
  21. package/dist/lib/action-DZHihU3Z.cjs +2 -0
  22. package/dist/lib/action-DZHihU3Z.cjs.map +1 -0
  23. package/dist/lib/adapters/bun.cjs +30 -0
  24. package/dist/lib/adapters/bun.cjs.map +1 -0
  25. package/dist/lib/adapters/bun.d.cts +13 -0
  26. package/dist/lib/adapters/bun.d.ts +13 -0
  27. package/dist/lib/adapters/bun.js +65 -0
  28. package/dist/lib/adapters/bun.js.map +1 -0
  29. package/dist/lib/adapters/index.cjs +0 -0
  30. package/dist/lib/adapters/index.d.cts +30 -0
  31. package/dist/lib/adapters/index.d.ts +30 -0
  32. package/dist/lib/adapters/index.js +0 -0
  33. package/dist/lib/adapters/netlify.cjs +10 -0
  34. package/dist/lib/adapters/netlify.cjs.map +1 -0
  35. package/dist/lib/adapters/netlify.d.cts +13 -0
  36. package/dist/lib/adapters/netlify.d.ts +13 -0
  37. package/dist/lib/adapters/netlify.js +51 -0
  38. package/dist/lib/adapters/netlify.js.map +1 -0
  39. package/dist/lib/adapters/node.cjs +46 -0
  40. package/dist/lib/adapters/node.cjs.map +1 -0
  41. package/dist/lib/adapters/node.d.cts +13 -0
  42. package/dist/lib/adapters/node.d.ts +13 -0
  43. package/dist/lib/adapters/node.js +105 -0
  44. package/dist/lib/adapters/node.js.map +1 -0
  45. package/dist/lib/adapters/shared.d.cts +17 -0
  46. package/dist/lib/adapters/shared.d.ts +17 -0
  47. package/dist/lib/adapters/vercel.cjs +2 -0
  48. package/dist/lib/adapters/vercel.cjs.map +1 -0
  49. package/dist/lib/adapters/vercel.d.cts +9 -0
  50. package/dist/lib/adapters/vercel.d.ts +9 -0
  51. package/dist/lib/adapters/vercel.js +62 -0
  52. package/dist/lib/adapters/vercel.js.map +1 -0
  53. package/dist/lib/build/build.d.cts +83 -0
  54. package/dist/lib/build/build.d.ts +83 -0
  55. package/dist/lib/build/document-shell.d.cts +48 -0
  56. package/dist/lib/build/document-shell.d.ts +48 -0
  57. package/dist/lib/build/transform-source.d.cts +26 -0
  58. package/dist/lib/build/transform-source.d.ts +26 -0
  59. package/dist/lib/build/vite-build.d.cts +78 -0
  60. package/dist/lib/build/vite-build.d.ts +78 -0
  61. package/dist/lib/cache/policy.d.cts +25 -0
  62. package/dist/lib/cache/policy.d.ts +25 -0
  63. package/dist/lib/cache.d.cts +13 -0
  64. package/dist/lib/cache.d.ts +13 -0
  65. package/dist/lib/capabilities-C0TDQoMY.cjs +2 -0
  66. package/dist/lib/capabilities-C0TDQoMY.cjs.map +1 -0
  67. package/dist/lib/capabilities-C7txofmY.js +45 -0
  68. package/dist/lib/capabilities-C7txofmY.js.map +1 -0
  69. package/dist/lib/cli/commands.d.cts +15 -0
  70. package/dist/lib/cli/commands.d.ts +15 -0
  71. package/dist/lib/cli.cjs +5132 -0
  72. package/dist/lib/cli.cjs.map +1 -0
  73. package/dist/lib/cli.d.cts +30 -0
  74. package/dist/lib/cli.d.ts +30 -0
  75. package/dist/lib/cli.js +5131 -0
  76. package/dist/lib/cli.js.map +1 -0
  77. package/dist/lib/collections-Dbc8aRLf.js +233 -0
  78. package/dist/lib/collections-Dbc8aRLf.js.map +1 -0
  79. package/dist/lib/collections-VDy5g9p8.cjs +13 -0
  80. package/dist/lib/collections-VDy5g9p8.cjs.map +1 -0
  81. package/dist/lib/config/index.cjs +2 -0
  82. package/dist/lib/config/index.cjs.map +1 -0
  83. package/dist/lib/config/index.d.cts +100 -0
  84. package/dist/lib/config/index.d.ts +100 -0
  85. package/dist/lib/config/index.js +122 -0
  86. package/dist/lib/config/index.js.map +1 -0
  87. package/dist/lib/content/collections.d.cts +69 -0
  88. package/dist/lib/content/collections.d.ts +69 -0
  89. package/dist/lib/content/frontmatter.d.cts +20 -0
  90. package/dist/lib/content/frontmatter.d.ts +20 -0
  91. package/dist/lib/content/index.cjs +2 -0
  92. package/dist/lib/content/index.cjs.map +1 -0
  93. package/dist/lib/content/index.d.cts +5 -0
  94. package/dist/lib/content/index.d.ts +5 -0
  95. package/dist/lib/content/index.js +28 -0
  96. package/dist/lib/content/index.js.map +1 -0
  97. package/dist/lib/content/markdown.d.cts +6 -0
  98. package/dist/lib/content/markdown.d.ts +6 -0
  99. package/dist/lib/content/raw.d.cts +9 -0
  100. package/dist/lib/content/raw.d.ts +9 -0
  101. package/dist/lib/content/schema.d.cts +14 -0
  102. package/dist/lib/content/schema.d.ts +14 -0
  103. package/dist/lib/errors-0X7pCFNU.cjs +2 -0
  104. package/dist/lib/errors-0X7pCFNU.cjs.map +1 -0
  105. package/dist/lib/errors-ePYxDlhU.js +70 -0
  106. package/dist/lib/errors-ePYxDlhU.js.map +1 -0
  107. package/dist/lib/errors.d.cts +84 -0
  108. package/dist/lib/errors.d.ts +84 -0
  109. package/dist/lib/hydrate-8a3TbQbs.cjs +2 -0
  110. package/dist/lib/hydrate-8a3TbQbs.cjs.map +1 -0
  111. package/dist/lib/hydrate-CgZGrTxF.js +126 -0
  112. package/dist/lib/hydrate-CgZGrTxF.js.map +1 -0
  113. package/dist/lib/image/index.cjs +2 -0
  114. package/dist/lib/image/index.cjs.map +1 -0
  115. package/dist/lib/image/index.d.cts +37 -0
  116. package/dist/lib/image/index.d.ts +37 -0
  117. package/dist/lib/image/index.js +49 -0
  118. package/dist/lib/image/index.js.map +1 -0
  119. package/dist/lib/image/pipeline.d.cts +37 -0
  120. package/dist/lib/image/pipeline.d.ts +37 -0
  121. package/dist/lib/image/registry.cjs +2 -0
  122. package/dist/lib/image/registry.cjs.map +1 -0
  123. package/dist/lib/image/registry.d.cts +26 -0
  124. package/dist/lib/image/registry.d.ts +26 -0
  125. package/dist/lib/image/registry.js +23 -0
  126. package/dist/lib/image/registry.js.map +1 -0
  127. package/dist/lib/image/service.cjs +2 -0
  128. package/dist/lib/image/service.cjs.map +1 -0
  129. package/dist/lib/image/service.d.cts +164 -0
  130. package/dist/lib/image/service.d.ts +164 -0
  131. package/dist/lib/image/service.js +308 -0
  132. package/dist/lib/image/service.js.map +1 -0
  133. package/dist/lib/index.cjs +1 -0
  134. package/dist/lib/index.cjs.map +1 -0
  135. package/dist/lib/index.d.cts +38 -0
  136. package/dist/lib/index.d.ts +38 -0
  137. package/dist/lib/index.js +1 -0
  138. package/dist/lib/index.js.map +1 -0
  139. package/dist/lib/integrations/hooks.d.cts +58 -0
  140. package/dist/lib/integrations/hooks.d.ts +58 -0
  141. package/dist/lib/integrations/index.cjs +1 -0
  142. package/dist/lib/integrations/index.d.cts +18 -0
  143. package/dist/lib/integrations/index.d.ts +18 -0
  144. package/dist/lib/integrations/index.js +2 -0
  145. package/dist/lib/integrations-7dpN1RYB.js +35 -0
  146. package/dist/lib/integrations-7dpN1RYB.js.map +1 -0
  147. package/dist/lib/integrations-DDqfWjvH.cjs +2 -0
  148. package/dist/lib/integrations-DDqfWjvH.cjs.map +1 -0
  149. package/dist/lib/interpolation-plugin-Bt-KRKVY.js +365 -0
  150. package/dist/lib/interpolation-plugin-Bt-KRKVY.js.map +1 -0
  151. package/dist/lib/interpolation-plugin-CMPCDlVJ.cjs +31 -0
  152. package/dist/lib/interpolation-plugin-CMPCDlVJ.cjs.map +1 -0
  153. package/dist/lib/island/generate-entry.d.cts +27 -0
  154. package/dist/lib/island/generate-entry.d.ts +27 -0
  155. package/dist/lib/island/hydrate.d.cts +33 -0
  156. package/dist/lib/island/hydrate.d.ts +33 -0
  157. package/dist/lib/island/index.cjs +1 -0
  158. package/dist/lib/island/index.d.cts +2 -0
  159. package/dist/lib/island/index.d.ts +2 -0
  160. package/dist/lib/island/index.js +1 -0
  161. package/dist/lib/island/island.d.cts +32 -0
  162. package/dist/lib/island/island.d.ts +32 -0
  163. package/dist/lib/island/scan.d.cts +14 -0
  164. package/dist/lib/island/scan.d.ts +14 -0
  165. package/dist/lib/manifest/index.cjs +3 -0
  166. package/dist/lib/manifest/index.cjs.map +1 -0
  167. package/dist/lib/manifest/index.d.cts +18 -0
  168. package/dist/lib/manifest/index.d.ts +18 -0
  169. package/dist/lib/manifest/index.js +110 -0
  170. package/dist/lib/manifest/index.js.map +1 -0
  171. package/dist/lib/middleware/index.d.cts +56 -0
  172. package/dist/lib/middleware/index.d.ts +56 -0
  173. package/dist/lib/middleware/stream-boundary.d.cts +53 -0
  174. package/dist/lib/middleware/stream-boundary.d.ts +53 -0
  175. package/dist/lib/node-http-DRAUhO0c.js +617 -0
  176. package/dist/lib/node-http-DRAUhO0c.js.map +1 -0
  177. package/dist/lib/node-http-DhxguYyz.cjs +13 -0
  178. package/dist/lib/node-http-DhxguYyz.cjs.map +1 -0
  179. package/dist/lib/render/render-to-string.d.cts +12 -0
  180. package/dist/lib/render/render-to-string.d.ts +12 -0
  181. package/dist/lib/render/ssr-flag.d.cts +4 -0
  182. package/dist/lib/render/ssr-flag.d.ts +4 -0
  183. package/dist/lib/route-scanner-JY6YrNH5.cjs +2 -0
  184. package/dist/lib/route-scanner-JY6YrNH5.cjs.map +1 -0
  185. package/dist/lib/route-scanner-XcLId7lK.js +100 -0
  186. package/dist/lib/route-scanner-XcLId7lK.js.map +1 -0
  187. package/dist/lib/router/client.cjs +2 -0
  188. package/dist/lib/router/client.cjs.map +1 -0
  189. package/dist/lib/router/client.d.cts +47 -0
  190. package/dist/lib/router/client.d.ts +47 -0
  191. package/dist/lib/router/client.js +298 -0
  192. package/dist/lib/router/client.js.map +1 -0
  193. package/dist/lib/router/route-scanner.d.cts +50 -0
  194. package/dist/lib/router/route-scanner.d.ts +50 -0
  195. package/dist/lib/runtime/capabilities.d.cts +47 -0
  196. package/dist/lib/runtime/capabilities.d.ts +47 -0
  197. package/dist/lib/runtime/context.d.cts +140 -0
  198. package/dist/lib/runtime/context.d.ts +140 -0
  199. package/dist/lib/runtime/handler.d.cts +39 -0
  200. package/dist/lib/runtime/handler.d.ts +39 -0
  201. package/dist/lib/runtime/index.cjs +1 -0
  202. package/dist/lib/runtime/index.d.cts +6 -0
  203. package/dist/lib/runtime/index.d.ts +6 -0
  204. package/dist/lib/runtime/index.js +4 -0
  205. package/dist/lib/runtime/node-http.d.cts +2 -0
  206. package/dist/lib/runtime/node-http.d.ts +2 -0
  207. package/dist/lib/runtime/security-headers.d.cts +13 -0
  208. package/dist/lib/runtime/security-headers.d.ts +13 -0
  209. package/dist/lib/runtime/static.d.cts +1 -0
  210. package/dist/lib/runtime/static.d.ts +1 -0
  211. package/dist/lib/runtime-CrH5X-Es.cjs +2 -0
  212. package/dist/lib/runtime-CrH5X-Es.cjs.map +1 -0
  213. package/dist/lib/runtime-Ds2-wH6P.js +520 -0
  214. package/dist/lib/runtime-Ds2-wH6P.js.map +1 -0
  215. package/dist/lib/scan-CY2O9ty6.cjs +2 -0
  216. package/dist/lib/scan-CY2O9ty6.cjs.map +1 -0
  217. package/dist/lib/scan-CjMUgnsd.js +22 -0
  218. package/dist/lib/scan-CjMUgnsd.js.map +1 -0
  219. package/dist/lib/scan-DXzYtmRQ.cjs +2 -0
  220. package/dist/lib/scan-DXzYtmRQ.cjs.map +1 -0
  221. package/dist/lib/scan-Dn93ycXG.js +33 -0
  222. package/dist/lib/scan-Dn93ycXG.js.map +1 -0
  223. package/dist/lib/seo/index.cjs +10 -0
  224. package/dist/lib/seo/index.cjs.map +1 -0
  225. package/dist/lib/seo/index.d.cts +99 -0
  226. package/dist/lib/seo/index.d.ts +99 -0
  227. package/dist/lib/seo/index.js +41 -0
  228. package/dist/lib/seo/index.js.map +1 -0
  229. package/dist/lib/shared-CfqOLsKj.cjs +183 -0
  230. package/dist/lib/shared-CfqOLsKj.cjs.map +1 -0
  231. package/dist/lib/shared-DU3iQgr7.js +236 -0
  232. package/dist/lib/shared-DU3iQgr7.js.map +1 -0
  233. package/dist/lib/ssr/match.d.cts +25 -0
  234. package/dist/lib/ssr/match.d.ts +25 -0
  235. package/dist/lib/ssr/render.d.cts +62 -0
  236. package/dist/lib/ssr/render.d.ts +62 -0
  237. package/dist/lib/ssr/server.d.cts +41 -0
  238. package/dist/lib/ssr/server.d.ts +41 -0
  239. package/dist/lib/ssr/stream.d.cts +48 -0
  240. package/dist/lib/ssr/stream.d.ts +48 -0
  241. package/dist/lib/stream-CpOG052V.js +104 -0
  242. package/dist/lib/stream-CpOG052V.js.map +1 -0
  243. package/dist/lib/stream-DmZjYqHm.cjs +17 -0
  244. package/dist/lib/stream-DmZjYqHm.cjs.map +1 -0
  245. package/dist/lib/types.d.cts +97 -0
  246. package/dist/lib/types.d.ts +97 -0
  247. package/dist/lib/vite/index.cjs +2 -0
  248. package/dist/lib/vite/index.cjs.map +1 -0
  249. package/dist/lib/vite/index.d.cts +41 -0
  250. package/dist/lib/vite/index.d.ts +41 -0
  251. package/dist/lib/vite/index.js +229 -0
  252. package/dist/lib/vite/index.js.map +1 -0
  253. package/dist/lib/vite/interpolation-plugin.d.cts +64 -0
  254. package/dist/lib/vite/interpolation-plugin.d.ts +64 -0
  255. package/package.json +292 -0
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync } from "node:fs";
3
+ import { join, dirname } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { spawnSync } from "node:child_process";
6
+
7
+ const cwd = process.cwd();
8
+ const here = dirname(fileURLToPath(import.meta.url));
9
+
10
+ // Bun projects can use `bun:` protocol imports (bun:sqlite, etc.). When the
11
+ // bin is spawned through node (e.g. `bun run build` -> sh -> `env node`),
12
+ // those imports cannot be resolved, so re-exec with the Bun runtime when the
13
+ // project is bun-managed (bun.lock present).
14
+ if (
15
+ !process.versions.bun &&
16
+ (existsSync(join(cwd, "bun.lock")) || existsSync(join(cwd, "bun.lockb")))
17
+ ) {
18
+ const probe = spawnSync("bun", ["--version"], { stdio: "ignore" });
19
+ if (probe.status === 0) {
20
+ const result = spawnSync("bun", [fileURLToPath(import.meta.url), ...process.argv.slice(2)], {
21
+ stdio: "inherit",
22
+ env: process.env,
23
+ });
24
+ process.exit(result.status ?? 1);
25
+ }
26
+ }
27
+
28
+ // Register tsx so dynamic imports of user .ts pages/islands work at runtime
29
+ // under Node. Bun transpiles TypeScript natively and does not need it.
30
+ if (!process.versions.bun) {
31
+ const tsx = await import("tsx/esm/api").catch(() => null);
32
+ if (tsx) tsx.register();
33
+ }
34
+
35
+ const built = join(here, "../dist/lib/cli.js");
36
+
37
+ if (!existsSync(built)) {
38
+ console.log("[elur-kit] dist/lib/cli.js not found, running npm run build:lib...");
39
+ const result = spawnSync("npm", ["run", "build:lib"], {
40
+ stdio: "inherit",
41
+ cwd: join(here, ".."),
42
+ });
43
+ if (result.status !== 0) {
44
+ console.error("[elur-kit] build:lib failed");
45
+ process.exit(result.status ?? 1);
46
+ }
47
+ }
48
+
49
+ const { run } = await import(built);
50
+
51
+ run(process.argv).catch((err) => {
52
+ console.error(err);
53
+ process.exit(1);
54
+ });
@@ -0,0 +1,72 @@
1
+ import type { ActionFailure } from "../errors.js";
2
+ /** Concurrency mode for actions called multiple times in rapid succession. */
3
+ export type ActionConcurrencyMode = "latest" | "queue" | "parallel";
4
+ /** Options for defining a typed server action. */
5
+ export interface DefineActionOptions<TInput> {
6
+ /**
7
+ * Optional input validator. Can be a Zod schema, a plain function, or any
8
+ * object with a `.parse()` method. If validation fails, the action returns
9
+ * a 400 ActionFailure with the validation error.
10
+ */
11
+ input?: ActionInputValidator<TInput>;
12
+ /** Concurrency mode when the same action is called multiple times. */
13
+ concurrency?: ActionConcurrencyMode;
14
+ /** Whether the action is idempotent (safe to retry). */
15
+ idempotent?: boolean;
16
+ /** Tags to invalidate from the cache after a successful action (§9.4). */
17
+ invalidateTags?: string[];
18
+ /** Paths to invalidate from the cache after a successful action (§9.4). */
19
+ invalidatePaths?: string[];
20
+ }
21
+ /** A validator that has a `.parse()` method (Zod-compatible) or is a function. */
22
+ export interface ActionInputValidator<T> {
23
+ parse(input: unknown): T;
24
+ }
25
+ /** Context passed to a defined action. */
26
+ export interface ActionContext {
27
+ /** The original Web Request. */
28
+ request: Request;
29
+ /** AbortSignal from the request — aborts if the client disconnects. */
30
+ signal: AbortSignal;
31
+ /** Idempotency key from the request header, if present. */
32
+ idempotencyKey?: string;
33
+ /** Route params (for page-scoped actions). */
34
+ params: Record<string, string | string[]>;
35
+ /** Per-request locals (populated by middleware). */
36
+ locals: Record<string, unknown>;
37
+ }
38
+ /** A defined action function. */
39
+ export type DefinedActionFn<TInput, TOutput> = (input: TInput, ctx: ActionContext) => Promise<TOutput | ActionFailure<TOutput>>;
40
+ /** The return type of defineAction(): a callable with metadata. */
41
+ export interface DefinedAction<TInput, TOutput> {
42
+ (input: TInput, ctx: ActionContext): Promise<TOutput | ActionFailure<TOutput>>;
43
+ /** Metadata for the action (used by the runtime/manifest). */
44
+ __elurAction: {
45
+ name: string;
46
+ concurrency: ActionConcurrencyMode;
47
+ idempotent: boolean;
48
+ invalidateTags: readonly string[];
49
+ invalidatePaths: readonly string[];
50
+ };
51
+ }
52
+ /**
53
+ * Defines a typed server action with validation, abort support, and cache
54
+ * invalidation metadata.
55
+ *
56
+ * ```ts
57
+ * import { defineAction, fail } from "@elurjs/kit/action";
58
+ *
59
+ * export const submitContact = defineAction({
60
+ * input: { parse: (v) => v as { name: string; email: string } },
61
+ * invalidateTags: ["contacts"],
62
+ * }, async (input, ctx) => {
63
+ * if (!input.email.includes("@")) return fail(400, { email: "Invalid" });
64
+ * await saveContact(input);
65
+ * return { success: true };
66
+ * });
67
+ * ```
68
+ *
69
+ * Legacy exported async functions (without `defineAction`) continue to work
70
+ * as before — this is an opt-in upgrade.
71
+ */
72
+ export declare function defineAction<TInput = unknown, TOutput = unknown>(options: DefineActionOptions<TInput>, handler: DefinedActionFn<TInput, TOutput>): DefinedAction<TInput, TOutput>;
@@ -0,0 +1,72 @@
1
+ import type { ActionFailure } from "../errors.js";
2
+ /** Concurrency mode for actions called multiple times in rapid succession. */
3
+ export type ActionConcurrencyMode = "latest" | "queue" | "parallel";
4
+ /** Options for defining a typed server action. */
5
+ export interface DefineActionOptions<TInput> {
6
+ /**
7
+ * Optional input validator. Can be a Zod schema, a plain function, or any
8
+ * object with a `.parse()` method. If validation fails, the action returns
9
+ * a 400 ActionFailure with the validation error.
10
+ */
11
+ input?: ActionInputValidator<TInput>;
12
+ /** Concurrency mode when the same action is called multiple times. */
13
+ concurrency?: ActionConcurrencyMode;
14
+ /** Whether the action is idempotent (safe to retry). */
15
+ idempotent?: boolean;
16
+ /** Tags to invalidate from the cache after a successful action (§9.4). */
17
+ invalidateTags?: string[];
18
+ /** Paths to invalidate from the cache after a successful action (§9.4). */
19
+ invalidatePaths?: string[];
20
+ }
21
+ /** A validator that has a `.parse()` method (Zod-compatible) or is a function. */
22
+ export interface ActionInputValidator<T> {
23
+ parse(input: unknown): T;
24
+ }
25
+ /** Context passed to a defined action. */
26
+ export interface ActionContext {
27
+ /** The original Web Request. */
28
+ request: Request;
29
+ /** AbortSignal from the request — aborts if the client disconnects. */
30
+ signal: AbortSignal;
31
+ /** Idempotency key from the request header, if present. */
32
+ idempotencyKey?: string;
33
+ /** Route params (for page-scoped actions). */
34
+ params: Record<string, string | string[]>;
35
+ /** Per-request locals (populated by middleware). */
36
+ locals: Record<string, unknown>;
37
+ }
38
+ /** A defined action function. */
39
+ export type DefinedActionFn<TInput, TOutput> = (input: TInput, ctx: ActionContext) => Promise<TOutput | ActionFailure<TOutput>>;
40
+ /** The return type of defineAction(): a callable with metadata. */
41
+ export interface DefinedAction<TInput, TOutput> {
42
+ (input: TInput, ctx: ActionContext): Promise<TOutput | ActionFailure<TOutput>>;
43
+ /** Metadata for the action (used by the runtime/manifest). */
44
+ __elurAction: {
45
+ name: string;
46
+ concurrency: ActionConcurrencyMode;
47
+ idempotent: boolean;
48
+ invalidateTags: readonly string[];
49
+ invalidatePaths: readonly string[];
50
+ };
51
+ }
52
+ /**
53
+ * Defines a typed server action with validation, abort support, and cache
54
+ * invalidation metadata.
55
+ *
56
+ * ```ts
57
+ * import { defineAction, fail } from "@elurjs/kit/action";
58
+ *
59
+ * export const submitContact = defineAction({
60
+ * input: { parse: (v) => v as { name: string; email: string } },
61
+ * invalidateTags: ["contacts"],
62
+ * }, async (input, ctx) => {
63
+ * if (!input.email.includes("@")) return fail(400, { email: "Invalid" });
64
+ * await saveContact(input);
65
+ * return { success: true };
66
+ * });
67
+ * ```
68
+ *
69
+ * Legacy exported async functions (without `defineAction`) continue to work
70
+ * as before — this is an opt-in upgrade.
71
+ */
72
+ export declare function defineAction<TInput = unknown, TOutput = unknown>(options: DefineActionOptions<TInput>, handler: DefinedActionFn<TInput, TOutput>): DefinedAction<TInput, TOutput>;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Encodes an action failure for the redirect cookie. When the payload fits
3
+ * inside the cookie limit, it is embedded directly as a signed base64url JSON
4
+ * value. When it is too large, it is stored in memory and only a short signed
5
+ * id is written to the cookie.
6
+ *
7
+ * The cookie is signed with HMAC-SHA256 to prevent forgery (A-20).
8
+ *
9
+ * @returns The cookie value to set on the redirect response.
10
+ */
11
+ export declare function encodeActionErrorCookie(data: unknown, status: number): {
12
+ value: string;
13
+ storeId?: string;
14
+ };
15
+ /**
16
+ * Decodes a cookie value (previously produced by `encodeActionErrorCookie`)
17
+ * into the failure payload. Verifies the HMAC signature first, then resolves
18
+ * in-memory overflow entries and deletes them after reading.
19
+ */
20
+ export declare function decodeActionErrorCookie(value: string | undefined | null): {
21
+ data: unknown;
22
+ status: number;
23
+ } | undefined;
24
+ /** Name of the cookie used to relay action errors. */
25
+ export declare const ACTION_ERROR_COOKIE = "__elur_js_action_error";
26
+ /** Builds the Set-Cookie header value that clears the error cookie. */
27
+ export declare function clearActionErrorCookieHeader(): string;
28
+ /** Builds the Set-Cookie header value that sets the error cookie. */
29
+ export declare function setActionErrorCookieHeader(value: string): string;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Encodes an action failure for the redirect cookie. When the payload fits
3
+ * inside the cookie limit, it is embedded directly as a signed base64url JSON
4
+ * value. When it is too large, it is stored in memory and only a short signed
5
+ * id is written to the cookie.
6
+ *
7
+ * The cookie is signed with HMAC-SHA256 to prevent forgery (A-20).
8
+ *
9
+ * @returns The cookie value to set on the redirect response.
10
+ */
11
+ export declare function encodeActionErrorCookie(data: unknown, status: number): {
12
+ value: string;
13
+ storeId?: string;
14
+ };
15
+ /**
16
+ * Decodes a cookie value (previously produced by `encodeActionErrorCookie`)
17
+ * into the failure payload. Verifies the HMAC signature first, then resolves
18
+ * in-memory overflow entries and deletes them after reading.
19
+ */
20
+ export declare function decodeActionErrorCookie(value: string | undefined | null): {
21
+ data: unknown;
22
+ status: number;
23
+ } | undefined;
24
+ /** Name of the cookie used to relay action errors. */
25
+ export declare const ACTION_ERROR_COOKIE = "__elur_js_action_error";
26
+ /** Builds the Set-Cookie header value that clears the error cookie. */
27
+ export declare function clearActionErrorCookieHeader(): string;
28
+ /** Builds the Set-Cookie header value that sets the error cookie. */
29
+ export declare function setActionErrorCookieHeader(value: string): string;
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../action-DZHihU3Z.cjs");exports.callAction=e.t,exports.defineAction=e.r,exports.elurJsAction=e.n;
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Client-side helpers for invoking server actions.
3
+ *
4
+ * Server actions are defined in `page.action.ts` files next to `page.ts`.
5
+ * They export async functions that run on the server. On the client, call them
6
+ * by name using `callAction` or the higher-level `elurJsAction` helper:
7
+ *
8
+ * ```ts
9
+ * import { callAction } from "@elurjs/kit/action";
10
+ *
11
+ * const result = await callAction("submitContact", { name: "Ada" }, { page: "/contact" });
12
+ * ```
13
+ *
14
+ * ```ts
15
+ * import { elurJsAction } from "@elurjs/kit/action";
16
+ *
17
+ * const contact = elurJsAction("submitContact", { page: "/contact" });
18
+ * await contact.submit({ name: "Ada" });
19
+ * console.log(contact.data.value, contact.error.value, contact.pending.value);
20
+ * ```
21
+ */
22
+ import { ActionFailure, RedirectResponse } from "../errors.js";
23
+ export interface ActionRequest {
24
+ name: string;
25
+ page?: string;
26
+ args: unknown[];
27
+ }
28
+ export interface CallActionOptions {
29
+ /** Page URL path that scopes the action, e.g. `/contact`. */
30
+ page?: string;
31
+ }
32
+ /**
33
+ * Call a server action by name.
34
+ *
35
+ * The request is sent as a POST to `/__elur-js/actions` with the action name,
36
+ * optional page scope, and serialized arguments. The server executes the
37
+ * matching exported function from the scanned `page.action.ts` modules and
38
+ * returns its JSON result.
39
+ */
40
+ export declare function callAction<T = unknown>(name: string, args?: unknown, options?: CallActionOptions): Promise<T | ActionFailure<T> | RedirectResponse>;
41
+ export interface ElurJsAction<TInput = unknown, TOutput = unknown> {
42
+ /** Submit the action with the given input. */
43
+ submit(input: TInput): Promise<TOutput | ActionFailure<TOutput> | RedirectResponse>;
44
+ /** Signal that is true while the action is running. */
45
+ pending: {
46
+ value: boolean;
47
+ };
48
+ /** Signal with the last successful result, action failure, redirect, or null. */
49
+ data: {
50
+ value: TOutput | ActionFailure<TOutput> | RedirectResponse | null;
51
+ };
52
+ /** Signal with the last error, or null. */
53
+ error: {
54
+ value: Error | null;
55
+ };
56
+ }
57
+ /**
58
+ * Create a reactive handle for a server action.
59
+ *
60
+ * Returns a `submit` function and signals for `pending`, `data`, and `error`.
61
+ * Useful for wiring actions to forms and islands without manual signal boilerplate.
62
+ */
63
+ export declare function elurJsAction<TInput = unknown, TOutput = unknown>(name: string, options?: CallActionOptions): ElurJsAction<TInput, TOutput>;
64
+ export { defineAction, type DefineActionOptions, type DefinedAction, type DefinedActionFn, type ActionContext, type ActionInputValidator, type ActionConcurrencyMode, } from "./define.js";
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Client-side helpers for invoking server actions.
3
+ *
4
+ * Server actions are defined in `page.action.ts` files next to `page.ts`.
5
+ * They export async functions that run on the server. On the client, call them
6
+ * by name using `callAction` or the higher-level `elurJsAction` helper:
7
+ *
8
+ * ```ts
9
+ * import { callAction } from "@elurjs/kit/action";
10
+ *
11
+ * const result = await callAction("submitContact", { name: "Ada" }, { page: "/contact" });
12
+ * ```
13
+ *
14
+ * ```ts
15
+ * import { elurJsAction } from "@elurjs/kit/action";
16
+ *
17
+ * const contact = elurJsAction("submitContact", { page: "/contact" });
18
+ * await contact.submit({ name: "Ada" });
19
+ * console.log(contact.data.value, contact.error.value, contact.pending.value);
20
+ * ```
21
+ */
22
+ import { ActionFailure, RedirectResponse } from "../errors.js";
23
+ export interface ActionRequest {
24
+ name: string;
25
+ page?: string;
26
+ args: unknown[];
27
+ }
28
+ export interface CallActionOptions {
29
+ /** Page URL path that scopes the action, e.g. `/contact`. */
30
+ page?: string;
31
+ }
32
+ /**
33
+ * Call a server action by name.
34
+ *
35
+ * The request is sent as a POST to `/__elur-js/actions` with the action name,
36
+ * optional page scope, and serialized arguments. The server executes the
37
+ * matching exported function from the scanned `page.action.ts` modules and
38
+ * returns its JSON result.
39
+ */
40
+ export declare function callAction<T = unknown>(name: string, args?: unknown, options?: CallActionOptions): Promise<T | ActionFailure<T> | RedirectResponse>;
41
+ export interface ElurJsAction<TInput = unknown, TOutput = unknown> {
42
+ /** Submit the action with the given input. */
43
+ submit(input: TInput): Promise<TOutput | ActionFailure<TOutput> | RedirectResponse>;
44
+ /** Signal that is true while the action is running. */
45
+ pending: {
46
+ value: boolean;
47
+ };
48
+ /** Signal with the last successful result, action failure, redirect, or null. */
49
+ data: {
50
+ value: TOutput | ActionFailure<TOutput> | RedirectResponse | null;
51
+ };
52
+ /** Signal with the last error, or null. */
53
+ error: {
54
+ value: Error | null;
55
+ };
56
+ }
57
+ /**
58
+ * Create a reactive handle for a server action.
59
+ *
60
+ * Returns a `submit` function and signals for `pending`, `data`, and `error`.
61
+ * Useful for wiring actions to forms and islands without manual signal boilerplate.
62
+ */
63
+ export declare function elurJsAction<TInput = unknown, TOutput = unknown>(name: string, options?: CallActionOptions): ElurJsAction<TInput, TOutput>;
64
+ export { defineAction, type DefineActionOptions, type DefinedAction, type DefinedActionFn, type ActionContext, type ActionInputValidator, type ActionConcurrencyMode, } from "./define.js";
@@ -0,0 +1,2 @@
1
+ import { n as e, r as t, t as n } from "../action-BB6N5yD-.js";
2
+ export { n as callAction, t as defineAction, e as elurJsAction };
@@ -0,0 +1,20 @@
1
+ export interface OriginCheckOptions {
2
+ /** Extra origins allowed to call actions (e.g. preview deployments). */
3
+ allowedOrigins?: string[];
4
+ /**
5
+ * When true, requests missing both `Origin` and `Referer` are rejected.
6
+ * Defaults to false so curl/server-to-server calls keep working.
7
+ */
8
+ strictOrigin?: boolean;
9
+ }
10
+ /**
11
+ * Verifies that a request originates from the same host (or an allow-listed
12
+ * origin). Returns an error message when the request must be rejected, or
13
+ * undefined when it is allowed.
14
+ *
15
+ * @param request The incoming Request to actions.
16
+ * @param options Origin check configuration.
17
+ */
18
+ export declare function verifyOrigin(request: Request, options?: OriginCheckOptions): string | undefined;
19
+ /** Builds a 403 Response for a rejected origin. */
20
+ export declare function originForbidden(message: string): Response;
@@ -0,0 +1,20 @@
1
+ export interface OriginCheckOptions {
2
+ /** Extra origins allowed to call actions (e.g. preview deployments). */
3
+ allowedOrigins?: string[];
4
+ /**
5
+ * When true, requests missing both `Origin` and `Referer` are rejected.
6
+ * Defaults to false so curl/server-to-server calls keep working.
7
+ */
8
+ strictOrigin?: boolean;
9
+ }
10
+ /**
11
+ * Verifies that a request originates from the same host (or an allow-listed
12
+ * origin). Returns an error message when the request must be rejected, or
13
+ * undefined when it is allowed.
14
+ *
15
+ * @param request The incoming Request to actions.
16
+ * @param options Origin check configuration.
17
+ */
18
+ export declare function verifyOrigin(request: Request, options?: OriginCheckOptions): string | undefined;
19
+ /** Builds a 403 Response for a rejected origin. */
20
+ export declare function originForbidden(message: string): Response;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Registry of server actions grouped by page path.
3
+ *
4
+ * The outer key is the page URL path (e.g. "/contact"). The inner object maps
5
+ * each exported action name to the absolute file path of the `page.action.ts`
6
+ * module that defines it.
7
+ */
8
+ export type ActionRegistry = Record<string, Record<string, string>>;
9
+ /**
10
+ * Scans `page.action.ts` modules and returns a per-page registry of server actions.
11
+ *
12
+ * Only named function exports are collected; default exports are ignored. The
13
+ * registry is keyed by page URL path so the client can resolve actions scoped
14
+ * to a specific page and avoid name collisions between different routes.
15
+ */
16
+ export declare function scanActions(appDir: string): Promise<ActionRegistry>;
17
+ /**
18
+ * Return a copy of the action registry where every file path is made relative to
19
+ * the given project root. Useful for serializing actions into the HTML shell
20
+ * without exposing absolute server paths.
21
+ */
22
+ export declare function relativeActions(actions: ActionRegistry, root: string): ActionRegistry;
23
+ /**
24
+ * Return only the names of available actions per page, without file paths.
25
+ * This is the safe format to serialize into the HTML shell: the client only
26
+ * needs to know which actions exist, never where they are implemented.
27
+ */
28
+ export declare function actionNames(actions: ActionRegistry): Record<string, string[]>;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Registry of server actions grouped by page path.
3
+ *
4
+ * The outer key is the page URL path (e.g. "/contact"). The inner object maps
5
+ * each exported action name to the absolute file path of the `page.action.ts`
6
+ * module that defines it.
7
+ */
8
+ export type ActionRegistry = Record<string, Record<string, string>>;
9
+ /**
10
+ * Scans `page.action.ts` modules and returns a per-page registry of server actions.
11
+ *
12
+ * Only named function exports are collected; default exports are ignored. The
13
+ * registry is keyed by page URL path so the client can resolve actions scoped
14
+ * to a specific page and avoid name collisions between different routes.
15
+ */
16
+ export declare function scanActions(appDir: string): Promise<ActionRegistry>;
17
+ /**
18
+ * Return a copy of the action registry where every file path is made relative to
19
+ * the given project root. Useful for serializing actions into the HTML shell
20
+ * without exposing absolute server paths.
21
+ */
22
+ export declare function relativeActions(actions: ActionRegistry, root: string): ActionRegistry;
23
+ /**
24
+ * Return only the names of available actions per page, without file paths.
25
+ * This is the safe format to serialize into the HTML shell: the client only
26
+ * needs to know which actions exist, never where they are implemented.
27
+ */
28
+ export declare function actionNames(actions: ActionRegistry): Record<string, string[]>;
@@ -0,0 +1,30 @@
1
+ import { type OriginCheckOptions } from "./origin.js";
2
+ /**
3
+ * Resolves a server action by name and optional page scope.
4
+ */
5
+ export type ActionResolver = (name: string, page?: string) => Promise<((...args: unknown[]) => unknown) | undefined>;
6
+ /** Options shared by `handleActionRequest` callers for CSRF protection. */
7
+ export interface ActionSecurityOptions extends OriginCheckOptions {
8
+ /** Maximum body size in bytes. Defaults to 1MB (1_048_576). */
9
+ bodyLimit?: number;
10
+ }
11
+ /**
12
+ * Handles a POST request to the server action endpoint.
13
+ *
14
+ * Accepts both JSON requests (`{ name, page?, args }`) and HTML form submissions
15
+ * for progressive enhancement. The provided resolver looks up the action
16
+ * implementation, invokes it with the supplied arguments and returns the result
17
+ * as JSON or redirects back to the request origin for form submissions.
18
+ *
19
+ * Origin verification (CSRF protection) runs before parsing the body: any
20
+ * cross-origin POST is rejected with 403 unless its origin is allow-listed via
21
+ * `security.allowedOrigins`.
22
+ *
23
+ * For progressive-enhancement form submissions that fail, the failure payload
24
+ * is relayed back via a short-lived `__elur_js_action_error` cookie (SameSite=Lax,
25
+ * Max-Age=15s) instead of a query param, so errors do not leak into browser
26
+ * history, server logs or third-party Referer headers.
27
+ */
28
+ export declare function handleActionRequest(request: Request, resolveAction: ActionResolver, security?: ActionSecurityOptions): Promise<Response>;
29
+ export { verifyOrigin, originForbidden, type OriginCheckOptions } from "./origin.js";
30
+ export { decodeActionErrorCookie, clearActionErrorCookieHeader, setActionErrorCookieHeader, ACTION_ERROR_COOKIE, } from "./error-store.js";
@@ -0,0 +1,30 @@
1
+ import { type OriginCheckOptions } from "./origin.js";
2
+ /**
3
+ * Resolves a server action by name and optional page scope.
4
+ */
5
+ export type ActionResolver = (name: string, page?: string) => Promise<((...args: unknown[]) => unknown) | undefined>;
6
+ /** Options shared by `handleActionRequest` callers for CSRF protection. */
7
+ export interface ActionSecurityOptions extends OriginCheckOptions {
8
+ /** Maximum body size in bytes. Defaults to 1MB (1_048_576). */
9
+ bodyLimit?: number;
10
+ }
11
+ /**
12
+ * Handles a POST request to the server action endpoint.
13
+ *
14
+ * Accepts both JSON requests (`{ name, page?, args }`) and HTML form submissions
15
+ * for progressive enhancement. The provided resolver looks up the action
16
+ * implementation, invokes it with the supplied arguments and returns the result
17
+ * as JSON or redirects back to the request origin for form submissions.
18
+ *
19
+ * Origin verification (CSRF protection) runs before parsing the body: any
20
+ * cross-origin POST is rejected with 403 unless its origin is allow-listed via
21
+ * `security.allowedOrigins`.
22
+ *
23
+ * For progressive-enhancement form submissions that fail, the failure payload
24
+ * is relayed back via a short-lived `__elur_js_action_error` cookie (SameSite=Lax,
25
+ * Max-Age=15s) instead of a query param, so errors do not leak into browser
26
+ * history, server logs or third-party Referer headers.
27
+ */
28
+ export declare function handleActionRequest(request: Request, resolveAction: ActionResolver, security?: ActionSecurityOptions): Promise<Response>;
29
+ export { verifyOrigin, originForbidden, type OriginCheckOptions } from "./origin.js";
30
+ export { decodeActionErrorCookie, clearActionErrorCookieHeader, setActionErrorCookieHeader, ACTION_ERROR_COOKIE, } from "./error-store.js";
@@ -0,0 +1,111 @@
1
+ import { n as e, t } from "./errors-ePYxDlhU.js";
2
+ import { signal as n } from "@elurjs/core";
3
+ //#region src/action/define.ts
4
+ var r = globalThis.AbortController;
5
+ function i(e, t) {
6
+ let n = e.concurrency ?? "latest", i = e.idempotent ?? !1, o = e.invalidateTags ?? [], s = e.invalidatePaths ?? [], c = null, l = [], u = 0;
7
+ async function d(n, r) {
8
+ if (e.input) try {
9
+ n = e.input.parse(n);
10
+ } catch (e) {
11
+ let t = e instanceof Error ? e.message : String(e), { fail: n } = await import("./errors-ePYxDlhU.js").then((e) => e.r);
12
+ return n(400, { validation: t });
13
+ }
14
+ return t(n, r);
15
+ }
16
+ let f = async (e, t) => {
17
+ if (n === "latest") {
18
+ c && c.abort(), c = new r();
19
+ let n = a(t.signal, c.signal);
20
+ return d(e, {
21
+ ...t,
22
+ signal: n
23
+ });
24
+ }
25
+ if (n === "queue") {
26
+ u > 0 && await new Promise((e) => l.push(e)), u++;
27
+ try {
28
+ return await d(e, t);
29
+ } finally {
30
+ u--;
31
+ let e = l.shift();
32
+ e && e();
33
+ }
34
+ }
35
+ return d(e, t);
36
+ };
37
+ return f.__elurAction = {
38
+ name: t.name || "anonymous",
39
+ concurrency: n,
40
+ idempotent: i,
41
+ invalidateTags: o,
42
+ invalidatePaths: s
43
+ }, f;
44
+ }
45
+ function a(...e) {
46
+ let t = new r();
47
+ for (let n of e) if (n) {
48
+ if (n.aborted) {
49
+ t.abort();
50
+ break;
51
+ }
52
+ n.addEventListener("abort", () => t.abort(), { once: !0 });
53
+ }
54
+ return t.signal;
55
+ }
56
+ //#endregion
57
+ //#region src/action/index.ts
58
+ function o(e) {
59
+ return typeof e == "object" && !!e && e.__elur_js_action_failure === !0;
60
+ }
61
+ function s(e) {
62
+ return typeof e == "object" && !!e && e.__elur_js_action_redirect === !0;
63
+ }
64
+ async function c(n, r = [], i = {}) {
65
+ let a = Array.isArray(r) ? r : [r], c = await fetch("/__elur-js/actions", {
66
+ method: "POST",
67
+ headers: {
68
+ "Content-Type": "application/json",
69
+ Accept: "application/json"
70
+ },
71
+ body: JSON.stringify({
72
+ name: n,
73
+ page: i.page,
74
+ args: a
75
+ })
76
+ }), l = await c.text();
77
+ if (!c.ok) {
78
+ let e;
79
+ try {
80
+ e = JSON.parse(l);
81
+ } catch {}
82
+ if (o(e) && e.status !== void 0) return new t(e.status, e.data);
83
+ throw Error(`Action "${n}" failed: ${l}`);
84
+ }
85
+ let u = JSON.parse(l);
86
+ return s(u) && u.status !== void 0 && u.location !== void 0 ? new e(u.status, u.location) : u;
87
+ }
88
+ function l(e, t = {}) {
89
+ let r = n(!1), i = n(null), a = n(null);
90
+ async function o(n) {
91
+ r.value = !0, i.value = null;
92
+ try {
93
+ let r = await c(e, n, t);
94
+ return a.value = r, r;
95
+ } catch (e) {
96
+ throw i.value = e instanceof Error ? e : Error(String(e)), e;
97
+ } finally {
98
+ r.value = !1;
99
+ }
100
+ }
101
+ return {
102
+ submit: o,
103
+ pending: r,
104
+ data: a,
105
+ error: i
106
+ };
107
+ }
108
+ //#endregion
109
+ export { l as n, i as r, c as t };
110
+
111
+ //# sourceMappingURL=action-BB6N5yD-.js.map