alepha 0.15.2 → 0.15.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.
Files changed (132) hide show
  1. package/README.md +68 -80
  2. package/dist/api/audits/index.d.ts +332 -332
  3. package/dist/api/audits/index.d.ts.map +1 -1
  4. package/dist/api/files/index.d.ts +170 -170
  5. package/dist/api/files/index.d.ts.map +1 -1
  6. package/dist/api/jobs/index.d.ts +151 -151
  7. package/dist/api/keys/index.d.ts +195 -195
  8. package/dist/api/keys/index.d.ts.map +1 -1
  9. package/dist/api/parameters/index.d.ts +260 -260
  10. package/dist/api/users/index.d.ts +22 -11
  11. package/dist/api/users/index.d.ts.map +1 -1
  12. package/dist/api/users/index.js +7 -2
  13. package/dist/api/users/index.js.map +1 -1
  14. package/dist/api/verifications/index.d.ts +128 -128
  15. package/dist/api/verifications/index.d.ts.map +1 -1
  16. package/dist/bucket/index.d.ts +8 -0
  17. package/dist/bucket/index.d.ts.map +1 -1
  18. package/dist/bucket/index.js +7 -2
  19. package/dist/bucket/index.js.map +1 -1
  20. package/dist/cli/index.d.ts +191 -74
  21. package/dist/cli/index.d.ts.map +1 -1
  22. package/dist/cli/index.js +215 -48
  23. package/dist/cli/index.js.map +1 -1
  24. package/dist/command/index.d.ts +10 -0
  25. package/dist/command/index.d.ts.map +1 -1
  26. package/dist/command/index.js +67 -13
  27. package/dist/command/index.js.map +1 -1
  28. package/dist/core/index.browser.js +28 -21
  29. package/dist/core/index.browser.js.map +1 -1
  30. package/dist/core/index.d.ts.map +1 -1
  31. package/dist/core/index.js +28 -21
  32. package/dist/core/index.js.map +1 -1
  33. package/dist/core/index.native.js +28 -21
  34. package/dist/core/index.native.js.map +1 -1
  35. package/dist/email/index.d.ts +8 -0
  36. package/dist/email/index.d.ts.map +1 -1
  37. package/dist/email/index.js +7 -2
  38. package/dist/email/index.js.map +1 -1
  39. package/dist/mcp/index.d.ts +5 -5
  40. package/dist/orm/index.bun.js +32 -16
  41. package/dist/orm/index.bun.js.map +1 -1
  42. package/dist/orm/index.d.ts +4 -1
  43. package/dist/orm/index.d.ts.map +1 -1
  44. package/dist/orm/index.js +34 -22
  45. package/dist/orm/index.js.map +1 -1
  46. package/dist/react/router/index.browser.js +9 -15
  47. package/dist/react/router/index.browser.js.map +1 -1
  48. package/dist/react/router/index.d.ts +295 -407
  49. package/dist/react/router/index.d.ts.map +1 -1
  50. package/dist/react/router/index.js +566 -776
  51. package/dist/react/router/index.js.map +1 -1
  52. package/dist/redis/index.d.ts +19 -19
  53. package/dist/security/index.d.ts +42 -42
  54. package/dist/security/index.d.ts.map +1 -1
  55. package/dist/security/index.js +8 -7
  56. package/dist/security/index.js.map +1 -1
  57. package/dist/server/auth/index.d.ts +167 -167
  58. package/dist/server/core/index.d.ts +9 -9
  59. package/dist/server/health/index.d.ts +17 -17
  60. package/dist/server/links/index.d.ts +39 -39
  61. package/dist/server/static/index.js +7 -2
  62. package/dist/server/static/index.js.map +1 -1
  63. package/dist/server/swagger/index.d.ts +8 -0
  64. package/dist/server/swagger/index.d.ts.map +1 -1
  65. package/dist/server/swagger/index.js +7 -2
  66. package/dist/server/swagger/index.js.map +1 -1
  67. package/dist/sms/index.d.ts +8 -0
  68. package/dist/sms/index.d.ts.map +1 -1
  69. package/dist/sms/index.js +7 -2
  70. package/dist/sms/index.js.map +1 -1
  71. package/dist/system/index.browser.js +734 -12
  72. package/dist/system/index.browser.js.map +1 -1
  73. package/dist/system/index.d.ts +8 -0
  74. package/dist/system/index.d.ts.map +1 -1
  75. package/dist/system/index.js +7 -2
  76. package/dist/system/index.js.map +1 -1
  77. package/dist/vite/index.d.ts +1 -1
  78. package/dist/vite/index.js +15 -7
  79. package/dist/vite/index.js.map +1 -1
  80. package/package.json +4 -2
  81. package/src/api/logs/TODO.md +13 -10
  82. package/src/cli/apps/AlephaPackageBuilderCli.ts +9 -0
  83. package/src/cli/atoms/buildOptions.ts +99 -9
  84. package/src/cli/commands/build.ts +149 -32
  85. package/src/cli/commands/db.ts +5 -7
  86. package/src/cli/commands/init.spec.ts +50 -6
  87. package/src/cli/commands/init.ts +28 -5
  88. package/src/cli/providers/ViteDevServerProvider.ts +1 -10
  89. package/src/cli/services/AlephaCliUtils.ts +16 -0
  90. package/src/cli/services/PackageManagerUtils.ts +2 -0
  91. package/src/cli/services/ProjectScaffolder.spec.ts +97 -0
  92. package/src/cli/services/ProjectScaffolder.ts +28 -6
  93. package/src/cli/templates/agentMd.ts +6 -1
  94. package/src/cli/templates/apiAppSecurityTs.ts +11 -0
  95. package/src/cli/templates/apiIndexTs.ts +18 -4
  96. package/src/cli/templates/webAppRouterTs.ts +25 -1
  97. package/src/cli/templates/webHelloComponentTsx.ts +15 -5
  98. package/src/command/helpers/Runner.spec.ts +135 -0
  99. package/src/command/helpers/Runner.ts +4 -1
  100. package/src/command/providers/CliProvider.spec.ts +325 -0
  101. package/src/command/providers/CliProvider.ts +117 -7
  102. package/src/core/Alepha.ts +32 -25
  103. package/src/orm/index.bun.ts +1 -1
  104. package/src/orm/index.ts +2 -6
  105. package/src/orm/providers/drivers/BunSqliteProvider.ts +4 -1
  106. package/src/orm/providers/drivers/CloudflareD1Provider.ts +57 -30
  107. package/src/orm/providers/drivers/DatabaseProvider.ts +9 -1
  108. package/src/orm/providers/drivers/NodeSqliteProvider.ts +4 -1
  109. package/src/react/router/hooks/useActive.ts +1 -1
  110. package/src/react/router/hooks/useRouter.ts +1 -1
  111. package/src/react/router/index.ts +4 -0
  112. package/src/react/router/primitives/$page.browser.spec.tsx +24 -24
  113. package/src/react/router/primitives/$page.spec.tsx +0 -32
  114. package/src/react/router/primitives/$page.ts +6 -14
  115. package/src/react/router/providers/ReactBrowserProvider.ts +6 -3
  116. package/src/react/router/providers/ReactPageProvider.ts +1 -1
  117. package/src/react/router/providers/ReactPreloadProvider.spec.ts +142 -0
  118. package/src/react/router/providers/ReactPreloadProvider.ts +85 -0
  119. package/src/react/router/providers/ReactServerProvider.ts +7 -78
  120. package/src/react/router/providers/ReactServerTemplateProvider.spec.ts +210 -0
  121. package/src/react/router/providers/ReactServerTemplateProvider.ts +228 -665
  122. package/src/react/router/services/ReactRouter.ts +13 -13
  123. package/src/security/__tests__/ServerSecurityProvider.spec.ts +77 -0
  124. package/src/security/providers/ServerSecurityProvider.ts +30 -22
  125. package/src/server/core/providers/NodeHttpServerProvider.spec.ts +9 -3
  126. package/src/system/index.browser.ts +25 -0
  127. package/src/system/index.workerd.ts +1 -0
  128. package/src/system/providers/FileSystemProvider.ts +8 -0
  129. package/src/system/providers/NodeFileSystemProvider.ts +11 -2
  130. package/src/vite/tasks/buildServer.ts +2 -12
  131. package/src/vite/tasks/generateCloudflare.ts +10 -7
  132. package/src/vite/tasks/generateDocker.ts +4 -0
