startx 0.7.2 → 0.8.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 (34) hide show
  1. package/.prettierrc.js +2 -2
  2. package/.vscode/settings.json +2 -1
  3. package/apps/core-server/package.json +1 -1
  4. package/apps/core-server/src/index.ts +0 -1
  5. package/apps/startx-cli/dist/index.mjs +2 -2
  6. package/apps/startx-cli/src/commands/init.ts +183 -255
  7. package/apps/startx-cli/src/configs/files.ts +3 -4
  8. package/apps/startx-cli/src/configs/scripts.ts +24 -6
  9. package/apps/startx-cli/src/types.ts +18 -6
  10. package/apps/startx-cli/src/utils/cli-utils.ts +60 -49
  11. package/apps/startx-cli/src/utils/file-handler.ts +8 -3
  12. package/biome.json +1 -1
  13. package/configs/eslint-config/eslint.config.ts +0 -0
  14. package/configs/eslint-config/src/configs/base.ts +32 -79
  15. package/configs/eslint-config/src/configs/extend.ts +2 -2
  16. package/configs/eslint-config/src/configs/frontend.ts +29 -19
  17. package/configs/eslint-config/src/configs/node.ts +46 -6
  18. package/configs/vitest-config/package.json +3 -2
  19. package/package.json +3 -2
  20. package/packages/@repo/db/drizzle.config.ts +14 -0
  21. package/packages/@repo/db/package.json +5 -1
  22. package/packages/@repo/db/src/index.ts +1 -1
  23. package/packages/@repo/lib/src/otp-module/index.ts +6 -13
  24. package/packages/@repo/lib/tsconfig.json +2 -1
  25. package/packages/@repo/mail/eslint.config.ts +2 -2
  26. package/packages/@repo/mail/src/emails/admin/OtpEmail.tsx +3 -9
  27. package/packages/@repo/mail/src/emails/emails.ts +1 -0
  28. package/packages/@repo/mail/src/index.ts +10 -9
  29. package/packages/@repo/mail/tsconfig.json +4 -2
  30. package/packages/ui/package.json +1 -0
  31. package/packages/ui/src/components/ui/command.tsx +5 -15
  32. package/pnpm-workspace.yaml +1 -0
  33. package/turbo.json +9 -0
  34. package/apps/startx-cli/src/utils/config.ts +0 -104
@@ -11,11 +11,13 @@
11
11
  "format:check": "biome ci .",
12
12
  "lint": "eslint .",
13
13
  "lint:fix": "eslint . --fix",
14
+ "db:push": "drizzle-kit push",
14
15
  "watch": "tsc -p tsconfig.build.json --watch"
15
16
  },
16
17
  "exports": "./src/index.ts",
17
18
  "devDependencies": {
18
19
  "@types/pg": "catalog:",
20
+ "drizzle-kit": "catalog:",
19
21
  "eslint-config": "workspace:*",
20
22
  "vitest-config": "workspace:*",
21
23
  "typescript-config": "workspace:*"
@@ -30,8 +32,10 @@
30
32
  "node",
31
33
  "backend"
32
34
  ],
35
+ "gTags": [
36
+ "db"
37
+ ],
33
38
  "tags": [
34
- "db",
35
39
  "drizzle"
36
40
  ],
