create-m5kdev 0.25.3 → 0.26.2

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 (143) hide show
  1. package/dist/src/create.cjs +18 -1
  2. package/dist/src/create.cjs.map +1 -1
  3. package/dist/src/fs.cjs +65 -5
  4. package/dist/src/fs.cjs.map +1 -1
  5. package/dist/src/fs.d.cts +13 -2
  6. package/dist/src/index.cjs +0 -0
  7. package/dist/src/paths.cjs +2 -2
  8. package/dist/src/prompts.cjs +22 -0
  9. package/dist/src/prompts.cjs.map +1 -1
  10. package/dist/src/runCli.cjs +13 -2
  11. package/dist/src/runCli.cjs.map +1 -1
  12. package/dist/src/types.d.cts +9 -1
  13. package/package.json +8 -6
  14. package/templates/minimal-app/.cursor/rules/frontend-data-guide.mdc +46 -3
  15. package/templates/minimal-app/.cursor/rules/module-db-guide.mdc +15 -1
  16. package/templates/minimal-app/.cursor/rules/module-dto-guide.mdc +60 -0
  17. package/templates/minimal-app/.cursor/rules/module-repository-guide.mdc +98 -193
  18. package/templates/minimal-app/.cursor/rules/module-schema-guide.mdc +53 -173
  19. package/templates/minimal-app/.cursor/rules/module-service-guide.mdc +133 -240
  20. package/templates/minimal-app/.cursor/rules/module-trpc-guide.mdc +71 -113
  21. package/templates/minimal-app/README.md.tpl +3 -3
  22. package/templates/minimal-app/apps/.gitignore.tpl +13 -0
  23. package/templates/minimal-app/apps/e2e/package.json.tpl +23 -0
  24. package/templates/minimal-app/apps/e2e/playwright.config.ts.tpl +39 -0
  25. package/templates/minimal-app/apps/e2e/playwright.expo.config.ts.tpl +38 -0
  26. package/templates/minimal-app/apps/e2e/servers.ts.tpl +100 -0
  27. package/templates/minimal-app/apps/e2e/tests/email.spec.ts.tpl +47 -0
  28. package/templates/minimal-app/apps/e2e/tests/expo-helpers.ts.tpl +73 -0
  29. package/templates/minimal-app/apps/e2e/tests/expo-standard.spec.ts.tpl +517 -0
  30. package/templates/minimal-app/apps/e2e/tests/expo-waitlist.spec.ts.tpl +94 -0
  31. package/templates/minimal-app/apps/e2e/tests/helpers.ts.tpl +289 -0
  32. package/templates/minimal-app/apps/e2e/tests/standard.spec.ts.tpl +516 -0
  33. package/templates/minimal-app/apps/e2e/tests/waitlist.spec.ts.tpl +107 -0
  34. package/templates/minimal-app/apps/e2e/tsconfig.json.tpl +10 -0
  35. package/templates/minimal-app/apps/email/package.json.tpl +34 -34
  36. package/templates/minimal-app/apps/email/src/emails/accountDeletionEmail.tsx.tpl +35 -34
  37. package/templates/minimal-app/apps/email/src/emails/organizationInviteEmail.tsx.tpl +34 -33
  38. package/templates/minimal-app/apps/email/src/emails/passwordResetEmail.tsx.tpl +35 -34
  39. package/templates/minimal-app/apps/email/src/emails/verificationEmail.tsx.tpl +37 -36
  40. package/templates/minimal-app/apps/email/src/emails/waitlistEmails.tsx.tpl +87 -0
  41. package/templates/minimal-app/apps/email/src/index.ts.tpl +72 -32
  42. package/templates/minimal-app/apps/email/src/resources.ts.tpl +65 -36
  43. package/templates/minimal-app/apps/email/tsconfig.json.tpl +16 -11
  44. package/templates/minimal-app/apps/expo/.gitignore.tpl +44 -0
  45. package/templates/minimal-app/apps/expo/.prettierignore +13 -0
  46. package/templates/minimal-app/apps/expo/.prettierrc.json.tpl +9 -0
  47. package/templates/minimal-app/apps/expo/CHANGELOG.md.tpl +156 -0
  48. package/templates/minimal-app/apps/expo/README.md.tpl +44 -0
  49. package/templates/minimal-app/apps/expo/app.json.tpl +36 -0
  50. package/templates/minimal-app/apps/expo/assets/images/adaptive-icon.png +0 -0
  51. package/templates/minimal-app/apps/expo/assets/images/favicon.png +0 -0
  52. package/templates/minimal-app/apps/expo/assets/images/icon.png +0 -0
  53. package/templates/minimal-app/apps/expo/assets/images/splash-icon.png +0 -0
  54. package/templates/minimal-app/apps/expo/eslint.config.js.tpl +8 -0
  55. package/templates/minimal-app/apps/expo/expo-env.d.ts.tpl +3 -0
  56. package/templates/minimal-app/apps/expo/metro.config.js.tpl +16 -0
  57. package/templates/minimal-app/apps/expo/package.json.tpl +59 -0
  58. package/templates/minimal-app/apps/expo/src/app/_layout.tsx.tpl +31 -0
  59. package/templates/minimal-app/apps/expo/src/app/claim-account.tsx.tpl +151 -0
  60. package/templates/minimal-app/apps/expo/src/app/forgot-password.tsx.tpl +53 -0
  61. package/templates/minimal-app/apps/expo/src/app/index.tsx.tpl +8 -0
  62. package/templates/minimal-app/apps/expo/src/app/login.tsx.tpl +71 -0
  63. package/templates/minimal-app/apps/expo/src/app/logout.tsx.tpl +19 -0
  64. package/templates/minimal-app/apps/expo/src/app/organization/accept-invitation.tsx.tpl +85 -0
  65. package/templates/minimal-app/apps/expo/src/app/posts.tsx.tpl +40 -0
  66. package/templates/minimal-app/apps/expo/src/app/reset-password.tsx.tpl +75 -0
  67. package/templates/minimal-app/apps/expo/src/app/signup.tsx.tpl +193 -0
  68. package/templates/minimal-app/apps/expo/src/components/AuthScaffold.tsx.tpl +34 -0
  69. package/templates/minimal-app/apps/expo/src/components/FormTextField.tsx.tpl +37 -0
  70. package/templates/minimal-app/apps/expo/src/components/LoadingScreen.tsx.tpl +10 -0
  71. package/templates/minimal-app/apps/expo/src/components/StatusText.tsx.tpl +22 -0
  72. package/templates/minimal-app/apps/expo/src/config.ts.tpl +9 -0
  73. package/templates/minimal-app/apps/expo/src/global.css.tpl +11 -0
  74. package/templates/minimal-app/apps/expo/src/lib/trpc.ts.tpl +20 -0
  75. package/templates/minimal-app/apps/expo/tsconfig.json.tpl +11 -0
  76. package/templates/minimal-app/apps/expo/uniwind-env.d.ts.tpl +1 -0
  77. package/templates/minimal-app/apps/expo/uniwind-types.d.ts.tpl +10 -0
  78. package/templates/minimal-app/apps/server/AGENTS.md.tpl +39 -39
  79. package/templates/minimal-app/apps/server/drizzle/0000_wealthy_absorbing_man.sql +268 -0
  80. package/templates/minimal-app/apps/server/drizzle/db.ts.tpl +26 -0
  81. package/templates/minimal-app/apps/server/drizzle/meta/0000_snapshot.json.tpl +1890 -0
  82. package/templates/minimal-app/apps/server/drizzle/meta/_journal.json.tpl +13 -0
  83. package/templates/minimal-app/apps/server/drizzle/reset.ts.tpl +33 -0
  84. package/templates/minimal-app/apps/server/drizzle/seed.e2e.ts.tpl +244 -0
  85. package/templates/minimal-app/apps/server/drizzle/seed.ts.tpl +181 -180
  86. package/templates/minimal-app/apps/server/drizzle/sync.ts.tpl +14 -21
  87. package/templates/minimal-app/apps/server/drizzle.config.ts.tpl +33 -35
  88. package/templates/minimal-app/apps/server/package.json.tpl +56 -52
  89. package/templates/minimal-app/apps/server/src/app.ts.tpl +142 -126
  90. package/templates/minimal-app/apps/server/src/index.ts.tpl +58 -58
  91. package/templates/minimal-app/apps/server/src/lib/auth.ts.tpl +12 -12
  92. package/templates/minimal-app/apps/server/src/modules/posts/posts.db.ts.tpl +25 -25
  93. package/templates/minimal-app/apps/server/src/modules/posts/posts.dto.ts.tpl +23 -0
  94. package/templates/minimal-app/apps/server/src/modules/posts/posts.grants.ts.tpl +30 -40
  95. package/templates/minimal-app/apps/server/src/modules/posts/posts.module.ts.tpl +54 -54
  96. package/templates/minimal-app/apps/server/src/modules/posts/posts.repository.ts.tpl +67 -112
  97. package/templates/minimal-app/apps/server/src/modules/posts/posts.service.ts.tpl +104 -170
  98. package/templates/minimal-app/apps/server/src/modules/posts/posts.trpc.ts.tpl +37 -48
  99. package/templates/minimal-app/apps/server/src/modules/posts/posts.utils.ts.tpl +19 -0
  100. package/templates/minimal-app/apps/server/src/modules/test-harness/test-harness.module.ts.tpl +279 -0
  101. package/templates/minimal-app/apps/server/src/schema.ts.tpl +20 -0
  102. package/templates/minimal-app/apps/server/src/types.ts.tpl +1 -1
  103. package/templates/minimal-app/apps/server/tsconfig.json.tpl +20 -14
  104. package/templates/minimal-app/apps/server/tsup.config.ts.tpl +9 -9
  105. package/templates/minimal-app/apps/shared/package.json.tpl +24 -24
  106. package/templates/minimal-app/apps/shared/src/modules/app/app.constants.ts.tpl +28 -2
  107. package/templates/minimal-app/apps/shared/src/modules/notification/notification.schema.ts.tpl +3 -3
  108. package/templates/minimal-app/apps/shared/src/modules/posts/posts.constants.ts.tpl +5 -5
  109. package/templates/minimal-app/apps/shared/src/modules/posts/posts.schema.ts.tpl +25 -76
  110. package/templates/minimal-app/apps/shared/tsconfig.json.tpl +16 -12
  111. package/templates/minimal-app/apps/webapp/index.html.tpl +22 -22
  112. package/templates/minimal-app/apps/webapp/package.json.tpl +53 -52
  113. package/templates/minimal-app/apps/webapp/public/{push-sw.js → push-sw.js.tpl} +34 -34
  114. package/templates/minimal-app/apps/webapp/src/App.tsx.tpl +44 -13
  115. package/templates/minimal-app/apps/webapp/src/Layout.tsx.tpl +18 -12
  116. package/templates/minimal-app/apps/webapp/src/Router.tsx.tpl +33 -40
  117. package/templates/minimal-app/apps/webapp/src/index.css.tpl +15 -75
  118. package/templates/minimal-app/apps/webapp/src/main.tsx.tpl +26 -26
  119. package/templates/minimal-app/apps/webapp/src/modules/posts/PostsRoute.tsx.tpl +278 -307
  120. package/templates/minimal-app/apps/webapp/src/modules/posts/components/PostCard.tsx.tpl +96 -138
  121. package/templates/minimal-app/apps/webapp/src/modules/posts/components/PostEditorModal.tsx.tpl +118 -124
  122. package/templates/minimal-app/apps/webapp/src/modules/posts/hooks/usePostActions.ts.tpl +108 -116
  123. package/templates/minimal-app/apps/webapp/src/modules/posts/hooks/usePostsList.ts.tpl +15 -9
  124. package/templates/minimal-app/apps/webapp/src/modules/posts/hooks/usePostsRoute.ts.tpl +13 -13
  125. package/templates/minimal-app/apps/webapp/src/modules/posts/posts.utils.ts.tpl +16 -16
  126. package/templates/minimal-app/apps/webapp/src/utils/i18n.ts.tpl +13 -13
  127. package/templates/minimal-app/apps/webapp/src/utils/trpc.ts.tpl +10 -6
  128. package/templates/minimal-app/apps/webapp/src/vite-env.d.ts.tpl +1 -1
  129. package/templates/minimal-app/apps/webapp/translations/{app.json.tpl → en/app.json.tpl} +7 -7
  130. package/templates/minimal-app/apps/webapp/translations/en/{blog-app.json.tpl → {{APP_SLUG}}.json.tpl} +135 -135
  131. package/templates/minimal-app/apps/webapp/tsconfig.json.tpl +17 -17
  132. package/templates/minimal-app/apps/webapp/vite.config.ts.tpl +31 -31
  133. package/templates/minimal-app/template.manifest.json +21 -0
  134. package/templates/minimal-app/apps/server/drizzle/generate-schema.ts.tpl +0 -31
  135. package/templates/minimal-app/apps/server/src/db.ts.tpl +0 -7
  136. package/templates/minimal-app/apps/server/src/generated/schema.ts.tpl +0 -13
  137. package/templates/minimal-app/apps/server/src/utils/trpc.ts.tpl +0 -8
  138. package/templates/minimal-app/apps/shared/src/modules/app/locale.constants.ts.tpl +0 -7
  139. package/templates/minimal-app/apps/shared/src/modules/app/roles.constants.ts.tpl +0 -17
  140. package/templates/minimal-app/apps/webapp/src/Providers.tsx.tpl +0 -36
  141. package/templates/minimal-app/apps/webapp/src/modules/notification/PushNotificationsPanel.tsx.tpl +0 -89
  142. package/templates/minimal-app/apps/webapp/src/navigation/navigation.config.tsx.tpl +0 -85
  143. /package/templates/minimal-app/apps/webapp/public/{logo.svg → logo.svg.tpl} +0 -0
