@kuratchi/js 0.0.3 → 0.0.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.
@@ -5,5 +5,5 @@ export { Router, filePathToPattern } from './router.js';
5
5
  export { getCtx, getRequest, getLocals, getParams, getParam, redirect, goto, setBreadcrumbs, getBreadcrumbs, breadcrumbsHome, breadcrumbsPrev, breadcrumbsNext, breadcrumbsCurrent, buildDefaultBreadcrumbs, } from './context.js';
6
6
  export { kuratchiDO, doRpc } from './do.js';
7
7
  export { extractSubdomainSlug, extractSlugFromPrefix, matchContainerViewPath, rewriteProxyLocationHeader, buildContainerRequest, createContainerEnvVars, startContainer, proxyToContainer, handleContainerRouting, forwardJsonPostToContainerDO, matchSiteViewPath, buildSiteContainerRequest, createWpContainerEnvVars, startSiteContainer, proxyToSiteContainer, } from './containers.js';
8
- export type { AppConfig, Env, AuthConfig, RouteContext, RouteModule, LayoutModule, RuntimeContext, RuntimeDefinition, RuntimeStep, RuntimeNext, RuntimeErrorResult, } from './types.js';
8
+ export type { AppConfig, Env, AuthConfig, RouteContext, RouteModule, ApiRouteModule, HttpMethod, LayoutModule, RuntimeContext, RuntimeDefinition, RuntimeStep, RuntimeNext, RuntimeErrorResult, } from './types.js';
9
9
  export type { RpcOf } from './do.js';
