solidstep 0.1.1 → 0.1.3

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.
package/README.md CHANGED
@@ -4,6 +4,7 @@ Next Solid Step towards a more performant web - A full-stack SolidJS framework f
4
4
 
5
5
  ## Features
6
6
 
7
+ - 🌟 **Built on SolidJS and Vite** - Leverage the power of SolidJS for reactive and efficient UIs
7
8
  - 🚀 **File-based Routing** - Automatic routing based on your file structure
8
9
  - ⚡ **Server-Side Rendering (SSR)** - Fast initial page loads with full SSR support
9
10
  - 🔄 **Data Loading** - Built-in loaders for efficient data fetching
@@ -12,8 +13,9 @@ Next Solid Step towards a more performant web - A full-stack SolidJS framework f
12
13
  - 🎯 **Server Actions** - Type-safe server functions with automatic serialization
13
14
  - ⚙️ **Middleware Support** - Request/response interceptors
14
15
  - 📦 **Caching** - Built-in page-level caching
15
- - 🔥 **Hot Module Replacement** - Fast development experience
16
16
  - 📝 **TypeScript** - Full TypeScript support out of the box
17
+ - 📊 **Built-in Logging** - Configurable Pino logger for logging
18
+ - 🌐 **Fetch Utilities** - Type-safe fetch wrappers with timeout and error handling for both client and server
17
19
 
18
20
  ## Getting Started
19
21
 
@@ -38,6 +40,8 @@ cd my-app
38
40
 
39
41
  **A route is defined by either the presence of a `page.tsx` or `route.ts` file in a directory.**
40
42
 
43
+ **Similar to NextJS, routes are not indexed if they have a '_' placed at the beginning of the name**
44
+
41
45
  ### Configuration
42
46
 
43
47
  Configure your app in `app.config.ts`:
@@ -47,7 +51,6 @@ import { defineConfig } from 'solidstep';
47
51
 
