create-rudder-app 0.0.28 → 0.0.30
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.
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/templates.d.ts +1 -0
- package/dist/templates.d.ts.map +1 -1
- package/dist/templates.js +602 -165
- package/dist/templates.js.map +1 -1
- package/package.json +2 -2
package/dist/templates.js
CHANGED
|
@@ -72,9 +72,7 @@ export function getTemplates(ctx) {
|
|
|
72
72
|
files['prisma/schema/todo.prisma'] = prismaTodo();
|
|
73
73
|
files['prisma/schema/modules.prisma'] = '// <rudderjs:modules:start>\n// <rudderjs:modules:end>\n';
|
|
74
74
|
}
|
|
75
|
-
|
|
76
|
-
files['src/index.css'] = indexCss(ctx);
|
|
77
|
-
}
|
|
75
|
+
files['src/index.css'] = indexCss(ctx);
|
|
78
76
|
files['bootstrap/app.ts'] = bootstrapApp(ctx);
|
|
79
77
|
files['bootstrap/providers.ts'] = bootstrapProviders(ctx);
|
|
80
78
|
// Config files — always generated
|
|
@@ -106,6 +104,8 @@ export function getTemplates(ctx) {
|
|
|
106
104
|
files['config/passport.ts'] = configPassport();
|
|
107
105
|
if (ctx.packages.localization)
|
|
108
106
|
files['config/localization.ts'] = configLocalization();
|
|
107
|
+
if (ctx.packages.telescope)
|
|
108
|
+
files['config/telescope.ts'] = configTelescope();
|
|
109
109
|
files['config/index.ts'] = configIndex(ctx);
|
|
110
110
|
files['env.d.ts'] = envDts();
|
|
111
111
|
if (ctx.packages.auth && ctx.orm)
|
|
@@ -272,6 +272,8 @@ function packageJson(ctx) {
|
|
|
272
272
|
deps['@rudderjs/passport'] = 'latest';
|
|
273
273
|
if (ctx.packages.localization)
|
|
274
274
|
deps['@rudderjs/localization'] = 'latest';
|
|
275
|
+
if (ctx.packages.telescope)
|
|
276
|
+
deps['@rudderjs/telescope'] = 'latest';
|
|
275
277
|
const devDeps = {
|
|
276
278
|
'@rudderjs/cli': 'latest',
|
|
277
279
|
'@types/node': '^20.0.0',
|
|
@@ -652,10 +654,14 @@ model Todo {
|
|
|
652
654
|
}
|
|
653
655
|
// ─── src/index.css ─────────────────────────────────────────
|
|
654
656
|
function indexCss(ctx) {
|
|
657
|
+
if (!ctx.tailwind) {
|
|
658
|
+
return indexCssPlain();
|
|
659
|
+
}
|
|
655
660
|
if (!ctx.shadcn) {
|
|
656
661
|
return `@import "tailwindcss";
|
|
657
662
|
@import "tw-animate-css";
|
|
658
|
-
|
|
663
|
+
|
|
664
|
+
${semanticRulesApply()}`;
|
|
659
665
|
}
|
|
660
666
|
return `@import "tailwindcss";
|
|
661
667
|
@import "tw-animate-css";
|
|
@@ -781,6 +787,444 @@ function indexCss(ctx) {
|
|
|
781
787
|
@apply bg-background text-foreground;
|
|
782
788
|
}
|
|
783
789
|
}
|
|
790
|
+
|
|
791
|
+
${semanticRulesApply()}`;
|
|
792
|
+
}
|
|
793
|
+
function semanticRulesApply() {
|
|
794
|
+
return `/* ─── Scaffolded view classes ────────────────────────────────
|
|
795
|
+
Semantic classes shared by app/Views/Welcome and vendored
|
|
796
|
+
@rudderjs/auth views. The --no-tailwind variant of this
|
|
797
|
+
scaffolder emits equivalent hand-authored CSS under the
|
|
798
|
+
same selectors. */
|
|
799
|
+
|
|
800
|
+
.page {
|
|
801
|
+
@apply min-h-svh bg-gradient-to-b from-white to-zinc-50 text-zinc-900 dark:from-zinc-950 dark:to-black dark:text-zinc-100;
|
|
802
|
+
}
|
|
803
|
+
.page-nav {
|
|
804
|
+
@apply mx-auto flex max-w-6xl items-center justify-between px-6 py-5;
|
|
805
|
+
}
|
|
806
|
+
.page-footer {
|
|
807
|
+
@apply border-t border-zinc-200 dark:border-zinc-900;
|
|
808
|
+
}
|
|
809
|
+
.footer-inner {
|
|
810
|
+
@apply mx-auto flex max-w-6xl flex-col items-center gap-3 px-6 py-6 text-xs text-zinc-500 sm:flex-row sm:justify-between;
|
|
811
|
+
}
|
|
812
|
+
.footer-links {
|
|
813
|
+
@apply flex gap-4;
|
|
814
|
+
}
|
|
815
|
+
.footer-link {
|
|
816
|
+
@apply transition-colors hover:text-zinc-900 dark:hover:text-zinc-100;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
.brand {
|
|
820
|
+
@apply flex items-center gap-2 text-sm font-semibold tracking-tight;
|
|
821
|
+
}
|
|
822
|
+
.brand-dot {
|
|
823
|
+
@apply inline-block h-2 w-2 rounded-full bg-emerald-500;
|
|
824
|
+
}
|
|
825
|
+
.nav-right {
|
|
826
|
+
@apply flex items-center gap-4 text-sm;
|
|
827
|
+
}
|
|
828
|
+
.nav-badge {
|
|
829
|
+
@apply text-zinc-500 dark:text-zinc-400;
|
|
830
|
+
}
|
|
831
|
+
.nav-badge strong {
|
|
832
|
+
@apply font-medium text-zinc-900 dark:text-zinc-100;
|
|
833
|
+
}
|
|
834
|
+
.nav-button {
|
|
835
|
+
@apply rounded-md border border-zinc-200 px-3 py-1.5 text-xs font-medium text-zinc-700 transition-colors hover:bg-zinc-100 dark:border-zinc-800 dark:text-zinc-300 dark:hover:bg-zinc-900;
|
|
836
|
+
}
|
|
837
|
+
.nav-link {
|
|
838
|
+
@apply text-zinc-500 transition-colors hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-zinc-100;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
.hero {
|
|
842
|
+
@apply mx-auto max-w-3xl px-6 pb-12 pt-20 text-center;
|
|
843
|
+
}
|
|
844
|
+
.hero-title {
|
|
845
|
+
@apply text-5xl font-bold tracking-tight sm:text-6xl;
|
|
846
|
+
}
|
|
847
|
+
.hero-lead {
|
|
848
|
+
@apply mt-6 text-lg text-zinc-600 dark:text-zinc-400;
|
|
849
|
+
}
|
|
850
|
+
.hero-meta {
|
|
851
|
+
@apply mt-8 flex items-center justify-center gap-3 text-xs text-zinc-500;
|
|
852
|
+
}
|
|
853
|
+
.inline-code {
|
|
854
|
+
@apply rounded bg-zinc-100 px-1.5 py-0.5 text-sm dark:bg-zinc-900;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
.feature-section {
|
|
858
|
+
@apply mx-auto max-w-6xl px-6 pb-20;
|
|
859
|
+
}
|
|
860
|
+
.feature-grid {
|
|
861
|
+
@apply grid gap-4 md:grid-cols-2 lg:grid-cols-3;
|
|
862
|
+
}
|
|
863
|
+
.feature-card {
|
|
864
|
+
@apply rounded-xl border border-zinc-200 bg-white p-6 transition-colors hover:border-zinc-900 dark:border-zinc-800 dark:bg-zinc-950 dark:hover:border-zinc-100;
|
|
865
|
+
}
|
|
866
|
+
.feature-title {
|
|
867
|
+
@apply font-semibold;
|
|
868
|
+
}
|
|
869
|
+
.feature-desc {
|
|
870
|
+
@apply mt-2 text-sm text-zinc-600 dark:text-zinc-400;
|
|
871
|
+
}
|
|
872
|
+
.feature-card:hover .feature-desc {
|
|
873
|
+
@apply text-zinc-900 dark:text-zinc-100;
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
/* Auth forms + error page (reused selectors) */
|
|
877
|
+
.auth-wrap {
|
|
878
|
+
@apply flex min-h-svh items-center justify-center p-4;
|
|
879
|
+
}
|
|
880
|
+
.auth-card {
|
|
881
|
+
@apply w-full max-w-sm space-y-6;
|
|
882
|
+
}
|
|
883
|
+
.auth-head {
|
|
884
|
+
@apply text-center;
|
|
885
|
+
}
|
|
886
|
+
.heading-lg {
|
|
887
|
+
@apply text-2xl font-bold;
|
|
888
|
+
}
|
|
889
|
+
.muted {
|
|
890
|
+
@apply text-sm text-zinc-500 dark:text-zinc-400;
|
|
891
|
+
}
|
|
892
|
+
.form-card {
|
|
893
|
+
@apply space-y-4 rounded-lg border border-zinc-200 p-6 shadow-sm dark:border-zinc-800;
|
|
894
|
+
}
|
|
895
|
+
.form-error {
|
|
896
|
+
@apply rounded-md bg-red-50 px-3 py-2 text-sm text-red-600 dark:bg-red-950 dark:text-red-400;
|
|
897
|
+
}
|
|
898
|
+
.form-success {
|
|
899
|
+
@apply rounded-md bg-green-50 px-3 py-2 text-sm text-green-600 dark:bg-green-950 dark:text-green-400;
|
|
900
|
+
}
|
|
901
|
+
.form-label {
|
|
902
|
+
@apply block text-sm font-medium mb-1;
|
|
903
|
+
}
|
|
904
|
+
.form-input {
|
|
905
|
+
@apply w-full rounded-md border border-zinc-200 px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-zinc-900 dark:border-zinc-800 dark:bg-zinc-950 dark:focus:ring-zinc-100;
|
|
906
|
+
}
|
|
907
|
+
.form-submit {
|
|
908
|
+
@apply w-full rounded-md bg-zinc-900 px-4 py-2 text-sm font-medium text-white transition-opacity hover:opacity-90 disabled:opacity-50 dark:bg-zinc-100 dark:text-zinc-900;
|
|
909
|
+
}
|
|
910
|
+
.form-link-row {
|
|
911
|
+
@apply flex items-center justify-between text-sm text-zinc-500 dark:text-zinc-400;
|
|
912
|
+
}
|
|
913
|
+
.auth-link {
|
|
914
|
+
@apply underline transition-colors hover:text-zinc-900 dark:hover:text-zinc-100;
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
.error-wrap {
|
|
918
|
+
@apply flex min-h-svh flex-col items-center justify-center gap-2;
|
|
919
|
+
}
|
|
920
|
+
.error-link {
|
|
921
|
+
@apply mt-4 text-sm underline transition-colors hover:text-zinc-900 dark:hover:text-zinc-100;
|
|
922
|
+
}
|
|
923
|
+
`;
|
|
924
|
+
}
|
|
925
|
+
function indexCssPlain() {
|
|
926
|
+
return `:root {
|
|
927
|
+
--bg-start: #ffffff;
|
|
928
|
+
--bg-end: #fafafa;
|
|
929
|
+
--fg: #18181b;
|
|
930
|
+
--fg-muted: #52525b;
|
|
931
|
+
--fg-strong: #09090b;
|
|
932
|
+
--border: #e4e4e7;
|
|
933
|
+
--surface: #ffffff;
|
|
934
|
+
--surface-muted: #f4f4f5;
|
|
935
|
+
--accent: #10b981;
|
|
936
|
+
--danger-bg: #fef2f2;
|
|
937
|
+
--danger-fg: #dc2626;
|
|
938
|
+
--success-bg: #f0fdf4;
|
|
939
|
+
--success-fg: #16a34a;
|
|
940
|
+
}
|
|
941
|
+
@media (prefers-color-scheme: dark) {
|
|
942
|
+
:root {
|
|
943
|
+
--bg-start: #09090b;
|
|
944
|
+
--bg-end: #000000;
|
|
945
|
+
--fg: #fafafa;
|
|
946
|
+
--fg-muted: #a1a1aa;
|
|
947
|
+
--fg-strong: #ffffff;
|
|
948
|
+
--border: #27272a;
|
|
949
|
+
--surface: #09090b;
|
|
950
|
+
--surface-muted: #18181b;
|
|
951
|
+
--danger-bg: #450a0a;
|
|
952
|
+
--danger-fg: #f87171;
|
|
953
|
+
--success-bg: #052e16;
|
|
954
|
+
--success-fg: #4ade80;
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
*, *::before, *::after { box-sizing: border-box; }
|
|
959
|
+
html, body { margin: 0; padding: 0; }
|
|
960
|
+
body {
|
|
961
|
+
background: linear-gradient(to bottom, var(--bg-start), var(--bg-end));
|
|
962
|
+
color: var(--fg);
|
|
963
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
|
|
964
|
+
min-height: 100vh;
|
|
965
|
+
-webkit-font-smoothing: antialiased;
|
|
966
|
+
}
|
|
967
|
+
a { color: inherit; }
|
|
968
|
+
|
|
969
|
+
/* Layout */
|
|
970
|
+
.page { min-height: 100svh; }
|
|
971
|
+
.page-nav {
|
|
972
|
+
max-width: 72rem;
|
|
973
|
+
margin: 0 auto;
|
|
974
|
+
padding: 1.25rem 1.5rem;
|
|
975
|
+
display: flex;
|
|
976
|
+
align-items: center;
|
|
977
|
+
justify-content: space-between;
|
|
978
|
+
}
|
|
979
|
+
.page-footer {
|
|
980
|
+
border-top: 1px solid var(--border);
|
|
981
|
+
}
|
|
982
|
+
.footer-inner {
|
|
983
|
+
max-width: 72rem;
|
|
984
|
+
margin: 0 auto;
|
|
985
|
+
padding: 1.5rem;
|
|
986
|
+
display: flex;
|
|
987
|
+
flex-direction: column;
|
|
988
|
+
align-items: center;
|
|
989
|
+
gap: 0.75rem;
|
|
990
|
+
font-size: 0.75rem;
|
|
991
|
+
color: var(--fg-muted);
|
|
992
|
+
}
|
|
993
|
+
@media (min-width: 640px) {
|
|
994
|
+
.footer-inner { flex-direction: row; justify-content: space-between; }
|
|
995
|
+
}
|
|
996
|
+
.footer-links { display: flex; gap: 1rem; }
|
|
997
|
+
.footer-link {
|
|
998
|
+
text-decoration: none;
|
|
999
|
+
transition: color 150ms;
|
|
1000
|
+
}
|
|
1001
|
+
.footer-link:hover { color: var(--fg-strong); }
|
|
1002
|
+
|
|
1003
|
+
/* Welcome */
|
|
1004
|
+
.brand {
|
|
1005
|
+
display: flex;
|
|
1006
|
+
align-items: center;
|
|
1007
|
+
gap: 0.5rem;
|
|
1008
|
+
font-size: 0.875rem;
|
|
1009
|
+
font-weight: 600;
|
|
1010
|
+
letter-spacing: -0.01em;
|
|
1011
|
+
}
|
|
1012
|
+
.brand-dot {
|
|
1013
|
+
display: inline-block;
|
|
1014
|
+
width: 0.5rem;
|
|
1015
|
+
height: 0.5rem;
|
|
1016
|
+
border-radius: 9999px;
|
|
1017
|
+
background: var(--accent);
|
|
1018
|
+
}
|
|
1019
|
+
.nav-right {
|
|
1020
|
+
display: flex;
|
|
1021
|
+
align-items: center;
|
|
1022
|
+
gap: 1rem;
|
|
1023
|
+
font-size: 0.875rem;
|
|
1024
|
+
}
|
|
1025
|
+
.nav-badge { color: var(--fg-muted); }
|
|
1026
|
+
.nav-badge strong { color: var(--fg-strong); font-weight: 500; }
|
|
1027
|
+
.nav-button {
|
|
1028
|
+
display: inline-block;
|
|
1029
|
+
border: 1px solid var(--border);
|
|
1030
|
+
border-radius: 0.375rem;
|
|
1031
|
+
padding: 0.375rem 0.75rem;
|
|
1032
|
+
font-size: 0.75rem;
|
|
1033
|
+
font-weight: 500;
|
|
1034
|
+
color: var(--fg);
|
|
1035
|
+
background: transparent;
|
|
1036
|
+
cursor: pointer;
|
|
1037
|
+
text-decoration: none;
|
|
1038
|
+
transition: background-color 150ms;
|
|
1039
|
+
}
|
|
1040
|
+
.nav-button:hover { background: var(--surface-muted); }
|
|
1041
|
+
.nav-link {
|
|
1042
|
+
color: var(--fg-muted);
|
|
1043
|
+
text-decoration: none;
|
|
1044
|
+
transition: color 150ms;
|
|
1045
|
+
}
|
|
1046
|
+
.nav-link:hover { color: var(--fg-strong); }
|
|
1047
|
+
|
|
1048
|
+
.hero {
|
|
1049
|
+
max-width: 48rem;
|
|
1050
|
+
margin: 0 auto;
|
|
1051
|
+
padding: 5rem 1.5rem 3rem;
|
|
1052
|
+
text-align: center;
|
|
1053
|
+
}
|
|
1054
|
+
.hero-title {
|
|
1055
|
+
font-size: 3rem;
|
|
1056
|
+
font-weight: 700;
|
|
1057
|
+
letter-spacing: -0.02em;
|
|
1058
|
+
margin: 0;
|
|
1059
|
+
}
|
|
1060
|
+
@media (min-width: 640px) {
|
|
1061
|
+
.hero-title { font-size: 3.75rem; }
|
|
1062
|
+
}
|
|
1063
|
+
.hero-lead {
|
|
1064
|
+
margin: 1.5rem 0 0;
|
|
1065
|
+
font-size: 1.125rem;
|
|
1066
|
+
color: var(--fg-muted);
|
|
1067
|
+
line-height: 1.6;
|
|
1068
|
+
}
|
|
1069
|
+
.hero-meta {
|
|
1070
|
+
margin-top: 2rem;
|
|
1071
|
+
display: flex;
|
|
1072
|
+
align-items: center;
|
|
1073
|
+
justify-content: center;
|
|
1074
|
+
gap: 0.75rem;
|
|
1075
|
+
font-size: 0.75rem;
|
|
1076
|
+
color: var(--fg-muted);
|
|
1077
|
+
}
|
|
1078
|
+
.inline-code {
|
|
1079
|
+
background: var(--surface-muted);
|
|
1080
|
+
padding: 0.125rem 0.375rem;
|
|
1081
|
+
border-radius: 0.25rem;
|
|
1082
|
+
font-size: 0.875rem;
|
|
1083
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
.feature-section {
|
|
1087
|
+
max-width: 72rem;
|
|
1088
|
+
margin: 0 auto;
|
|
1089
|
+
padding: 0 1.5rem 5rem;
|
|
1090
|
+
}
|
|
1091
|
+
.feature-grid {
|
|
1092
|
+
display: grid;
|
|
1093
|
+
gap: 1rem;
|
|
1094
|
+
}
|
|
1095
|
+
@media (min-width: 768px) { .feature-grid { grid-template-columns: repeat(2, 1fr); } }
|
|
1096
|
+
@media (min-width: 1024px) { .feature-grid { grid-template-columns: repeat(3, 1fr); } }
|
|
1097
|
+
.feature-card {
|
|
1098
|
+
display: block;
|
|
1099
|
+
border: 1px solid var(--border);
|
|
1100
|
+
background: var(--surface);
|
|
1101
|
+
border-radius: 0.75rem;
|
|
1102
|
+
padding: 1.5rem;
|
|
1103
|
+
text-decoration: none;
|
|
1104
|
+
color: inherit;
|
|
1105
|
+
transition: border-color 150ms, color 150ms;
|
|
1106
|
+
}
|
|
1107
|
+
.feature-card:hover { border-color: var(--fg-strong); }
|
|
1108
|
+
.feature-title { font-weight: 600; margin: 0; }
|
|
1109
|
+
.feature-desc {
|
|
1110
|
+
margin: 0.5rem 0 0;
|
|
1111
|
+
font-size: 0.875rem;
|
|
1112
|
+
color: var(--fg-muted);
|
|
1113
|
+
}
|
|
1114
|
+
.feature-card:hover .feature-desc { color: var(--fg-strong); }
|
|
1115
|
+
|
|
1116
|
+
/* Auth forms + error page */
|
|
1117
|
+
.auth-wrap {
|
|
1118
|
+
display: flex;
|
|
1119
|
+
min-height: 100svh;
|
|
1120
|
+
align-items: center;
|
|
1121
|
+
justify-content: center;
|
|
1122
|
+
padding: 1rem;
|
|
1123
|
+
}
|
|
1124
|
+
.auth-card {
|
|
1125
|
+
width: 100%;
|
|
1126
|
+
max-width: 24rem;
|
|
1127
|
+
display: flex;
|
|
1128
|
+
flex-direction: column;
|
|
1129
|
+
gap: 1.5rem;
|
|
1130
|
+
}
|
|
1131
|
+
.auth-head { text-align: center; }
|
|
1132
|
+
.heading-lg { font-size: 1.5rem; font-weight: 700; margin: 0; }
|
|
1133
|
+
.muted { font-size: 0.875rem; color: var(--fg-muted); margin: 0; }
|
|
1134
|
+
.auth-head .muted { margin-top: 0.25rem; }
|
|
1135
|
+
|
|
1136
|
+
.form-card {
|
|
1137
|
+
display: flex;
|
|
1138
|
+
flex-direction: column;
|
|
1139
|
+
gap: 1rem;
|
|
1140
|
+
border: 1px solid var(--border);
|
|
1141
|
+
border-radius: 0.5rem;
|
|
1142
|
+
padding: 1.5rem;
|
|
1143
|
+
background: var(--surface);
|
|
1144
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
1145
|
+
}
|
|
1146
|
+
.form-error {
|
|
1147
|
+
background: var(--danger-bg);
|
|
1148
|
+
color: var(--danger-fg);
|
|
1149
|
+
font-size: 0.875rem;
|
|
1150
|
+
padding: 0.5rem 0.75rem;
|
|
1151
|
+
border-radius: 0.375rem;
|
|
1152
|
+
margin: 0;
|
|
1153
|
+
}
|
|
1154
|
+
.form-success {
|
|
1155
|
+
background: var(--success-bg);
|
|
1156
|
+
color: var(--success-fg);
|
|
1157
|
+
font-size: 0.875rem;
|
|
1158
|
+
padding: 0.5rem 0.75rem;
|
|
1159
|
+
border-radius: 0.375rem;
|
|
1160
|
+
margin: 0;
|
|
1161
|
+
}
|
|
1162
|
+
.form-label {
|
|
1163
|
+
display: block;
|
|
1164
|
+
font-size: 0.875rem;
|
|
1165
|
+
font-weight: 500;
|
|
1166
|
+
margin-bottom: 0.25rem;
|
|
1167
|
+
}
|
|
1168
|
+
.form-input {
|
|
1169
|
+
display: block;
|
|
1170
|
+
width: 100%;
|
|
1171
|
+
border: 1px solid var(--border);
|
|
1172
|
+
border-radius: 0.375rem;
|
|
1173
|
+
padding: 0.5rem 0.75rem;
|
|
1174
|
+
font-size: 0.875rem;
|
|
1175
|
+
background: var(--surface);
|
|
1176
|
+
color: var(--fg);
|
|
1177
|
+
outline: none;
|
|
1178
|
+
transition: box-shadow 150ms, border-color 150ms;
|
|
1179
|
+
}
|
|
1180
|
+
.form-input:focus {
|
|
1181
|
+
border-color: var(--fg-strong);
|
|
1182
|
+
box-shadow: 0 0 0 2px var(--fg-strong);
|
|
1183
|
+
}
|
|
1184
|
+
.form-submit {
|
|
1185
|
+
width: 100%;
|
|
1186
|
+
background: var(--fg-strong);
|
|
1187
|
+
color: var(--bg-start);
|
|
1188
|
+
border: 0;
|
|
1189
|
+
border-radius: 0.375rem;
|
|
1190
|
+
padding: 0.625rem 1rem;
|
|
1191
|
+
font-size: 0.875rem;
|
|
1192
|
+
font-weight: 500;
|
|
1193
|
+
cursor: pointer;
|
|
1194
|
+
transition: opacity 150ms;
|
|
1195
|
+
}
|
|
1196
|
+
.form-submit:hover { opacity: 0.9; }
|
|
1197
|
+
.form-submit:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
1198
|
+
.form-link-row {
|
|
1199
|
+
display: flex;
|
|
1200
|
+
align-items: center;
|
|
1201
|
+
justify-content: space-between;
|
|
1202
|
+
font-size: 0.875rem;
|
|
1203
|
+
color: var(--fg-muted);
|
|
1204
|
+
}
|
|
1205
|
+
.auth-link {
|
|
1206
|
+
text-decoration: underline;
|
|
1207
|
+
transition: color 150ms;
|
|
1208
|
+
}
|
|
1209
|
+
.auth-link:hover { color: var(--fg-strong); }
|
|
1210
|
+
|
|
1211
|
+
.error-wrap {
|
|
1212
|
+
display: flex;
|
|
1213
|
+
min-height: 100svh;
|
|
1214
|
+
flex-direction: column;
|
|
1215
|
+
align-items: center;
|
|
1216
|
+
justify-content: center;
|
|
1217
|
+
gap: 0.5rem;
|
|
1218
|
+
padding: 1rem;
|
|
1219
|
+
text-align: center;
|
|
1220
|
+
}
|
|
1221
|
+
.error-link {
|
|
1222
|
+
margin-top: 1rem;
|
|
1223
|
+
font-size: 0.875rem;
|
|
1224
|
+
text-decoration: underline;
|
|
1225
|
+
transition: color 150ms;
|
|
1226
|
+
}
|
|
1227
|
+
.error-link:hover { color: var(--fg-strong); }
|
|
784
1228
|
`;
|
|
785
1229
|
}
|
|
786
1230
|
// ─── bootstrap/app.ts ──────────────────────────────────────
|
|
@@ -1135,6 +1579,10 @@ function configIndex(ctx) {
|
|
|
1135
1579
|
imports.push("import localization from './localization.js'");
|
|
1136
1580
|
keys.push('localization');
|
|
1137
1581
|
}
|
|
1582
|
+
if (ctx.packages.telescope) {
|
|
1583
|
+
imports.push("import telescope from './telescope.js'");
|
|
1584
|
+
keys.push('telescope');
|
|
1585
|
+
}
|
|
1138
1586
|
return `${imports.join('\n')}
|
|
1139
1587
|
|
|
1140
1588
|
const configs = { ${keys.join(', ')} }
|
|
@@ -1251,6 +1699,30 @@ export default {
|
|
|
1251
1699
|
} satisfies LocalizationConfig
|
|
1252
1700
|
`;
|
|
1253
1701
|
}
|
|
1702
|
+
function configTelescope() {
|
|
1703
|
+
return `import type { TelescopeConfig } from '@rudderjs/telescope'
|
|
1704
|
+
|
|
1705
|
+
// Debug dashboard mounted at /telescope. 18 collectors record requests, queries,
|
|
1706
|
+
// jobs, exceptions, logs, mail, events, cache, schedule, models, commands,
|
|
1707
|
+
// broadcasts, live, HTTP client, gate checks, dumps, AI runs, and MCP calls.
|
|
1708
|
+
//
|
|
1709
|
+
// Storage defaults to in-memory (bounded, no extra deps). Switch to 'sqlite'
|
|
1710
|
+
// for persistence across restarts — install better-sqlite3 first:
|
|
1711
|
+
// pnpm add -D better-sqlite3
|
|
1712
|
+
//
|
|
1713
|
+
// In production, gate access by returning \`false\` from \`auth(req)\` or simply
|
|
1714
|
+
// disable by setting \`enabled: false\` via an env var.
|
|
1715
|
+
export default {
|
|
1716
|
+
enabled: true,
|
|
1717
|
+
path: 'telescope',
|
|
1718
|
+
storage: 'memory',
|
|
1719
|
+
maxEntries: 1000,
|
|
1720
|
+
pruneAfterHours: 24,
|
|
1721
|
+
slowQueryThreshold: 100,
|
|
1722
|
+
ignoreRequests: ['/telescope*', '/health', '/@*'],
|
|
1723
|
+
} satisfies TelescopeConfig
|
|
1724
|
+
`;
|
|
1725
|
+
}
|
|
1254
1726
|
// ─── app files ─────────────────────────────────────────────
|
|
1255
1727
|
function userModel() {
|
|
1256
1728
|
return `import { Model } from '@rudderjs/orm'
|
|
@@ -1681,7 +2153,7 @@ function pagesIndexPage(ctx) {
|
|
|
1681
2153
|
}
|
|
1682
2154
|
}
|
|
1683
2155
|
function pagesIndexPageReact(ctx) {
|
|
1684
|
-
const cssImport =
|
|
2156
|
+
const cssImport = `import '@/index.css'\n`;
|
|
1685
2157
|
const extraLinks = [];
|
|
1686
2158
|
if (ctx.withTodo)
|
|
1687
2159
|
extraLinks.push(' <a href="/todos" className="underline hover:text-foreground">Todos</a>');
|
|
@@ -1766,7 +2238,7 @@ ${todosLink}
|
|
|
1766
2238
|
`;
|
|
1767
2239
|
}
|
|
1768
2240
|
function pagesIndexPageVue(ctx) {
|
|
1769
|
-
const cssImport =
|
|
2241
|
+
const cssImport = `import '@/index.css'\n`;
|
|
1770
2242
|
const extraLinks = [];
|
|
1771
2243
|
if (ctx.withTodo)
|
|
1772
2244
|
extraLinks.push(' <a href="/todos" class="underline hover:text-foreground">Todos</a>');
|
|
@@ -1843,7 +2315,7 @@ async function signOut() {
|
|
|
1843
2315
|
`;
|
|
1844
2316
|
}
|
|
1845
2317
|
function pagesIndexPageSolid(ctx) {
|
|
1846
|
-
const cssImport =
|
|
2318
|
+
const cssImport = `import '@/index.css'\n`;
|
|
1847
2319
|
const extraLinks = [];
|
|
1848
2320
|
if (ctx.withTodo)
|
|
1849
2321
|
extraLinks.push(' <a href="/todos" class="underline hover:text-foreground">Todos</a>');
|
|
@@ -1969,7 +2441,7 @@ const features: Feature[] = [
|
|
|
1969
2441
|
},
|
|
1970
2442
|
]`;
|
|
1971
2443
|
function welcomeViewReact(ctx) {
|
|
1972
|
-
const cssImport =
|
|
2444
|
+
const cssImport = `import '@/index.css'\n\n`;
|
|
1973
2445
|
return `${cssImport}// URL this view is served at — MUST match the Route.get('/', ...) in routes/web.ts.
|
|
1974
2446
|
// The scanner reads this constant and writes it into the generated +route.ts,
|
|
1975
2447
|
// so Vike's client router can SPA-navigate here instead of doing full reloads.
|
|
@@ -2013,47 +2485,41 @@ export default function Welcome(props: WelcomeProps) {
|
|
|
2013
2485
|
}
|
|
2014
2486
|
|
|
2015
2487
|
return (
|
|
2016
|
-
<div className="
|
|
2017
|
-
<nav className="
|
|
2018
|
-
<div className="
|
|
2019
|
-
<span className="
|
|
2488
|
+
<div className="page">
|
|
2489
|
+
<nav className="page-nav">
|
|
2490
|
+
<div className="brand">
|
|
2491
|
+
<span className="brand-dot" />
|
|
2020
2492
|
RudderJS
|
|
2021
2493
|
</div>
|
|
2022
|
-
<div className="
|
|
2494
|
+
<div className="nav-right">
|
|
2023
2495
|
{props.loginUrl && (props.user ? (
|
|
2024
2496
|
<>
|
|
2025
|
-
<span className="
|
|
2026
|
-
Signed in as{
|
|
2027
|
-
<span className="font-medium text-zinc-900 dark:text-zinc-100">{props.user.name}</span>
|
|
2497
|
+
<span className="nav-badge">
|
|
2498
|
+
Signed in as <strong>{props.user.name}</strong>
|
|
2028
2499
|
</span>
|
|
2029
|
-
<button
|
|
2030
|
-
type="button"
|
|
2031
|
-
onClick={handleSignOut}
|
|
2032
|
-
className="rounded-md border border-zinc-200 px-3 py-1.5 text-xs font-medium text-zinc-700 transition-colors hover:bg-zinc-100 dark:border-zinc-800 dark:text-zinc-300 dark:hover:bg-zinc-900"
|
|
2033
|
-
>
|
|
2500
|
+
<button type="button" onClick={handleSignOut} className="nav-button">
|
|
2034
2501
|
Sign out
|
|
2035
2502
|
</button>
|
|
2036
2503
|
</>
|
|
2037
2504
|
) : (
|
|
2038
2505
|
<>
|
|
2039
|
-
<a href={props.loginUrl} className="
|
|
2506
|
+
<a href={props.loginUrl} className="nav-link">Log in</a>
|
|
2040
2507
|
{props.registerUrl && (
|
|
2041
|
-
<a href={props.registerUrl} className="
|
|
2508
|
+
<a href={props.registerUrl} className="nav-button">Register</a>
|
|
2042
2509
|
)}
|
|
2043
2510
|
</>
|
|
2044
2511
|
))}
|
|
2045
2512
|
</div>
|
|
2046
2513
|
</nav>
|
|
2047
2514
|
|
|
2048
|
-
<section className="
|
|
2049
|
-
<h1 className="
|
|
2050
|
-
<p className="
|
|
2515
|
+
<section className="hero">
|
|
2516
|
+
<h1 className="hero-title">{props.appName}</h1>
|
|
2517
|
+
<p className="hero-lead">
|
|
2051
2518
|
Laravel's developer experience, Vike's performance, Node's ecosystem.
|
|
2052
|
-
<br className="hidden sm:block" />
|
|
2053
2519
|
This page is served by a controller, rendered through{' '}
|
|
2054
|
-
<code className="
|
|
2520
|
+
<code className="inline-code">view('welcome')</code>.
|
|
2055
2521
|
</p>
|
|
2056
|
-
<div className="
|
|
2522
|
+
<div className="hero-meta">
|
|
2057
2523
|
<span>RudderJS v{props.rudderVersion}</span>
|
|
2058
2524
|
<span>•</span>
|
|
2059
2525
|
<span>Node {props.nodeVersion}</span>
|
|
@@ -2062,29 +2528,23 @@ export default function Welcome(props: WelcomeProps) {
|
|
|
2062
2528
|
</div>
|
|
2063
2529
|
</section>
|
|
2064
2530
|
|
|
2065
|
-
<section className="
|
|
2066
|
-
<div className="
|
|
2531
|
+
<section className="feature-section">
|
|
2532
|
+
<div className="feature-grid">
|
|
2067
2533
|
{features.map(f => (
|
|
2068
|
-
<a
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
className="group rounded-xl border border-zinc-200 bg-white p-6 transition-colors hover:border-zinc-900 dark:border-zinc-800 dark:bg-zinc-950 dark:hover:border-zinc-100"
|
|
2072
|
-
>
|
|
2073
|
-
<h3 className="font-semibold">{f.title}</h3>
|
|
2074
|
-
<p className="mt-2 text-sm text-zinc-600 group-hover:text-zinc-900 dark:text-zinc-400 dark:group-hover:text-zinc-100">
|
|
2075
|
-
{f.description}
|
|
2076
|
-
</p>
|
|
2534
|
+
<a key={f.title} href={f.href} className="feature-card">
|
|
2535
|
+
<h3 className="feature-title">{f.title}</h3>
|
|
2536
|
+
<p className="feature-desc">{f.description}</p>
|
|
2077
2537
|
</a>
|
|
2078
2538
|
))}
|
|
2079
2539
|
</div>
|
|
2080
2540
|
</section>
|
|
2081
2541
|
|
|
2082
|
-
<footer className="
|
|
2083
|
-
<div className="
|
|
2542
|
+
<footer className="page-footer">
|
|
2543
|
+
<div className="footer-inner">
|
|
2084
2544
|
<div>Built with RudderJS. Edit <code>app/Views/Welcome.tsx</code> to customize this page.</div>
|
|
2085
|
-
<div className="
|
|
2086
|
-
<a href={docsUrl} className="
|
|
2087
|
-
<a href={githubUrl} className="
|
|
2545
|
+
<div className="footer-links">
|
|
2546
|
+
<a href={docsUrl} className="footer-link">Docs</a>
|
|
2547
|
+
<a href={githubUrl} className="footer-link">GitHub</a>
|
|
2088
2548
|
</div>
|
|
2089
2549
|
</div>
|
|
2090
2550
|
</footer>
|
|
@@ -2094,7 +2554,7 @@ export default function Welcome(props: WelcomeProps) {
|
|
|
2094
2554
|
`;
|
|
2095
2555
|
}
|
|
2096
2556
|
function welcomeViewVue(ctx) {
|
|
2097
|
-
const cssImport =
|
|
2557
|
+
const cssImport = `import '@/index.css'\n`;
|
|
2098
2558
|
// Vue SFC quirk: top-level `export` statements must live in a regular
|
|
2099
2559
|
// <script> block, NOT <script setup> (the compiler rejects exports there).
|
|
2100
2560
|
// The scanner reads both blocks as plain text, so the route override is
|
|
@@ -2147,42 +2607,36 @@ async function handleSignOut() {
|
|
|
2147
2607
|
</script>
|
|
2148
2608
|
|
|
2149
2609
|
<template>
|
|
2150
|
-
<div class="
|
|
2151
|
-
<nav class="
|
|
2152
|
-
<div class="
|
|
2153
|
-
<span class="
|
|
2610
|
+
<div class="page">
|
|
2611
|
+
<nav class="page-nav">
|
|
2612
|
+
<div class="brand">
|
|
2613
|
+
<span class="brand-dot"></span>
|
|
2154
2614
|
RudderJS
|
|
2155
2615
|
</div>
|
|
2156
|
-
<div v-if="props.loginUrl" class="
|
|
2616
|
+
<div v-if="props.loginUrl" class="nav-right">
|
|
2157
2617
|
<template v-if="props.user">
|
|
2158
|
-
<span class="
|
|
2159
|
-
Signed in as
|
|
2160
|
-
<span class="font-medium text-zinc-900 dark:text-zinc-100">{{ props.user.name }}</span>
|
|
2618
|
+
<span class="nav-badge">
|
|
2619
|
+
Signed in as <strong>{{ props.user.name }}</strong>
|
|
2161
2620
|
</span>
|
|
2162
|
-
<button
|
|
2163
|
-
type="button"
|
|
2164
|
-
@click="handleSignOut"
|
|
2165
|
-
class="rounded-md border border-zinc-200 px-3 py-1.5 text-xs font-medium text-zinc-700 transition-colors hover:bg-zinc-100 dark:border-zinc-800 dark:text-zinc-300 dark:hover:bg-zinc-900"
|
|
2166
|
-
>
|
|
2621
|
+
<button type="button" @click="handleSignOut" class="nav-button">
|
|
2167
2622
|
Sign out
|
|
2168
2623
|
</button>
|
|
2169
2624
|
</template>
|
|
2170
2625
|
<template v-else>
|
|
2171
|
-
<a :href="props.loginUrl" class="
|
|
2172
|
-
<a v-if="props.registerUrl" :href="props.registerUrl" class="
|
|
2626
|
+
<a :href="props.loginUrl" class="nav-link">Log in</a>
|
|
2627
|
+
<a v-if="props.registerUrl" :href="props.registerUrl" class="nav-button">Register</a>
|
|
2173
2628
|
</template>
|
|
2174
2629
|
</div>
|
|
2175
2630
|
</nav>
|
|
2176
2631
|
|
|
2177
|
-
<section class="
|
|
2178
|
-
<h1 class="
|
|
2179
|
-
<p class="
|
|
2632
|
+
<section class="hero">
|
|
2633
|
+
<h1 class="hero-title">{{ props.appName }}</h1>
|
|
2634
|
+
<p class="hero-lead">
|
|
2180
2635
|
Laravel's developer experience, Vike's performance, Node's ecosystem.
|
|
2181
|
-
<br class="hidden sm:block" />
|
|
2182
2636
|
This page is served by a controller, rendered through
|
|
2183
|
-
<code class="
|
|
2637
|
+
<code class="inline-code">view('welcome')</code>.
|
|
2184
2638
|
</p>
|
|
2185
|
-
<div class="
|
|
2639
|
+
<div class="hero-meta">
|
|
2186
2640
|
<span>RudderJS v{{ props.rudderVersion }}</span>
|
|
2187
2641
|
<span>•</span>
|
|
2188
2642
|
<span>Node {{ props.nodeVersion }}</span>
|
|
@@ -2191,28 +2645,21 @@ async function handleSignOut() {
|
|
|
2191
2645
|
</div>
|
|
2192
2646
|
</section>
|
|
2193
2647
|
|
|
2194
|
-
<section class="
|
|
2195
|
-
<div class="
|
|
2196
|
-
<a
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
:href="f.href"
|
|
2200
|
-
class="group rounded-xl border border-zinc-200 bg-white p-6 transition-colors hover:border-zinc-900 dark:border-zinc-800 dark:bg-zinc-950 dark:hover:border-zinc-100"
|
|
2201
|
-
>
|
|
2202
|
-
<h3 class="font-semibold">{{ f.title }}</h3>
|
|
2203
|
-
<p class="mt-2 text-sm text-zinc-600 group-hover:text-zinc-900 dark:text-zinc-400 dark:group-hover:text-zinc-100">
|
|
2204
|
-
{{ f.description }}
|
|
2205
|
-
</p>
|
|
2648
|
+
<section class="feature-section">
|
|
2649
|
+
<div class="feature-grid">
|
|
2650
|
+
<a v-for="f in features" :key="f.title" :href="f.href" class="feature-card">
|
|
2651
|
+
<h3 class="feature-title">{{ f.title }}</h3>
|
|
2652
|
+
<p class="feature-desc">{{ f.description }}</p>
|
|
2206
2653
|
</a>
|
|
2207
2654
|
</div>
|
|
2208
2655
|
</section>
|
|
2209
2656
|
|
|
2210
|
-
<footer class="
|
|
2211
|
-
<div class="
|
|
2657
|
+
<footer class="page-footer">
|
|
2658
|
+
<div class="footer-inner">
|
|
2212
2659
|
<div>Built with RudderJS. Edit <code>app/Views/Welcome.vue</code> to customize this page.</div>
|
|
2213
|
-
<div class="
|
|
2214
|
-
<a :href="docsUrl" class="
|
|
2215
|
-
<a :href="githubUrl" class="
|
|
2660
|
+
<div class="footer-links">
|
|
2661
|
+
<a :href="docsUrl" class="footer-link">Docs</a>
|
|
2662
|
+
<a :href="githubUrl" class="footer-link">GitHub</a>
|
|
2216
2663
|
</div>
|
|
2217
2664
|
</div>
|
|
2218
2665
|
</footer>
|
|
@@ -2221,7 +2668,7 @@ async function handleSignOut() {
|
|
|
2221
2668
|
`;
|
|
2222
2669
|
}
|
|
2223
2670
|
function welcomeViewSolid(ctx) {
|
|
2224
|
-
const cssImport =
|
|
2671
|
+
const cssImport = `import '@/index.css'\n`;
|
|
2225
2672
|
return `${cssImport}import { For, Show } from 'solid-js'
|
|
2226
2673
|
|
|
2227
2674
|
// URL this view is served at — see the React variant for rationale.
|
|
@@ -2265,23 +2712,23 @@ export default function Welcome(props: WelcomeProps) {
|
|
|
2265
2712
|
}
|
|
2266
2713
|
|
|
2267
2714
|
return (
|
|
2268
|
-
<div class="
|
|
2269
|
-
<nav class="
|
|
2270
|
-
<div class="
|
|
2271
|
-
<span class="
|
|
2715
|
+
<div class="page">
|
|
2716
|
+
<nav class="page-nav">
|
|
2717
|
+
<div class="brand">
|
|
2718
|
+
<span class="brand-dot" />
|
|
2272
2719
|
RudderJS
|
|
2273
2720
|
</div>
|
|
2274
2721
|
<Show when={props.loginUrl}>
|
|
2275
2722
|
{(loginUrl) => (
|
|
2276
|
-
<div class="
|
|
2723
|
+
<div class="nav-right">
|
|
2277
2724
|
<Show
|
|
2278
2725
|
when={props.user}
|
|
2279
2726
|
fallback={
|
|
2280
2727
|
<>
|
|
2281
|
-
<a href={loginUrl()} class="
|
|
2728
|
+
<a href={loginUrl()} class="nav-link">Log in</a>
|
|
2282
2729
|
<Show when={props.registerUrl}>
|
|
2283
2730
|
{(registerUrl) => (
|
|
2284
|
-
<a href={registerUrl()} class="
|
|
2731
|
+
<a href={registerUrl()} class="nav-button">Register</a>
|
|
2285
2732
|
)}
|
|
2286
2733
|
</Show>
|
|
2287
2734
|
</>
|
|
@@ -2289,14 +2736,10 @@ export default function Welcome(props: WelcomeProps) {
|
|
|
2289
2736
|
>
|
|
2290
2737
|
{(user) => (
|
|
2291
2738
|
<>
|
|
2292
|
-
<span class="
|
|
2293
|
-
Signed in as <
|
|
2739
|
+
<span class="nav-badge">
|
|
2740
|
+
Signed in as <strong>{user().name}</strong>
|
|
2294
2741
|
</span>
|
|
2295
|
-
<button
|
|
2296
|
-
type="button"
|
|
2297
|
-
onClick={handleSignOut}
|
|
2298
|
-
class="rounded-md border border-zinc-200 px-3 py-1.5 text-xs font-medium text-zinc-700 transition-colors hover:bg-zinc-100 dark:border-zinc-800 dark:text-zinc-300 dark:hover:bg-zinc-900"
|
|
2299
|
-
>
|
|
2742
|
+
<button type="button" onClick={handleSignOut} class="nav-button">
|
|
2300
2743
|
Sign out
|
|
2301
2744
|
</button>
|
|
2302
2745
|
</>
|
|
@@ -2307,15 +2750,14 @@ export default function Welcome(props: WelcomeProps) {
|
|
|
2307
2750
|
</Show>
|
|
2308
2751
|
</nav>
|
|
2309
2752
|
|
|
2310
|
-
<section class="
|
|
2311
|
-
<h1 class="
|
|
2312
|
-
<p class="
|
|
2753
|
+
<section class="hero">
|
|
2754
|
+
<h1 class="hero-title">{props.appName}</h1>
|
|
2755
|
+
<p class="hero-lead">
|
|
2313
2756
|
Laravel's developer experience, Vike's performance, Node's ecosystem.
|
|
2314
|
-
<br class="hidden sm:block" />
|
|
2315
2757
|
This page is served by a controller, rendered through{' '}
|
|
2316
|
-
<code class="
|
|
2758
|
+
<code class="inline-code">view('welcome')</code>.
|
|
2317
2759
|
</p>
|
|
2318
|
-
<div class="
|
|
2760
|
+
<div class="hero-meta">
|
|
2319
2761
|
<span>RudderJS v{props.rudderVersion}</span>
|
|
2320
2762
|
<span>•</span>
|
|
2321
2763
|
<span>Node {props.nodeVersion}</span>
|
|
@@ -2324,30 +2766,25 @@ export default function Welcome(props: WelcomeProps) {
|
|
|
2324
2766
|
</div>
|
|
2325
2767
|
</section>
|
|
2326
2768
|
|
|
2327
|
-
<section class="
|
|
2328
|
-
<div class="
|
|
2769
|
+
<section class="feature-section">
|
|
2770
|
+
<div class="feature-grid">
|
|
2329
2771
|
<For each={features}>
|
|
2330
2772
|
{(f) => (
|
|
2331
|
-
<a
|
|
2332
|
-
|
|
2333
|
-
class="
|
|
2334
|
-
>
|
|
2335
|
-
<h3 class="font-semibold">{f.title}</h3>
|
|
2336
|
-
<p class="mt-2 text-sm text-zinc-600 group-hover:text-zinc-900 dark:text-zinc-400 dark:group-hover:text-zinc-100">
|
|
2337
|
-
{f.description}
|
|
2338
|
-
</p>
|
|
2773
|
+
<a href={f.href} class="feature-card">
|
|
2774
|
+
<h3 class="feature-title">{f.title}</h3>
|
|
2775
|
+
<p class="feature-desc">{f.description}</p>
|
|
2339
2776
|
</a>
|
|
2340
2777
|
)}
|
|
2341
2778
|
</For>
|
|
2342
2779
|
</div>
|
|
2343
2780
|
</section>
|
|
2344
2781
|
|
|
2345
|
-
<footer class="
|
|
2346
|
-
<div class="
|
|
2782
|
+
<footer class="page-footer">
|
|
2783
|
+
<div class="footer-inner">
|
|
2347
2784
|
<div>Built with RudderJS. Edit <code>app/Views/Welcome.tsx</code> to customize this page.</div>
|
|
2348
|
-
<div class="
|
|
2349
|
-
<a href={docsUrl()} class="
|
|
2350
|
-
<a href={githubUrl()} class="
|
|
2785
|
+
<div class="footer-links">
|
|
2786
|
+
<a href={docsUrl()} class="footer-link">Docs</a>
|
|
2787
|
+
<a href={githubUrl()} class="footer-link">GitHub</a>
|
|
2351
2788
|
</div>
|
|
2352
2789
|
</div>
|
|
2353
2790
|
</footer>
|
|
@@ -2392,7 +2829,7 @@ function pagesErrorPage(ctx) {
|
|
|
2392
2829
|
}
|
|
2393
2830
|
}
|
|
2394
2831
|
function pagesErrorPageReact(ctx) {
|
|
2395
|
-
const cssImport =
|
|
2832
|
+
const cssImport = `import '@/index.css'\n`;
|
|
2396
2833
|
return `${cssImport}import { usePageContext } from 'vike-react/usePageContext'
|
|
2397
2834
|
|
|
2398
2835
|
export default function Page() {
|
|
@@ -2404,36 +2841,36 @@ export default function Page() {
|
|
|
2404
2841
|
|
|
2405
2842
|
if (is404) {
|
|
2406
2843
|
return (
|
|
2407
|
-
<div className="
|
|
2408
|
-
<h1 className="
|
|
2409
|
-
<p className="
|
|
2410
|
-
<a href="/" className="
|
|
2844
|
+
<div className="error-wrap">
|
|
2845
|
+
<h1 className="heading-lg">404 — Page Not Found</h1>
|
|
2846
|
+
<p className="muted">This page could not be found.</p>
|
|
2847
|
+
<a href="/" className="error-link">Go home</a>
|
|
2411
2848
|
</div>
|
|
2412
2849
|
)
|
|
2413
2850
|
}
|
|
2414
2851
|
|
|
2415
2852
|
if (abortStatusCode === 401) {
|
|
2416
2853
|
return (
|
|
2417
|
-
<div className="
|
|
2418
|
-
<h1 className="
|
|
2419
|
-
<p className="
|
|
2420
|
-
<a href="/" className="
|
|
2854
|
+
<div className="error-wrap">
|
|
2855
|
+
<h1 className="heading-lg">401 — Unauthorized</h1>
|
|
2856
|
+
<p className="muted">{abortReason ?? 'You must be logged in to view this page.'}</p>
|
|
2857
|
+
<a href="/" className="error-link">Go home</a>
|
|
2421
2858
|
</div>
|
|
2422
2859
|
)
|
|
2423
2860
|
}
|
|
2424
2861
|
|
|
2425
2862
|
return (
|
|
2426
|
-
<div className="
|
|
2427
|
-
<h1 className="
|
|
2428
|
-
<p className="
|
|
2429
|
-
<a href="/" className="
|
|
2863
|
+
<div className="error-wrap">
|
|
2864
|
+
<h1 className="heading-lg">Something went wrong</h1>
|
|
2865
|
+
<p className="muted">{abortReason ?? 'An unexpected error occurred.'}</p>
|
|
2866
|
+
<a href="/" className="error-link">Go home</a>
|
|
2430
2867
|
</div>
|
|
2431
2868
|
)
|
|
2432
2869
|
}
|
|
2433
2870
|
`;
|
|
2434
2871
|
}
|
|
2435
2872
|
function pagesErrorPageVue(ctx) {
|
|
2436
|
-
const cssImport =
|
|
2873
|
+
const cssImport = `import '@/index.css'\n`;
|
|
2437
2874
|
return `<script setup lang="ts">
|
|
2438
2875
|
${cssImport}import { usePageContext } from 'vike-vue/usePageContext'
|
|
2439
2876
|
|
|
@@ -2445,26 +2882,26 @@ const pageContext = usePageContext() as {
|
|
|
2445
2882
|
</script>
|
|
2446
2883
|
|
|
2447
2884
|
<template>
|
|
2448
|
-
<div v-if="pageContext.is404" class="
|
|
2449
|
-
<h1 class="
|
|
2450
|
-
<p class="
|
|
2451
|
-
<a href="/" class="
|
|
2885
|
+
<div v-if="pageContext.is404" class="error-wrap">
|
|
2886
|
+
<h1 class="heading-lg">404 — Page Not Found</h1>
|
|
2887
|
+
<p class="muted">This page could not be found.</p>
|
|
2888
|
+
<a href="/" class="error-link">Go home</a>
|
|
2452
2889
|
</div>
|
|
2453
|
-
<div v-else-if="pageContext.abortStatusCode === 401" class="
|
|
2454
|
-
<h1 class="
|
|
2455
|
-
<p class="
|
|
2456
|
-
<a href="/" class="
|
|
2890
|
+
<div v-else-if="pageContext.abortStatusCode === 401" class="error-wrap">
|
|
2891
|
+
<h1 class="heading-lg">401 — Unauthorized</h1>
|
|
2892
|
+
<p class="muted">{{ pageContext.abortReason ?? 'You must be logged in to view this page.' }}</p>
|
|
2893
|
+
<a href="/" class="error-link">Go home</a>
|
|
2457
2894
|
</div>
|
|
2458
|
-
<div v-else class="
|
|
2459
|
-
<h1 class="
|
|
2460
|
-
<p class="
|
|
2461
|
-
<a href="/" class="
|
|
2895
|
+
<div v-else class="error-wrap">
|
|
2896
|
+
<h1 class="heading-lg">Something went wrong</h1>
|
|
2897
|
+
<p class="muted">{{ pageContext.abortReason ?? 'An unexpected error occurred.' }}</p>
|
|
2898
|
+
<a href="/" class="error-link">Go home</a>
|
|
2462
2899
|
</div>
|
|
2463
2900
|
</template>
|
|
2464
2901
|
`;
|
|
2465
2902
|
}
|
|
2466
2903
|
function pagesErrorPageSolid(ctx) {
|
|
2467
|
-
const cssImport =
|
|
2904
|
+
const cssImport = `import '@/index.css'\n`;
|
|
2468
2905
|
return `${cssImport}import { Switch, Match } from 'solid-js'
|
|
2469
2906
|
import { usePageContext } from 'vike-solid/usePageContext'
|
|
2470
2907
|
|
|
@@ -2478,24 +2915,24 @@ export default function Page() {
|
|
|
2478
2915
|
return (
|
|
2479
2916
|
<Switch>
|
|
2480
2917
|
<Match when={pageContext.is404}>
|
|
2481
|
-
<div class="
|
|
2482
|
-
<h1 class="
|
|
2483
|
-
<p class="
|
|
2484
|
-
<a href="/" class="
|
|
2918
|
+
<div class="error-wrap">
|
|
2919
|
+
<h1 class="heading-lg">404 — Page Not Found</h1>
|
|
2920
|
+
<p class="muted">This page could not be found.</p>
|
|
2921
|
+
<a href="/" class="error-link">Go home</a>
|
|
2485
2922
|
</div>
|
|
2486
2923
|
</Match>
|
|
2487
2924
|
<Match when={pageContext.abortStatusCode === 401}>
|
|
2488
|
-
<div class="
|
|
2489
|
-
<h1 class="
|
|
2490
|
-
<p class="
|
|
2491
|
-
<a href="/" class="
|
|
2925
|
+
<div class="error-wrap">
|
|
2926
|
+
<h1 class="heading-lg">401 — Unauthorized</h1>
|
|
2927
|
+
<p class="muted">{pageContext.abortReason ?? 'You must be logged in to view this page.'}</p>
|
|
2928
|
+
<a href="/" class="error-link">Go home</a>
|
|
2492
2929
|
</div>
|
|
2493
2930
|
</Match>
|
|
2494
2931
|
<Match when={true}>
|
|
2495
|
-
<div class="
|
|
2496
|
-
<h1 class="
|
|
2497
|
-
<p class="
|
|
2498
|
-
<a href="/" class="
|
|
2932
|
+
<div class="error-wrap">
|
|
2933
|
+
<h1 class="heading-lg">Something went wrong</h1>
|
|
2934
|
+
<p class="muted">{pageContext.abortReason ?? 'An unexpected error occurred.'}</p>
|
|
2935
|
+
<a href="/" class="error-link">Go home</a>
|
|
2499
2936
|
</div>
|
|
2500
2937
|
</Match>
|
|
2501
2938
|
</Switch>
|
|
@@ -2658,7 +3095,7 @@ function todoPage(ctx) {
|
|
|
2658
3095
|
}
|
|
2659
3096
|
}
|
|
2660
3097
|
function todoPageReact(ctx) {
|
|
2661
|
-
const cssImport =
|
|
3098
|
+
const cssImport = `import '@/index.css'\n`;
|
|
2662
3099
|
return `${cssImport}import { useState } from 'react'
|
|
2663
3100
|
import { useData } from 'vike-react/useData'
|
|
2664
3101
|
import type { Data } from './+data.js'
|
|
@@ -2751,7 +3188,7 @@ export default function Page() {
|
|
|
2751
3188
|
`;
|
|
2752
3189
|
}
|
|
2753
3190
|
function todoPageVue(ctx) {
|
|
2754
|
-
const cssImport =
|
|
3191
|
+
const cssImport = `import '@/index.css'\n`;
|
|
2755
3192
|
return `<script setup lang="ts">
|
|
2756
3193
|
${cssImport}import { ref } from 'vue'
|
|
2757
3194
|
import { useData } from 'vike-vue/useData'
|
|
@@ -2836,7 +3273,7 @@ async function deleteTodo(id: string) {
|
|
|
2836
3273
|
`;
|
|
2837
3274
|
}
|
|
2838
3275
|
function todoPageSolid(ctx) {
|
|
2839
|
-
const cssImport =
|
|
3276
|
+
const cssImport = `import '@/index.css'\n`;
|
|
2840
3277
|
return `${cssImport}import { createSignal } from 'solid-js'
|
|
2841
3278
|
import { For, Show } from 'solid-js'
|
|
2842
3279
|
import { useData } from 'vike-solid/useData'
|
|
@@ -2962,7 +3399,7 @@ function aiChatPage(ctx) {
|
|
|
2962
3399
|
}
|
|
2963
3400
|
}
|
|
2964
3401
|
function aiChatPageReact(ctx) {
|
|
2965
|
-
const cssImport =
|
|
3402
|
+
const cssImport = `import '@/index.css'\n`;
|
|
2966
3403
|
return `${cssImport}import { useState, useRef, useEffect } from 'react'
|
|
2967
3404
|
|
|
2968
3405
|
interface Message {
|
|
@@ -3057,7 +3494,7 @@ export default function Page() {
|
|
|
3057
3494
|
`;
|
|
3058
3495
|
}
|
|
3059
3496
|
function aiChatPageVue(ctx) {
|
|
3060
|
-
const cssImport =
|
|
3497
|
+
const cssImport = `import '@/index.css'\n`;
|
|
3061
3498
|
return `<script setup lang="ts">
|
|
3062
3499
|
${cssImport}import { ref, nextTick } from 'vue'
|
|
3063
3500
|
|
|
@@ -3139,7 +3576,7 @@ async function send(e: Event) {
|
|
|
3139
3576
|
`;
|
|
3140
3577
|
}
|
|
3141
3578
|
function aiChatPageSolid(ctx) {
|
|
3142
|
-
const cssImport =
|
|
3579
|
+
const cssImport = `import '@/index.css'\n`;
|
|
3143
3580
|
return `${cssImport}import { createSignal, For, Show, onCleanup } from 'solid-js'
|
|
3144
3581
|
|
|
3145
3582
|
interface Message {
|