create-absolutejs 0.8.2 → 0.9.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.
Files changed (61) hide show
  1. package/LICENSE +24 -24
  2. package/README.md +179 -179
  3. package/dist/data.js +3 -0
  4. package/dist/generators/configurations/generateDrizzleConfig.js +15 -15
  5. package/dist/generators/configurations/generatePrettierrc.js +9 -9
  6. package/dist/generators/configurations/initializeRoot.js +2 -0
  7. package/dist/generators/db/dockerInitTemplates.js +79 -79
  8. package/dist/generators/db/generateDatabaseTypes.js +6 -6
  9. package/dist/generators/db/generateDockerContainer.js +19 -19
  10. package/dist/generators/db/generateDrizzleSchema.js +17 -17
  11. package/dist/generators/db/generateSqliteSchema.js +8 -8
  12. package/dist/generators/db/handlerTemplates.js +259 -259
  13. package/dist/generators/db/scaffoldDocker.js +1 -1
  14. package/dist/generators/html/generateHTMLPage.js +60 -60
  15. package/dist/generators/htmx/generateHTMXPage.js +86 -86
  16. package/dist/generators/project/generateAbsoluteAuthConfig.js +96 -96
  17. package/dist/generators/project/generateBuildBlock.d.ts +2 -1
  18. package/dist/generators/project/generateBuildBlock.js +9 -5
  19. package/dist/generators/project/generateDBBlock.js +9 -9
  20. package/dist/generators/project/generateImportsBlock.js +1 -0
  21. package/dist/generators/project/generateMarkupCSS.js +145 -145
  22. package/dist/generators/project/generateRoutesBlock.js +36 -36
  23. package/dist/generators/project/generateServer.d.ts +2 -1
  24. package/dist/generators/project/generateServer.js +29 -19
  25. package/dist/generators/project/scaffoldBackend.d.ts +2 -1
  26. package/dist/generators/project/scaffoldBackend.js +2 -1
  27. package/dist/generators/react/generateReactComponents.js +95 -95
  28. package/dist/generators/svelte/generateSveltePage.js +210 -210
  29. package/dist/generators/vue/generateVuePage.js +261 -261
  30. package/dist/messages.js +43 -43
  31. package/dist/scaffold.js +1 -0
  32. package/dist/templates/README.md +35 -35
  33. package/dist/templates/assets/svg/google-logo.svg +7 -7
  34. package/dist/templates/assets/svg/htmx-logo-black.svg +9 -9
  35. package/dist/templates/assets/svg/htmx-logo-white.svg +9 -9
  36. package/dist/templates/assets/svg/vue-logo.svg +4 -4
  37. package/dist/templates/configurations/.prettierignore +3 -3
  38. package/dist/templates/configurations/.prettierrc.json +9 -9
  39. package/dist/templates/configurations/drizzle.config.ts +13 -13
  40. package/dist/templates/configurations/eslint.config.mjs +243 -243
  41. package/dist/templates/configurations/tsconfig.example.json +98 -98
  42. package/dist/templates/constants.ts +2 -2
  43. package/dist/templates/db/docker-compose.db.yml +15 -15
  44. package/dist/templates/git/gitignore +51 -51
  45. package/dist/templates/html/scripts/typescript-example.ts +21 -21
  46. package/dist/templates/react/components/App.tsx +52 -52
  47. package/dist/templates/react/components/Head.tsx +34 -34
  48. package/dist/templates/react/components/OAuthLink.tsx +39 -39
  49. package/dist/templates/react/components/ProfilePicture.tsx +56 -56
  50. package/dist/templates/styles/colors.ts +11 -11
  51. package/dist/templates/styles/reset.css +84 -84
  52. package/dist/templates/svelte/components/Counter.svelte +19 -19
  53. package/dist/templates/svelte/composables/counter.svelte.ts +14 -14
  54. package/dist/templates/tailwind/postcss.config.ts +8 -8
  55. package/dist/templates/tailwind/tailwind.config.ts +7 -7
  56. package/dist/templates/tailwind/tailwind.css +1 -1
  57. package/dist/templates/vue/components/CountButton.vue +39 -39
  58. package/dist/templates/vue/composables/useCount.ts +14 -14
  59. package/dist/versions.d.ts +1 -1
  60. package/dist/versions.js +1 -1
  61. package/package.json +1 -1