@@ -0,0 +1,16 @@
1
+ /**
2
+ * PageError — throw from a route's load scope to return a specific HTTP status page.
3
+ *
4
+ * Without PageError, any thrown error becomes a 500. PageError lets you return
5
+ * the correct HTTP status (404, 403, 401, etc.) and an optional message.
6
+ *
7
+ * @example
8
+ * const post = await db.posts.findOne({ id: params.id });
9
+ * if (!post) throw new PageError(404);
10
+ * if (!post.isPublished) throw new PageError(403, 'This post is not published');
11
+ */
12
+ export declare class PageError extends Error {
13
+ readonly isPageError = true;
14
+ readonly status: number;
15
+ constructor(status: number, message?: string);
16
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * PageError — throw from a route's load scope to return a specific HTTP status page.
3
+ *
4
+ * Without PageError, any thrown error becomes a 500. PageError lets you return
5
+ * the correct HTTP status (404, 403, 401, etc.) and an optional message.
6
+ *
7
+ * @example
8
+ * const post = await db.posts.findOne({ id: params.id });
9
+ * if (!post) throw new PageError(404);
10
+ * if (!post.isPublished) throw new PageError(403, 'This post is not published');
11
+ */
12
+ export class PageError extends Error {
13
+ isPageError = true;
14
+ status;
15
+ constructor(status, message) {
16
+ super(message);
17
+ this.name = 'PageError';
18
+ this.status = status;
19
+ }
20
+ }
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * Core framework types
3
3
  */
4
- /** Cloudflare Worker env — consumers define their own Env type */
4
+ /** Cloudflare Worker env â€" consumers define their own Env type */
5
5
  export type Env = Record<string, any>;
6
- /** Route context — passed to load functions, actions, and server utilities */
6
+ /** Route context â€" passed to load functions, actions, and server utilities */
7
7
  export interface RouteContext<E extends Env = Env> {
8
8
  /** The incoming Request (standard Web API) */
9
9
  request: Request;
10
- /** Cloudflare Worker env — D1, KV, R2, DO, AI, etc. */
10
+ /** Cloudflare Worker env â€" D1, KV, R2, DO, AI, etc. */
11
11
  env: E;
12
12
  /** Cloudflare execution context */
13
13
  ctx: ExecutionContext;
@@ -22,36 +22,47 @@ export interface RouteContext<E extends Env = Env> {
22
22
  export interface RouteModule {
23
23
  /** Pattern string (e.g., '/todos', '/blog/:slug') */
24
24
  pattern: string;
25
- /** Load function — runs on GET, returns data for the template */
25
+ /** Load function â€" runs on GET, returns data for the template */
26
26
  load?: (ctx: RouteContext) => Promise<Record<string, any>> | Record<string, any>;
27
- /** Form actions — keyed by action name */
27
+ /** Form actions â€" keyed by action name */
28
28
  actions?: Record<string, (formData: FormData, env: Env, ctx: RouteContext) => Promise<any>>;
29
- /** RPC functions — callable from client via fetch */
29
+ /** RPC functions â€" callable from client via fetch */
30
30
  rpc?: Record<string, (args: any[], env: Env, ctx: RouteContext) => Promise<any>>;
31
- /** Render function — returns HTML string from data */
31
+ /** Render function â€" returns HTML string from data */
32
32
  render: (data: Record<string, any>) => string;
33
33
  /** Layout name (default: 'default') */
34
34
  layout?: string;
35
35
  }
36
+ /** HTTP methods supported by API routes */
37
+ export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';
38
+ /** A compiled API route module (route.ts) — returns raw Response objects */
39
+ export interface ApiRouteModule {
40
+ /** Pattern string (e.g., '/api/v1/health', '/api/v1/db/:name') */
41
+ pattern: string;
42
+ /** Marker that distinguishes API routes from page routes */
43
+ __api: true;
44
+ /** Method handlers — keyed by HTTP method */
45
+ [method: string]: ((ctx: RouteContext) => Promise<Response> | Response) | string | boolean;
46
+ }
36
47
  /** Layout module */
37
48
  export interface LayoutModule {
38
- /** Render function — wraps page content */
49
+ /** Render function â€" wraps page content */
39
50
  render: (data: {
40
51
  content: string;
41
52
  data: Record<string, any>;
42
53
  head?: string;
43
54
  }) => string;
44
55
  }
45
- /** App configuration (internal — used by compiler-generated code) */
56
+ /** App configuration (internal â€" used by compiler-generated code) */
46
57
  export interface AppConfig<E extends Env = Env> {
47
- /** Route modules — generated by compiler or defined manually */
48
- routes?: RouteModule[];
49
- /** Layout modules — keyed by name */
58
+ /** Route modules â€" generated by compiler or defined manually */
59
+ routes?: (RouteModule | ApiRouteModule)[];
60
+ /** Layout modules â€" keyed by name */
50
61
  layouts?: Record<string, LayoutModule>;
51
62
  /** Static file directory (relative to project root) */
52
63
  publicDir?: string;
53
64
  }
54
- /** Database schema config — maps a binding name to its schema */
65
+ /** Database schema config â€" maps a binding name to its schema */
55
66
  export interface DatabaseConfig {
56
67
  /** Schema definition (SchemaDsl or DatabaseSchema from @kuratchi/orm) */
57
68
  schema: any;
@@ -61,7 +72,7 @@ export interface DatabaseConfig {
61
72
  skipMigrations?: boolean;
62
73
  }
63
74
  /**
64
- * Framework configuration — the user-facing config file (kuratchi.config.ts)
75
+ * Framework configuration â€" the user-facing config file (kuratchi.config.ts)
65
76
  *
66
77
  * @example
67
78
  * ```ts
@@ -79,20 +90,21 @@ export interface DatabaseConfig {
79
90
  * ```
80
91
  */
81
92
  export interface kuratchiConfig<E extends Env = Env> {
82
- /** ORM configuration — schema definitions and auto-migration */
93
+ /** ORM configuration â€" schema definitions and auto-migration */
83
94
  orm?: {
84
95
  /** Map of D1 binding names to their database configs */
85
- databases: Record<string, DatabaseConfig>;
96
+ databases?: Record<string, DatabaseConfig>;
97
+ [key: string]: any;
86
98
  };
87
- /** UI configuration — opt into @kuratchi/ui theme and components */
99
+ /** UI configuration â€" opt into @kuratchi/ui theme and components */
88
100
  ui?: {
89
101
  /** Theme to inject: 'default' uses @kuratchi/ui's built-in theme, or a path to a custom CSS file */
90
102
  theme?: 'default' | string;
91
103
  };
92
- /** Auth configuration — @kuratchi/auth plugin setup */
93
- auth?: AuthConfig;
104
+ /** Auth configuration â€" @kuratchi/auth plugin setup */
105
+ auth?: AuthConfig | Record<string, any>;
94
106
  /**
95
- * Durable Object configuration — config-driven DO class generation.
107
+ * Durable Object configuration â€" config-driven DO class generation.
96
108
  *
97
109
  * Map a DO namespace binding to its class name and optional configuration.
98
110
  * Supports string shorthand or an object with stubId option.
@@ -100,12 +112,12 @@ export interface kuratchiConfig<E extends Env = Env> {
100
112
  * @example
101
113
  * ```ts
102
114
  * durableObjects: {
103
- * // Object form — stubId tells the framework which user field identifies the stub
115
+ * // Object form â€" stubId tells the framework which user field identifies the stub
104
116
  * ORG_DB: {
105
117
  * className: 'OrganizationDO',
106
118
  * stubId: 'user.orgId'
107
119
  * },
108
- * // String shorthand — className only, no auto-stub resolution
120
+ * // String shorthand â€" className only, no auto-stub resolution
109
121
  * CACHE_DB: 'CacheDO'
110
122
  * }
111
123
  * ```
@@ -114,6 +126,8 @@ export interface kuratchiConfig<E extends Env = Env> {
114
126
  className: string;
115
127
  /** The user field path that identifies the DO stub (e.g. 'user.orgId') */
116
128
  stubId?: string;
129
+ /** DO source files (e.g. ['auth.do.ts', 'sites.do.ts']) */
130
+ files?: string[];
117
131
  }>;
118
132
  /** Container classes exported into the generated worker entry. */
119
133
  containers?: Record<string, string | {
@@ -138,7 +152,7 @@ export interface AuthConfig {
138
152
  secretEnvKey?: string;
139
153
  /** Enable session parsing on every request (default: true) */
140
154
  sessionEnabled?: boolean;
141
- /** Credentials config — enables signUp/signIn/signOut/getCurrentUser */
155
+ /** Credentials config â€" enables signUp/signIn/signOut/getCurrentUser */
142
156
  credentials?: {
143
157
  /** D1 binding name for auth database (default: 'DB') */
144
158
  binding?: string;
@@ -154,16 +168,17 @@ export interface AuthConfig {
154
168
  signInRedirect?: string;
155
169
  /** Redirect after signout (default: '/auth/login') */
156
170
  signOutRedirect?: string;
171
+ [key: string]: any;
157
172
  };
158
- /** Activity tracking config — enables logActivity/getActivity */
173
+ /** Activity tracking config â€" enables logActivity/getActivity */
159
174
  activity?: Record<string, {
160
175
  label: string;
161
176
  severity?: 'info' | 'warning' | 'critical';
162
177
  category?: string;
163
178
  }>;
164
- /** Role definitions — enables hasRole/hasPermission/assignRole */
179
+ /** Role definitions â€" enables hasRole/hasPermission/assignRole */
165
180
  roles?: Record<string, string[]>;
166
- /** OAuth providers config — enables startOAuth/handleOAuthCallback */
181
+ /** OAuth providers config â€" enables startOAuth/handleOAuthCallback */
167
182
  oauth?: {
168
183
  providers?: Record<string, {
169
184
  clientIdEnv: string;
@@ -172,14 +187,16 @@ export interface AuthConfig {
172
187
  }>;
173
188
  /** Redirect after OAuth login (default: '/admin') */
174
189
  loginRedirect?: string;
190
+ [key: string]: any;
175
191
  };
176
- /** Route guards — protect paths, redirect if not authenticated */
192
+ /** Route guards â€" protect paths, redirect if not authenticated */
177
193
  guards?: {
178
194
  paths?: string[];
179
195
  exclude?: string[];
180
196
  redirectTo?: string;
197
+ [key: string]: any;
181
198
  };
182
- /** Rate limiting — throttle requests per route */
199
+ /** Rate limiting â€" throttle requests per route */
183
200
  rateLimit?: {
184
201
  defaultWindowMs?: number;
185
202
  defaultMaxRequests?: number;
@@ -193,12 +210,13 @@ export interface AuthConfig {
193
210
  windowMs?: number;
194
211
  message?: string;
195
212
  }[];
213
+ [key: string]: any;
196
214
  };
197
- /** Turnstile bot protection — verify Cloudflare Turnstile tokens */
215
+ /** Turnstile bot protection â€" verify Cloudflare Turnstile tokens */
198
216
  turnstile?: {
199
217
  /** Env var name for Turnstile secret key (default: 'TURNSTILE_SECRET') */
200
218
  secretEnv?: string;
201
- /** Env var name for Turnstile site key (default: 'TURNSTILE_SITE_KEY') — exposed to client */
219
+ /** Env var name for Turnstile site key (default: 'TURNSTILE_SITE_KEY') â€" exposed to client */
202
220
  siteKeyEnv?: string;
203
221
  /** Skip Turnstile verification in dev mode (default: true) */
204
222
  skipInDev?: boolean;
@@ -212,12 +230,14 @@ export interface AuthConfig {
212
230
  message?: string;
213
231
  expectedAction?: string;
214
232
  }[];
233
+ [key: string]: any;
215
234
  };
216
- /** Organization multi-tenancy — DO-backed per-org databases */
235
+ /** Organization multi-tenancy â€" DO-backed per-org databases */
217
236
  organizations?: {
218
237
  /** DO namespace binding name in env (e.g. 'ORG_DB') */
219
- binding: string;
220
- };
238
+ binding?: string;
239
+ [key: string]: any;
240
+ } | Record<string, any>;
221
241
  }
222
242
  /** Runtime pipeline context - shared across runtime step handlers */
223
243
  export interface RuntimeContext<E extends Env = Env> {
package/package.json CHANGED
@@ -1,46 +1,48 @@
1
1
  {
2
- "name": "@kuratchi/js",
3
- "version": "0.0.3",
4
- "description": "A thin, Cloudflare Workers-native web framework with Svelte-inspired syntax",
5
- "type": "module",
6
- "main": "./dist/index.js",
7
- "types": "./dist/index.d.ts",
8
- "bin": {
9
- "kuratchi": "./dist/cli.js"
10
- },
11
- "files": [
12
- "dist",
13
- "README.md"
14
- ],
15
- "scripts": {
16
- "build": "tsc -p tsconfig.build.json",
17
- "check": "tsc -p tsconfig.build.json --noEmit",
18
- "prepublishOnly": "npm run build"
19
- },
20
- "exports": {
21
- ".": {
22
- "types": "./dist/index.d.ts",
23
- "import": "./dist/index.js"
24
- },
25
- "./runtime/context.js": {
26
- "types": "./dist/runtime/context.d.ts",
27
- "import": "./dist/runtime/context.js"
28
- },
29
- "./runtime/do.js": {
30
- "types": "./dist/runtime/do.d.ts",
31
- "import": "./dist/runtime/do.js"
32
- },
33
- "./package.json": "./package.json"
34
- },
35
- "engines": {
36
- "node": "\u003e=18"
37
- },
38
- "publishConfig": {
39
- "access": "public"
40
- },
41
- "devDependencies": {
42
- "@cloudflare/workers-types": "^4.20260223.0",
43
- "@types/node": "^24.4.0",
44
- "typescript": "^5.8.0"
45
- }
46
- }
2
+ "name": "@kuratchi/js",
3
+ "version": "0.0.4",
4
+ "description": "A thin, Cloudflare Workers-native web framework with Svelte-inspired syntax",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "bin": {
9
+ "kuratchi": "./dist/cli.js"
10
+ },
11
+ "files": [
12
+ "dist",
13
+ "README.md"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc -p tsconfig.build.json",
17
+ "check": "tsc -p tsconfig.build.json --noEmit",
18
+ "test": "bun test",
19
+ "test:watch": "bun test --watch",
20
+ "prepublishOnly": "npm run build"
21
+ },
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/index.d.ts",
25
+ "import": "./dist/index.js"
26
+ },
27
+ "./runtime/context.js": {
28
+ "types": "./dist/runtime/context.d.ts",
29
+ "import": "./dist/runtime/context.js"
30
+ },
31
+ "./runtime/do.js": {
32
+ "types": "./dist/runtime/do.d.ts",
33
+ "import": "./dist/runtime/do.js"
34
+ },
35
+ "./package.json": "./package.json"
36
+ },
37
+ "engines": {
38
+ "node": "\u003e=18"
39
+ },
40
+ "publishConfig": {
41
+ "access": "public"
42
+ },
43
+ "devDependencies": {
44
+ "@cloudflare/workers-types": "^4.20260223.0",
45
+ "@types/node": "^24.4.0",
46
+ "typescript": "^5.8.0"
47
+ }
48
+ }