davaux 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 (333) hide show
  1. package/BASELINE.md +169 -0
  2. package/CLAUDE.md +518 -0
  3. package/LICENSE +21 -0
  4. package/README.md +36 -0
  5. package/ROADMAP.md +198 -0
  6. package/build.mjs +101 -0
  7. package/client/control.ts +247 -0
  8. package/client/hydrate.ts +37 -0
  9. package/client/index.ts +19 -0
  10. package/client/jsx-runtime.ts +209 -0
  11. package/client/resource.ts +122 -0
  12. package/client/signal.ts +211 -0
  13. package/client/store.ts +110 -0
  14. package/client/useHead.ts +63 -0
  15. package/dist/build/config.d.ts +3 -0
  16. package/dist/build/config.d.ts.map +1 -0
  17. package/dist/build/config.js +38 -0
  18. package/dist/build/config.js.map +7 -0
  19. package/dist/build/index.d.ts +2 -0
  20. package/dist/build/index.d.ts.map +1 -0
  21. package/dist/build/index.js +13 -0
  22. package/dist/build/index.js.map +7 -0
  23. package/dist/build/plugins.d.ts +7 -0
  24. package/dist/build/plugins.d.ts.map +1 -0
  25. package/dist/build/plugins.js +85 -0
  26. package/dist/build/plugins.js.map +7 -0
  27. package/dist/cli.d.ts +2 -0
  28. package/dist/cli.d.ts.map +1 -0
  29. package/dist/cli.js +427 -0
  30. package/dist/cli.js.map +7 -0
  31. package/dist/client/control.d.ts +49 -0
  32. package/dist/client/control.d.ts.map +1 -0
  33. package/dist/client/control.js +154 -0
  34. package/dist/client/control.js.map +7 -0
  35. package/dist/client/hydrate.d.ts +7 -0
  36. package/dist/client/hydrate.d.ts.map +1 -0
  37. package/dist/client/hydrate.js +23 -0
  38. package/dist/client/hydrate.js.map +7 -0
  39. package/dist/client/index.d.ts +12 -0
  40. package/dist/client/index.d.ts.map +1 -0
  41. package/dist/client/index.js +32 -0
  42. package/dist/client/index.js.map +7 -0
  43. package/dist/client/jsx-runtime.d.ts +40 -0
  44. package/dist/client/jsx-runtime.d.ts.map +1 -0
  45. package/dist/client/jsx-runtime.js +139 -0
  46. package/dist/client/jsx-runtime.js.map +7 -0
  47. package/dist/client/resource.d.ts +31 -0
  48. package/dist/client/resource.d.ts.map +1 -0
  49. package/dist/client/resource.js +64 -0
  50. package/dist/client/resource.js.map +7 -0
  51. package/dist/client/signal.d.ts +90 -0
  52. package/dist/client/signal.d.ts.map +1 -0
  53. package/dist/client/signal.js +115 -0
  54. package/dist/client/signal.js.map +7 -0
  55. package/dist/client/store.d.ts +26 -0
  56. package/dist/client/store.d.ts.map +1 -0
  57. package/dist/client/store.js +63 -0
  58. package/dist/client/store.js.map +7 -0
  59. package/dist/client/useHead.d.ts +28 -0
  60. package/dist/client/useHead.d.ts.map +1 -0
  61. package/dist/client/useHead.js +33 -0
  62. package/dist/client/useHead.js.map +7 -0
  63. package/dist/config.d.ts +182 -0
  64. package/dist/config.d.ts.map +1 -0
  65. package/dist/config.js +21 -0
  66. package/dist/config.js.map +7 -0
  67. package/dist/create-multisite.d.ts +2 -0
  68. package/dist/create-multisite.d.ts.map +1 -0
  69. package/dist/create-multisite.js +291 -0
  70. package/dist/create-multisite.js.map +7 -0
  71. package/dist/create.d.ts +2 -0
  72. package/dist/create.d.ts.map +1 -0
  73. package/dist/create.js +179 -0
  74. package/dist/create.js.map +7 -0
  75. package/dist/dev/blueprints.d.ts +11 -0
  76. package/dist/dev/blueprints.d.ts.map +1 -0
  77. package/dist/dev/blueprints.js +65 -0
  78. package/dist/dev/blueprints.js.map +7 -0
  79. package/dist/dev/components.d.ts +19 -0
  80. package/dist/dev/components.d.ts.map +1 -0
  81. package/dist/dev/components.js +87 -0
  82. package/dist/dev/components.js.map +7 -0
  83. package/dist/dev/insert.d.ts +11 -0
  84. package/dist/dev/insert.d.ts.map +1 -0
  85. package/dist/dev/insert.js +160 -0
  86. package/dist/dev/insert.js.map +7 -0
  87. package/dist/dev/remove.d.ts +53 -0
  88. package/dist/dev/remove.d.ts.map +1 -0
  89. package/dist/dev/remove.js +518 -0
  90. package/dist/dev/remove.js.map +7 -0
  91. package/dist/dev/watch.d.ts +26 -0
  92. package/dist/dev/watch.d.ts.map +1 -0
  93. package/dist/dev/watch.js +2905 -0
  94. package/dist/dev/watch.js.map +7 -0
  95. package/dist/errors.d.ts +6 -0
  96. package/dist/errors.d.ts.map +1 -0
  97. package/dist/errors.js +63 -0
  98. package/dist/errors.js.map +7 -0
  99. package/dist/generate.d.ts +2 -0
  100. package/dist/generate.d.ts.map +1 -0
  101. package/dist/generate.js +191 -0
  102. package/dist/generate.js.map +7 -0
  103. package/dist/index.d.ts +9 -0
  104. package/dist/index.d.ts.map +1 -0
  105. package/dist/index.js +57 -0
  106. package/dist/index.js.map +7 -0
  107. package/dist/island.d.ts +24 -0
  108. package/dist/island.d.ts.map +1 -0
  109. package/dist/island.js +15 -0
  110. package/dist/island.js.map +7 -0
  111. package/dist/jsx-runtime.d.ts +406 -0
  112. package/dist/jsx-runtime.d.ts.map +1 -0
  113. package/dist/jsx-runtime.js +90 -0
  114. package/dist/jsx-runtime.js.map +7 -0
  115. package/dist/link.d.ts +27 -0
  116. package/dist/link.d.ts.map +1 -0
  117. package/dist/link.js +29 -0
  118. package/dist/link.js.map +7 -0
  119. package/dist/oml/fragment.d.ts +16 -0
  120. package/dist/oml/fragment.d.ts.map +1 -0
  121. package/dist/oml/fragment.js +26 -0
  122. package/dist/oml/fragment.js.map +7 -0
  123. package/dist/oml/index.d.ts +11 -0
  124. package/dist/oml/index.d.ts.map +1 -0
  125. package/dist/oml/index.js +21 -0
  126. package/dist/oml/index.js.map +7 -0
  127. package/dist/oml/jsx-runtime.d.ts +34 -0
  128. package/dist/oml/jsx-runtime.d.ts.map +1 -0
  129. package/dist/oml/jsx-runtime.js +59 -0
  130. package/dist/oml/jsx-runtime.js.map +7 -0
  131. package/dist/oml/jsx.d.ts +14 -0
  132. package/dist/oml/jsx.d.ts.map +1 -0
  133. package/dist/oml/jsx.js +96 -0
  134. package/dist/oml/jsx.js.map +7 -0
  135. package/dist/oml/page.d.ts +7 -0
  136. package/dist/oml/page.d.ts.map +1 -0
  137. package/dist/oml/page.js +6 -0
  138. package/dist/oml/page.js.map +7 -0
  139. package/dist/oml/render.d.ts +13 -0
  140. package/dist/oml/render.d.ts.map +1 -0
  141. package/dist/oml/render.js +117 -0
  142. package/dist/oml/render.js.map +7 -0
  143. package/dist/oml/types.d.ts +79 -0
  144. package/dist/oml/types.d.ts.map +1 -0
  145. package/dist/oml/types.js +64 -0
  146. package/dist/oml/types.js.map +7 -0
  147. package/dist/router/handler.d.ts +53 -0
  148. package/dist/router/handler.d.ts.map +1 -0
  149. package/dist/router/handler.js +342 -0
  150. package/dist/router/handler.js.map +7 -0
  151. package/dist/router/matcher.d.ts +21 -0
  152. package/dist/router/matcher.d.ts.map +1 -0
  153. package/dist/router/matcher.js +28 -0
  154. package/dist/router/matcher.js.map +7 -0
  155. package/dist/router/scanner.d.ts +17 -0
  156. package/dist/router/scanner.d.ts.map +1 -0
  157. package/dist/router/scanner.js +197 -0
  158. package/dist/router/scanner.js.map +7 -0
  159. package/dist/server/index.d.ts +23 -0
  160. package/dist/server/index.d.ts.map +1 -0
  161. package/dist/server/index.js +29 -0
  162. package/dist/server/index.js.map +7 -0
  163. package/dist/signal.d.ts +15 -0
  164. package/dist/signal.d.ts.map +1 -0
  165. package/dist/signal.js +29 -0
  166. package/dist/signal.js.map +7 -0
  167. package/dist/ssg.d.ts +45 -0
  168. package/dist/ssg.d.ts.map +1 -0
  169. package/dist/ssg.js +175 -0
  170. package/dist/ssg.js.map +7 -0
  171. package/dist/test/actions.test.d.ts +2 -0
  172. package/dist/test/actions.test.d.ts.map +1 -0
  173. package/dist/test/body-limits.test.d.ts +2 -0
  174. package/dist/test/body-limits.test.d.ts.map +1 -0
  175. package/dist/test/errors.test.d.ts +2 -0
  176. package/dist/test/errors.test.d.ts.map +1 -0
  177. package/dist/test/fixtures/routes/[id].page.d.ts +4 -0
  178. package/dist/test/fixtures/routes/[id].page.d.ts.map +1 -0
  179. package/dist/test/fixtures/routes/_error.d.ts +3 -0
  180. package/dist/test/fixtures/routes/_error.d.ts.map +1 -0
  181. package/dist/test/fixtures/routes/_global.d.ts +3 -0
  182. package/dist/test/fixtures/routes/_global.d.ts.map +1 -0
  183. package/dist/test/fixtures/routes/_layout-template.d.ts +3 -0
  184. package/dist/test/fixtures/routes/_layout-template.d.ts.map +1 -0
  185. package/dist/test/fixtures/routes/_layout.d.ts +3 -0
  186. package/dist/test/fixtures/routes/_layout.d.ts.map +1 -0
  187. package/dist/test/fixtures/routes/_layout_scripts.d.ts +3 -0
  188. package/dist/test/fixtures/routes/_layout_scripts.d.ts.map +1 -0
  189. package/dist/test/fixtures/routes/_middleware.d.ts +3 -0
  190. package/dist/test/fixtures/routes/_middleware.d.ts.map +1 -0
  191. package/dist/test/fixtures/routes/_redirect301_mw.d.ts +3 -0
  192. package/dist/test/fixtures/routes/_redirect301_mw.d.ts.map +1 -0
  193. package/dist/test/fixtures/routes/_redirect_mw.d.ts +3 -0
  194. package/dist/test/fixtures/routes/_redirect_mw.d.ts.map +1 -0
  195. package/dist/test/fixtures/routes/about.page.d.ts +3 -0
  196. package/dist/test/fixtures/routes/about.page.d.ts.map +1 -0
  197. package/dist/test/fixtures/routes/action.page.d.ts +6 -0
  198. package/dist/test/fixtures/routes/action.page.d.ts.map +1 -0
  199. package/dist/test/fixtures/routes/api/form-all.post.d.ts +3 -0
  200. package/dist/test/fixtures/routes/api/form-all.post.d.ts.map +1 -0
  201. package/dist/test/fixtures/routes/api/form-limited.post.d.ts +6 -0
  202. package/dist/test/fixtures/routes/api/form-limited.post.d.ts.map +1 -0
  203. package/dist/test/fixtures/routes/api/response-obj.get.d.ts +3 -0
  204. package/dist/test/fixtures/routes/api/response-obj.get.d.ts.map +1 -0
  205. package/dist/test/fixtures/routes/api/upload.post.d.ts +12 -0
  206. package/dist/test/fixtures/routes/api/upload.post.d.ts.map +1 -0
  207. package/dist/test/fixtures/routes/api/users.get.d.ts +6 -0
  208. package/dist/test/fixtures/routes/api/users.get.d.ts.map +1 -0
  209. package/dist/test/fixtures/routes/api/xml.get.d.ts +3 -0
  210. package/dist/test/fixtures/routes/api/xml.get.d.ts.map +1 -0
  211. package/dist/test/fixtures/routes/auth/_middleware.d.ts +3 -0
  212. package/dist/test/fixtures/routes/auth/_middleware.d.ts.map +1 -0
  213. package/dist/test/fixtures/routes/auth/protected.page.d.ts +3 -0
  214. package/dist/test/fixtures/routes/auth/protected.page.d.ts.map +1 -0
  215. package/dist/test/fixtures/routes/index.page.d.ts +3 -0
  216. package/dist/test/fixtures/routes/index.page.d.ts.map +1 -0
  217. package/dist/test/fixtures/routes/oml.page.d.ts +3 -0
  218. package/dist/test/fixtures/routes/oml.page.d.ts.map +1 -0
  219. package/dist/test/fixtures/routes/redirect.page.d.ts +3 -0
  220. package/dist/test/fixtures/routes/redirect.page.d.ts.map +1 -0
  221. package/dist/test/fixtures/routes/ssg/[slug].page.d.ts +5 -0
  222. package/dist/test/fixtures/routes/ssg/[slug].page.d.ts.map +1 -0
  223. package/dist/test/fixtures/routes/ssg/server.page.d.ts +4 -0
  224. package/dist/test/fixtures/routes/ssg/server.page.d.ts.map +1 -0
  225. package/dist/test/fixtures/routes/state.page.d.ts +3 -0
  226. package/dist/test/fixtures/routes/state.page.d.ts.map +1 -0
  227. package/dist/test/fixtures/routes/throw.page.d.ts +3 -0
  228. package/dist/test/fixtures/routes/throw.page.d.ts.map +1 -0
  229. package/dist/test/fixtures/routes/wiki/[...slug].page.d.ts +3 -0
  230. package/dist/test/fixtures/routes/wiki/[...slug].page.d.ts.map +1 -0
  231. package/dist/test/helpers.d.ts +37 -0
  232. package/dist/test/helpers.d.ts.map +1 -0
  233. package/dist/test/layouts.test.d.ts +2 -0
  234. package/dist/test/layouts.test.d.ts.map +1 -0
  235. package/dist/test/middleware.test.d.ts +2 -0
  236. package/dist/test/middleware.test.d.ts.map +1 -0
  237. package/dist/test/multipart.test.d.ts +2 -0
  238. package/dist/test/multipart.test.d.ts.map +1 -0
  239. package/dist/test/oml-routing.test.d.ts +2 -0
  240. package/dist/test/oml-routing.test.d.ts.map +1 -0
  241. package/dist/test/oml.test.d.ts +2 -0
  242. package/dist/test/oml.test.d.ts.map +1 -0
  243. package/dist/test/redirects.test.d.ts +2 -0
  244. package/dist/test/redirects.test.d.ts.map +1 -0
  245. package/dist/test/routing.test.d.ts +2 -0
  246. package/dist/test/routing.test.d.ts.map +1 -0
  247. package/dist/test/ssg.test.d.ts +2 -0
  248. package/dist/test/ssg.test.d.ts.map +1 -0
  249. package/dist/test/web-response.test.d.ts +2 -0
  250. package/dist/test/web-response.test.d.ts.map +1 -0
  251. package/dist/types.d.ts +314 -0
  252. package/dist/types.d.ts.map +1 -0
  253. package/dist/types.js +292 -0
  254. package/dist/types.js.map +7 -0
  255. package/package.json +103 -0
  256. package/pka.config.json +32 -0
  257. package/src/build/config.ts +42 -0
  258. package/src/build/index.ts +6 -0
  259. package/src/build/plugins.ts +118 -0
  260. package/src/cli.ts +502 -0
  261. package/src/config.ts +197 -0
  262. package/src/create-multisite.ts +310 -0
  263. package/src/create.ts +194 -0
  264. package/src/dev/blueprints.ts +75 -0
  265. package/src/dev/components.ts +108 -0
  266. package/src/dev/insert.ts +221 -0
  267. package/src/dev/remove.ts +677 -0
  268. package/src/dev/watch.ts +3098 -0
  269. package/src/env.d.ts +5 -0
  270. package/src/errors.ts +64 -0
  271. package/src/generate.ts +228 -0
  272. package/src/index.ts +67 -0
  273. package/src/island.ts +47 -0
  274. package/src/jsx-runtime.d.ts +408 -0
  275. package/src/jsx-runtime.d.ts.map +1 -0
  276. package/src/jsx-runtime.ts +536 -0
  277. package/src/link.ts +49 -0
  278. package/src/oml/fragment.ts +54 -0
  279. package/src/oml/index.ts +21 -0
  280. package/src/oml/jsx-runtime.ts +121 -0
  281. package/src/oml/jsx.ts +151 -0
  282. package/src/oml/page.ts +13 -0
  283. package/src/oml/render.ts +181 -0
  284. package/src/oml/types.ts +159 -0
  285. package/src/router/handler.ts +515 -0
  286. package/src/router/matcher.ts +52 -0
  287. package/src/router/scanner.ts +272 -0
  288. package/src/server/index.ts +49 -0
  289. package/src/signal.ts +39 -0
  290. package/src/ssg.ts +253 -0
  291. package/src/test/actions.test.ts +40 -0
  292. package/src/test/body-limits.test.ts +83 -0
  293. package/src/test/errors.test.ts +53 -0
  294. package/src/test/fixtures/routes/[id].page.ts +3 -0
  295. package/src/test/fixtures/routes/_error.ts +6 -0
  296. package/src/test/fixtures/routes/_global.ts +8 -0
  297. package/src/test/fixtures/routes/_layout-template.ts +7 -0
  298. package/src/test/fixtures/routes/_layout.ts +7 -0
  299. package/src/test/fixtures/routes/_layout_scripts.ts +8 -0
  300. package/src/test/fixtures/routes/_middleware.ts +8 -0
  301. package/src/test/fixtures/routes/_redirect301_mw.ts +5 -0
  302. package/src/test/fixtures/routes/_redirect_mw.ts +5 -0
  303. package/src/test/fixtures/routes/about.page.ts +6 -0
  304. package/src/test/fixtures/routes/action.page.ts +11 -0
  305. package/src/test/fixtures/routes/api/form-all.post.ts +5 -0
  306. package/src/test/fixtures/routes/api/form-limited.post.ts +6 -0
  307. package/src/test/fixtures/routes/api/response-obj.get.ts +17 -0
  308. package/src/test/fixtures/routes/api/upload.post.ts +14 -0
  309. package/src/test/fixtures/routes/api/users.get.ts +3 -0
  310. package/src/test/fixtures/routes/api/xml.get.ts +5 -0
  311. package/src/test/fixtures/routes/auth/_middleware.ts +11 -0
  312. package/src/test/fixtures/routes/auth/protected.page.ts +3 -0
  313. package/src/test/fixtures/routes/index.page.ts +3 -0
  314. package/src/test/fixtures/routes/oml.page.ts +7 -0
  315. package/src/test/fixtures/routes/redirect.page.ts +3 -0
  316. package/src/test/fixtures/routes/ssg/[slug].page.ts +8 -0
  317. package/src/test/fixtures/routes/ssg/server.page.ts +5 -0
  318. package/src/test/fixtures/routes/state.page.ts +4 -0
  319. package/src/test/fixtures/routes/throw.page.ts +5 -0
  320. package/src/test/fixtures/routes/wiki/[...slug].page.ts +3 -0
  321. package/src/test/helpers.ts +132 -0
  322. package/src/test/layouts.test.ts +76 -0
  323. package/src/test/middleware.test.ts +69 -0
  324. package/src/test/multipart.test.ts +91 -0
  325. package/src/test/oml-routing.test.ts +59 -0
  326. package/src/test/oml.test.ts +429 -0
  327. package/src/test/redirects.test.ts +32 -0
  328. package/src/test/routing.test.ts +118 -0
  329. package/src/test/ssg.test.ts +273 -0
  330. package/src/test/web-response.test.ts +33 -0
  331. package/src/types.ts +670 -0
  332. package/tsconfig.client.json +17 -0
  333. package/tsconfig.json +20 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/config.ts"],