@@ -5,65 +5,65 @@ export const generateHTMLPage = (frontends, useHTMLScripts) => {
5
5
  const scriptTagBlock = useHTMLScripts
6
6
  ? ` <script src="../scripts/typescript-example.ts"></script>\n`
7
7
  : '';
8
- return `<!doctype html>
9
- <html>
10
- <head>
11
- <title>AbsoluteJS + HTML</title>
12
- <meta name="description" content="AbsoluteJS HTML Example" />
13
- <meta charset="utf-8" />
14
- <meta name="viewport" content="width=device-width, initial-scale=1" />
15
- <link
16
- rel="stylesheet"
17
- type="text/css"
18
- href="../styles/html-example.css"
19
- />
20
- <link rel="icon" href="/assets/ico/favicon.ico" />
21
- </head>
22
- <body>
23
- <header>
24
- <a href="/">AbsoluteJS</a>
25
- <details>
26
- <summary>Pages</summary>
27
- <nav>
28
- ${navLinks}
29
- </nav>
30
- </details>
31
- </header>
32
- <main>
33
- <nav>
34
- <a href="https://absolutejs.com" target="_blank">
35
- <img
36
- class="logo"
37
- src="/assets/png/absolutejs-temp.png"
38
- alt="AbsoluteJS Logo"
39
- />
40
- </a>
41
- <a href="https://html.spec.whatwg.org/multipage/">
42
- <img
43
- class="logo html"
44
- src="/assets/svg/HTML5_Badge.svg"
45
- alt="HTML Logo"
46
- />
47
- </a>
48
- </nav>
49
- <h1>AbsoluteJS + HTML</h1>
50
- <button id="counter-button">
51
- count is <span id="counter">${initialCount}</span>
52
- </button>
53
- <p>
54
- Edit <code>example/html/pages/HtmlExample.html</code> save and
55
- rebuild to update the page.
56
- </p>
57
- <p style="color: #777">( Hot Module Reloading is coming soon )</p>
58
- <p style="margin-top: 2rem">
59
- Explore the other pages to see how AbsoluteJS seamlessly unifies
60
- multiple frameworks on a single server.
61
- </p>
62
- <p style="margin-top: 2rem; font-size: 1rem; color: #777">
63
- Click on the AbsoluteJS and HTML logos to learn more.
64
- </p>
65
- </main>
66
- ${scriptTagBlock} </body>
67
- </html>
8
+ return `<!doctype html>
9
+ <html>
10
+ <head>
11
+ <title>AbsoluteJS + HTML</title>
12
+ <meta name="description" content="AbsoluteJS HTML Example" />
13
+ <meta charset="utf-8" />
14
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
15
+ <link
16
+ rel="stylesheet"
17
+ type="text/css"
18
+ href="../styles/html-example.css"
19
+ />
20
+ <link rel="icon" href="/assets/ico/favicon.ico" />
21
+ </head>
22
+ <body>
23
+ <header>
24
+ <a href="/">AbsoluteJS</a>
25
+ <details>
26
+ <summary>Pages</summary>
27
+ <nav>
28
+ ${navLinks}
29
+ </nav>
30
+ </details>
31
+ </header>
32
+ <main>
33
+ <nav>
34
+ <a href="https://absolutejs.com" target="_blank">
35
+ <img
36
+ class="logo"
37
+ src="/assets/png/absolutejs-temp.png"
38
+ alt="AbsoluteJS Logo"
39
+ />
40
+ </a>
41
+ <a href="https://html.spec.whatwg.org/multipage/">
42
+ <img
43
+ class="logo html"
44
+ src="/assets/svg/HTML5_Badge.svg"
45
+ alt="HTML Logo"
46
+ />
47
+ </a>
48
+ </nav>
49
+ <h1>AbsoluteJS + HTML</h1>
50
+ <button id="counter-button">
51
+ count is <span id="counter">${initialCount}</span>
52
+ </button>
53
+ <p>
54
+ Edit <code>example/html/pages/HtmlExample.html</code> save and
55
+ rebuild to update the page.
56
+ </p>
57
+ <p style="color: #777">( Hot Module Reloading is coming soon )</p>
58
+ <p style="margin-top: 2rem">
59
+ Explore the other pages to see how AbsoluteJS seamlessly unifies
60
+ multiple frameworks on a single server.
61
+ </p>
62
+ <p style="margin-top: 2rem; font-size: 1rem; color: #777">
63
+ Click on the AbsoluteJS and HTML logos to learn more.
64
+ </p>
65
+ </main>
66
+ ${scriptTagBlock} </body>
67
+ </html>
68
68
  `;
69
69
  };
@@ -1,91 +1,91 @@
1
1
  import { formatNavLink } from '../../utils/formatNavLink';
2
2
  export const generateHTMXPage = (isSingle, frontends) => {
3
3
  const navLinks = frontends.map(formatNavLink).join('\n\t\t\t');
4
- return `<!doctype html>
5
- <html>
6
- <head>
7
- <title>AbsoluteJS + HTMX</title>
8
- <meta name="description" content="AbsoluteJS HTMX Example" />
9
- <meta charset="utf-8" />
10
- <meta name="viewport" content="width=device-width, initial-scale=1" />
11
- <link
12
- rel="stylesheet"
13
- type="text/css"
14
- href="../styles/htmx-example.css"
15
- />
16
- <link rel="icon" href="/assets/ico/favicon.ico" />
17
- <script src="${isSingle ? '' : '/htmx'}/htmx.min.js"></script>
18
- </head>
19
- <body
20
- hx-post="/htmx/reset"
21
- hx-trigger="beforeunload from:window once"
22
- hx-swap="none"
23
- >
24
- <header>
25
- <a href="/">AbsoluteJS</a>
26
- <details
27
- hx-on:pointerenter="this.open = true"
28
- hx-on:pointerleave="this.open = false"
29
- >
30
- <summary>Pages</summary>
31
- <nav>
32
- ${navLinks}
33
- </nav>
34
- </details>
35
- </header>
36
- <main>
37
- <nav>
38
- <a href="https://absolutejs.com" target="_blank">
39
- <img
40
- class="logo"
41
- src="/assets/png/absolutejs-temp.png"
42
- alt="AbsoluteJS Logo"
43
- />
44
- </a>
45
- <a href="https://htmx.org" target="_blank">
46
- <picture>
47
- <source
48
- srcset="/assets/svg/htmx-logo-white.svg"
49
- media="(prefers-color-scheme: dark)"
50
- />
51
-
52
- <img
53
- src="/assets/svg/htmx-logo-black.svg"
54
- alt="HTMX logo"
55
- class="logo htmx"
56
- />
57
- </picture>
58
- </a>
59
- </nav>
60
- <h1>AbsoluteJS + HTMX</h1>
61
- <button
62
- hx-post="/htmx/increment"
63
- hx-target="#count"
64
- hx-swap="innerHTML"
65
- >
66
- count is
67
- <span
68
- id="count"
69
- hx-get="/htmx/count"
70
- hx-trigger="load"
71
- hx-swap="innerHTML"
72
- >0</span
73
- >
74
- </button>
75
- <p>
76
- Edit <code>example/htmx/pages/HtmxHome.html</code> save and
77
- rebuild to update the page.
78
- </p>
79
- <p style="color: #777">( Hot Module Reloading is coming soon )</p>
80
- <p style="margin-top: 2rem">
81
- Explore the other pages to see how AbsoluteJS seamlessly unifies
82
- multiple frameworks on a single server.
83
- </p>
84
- <p style="margin-top: 2rem; font-size: 1rem; color: #777">
85
- Click on the AbsoluteJS and HTML logos to learn more.
86
- </p>
87
- </main>
88
- </body>
89
- </html>
4
+ return `<!doctype html>
5
+ <html>
6
+ <head>
7
+ <title>AbsoluteJS + HTMX</title>
8
+ <meta name="description" content="AbsoluteJS HTMX Example" />
9
+ <meta charset="utf-8" />
10
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
11
+ <link
12
+ rel="stylesheet"
13
+ type="text/css"
14
+ href="../styles/htmx-example.css"
15
+ />
16
+ <link rel="icon" href="/assets/ico/favicon.ico" />
17
+ <script src="${isSingle ? '' : '/htmx'}/htmx.min.js"></script>
18
+ </head>
19
+ <body
20
+ hx-post="/htmx/reset"
21
+ hx-trigger="beforeunload from:window once"
22
+ hx-swap="none"
23
+ >
24
+ <header>
25
+ <a href="/">AbsoluteJS</a>
26
+ <details
27
+ hx-on:pointerenter="this.open = true"
28
+ hx-on:pointerleave="this.open = false"
29
+ >
30
+ <summary>Pages</summary>
31
+ <nav>
32
+ ${navLinks}
33
+ </nav>
34
+ </details>
35
+ </header>
36
+ <main>
37
+ <nav>
38
+ <a href="https://absolutejs.com" target="_blank">
39
+ <img
40
+ class="logo"
41
+ src="/assets/png/absolutejs-temp.png"
42
+ alt="AbsoluteJS Logo"
43
+ />
44
+ </a>
45
+ <a href="https://htmx.org" target="_blank">
46
+ <picture>
47
+ <source
48
+ srcset="/assets/svg/htmx-logo-white.svg"
49
+ media="(prefers-color-scheme: dark)"
50
+ />
51
+
52
+ <img
53
+ src="/assets/svg/htmx-logo-black.svg"
54
+ alt="HTMX logo"
55
+ class="logo htmx"
56
+ />
57
+ </picture>
58
+ </a>
59
+ </nav>
60
+ <h1>AbsoluteJS + HTMX</h1>
61
+ <button
62
+ hx-post="/htmx/increment"
63
+ hx-target="#count"
64
+ hx-swap="innerHTML"
65
+ >
66
+ count is
67
+ <span
68
+ id="count"
69
+ hx-get="/htmx/count"
70
+ hx-trigger="load"
71
+ hx-swap="innerHTML"
72
+ >0</span
73
+ >
74
+ </button>
75
+ <p>
76
+ Edit <code>example/htmx/pages/HtmxHome.html</code> save and
77
+ rebuild to update the page.
78
+ </p>
79
+ <p style="color: #777">( Hot Module Reloading is coming soon )</p>
80
+ <p style="margin-top: 2rem">
81
+ Explore the other pages to see how AbsoluteJS seamlessly unifies
82
+ multiple frameworks on a single server.
83
+ </p>
84
+ <p style="margin-top: 2rem; font-size: 1rem; color: #777">
85
+ Click on the AbsoluteJS and HTML logos to learn more.
86
+ </p>
87
+ </main>
88
+ </body>
89
+ </html>
90
90
  `;
91
91
  };