@@ -7,7 +7,7 @@ import {
7
7
  type ReactRouterState,
8
8
  } from "../providers/ReactPageProvider.ts";
9
9
 
10
- export interface RouterGoOptions {
10
+ export interface RouterPushOptions {
11
11
  replace?: boolean;
12
12
  params?: Record<string, string>;
13
13
  query?: Record<string, string>;
@@ -114,7 +114,7 @@ export class ReactRouter<T extends object> {
114
114
  return;
115
115
  }
116
116
 
117
- await this.go(this.location.pathname + this.location.search, {
117
+ await this.push(this.location.pathname + this.location.search, {
118
118
  replace: true,
119
119
  force: true,
120
120
  });
@@ -168,18 +168,18 @@ export class ReactRouter<T extends object> {
168
168
  await this.browser?.invalidate(props);
169
169
  }
170
170
 
171
- public async go(path: string, options?: RouterGoOptions): Promise<void>;
172
- public async go(
171
+ public async push(path: string, options?: RouterPushOptions): Promise<void>;
172
+ public async push(
173
173
  path: keyof VirtualRouter<T>,
174
- options?: RouterGoOptions,
174
+ options?: RouterPushOptions,
175
175
  ): Promise<void>;
176
- public async go(
176
+ public async push(
177
177
  path: string | keyof VirtualRouter<T>,
178
- options?: RouterGoOptions,
178
+ options?: RouterPushOptions,
179
179
  ): Promise<void> {
180
180
  for (const page of this.pages) {
181
181
  if (page.name === path) {
182
- await this.browser?.go(
182
+ await this.browser?.push(
183
183
  this.path(path as keyof VirtualRouter<T>, options),
184
184
  options,
185
185
  );
@@ -187,17 +187,17 @@ export class ReactRouter<T extends object> {
187
187
  }
188
188
  }
189
189
 
190
- await this.browser?.go(path as string, options);
190
+ await this.browser?.push(path as string, options);
191
191
  }
192
192
 
193
- public anchor(path: string, options?: RouterGoOptions): AnchorProps;
193
+ public anchor(path: string, options?: RouterPushOptions): AnchorProps;
194
194
  public anchor(
195
195
  path: keyof VirtualRouter<T>,
196
- options?: RouterGoOptions,
196
+ options?: RouterPushOptions,
197
197
  ): AnchorProps;
198
198
  public anchor(
199
199
  path: string | keyof VirtualRouter<T>,
200
- options: RouterGoOptions = {},
200
+ options: RouterPushOptions = {},
201
201
  ): AnchorProps {
202
202
  let href = path as string;
203
203
 
@@ -214,7 +214,7 @@ export class ReactRouter<T extends object> {
214
214
  ev.stopPropagation();
215
215
  ev.preventDefault();
216
216
 
217
- this.go(href, options).catch(console.error);
217
+ this.push(href, options).catch(console.error);
218
218
  },
219
219
  };
220
220
  }
@@ -15,6 +15,7 @@ describe("ServerSecurityProvider", () => {
15
15
  it("should protect action from unauthorized users", async () => {
16
16
  class TestApp {
17
17
  ok = $action({
18
+ secure: true,
18
19
  handler: () => "OK",
19
20
  });
20
21
  }
@@ -63,10 +64,12 @@ describe("ServerSecurityProvider", () => {
63
64
  it("should guard by permission", async () => {
64
65
  class TestApp {
65
66
  admin = $action({
67
+ secure: true,
66
68
  group: "read",
67
69
  handler: () => "ADMIN",
68
70
  });
69
71
  user = $action({
72
+ secure: true,
70
73
  group: "read",
71
74
  handler: () => "USER",
72
75
  });
@@ -128,4 +131,78 @@ describe("ServerSecurityProvider", () => {
128
131
  await app.admin.fetch({}, { user: admin }).then((it) => it.data),
129
132
  ).toBe("ADMIN");
130
133
  });
134
+
135
+ it("should allow public actions by default (no secure option)", async () => {
136
+ class TestApp {
137
+ public = $action({
138
+ handler: () => "PUBLIC",
139
+ });
140
+ issuer = $issuer({
141
+ secret: "test",
142
+ roles: [{ name: "user", permissions: [{ name: "*" }] }],
143
+ });
144
+ }
145
+
146
+ const alepha = Alepha.create().with(AlephaServer).with(AlephaSecurity);
147
+ const app = alepha.inject(TestApp);
148
+ await alepha.start();
149
+
150
+ // Should work without authentication via .run()
151
+ expect(await app.public.run({})).toBe("PUBLIC");
152
+
153
+ // Should work without authentication via .fetch()
154
+ expect(await app.public.fetch({}).then((it) => it.data)).toBe("PUBLIC");
155
+
156
+ // Should work via HTTP without token
157
+ const response = await fetch(
158
+ `${alepha.inject(ServerProvider).hostname}${app.public.route.path}`,
159
+ );
160
+ expect(response.status).toBe(200);
161
+ expect(await response.text()).toBe("PUBLIC");
162
+ });
163
+
164
+ it("should allow explicit secure: false", async () => {
165
+ class TestApp {
166
+ public = $action({
167
+ secure: false,
168
+ handler: () => "PUBLIC",
169
+ });
170
+ issuer = $issuer({
171
+ secret: "test",
172
+ roles: [{ name: "user", permissions: [{ name: "*" }] }],
173
+ });
174
+ }
175
+
176
+ const alepha = Alepha.create().with(AlephaServer).with(AlephaSecurity);
177
+ const app = alepha.inject(TestApp);
178
+ await alepha.start();
179
+
180
+ // Should work without authentication
181
+ expect(await app.public.run({})).toBe("PUBLIC");
182
+ expect(await app.public.fetch({}).then((it) => it.data)).toBe("PUBLIC");
183
+ });
184
+
185
+ it("should require auth when secure: true is explicit", async () => {
186
+ class TestApp {
187
+ protected = $action({
188
+ secure: true,
189
+ handler: () => "PROTECTED",
190
+ });
191
+ issuer = $issuer({
192
+ secret: "test",
193
+ roles: [{ name: "user", permissions: [{ name: "*" }] }],
194
+ });
195
+ }
196
+
197
+ const alepha = Alepha.create().with(AlephaServer).with(AlephaSecurity);
198
+ const app = alepha.inject(TestApp);
199
+ await alepha.start();
200
+
201
+ // Should fail without user
202
+ await expect(app.protected.run({})).rejects.toThrowError(UnauthorizedError);
203
+
204
+ // Should succeed with user
205
+ const user = { id: randomUUID(), roles: ["user"] };
206
+ expect(await app.protected.run({}, { user })).toBe("PROTECTED");
207
+ });
131
208
  });
@@ -31,25 +31,23 @@ export class ServerSecurityProvider {
31
31
  handler: async () => {
32
32
  for (const action of this.alepha.primitives($action)) {
33
33
  // -------------------------------------------------------------------------------------------------------------
34
- // if the action is disabled or not secure, we do NOT create a permission for it
34
+ // Only create permission when secure is explicitly set to true
35
+ // Actions are public by default (like $route)
35
36
  // -------------------------------------------------------------------------------------------------------------
36
37
  if (
37
38
  action.options.disabled ||
38
- action.options.secure === false ||
39
+ action.options.secure !== true ||
39
40
  this.securityProvider.getRealms().length === 0
40
41
  ) {
41
42
  continue;
42
43
  }
43
44
 
44
- const secure = action.options.secure;
45
- if (typeof secure !== "object") {
46
- this.securityProvider.createPermission({
47
- name: action.name,
48
- group: action.group,
49
- method: action.route.method,
50
- path: action.route.path,
51
- });
52
- }
45
+ this.securityProvider.createPermission({
46
+ name: action.name,
47
+ group: action.group,
48
+ method: action.route.method,
49
+ path: action.route.path,
50
+ });
53
51
  }
54
52
  },
55
53
  });
@@ -59,10 +57,12 @@ export class ServerSecurityProvider {
59
57
  protected readonly onActionRequest = $hook({
60
58
  on: "action:onRequest",
61
59
  handler: async ({ action, request, options }) => {
62
- // if you set explicitly secure: false, we assume you don't want any security check
63
- // but only if no user is provided in options
64
- if (action.options.secure === false && !options.user) {
65
- this.log.trace("Skipping security check for route");
60
+ const secure = action.options.secure;
61
+
62
+ // Skip security if not explicitly enabled (secure: true or secure: { realm: ... })
63
+ // Actions are public by default (like $route)
64
+ if (secure !== true && typeof secure !== "object" && !options.user) {
65
+ this.log.trace("Skipping security check for action - not secured");
66
66
  return;
67
67
  }
68
68
 
@@ -93,7 +93,7 @@ export class ServerSecurityProvider {
93
93
  this.alepha.codec.decode(userAccountInfoSchema, request.user),
94
94
  );
95
95
  } catch (error) {
96
- if (action.options.secure || permission) {
96
+ if (secure === true || typeof secure === "object" || permission) {
97
97
  throw error;
98
98
  }
99
99
  // else, we skip the security check
@@ -106,7 +106,7 @@ export class ServerSecurityProvider {
106
106
  on: "server:onRequest",
107
107
  priority: "last",
108
108
  handler: async ({ request, route }) => {
109
- // if you set explicitly secure: false, we assume you don't want any security check
109
+ // Skip entirely only if explicitly disabled
110
110
  if (route.secure === false) {
111
111
  this.log.trace(
112
112
  "Skipping security check for route - explicitly disabled",
@@ -126,7 +126,7 @@ export class ServerSecurityProvider {
126
126
  typeof route.secure === "object" ? route.secure.realm : undefined;
127
127
 
128
128
  try {
129
- // Try to resolve user (JWT, API key, etc.)
129
+ // Try to resolve user (JWT, API key, etc.) - even for public routes (optional auth)
130
130
  request.user = await this.securityProvider.resolveUserFromServerRequest(
131
131
  request,
132
132
  { permission, realm },
@@ -135,7 +135,11 @@ export class ServerSecurityProvider {
135
135
  // No user resolved?
136
136
  if (!request.user) {
137
137
  // Route requires auth → throw
138
- if (route.secure || permission) {
138
+ if (
139
+ route.secure === true ||
140
+ typeof route.secure === "object" ||
141
+ permission
142
+ ) {
139
143
  // Provide a more specific error message when no auth header was provided
140
144
  if (!request.headers.authorization) {
141
145
  throw new InvalidTokenError(
@@ -144,7 +148,7 @@ export class ServerSecurityProvider {
144
148
  }
145
149
  throw new UnauthorizedError("Authentication required");
146
150
  }
147
- // Route is public → skip
151
+ // Route is public → skip (but we tried to resolve user for optional auth)
148
152
  this.log.trace(
149
153
  "Skipping security check for route - no auth provided and not required",
150
154
  );
@@ -166,11 +170,15 @@ export class ServerSecurityProvider {
166
170
  permission,
167
171
  });
168
172
  } catch (error) {
169
- if (route.secure || permission) {
173
+ if (
174
+ route.secure === true ||
175
+ typeof route.secure === "object" ||
176
+ permission
177
+ ) {
170
178
  throw error;
171
179
  }
172
180
 
173
- // else, we skip the security check
181
+ // else, we skip the security check (route is public)
174
182
  this.log.trace(
175
183
  "Skipping security check for route - error occurred",
176
184
  error,
@@ -31,7 +31,9 @@ describe("NodeHttpServerProvider", () => {
31
31
  });
32
32
 
33
33
  test("production mode: waits for connections then closes", async () => {
34
- alepha = Alepha.create({ env: { NODE_ENV: "production" } });
34
+ alepha = Alepha.create({
35
+ env: { NODE_ENV: "production", SERVER_PORT: 0 },
36
+ });
35
37
  alepha.with(NodeHttpServerProvider);
36
38
 
37
39
  await alepha.start();
@@ -52,7 +54,9 @@ describe("NodeHttpServerProvider", () => {
52
54
  });
53
55
 
54
56
  test("production mode: forces close after timeout", async () => {
55
- alepha = Alepha.create({ env: { NODE_ENV: "production" } });
57
+ alepha = Alepha.create({
58
+ env: { NODE_ENV: "production", SERVER_PORT: 0 },
59
+ });
56
60
  alepha.with(NodeHttpServerProvider);
57
61
 
58
62
  await alepha.start();
@@ -89,7 +93,9 @@ describe("NodeHttpServerProvider", () => {
89
93
  });
90
94
 
91
95
  test("rejects new requests during shutdown", async () => {
92
- alepha = Alepha.create({ env: { NODE_ENV: "production" } });
96
+ alepha = Alepha.create({
97
+ env: { NODE_ENV: "production", SERVER_PORT: 0 },
98
+ });
93
99
  alepha.with(NodeHttpServerProvider);
94
100
 
95
101
  await alepha.start();
@@ -1,11 +1,36 @@
1
1
  import { $module } from "alepha";
2
+ import { FileSystemProvider } from "./providers/FileSystemProvider.ts";
3
+ import { MemoryFileSystemProvider } from "./providers/MemoryFileSystemProvider.ts";
4
+ import { MemoryShellProvider } from "./providers/MemoryShellProvider.ts";
5
+ import { ShellProvider } from "./providers/ShellProvider.ts";
6
+ import { FileDetector } from "./services/FileDetector.ts";
2
7
 
3
8
  export * from "./errors/FileError.ts";
4
9
  export * from "./providers/FileSystemProvider.ts";
5
10
  export * from "./providers/MemoryFileSystemProvider.ts";
6
11
  export * from "./providers/MemoryShellProvider.ts";
7
12
  export * from "./providers/ShellProvider.ts";
13
+ export * from "./services/FileDetector.ts";
8
14
 
9
15
  export const AlephaSystem = $module({
10
16
  name: "alepha.system",
17
+ services: [
18
+ FileDetector,
19
+ FileSystemProvider,
20
+ MemoryFileSystemProvider,
21
+ ShellProvider,
22
+ MemoryShellProvider,
23
+ ],
24
+ register: (alepha) =>
25
+ alepha
26
+ .with({
27
+ optional: true,
28
+ provide: FileSystemProvider,
29
+ use: MemoryFileSystemProvider,
30
+ })
31
+ .with({
32
+ optional: true,
33
+ provide: ShellProvider,
34
+ use: MemoryShellProvider,
35
+ }),
11
36
  });
@@ -0,0 +1 @@
1
+ export * from "./index.browser.ts";
@@ -196,8 +196,16 @@ export interface CpOptions {
196
196
  export interface MkdirOptions {
197
197
  /**
198
198
  * If true, creates parent directories as needed
199
+ *
200
+ * @default true
199
201
  */
200
202
  recursive?: boolean;
203
+ /**
204
+ * If true, does not throw an error if the directory already exists
205
+ *
206
+ * @default true
207
+ */
208
+ force?: boolean;
201
209
  /**
202
210
  * File mode (permission and sticky bits)
203
211
  */
@@ -291,8 +291,17 @@ export class NodeFileSystemProvider implements FileSystemProvider {
291
291
  * await fs.mkdir("/tmp/mydir", { mode: 0o755 });
292
292
  * ```
293
293
  */
294
- async mkdir(path: string, options?: MkdirOptions): Promise<void> {
295
- await fsMkdir(path, options);
294
+ async mkdir(path: string, options: MkdirOptions = {}): Promise<void> {
295
+ const p = fsMkdir(path, {
296
+ recursive: options.recursive ?? true,
297
+ mode: options.mode,
298
+ });
299
+
300
+ if (options.force === false) {
301
+ await p;
302
+ } else {
303
+ await p.catch(() => {});
304
+ }
296
305
  }
297
306
 
298
307
  /**
@@ -23,7 +23,7 @@ export interface BuildServerOptions {
23
23
 
24
24
  /**
25
25
  * Optional client directory name (relative to distDir).
26
- * If provided, the client template will be embedded in the server output.
26
+ * If provided, the SSR manifest will be embedded in the server output.
27
27
  */
28
28
  clientDir?: string;
29
29
 
@@ -167,16 +167,6 @@ export async function buildServer(
167
167
 
168
168
  const entryFile = extractEntryFromBundle(opts.entry, result);
169
169
 
170
- // Embed client template if client was built
171
- let template = "";
172
- if (opts.clientDir) {
173
- const index = await readFile(
174
- `${opts.distDir}/${opts.clientDir}/index.html`,
175
- "utf-8",
176
- );
177
- template = `__alepha.set("alepha.react.server.template", \`${index.replace(/>\s*</g, "><").trim()}\`);\n`;
178
- }
179
-
180
170
  // Embed SSR manifests if client was built
181
171
  // This bundles all manifest data into index.js for serverless deployments
182
172
  let manifest = "";
@@ -230,7 +220,7 @@ export async function buildServer(
230
220
 
231
221
  await writeFile(
232
222
  `${opts.distDir}/index.js`,
233
- `${warning}\n${template}${manifest}import './server/${entryFile}';\n`.trim(),
223
+ `${warning}\n${manifest}import './server/${entryFile}';\n`.trim(),
234
224
  );
235
225
 
236
226
  return { entryFile, manifest: manifestData };
@@ -63,11 +63,8 @@ export async function generateCloudflare(
63
63
  }
64
64
 
65
65
  const url = process.env.DATABASE_URL;
66
- if (url?.startsWith("cloudflare-d1:")) {
67
- const [name, id] = url
68
- .replace("cloudflare-d1://", "")
69
- .replace("cloudflare-d1:", "")
70
- .split(":");
66
+ if (url?.startsWith("d1:")) {
67
+ const [name, id] = url.replace("d1://", "").replace("d1:", "").split(":");
71
68
  wrangler.d1_databases = wrangler.d1_databases || [];
72
69
  wrangler.d1_databases.push({
73
70
  binding: name,
@@ -75,7 +72,7 @@ export async function generateCloudflare(
75
72
  database_id: id,
76
73
  });
77
74
  wrangler.vars ??= {};
78
- wrangler.vars.DATABASE_URL = `cloudflare-d1://${name}:${id}`;
75
+ wrangler.vars.DATABASE_URL = `d1://${name}:${id}`;
79
76
  }
80
77
 
81
78
  await writeFile(
@@ -102,7 +99,13 @@ export default {
102
99
 
103
100
  __alepha.set("cloudflare.env", env);
104
101
 
105
- await __alepha.start();
102
+ try {
103
+ await __alepha.start();
104
+ } catch (err) {
105
+ console.error(err);
106
+ return new Response("Internal Server Error", { status: 500 });
107
+ }
108
+
106
109
  await __alepha.events.emit("web:request", ctx);
107
110
 
108
111
  return ctx.res;
@@ -67,6 +67,10 @@ WORKDIR /app
67
67
 
68
68
  COPY . .
69
69
 
70
+ RUN ${command === "bun" ? "bun" : "npm"} install
71
+
72
+ ENV SERVER_HOST=0.0.0.0
73
+
70
74
  CMD ["${command}", "index.js"]
71
75
  `;
72
76