elysia-autoload 1.2.1 → 1.4.0

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
@@ -2,8 +2,6 @@
2
2
 
3
3
  Plugin for [Elysia](https://elysiajs.com/) which autoload all routes in directory and code-generate types for [Eden](https://elysiajs.com/eden/overview.html) with [`Bun.build`](#bun-build-usage) support!
4
4
 
5
- **Currently, Eden types generation is broken!!**
6
-
7
5
  ## Installation
8
6
 
9
7
  ### Start new project with [create-elysiajs](https://github.com/kravetsone/create-elysiajs)
@@ -65,6 +63,9 @@ Guide how `elysia-autoload` match routes
65
63
  └──index.ts
66
64
  ├── frontend
67
65
  └──index.tsx // usage of tsx extension
66
+ ├── events
67
+ └──(post).ts // post and get will not be in the link
68
+ └──(get).ts
68
69
  └── users.ts
69
70
  └── package.json
70
71
  ```
@@ -76,6 +77,8 @@ Guide how `elysia-autoload` match routes
76
77
  - /routes/likes/[...].ts → /likes/\*
77
78
  - /routes/domains/@[...]/index.ts → /domains/@\*
78
79
  - /routes/frontend/index.tsx → /frontend
80
+ - /routes/events/(post).ts → /events
81
+ - /routes/events/(get).ts → /events
79
82
 
80
83
  ## Options
81
84
 
@@ -119,14 +122,14 @@ export type ElysiaApp = typeof app;
119
122
  ```ts
120
123
  // client.ts
121
124
 
122
- import { edenTreaty } from "@elysiajs/eden";
125
+ import { treaty } from "@elysiajs/eden";
123
126
 
124
127
  // Routes are a global type so you don't need to import it.
125
128
 
126
- const app = edenTreaty<Routes>("http://localhost:3002");
129
+ const app = treaty<Routes>("http://localhost:3002");
127
130
 
128
131
  const { data } = await app.test["some-path-param"].get({
129
- $query: {
132
+ query: {
130
133
  key: 2,
131
134
  },
132
135
  });
@@ -144,15 +147,13 @@ import type Route0 from "./routes/index";
144
147
  import type Route1 from "./routes/test/[some]/index";
145
148
 
146
149
  declare global {
147
- export type Routes = ElysiaWithBaseUrl<"/api", ReturnType<typeof Route0>> &
148
- ElysiaWithBaseUrl<"/api/test/:some", ReturnType<typeof Route1>>;
150
+ export type Routes = ElysiaWithBaseUrl<"/api", typeof Route0> &
151
+ ElysiaWithBaseUrl<"/api/test/:some", typeof Route1>;
149
152
  }
150
153
  ```
151
154
 
152
155
  Example of app with types code-generation you can see in [example](https://github.com/kravetsone/elysia-autoload/tree/main/example)
153
156
 
154
- **Currently, Eden types generation is broken!!**
155
-
156
157
  ### [Bun build](https://bun.sh/docs/bundler) usage
157
158
 
158
159
  You can use this plugin with [`Bun.build`](https://bun.sh/docs/bundler), thanks to [esbuild-plugin-autoload](https://github.com/kravetsone/esbuild-plugin-autoload)!
package/dist/index.d.ts CHANGED
@@ -1,23 +1,22 @@
1
- import Elysia, { RouteBase, LocalHook, InputSchema, RouteSchema, SingletonBase, BaseMacro, Elysia as Elysia$1 } from 'elysia';
1
+ import Elysia, { RouteBase, RouteSchema, AnyElysia, LocalHook, InputSchema, SingletonBase, BaseMacro, Elysia as Elysia$1 } from 'elysia';
2
2
 
3
3
  type PathToObject<Path extends string, Type extends RouteBase> = Path extends `${infer Head}/${infer Rest}` ? Head extends "" ? PathToObject<Rest, Type> : {
4
4
  [K in Head]: PathToObject<Rest, Type>;
5
5
  } : {
6
6
  [K in Path]: Type;
7
7
  };
8
- type RouteEndType = Record<string, {
9
- body: any;
10
- params: any;
11
- query: any;
12
- headers: any;
13
- response: any;
14
- }>;
8
+ declare namespace ElysiaMatch {
9
+ type RouteEnd = Record<string, RouteSchema>;
10
+ type Fx = (...args: any[]) => AnyElysia;
11
+ type All = AnyElysia | Fx;
12
+ type Extract<T extends All> = T extends Fx ? ReturnType<T> : T;
13
+ }
15
14
  type FlattenIndexRoutes<T> = T extends object ? {
16
- [K in keyof T as K extends "index" ? T[K] extends RouteEndType ? never : K : K]: FlattenIndexRoutes<T[K]>;
15
+ [K in keyof T as K extends "index" ? T[K] extends ElysiaMatch.RouteEnd ? never : K : K]: FlattenIndexRoutes<T[K]>;
17
16
  } & (T extends {
18
17
  index: infer I;
19
- } ? I extends RouteEndType ? FlattenIndexRoutes<I> : {} : {}) : T;
20
- type ElysiaWithBaseUrl<BaseUrl extends string, ElysiaType extends Elysia<any, any, any, any, any, any, any, any>> = ElysiaType extends Elysia<infer BasePath, infer Scoped, infer Singleton, infer Definitions, infer Metadata, infer Routes, infer Ephemeral, infer Volatile> ? Elysia<BasePath, Scoped, Singleton, Definitions, Metadata, FlattenIndexRoutes<PathToObject<BaseUrl, Routes>>, Ephemeral, Volatile> : never;
18
+ } ? I extends ElysiaMatch.RouteEnd ? FlattenIndexRoutes<I> : T : T) : T;
19
+ type ElysiaWithBaseUrl<BaseUrl extends string, ElysiaType extends ElysiaMatch.All> = ElysiaMatch.Extract<ElysiaType> extends Elysia<infer BasePath, infer Scoped, infer Singleton, infer Definitions, infer Metadata, infer Routes, infer Ephemeral, infer Volatile> ? Elysia<BasePath, Scoped, Singleton, Definitions, Metadata, FlattenIndexRoutes<PathToObject<BaseUrl, Routes>>, Ephemeral, Volatile> : never;
21
20
  type SoftString<T extends string> = T | (string & {});
22
21
 
23
22
  type SchemaHandler = ({ path, url, }: {
package/dist/index.js CHANGED
@@ -3,8 +3,7 @@ import path from 'node:path';
3
3
  import { Elysia } from 'elysia';
4
4
 
5
5
  function getPath(dir) {
6
- if (path.isAbsolute(dir))
7
- return dir;
6
+ if (path.isAbsolute(dir)) return dir;
8
7
  if (path.isAbsolute(process.argv[1]))
9
8
  return path.join(process.argv[1], "..", dir);
10
9
  return path.join(process.cwd(), process.argv[1], "..", dir);
@@ -22,6 +21,10 @@ function transformToUrl(path2) {
22
21
  regex: /\[(.*?)\]/gu,
23
22
  replacement: (_, match) => `:${match}`
24
23
  },
24
+ {
25
+ regex: /\/?\((.*)\)/,
26
+ replacement: ""
27
+ },
25
28
  // Handle the case when multiple parameters are present in one file
26
29
  // users / [id] - [name].ts to users /: id -:name and users / [id] - [name] / [age].ts to users /: id -: name /: age
27
30
  { regex: /\]-\[/gu, replacement: "-:" },
@@ -44,13 +47,11 @@ function sortByNestedParams(routes) {
44
47
  return routes.sort((a, b) => getParamsCount(a) - getParamsCount(b));
45
48
  }
46
49
  function fixSlashes(prefix) {
47
- if (!prefix?.endsWith("/"))
48
- return prefix;
50
+ if (!prefix?.endsWith("/")) return prefix;
49
51
  return prefix.slice(0, -1);
50
52
  }
51
53
  function addRelativeIfNotDot(path2) {
52
- if (path2.at(0) !== ".")
53
- return `./${path2}`;
54
+ if (path2.at(0) !== ".") return `./${path2}`;
54
55
  return path2;
55
56
  }
56
57
 
@@ -102,8 +103,7 @@ async function autoload(options = {}) {
102
103
  const fullPath = path.join(directoryPath, filePath);
103
104
  const file = await import(fullPath);
104
105
  const importName = typeof getImportName === "string" ? getImportName : getImportName(file);
105
- if (!file[importName] && options?.skipImportErrors)
106
- continue;
106
+ if (!file[importName] && options?.skipImportErrors) continue;
107
107
  if (!file[importName])
108
108
  throw new Error(`${filePath} don't provide export ${importName}`);
109
109
  const url = transformToUrl(filePath);
@@ -115,14 +115,13 @@ async function autoload(options = {}) {
115
115
  plugin.group(url, groupOptions, (app) => app.use(importedValue()));
116
116
  if (importedValue instanceof Elysia)
117
117
  plugin.group(url, groupOptions, (app) => app.use(importedValue));
118
- if (types)
119
- paths.push(fullPath.replace(directoryPath, ""));
118
+ if (types) paths.push([fullPath.replace(directoryPath, ""), importName]);
120
119
  }
121
120
  if (types) {
122
121
  for await (const outputPath of types.output) {
123
122
  const outputAbsolutePath = getPath(outputPath);
124
123
  const imports = paths.map(
125
- (x, index) => `import type Route${index} from "${addRelativeIfNotDot(
124
+ ([x, exportName], index) => `import type ${exportName === "default" ? `Route${index}` : `{ ${exportName} as Route${index} }`} from "${addRelativeIfNotDot(
126
125
  path.relative(
127
126
  path.dirname(outputAbsolutePath),
128
127
  directoryPath + x.replace(".ts", "").replace(".tsx", "")
@@ -137,7 +136,7 @@ async function autoload(options = {}) {
137
136
  "",
138
137
  !types.useExport ? "declare global {" : "",
139
138
  ` export type ${types.typeName} = ${paths.map(
140
- (x, index) => `ElysiaWithBaseUrl<"${((prefix?.endsWith("/") ? prefix.slice(0, -1) : prefix) ?? "") + transformToUrl(x) || "/"}", ReturnType<typeof Route${index}>>`
139
+ ([x], index) => `ElysiaWithBaseUrl<"${((prefix?.endsWith("/") ? prefix.slice(0, -1) : prefix) ?? "") + transformToUrl(x) || "/"}", typeof Route${index}>`
141
140
  ).join("\n & ")}`,
142
141
  !types.useExport ? "}" : ""
143
142
  ].join("\n")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "elysia-autoload",
3
- "version": "1.2.1",
3
+ "version": "1.4.0",
4
4
  "author": "kravetsone",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
@@ -29,18 +29,17 @@
29
29
  "scripts": {
30
30
  "prepublishOnly": "bun test && bunx pkgroll",
31
31
  "lint": "bunx @biomejs/biome check src",
32
- "lint:fix": "bun lint --apply",
33
- "prepare": "bunx husky"
32
+ "lint:fix": "bun lint --apply"
34
33
  },
35
34
  "files": ["dist"],
36
35
  "devDependencies": {
37
- "@biomejs/biome": "1.8.3",
38
- "@elysiajs/eden": "^1.1.0",
39
- "@elysiajs/swagger": "^1.1.0",
40
- "@types/bun": "^1.1.6",
41
- "elysia": "^1.1.2",
42
- "pkgroll": "^2.1.1",
43
- "typescript": "^5.5.3"
36
+ "@biomejs/biome": "1.9.2",
37
+ "@elysiajs/eden": "^1.1.3",
38
+ "@elysiajs/swagger": "^1.1.1",
39
+ "@types/bun": "^1.1.9",
40
+ "elysia": "^1.1.13",
41
+ "pkgroll": "^2.5.0",
42
+ "typescript": "^5.6.2"
44
43
  },
45
44
  "peerDependencies": {
46
45
  "elysia": "^1.1.0"