create-mikstack 0.1.35 → 0.1.37

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.
@@ -180,6 +180,10 @@ function scaffold(config, onStatus) {
180
180
  fs.rmSync(path.join(target, "agents.md"), { force: true });
181
181
  fs.rmSync(path.join(target, ".npmrc"), { force: true });
182
182
  fs.rmSync(path.join(target, "src", "lib", "index.ts"), { force: true });
183
+ const pkgPath = path.join(target, "package.json");
184
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
185
+ delete pkg.devDependencies?.["@sveltejs/adapter-auto"];
186
+ fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
183
187
  onStatus?.("Applying templates...");
184
188
  const overlay = (dir) => {
185
189
  copyDir(dir, target);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-mikstack",
3
- "version": "0.1.35",
3
+ "version": "0.1.37",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -8,7 +8,7 @@
8
8
  "directory": "packages/create-mikstack"
9
9
  },
10
10
  "bin": {
11
- "create-mikstack": "./dist/index.js"
11
+ "create-mikstack": "./dist/index.mjs"
12
12
  },
13
13
  "files": [
14
14
  "dist",
@@ -25,7 +25,7 @@
25
25
  "test": "bun test"
26
26
  },
27
27
  "dependencies": {
28
- "@clack/prompts": "^0.10.0",
28
+ "@clack/prompts": "^1.0.0",
29
29
  "picocolors": "^1.1.1",
30
30
  "sv": "0.12.1"
31
31
  },
@@ -37,7 +37,7 @@
37
37
  "oxfmt": "^0.28.0",
38
38
  "oxlint": "^1.43.0",
39
39
  "oxlint-tsgolint": "^0.11.4",
40
- "tsdown": "^0.12.0",
40
+ "tsdown": "^0.20.0",
41
41
  "typescript": "^5.9.3"
42
42
  }
43
43
  }
@@ -40,7 +40,7 @@ services:
40
40
  BETTER_AUTH_SECRET: ${BETTER_AUTH_SECRET}
41
41
  BETTER_AUTH_URL: ${BETTER_AUTH_URL}
42
42
  ORIGIN: ${BETTER_AUTH_URL}
43
- PUBLIC_SERVER: http://zero-cache:4848
43
+ PUBLIC_SERVER: ${PUBLIC_SERVER}
44
44
  depends_on:
45
45
  - db
46
46
  - zero-cache
@@ -1,2 +1,6 @@
1
1
  # Generated
2
2
  *.gen.ts
