@weft-js/create 0.1.1 → 0.1.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 (127) hide show
  1. package/README.md +60 -10
  2. package/bin/create-weft.mjs +62 -14
  3. package/package.json +26 -16
  4. package/scripts/tarballs.mjs +56 -6
  5. package/src/data.mjs +90 -18
  6. package/src/index.mjs +210 -51
  7. package/src/stack/pages.mjs +151 -0
  8. package/src/stack/schema.mjs +195 -0
  9. package/src/stack.mjs +102 -313
  10. package/src/templates.mjs +174 -0
  11. package/src/wizard.mjs +65 -16
  12. package/templates/admin/files/drizzle/.schema-hash +1 -0
  13. package/templates/admin/files/drizzle/0000_admin.sql +136 -0
  14. package/templates/admin/files/drizzle/meta/0000_snapshot.json +771 -0
  15. package/templates/admin/files/drizzle/meta/_journal.json +13 -0
  16. package/templates/admin/files/public/favicon.svg +1 -0
  17. package/templates/admin/files/src/auth.server.ts +24 -0
  18. package/templates/admin/files/src/components/AuthPage.tsx +33 -0
  19. package/templates/admin/files/src/components/Failed.tsx +19 -0
  20. package/templates/admin/files/src/components/Logo.tsx +16 -0
  21. package/templates/admin/files/src/components/OrderDetail.tsx +93 -0
  22. package/templates/admin/files/src/components/OrdersFilters.tsx +44 -0
  23. package/templates/admin/files/src/components/OrdersTable.tsx +144 -0
  24. package/templates/admin/files/src/components/Overview.tsx +113 -0
  25. package/templates/admin/files/src/components/StatusBadge.tsx +12 -0
  26. package/templates/admin/files/src/db/schema.ts +68 -0
  27. package/templates/admin/files/src/lib/orders.ts +60 -0
  28. package/templates/admin/files/src/routes/404.tsx +20 -0
  29. package/templates/admin/files/src/routes/_error.tsx +20 -0
  30. package/templates/admin/files/src/routes/_layout.tsx +6 -0
  31. package/templates/admin/files/src/routes/admin/_layout.tsx +89 -0
  32. package/templates/admin/files/src/routes/admin/index.tsx +45 -0
  33. package/templates/admin/files/src/routes/admin/nested/_layout.tsx +35 -0
  34. package/templates/admin/files/src/routes/admin/nested/index.tsx +77 -0
  35. package/templates/admin/files/src/routes/admin/orders/[id].tsx +24 -0
  36. package/templates/admin/files/src/routes/admin/orders/index.tsx +28 -0
  37. package/templates/admin/files/src/routes/admin/per-row.tsx +81 -0
  38. package/templates/admin/files/src/routes/admin/slow.tsx +74 -0
  39. package/templates/admin/files/src/routes/index.tsx +13 -0
  40. package/templates/admin/files/src/routes/login.tsx +53 -0
  41. package/templates/admin/files/src/routes/signup.tsx +60 -0
  42. package/templates/admin/files/src/server/orders.ts +193 -0
  43. package/templates/admin/files/src/server/reports.ts +92 -0
  44. package/templates/admin/files/src/server/session.ts +42 -0
  45. package/templates/admin/files/src/theme.css +43 -0
  46. package/templates/admin/files/weft.config.ts +31 -0
  47. package/templates/admin/template.json +22 -0
  48. package/templates/catalog/files/drizzle/.schema-hash +1 -0
  49. package/templates/catalog/files/drizzle/0000_catalog.sql +47 -0
  50. package/templates/catalog/files/drizzle/meta/0000_snapshot.json +263 -0
  51. package/templates/catalog/files/drizzle/meta/_journal.json +13 -0
  52. package/templates/catalog/files/public/favicon.svg +1 -0
  53. package/templates/catalog/files/seed.sql +13 -0
  54. package/templates/catalog/files/src/components/AddToCart.tsx +22 -0
  55. package/templates/catalog/files/src/components/Aisles.tsx +31 -0
  56. package/templates/catalog/files/src/components/CartLines.tsx +96 -0
  57. package/templates/catalog/files/src/components/CartLink.tsx +29 -0
  58. package/templates/catalog/files/src/components/Failed.tsx +19 -0
  59. package/templates/catalog/files/src/components/Featured.tsx +19 -0
  60. package/templates/catalog/files/src/components/Filters.tsx +40 -0
  61. package/templates/catalog/files/src/components/Logo.tsx +16 -0
  62. package/templates/catalog/files/src/components/ProductArt.tsx +42 -0
  63. package/templates/catalog/files/src/components/ProductCard.tsx +42 -0
  64. package/templates/catalog/files/src/components/ProductList.tsx +65 -0
  65. package/templates/catalog/files/src/components/Related.tsx +19 -0
  66. package/templates/catalog/files/src/components/SiteFooter.tsx +9 -0
  67. package/templates/catalog/files/src/components/SiteHeader.tsx +16 -0
  68. package/templates/catalog/files/src/db/schema.ts +53 -0
  69. package/templates/catalog/files/src/lib/catalog.ts +35 -0
  70. package/templates/catalog/files/src/routes/404.tsx +18 -0
  71. package/templates/catalog/files/src/routes/_error.tsx +18 -0
  72. package/templates/catalog/files/src/routes/_layout.tsx +14 -0
  73. package/templates/catalog/files/src/routes/c/[slug].tsx +53 -0
  74. package/templates/catalog/files/src/routes/cart.tsx +29 -0
  75. package/templates/catalog/files/src/routes/index.tsx +84 -0
  76. package/templates/catalog/files/src/routes/p/[slug].tsx +67 -0
  77. package/templates/catalog/files/src/server/cart.ts +125 -0
  78. package/templates/catalog/files/src/server/catalog.ts +107 -0
  79. package/templates/catalog/files/src/theme.css +159 -0
  80. package/templates/catalog/files/weft.config.ts +30 -0
  81. package/templates/catalog/template.json +20 -0
  82. package/templates/landing/files/.weft/plugins.lock.json +42 -0
  83. package/templates/landing/files/assets/fonts/LICENSE-figtree.txt +93 -0
  84. package/templates/landing/files/assets/fonts/figtree.woff2 +0 -0
  85. package/templates/landing/files/assets/hero.webp +0 -0
  86. package/templates/landing/files/drizzle/.schema-hash +1 -0
  87. package/templates/landing/files/drizzle/0000_landing.sql +6 -0
  88. package/templates/landing/files/drizzle/meta/0000_snapshot.json +60 -0
  89. package/templates/landing/files/drizzle/meta/_journal.json +13 -0
  90. package/templates/landing/files/public/favicon.svg +1 -0
  91. package/templates/landing/files/src/components/SiteFooter.tsx +24 -0
  92. package/templates/landing/files/src/components/SiteHeader.tsx +23 -0
  93. package/templates/landing/files/src/components/WaitlistForm.tsx +36 -0
  94. package/templates/landing/files/src/db/schema.ts +7 -0
  95. package/templates/landing/files/src/routes/404.tsx +24 -0
  96. package/templates/landing/files/src/routes/_error.tsx +24 -0
  97. package/templates/landing/files/src/routes/_layout.tsx +14 -0
  98. package/templates/landing/files/src/routes/index.tsx +130 -0
  99. package/templates/landing/files/src/routes/joined.tsx +30 -0
  100. package/templates/landing/files/src/routes/pricing.tsx +131 -0
  101. package/templates/landing/files/src/routes/privacy.tsx +56 -0
  102. package/templates/landing/files/src/server/waitlist.ts +13 -0
  103. package/templates/landing/files/src/theme.css +108 -0
  104. package/templates/landing/files/weft.config.ts +44 -0
  105. package/templates/landing/template.json +17 -0
  106. package/templates/todo/files/drizzle/.schema-hash +1 -0
  107. package/templates/todo/files/drizzle/0000_todo.sql +82 -0
  108. package/templates/todo/files/drizzle/meta/0000_snapshot.json +462 -0
  109. package/templates/todo/files/drizzle/meta/_journal.json +13 -0
  110. package/templates/todo/files/public/favicon.svg +1 -0
  111. package/templates/todo/files/src/components/AuthPage.tsx +33 -0
  112. package/templates/todo/files/src/components/Logo.tsx +14 -0
  113. package/templates/todo/files/src/components/NewTodo.tsx +27 -0
  114. package/templates/todo/files/src/components/TodoList.tsx +101 -0
  115. package/templates/todo/files/src/db/schema.ts +18 -0
  116. package/templates/todo/files/src/lib/views.ts +13 -0
  117. package/templates/todo/files/src/routes/404.tsx +20 -0
  118. package/templates/todo/files/src/routes/_error.tsx +20 -0
  119. package/templates/todo/files/src/routes/_layout.tsx +6 -0
  120. package/templates/todo/files/src/routes/index.tsx +13 -0
  121. package/templates/todo/files/src/routes/login.tsx +53 -0
  122. package/templates/todo/files/src/routes/signup.tsx +57 -0
  123. package/templates/todo/files/src/routes/todos.tsx +87 -0
  124. package/templates/todo/files/src/server/todos.ts +98 -0
  125. package/templates/todo/files/src/theme.css +71 -0
  126. package/templates/todo/files/weft.config.ts +30 -0
  127. package/templates/todo/template.json +18 -0