@@ -27,113 +27,113 @@ export const generateAbsoluteAuthConfig = (absProviders, hasDatabase) => {
27
27
  ` redirectUri: getEnv('OAUTH2_CALLBACK_URI')`
28
28
  ].join(',\n');
29
29
  const scopePart = config.scope
30
- ? `,
30
+ ? `,
31
31
  scope: ${JSON.stringify(config.scope)}`
32
32
  : '';
33
33
  const searchParamsPart = config.searchParams && config.searchParams.length > 0
34
- ? `,
34
+ ? `,
35
35
  searchParams: ${JSON.stringify(config.searchParams)}`
36
36
  : '';
37
- return ` ${provider}: {
38
- credentials: {
39
- ${credentialsLines}
40
- }${scopePart}${searchParamsPart}
37
+ return ` ${provider}: {
38
+ credentials: {
39
+ ${credentialsLines}
40
+ }${scopePart}${searchParamsPart}
41
41
  }`;
42
42
  })
43
43
  .filter((entry) => entry !== null)
44
44
  .join(',\n');
45
45
  if (!hasDatabase) {
46
- return `import { getEnv } from '@absolutejs/absolute';
47
- import { AbsoluteAuthProps } from '@absolutejs/auth';
48
-
49
- export const absoluteAuthConfig = (): AbsoluteAuthProps => ({
50
- providersConfiguration: {
51
- ${providerConfigs}
52
- }
53
- });
46
+ return `import { getEnv } from '@absolutejs/absolute';
47
+ import { AbsoluteAuthProps } from '@absolutejs/auth';
48
+
49
+ export const absoluteAuthConfig = (): AbsoluteAuthProps => ({
50
+ providersConfiguration: {
51
+ ${providerConfigs}
52
+ }
53
+ });
54
54
  `;