48
52
  export default defineConfig({
49
53
  server: {
50
- port: 3000,
51
54
  preset: 'node',
52
55
  },
53
56
  plugins: [
@@ -237,9 +240,10 @@ function CreatePostForm() {
237
240
  Define metadata for SEO:
238
241
 
239
242
  ```tsx
240
- import type { Meta } from 'solidstep/utils/types';
243
+ import { meta } from 'solidstep/utils/types';
241
244
 
242
- export const generateMeta = async () => {
245
+ // can also be async
246
+ export const generateMeta = meta(() => {
243
247
  return {
244
248
  title: {
245
249
  type: 'title',
@@ -292,8 +296,8 @@ export const generateMeta = async () => {
292
296
  defer: true,
293
297
  }
294
298
  }
295
- } satisfies Meta;
296
- };
299
+ };
300
+ });
297
301
  ```
298
302
 
299
303
  ### Middleware
@@ -301,13 +305,14 @@ export const generateMeta = async () => {
301
305
  Intercept and modify requests:
302
306
 
303
307
  ```tsx
304
- import { eventHandler } from 'vinxi/http';
305
-
306
- export default eventHandler((event) => {
307
- event.locals = { user: getCurrentUser() };
308
+ import { defineMiddleware } from 'vinxi/http';
308
309
 
309
- // you can also modify request/response here
310
- // also include cors, csrf, csp logic if needed
310
+ export default defineMiddleware({
311
+ onRequest: async (request) => {
312
+ console.log('Incoming request:', request.url);
313
+ // Modify request if needed
314
+ return request;
315
+ },
311
316
  });
312
317
  ```
313
318
 
@@ -326,6 +331,11 @@ export const options = {
326
331
  ## API Routes
327
332
 
328
333
  Create REST endpoints:
334
+ - GET
335
+ - POST
336
+ - PUT
337
+ - DELETE
338
+ - PATCH
329
339
 
330
340
  ```tsx
331
341
  export async function GET(request: Request, { params }: any) {
@@ -515,12 +525,144 @@ export const loader = defineLoader(async () => {
515
525
  });
516
526
  ```
517
527
 
528
+ ### Logging
529
+
530
+ SolidStep includes a built-in Pino logger that can be configured globally:
531
+
532
+ ```tsx
533
+ import { defineConfig } from 'solidstep';
534
+
535
+ export default defineConfig({
536
+ server: {
537
+ preset: 'node',
538
+ },
539
+ logger: {
540
+ level: 'info',
541
+ transport: {
542
+ target: 'pino-pretty',
543
+ options: {
544
+ colorize: true
545
+ }
546
+ }
547
+ }
548
+ });
549
+ ```
550
+
551
+ Use the logger in your code:
552
+
553
+ ```tsx
554
+ import { logger } from 'solidstep/utils/logger';
555
+
556
+ export const loader = defineLoader(async () => {
557
+ logger.info('Fetching posts');
558
+
559
+ try {
560
+ const posts = await fetchPosts();
561
+ logger.info(`Fetched ${posts.length} posts`);
562
+ return { posts };
563
+ } catch (error) {
564
+ logger.error('Failed to fetch posts', error);
565
+ throw error;
566
+ }
567
+ });
568
+ ```
569
+
570
+ **Logger Configuration Options:**
571
+ - `false` or `undefined` - Disables logging (silent mode)
572
+ - `true` - Enables default Pino logger
573
+ - `object` - Custom Pino configuration object [Pino Docs](https://getpino.io/#/docs/api?id=options)
574
+
575
+ ### Fetch Utilities
576
+
577
+ SolidStep provides type-safe fetch wrappers for both client and server with built-in timeout and error handling:
578
+
579
+ **Client-side Fetch:**
580
+ ```tsx
581
+ import fetch from 'solidstep/utils/fetch.client';
582
+
583
+ async function fetchPosts() {
584
+ const posts = await fetch<Post[]>('/api/posts', {
585
+ method: 'GET',
586
+ MAX_FETCH_TIME: 5000,
587
+ });
588
+
589
+ return posts;
590
+ }
591
+
592
+ ...
593
+
594
+ // To get full response including status, headers, etc.
595
+ const response = await fetch<Post[], false>(
596
+ '/api/posts',
597
+ { method: 'GET' },
598
+ false
599
+ );
600
+
601
+ console.log(response.status); // HTTP status code
602
+ ```
603
+
604
+ **Server-side Fetch:**
605
+ ```tsx
606
+ import fetch from 'solidstep/utils/fetch.server';
607
+
608
+ export const loader = defineLoader(async () => {
609
+ const data = await fetch<ApiResponse>('https://api.example.com/data', {
610
+ method: 'POST',
611
+ body: JSON.stringify({ query: 'test' }),
612
+ headers: {
613
+ 'Content-Type': 'application/json',
614
+ },
615
+ MAX_FETCH_TIME: 10000,
616
+ });
617
+
618
+ return data;
619
+ });
620
+ ```
621
+
622
+ **Features:**
623
+ - Automatic timeout handling with AbortController (default: 4000ms)
624
+ - Automatic JSON parsing (optional)
625
+ - Error handling for HTTP 4xx/5xx responses
626
+ - Type-safe responses with TypeScript generics
627
+ - Server-side uses undici for better performance
628
+
629
+ ### Server-Only Code
630
+
631
+ Ensure code only runs on the server and throws an error if accessed on the client:
632
+
633
+ ```tsx
634
+ import 'solidstep/utils/server-only';
635
+
636
+ export const SECRET_KEY = process.env.SECRET_KEY;
637
+ export const DATABASE_URL = process.env.DATABASE_URL;
638
+
639
+ export async function queryDatabase(query: string) {
640
+ }
641
+ ```
642
+
643
+ **Use case:** Import this at the top of any file that should never be used for the client (e.g., database utilities, API keys, server secrets).
644
+
645
+ ```tsx
646
+ import 'solidstep/utils/server-only';
647
+
648
+ export const db = createDatabaseConnection(process.env.DATABASE_URL);
649
+ ```
650
+
651
+ If accidentally imported on the client, it will throw:
652
+ ```
653
+ Error: This module is only available on the server side.
654
+ ```
655
+
518
656
  ## Future Plans
657
+ - Revalidate on demand
658
+ - Preloading/prefetching strategies
519
659
  - Support for dynamic site.webmanifest, robots.txt, sitemap.xml, manifest.json, and llms.txt
520
660
  - Support loading and error pages for parallel routes
521
661
  - Support deferring loaders
522
662
  - Image/font optimizations
523
663
  - Possible CSR/SPA, SSG, ISR, and PPR
664
+ - Advanced caching strategies
665
+ - WebSocket support
524
666
 
525
667
  ## License
526
668
 
@@ -533,4 +675,4 @@ MIT
533
675
 
534
676
  ## Special Mentions
535
677
  - Inspired by [Remix](https://remix.run/), [Next.js](https://nextjs.org/), and [TanStack](https://tanstack.com/)
536
- - Built with [Vite](https://vitejs.dev/), [SolidJS](https://www.solidjs.com/), [Vinxi](https://github.com/nksaraf/vinxi) and [Seroval](https://github.com/lxsmnsyc/seroval)
678
+ - Built with [Vite](https://vitejs.dev/), [SolidJS](https://www.solidjs.com/), [Vinxi](https://github.com/nksaraf/vinxi), [Undici](https://undici.nodejs.org/#/), [Pino](https://getpino.io/#/) and [Seroval](https://github.com/lxsmnsyc/seroval)
package/index.d.ts CHANGED
@@ -1,10 +1,12 @@
1
1
  import type { AppOptions } from 'vinxi';
2
+ import type { LoggerOptions } from 'pino';
2
3
  type Config = {
3
4
  server?: Omit<AppOptions['server'], 'experimental'>;
4
5
  plugins?: {
5
6
  type: 'client' | 'server' | 'both';
6
7
  plugin: any;
7
8
  }[];
9
+ logger?: true | LoggerOptions;
8
10
  };
9
11
  export declare const defineConfig: (config?: Config) => import("vinxi").App;
10
12
  export {};
package/index.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAWxC,KAAK,MAAM,GAAG;IACV,MAAM,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC,CAAC;IACpD,OAAO,CAAC,EAAE;QACN,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;QACnC,MAAM,EAAE,GAAG,CAAC;KACf,EAAE,CAAC;CACP,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,SAAQ,MAGpC,wBAoGA,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAUxC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAE1C,KAAK,MAAM,GAAG;IACV,MAAM,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC,CAAC;IACpD,OAAO,CAAC,EAAE;QACN,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;QACnC,MAAM,EAAE,GAAG,CAAC;KACf,EAAE,CAAC;IACJ,MAAM,CAAC,EAAE,IAAI,GAAG,aAAa,CAAC;CACjC,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,SAAQ,MAGpC,wBA4GA,CAAC"}
package/index.js CHANGED
@@ -5,7 +5,7 @@ import { serverFunctions } from '@vinxi/server-functions/plugin';
5
5
  import { ServerRouter, ClientRouter } from './utils/router.js';
6
6
  import { join } from 'node:path';
7
7
  import { fileURLToPath } from 'node:url';
8
- import { cpSync, mkdirSync, existsSync } from 'node:fs';
8
+ import { cpSync, mkdirSync, existsSync, writeFileSync } from 'node:fs';
9
9
  import { normalize } from 'vinxi/lib/path';
10
10
  export const defineConfig = (config = {
11
11
  server: {},
@@ -15,6 +15,11 @@ export const defineConfig = (config = {
15
15
  if (!existsSync(middlewarePath)) {
16
16
  middlewarePath = join(process.cwd(), 'app', 'middleware.js');
17
17
  }
18
+ const sharedConfig = {
19
+ logger: config.logger || false,
20
+ };
21
+ // @ts-ignore
22
+ globalThis.__SOLIDSTEP_CONFIG__ = sharedConfig;
18
23
  const app = createApp({
19
24
  server: {
20
25
  ...config.server,
@@ -78,6 +83,7 @@ export const defineConfig = (config = {
78
83
  if (event.name === 'app:build:nitro:end') {
79
84
  const [{ nitro }] = event.args;
80
85
  const serverDir = nitro.options.output.serverDir;
86
+ writeFileSync(`${serverDir}/.config.json`, JSON.stringify(sharedConfig), 'utf-8');
81
87
  const fromDir = join(process.cwd(), 'server-assets');
82
88
  if (existsSync(fromDir)) {
83
89
  const toDir = join(serverDir, 'server-assets');
package/package.json CHANGED
@@ -1,64 +1,70 @@
1
- {
2
- "name": "solidstep",
3
- "version": "0.1.1",
4
- "description": "Next Step SolidJS Framework for building web applications.",
5
- "type": "module",
6
- "author": "HamzaKV <hamzakv333@gmail.com>",
7
- "repository": {
8
- "type": "git",
9
- "url": "https://github.com/HamzaKV/solidstep.git"
10
- },
11
- "license": "MIT",
12
- "exports": {
13
- ".": "./index.js",
14
- "./utils/hooks/action-state": "./utils/hooks/action-state.js",
15
- "./utils/cache": "./utils/cache.js",
16
- "./utils/cookies": "./utils/cookies.js",
17
- "./utils/cors": "./utils/cors.js",
18
- "./utils/csp": "./utils/csp.js",
19
- "./utils/csrf": "./utils/csrf.js",
20
- "./utils/error-handler": "./utils/error-handler.js",
21
- "./utils/fetch.client": "./utils/fetch.client.js",
22
- "./utils/fetch.server": "./utils/fetch.server.js",
23
- "./utils/loader": "./utils/loader.js",
24
- "./utils/redirect": "./utils/redirect.js",
25
- "./utils/server-only": "./utils/server-only.js",
26
- "./utils/types": "./utils/types.js"
27
- },
28
- "scripts": {
29
- "clean": "rimraf ./dist",
30
- "copy-files:root": "copyfiles -u 0 README.md package.json generate/**/* LICENSE ./dist",
31
- "build": "pnpm clean && tsc && pnpm copy-files:root",
32
- "test:local": "pnpm build && cd ./dist && pnpm link --global",
33
- "test:local:clean": "pnpm unlink && pnpm clean",
34
- "roll": "pnpm build && cd dist && npm publish"
35
- },
36
- "keywords": [
37
- "solidjs",
38
- "web-development",
39
- "typescript",
40
- "npm",
41
- "solidstep",
42
- "framework"
43
- ],
44
- "dependencies": {
45
- "@vinxi/server-functions": "0.5.1",
46
- "seroval": "^1.3.2",
47
- "seroval-plugins": "^1.3.2",
48
- "solid-js": "^1.9.7",
49
- "undici": "^7.15.0",
50
- "vinxi": "^0.5.8"
51
- },
52
- "devDependencies": {
53
- "copyfiles": "^2.4.1",
54
- "rimraf": "^6.0.1",
55
- "typescript": "^5.8.3",
56
- "vite-plugin-solid": "^2.11.7"
57
- },
58
- "engines": {
59
- "node": ">=20"
60
- },
61
- "publishConfig": {
62
- "access": "public"
63
- }
64
- }
1
+ {
2
+ "name": "solidstep",
3
+ "version": "0.1.3",
4
+ "description": "Next Step SolidJS Framework for building web applications.",
5
+ "type": "module",
6
+ "author": "HamzaKV <hamzakv333@gmail.com>",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/HamzaKV/solidstep.git"
10
+ },
11
+ "license": "MIT",
12
+ "exports": {
13
+ ".": "./index.js",
14
+ "./hooks/action-state": "./utils/hooks/action-state.js",
15
+ "./utils/cache": "./utils/cache.js",
16
+ "./utils/cookies": "./utils/cookies.js",
17
+ "./utils/cors": "./utils/cors.js",
18
+ "./utils/csp": "./utils/csp.js",
19
+ "./utils/csrf": "./utils/csrf.js",
20
+ "./utils/error-handler": "./utils/error-handler.js",
21
+ "./utils/fetch.client": "./utils/fetch.client.js",
22
+ "./utils/fetch.server": "./utils/fetch.server.js",
23
+ "./utils/loader": "./utils/loader.js",
24
+ "./utils/logger": "./utils/logger.js",
25
+ "./utils/meta": "./utils/meta.js",
26
+ "./utils/redirect": "./utils/redirect.js",
27
+ "./utils/server-only": "./utils/server-only.js"
28
+ },
29
+ "scripts": {
30
+ "clean": "rimraf ./dist",
31
+ "copy-files:root": "copyfiles -u 0 README.md package.json generate/**/* LICENSE ./dist",
32
+ "build": "pnpm clean && tsc && pnpm copy-files:root",
33
+ "test:local": "pnpm build && cd ./dist && pnpm link --global",
34
+ "test:local:clean": "pnpm unlink && pnpm clean",
35
+ "roll": "pnpm build && cd dist && npm publish"
36
+ },
37
+ "keywords": [
38
+ "solidjs",
39
+ "web-development",
40
+ "typescript",
41
+ "npm",
42
+ "solidstep",
43
+ "framework"
44
+ ],
45
+ "dependencies": {
46
+ "@vinxi/server-functions": "0.5.1",
47
+ "pino": "^10.1.0",
48
+ "seroval": "^1.3.2",
49
+ "seroval-plugins": "^1.3.2",
50
+ "undici": "^7.15.0",
51
+ "vite-plugin-solid": "^2.11.7"
52
+ },
53
+ "devDependencies": {
54
+ "copyfiles": "^2.4.1",
55
+ "rimraf": "^6.0.1",
56
+ "solid-js": "^1.9.7",
57
+ "typescript": "^5.8.3",
58
+ "vinxi": "^0.5.8"
59
+ },
60
+ "peerDependencies": {
61
+ "solid-js": "^1.9.7",
62
+ "vinxi": "^0.5.8"
63
+ },
64
+ "engines": {
65
+ "node": ">=20"
66
+ },
67
+ "publishConfig": {
68
+ "access": "public"
69
+ }
70
+ }
package/server.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../server.ts"],"names":[],"mappings":"AAggBA,QAAA,MAAM,OAAO,+FA+TX,CAAC;AAEH,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../server.ts"],"names":[],"mappings":"AAygBA,QAAA,MAAM,OAAO,+FA+TX,CAAC;AAEH,eAAe,OAAO,CAAC"}
package/server.js CHANGED
@@ -5,7 +5,9 @@ import fileRoutes, {} from 'vinxi/routes';
5
5
  import { RedirectError } from './utils/redirect';
6
6
  import { setCache, getCache } from './utils/cache';
7
7
  import { handleServerFunction } from './utils/server-action.server';
8
- import util from 'node:util';
8
+ import { readFile } from 'node:fs/promises';
9
+ import { dirname } from 'node:path';
10
+ import { fileURLToPath } from 'node:url';
9
11
  const isPageFile = (file) => file.endsWith('page.tsx')
10
12
  || file.endsWith('page.jsx')
11
13
  || file.endsWith('page.ts')
@@ -366,6 +368,13 @@ const hydrationScript = ({ nonce, }) => {
366
368
  const onStart = async () => {
367
369
  try {
368
370
  routeManifest = await createRouteManifest();
371
+ const sharedConfig = globalThis.__SOLIDSTEP_CONFIG__;
372
+ if (!sharedConfig) {
373
+ const __dirname = dirname(fileURLToPath(import.meta.url));
374
+ const configContent = await readFile(`${__dirname}/.config.json`, 'utf-8');
375
+ // @ts-ignore
376
+ globalThis.__SOLIDSTEP_CONFIG__ = JSON.parse(configContent);
377
+ }
369
378
  }
370
379
  catch (e) {
371
380
  console.error('Error creating route manifest:', e);
package/utils/cors.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export declare const cors: (trustedOrigins: string[]) => (origin: string, isPreflight: boolean) => {
1
+ export declare const cors: (trustedOrigins: string[], allowMethods?: string[], allowHeaders?: string[]) => (origin: string, isPreflight: boolean) => {
2
2
  'Access-Control-Allow-Origin': string;
3
3
  'Access-Control-Allow-Methods': string;
4
4
  'Access-Control-Allow-Headers': string;
@@ -1 +1 @@
1
- {"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../utils/cors.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,IAAI,GAAI,gBAAgB,MAAM,EAAE,MAAM,QAAQ,MAAM,EAAE,aAAa,OAAO;;;;;;;;;;;;CActF,CAAA"}
1
+ {"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../utils/cors.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,IAAI,GACb,gBAAgB,MAAM,EAAE,EACxB,eAAc,MAAM,EAAyD,EAC7E,eAAc,MAAM,EAAsC,MACxD,QAAQ,MAAM,EAAE,aAAa,OAAO;;;;;;;;;;;;CAczC,CAAA"}
package/utils/cors.js CHANGED
@@ -1,10 +1,10 @@
1
- export const cors = (trustedOrigins) => (origin, isPreflight) => {
1
+ export const cors = (trustedOrigins, allowMethods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'], allowHeaders = ['Content-Type', 'Authorization']) => (origin, isPreflight) => {
2
2
  if (trustedOrigins.includes(origin)) {
3
3
  if (isPreflight) {
4
4
  return {
5
5
  'Access-Control-Allow-Origin': origin,
6
- 'Access-Control-Allow-Methods': 'GET, POST, PUT, PATCH, DELETE, OPTIONS',
7
- 'Access-Control-Allow-Headers': 'Content-Type, Authorization',
6
+ 'Access-Control-Allow-Methods': allowMethods.join(', '),
7
+ 'Access-Control-Allow-Headers': allowHeaders.join(', '),
8
8
  };
9
9
  }
10
10
  return {
package/utils/csrf.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export declare const csrf: (trustedOrigins: string[]) => (requestMethod: string, requestUrl: URL, origin?: string, referer?: string) => {
1
+ export declare const csrf: (trustedOrigins: string[], safeMethods?: string[]) => (requestMethod: string, requestUrl: URL, origin?: string, referer?: string) => {
2
2
  success: boolean;
3
3
  message: string;
4
4
  };
@@ -1 +1 @@
1
- {"version":3,"file":"csrf.d.ts","sourceRoot":"","sources":["../../utils/csrf.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,IAAI,GAAI,gBAAgB,MAAM,EAAE,MAErC,eAAe,MAAM,EACrB,YAAY,GAAG,EACf,SAAS,MAAM,EACf,UAAU,MAAM;;;CAsDnB,CAAC"}
1
+ {"version":3,"file":"csrf.d.ts","sourceRoot":"","sources":["../../utils/csrf.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,IAAI,GACb,gBAAgB,MAAM,EAAE,EACxB,cAAa,MAAM,EAAiB,MAGhC,eAAe,MAAM,EACrB,YAAY,GAAG,EACf,SAAS,MAAM,EACf,UAAU,MAAM;;;CAsDnB,CAAC"}
package/utils/csrf.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const SAFE_METHODS = ['GET', 'OPTIONS', 'HEAD', 'TRACE'];
2
- export const csrf = (trustedOrigins) => (requestMethod, requestUrl, origin, referer) => {
2
+ export const csrf = (trustedOrigins, safeMethods = SAFE_METHODS) => (requestMethod, requestUrl, origin, referer) => {
3
3
  // Check if the request method is safe
4
- if (!SAFE_METHODS.includes(requestMethod)) {
4
+ if (!safeMethods.includes(requestMethod)) {
5
5
  // If we have an Origin header, check it against our allowlist.
6
6
  if (origin) {
7
7
  const parsedOrigin = new URL(origin);
@@ -0,0 +1,2 @@
1
+ export declare const logger: import("pino").Logger<never, boolean>;
2
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../utils/logger.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,MAAM,uCAAc,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { getLogger } from './pino';
2
+ export const logger = getLogger();
@@ -0,0 +1,15 @@
1
+ export type Meta = {
2
+ [key: string]: {
3
+ type: 'link' | 'meta' | 'script' | 'style' | 'title';
4
+ attributes: Record<string, string>;
5
+ content?: string;
6
+ };
7
+ };
8
+ type MetaFunctionParameters = {
9
+ req: Request;
10
+ cspNonce?: string;
11
+ };
12
+ export type MetaFunction = (params: MetaFunctionParameters) => Promise<Meta> | Meta;
13
+ export declare const meta: (metaFunction: MetaFunction) => MetaFunction;
14
+ export {};
15
+ //# sourceMappingURL=meta.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../utils/meta.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,IAAI,GAAG;IACf,CAAC,GAAG,EAAE,MAAM,GAAG;QACX,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;QACrD,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,OAAO,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;CACL,CAAC;AAEF,KAAK,sBAAsB,GAAG;IAC1B,GAAG,EAAE,OAAO,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AACF,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,sBAAsB,KACtD,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAEzB,eAAO,MAAM,IAAI,GAAI,cAAc,YAAY,iBAAiB,CAAC"}
package/utils/meta.js ADDED
@@ -0,0 +1 @@
1
+ export const meta = (metaFunction) => metaFunction;
@@ -0,0 +1,3 @@
1
+ import pino from 'pino';
2
+ export declare const getLogger: () => pino.Logger;
3
+ //# sourceMappingURL=pino.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pino.d.ts","sourceRoot":"","sources":["../../utils/pino.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAIxB,eAAO,MAAM,SAAS,QAAO,IAAI,CAAC,MAgBjC,CAAC"}
package/utils/pino.js ADDED
@@ -0,0 +1,20 @@
1
+ import pino from 'pino';
2
+ let logger = null;
3
+ export const getLogger = () => {
4
+ if (logger) {
5
+ return logger;
6
+ }
7
+ // @ts-ignore
8
+ const sharedConfig = globalThis.__SOLIDSTEP_CONFIG__;
9
+ const loggerConfig = sharedConfig?.logger;
10
+ if (loggerConfig === false || loggerConfig === undefined) {
11
+ logger = pino({ level: 'silent' });
12
+ }
13
+ else if (loggerConfig === true) {
14
+ logger = pino();
15
+ }
16
+ else {
17
+ logger = pino(loggerConfig);
18
+ }
19
+ return logger;
20
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../utils/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAa,MAAM,iBAAiB,CAAC;AAMlE,qBAAa,YAAa,SAAQ,oBAAoB;IAClD,MAAM,CAAC,GAAG,EAAE,MAAM;IAclB,OAAO,CAAC,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsK3B;AAED,qBAAa,YAAa,SAAQ,oBAAoB;IAClD,MAAM,CAAC,GAAG,EAAE,MAAM;IAgBlB,OAAO,CAAC,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;;;CA2E3B"}
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../utils/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAa,MAAM,iBAAiB,CAAC;AAElE,qBAAa,YAAa,SAAQ,oBAAoB;IAClD,MAAM,CAAC,GAAG,EAAE,MAAM;IAQlB,OAAO,CAAC,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4K3B;AAED,qBAAa,YAAa,SAAQ,oBAAoB;IAClD,MAAM,CAAC,GAAG,EAAE,MAAM;IAQlB,OAAO,CAAC,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;;;CAiF3B"}
package/utils/router.js CHANGED
@@ -1,20 +1,18 @@
1
1
  import { BaseFileSystemRouter, cleanPath } from 'vinxi/fs-router';
2
- import { dirname } from 'node:path';
3
- import { fileURLToPath } from 'node:url';
4
- const __dirname = dirname(fileURLToPath(import.meta.url));
5
2
  export class ServerRouter extends BaseFileSystemRouter {
6
3
  toPath(src) {
7
4
  const routePath = cleanPath(src, this.config)
8
5
  .replace(new RegExp(`\.(${(this.config.extensions ?? []).join('|')})$`), '')
9
6
  .replace(/\/(page|route|layout|error|not-found|loading)$/, '');
10
- // src = src
11
- // .slice((`${__dirname}/app`).length);
12
- // const routePath = src
13
- // .replace(new RegExp(`\.(${(this.config.extensions ?? []).join('|')})$`), '')
14
- // .replace(/\/(page|route|layout|error|not-found|loading)$/, '');
15
7
  return routePath?.length > 0 ? routePath : '/';
16
8
  }
17
9
  toRoute(filePath) {
10
+ const normalizePath = cleanPath(filePath, this.config);
11
+ const splitPath = normalizePath.split('/');
12
+ const shouldIgnore = splitPath.some(part => part.startsWith('_'));
13
+ if (shouldIgnore) {
14
+ return;
15
+ }
18
16
  const path = this.toPath(filePath);
19
17
  if ((/\/route\.(js|ts)$/).test(filePath)) {
20
18
  return {
@@ -179,14 +177,15 @@ export class ClientRouter extends BaseFileSystemRouter {
179
177
  const routePath = cleanPath(src, this.config)
180
178
  .replace(new RegExp(`\.(${(this.config.extensions ?? []).join('|')})$`), '')
181
179
  .replace(/\/(page|route|layout|error|not-found|loading)$/, '');
182
- // src = src
183
- // .slice((`${__dirname}/app`).length);
184
- // const routePath = src
185
- // .replace(new RegExp(`\.(${(this.config.extensions ?? []).join('|')})$`), '')
186
- // .replace(/\/(page|layout|error|not-found|loading)$/, '');
187
180
  return routePath?.length > 0 ? routePath : '/';
188
181
  }
189
182
  toRoute(filePath) {
183
+ const normalizePath = cleanPath(filePath, this.config);
184
+ const splitPath = normalizePath.split('/');
185
+ const shouldIgnore = splitPath.some(part => part.startsWith('_'));
186
+ if (shouldIgnore) {
187
+ return;
188
+ }
190
189
  const path = this.toPath(filePath);
191
190
  // biome-ignore lint/correctness/noEmptyCharacterClassInRegex: <explanation>
192
191
  const scopedPackageMatch = path.match(/@[^]+/g);
package/utils/types.d.ts DELETED
@@ -1,8 +0,0 @@
1
- export type Meta = {
2
- [key: string]: {
3
- type: 'link' | 'meta' | 'script' | 'style' | 'title';
4
- attributes: Record<string, string>;
5
- content?: string;
6
- };
7
- };
8
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../utils/types.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,IAAI,GAAG;IACf,CAAC,GAAG,EAAE,MAAM,GAAG;QACX,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;QACrD,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,OAAO,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;CACL,CAAC"}
package/utils/types.js DELETED
@@ -1 +0,0 @@
1
- export {};