@@ -1,18 +1,16 @@
1
1
  import { syncI18nLocale } from "@m5kdev/frontend/modules/app/utils/locale";
2
- import { useSession } from "@m5kdev/frontend/modules/auth/hooks/useSession";
3
2
  import { AuthAdminRouter } from "@m5kdev/web-ui/modules/auth/components/AuthAdminRouter";
3
+ import { AuthOrganizationAcceptInvitationRoute } from "@m5kdev/web-ui/modules/auth/components/AuthOrganizationAcceptInvitationRoute";
4
4
  import { AuthOrganizationRouter } from "@m5kdev/web-ui/modules/auth/components/AuthOrganizationRouter";
5
5
  import { AuthPublicRouter } from "@m5kdev/web-ui/modules/auth/components/AuthPublicRouter";
6
6
  import { AuthUserRouter } from "@m5kdev/web-ui/modules/auth/components/AuthUserRouter";
7
- import { BillingBetaPage } from "@m5kdev/web-ui/modules/billing/components/BillingBetaPage";
7
+ import { AuthUtilityProtectedRoutes as ProtectedRoutes } from "@m5kdev/web-ui/modules/auth/components/AuthUtilityProtectedRoutes";
8
8
  import { APP_NAME } from "{{PACKAGE_SCOPE}}/shared/modules/app/app.constants";