@@ -0,0 +1,195 @@
1
+ export const authTablesFile = (db) =>
2
+ ({
3
+ sqlite: () =>
4
+ `import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core'\n${authTablesSqlite()}`,
5
+ postgres: () =>
6
+ `import { boolean, pgTable, text, timestamp } from 'drizzle-orm/pg-core'\n${authTablesPg()}`,
7
+ mysql: () =>
8
+ `import { boolean, mysqlTable, text, timestamp, varchar } from 'drizzle-orm/mysql-core'\n${authTablesMysql()}`,
9
+ })[db]()
10
+
11
+ const camel = (column) => column.replace(/_(\w)/g, (_, c) => c.toUpperCase())
12
+
13
+ /** A template's `src/db/auth.ts`: Better Auth's own column names with time zones, as examples/shared/pg/schema.sql has them. */
14
+ export const sharedAuthTables = () =>
15
+ `import { boolean, pgTable, text, timestamp } from 'drizzle-orm/pg-core'\n${authTablesPg().replace(
16
+ /(text|boolean|timestamp)\('(\w+)'\)/g,
17
+ (_, type, column) =>
18
+ `${type}('${camel(column)}'${type === 'timestamp' ? ', { withTimezone: true }' : ''})`,
19
+ )}`
20
+
21
+ export function sqliteSchema(auth) {
22
+ const owner = auth
23
+ ? `\n userId: text('user_id').notNull().references(() => user.id, { onDelete: 'cascade' }),`
24
+ : ''
25
+ return `import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core'
26
+ ${auth ? authTablesSqlite() : ''}
27
+ export const todos = sqliteTable('todos', {
28
+ id: text('id').primaryKey(),${owner}
29
+ title: text('title').notNull(),
30
+ done: integer('done', { mode: 'boolean' }).notNull().default(false),
31
+ createdAt: integer('created_at').notNull(),
32
+ })
33
+ `
34
+ }
35
+
36
+ export function pgSchema(auth) {
37
+ const owner = auth
38
+ ? `\n userId: text('user_id').notNull().references(() => user.id, { onDelete: 'cascade' }),`
39
+ : ''
40
+ return `import { bigint, boolean, pgTable, text${auth ? ', timestamp' : ''} } from 'drizzle-orm/pg-core'
41
+ ${auth ? authTablesPg() : ''}
42
+ export const todos = pgTable('todos', {
43
+ id: text('id').primaryKey(),${owner}
44
+ title: text('title').notNull(),
45
+ done: boolean('done').notNull().default(false),
46
+ createdAt: bigint('created_at', { mode: 'number' }).notNull(),
47
+ })
48
+ `
49
+ }
50
+
51
+ // MySQL can't index a TEXT column, so ids, keys and anything unique are VARCHAR. Otherwise Postgres's tables hold.
52
+ const authTablesMysql = () =>
53
+ authTablesPg()
54
+ .replaceAll('pgTable', 'mysqlTable')
55
+ .replace(
56
+ /text\('(id|user_id|email|token|account_id|provider_id|identifier)'\)/g,
57
+ "varchar('$1', { length: 255 })",
58
+ )
59
+ .replace(/timestamp\('(\w+)'\)/g, "timestamp('$1', { fsp: 3 })")
60
+
61
+ export function mysqlSchema(auth) {
62
+ const owner = auth
63
+ ? `\n userId: varchar('user_id', { length: 255 }).notNull().references(() => user.id, { onDelete: 'cascade' }),`
64
+ : ''
65
+ return `import { bigint, boolean, mysqlTable, ${auth ? 'text, timestamp, ' : ''}varchar } from 'drizzle-orm/mysql-core'
66
+ ${auth ? authTablesMysql() : ''}
67
+ export const todos = mysqlTable('todos', {
68
+ id: varchar('id', { length: 36 }).primaryKey(),${owner}
69
+ title: varchar('title', { length: 200 }).notNull(),
70
+ done: boolean('done').notNull().default(false),
71
+ createdAt: bigint('created_at', { mode: 'number' }).notNull(),
72
+ })
73
+ `
74
+ }
75
+
76
+ const authTablesSqlite = () => {
77
+ const when = (col, opts = '.notNull()') => `integer('${col}', { mode: 'timestamp_ms' })${opts}`
78
+ return `
79
+ // Better Auth's tables: it reads and writes them through Drizzle, with these names.
80
+ export const user = sqliteTable('user', {
81
+ id: text('id').primaryKey(),
82
+ name: text('name').notNull(),
83
+ email: text('email').notNull().unique(),
84
+ emailVerified: integer('email_verified', { mode: 'boolean' }).notNull(),
85
+ image: text('image'),
86
+ createdAt: ${when('created_at')},
87
+ updatedAt: ${when('updated_at')},
88
+ })
89
+
90
+ export const session = sqliteTable('session', {
91
+ id: text('id').primaryKey(),
92
+ expiresAt: ${when('expires_at')},
93
+ token: text('token').notNull().unique(),
94
+ createdAt: ${when('created_at')},
95
+ updatedAt: ${when('updated_at')},
96
+ ipAddress: text('ip_address'),
97
+ userAgent: text('user_agent'),
98
+ userId: text('user_id').notNull().references(() => user.id, { onDelete: 'cascade' }),
99
+ })
100
+
101
+ export const account = sqliteTable('account', {
102
+ id: text('id').primaryKey(),
103
+ accountId: text('account_id').notNull(),
104
+ providerId: text('provider_id').notNull(),
105
+ userId: text('user_id').notNull().references(() => user.id, { onDelete: 'cascade' }),
106
+ accessToken: text('access_token'),
107
+ refreshToken: text('refresh_token'),
108
+ idToken: text('id_token'),
109
+ accessTokenExpiresAt: ${when('access_token_expires_at', '')},
110
+ refreshTokenExpiresAt: ${when('refresh_token_expires_at', '')},
111
+ scope: text('scope'),
112
+ password: text('password'),
113
+ createdAt: ${when('created_at')},
114
+ updatedAt: ${when('updated_at')},
115
+ })
116
+
117
+ export const verification = sqliteTable('verification', {
118
+ id: text('id').primaryKey(),
119
+ identifier: text('identifier').notNull(),
120
+ value: text('value').notNull(),
121
+ expiresAt: ${when('expires_at')},
122
+ createdAt: ${when('created_at', '')},
123
+ updatedAt: ${when('updated_at', '')},
124
+ })
125
+
126
+ export const jwks = sqliteTable('jwks', {
127
+ id: text('id').primaryKey(),
128
+ publicKey: text('public_key').notNull(),
129
+ privateKey: text('private_key').notNull(),
130
+ createdAt: ${when('created_at')},
131
+ expiresAt: ${when('expires_at', '')},
132
+ alg: text('alg'),
133
+ crv: text('crv'),
134
+ })
135
+ `
136
+ }
137
+
138
+ const authTablesPg = () => `
139
+ // Better Auth's tables: it reads and writes them through Drizzle, with these names.
140
+ export const user = pgTable('user', {
141
+ id: text('id').primaryKey(),
142
+ name: text('name').notNull(),
143
+ email: text('email').notNull().unique(),
144
+ emailVerified: boolean('email_verified').notNull(),
145
+ image: text('image'),
146
+ createdAt: timestamp('created_at').notNull(),
147
+ updatedAt: timestamp('updated_at').notNull(),
148
+ })
149
+
150
+ export const session = pgTable('session', {
151
+ id: text('id').primaryKey(),
152
+ expiresAt: timestamp('expires_at').notNull(),
153
+ token: text('token').notNull().unique(),
154
+ createdAt: timestamp('created_at').notNull(),
155
+ updatedAt: timestamp('updated_at').notNull(),
156
+ ipAddress: text('ip_address'),
157
+ userAgent: text('user_agent'),
158
+ userId: text('user_id').notNull().references(() => user.id, { onDelete: 'cascade' }),
159
+ })
160
+
161
+ export const account = pgTable('account', {
162
+ id: text('id').primaryKey(),
163
+ accountId: text('account_id').notNull(),
164
+ providerId: text('provider_id').notNull(),
165
+ userId: text('user_id').notNull().references(() => user.id, { onDelete: 'cascade' }),
166
+ accessToken: text('access_token'),
167
+ refreshToken: text('refresh_token'),
168
+ idToken: text('id_token'),
169
+ accessTokenExpiresAt: timestamp('access_token_expires_at'),
170
+ refreshTokenExpiresAt: timestamp('refresh_token_expires_at'),
171
+ scope: text('scope'),
172
+ password: text('password'),
173
+ createdAt: timestamp('created_at').notNull(),
174
+ updatedAt: timestamp('updated_at').notNull(),
175
+ })
176
+
177
+ export const verification = pgTable('verification', {
178
+ id: text('id').primaryKey(),
179
+ identifier: text('identifier').notNull(),
180
+ value: text('value').notNull(),
181
+ expiresAt: timestamp('expires_at').notNull(),
182
+ createdAt: timestamp('created_at'),
183
+ updatedAt: timestamp('updated_at'),
184
+ })
185
+
186
+ export const jwks = pgTable('jwks', {
187
+ id: text('id').primaryKey(),
188
+ publicKey: text('public_key').notNull(),
189
+ privateKey: text('private_key').notNull(),
190
+ createdAt: timestamp('created_at').notNull(),
191
+ expiresAt: timestamp('expires_at'),
192
+ alg: text('alg'),
193
+ crv: text('crv'),
194
+ })
195
+ `