55
55
  }
56
- return `import { getEnv } from '@absolutejs/absolute';
57
- import {
58
- AbsoluteAuthProps,
59
- extractPropFromIdentity,
60
- instantiateUserSession,
61
- providers
62
- } from '@absolutejs/auth';
63
- import { DatabaseType, User } from '../../types/databaseTypes';
64
- import { createUser, getUser } from '../handlers/userHandlers';
65
-
66
- export const absoluteAuthConfig = (
67
- db: DatabaseType
68
- ): AbsoluteAuthProps<User> => ({
69
- providersConfiguration: {
70
- ${providerConfigs}
71
- },
72
- onCallbackSuccess: async ({
73
- authProvider,
74
- providerInstance,
75
- tokenResponse,
76
- unregisteredSession,
77
- cookie: { user_session_id },
78
- status,
79
- session
80
- }) =>
81
- instantiateUserSession({
82
- authProvider,
83
- providerInstance,
84
- session,
85
- tokenResponse,
86
- unregisteredSession,
87
- user_session_id,
88
- getUser: async (userIdentity) => {
89
- const provider = authProvider.toUpperCase();
90
- const providerConfiguration = providers[authProvider];
91
-
92
- const subject = extractPropFromIdentity(
93
- userIdentity,
94
- providerConfiguration.subject,
95
- providerConfiguration.subjectType
96
- );
97
- const authSub = \`\${provider}|\${subject}\`;
98
-
99
- try {
100
- const user = await getUser(db, authSub);
101
-
102
- return user;
103
- } catch (error) {
104
- console.error('Error fetching user:', error);
105
- return status(
106
- 'Internal Server Error',
107
- 'Could not fetch user data.'
108
- );
109
- }
110
- },
111
- onNewUser: async (userIdentity) => {
112
- const provider = authProvider.toUpperCase();
113
- const providerConfiguration = providers[authProvider];
114
-
115
- const subject = extractPropFromIdentity(
116
- userIdentity,
117
- providerConfiguration.subject,
118
- providerConfiguration.subjectType
119
- );
120
- const authSub = \`\${provider}|\${subject}\`;
121
-
122
- try {
123
- const newUser = await createUser(db, {
124
- auth_sub: authSub,
125
- metadata: userIdentity
126
- });
127
- return newUser;
128
- } catch (error) {
129
- console.error('Error creating user:', error);
130
- return status(
131
- 'Internal Server Error',
132
- 'Could not create new user.'
133
- );
134
- }
135
- }
136
- })
137
- });
56
+ return `import { getEnv } from '@absolutejs/absolute';
57
+ import {
58
+ AbsoluteAuthProps,
59
+ extractPropFromIdentity,
60
+ instantiateUserSession,
61
+ providers
62
+ } from '@absolutejs/auth';
63
+ import { DatabaseType, User } from '../../types/databaseTypes';
64
+ import { createUser, getUser } from '../handlers/userHandlers';
65
+
66
+ export const absoluteAuthConfig = (
67
+ db: DatabaseType
68
+ ): AbsoluteAuthProps<User> => ({
69
+ providersConfiguration: {
70
+ ${providerConfigs}
71
+ },
72
+ onCallbackSuccess: async ({
73
+ authProvider,
74
+ providerInstance,
75
+ tokenResponse,
76
+ unregisteredSession,
77
+ cookie: { user_session_id },
78
+ status,
79
+ session
80
+ }) =>
81
+ instantiateUserSession({
82
+ authProvider,
83
+ providerInstance,
84
+ session,
85
+ tokenResponse,
86
+ unregisteredSession,
87
+ user_session_id,
88
+ getUser: async (userIdentity) => {
89
+ const provider = authProvider.toUpperCase();
90
+ const providerConfiguration = providers[authProvider];
91
+
92
+ const subject = extractPropFromIdentity(
93
+ userIdentity,
94
+ providerConfiguration.subject,
95
+ providerConfiguration.subjectType
96
+ );
97
+ const authSub = \`\${provider}|\${subject}\`;
98
+
99
+ try {
100
+ const user = await getUser(db, authSub);
101
+
102
+ return user;
103
+ } catch (error) {
104
+ console.error('Error fetching user:', error);
105
+ return status(
106
+ 'Internal Server Error',
107
+ 'Could not fetch user data.'
108
+ );
109
+ }
110
+ },
111
+ onNewUser: async (userIdentity) => {
112
+ const provider = authProvider.toUpperCase();
113
+ const providerConfiguration = providers[authProvider];
114
+
115
+ const subject = extractPropFromIdentity(
116
+ userIdentity,
117
+ providerConfiguration.subject,
118
+ providerConfiguration.subjectType
119
+ );
120
+ const authSub = \`\${provider}|\${subject}\`;
121
+
122
+ try {
123
+ const newUser = await createUser(db, {
124
+ auth_sub: authSub,
125
+ metadata: userIdentity
126
+ });
127
+ return newUser;
128
+ } catch (error) {
129
+ console.error('Error creating user:', error);
130
+ return status(
131
+ 'Internal Server Error',
132
+ 'Could not create new user.'
133
+ );
134
+ }
135
+ }
136
+ })
137
+ });
138
138
  `;
139
139
  };
@@ -3,7 +3,8 @@ type GenerateBuildBlockProps = {
3
3
  assetsDirectory: string;
4
4
  buildDirectory: string;
5
5
  frontendDirectories: FrontendDirectories;
6
+ publicDirectory: string;
6
7
  tailwind: CreateConfiguration['tailwind'];
7
8
  };
8
- export declare const generateBuildBlock: ({ assetsDirectory, buildDirectory, frontendDirectories, tailwind }: GenerateBuildBlockProps) => string;
9
+ export declare const generateBuildBlock: ({ assetsDirectory, buildDirectory, frontendDirectories, publicDirectory, tailwind }: GenerateBuildBlockProps) => string;
9
10
  export {};
@@ -1,13 +1,17 @@
1
- export const generateBuildBlock = ({ assetsDirectory, buildDirectory, frontendDirectories, tailwind }) => {
2
- const opts = [
1
+ export const generateBuildBlock = ({ assetsDirectory, buildDirectory, frontendDirectories, publicDirectory, tailwind }) => {
2
+ const configEntries = [
3
3
  `assetsDirectory: '${assetsDirectory}'`,
4
4
  `buildDirectory: '${buildDirectory}'`,
5
5
  ...Object.entries(frontendDirectories).map(([f, dir]) => `${f}Directory: 'src/frontend${dir ? `/${dir}` : ''}'`),
6
+ `publicDirectory: '${publicDirectory}'`,
6
7
  tailwind ? `tailwind: ${JSON.stringify(tailwind)}` : ''
7
8
  ]
8
9
  .filter(Boolean)
9
10
  .join(',\n ');
10
- const frameworks = ['react', 'svelte', 'vue'];
11
- const nonFrameworkOnly = frameworks.every((f) => frontendDirectories[f] === undefined);
12
- return `${nonFrameworkOnly ? '' : 'const manifest = '}await build({\n ${opts}\n});`;
11
+ return `const buildConfig: BuildConfig = {
12
+ ${configEntries}
13
+ };
14
+
15
+ const isDev = env.NODE_ENV === 'development';
16
+ const result = isDev ? await devBuild(buildConfig) : await build(buildConfig);`;
13
17
  };
@@ -61,19 +61,19 @@ export const generateDBBlock = ({ databaseEngine, orm, databaseHost }) => {
61
61
  return '';
62
62
  if ((databaseEngine === 'mysql' || databaseEngine === 'mariadb') &&
63
63
  databaseHost !== 'planetscale') {
64
- return `
65
- const pool = createPool(getEnv("DATABASE_URL"))
66
- const db = drizzle(pool, { schema, mode: 'default' })
64
+ return `
65
+ const pool = createPool(getEnv("DATABASE_URL"))
66
+ const db = drizzle(pool, { schema, mode: 'default' })
67
67
  `;
68
68
  }
69
69
  if (databaseEngine === 'postgresql' && databaseHost === 'neon') {
70
- return `
71
- const sql = neon(getEnv('DATABASE_URL'));
72
- const db = drizzle(sql, { schema });
70
+ return `
71
+ const sql = neon(getEnv('DATABASE_URL'));
72
+ const db = drizzle(sql, { schema });
73
73
  `;
74
74
  }
75
- return `
76
- const pool = ${expr}
77
- const db = drizzle(pool, { schema })
75
+ return `
76
+ const pool = ${expr}
77
+ const db = drizzle(pool, { schema })
78
78
  `;
79
79
  };
@@ -27,6 +27,7 @@ export const generateImportsBlock = ({ backendDirectory, deps, flags, orm, authO
27
27
  .sort()
28
28
  .join(', ')} } from '${dependency.value}'`);
29
29
  }
30
+ rawImports.push(`import { env } from 'bun'`);
30
31
  const buildExamplePath = (dir, file) => `../frontend${dir ? `/${dir}` : ''}/pages/${file}`;
31
32
  const reactDir = frontendDirectories.react;
32
33
  const svelteDir = frontendDirectories.svelte;