@ereo/router-conventions 0.1.6
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 +103 -0
- package/dist/conventions.d.ts +66 -0
- package/dist/conventions.d.ts.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +128 -0
- package/dist/integration.d.ts +40 -0
- package/dist/integration.d.ts.map +1 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# @ereo/router-conventions
|
|
2
|
+
|
|
3
|
+
File-based routing conventions for the EreoJS framework. Automatically configure routes based on filename patterns, enabling intuitive and powerful file-based routing.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @ereo/router-conventions
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { parseConvention, applyConventionConfig } from '@ereo/router-conventions';
|
|
15
|
+
|
|
16
|
+
// Parse a filename to extract convention info
|
|
17
|
+
const info = parseConvention('blog/[slug].ssg.tsx');
|
|
18
|
+
// => { basePath: 'blog/[slug]', renderMode: 'ssg', isApi: false, ... }
|
|
19
|
+
|
|
20
|
+
// Apply convention-based configuration to a route
|
|
21
|
+
const config = applyConventionConfig('blog/[slug].ssg.tsx');
|
|
22
|
+
// => { render: { mode: 'ssg', prerender: { enabled: true } }, ... }
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Convention Patterns
|
|
26
|
+
|
|
27
|
+
Use filename suffixes to configure route behavior:
|
|
28
|
+
|
|
29
|
+
| Pattern | Description |
|
|
30
|
+
|---------|-------------|
|
|
31
|
+
| `*.ssg.tsx` | Static Site Generation (pre-rendered at build time) |
|
|
32
|
+
| `*.server.tsx` | Server-side only (no client JavaScript) |
|
|
33
|
+
| `*.client.tsx` | Client-side rendering only |
|
|
34
|
+
| `*.api.tsx` | API endpoint (JSON response) |
|
|
35
|
+
| `*.rsc.tsx` | React Server Component |
|
|
36
|
+
| `_islands/*.tsx` | Auto-extracted island components |
|
|
37
|
+
| `_layout.tsx` | Nested layout wrapper |
|
|
38
|
+
|
|
39
|
+
## Examples
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
app/routes/
|
|
43
|
+
index.tsx # SSR (default)
|
|
44
|
+
about.server.tsx # Server-only, no hydration
|
|
45
|
+
blog/
|
|
46
|
+
index.tsx # SSR blog list
|
|
47
|
+
[slug].ssg.tsx # Static blog posts
|
|
48
|
+
api/
|
|
49
|
+
posts.api.tsx # JSON API endpoint
|
|
50
|
+
_islands/
|
|
51
|
+
Counter.tsx # Auto-hydrated island
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## API
|
|
55
|
+
|
|
56
|
+
### `parseConvention(filename)`
|
|
57
|
+
|
|
58
|
+
Parse a filename to extract convention information.
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
const info = parseConvention('posts/[id].ssg.tsx');
|
|
62
|
+
// {
|
|
63
|
+
// basePath: 'posts/[id]',
|
|
64
|
+
// renderMode: 'ssg',
|
|
65
|
+
// isApi: false,
|
|
66
|
+
// isIsland: false,
|
|
67
|
+
// isLayout: false,
|
|
68
|
+
// filename: 'posts/[id].ssg.tsx',
|
|
69
|
+
// extension: '.tsx'
|
|
70
|
+
// }
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### `applyConventionConfig(routePath, explicitConfig?)`
|
|
74
|
+
|
|
75
|
+
Apply convention-based configuration, merging with explicit config.
|
|
76
|
+
|
|
77
|
+
### `hasConvention(filename)`
|
|
78
|
+
|
|
79
|
+
Check if a filename uses any convention pattern.
|
|
80
|
+
|
|
81
|
+
### `stripConvention(routePath)`
|
|
82
|
+
|
|
83
|
+
Remove convention suffix from a route path for URL generation.
|
|
84
|
+
|
|
85
|
+
## Key Features
|
|
86
|
+
|
|
87
|
+
- Automatic render mode detection from filenames
|
|
88
|
+
- Support for SSG, SSR, CSR, API, and RSC modes
|
|
89
|
+
- Island component detection
|
|
90
|
+
- Layout file recognition
|
|
91
|
+
- Seamless integration with EreoJS router
|
|
92
|
+
|
|
93
|
+
## Documentation
|
|
94
|
+
|
|
95
|
+
For full documentation, visit [https://ereo.dev/docs/router-conventions](https://ereo.dev/docs/router-conventions)
|
|
96
|
+
|
|
97
|
+
## Part of EreoJS
|
|
98
|
+
|
|
99
|
+
This package is part of the [EreoJS monorepo](https://github.com/anthropics/ereo-js).
|
|
100
|
+
|
|
101
|
+
## License
|
|
102
|
+
|
|
103
|
+
MIT
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ereo/router-conventions - File naming convention parser
|
|
3
|
+
*
|
|
4
|
+
* Parses file names to determine route configuration:
|
|
5
|
+
* - [slug].ssg.tsx -> SSG mode
|
|
6
|
+
* - [slug].server.tsx -> Server-only, no hydration
|
|
7
|
+
* - [slug].client.tsx -> CSR only
|
|
8
|
+
* - [slug].api.tsx -> API endpoint
|
|
9
|
+
* - _islands/*.tsx -> Auto-extracted islands
|
|
10
|
+
*/
|
|
11
|
+
import type { RenderMode, RouteConfig } from '@ereo/core';
|
|
12
|
+
/** Convention suffixes and their render modes */
|
|
13
|
+
export declare const CONVENTION_SUFFIXES: Record<string, RenderMode | 'api'>;
|
|
14
|
+
/** Parsed convention info from a filename */
|
|
15
|
+
export interface ConventionInfo {
|
|
16
|
+
/** Base route path (without convention suffix) */
|
|
17
|
+
basePath: string;
|
|
18
|
+
/** Detected render mode from convention */
|
|
19
|
+
renderMode?: RenderMode;
|
|
20
|
+
/** Whether this is an API route */
|
|
21
|
+
isApi: boolean;
|
|
22
|
+
/** Whether this is an island component */
|
|
23
|
+
isIsland: boolean;
|
|
24
|
+
/** Whether this is a layout file */
|
|
25
|
+
isLayout: boolean;
|
|
26
|
+
/** Original filename */
|
|
27
|
+
filename: string;
|
|
28
|
+
/** File extension */
|
|
29
|
+
extension: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Parse a filename to extract convention information.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* parseConvention('blog/[slug].ssg.tsx')
|
|
36
|
+
* // => { basePath: 'blog/[slug]', renderMode: 'ssg', isApi: false, ... }
|
|
37
|
+
*
|
|
38
|
+
* parseConvention('_islands/Counter.tsx')
|
|
39
|
+
* // => { basePath: '_islands/Counter', isIsland: true, ... }
|
|
40
|
+
*/
|
|
41
|
+
export declare function parseConvention(filename: string): ConventionInfo;
|
|
42
|
+
/**
|
|
43
|
+
* Generate route configuration from convention info.
|
|
44
|
+
*/
|
|
45
|
+
export declare function conventionToRouteConfig(info: ConventionInfo): Partial<RouteConfig>;
|
|
46
|
+
/**
|
|
47
|
+
* Check if a filename matches a convention pattern.
|
|
48
|
+
*/
|
|
49
|
+
export declare function hasConvention(filename: string): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Get all supported convention patterns for documentation.
|
|
52
|
+
*/
|
|
53
|
+
export declare function getConventionPatterns(): string[];
|
|
54
|
+
/**
|
|
55
|
+
* Strip convention suffix from route path for URL generation.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* stripConvention('blog/[slug].ssg') // => 'blog/[slug]'
|
|
59
|
+
*/
|
|
60
|
+
export declare function stripConvention(routePath: string): string;
|
|
61
|
+
/**
|
|
62
|
+
* Apply convention-based configuration to a route.
|
|
63
|
+
* This merges convention config with explicit config exports.
|
|
64
|
+
*/
|
|
65
|
+
export declare function applyConventionConfig(routePath: string, explicitConfig?: Partial<RouteConfig>): Partial<RouteConfig>;
|
|
66
|
+
//# sourceMappingURL=conventions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conventions.d.ts","sourceRoot":"","sources":["../src/conventions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE1D,iDAAiD;AACjD,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,KAAK,CAMlE,CAAC;AAEF,6CAA6C;AAC7C,MAAM,WAAW,cAAc;IAC7B,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,mCAAmC;IACnC,KAAK,EAAE,OAAO,CAAC;IACf,0CAA0C;IAC1C,QAAQ,EAAE,OAAO,CAAC;IAClB,oCAAoC;IACpC,QAAQ,EAAE,OAAO,CAAC;IAClB,wBAAwB;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,qBAAqB;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAsChE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC,CAsClF;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGvD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAUhD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAOzD;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,cAAc,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GACpC,OAAO,CAAC,WAAW,CAAC,CAatB"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ereo/router-conventions - Main exports
|
|
3
|
+
*/
|
|
4
|
+
export { parseConvention, conventionToRouteConfig, hasConvention, stripConvention, applyConventionConfig, getConventionPatterns, CONVENTION_SUFFIXES, } from './conventions';
|
|
5
|
+
export type { ConventionInfo, } from './conventions';
|
|
6
|
+
export { integrateConventions } from './integration';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,aAAa,EACb,eAAe,EACf,qBAAqB,EACrB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,eAAe,CAAC;AAEvB,YAAY,EACV,cAAc,GACf,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// src/conventions.ts
|
|
3
|
+
var CONVENTION_SUFFIXES = {
|
|
4
|
+
".ssg": "ssg",
|
|
5
|
+
".server": "ssr",
|
|
6
|
+
".client": "csr",
|
|
7
|
+
".api": "api",
|
|
8
|
+
".rsc": "rsc"
|
|
9
|
+
};
|
|
10
|
+
function parseConvention(filename) {
|
|
11
|
+
const lastDot = filename.lastIndexOf(".");
|
|
12
|
+
const extension = lastDot >= 0 ? filename.slice(lastDot) : "";
|
|
13
|
+
const nameWithoutExt = lastDot >= 0 ? filename.slice(0, lastDot) : filename;
|
|
14
|
+
const isIsland = filename.includes("/_islands/") || filename.startsWith("_islands/");
|
|
15
|
+
const isLayout = nameWithoutExt.endsWith("/_layout") || nameWithoutExt === "_layout";
|
|
16
|
+
let basePath = nameWithoutExt;
|
|
17
|
+
let renderMode;
|
|
18
|
+
let isApi = false;
|
|
19
|
+
for (const [suffix, mode] of Object.entries(CONVENTION_SUFFIXES)) {
|
|
20
|
+
if (nameWithoutExt.endsWith(suffix)) {
|
|
21
|
+
basePath = nameWithoutExt.slice(0, -suffix.length);
|
|
22
|
+
if (mode === "api") {
|
|
23
|
+
isApi = true;
|
|
24
|
+
} else {
|
|
25
|
+
renderMode = mode;
|
|
26
|
+
}
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
basePath,
|
|
32
|
+
renderMode,
|
|
33
|
+
isApi,
|
|
34
|
+
isIsland,
|
|
35
|
+
isLayout,
|
|
36
|
+
filename,
|
|
37
|
+
extension
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function conventionToRouteConfig(info) {
|
|
41
|
+
const config = {};
|
|
42
|
+
if (info.renderMode) {
|
|
43
|
+
config.render = {
|
|
44
|
+
mode: info.renderMode,
|
|
45
|
+
streaming: { enabled: info.renderMode === "ssr" }
|
|
46
|
+
};
|
|
47
|
+
if (info.renderMode === "ssg") {
|
|
48
|
+
config.render.prerender = {
|
|
49
|
+
enabled: true,
|
|
50
|
+
fallback: "blocking"
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
if (info.renderMode === "ssr" && info.filename.includes(".server.")) {
|
|
54
|
+
config.islands = { disabled: true, defaultStrategy: "none" };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (info.isApi) {
|
|
58
|
+
config.render = { mode: "json" };
|
|
59
|
+
}
|
|
60
|
+
if (info.isIsland) {
|
|
61
|
+
config.islands = {
|
|
62
|
+
defaultStrategy: "load",
|
|
63
|
+
...config.islands
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
return config;
|
|
67
|
+
}
|
|
68
|
+
function hasConvention(filename) {
|
|
69
|
+
const info = parseConvention(filename);
|
|
70
|
+
return !!info.renderMode || info.isApi || info.isIsland;
|
|
71
|
+
}
|
|
72
|
+
function getConventionPatterns() {
|
|
73
|
+
return [
|
|
74
|
+
"*.ssg.tsx - Static Site Generation (pre-rendered at build)",
|
|
75
|
+
"*.server.tsx - Server-side only (no client JavaScript)",
|
|
76
|
+
"*.client.tsx - Client-side rendering only",
|
|
77
|
+
"*.api.tsx - API endpoint (JSON response)",
|
|
78
|
+
"*.rsc.tsx - React Server Component",
|
|
79
|
+
"_islands/*.tsx - Auto-extracted island components",
|
|
80
|
+
"_layout.tsx - Nested layout wrapper"
|
|
81
|
+
];
|
|
82
|
+
}
|
|
83
|
+
function stripConvention(routePath) {
|
|
84
|
+
for (const suffix of Object.keys(CONVENTION_SUFFIXES)) {
|
|
85
|
+
if (routePath.endsWith(suffix)) {
|
|
86
|
+
return routePath.slice(0, -suffix.length);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return routePath;
|
|
90
|
+
}
|
|
91
|
+
function applyConventionConfig(routePath, explicitConfig) {
|
|
92
|
+
const info = parseConvention(routePath);
|
|
93
|
+
const conventionConfig = conventionToRouteConfig(info);
|
|
94
|
+
return {
|
|
95
|
+
...conventionConfig,
|
|
96
|
+
...explicitConfig,
|
|
97
|
+
render: explicitConfig?.render ?? conventionConfig.render,
|
|
98
|
+
islands: explicitConfig?.islands ?? conventionConfig.islands,
|
|
99
|
+
cache: explicitConfig?.cache ?? conventionConfig.cache
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
// src/integration.ts
|
|
103
|
+
function integrateConventions(routes, options = {}) {
|
|
104
|
+
const { enabled = true } = options;
|
|
105
|
+
if (!enabled) {
|
|
106
|
+
return routes;
|
|
107
|
+
}
|
|
108
|
+
return routes.map((route) => {
|
|
109
|
+
const conventionConfig = applyConventionConfig(route.file, route.config);
|
|
110
|
+
return {
|
|
111
|
+
...route,
|
|
112
|
+
config: {
|
|
113
|
+
...route.config,
|
|
114
|
+
...conventionConfig
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
export {
|
|
120
|
+
stripConvention,
|
|
121
|
+
parseConvention,
|
|
122
|
+
integrateConventions,
|
|
123
|
+
hasConvention,
|
|
124
|
+
getConventionPatterns,
|
|
125
|
+
conventionToRouteConfig,
|
|
126
|
+
applyConventionConfig,
|
|
127
|
+
CONVENTION_SUFFIXES
|
|
128
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ereo/router-conventions - Integration with file router
|
|
3
|
+
*
|
|
4
|
+
* Integrates convention-based routing with the file router system.
|
|
5
|
+
*/
|
|
6
|
+
import type { Route } from '@ereo/core';
|
|
7
|
+
/**
|
|
8
|
+
* Options for integrating conventions with the router.
|
|
9
|
+
*/
|
|
10
|
+
export interface ConventionIntegrationOptions {
|
|
11
|
+
/** Enable convention parsing (default: true) */
|
|
12
|
+
enabled?: boolean;
|
|
13
|
+
/** Custom convention suffixes to add */
|
|
14
|
+
customSuffixes?: Record<string, string>;
|
|
15
|
+
/** Directories to scan for islands */
|
|
16
|
+
islandDirs?: string[];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Integrate conventions with discovered routes.
|
|
20
|
+
* This transforms route configs based on filename conventions.
|
|
21
|
+
*/
|
|
22
|
+
export declare function integrateConventions(routes: Route[], options?: ConventionIntegrationOptions): Route[];
|
|
23
|
+
/**
|
|
24
|
+
* Generate route ID from convention info.
|
|
25
|
+
* Strips convention suffixes for cleaner route IDs.
|
|
26
|
+
*/
|
|
27
|
+
export declare function generateRouteId(filePath: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* Check if a route should be treated as an API route.
|
|
30
|
+
*/
|
|
31
|
+
export declare function isApiRoute(filePath: string): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Check if a route should be treated as an island component.
|
|
34
|
+
*/
|
|
35
|
+
export declare function isIslandComponent(filePath: string): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Get the effective render mode for a route file.
|
|
38
|
+
*/
|
|
39
|
+
export declare function getEffectiveRenderMode(filePath: string, explicitMode?: string): string;
|
|
40
|
+
//# sourceMappingURL=integration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../src/integration.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGxC;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,gDAAgD;IAChD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wCAAwC;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,sCAAsC;IACtC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,KAAK,EAAE,EACf,OAAO,GAAE,4BAAiC,GACzC,KAAK,EAAE,CAkBT;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGxD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGpD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAG3D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,CAaR"}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ereo/router-conventions",
|
|
3
|
+
"version": "0.1.6",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"author": "Ereo Team",
|
|
6
|
+
"homepage": "https://ereo.dev",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/ereojs/ereo.git",
|
|
10
|
+
"directory": "packages/router-conventions"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/ereojs/ereo/issues"
|
|
14
|
+
},
|
|
15
|
+
"description": "File-based routing conventions for EreoJS framework",
|
|
16
|
+
"type": "module",
|
|
17
|
+
"main": "./dist/index.js",
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"import": "./dist/index.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist"
|
|
27
|
+
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "bun build ./src/index.ts --outdir ./dist --target bun --external @ereo/core --external @ereo/router && bun run build:types",
|
|
30
|
+
"build:types": "tsc --emitDeclarationOnly --outDir dist",
|
|
31
|
+
"dev": "bun build ./src/index.ts --outdir ./dist --target bun --watch",
|
|
32
|
+
"test": "bun test",
|
|
33
|
+
"typecheck": "tsc --noEmit"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@ereo/core": "workspace:*",
|
|
37
|
+
"@ereo/router": "workspace:*"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/bun": "^1.1.0",
|
|
41
|
+
"typescript": "^5.4.0"
|
|
42
|
+
}
|
|
43
|
+
}
|