4
+ "sourcesContent": ["import type { Plugin } from 'esbuild'\nimport type { RouteType } from './types.js'\n\n// \u2500\u2500\u2500 Plugin API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * A Davaux plugin \u2014 extends the framework with new route file types and/or\n * esbuild transforms. Implement this interface and return it from a factory\n * function, then pass it to `plugins` in `davaux.config.ts`.\n *\n * @example\n * // packages/my-plugin/src/index.ts\n * import type { DavauxPlugin } from 'davaux/config'\n * export function myPlugin(): DavauxPlugin {\n * return {\n * name: 'my-plugin',\n * esbuild: [myEsbuildPlugin()],\n * scanner: { suffixes: [['.page.myext', 'page']] },\n * }\n * }\n */\nexport interface DavauxPlugin {\n name: string\n /** esbuild plugins contributed to every build context (server routes, islands, client) */\n esbuild?: Plugin[]\n /** Additional route file suffixes the scanner should recognize */\n scanner?: {\n suffixes: [suffix: string, type: RouteType][]\n }\n}\n\n/** Collect esbuild plugins from an array of DavauxPlugins. */\nexport function collectEsbuildPlugins(plugins: DavauxPlugin[] = []): Plugin[] {\n return plugins.flatMap((p) => p.esbuild ?? [])\n}\n\n/** Collect scanner suffix entries from an array of DavauxPlugins. */\nexport function collectScannerSuffixes(plugins: DavauxPlugin[] = []): [string, RouteType][] {\n return plugins.flatMap((p) => p.scanner?.suffixes ?? [])\n}\n\n// \u2500\u2500\u2500 User-facing config type \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface EditorConfig {\n /**\n * Opt-in to the visual editor and inspector overlay.\n * Must be explicitly set to `true` \u2014 disabled by default so the editor\n * endpoints and inspector script are never exposed unless intended.\n */\n enabled?: boolean\n /** Floating inspector/editor badge options. */\n badge?: {\n /** Corner of the viewport where the badge appears. Default: `'bottom-right'` */\n position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'\n /** Custom label text shown on the badge. Default: `'Inspector'` */\n label?: string\n }\n /**\n * Force a specific colour scheme for the editor UI instead of auto-detecting\n * from the inspected page's theme attribute.\n */\n theme?: 'auto' | 'dark' | 'light'\n /**\n * Raw CSS string injected into the editor frame's `<style>` tag.\n * Use this to override colours, hide elements, or adjust layout.\n */\n css?: string\n /**\n * Path to a CSS file (relative to the project root) whose contents are\n * injected into the editor frame. Merged with `css` if both are provided.\n * The file is re-read on each request in dev mode, so changes apply without a restart.\n */\n cssFile?: string\n}\n\nexport interface DavauxConfig {\n /** Server defaults for `davaux dev`, `davaux start`, and `davaux preview`. CLI flags (--port, --hostname) take priority over these. */\n server?: {\n port?: number\n hostname?: string\n }\n /**\n * Import path aliases, using the same glob syntax as `tsconfig.json` `paths`.\n * Each entry is forwarded to esbuild `alias` in every build context so TypeScript\n * and the bundler stay in sync without any extra plugin.\n *\n * @example\n * import { defineConfig } from 'davaux/config'\n * export default defineConfig({\n * paths: { '@/*': './src/*' },\n * })\n */\n paths?: Record<string, string>\n /**\n * Davaux plugins \u2014 each plugin can contribute esbuild transforms and/or\n * register new route file extensions with the scanner.\n *\n * @example\n * import { defineConfig } from 'davaux/config'\n * import { markdown } from '@davaux/markdown'\n * export default defineConfig({\n * plugins: [markdown()],\n * })\n */\n plugins?: DavauxPlugin[]\n /**\n * Additional packages to exclude from esbuild bundling. Useful for packages\n * that use native bindings or CJS `require()` that cannot be bundled into ESM.\n * Each entry is added to the esbuild `external` list alongside `node:*` and `davaux`.\n *\n * @example\n * import { defineConfig } from 'davaux/config'\n * export default defineConfig({\n * external: ['@libsql/client', 'libsql'],\n * })\n */\n external?: string[]\n /** Visual editor and inspector overlay configuration. Disabled by default \u2014 set `enabled: true` to opt in. */\n editor?: EditorConfig\n /**\n * OML (Object Markup Language) options. OML is the intermediate representation\n * used by the visual editor and production page caching.\n */\n oml?: {\n /**\n * Control which routes use OML tree construction and result caching in production.\n * By default no routes are cached \u2014 this must be explicitly configured.\n *\n * Use `include` for apps that are mostly dynamic with a few cacheable routes,\n * or `exclude` for apps that are mostly static with a few dynamic routes.\n * Routes not covered by the cache config use the string renderer directly in\n * production \u2014 no OML tree is built and no result is stored.\n *\n * @example\n * // Whitelist \u2014 only these routes are cached\n * oml: { cache: { include: ['/', '/blog/:slug', '/docs/*'] } }\n *\n * // Blacklist \u2014 all routes cached except these\n * oml: { cache: { exclude: ['/dashboard', '/account/*'] } }\n */\n cache?: OmlCacheConfig\n }\n /** Options that only apply to `davaux static` (static site generation). */\n ssg?: {\n /**\n * Override the default `out/` output directory.\n * The `--out` CLI flag takes priority over this value.\n */\n outDir?: string\n /**\n * Trailing slash behaviour for generated output files.\n * - `'always'` (default) \u2014 `/about` \u2192 `out/about/index.html` (served as `/about/`)\n * - `'never'` \u2014 `/about` \u2192 `out/about.html` (served as `/about`)\n */\n trailingSlash?: 'always' | 'never'\n /**\n * Path prefix for subdirectory deployments (e.g. `'/docs'` for GitHub Pages\n * at `user.github.io/my-project/`). Prepended to all injected `/_davaux/*`\n * script and stylesheet URLs in the generated HTML.\n */\n basePath?: string\n /**\n * Generate a `404.html` at the root of `outDir` for static hosts\n * (Netlify, GitHub Pages) that serve it on unmatched paths.\n * Defaults to `true` when an `_error.tsx` exists in the routes directory.\n */\n notFound?: boolean\n /**\n * Auto-generate a `sitemap.xml` from all rendered routes.\n * Pass `{ baseUrl: 'https://example.com' }` to enable.\n * Pass `false` to explicitly disable.\n */\n sitemap?: false | { baseUrl: string }\n }\n}\n\n/**\n * Convert tsconfig-style `paths` glob entries to esbuild `alias` entries.\n * `'@/*': './src/*'` \u2192 `'@': './src'`\n */\nexport function pathsToAlias(paths: Record<string, string>): Record<string, string> {\n return Object.fromEntries(\n Object.entries(paths).map(([k, v]) => [k.replace(/\\/\\*$/, ''), v.replace(/\\/\\*$/, '')]),\n )\n}\n\n/**\n * Controls which routes use OML tree construction and caching in production.\n * Use `include` to whitelist specific URL patterns, or `exclude` to blacklist them.\n * Patterns support `:param` (single dynamic segment) and `*` (any characters).\n */\nexport type OmlCacheConfig = { include: string[] } | { exclude: string[] }\n\n/** Wraps a config object for TypeScript inference \u2014 returns it unchanged. */\nexport function defineConfig(config: DavauxConfig): DavauxConfig {\n return config\n}\n"],
5
+ "mappings": "AAgCO,SAAS,sBAAsB,UAA0B,CAAC,GAAa;AAC5E,SAAO,QAAQ,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAC/C;AAGO,SAAS,uBAAuB,UAA0B,CAAC,GAA0B;AAC1F,SAAO,QAAQ,QAAQ,CAAC,MAAM,EAAE,SAAS,YAAY,CAAC,CAAC;AACzD;AA6IO,SAAS,aAAa,OAAuD;AAClF,SAAO,OAAO;AAAA,IACZ,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,QAAQ,SAAS,EAAE,GAAG,EAAE,QAAQ,SAAS,EAAE,CAAC,CAAC;AAAA,EACxF;AACF;AAUO,SAAS,aAAa,QAAoC;AAC/D,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -0,0 +1,2 @@
1
+ export declare function scaffoldMultisite(name: string | undefined, cwd: string): Promise<void>;
2
+ //# sourceMappingURL=create-multisite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-multisite.d.ts","sourceRoot":"","sources":["../src/create-multisite.ts"],"names":[],"mappings":"AAGA,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,iBA2C5E"}
@@ -0,0 +1,291 @@
1
+ import { existsSync, mkdirSync, writeFileSync } from "node:fs";
2
+ import { join, resolve } from "node:path";
3
+ async function scaffoldMultisite(name, cwd) {
4
+ if (!name) {
5
+ console.error("Usage: davaux create-multisite <project-name>");
6
+ process.exit(1);
7
+ }
8
+ if (!/^[a-z0-9]([a-z0-9._-]*[a-z0-9])?$/.test(name)) {
9
+ console.error(
10
+ `[davaux] Invalid project name "${name}". Use lowercase letters, numbers, hyphens, underscores, or dots.`
11
+ );
12
+ process.exit(1);
13
+ }
14
+ const dir = resolve(cwd, name);
15
+ if (existsSync(dir)) {
16
+ console.error(`[davaux] Directory "${name}" already exists.`);
17
+ process.exit(1);
18
+ }
19
+ const title = name.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
20
+ mkdirSync(join(dir, "src", "routes"), { recursive: true });
21
+ mkdirSync(join(dir, "sites", "main", "routes"), { recursive: true });
22
+ mkdirSync(join(dir, "public"), { recursive: true });
23
+ write(dir, "package.json", packageJson(name));
24
+ write(dir, "tsconfig.json", tsConfig());
25
+ write(dir, "biome.json", biomeConfig());
26
+ write(dir, "multisite.config.ts", multisiteConfig());
27
+ write(dir, "server.ts", serverEntry());
28
+ write(dir, "build.ts", buildEntry());
29
+ write(dir, "src/routes/_layout.tsx", baseLayout(title));
30
+ write(dir, "src/routes/index.page.tsx", baseIndexPage(title));
31
+ write(dir, "sites/main/routes/_layout.tsx", siteLayout());
32
+ write(dir, "sites/main/routes/index.page.tsx", siteIndexPage(title));
33
+ console.log(`
34
+ Created multisite project: ${name}
35
+ `);
36
+ console.log(" Next steps:\n");
37
+ console.log(` cd ${name}`);
38
+ console.log(" npm install");
39
+ console.log(" npm run dev\n");
40
+ console.log(" Docs: https://davaux.codeberg.page/docs/packages/multisite\n");
41
+ }
42
+ function write(dir, file, content) {
43
+ writeFileSync(join(dir, file), content, "utf8");
44
+ }
45
+ function packageJson(name) {
46
+ return JSON.stringify(
47
+ {
48
+ name,
49
+ version: "0.1.0",
50
+ type: "module",
51
+ scripts: {
52
+ dev: "node --watch --import tsx/esm server.ts",
53
+ build: "tsx build.ts",
54
+ start: "NODE_ENV=production node dist/server.js"
55
+ },
56
+ dependencies: {
57
+ "@davaux/multisite": "latest",
58
+ davaux: "latest"
59
+ },
60
+ devDependencies: {
61
+ "@biomejs/biome": "latest",
62
+ "@types/node": "latest",
63
+ tsx: "latest"
64
+ }
65
+ },
66
+ null,
67
+ 2
68
+ ) + "\n";
69
+ }
70
+ function tsConfig() {
71
+ return JSON.stringify(
72
+ {
73
+ compilerOptions: {
74
+ target: "ESNext",
75
+ module: "NodeNext",
76
+ moduleResolution: "NodeNext",
77
+ jsx: "react-jsx",
78
+ jsxImportSource: "davaux",
79
+ strict: true,
80
+ lib: ["ESNext", "DOM"],
81
+ allowImportingTsExtensions: true,
82
+ noEmit: true,
83
+ skipLibCheck: true,
84
+ types: ["node", "davaux/env"]
85
+ },
86
+ include: ["src/**/*", "sites/**/*", "*.ts"]
87
+ },
88
+ null,
89
+ 2
90
+ ) + "\n";
91
+ }
92
+ function biomeConfig() {
93
+ return JSON.stringify(
94
+ {
95
+ $schema: "https://biomejs.dev/schemas/2.4.15/schema.json",
96
+ assist: { actions: { source: { organizeImports: "on" } } },
97
+ linter: {
98
+ enabled: true,
99
+ rules: {
100
+ recommended: true,
101
+ correctness: {
102
+ noUnusedVariables: "error",
103
+ noUnusedImports: "error"
104
+ },
105
+ style: {
106
+ noNonNullAssertion: "warn"
107
+ }
108
+ }
109
+ },
110
+ formatter: {
111
+ enabled: true,
112
+ indentStyle: "space",
113
+ indentWidth: 2,
114
+ lineWidth: 100
115
+ },
116
+ javascript: {
117
+ formatter: {
118
+ quoteStyle: "single",
119
+ trailingCommas: "all",
120
+ semicolons: "asNeeded"
121
+ }
122
+ },
123
+ css: {
124
+ formatter: {
125
+ enabled: true,
126
+ quoteStyle: "single"
127
+ }
128
+ },
129
+ files: {
130
+ includes: ["src/**", "sites/**", "*.ts"]
131
+ }
132
+ },
133
+ null,
134
+ 2
135
+ ) + "\n";
136
+ }
137
+ function multisiteConfig() {
138
+ return `import { join } from 'node:path'
139
+ import { fileURLToPath } from 'node:url'
140
+ import { defineSites } from '@davaux/multisite'
141
+
142
+ const root = fileURLToPath(new URL('.', import.meta.url))
143
+
144
+ export interface SiteConfig {
145
+ name: string
146
+ primaryColor: string
147
+ }
148
+
149
+ export const sites = defineSites<SiteConfig>({
150
+ baseDir: join(root, 'src/routes'),
151
+ sites: [
152
+ {
153
+ name: 'main',
154
+ hostname: 'localhost',
155
+ routesDir: join(root, 'sites/main/routes'),
156
+ config: { name: 'Main Site', primaryColor: '#1d4ed8' },
157
+ },
158
+ {
159
+ name: 'fallback',
160
+ hostname: '*',
161
+ config: { name: 'Fallback', primaryColor: '#374151' },
162
+ },
163
+ ],
164
+ })
165
+ `;
166
+ }
167
+ function serverEntry() {
168
+ return `import { startMultisite } from '@davaux/multisite'
169
+ import { sites } from './multisite.config.js'
170
+
171
+ startMultisite(sites, { port: 3000, hostname: 'localhost', cwd: import.meta.dirname })
172
+ `;
173
+ }
174
+ function buildEntry() {
175
+ return `import { buildMultisite } from '@davaux/multisite/build'
176
+ import { sites } from './multisite.config.js'
177
+
178
+ await buildMultisite(sites, { cwd: import.meta.dirname })
179
+ `;
180
+ }
181
+ function baseLayout(title) {
182
+ return `import { defineLayout } from 'davaux'
183
+
184
+ export default defineLayout(({ children, ctx }) => (
185
+ <html lang="en">
186
+ <head>
187
+ <meta charset="utf-8" />
188
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
189
+ <title>{ctx.head.title ?? '${title}'}</title>
190
+ {ctx.head.description && <meta name="description" content={ctx.head.description} />}
191
+ {Object.entries(ctx.head.meta).map(([name, content]) => (
192
+ <meta name={name} content={content} />
193
+ ))}
194
+ {ctx.head.stylesheets.map((href) => (
195
+ <link rel="stylesheet" href={href} />
196
+ ))}
197
+ </head>
198
+ <body>
199
+ {children as unknown as string}
200
+ {ctx.head.scripts.map((src) => (
201
+ <script type="module" src={src}></script>
202
+ ))}
203
+ </body>
204
+ </html>
205
+ ))
206
+ `;
207
+ }
208
+ function baseIndexPage(title) {
209
+ return `import { definePage } from 'davaux'
210
+
211
+ export default definePage((ctx) => {
212
+ ctx.head.title = '${title}'
213
+ return (
214
+ <main>
215
+ <h1>Welcome to ${title}</h1>
216
+ <p>
217
+ This page is served from the shared base routes (<code>src/routes/</code>). It is visible
218
+ at any hostname not explicitly registered in <code>multisite.config.ts</code> \u2014 in this
219
+ project, that means any hostname other than <code>localhost</code>.
220
+ </p>
221
+ <h2>Get started</h2>
222
+ <ul>
223
+ <li>
224
+ <a href="https://davaux.codeberg.page/docs/packages/multisite">@davaux/multisite</a>
225
+ {' \u2014 '}concepts, API reference, and operating modes
226
+ </li>
227
+ <li>
228
+ <a href="https://davaux.codeberg.page/docs/routing">Routing</a>
229
+ {' \u2014 '}file-based routing, dynamic segments, layouts, and middlewares
230
+ </li>
231
+ <li>
232
+ <a href="https://davaux.codeberg.page/docs/getting-started">Getting started</a>
233
+ {' \u2014 '}core Davaux concepts
234
+ </li>
235
+ </ul>
236
+ <h2>Project structure</h2>
237
+ <ul>
238
+ <li>
239
+ <code>multisite.config.ts</code> \u2014 site definitions and per-site config
240
+ </li>
241
+ <li>
242
+ <code>src/routes/</code> \u2014 shared base routes (you are here)
243
+ </li>
244
+ <li>
245
+ <code>sites/main/routes/</code> \u2014 main site overrides (served at <code>localhost</code>)
246
+ </li>
247
+ <li>
248
+ <code>server.ts</code> \u2014 starts the dev and production server
249
+ </li>
250
+ <li>
251
+ <code>build.ts</code> \u2014 production build script
252
+ </li>
253
+ </ul>
254
+ </main>
255
+ )
256
+ })
257
+ `;
258
+ }
259
+ function siteLayout() {
260
+ return `export { default } from '../../../src/routes/_layout.js'
261
+ `;
262
+ }
263
+ function siteIndexPage(title) {
264
+ return `import { definePage } from 'davaux'
265
+ import { getSite } from '@davaux/multisite'
266
+ import type { SiteConfig } from '../../../multisite.config.js'
267
+
268
+ export default definePage((ctx) => {
269
+ const site = getSite<SiteConfig>(ctx)
270
+ ctx.head.title = site?.name ?? '${title}'
271
+ return (
272
+ <main>
273
+ <h1>Welcome to {site?.name ?? '${title}'}</h1>
274
+ <p>
275
+ You're looking at the <strong>main</strong> site. Edit{' '}
276
+ <code>sites/main/routes/index.page.tsx</code> to get started.
277
+ </p>
278
+ <p>
279
+ Site config is defined in <code>multisite.config.ts</code> and accessed here via{' '}
280
+ <code>getSite(ctx)</code>. Use it for per-site themes, database URLs, feature flags \u2014
281
+ anything that varies between sites.
282
+ </p>
283
+ </main>
284
+ )
285
+ })
286
+ `;
287
+ }
288
+ export {
289
+ scaffoldMultisite
290
+ };
291
+ //# sourceMappingURL=create-multisite.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/create-multisite.ts"],
4
+ "sourcesContent": ["import { existsSync, mkdirSync, writeFileSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\n\nexport async function scaffoldMultisite(name: string | undefined, cwd: string) {\n if (!name) {\n console.error('Usage: davaux create-multisite <project-name>')\n process.exit(1)\n }\n\n if (!/^[a-z0-9]([a-z0-9._-]*[a-z0-9])?$/.test(name)) {\n console.error(\n `[davaux] Invalid project name \"${name}\". Use lowercase letters, numbers, hyphens, underscores, or dots.`,\n )\n process.exit(1)\n }\n\n const dir = resolve(cwd, name)\n\n if (existsSync(dir)) {\n console.error(`[davaux] Directory \"${name}\" already exists.`)\n process.exit(1)\n }\n\n const title = name.replace(/[-_]/g, ' ').replace(/\\b\\w/g, (c) => c.toUpperCase())\n\n mkdirSync(join(dir, 'src', 'routes'), { recursive: true })\n mkdirSync(join(dir, 'sites', 'main', 'routes'), { recursive: true })\n mkdirSync(join(dir, 'public'), { recursive: true })\n\n write(dir, 'package.json', packageJson(name))\n write(dir, 'tsconfig.json', tsConfig())\n write(dir, 'biome.json', biomeConfig())\n write(dir, 'multisite.config.ts', multisiteConfig())\n write(dir, 'server.ts', serverEntry())\n write(dir, 'build.ts', buildEntry())\n write(dir, 'src/routes/_layout.tsx', baseLayout(title))\n write(dir, 'src/routes/index.page.tsx', baseIndexPage(title))\n write(dir, 'sites/main/routes/_layout.tsx', siteLayout())\n write(dir, 'sites/main/routes/index.page.tsx', siteIndexPage(title))\n\n console.log(`\\n Created multisite project: ${name}\\n`)\n console.log(' Next steps:\\n')\n console.log(` cd ${name}`)\n console.log(' npm install')\n console.log(' npm run dev\\n')\n console.log(' Docs: https://davaux.codeberg.page/docs/packages/multisite\\n')\n}\n\nfunction write(dir: string, file: string, content: string) {\n writeFileSync(join(dir, file), content, 'utf8')\n}\n\nfunction packageJson(name: string) {\n return (\n JSON.stringify(\n {\n name,\n version: '0.1.0',\n type: 'module',\n scripts: {\n dev: 'node --watch --import tsx/esm server.ts',\n build: 'tsx build.ts',\n start: 'NODE_ENV=production node dist/server.js',\n },\n dependencies: {\n '@davaux/multisite': 'latest',\n davaux: 'latest',\n },\n devDependencies: {\n '@biomejs/biome': 'latest',\n '@types/node': 'latest',\n tsx: 'latest',\n },\n },\n null,\n 2,\n ) + '\\n'\n )\n}\n\nfunction tsConfig() {\n return (\n JSON.stringify(\n {\n compilerOptions: {\n target: 'ESNext',\n module: 'NodeNext',\n moduleResolution: 'NodeNext',\n jsx: 'react-jsx',\n jsxImportSource: 'davaux',\n strict: true,\n lib: ['ESNext', 'DOM'],\n allowImportingTsExtensions: true,\n noEmit: true,\n skipLibCheck: true,\n types: ['node', 'davaux/env'],\n },\n include: ['src/**/*', 'sites/**/*', '*.ts'],\n },\n null,\n 2,\n ) + '\\n'\n )\n}\n\nfunction biomeConfig() {\n return (\n JSON.stringify(\n {\n $schema: 'https://biomejs.dev/schemas/2.4.15/schema.json',\n assist: { actions: { source: { organizeImports: 'on' } } },\n linter: {\n enabled: true,\n rules: {\n recommended: true,\n correctness: {\n noUnusedVariables: 'error',\n noUnusedImports: 'error',\n },\n style: {\n noNonNullAssertion: 'warn',\n },\n },\n },\n formatter: {\n enabled: true,\n indentStyle: 'space',\n indentWidth: 2,\n lineWidth: 100,\n },\n javascript: {\n formatter: {\n quoteStyle: 'single',\n trailingCommas: 'all',\n semicolons: 'asNeeded',\n },\n },\n css: {\n formatter: {\n enabled: true,\n quoteStyle: 'single',\n },\n },\n files: {\n includes: ['src/**', 'sites/**', '*.ts'],\n },\n },\n null,\n 2,\n ) + '\\n'\n )\n}\n\nfunction multisiteConfig() {\n return `import { join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { defineSites } from '@davaux/multisite'\n\nconst root = fileURLToPath(new URL('.', import.meta.url))\n\nexport interface SiteConfig {\n name: string\n primaryColor: string\n}\n\nexport const sites = defineSites<SiteConfig>({\n baseDir: join(root, 'src/routes'),\n sites: [\n {\n name: 'main',\n hostname: 'localhost',\n routesDir: join(root, 'sites/main/routes'),\n config: { name: 'Main Site', primaryColor: '#1d4ed8' },\n },\n {\n name: 'fallback',\n hostname: '*',\n config: { name: 'Fallback', primaryColor: '#374151' },\n },\n ],\n})\n`\n}\n\nfunction serverEntry() {\n return `import { startMultisite } from '@davaux/multisite'\nimport { sites } from './multisite.config.js'\n\nstartMultisite(sites, { port: 3000, hostname: 'localhost', cwd: import.meta.dirname })\n`\n}\n\nfunction buildEntry() {\n return `import { buildMultisite } from '@davaux/multisite/build'\nimport { sites } from './multisite.config.js'\n\nawait buildMultisite(sites, { cwd: import.meta.dirname })\n`\n}\n\nfunction baseLayout(title: string) {\n return `import { defineLayout } from 'davaux'\n\nexport default defineLayout(({ children, ctx }) => (\n <html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>{ctx.head.title ?? '${title}'}</title>\n {ctx.head.description && <meta name=\"description\" content={ctx.head.description} />}\n {Object.entries(ctx.head.meta).map(([name, content]) => (\n <meta name={name} content={content} />\n ))}\n {ctx.head.stylesheets.map((href) => (\n <link rel=\"stylesheet\" href={href} />\n ))}\n </head>\n <body>\n {children as unknown as string}\n {ctx.head.scripts.map((src) => (\n <script type=\"module\" src={src}></script>\n ))}\n </body>\n </html>\n))\n`\n}\n\nfunction baseIndexPage(title: string) {\n return `import { definePage } from 'davaux'\n\nexport default definePage((ctx) => {\n ctx.head.title = '${title}'\n return (\n <main>\n <h1>Welcome to ${title}</h1>\n <p>\n This page is served from the shared base routes (<code>src/routes/</code>). It is visible\n at any hostname not explicitly registered in <code>multisite.config.ts</code> \u2014 in this\n project, that means any hostname other than <code>localhost</code>.\n </p>\n <h2>Get started</h2>\n <ul>\n <li>\n <a href=\"https://davaux.codeberg.page/docs/packages/multisite\">@davaux/multisite</a>\n {' \u2014 '}concepts, API reference, and operating modes\n </li>\n <li>\n <a href=\"https://davaux.codeberg.page/docs/routing\">Routing</a>\n {' \u2014 '}file-based routing, dynamic segments, layouts, and middlewares\n </li>\n <li>\n <a href=\"https://davaux.codeberg.page/docs/getting-started\">Getting started</a>\n {' \u2014 '}core Davaux concepts\n </li>\n </ul>\n <h2>Project structure</h2>\n <ul>\n <li>\n <code>multisite.config.ts</code> \u2014 site definitions and per-site config\n </li>\n <li>\n <code>src/routes/</code> \u2014 shared base routes (you are here)\n </li>\n <li>\n <code>sites/main/routes/</code> \u2014 main site overrides (served at <code>localhost</code>)\n </li>\n <li>\n <code>server.ts</code> \u2014 starts the dev and production server\n </li>\n <li>\n <code>build.ts</code> \u2014 production build script\n </li>\n </ul>\n </main>\n )\n})\n`\n}\n\nfunction siteLayout() {\n return `export { default } from '../../../src/routes/_layout.js'\n`\n}\n\nfunction siteIndexPage(title: string) {\n return `import { definePage } from 'davaux'\nimport { getSite } from '@davaux/multisite'\nimport type { SiteConfig } from '../../../multisite.config.js'\n\nexport default definePage((ctx) => {\n const site = getSite<SiteConfig>(ctx)\n ctx.head.title = site?.name ?? '${title}'\n return (\n <main>\n <h1>Welcome to {site?.name ?? '${title}'}</h1>\n <p>\n You're looking at the <strong>main</strong> site. Edit{' '}\n <code>sites/main/routes/index.page.tsx</code> to get started.\n </p>\n <p>\n Site config is defined in <code>multisite.config.ts</code> and accessed here via{' '}\n <code>getSite(ctx)</code>. Use it for per-site themes, database URLs, feature flags \u2014\n anything that varies between sites.\n </p>\n </main>\n )\n})\n`\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,2 @@
1
+ export declare function scaffold(name: string | undefined, cwd: string): Promise<void>;
2
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../src/create.ts"],"names":[],"mappings":"AAGA,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,iBAqCnE"}
package/dist/create.js ADDED
@@ -0,0 +1,179 @@
1
+ import { existsSync, mkdirSync, writeFileSync } from "node:fs";
2
+ import { join, resolve } from "node:path";
3
+ async function scaffold(name, cwd) {
4
+ if (!name) {
5
+ console.error("Usage: davaux create <project-name>");
6
+ process.exit(1);
7
+ }
8
+ if (!/^[a-z0-9]([a-z0-9._-]*[a-z0-9])?$/.test(name)) {
9
+ console.error(
10
+ `[davaux] Invalid project name "${name}". Use lowercase letters, numbers, hyphens, underscores, or dots.`
11
+ );
12
+ process.exit(1);
13
+ }
14
+ const dir = resolve(cwd, name);
15
+ if (existsSync(dir)) {
16
+ console.error(`[davaux] Directory "${name}" already exists.`);
17
+ process.exit(1);
18
+ }
19
+ const title = name.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
20
+ mkdirSync(join(dir, "src", "routes"), { recursive: true });
21
+ mkdirSync(join(dir, "public"), { recursive: true });
22
+ write(dir, "package.json", packageJson(name));
23
+ write(dir, "tsconfig.json", tsConfig());
24
+ write(dir, "davaux.config.ts", davauxConfig());
25
+ write(dir, "biome.json", biomeConfig());
26
+ write(dir, "src/routes/_layout.tsx", layout(title));
27
+ write(dir, "src/routes/index.page.tsx", indexPage(title));
28
+ console.log(`
29
+ Created project: ${name}
30
+ `);
31
+ console.log(" Next steps:\n");
32
+ console.log(` cd ${name}`);
33
+ console.log(" npm install");
34
+ console.log(" npm run dev\n");
35
+ }
36
+ function write(dir, file, content) {
37
+ writeFileSync(join(dir, file), content, "utf8");
38
+ }
39
+ function packageJson(name) {
40
+ return JSON.stringify(
41
+ {
42
+ name,
43
+ version: "0.1.0",
44
+ type: "module",
45
+ scripts: {
46
+ dev: "davaux dev",
47
+ build: "davaux build",
48
+ start: "davaux start"
49
+ },
50
+ dependencies: {
51
+ davaux: "latest"
52
+ },
53
+ devDependencies: {
54
+ "@biomejs/biome": "latest",
55
+ "@types/node": "latest"
56
+ }
57
+ },
58
+ null,
59
+ 2
60
+ ) + "\n";
61
+ }
62
+ function tsConfig() {
63
+ return JSON.stringify(
64
+ {
65
+ compilerOptions: {
66
+ target: "ESNext",
67
+ module: "NodeNext",
68
+ moduleResolution: "NodeNext",
69
+ jsx: "react-jsx",
70
+ jsxImportSource: "davaux",
71
+ strict: true,
72
+ lib: ["ESNext", "DOM"],
73
+ allowImportingTsExtensions: true,
74
+ noEmit: true,
75
+ skipLibCheck: true,
76
+ types: ["node", "davaux/env"]
77
+ },
78
+ include: ["src/**/*"]
79
+ },
80
+ null,
81
+ 2
82
+ ) + "\n";
83
+ }
84
+ function davauxConfig() {
85
+ return `import { defineConfig } from 'davaux/config'
86
+
87
+ export default defineConfig({
88
+ server: {
89
+ port: 3000,
90
+ hostname: 'localhost',
91
+ },
92
+ })
93
+ `;
94
+ }
95
+ function biomeConfig() {
96
+ return JSON.stringify(
97
+ {
98
+ $schema: "https://biomejs.dev/schemas/2.4.15/schema.json",
99
+ assist: { actions: { source: { organizeImports: "on" } } },
100
+ linter: {
101
+ enabled: true,
102
+ rules: {
103
+ recommended: true,
104
+ correctness: {
105
+ noUnusedVariables: "error",
106
+ noUnusedImports: "error"
107
+ },
108
+ style: {
109
+ noNonNullAssertion: "warn"
110
+ }
111
+ }
112
+ },
113
+ formatter: {
114
+ enabled: true,
115
+ indentStyle: "space",
116
+ indentWidth: 2,
117
+ lineWidth: 100
118
+ },
119
+ javascript: {
120
+ formatter: {
121
+ quoteStyle: "single",
122
+ trailingCommas: "all",
123
+ semicolons: "asNeeded"
124
+ }
125
+ },
126
+ css: {
127
+ formatter: {
128
+ enabled: true,
129
+ quoteStyle: "single"
130
+ }
131
+ },
132
+ files: {
133
+ includes: ["src/**"]
134
+ }
135
+ },
136
+ null,
137
+ 2
138
+ ) + "\n";
139
+ }
140
+ function layout(title) {
141
+ return `import { defineLayout } from 'davaux'
142
+
143
+ export default defineLayout(({ children, ctx }) => (
144
+ <html lang="en">
145
+ <head>
146
+ <meta charset="utf-8" />
147
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
148
+ <title>{ctx.head.title ?? '${title}'}</title>
149
+ {ctx.head.description && <meta name="description" content={ctx.head.description} />}
150
+ {Object.entries(ctx.head.meta).map(([name, content]) => (
151
+ <meta name={name} content={content} />
152
+ ))}
153
+ {ctx.head.stylesheets.map((href) => (
154
+ <link rel="stylesheet" href={href} />
155
+ ))}
156
+ </head>
157
+ <body>
158
+ {children as unknown as string}
159
+ {ctx.head.scripts.map((src) => (
160
+ <script type="module" src={src}></script>
161
+ ))}
162
+ </body>
163
+ </html>
164
+ ))
165
+ `;
166
+ }
167
+ function indexPage(title) {
168
+ return `import { definePage } from 'davaux'
169
+
170
+ export default definePage((ctx) => {
171
+ ctx.head.title = '${title}'
172
+ return <h1>Welcome to ${title}</h1>
173
+ })
174
+ `;
175
+ }
176
+ export {
177
+ scaffold
178
+ };
179
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/create.ts"],
4
+ "sourcesContent": ["import { existsSync, mkdirSync, writeFileSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\n\nexport async function scaffold(name: string | undefined, cwd: string) {\n if (!name) {\n console.error('Usage: davaux create <project-name>')\n process.exit(1)\n }\n\n if (!/^[a-z0-9]([a-z0-9._-]*[a-z0-9])?$/.test(name)) {\n console.error(\n `[davaux] Invalid project name \"${name}\". Use lowercase letters, numbers, hyphens, underscores, or dots.`,\n )\n process.exit(1)\n }\n\n const dir = resolve(cwd, name)\n\n if (existsSync(dir)) {\n console.error(`[davaux] Directory \"${name}\" already exists.`)\n process.exit(1)\n }\n\n const title = name.replace(/[-_]/g, ' ').replace(/\\b\\w/g, (c) => c.toUpperCase())\n\n mkdirSync(join(dir, 'src', 'routes'), { recursive: true })\n mkdirSync(join(dir, 'public'), { recursive: true })\n\n write(dir, 'package.json', packageJson(name))\n write(dir, 'tsconfig.json', tsConfig())\n write(dir, 'davaux.config.ts', davauxConfig())\n write(dir, 'biome.json', biomeConfig())\n write(dir, 'src/routes/_layout.tsx', layout(title))\n write(dir, 'src/routes/index.page.tsx', indexPage(title))\n\n console.log(`\\n Created project: ${name}\\n`)\n console.log(' Next steps:\\n')\n console.log(` cd ${name}`)\n console.log(' npm install')\n console.log(' npm run dev\\n')\n}\n\nfunction write(dir: string, file: string, content: string) {\n writeFileSync(join(dir, file), content, 'utf8')\n}\n\nfunction packageJson(name: string) {\n return (\n JSON.stringify(\n {\n name,\n version: '0.1.0',\n type: 'module',\n scripts: {\n dev: 'davaux dev',\n build: 'davaux build',\n start: 'davaux start',\n },\n dependencies: {\n davaux: 'latest',\n },\n devDependencies: {\n '@biomejs/biome': 'latest',\n '@types/node': 'latest',\n },\n },\n null,\n 2,\n ) + '\\n'\n )\n}\n\nfunction tsConfig() {\n return (\n JSON.stringify(\n {\n compilerOptions: {\n target: 'ESNext',\n module: 'NodeNext',\n moduleResolution: 'NodeNext',\n jsx: 'react-jsx',\n jsxImportSource: 'davaux',\n strict: true,\n lib: ['ESNext', 'DOM'],\n allowImportingTsExtensions: true,\n noEmit: true,\n skipLibCheck: true,\n types: ['node', 'davaux/env'],\n },\n include: ['src/**/*'],\n },\n null,\n 2,\n ) + '\\n'\n )\n}\n\nfunction davauxConfig() {\n return `import { defineConfig } from 'davaux/config'\n\nexport default defineConfig({\n server: {\n port: 3000,\n hostname: 'localhost',\n },\n})\n`\n}\n\nfunction biomeConfig() {\n return (\n JSON.stringify(\n {\n $schema: 'https://biomejs.dev/schemas/2.4.15/schema.json',\n assist: { actions: { source: { organizeImports: 'on' } } },\n linter: {\n enabled: true,\n rules: {\n recommended: true,\n correctness: {\n noUnusedVariables: 'error',\n noUnusedImports: 'error',\n },\n style: {\n noNonNullAssertion: 'warn',\n },\n },\n },\n formatter: {\n enabled: true,\n indentStyle: 'space',\n indentWidth: 2,\n lineWidth: 100,\n },\n javascript: {\n formatter: {\n quoteStyle: 'single',\n trailingCommas: 'all',\n semicolons: 'asNeeded',\n },\n },\n css: {\n formatter: {\n enabled: true,\n quoteStyle: 'single',\n },\n },\n files: {\n includes: ['src/**'],\n },\n },\n null,\n 2,\n ) + '\\n'\n )\n}\n\nfunction layout(title: string) {\n return `import { defineLayout } from 'davaux'\n\nexport default defineLayout(({ children, ctx }) => (\n <html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>{ctx.head.title ?? '${title}'}</title>\n {ctx.head.description && <meta name=\"description\" content={ctx.head.description} />}\n {Object.entries(ctx.head.meta).map(([name, content]) => (\n <meta name={name} content={content} />\n ))}\n {ctx.head.stylesheets.map((href) => (\n <link rel=\"stylesheet\" href={href} />\n ))}\n </head>\n <body>\n {children as unknown as string}\n {ctx.head.scripts.map((src) => (\n <script type=\"module\" src={src}></script>\n ))}\n </body>\n </html>\n))\n`\n}\n\nfunction indexPage(title: string) {\n return `import { definePage } from 'davaux'\n\nexport default definePage((ctx) => {\n ctx.head.title = '${title}'\n return <h1>Welcome to ${title}</h1>\n})\n`\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,11 @@
1
+ import type { OmlPropSchema } from '../oml/types.js';
2
+ export type BlueprintEntry = {
3
+ id: string;
4
+ name: string;
5
+ props: Record<string, OmlPropSchema>;
6
+ previewHtml: string;
7
+ jsxSnippet: string;
8
+ imports: Record<string, string>;
9
+ };
10
+ export declare function scanBlueprints(cwd: string): BlueprintEntry[];
11
+ //# sourceMappingURL=blueprints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blueprints.d.ts","sourceRoot":"","sources":["../../src/dev/blueprints.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAgB,aAAa,EAAe,MAAM,iBAAiB,CAAA;AAG/E,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;IACpC,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAChC,CAAA;AAsCD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,EAAE,CAuB5D"}
@@ -0,0 +1,65 @@
1
+ import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
2
+ import { extname, join } from "node:path";
3
+ import { renderToHtml } from "../oml/render.js";
4
+ import { parseOmlBlueprint } from "../oml/types.js";
5
+ function collectJsonFiles(dir, out) {
6
+ if (!existsSync(dir)) return;
7
+ for (const entry of readdirSync(dir)) {
8
+ const full = join(dir, entry);
9
+ if (statSync(full).isDirectory()) {
10
+ collectJsonFiles(full, out);
11
+ } else if (extname(entry) === ".json") {
12
+ out.push(full);
13
+ }
14
+ }
15
+ }
16
+ function propPlaceholder(schema) {
17
+ if (schema.default !== void 0) {
18
+ const d = schema.default;
19
+ if (typeof d === "string") return `"${d}"`;
20
+ return `{${JSON.stringify(d)}}`;
21
+ }
22
+ const placeholders = {
23
+ string: '"example"',
24
+ number: "{0}",
25
+ boolean: "{false}",
26
+ function: "{() => {}}",
27
+ node: '"content"',
28
+ array: "{[]}"
29
+ };
30
+ return placeholders[schema.type] ?? '"example"';
31
+ }
32
+ function toUsageJsx(bp) {
33
+ const entries = Object.entries(bp.props);
34
+ if (entries.length === 0) return `<${bp.name} />`;
35
+ const lines = entries.map(([name, schema]) => ` ${name}=${propPlaceholder(schema)}`);
36
+ return `<${bp.name}
37
+ ${lines.join("\n")}
38
+ />`;
39
+ }
40
+ function scanBlueprints(cwd) {
41
+ const files = [];
42
+ collectJsonFiles(join(cwd, "src", "blueprints"), files);
43
+ collectJsonFiles(join(cwd, "src", "components"), files);
44
+ const results = [];
45
+ for (const filePath of files) {
46
+ try {
47
+ const raw = JSON.parse(readFileSync(filePath, "utf-8"));
48
+ const bp = parseOmlBlueprint(raw);
49
+ results.push({
50
+ id: bp.id,
51
+ name: bp.name,
52
+ props: bp.props,
53
+ previewHtml: bp.output ? renderToHtml(bp.output) : "",
54
+ jsxSnippet: toUsageJsx(bp),
55
+ imports: bp.imports ?? {}
56
+ });
57
+ } catch {
58
+ }
59
+ }
60
+ return results;
61
+ }
62
+ export {
63
+ scanBlueprints
64
+ };
65
+ //# sourceMappingURL=blueprints.js.map