3
+
4
+ # Editor
5
+ .vscode/*
6
+ !.vscode/extensions.json
@@ -5,6 +5,9 @@ declare global {
5
5
  interface Locals {
6
6
  user: User | null;
7
7
  session: Session | null;
8
+ // {{#if:i18n}}
9
+ locale: string;
10
+ // {{/if:i18n}}
8
11
  }
9
12
  }
10
13
  }
@@ -4,6 +4,10 @@ import { svelteKitHandler } from "better-auth/svelte-kit";
4
4
  import { building } from "$app/environment";
5
5
 
6
6
  export const handle: Handle = async ({ event, resolve }) => {
7
+ // {{#if:i18n}}
8
+ event.locals.locale = event.cookies.get("locale") ?? "en";
9
+ // {{/if:i18n}}
10
+
7
11
  const session = await auth.api.getSession({
8
12
  headers: event.request.headers,
9
13
  });
@@ -4,7 +4,7 @@ import { magicLink } from "better-auth/plugins";
4
4
  import { sveltekitCookies } from "better-auth/svelte-kit";
5
5
  import { getRequestEvent } from "$app/server";
6
6
  import { building } from "$app/environment";
7
- import { env } from "$env/dynamic/private";
7
+ import { env } from "$lib/server/env";
8
8
  import { db } from "./db";
9
9
  import * as schema from "./db/schema";
10
10
  import { notif } from "./notifications";
@@ -1,7 +1,7 @@
1
1
  import { drizzle } from "drizzle-orm/postgres-js";
2
2
  import postgres from "postgres";
3
3
  import * as schema from "./schema";
4
- import { env } from "$env/dynamic/private";
4
+ import { env } from "$lib/server/env";
5
5
 
6
6
  export type DrizzleDB = ReturnType<typeof drizzle<typeof schema>>;
7
7
 
@@ -10,7 +10,6 @@ let _db: DrizzleDB | undefined;
10
10
  export const db = new Proxy({} as DrizzleDB, {
11
11
  get(_, prop) {
12
12
  if (!_db) {
13
- if (!env.DATABASE_URL) throw new Error("DATABASE_URL is not set");
14
13
  const client = postgres(env.DATABASE_URL);
15
14
  _db = drizzle(client, { schema, casing: "snake_case" });
16
15
  }
@@ -1,10 +1,12 @@
1
- import { createTransport } from "nodemailer";
1
+ import { createTransport, type Transporter } from "nodemailer";
2
2
  import { desc, eq } from "drizzle-orm";
3
3
  import { dev } from "$app/environment";
4
- import { env } from "$env/dynamic/private";
4
+ import { env } from "$lib/server/env";
5
5
  import { db } from "../db";
6
6
  import { notificationDelivery } from "../db/schema";
7
7
 
8
+ let cachedTransport: Transporter | undefined;
9
+
8
10
  interface Email {
9
11
  subject: string;
10
12
  html: string;
@@ -58,14 +60,16 @@ export async function sendEmail(to: string, email: Email): Promise<void> {
58
60
  throw new Error("SMTP not configured. Set SMTP_HOST, SMTP_USER, and SMTP_PASS in .env");
59
61
  }
60
62
 
61
- const transport = createTransport({
62
- host,
63
- port,
64
- secure: port === 465,
65
- auth: { user, pass },
66
- });
63
+ if (!cachedTransport) {
64
+ cachedTransport = createTransport({
65
+ host,
66
+ port,
67
+ secure: port === 465,
68
+ auth: { user, pass },
69
+ });
70
+ }
67
71
 
68
- await transport.sendMail({
72
+ await cachedTransport.sendMail({
69
73
  from,
70
74
  to,
71
75
  subject: email.subject,
@@ -0,0 +1,32 @@
1
+ import { env as privateEnv } from "$env/dynamic/private";
2
+ import * as v from "valibot";
3
+
4
+ const envSchema = v.object({
5
+ DATABASE_URL: v.pipe(v.string(), v.minLength(1, "DATABASE_URL is required")),
6
+ BETTER_AUTH_SECRET: v.pipe(v.string(), v.minLength(1, "BETTER_AUTH_SECRET is required")),
7
+ BETTER_AUTH_URL: v.optional(v.string(), "http://localhost:5173"),
8
+ SMTP_HOST: v.optional(v.string()),
9
+ SMTP_PORT: v.optional(v.string()),
10
+ SMTP_USER: v.optional(v.string()),
11
+ SMTP_PASS: v.optional(v.string()),
12
+ SMTP_FROM: v.optional(v.string()),
13
+ });
14
+
15
+ const parsed = v.safeParse(envSchema, {
16
+ DATABASE_URL: privateEnv.DATABASE_URL,
17
+ BETTER_AUTH_SECRET: privateEnv.BETTER_AUTH_SECRET,
18
+ BETTER_AUTH_URL: privateEnv.BETTER_AUTH_URL || undefined,
19
+ SMTP_HOST: privateEnv.SMTP_HOST || undefined,
20
+ SMTP_PORT: privateEnv.SMTP_PORT || undefined,
21
+ SMTP_USER: privateEnv.SMTP_USER || undefined,
22
+ SMTP_PASS: privateEnv.SMTP_PASS || undefined,
23
+ SMTP_FROM: privateEnv.SMTP_FROM || undefined,
24
+ });
25
+
26
+ if (!parsed.success) {
27
+ console.error("Invalid environment variables:");
28
+ console.error(JSON.stringify(v.flatten(parsed.issues), null, 2));
29
+ throw new Error("Environment validation failed. Check the errors above.");
30
+ }
31
+
32
+ export const env = parsed.output;
@@ -24,7 +24,7 @@ export const mutators = defineMutators({
24
24
  const note = await tx.run(
25
25
  zql.note.where("id", args.id).where("userId", ctx.userID).one(),
26
26
  );
27
- if (!note) return;
27
+ if (!note) throw new Error("Note not found");
28
28
  await tx.mutate.note.update({
29
29
  id: args.id,
30
30
  title: args.title,
@@ -37,7 +37,7 @@ export const mutators = defineMutators({
37
37
  const note = await tx.run(
38
38
  zql.note.where("id", args.id).where("userId", ctx.userID).one(),
39
39
  );
40
- if (!note) return;
40
+ if (!note) throw new Error("Note not found");
41
41
  await tx.mutate.note.delete({ id: args.id });
42
42
  }),
43
43
  },
@@ -0,0 +1,5 @@
1
+ import { json } from "@sveltejs/kit";
2
+
3
+ export function GET() {
4
+ return json({ status: "ok" });
5
+ }
@@ -20,3 +20,6 @@ jobs:
20
20
  - run: bun run format:check
21
21
  - run: bun run check
22
22
  - run: bun run build
23
+ # {{#if:testing}}
24
+ - run: bun run test
25
+ # {{/if:testing}}
@@ -23,3 +23,6 @@ jobs:
23
23
  - run: npm run format:check
24
24
  - run: npm run check
25
25
  - run: npm run build
26
+ # {{#if:testing}}
27
+ - run: npm run test
28
+ # {{/if:testing}}
@@ -25,3 +25,6 @@ jobs:
25
25
  - run: pnpm run format:check
26
26
  - run: pnpm run check
27
27
  - run: pnpm run build
28
+ # {{#if:testing}}
29
+ - run: pnpm run test
30
+ # {{/if:testing}}
@@ -0,0 +1,5 @@
1
+ import type { LayoutServerLoad } from "./$types";
2
+
3
+ export const load: LayoutServerLoad = ({ locals }) => {
4
+ return { locale: locals.locale };
5
+ };
@@ -3,10 +3,13 @@
3
3
  import "../app.css";
4
4
  // {{#if:i18n}}
5
5
  import { initI18n } from "$lib/i18n";
6
- initI18n();
7
- // {{/if:i18n}}
8
6
 
7
+ let { children, data }: { children: Snippet; data: { locale: string } } = $props();
8
+ initI18n(data.locale);
9
+ // {{/if:i18n}}
10
+ // {{#if:!i18n}}
9
11
  let { children }: { children: Snippet } = $props();
12
+ // {{/if:!i18n}}
10
13
  </script>
11
14
 
12
15
  {@render children()}