9
- import type { ReactNode } from "react";
10
9
  import { useTranslation } from "react-i18next";
11
- import { Navigate, Outlet, Route, Routes } from "react-router";
10
+ import { Route, Routes } from "react-router";
12
11
  import { z } from "zod";
13
12
  import { PostsRoute } from "@/modules/posts/PostsRoute";
14
13
  import { Layout } from "./Layout";
15
- import { APP_ROUTES } from "./navigation/navigation.config";
16
14
 
17
15
  const preferenceSchema = z.object({
18
16
  compactMode: z.boolean().optional(),
@@ -33,20 +31,8 @@ const preferenceControls = {
33
31
  },
34
32
  } as const;
35
33
 
36
- const toRelativePath = (path: string): string => path.replace(/^\//, "");
37
-
38
- function ProtectedRoutes({ children }: { children?: ReactNode }) {
39
- const { data: session } = useSession();
40
-
41
- if (!session) {
42
- return <Navigate to="/login" replace />;
43
- }
44
-
45
- return children ?? <Outlet />;
46
- }
47
-
48
34
  function AuthHeader() {
49
- const { t } = useTranslation("blog{{PACKAGE_SCOPE}}");
35
+ const { t } = useTranslation("{{APP_SLUG}}");
50
36
 
51
37
  return (
52
38
  <div className="text-center">
@@ -72,28 +58,35 @@ export function Router() {
72
58
  onLocaleChange: syncI18nLocale,
73
59
  })}
74
60
 
75
- <Route element={<ProtectedRoutes />}>
76
- <Route path={APP_ROUTES.home} element={<Layout />}>
77
- <Route index element={<Navigate to={APP_ROUTES.posts} replace />} />
78
- <Route path={toRelativePath(APP_ROUTES.posts)} element={<PostsRoute />} />
79
- <Route
80
- path={toRelativePath(APP_ROUTES.billing)}
81
- element={<BillingBetaPage appName={APP_NAME} />}
82
- />
83
- {AuthOrganizationRouter({
84
- schema: preferenceSchema,
85
- controls: preferenceControls,
86
- })}
87
- {AuthUserRouter({
88
- schema: preferenceSchema,
89
- controls: preferenceControls,
90
- onLocaleChange: syncI18nLocale,
91
- })}
92
- {AuthAdminRouter({
93
- enableWaitlist: true,
94
- enableAccountClaimActions: true,
95
- })}
96
- </Route>
61
+ {/* public: a logged-out invitee must reach this route so it can send
62
+ them to signup — inside ProtectedRoutes they'd bounce to /login */}
63
+ <Route
64
+ path="/organization/accept-invitation"
65
+ element={<AuthOrganizationAcceptInvitationRoute />}
66
+ />
67
+
68
+ <Route
69
+ element={
70
+ <ProtectedRoutes>
71
+ <Layout />
72
+ </ProtectedRoutes>
73
+ }
74
+ >
75
+ <Route index element={<PostsRoute />} />
76
+
77
+ {AuthUserRouter({
78
+ schema: preferenceSchema,
79
+ controls: preferenceControls,
80
+ onLocaleChange: syncI18nLocale,
81
+ })}
82
+ {AuthOrganizationRouter({
83
+ schema: preferenceSchema,
84
+ controls: preferenceControls,
85
+ })}
86
+ {AuthAdminRouter({
87
+ enableWaitlist: true,
88
+ enableAccountClaimActions: true,
89
+ })}
97
90
  </Route>
98
91
  </Routes>
99
92
  );
@@ -1,75 +1,15 @@
1
- /* biome-ignore-all lint/suspicious/noUnknownAtRules: Tailwind v4 */
2
-
3
- @import url("https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@500;600;700&family=Manrope:wght@400;500;600;700;800&display=swap");
4
- @import "tailwindcss";
5
- @import "tw-animate-css";
6
- @import "@heroui/styles";
7
-
8
- @source "./src/**/*.{ts,tsx}";
9
- @source "../../node_modules/@heroui/react/dist/**/*.{js,mjs}";
10
- @source "../../node_modules/@heroui/styles/dist/**/*.{js,mjs}";
11
- @source "../../node_modules/@m5kdev/web-ui/dist/src/**/*.{js,ts,jsx,tsx}";
12
-
13
- @custom-variant dark (&:is(.dark *));
14
-
15
- :root {
16
- --canvas: #f4ede2;
17
- --ink: #171314;
18
- --muted-ink: #6f635c;
19
- --panel: #fffaf1;
20
- --panel-strong: #f8efdf;
21
- --line: rgba(124, 93, 55, 0.18);
22
- --halo: rgba(231, 182, 100, 0.28);
23
- }
24
-
25
- .dark {
26
- --canvas: #12100f;
27
- --ink: #f7f1e8;
28
- --muted-ink: #b9aba0;
29
- --panel: #1d1917;
30
- --panel-strong: #26211f;
31
- --line: rgba(255, 240, 219, 0.12);
32
- --halo: rgba(77, 162, 143, 0.22);
33
- }
34
-
35
- @theme inline {
36
- --color-canvas: var(--canvas);
37
- --color-ink: var(--ink);
38
- --color-muted-ink: var(--muted-ink);
39
- --color-panel: var(--panel);
40
- --color-panel-strong: var(--panel-strong);
41
- --color-line: var(--line);
42
- --color-halo: var(--halo);
43
- }
44
-
45
- @layer base {
46
- * {
47
- @apply border-line;
48
- }
49
-
50
- html,
51
- body,
52
- #root {
53
- min-height: 100%;
54
- }
55
-
56
- body {
57
- @apply bg-canvas text-ink;
58
- background-image:
59
- radial-gradient(circle at top left, rgba(246, 189, 96, 0.16), transparent 28%),
60
- radial-gradient(circle at 80% 10%, rgba(31, 79, 70, 0.14), transparent 22%),
61
- linear-gradient(180deg, rgba(255, 250, 241, 0.36), rgba(244, 237, 226, 0.1));
62
- font-family: "Manrope", "Helvetica Neue", Arial, sans-serif;
63
- }
64
-
65
- button,
66
- input,
67
- textarea,
68
- select {
69
- font: inherit;
70
- }
71
- }
72
-
73
- .font-editorial {
74
- font-family: "Cormorant Garamond", Georgia, serif;
75
- }
1
+ /* biome-ignore-all lint/suspicious/noUnknownAtRules: Tailwind v4 */
2
+
3
+ @import "tailwindcss";
4
+ @import "@heroui/styles";
5
+ @import "tw-animate-css";
6
+
7
+ @source "./node_modules/@m5kdev/web-ui/dist/src/**/*.{mjs}";
8
+ @source "../node_modules/@m5kdev/web-ui/dist/src/**/*.{mjs}";
9
+ @source "../../node_modules/@m5kdev/web-ui/dist/src/**/*.{mjs}";
10
+ @source "../../../node_modules/@m5kdev/web-ui/dist/src/**/*.{mjs}";
11
+ @source "../../../../node_modules/@m5kdev/web-ui/dist/src/**/*.{mjs}";
12
+
13
+ :root {
14
+ --accent: oklch(0.6204 0.195 253.83);
15
+ }
@@ -1,26 +1,26 @@
1
- import type { PostHogConfig } from "posthog-js";
2
- import { PostHogProvider } from "posthog-js/react";
3
- import { StrictMode } from "react";
4
- import { createRoot } from "react-dom/client";
5
- import { App } from "./App";
6
- import "./index.css";
7
- import "./utils/i18n";
8
-
9
- const options = {
10
- api_host: import.meta.env.VITE_PUBLIC_POSTHOG_HOST,
11
- defaults: "2025-05-24",
12
- } satisfies Partial<PostHogConfig>;
13
-
14
- const rootElement = document.getElementById("root");
15
-
16
- if (!rootElement) {
17
- throw new Error("Root element #root not found.");
18
- }
19
-
20
- createRoot(rootElement).render(
21
- <StrictMode>
22
- <PostHogProvider apiKey={import.meta.env.VITE_PUBLIC_POSTHOG_KEY ?? "demo"} options={options}>
23
- <App />
24
- </PostHogProvider>
25
- </StrictMode>
26
- );
1
+ import type { PostHogConfig } from "posthog-js";
2
+ import { PostHogProvider } from "posthog-js/react";
3
+ import { StrictMode } from "react";
4
+ import { createRoot } from "react-dom/client";
5
+ import { App } from "./App";
6
+ import "./index.css";
7
+ import "./utils/i18n";
8
+
9
+ const options = {
10
+ api_host: import.meta.env.VITE_PUBLIC_POSTHOG_HOST,
11
+ defaults: "2025-05-24",
12
+ } satisfies Partial<PostHogConfig>;
13
+
14
+ const rootElement = document.getElementById("root");
15
+
16
+ if (!rootElement) {
17
+ throw new Error("Root element #root not found.");
18
+ }
19
+
20
+ createRoot(rootElement).render(
21
+ <StrictMode>
22
+ <PostHogProvider apiKey={import.meta.env.VITE_PUBLIC_POSTHOG_KEY ?? "demo"} options={options}>
23
+ <App />
24
+ </PostHogProvider>
25
+ </StrictMode>
26
+ );