37
41
  "requiredDeps": [
@@ -7,7 +7,7 @@ import z from "zod";
7
7
 
8
8
  import * as schema from "./schema/index.js";
9
9
 
10
- export const env = defineEnv({
10
+ const env = defineEnv({
11
11
  DATABASE_URL: z.string(),
12
12
  });
13
13
  export const client = new Pg.Pool({
@@ -1,6 +1,6 @@
1
1
  import { ENV } from "@repo/env";
2
2
  import { logger } from "@repo/logger";
3
- import { AdminEmailTemplate } from "@repo/mail";
3
+ import { EmailTemplate } from "@repo/mail";
4
4
  import { RedisStore } from "@repo/redis";
5
5
 
6
6
  import { HashingModule } from "../hashing-module/index.js";
@@ -41,13 +41,10 @@ export class OTPModule {
41
41
  logger?.info("otp: test-mode - OTP generated", { email: normalizedEmail, otp: otpStr });
42
42
  return;
43
43
  }
44
- const html = await AdminEmailTemplate.getOtpEmail({ otp: otpStr });
45
- await SMTPMailService.sendMail(
46
- normalizedEmail,
47
- `OTP for ${normalizedEmail}`,
48
- `Your OTP is ${otpStr}`,
49
- html
50
- );
44
+ const html = await EmailTemplate("VerifyEmailOtp", {
45
+ verificationCode: otpStr,
46
+ });
47
+ await SMTPMailService.sendMail(normalizedEmail, `OTP for ${normalizedEmail}`, `Your OTP is ${otpStr}`, html);
51
48
  }
52
49
 
53
50
  static async verifyMailOTP(email: string, otp: string, deleteOtp = false): Promise<boolean> {
@@ -67,11 +64,7 @@ export class OTPModule {
67
64
  if (deleteOtp) {
68
65
  await redisOtpStore.del(normalizedEmail);
69
66
  } else {
70
- await redisOtpStore.set(
71
- normalizedEmail,
72
- { ...rows, status: "verified" },
73
- this.otpExpirationMs
74
- );
67
+ await redisOtpStore.set(normalizedEmail, { ...rows, status: "verified" }, this.otpExpirationMs);
75
68
  }
76
69
  return true;
77
70
  }
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "extends": "typescript-config/tsconfig.node.json",
3
3
  "compilerOptions": {
4
- "baseUrl": "./src"
4
+ "baseUrl": "./src",
5
+ "jsx": "react"
5
6
  },
6
7
  "include": ["src/**/*.ts"]
7
8
  }
@@ -1,4 +1,4 @@
1
- import { baseConfig } from "eslint-config/base";
1
+ import { frontendConfig } from "eslint-config/frontend";
2
2
  import { extend } from "eslint-config/extend";
3
3
 
4
- export default extend(baseConfig);
4
+ export default extend(frontendConfig);
@@ -13,12 +13,7 @@ import {
13
13
  Text,
14
14
  } from "@react-email/components";
15
15
  import React from "react";
16
-
17
- export default function VerifyEmailOtp({
18
- verificationCode = "596853",
19
- }: {
20
- verificationCode: string;
21
- }) {
16
+ export function VerifyEmailOtp({ verificationCode = "596853" }: { verificationCode: string }) {
22
17
  return (
23
18
  <Html>
24
19
  <Head>
@@ -57,9 +52,8 @@ export default function VerifyEmailOtp({
57
52
  <Hr />
58
53
  <Section style={lowerSection}>
59
54
  <Text style={cautionText}>
60
- This OTP is valid for 10 minutes. Please do not share this code with anyone for
61
- security reasons. If you did not request this, please ignore this email or contact
62
- our support team immediately.
55
+ This OTP is valid for 10 minutes. Please do not share this code with anyone for security reasons. If you
56
+ did not request this, please ignore this email or contact our support team immediately.
63
57
  </Text>
64
58
  </Section>
65
59
  </Section>
@@ -0,0 +1 @@
1
+ export * from "./admin/OtpEmail.js";
@@ -1,11 +1,12 @@
1
1
  import { render } from "@react-email/render";
2
- import VerifyEmailOtp from "./emails/admin/OtpEmail.js";
3
- export class AdminEmailTemplate {
4
- static getOtpEmail = async (props: { otp: string }) => {
5
- return await render(
6
- VerifyEmailOtp({
7
- verificationCode: props.otp,
8
- })
9
- );
10
- };
2
+ import React, { createElement } from "react";
3
+ import * as emails from "./emails/emails.js";
4
+ export type AvailableEmails = keyof typeof emails;
5
+ export type EmailProps<T extends AvailableEmails> = React.ComponentProps<(typeof emails)[T]>;
6
+
7
+ // eslint-disable-next-line @typescript-eslint/naming-convention
8
+ export function EmailTemplate<T extends AvailableEmails>(name: T, props: EmailProps<T>) {
9
+ // eslint-disable-next-line import-x/namespace
10
+ const Component = emails[name] as React.ElementType;
11
+ return render(createElement(Component, props));
11
12
  }
@@ -2,12 +2,14 @@
2
2
  "extends": "typescript-config/tsconfig.frontend.json",
3
3
  "compilerOptions": {
4
4
  "rootDir": ".",
5
- "types": ["node"],
5
+ "types": ["node", "react"],
6
6
  "baseUrl": "src",
7
7
  "jsx": "react",
8
8
  "tsBuildInfoFile": "dist/typecheck.tsbuildinfo",
9
9
  "experimentalDecorators": true,
10
- "emitDecoratorMetadata": true
10
+ "emitDecoratorMetadata": true,
11
+ "moduleResolution": "nodenext",
12
+ "module": "nodenext"
11
13
  },
12
14
  "include": ["src/**/*.ts", "src/**/*.tsx"]
13
15
  }
@@ -9,6 +9,7 @@
9
9
  "typecheck": "tsc --noEmit",
10
10
  "format": "biome format --write .",
11
11
  "format:check": "biome ci .",
12
+ "test": "vitest run",
12
13
  "lint": "eslint .",
13
14
  "lint:fix": "eslint . --fix",
14
15
  "watch": "tsc -p tsconfig.build.json --watch"
@@ -4,8 +4,9 @@ import type { DialogProps } from "@radix-ui/react-dialog";
4
4
  import { Command as CommandPrimitive } from "cmdk";
5
5
  import { Search } from "lucide-react";
6
6
  import * as React from "react";
7
- import { cn } from "../lib/utils";
7
+
8
8
  import { Dialog, DialogContent } from "./dialog";
9
+ import { cn } from "../lib/utils";
9
10
 
10
11
  const Command = React.forwardRef<
11
12
  React.ElementRef<typeof CommandPrimitive>,
@@ -70,9 +71,7 @@ CommandList.displayName = CommandPrimitive.List.displayName;
70
71
  const CommandEmpty = React.forwardRef<
71
72
  React.ElementRef<typeof CommandPrimitive.Empty>,
72
73
  React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
73
- >((props, ref) => (
74
- <CommandPrimitive.Empty ref={ref} className="py-6 text-center text-sm" {...props} />
75
- ));
74
+ >((props, ref) => <CommandPrimitive.Empty ref={ref} className="py-6 text-center text-sm" {...props} />);
76
75
 
77
76
  CommandEmpty.displayName = CommandPrimitive.Empty.displayName;
78
77
 
@@ -96,11 +95,7 @@ const CommandSeparator = React.forwardRef<
96
95
  React.ElementRef<typeof CommandPrimitive.Separator>,
97
96
  React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
98
97
  >(({ className, ...props }, ref) => (
99
- <CommandPrimitive.Separator
100
- ref={ref}
101
- className={cn("-mx-1 h-px bg-border", className)}
102
- {...props}
103
- />
98
+ <CommandPrimitive.Separator ref={ref} className={cn("-mx-1 h-px bg-border", className)} {...props} />
104
99
  ));
105
100
  CommandSeparator.displayName = CommandPrimitive.Separator.displayName;
106
101
 
@@ -122,12 +117,7 @@ const CommandItem = React.forwardRef<
122
117
  CommandItem.displayName = CommandPrimitive.Item.displayName;
123
118
 
124
119
  const CommandShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {
125
- return (
126
- <span
127
- className={cn("ml-auto text-xs tracking-widest text-muted-foreground", className)}
128
- {...props}
129
- />
130
- );
120
+ return <span className={cn("ml-auto text-xs tracking-widest text-muted-foreground", className)} {...props} />;
131
121
  };
132
122
  CommandShortcut.displayName = "CommandShortcut";
133
123
 
@@ -64,6 +64,7 @@ catalog:
64
64
 
65
65
  # db
66
66
  drizzle-orm: ^0.45.1
67
+ drizzle-kit: ^0.31.10
67
68
  pg: ^8.19.0
68
69
 
69
70
  # db types
package/turbo.json CHANGED
@@ -65,6 +65,15 @@
65
65
  },
66
66
  "deep:clean": {
67
67
  "cache": false
68
+ },
69
+ "db:push": {
70
+ "cache": false,
71
+ "interactive": true
72
+ },
73
+ "db:studio": {
74
+ "cache": false,
75
+ "interactive": false,
76
+ "persistent": true
68
77
  }
69
78
  }
70
79
  }
@@ -1,104 +0,0 @@
1
- /* eslint-disable @typescript-eslint/naming-convention */
2
-
3
- import { Packages } from "../types";
4
-
5
- export const packages = Packages({
6
- "eslint-config": {
7
- source: "./configs/eslint-config",
8
- dependencies: [],
9
- devDependencies: ["typescript-config"],
10
- optional: ["vitest-config"],
11
- dir: ["src"],
12
- file: ["plugins.d.ts"],
13
- tags: ["common"],
14
- },
15
- "typescript-config": {
16
- source: "./configs/typescript-config",
17
- dependencies: [],
18
- devDependencies: [],
19
- dir: [],
20
- files: ["tsconfig.common.json", "tsconfig.frontend.json", "tsconfig.node.json"],
21
- tags: ["required"],
22
- },
23
- "vitest-config": {
24
- source: "./configs/vitest-config",
25
- dependencies: ["typescript-config"],
26
- devDependencies: ["eslint-config"],
27
- dir: [],
28
- tags: ["required"],
29
- },
30
- "@repo/ui": {
31
- source: "./packages/ui",
32
- dependencies: [],
33
- devDependencies: ["typescript-config"],
34
- optional: ["eslint-config"],
35
- dir: [
36
- "src/components/lib",
37
- "src/components/util",
38
- "src/components/ilb",
39
- "src/components/util",
40
- "src/components/custom",
41
- "src/components/extensions",
42
- "src/components/hooks",
43
- "src/components/ui",
44
- ],
45
- files: [
46
- "components.json",
47
- "tailwind.config.ts",
48
- "postcss.config.ts",
49
- "src/globals.css",
50
- "src/lucide.ts",
51
- ],
52
- tags: ["common", "react"],
53
- },
54
- "@repo/constants": {
55
- source: "./packages/@repo/constants",
56
- dependencies: [],
57
- devDependencies: ["typescript-config"],
58
- optional: ["eslint-config"],
59
- dir: ["src"],
60
- tags: ["common"],
61
- },
62
- "@repo/env": {
63
- source: "./packages/@repo/env",
64
- dependencies: [],
65
- devDependencies: ["typescript-config"],
66
- optional: ["eslint-config", "vitest-config"],
67
- dir: ["src"],
68
- tags: ["common", "node"],
69
- },
70
- "@repo/db": {
71
- source: "./packages/@repo/db",
72
- dependencies: ["@repo/env"],
73
- devDependencies: ["typescript-config"],
74
- optional: ["eslint-config"],
75
- dir: ["src"],
76
- tags: ["common", "node"],
77
- },
78
-
79
- "@repo/lib": {
80
- source: "./packages/@repo/lib",
81
- dependencies: ["@repo/env", "@repo/mail", "@repo/db"],
82
- devDependencies: ["typescript-config"],
83
- optional: ["eslint-config", "vitest-config"],
84
- dir: ["src"],
85
- tags: ["common", "node"],
86
- },
87
-
88
- "@repo/mail": {
89
- source: "./packages/@repo/mail",
90
- dependencies: [],
91
- devDependencies: ["typescript-config"],
92
- optional: ["eslint-config"],
93
- dir: ["src"],
94
- tags: ["common", "node"],
95
- },
96
- "@repo/redis": {
97
- source: "./packages/@repo/redis",
98
- dependencies: [],
99
- devDependencies: ["typescript-config"],
100
- optional: ["eslint-config"],
101
- dir: ["src"],
102
- tags: ["common", "node", "extra"],
103
- },
104
- });