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 +155 -13
- package/index.d.ts +2 -0
- package/index.d.ts.map +1 -1
- package/index.js +7 -1
- package/package.json +70 -64
- package/server.d.ts.map +1 -1
- package/server.js +10 -1
- package/utils/cors.d.ts +1 -1
- package/utils/cors.d.ts.map +1 -1
- package/utils/cors.js +3 -3
- package/utils/csrf.d.ts +1 -1
- package/utils/csrf.d.ts.map +1 -1
- package/utils/csrf.js +2 -2
- package/utils/logger.d.ts +2 -0
- package/utils/logger.d.ts.map +1 -0
- package/utils/logger.js +2 -0
- package/utils/meta.d.ts +15 -0
- package/utils/meta.d.ts.map +1 -0
- package/utils/meta.js +1 -0
- package/utils/pino.d.ts +3 -0
- package/utils/pino.d.ts.map +1 -0
- package/utils/pino.js +20 -0
- package/utils/router.d.ts.map +1 -1
- package/utils/router.js +12 -13
- package/utils/types.d.ts +0 -8
- package/utils/types.d.ts.map +0 -1
- package/utils/types.js +0 -1
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
|
|
243
|
+
import { meta } from 'solidstep/utils/types';
|
|
241
244
|
|
|
242
|
-
|
|
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
|
-
}
|
|
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 {
|
|
305
|
-
|
|
306
|
-
export default eventHandler((event) => {
|
|
307
|
-
event.locals = { user: getCurrentUser() };
|
|
308
|
+
import { defineMiddleware } from 'vinxi/http';
|
|
308
309
|
|
|
309
|
-
|
|
310
|
-
|
|
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;
|
|
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.
|
|
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
|
-
"./
|
|
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/
|
|
25
|
-
"./utils/
|
|
26
|
-
"./utils/
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"test:local
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
"
|
|
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":"
|
|
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
|
|
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;
|
package/utils/cors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../utils/cors.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,IAAI,
|
|
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': '
|
|
7
|
-
'Access-Control-Allow-Headers': '
|
|
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
|
};
|
package/utils/csrf.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"csrf.d.ts","sourceRoot":"","sources":["../../utils/csrf.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,IAAI,
|
|
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 (!
|
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../utils/logger.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,MAAM,uCAAc,CAAC"}
|
package/utils/logger.js
ADDED
package/utils/meta.d.ts
ADDED
|
@@ -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;
|
package/utils/pino.d.ts
ADDED
|
@@ -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
|
+
};
|
package/utils/router.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../utils/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAa,MAAM,iBAAiB,CAAC;
|
|
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
package/utils/types.d.ts.map
DELETED
|
@@ -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 {};
|