@stacksjs/stx 0.1.16 → 0.2.3

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 (277) hide show
  1. package/dist/a11y.d.ts +109 -5
  2. package/dist/analytics.d.ts +40 -0
  3. package/dist/animation.d.ts +91 -1
  4. package/dist/app.d.ts +51 -0
  5. package/dist/ast.d.ts +286 -0
  6. package/dist/async-components.d.ts +101 -0
  7. package/dist/auth.d.ts +1 -3
  8. package/dist/browser-composables.d.ts +314 -0
  9. package/dist/build-optimizer.d.ts +126 -0
  10. package/dist/build-views.d.ts +37 -0
  11. package/dist/bundle-analyzer/collector.d.ts +66 -0
  12. package/dist/bundle-analyzer/index.d.ts +60 -0
  13. package/dist/bundle-analyzer/report.d.ts +39 -0
  14. package/dist/bundle-analyzer/treemap.d.ts +19 -0
  15. package/dist/bundle-analyzer.js +499 -0
  16. package/dist/caching.d.ts +7 -0
  17. package/dist/cli.js +10885 -1203
  18. package/dist/client/directive.d.ts +10 -0
  19. package/dist/client/index.d.ts +7 -0
  20. package/dist/client/router.d.ts +36 -0
  21. package/dist/client/stx-router.browser.d.ts +0 -0
  22. package/dist/client-script.d.ts +22 -0
  23. package/dist/component-hmr.d.ts +120 -0
  24. package/dist/components.d.ts +23 -1
  25. package/dist/composables/index.d.ts +277 -0
  26. package/dist/composables/use-battery.d.ts +46 -0
  27. package/dist/composables/use-broadcast-channel.d.ts +58 -0
  28. package/dist/composables/use-clipboard.d.ts +34 -0
  29. package/dist/composables/use-cookie.d.ts +70 -0
  30. package/dist/composables/use-device-orientation.d.ts +109 -0
  31. package/dist/composables/use-event-source.d.ts +77 -0
  32. package/dist/composables/use-eye-dropper.d.ts +107 -0
  33. package/dist/composables/use-fetch.d.ts +84 -0
  34. package/dist/composables/use-fullscreen.d.ts +47 -0
  35. package/dist/composables/use-geolocation.d.ts +62 -0
  36. package/dist/composables/use-idle.d.ts +84 -0
  37. package/dist/composables/use-intersection-observer.d.ts +81 -0
  38. package/dist/composables/use-keyboard.d.ts +100 -0
  39. package/dist/composables/use-media-query.d.ts +56 -0
  40. package/dist/composables/use-mouse.d.ts +64 -0
  41. package/dist/composables/use-mutation-observer.d.ts +101 -0
  42. package/dist/composables/use-network.d.ts +40 -0
  43. package/dist/composables/use-notification.d.ts +89 -0
  44. package/dist/composables/use-permissions.d.ts +109 -0
  45. package/dist/composables/use-resize-observer.d.ts +60 -0
  46. package/dist/composables/use-share.d.ts +70 -0
  47. package/dist/composables/use-speech.d.ts +117 -0
  48. package/dist/composables/use-storage.d.ts +64 -0
  49. package/dist/composables/use-text-selection.d.ts +97 -0
  50. package/dist/composables/use-wake-lock.d.ts +85 -0
  51. package/dist/composables/use-websocket.d.ts +69 -0
  52. package/dist/composables/use-window.d.ts +84 -0
  53. package/dist/composables.d.ts +268 -0
  54. package/dist/composition-api.d.ts +190 -0
  55. package/dist/computed.d.ts +137 -0
  56. package/dist/conditionals.d.ts +14 -2
  57. package/dist/config.d.ts +36 -3
  58. package/dist/craft-bridge.d.ts +319 -0
  59. package/dist/craft-compiler.d.ts +229 -0
  60. package/dist/craft-components.d.ts +411 -0
  61. package/dist/craft-entry.d.ts +5 -0
  62. package/dist/craft-ssr.d.ts +134 -0
  63. package/dist/craft.js +1553 -0
  64. package/dist/csp.d.ts +229 -0
  65. package/dist/database.d.ts +407 -0
  66. package/dist/database.js +5 -0
  67. package/dist/defer.d.ts +4 -0
  68. package/dist/deploy/config-generators.d.ts +75 -0
  69. package/dist/deploy/index.d.ts +84 -0
  70. package/dist/deploy/netlify.d.ts +109 -0
  71. package/dist/dev-server/crosswind.d.ts +54 -0
  72. package/dist/dev-server/index.d.ts +7 -0
  73. package/dist/dev-server/keyboard-shortcuts.d.ts +34 -0
  74. package/dist/dev-server/native-window.d.ts +40 -0
  75. package/dist/dev-server/port-utils.d.ts +27 -0
  76. package/dist/dev-server/terminal-colors.d.ts +60 -0
  77. package/dist/dev-server/theme-selector.d.ts +32 -0
  78. package/dist/dev-server/types.d.ts +92 -0
  79. package/dist/dev-server.d.ts +21 -0
  80. package/dist/devtools.d.ts +142 -0
  81. package/dist/directive-api.d.ts +111 -0
  82. package/dist/dynamic-components.d.ts +14 -0
  83. package/dist/edge-runtime.d.ts +200 -0
  84. package/dist/env.d.ts +9 -0
  85. package/dist/error-boundaries.d.ts +71 -0
  86. package/dist/error-handling.d.ts +1 -101
  87. package/dist/errors/codes.d.ts +99 -0
  88. package/dist/errors/formatter.d.ts +64 -0
  89. package/dist/errors/index.d.ts +56 -0
  90. package/dist/errors/logger.d.ts +74 -0
  91. package/dist/errors/sanitizer.d.ts +43 -0
  92. package/dist/errors/types.d.ts +79 -0
  93. package/dist/events.d.ts +106 -0
  94. package/dist/expressions.d.ts +86 -11
  95. package/dist/formatter.d.ts +4 -0
  96. package/dist/forms-validation.d.ts +173 -0
  97. package/dist/forms.d.ts +157 -8
  98. package/dist/head.d.ts +225 -0
  99. package/dist/heatmap.d.ts +125 -0
  100. package/dist/hot-reload.d.ts +87 -0
  101. package/dist/hydration-runtime.d.ts +47 -0
  102. package/dist/hydration.d.ts +161 -0
  103. package/dist/i18n.d.ts +240 -4
  104. package/dist/image-optimization/build-plugin.d.ts +53 -0
  105. package/dist/image-optimization/component.d.ts +46 -0
  106. package/dist/image-optimization/directive.d.ts +30 -0
  107. package/dist/image-optimization/index.d.ts +86 -0
  108. package/dist/image-optimization/processor.d.ts +112 -0
  109. package/dist/includes.d.ts +94 -9
  110. package/dist/index.d.ts +63 -3
  111. package/dist/index.js +11604 -1318
  112. package/dist/init.d.ts +32 -2
  113. package/dist/interactive.d.ts +14 -0
  114. package/dist/internal-markdown.d.ts +22 -0
  115. package/dist/jsx-runtime.d.ts +110 -0
  116. package/dist/keep-alive.d.ts +87 -0
  117. package/dist/lazy-loader.d.ts +122 -0
  118. package/dist/loading-indicator.d.ts +40 -0
  119. package/dist/loops.d.ts +22 -1
  120. package/dist/media/client/blur-up.d.ts +65 -0
  121. package/dist/media/client/index.d.ts +77 -0
  122. package/dist/media/client/lazy-load.d.ts +73 -0
  123. package/dist/media/client/upload-handler.d.ts +79 -0
  124. package/dist/media/image/component.d.ts +46 -0
  125. package/dist/media/image/directive.d.ts +9 -0
  126. package/dist/media/image/editing.d.ts +212 -0
  127. package/dist/media/image/index.d.ts +118 -0
  128. package/dist/media/image/placeholder.d.ts +78 -0
  129. package/dist/media/image/processor/cache.d.ts +32 -0
  130. package/dist/media/image/processor/index.d.ts +12 -0
  131. package/dist/media/image/processor/optimizer.d.ts +13 -0
  132. package/dist/media/image/processor/responsive.d.ts +17 -0
  133. package/dist/media/image/srcset.d.ts +158 -0
  134. package/dist/media/index.d.ts +295 -0
  135. package/dist/media/manager/embed.d.ts +25 -0
  136. package/dist/media/protected/component.d.ts +34 -0
  137. package/dist/media/protected/index.d.ts +34 -0
  138. package/dist/media/protected/signature.d.ts +72 -0
  139. package/dist/media/shared/cache.d.ts +54 -0
  140. package/dist/media/shared/hash.d.ts +24 -0
  141. package/dist/media/shared/index.d.ts +2 -0
  142. package/dist/media/types.d.ts +1051 -0
  143. package/dist/media/upload/component.d.ts +23 -0
  144. package/dist/media/upload/index.d.ts +1 -0
  145. package/dist/media/video/directive.d.ts +9 -0
  146. package/dist/media/video/index.d.ts +47 -0
  147. package/dist/media/video/processor/cache.d.ts +33 -0
  148. package/dist/media/video/processor/index.d.ts +21 -0
  149. package/dist/media/video/processor/streaming.d.ts +19 -0
  150. package/dist/media/video/processor/thumbnail.d.ts +28 -0
  151. package/dist/media/video/processor/transcoder.d.ts +9 -0
  152. package/dist/middleware.d.ts +42 -3
  153. package/dist/native-build.d.ts +74 -0
  154. package/dist/parser/directive-parser.d.ts +79 -0
  155. package/dist/parser/expression-parser.d.ts +59 -0
  156. package/dist/parser/index.d.ts +35 -0
  157. package/dist/parser/tokenizer.d.ts +81 -0
  158. package/dist/partial-hydration.d.ts +88 -0
  159. package/dist/performance-utils.d.ts +146 -3
  160. package/dist/plugin-system.d.ts +128 -0
  161. package/dist/plugin.d.ts +1 -0
  162. package/dist/precompiler.d.ts +108 -0
  163. package/dist/production-build.d.ts +199 -0
  164. package/dist/props.d.ts +199 -0
  165. package/dist/pwa/audit.d.ts +42 -0
  166. package/dist/pwa/directives.d.ts +29 -0
  167. package/dist/pwa/icons.d.ts +39 -0
  168. package/dist/pwa/index.d.ts +59 -0
  169. package/dist/pwa/inject.d.ts +22 -0
  170. package/dist/pwa/manifest.d.ts +104 -0
  171. package/dist/pwa/offline.d.ts +8 -0
  172. package/dist/pwa/precache.d.ts +29 -0
  173. package/dist/pwa/service-worker.d.ts +21 -0
  174. package/dist/pwa/workbox-strategies.d.ts +100 -0
  175. package/dist/pwa/workbox.d.ts +52 -0
  176. package/dist/pwa.d.ts +51 -0
  177. package/dist/pwa.js +8124 -0
  178. package/dist/reactive-bindings.d.ts +24 -0
  179. package/dist/reactive.d.ts +100 -0
  180. package/dist/reactivity.d.ts +253 -0
  181. package/dist/route-middleware.d.ts +232 -0
  182. package/dist/router.d.ts +31 -0
  183. package/dist/routes.d.ts +0 -7
  184. package/dist/runtime.d.ts +140 -0
  185. package/dist/safe-evaluator.d.ts +117 -3
  186. package/dist/scaffolding.d.ts +113 -0
  187. package/dist/seo.d.ts +120 -7
  188. package/dist/server-components.d.ts +134 -0
  189. package/dist/signals.d.ts +501 -0
  190. package/dist/slots.d.ts +63 -0
  191. package/dist/source-maps.d.ts +117 -0
  192. package/dist/ssg.d.ts +157 -0
  193. package/dist/ssg.js +6831 -0
  194. package/dist/ssr.d.ts +107 -0
  195. package/dist/state-management.d.ts +324 -0
  196. package/dist/stores-client.d.ts +70 -0
  197. package/dist/story/addons.d.ts +123 -0
  198. package/dist/story/analytics.d.ts +92 -0
  199. package/dist/story/auto-stories.d.ts +38 -0
  200. package/dist/story/bookmarks.d.ts +53 -0
  201. package/dist/story/bun-test.d.ts +44 -0
  202. package/dist/story/cli.d.ts +34 -0
  203. package/dist/story/collect/analyzer.d.ts +33 -0
  204. package/dist/story/collect/index.d.ts +27 -0
  205. package/dist/story/collect/parser.d.ts +17 -0
  206. package/dist/story/collect/scanner.d.ts +13 -0
  207. package/dist/story/collect/tree.d.ts +17 -0
  208. package/dist/story/commands/build.d.ts +14 -0
  209. package/dist/story/commands/dev.d.ts +16 -0
  210. package/dist/story/commands/index.d.ts +6 -0
  211. package/dist/story/commands/preview.d.ts +15 -0
  212. package/dist/story/compiled-output.d.ts +26 -0
  213. package/dist/story/composition.d.ts +47 -0
  214. package/dist/story/config-watcher.d.ts +26 -0
  215. package/dist/story/config.d.ts +26 -0
  216. package/dist/story/context.d.ts +21 -0
  217. package/dist/story/controls/index.d.ts +54 -0
  218. package/dist/story/crosswind.d.ts +29 -0
  219. package/dist/story/desktop-preview.d.ts +34 -0
  220. package/dist/story/docs-generator.d.ts +30 -0
  221. package/dist/story/errors.d.ts +47 -0
  222. package/dist/story/figma-export.d.ts +169 -0
  223. package/dist/story/generator.d.ts +21 -0
  224. package/dist/story/hmr.d.ts +64 -0
  225. package/dist/story/hot-swap.d.ts +35 -0
  226. package/dist/story/index.d.ts +51 -0
  227. package/dist/story/interactions.d.ts +52 -0
  228. package/dist/story/keyboard-shortcuts.d.ts +34 -0
  229. package/dist/story/output.d.ts +85 -0
  230. package/dist/story/performance.d.ts +76 -0
  231. package/dist/story/presets.d.ts +62 -0
  232. package/dist/story/props-validation.d.ts +45 -0
  233. package/dist/story/renderer.d.ts +53 -0
  234. package/dist/story/search-index.d.ts +47 -0
  235. package/dist/story/search.d.ts +45 -0
  236. package/dist/story/server.d.ts +21 -0
  237. package/dist/story/setup.d.ts +47 -0
  238. package/dist/story/snapshots.d.ts +65 -0
  239. package/dist/story/testing.d.ts +58 -0
  240. package/dist/story/theme.d.ts +68 -0
  241. package/dist/story/types.d.ts +249 -0
  242. package/dist/story/ui/code-panel.d.ts +42 -0
  243. package/dist/story/ui/controls-panel.d.ts +25 -0
  244. package/dist/story/ui/index.d.ts +4 -0
  245. package/dist/story/ui/navigation.d.ts +55 -0
  246. package/dist/story/ui/preview.d.ts +46 -0
  247. package/dist/story/visual-testing.d.ts +45 -0
  248. package/dist/streaming.d.ts +82 -2
  249. package/dist/suspense.d.ts +83 -0
  250. package/dist/teleport.d.ts +9 -0
  251. package/dist/testing.d.ts +289 -0
  252. package/dist/transitions.d.ts +87 -0
  253. package/dist/type-checker.d.ts +109 -0
  254. package/dist/types/component-types.d.ts +129 -0
  255. package/dist/types/config-types.d.ts +336 -0
  256. package/dist/types/context-types.d.ts +99 -0
  257. package/dist/types/csp-types.d.ts +79 -0
  258. package/dist/types/directive-types.d.ts +259 -0
  259. package/dist/types/index.d.ts +98 -0
  260. package/dist/types/pwa-types.d.ts +218 -0
  261. package/dist/types.d.ts +1 -315
  262. package/dist/typescript-templates.d.ts +178 -0
  263. package/dist/utils.d.ts +52 -6
  264. package/dist/validator.d.ts +77 -0
  265. package/dist/variable-extractor.d.ts +39 -0
  266. package/dist/view-composers.d.ts +154 -9
  267. package/dist/virtual-scrolling.d.ts +103 -0
  268. package/dist/visual-editor.d.ts +209 -0
  269. package/dist/visual-testing.d.ts +109 -0
  270. package/dist/visual-testing.js +126 -0
  271. package/dist/vue-template.d.ts +16 -0
  272. package/dist/web-components/css-scoping.d.ts +54 -0
  273. package/dist/web-components/index.d.ts +20 -0
  274. package/dist/web-components/reactive-generator.d.ts +72 -0
  275. package/dist/web-components.d.ts +222 -2
  276. package/dist/x-element.d.ts +35 -0
  277. package/package.json +41 -10
package/dist/csp.d.ts ADDED
@@ -0,0 +1,229 @@
1
+ import type { CspConfig, CspDirectives, CspPreset, CustomDirective, StxOptions } from './types';
2
+ /**
3
+ * Generate a cryptographically secure nonce for CSP
4
+ *
5
+ * @param length - Length of nonce in bytes (default 16)
6
+ * @returns Base64-encoded nonce string
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const nonce = generateNonce()
11
+ * // Returns something like: "4AiRXmSkM+XRG3E2Y1fO9Q=="
12
+ * ```
13
+ */
14
+ export declare function generateNonce(length?: number): string;
15
+ /**
16
+ * Get or create a nonce for the current request context
17
+ *
18
+ * Uses WeakMap to ensure nonce is request-scoped and can be garbage collected.
19
+ * If no context is provided, generates a new nonce each time.
20
+ *
21
+ * @param context - Request context object for nonce scoping
22
+ * @param config - CSP configuration (may include custom nonce generator)
23
+ * @returns The nonce for the current context
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * // In a request handler
28
+ * const ctx = { requestId: '123' }
29
+ * const nonce = getNonce(ctx, cspConfig)
30
+ * // Same nonce returned for same context object
31
+ * const sameNonce = getNonce(ctx, cspConfig)
32
+ * ```
33
+ */
34
+ export declare function getNonce(context?: object, config?: CspConfig): string;
35
+ /**
36
+ * Clear the nonce for a context (useful for testing or manual cleanup)
37
+ *
38
+ * @param context - Request context to clear nonce for
39
+ */
40
+ export declare function clearNonce(context: object): void;
41
+ /**
42
+ * Generate a CSP header string from directive configuration
43
+ *
44
+ * @param directives - CSP directive configuration
45
+ * @param nonce - Optional nonce to inject into script-src and style-src
46
+ * @returns CSP header string
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * const header = generateCspHeader({
51
+ * 'default-src': ["'self'"],
52
+ * 'script-src': ["'self'", 'https://cdn.example.com'],
53
+ * 'upgrade-insecure-requests': true,
54
+ * })
55
+ * // Returns: "default-src 'self'; script-src 'self' https://cdn.example.com; upgrade-insecure-requests"
56
+ * ```
57
+ */
58
+ export declare function generateCspHeader(directives: CspDirectives, nonce?: string): string;
59
+ /**
60
+ * Generate CSP meta tag HTML
61
+ *
62
+ * @param directives - CSP directive configuration
63
+ * @param nonce - Optional nonce to inject
64
+ * @returns HTML meta tag string
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * const metaTag = generateCspMetaTag({
69
+ * 'default-src': ["'self'"],
70
+ * })
71
+ * // Returns: '<meta http-equiv="Content-Security-Policy" content="default-src \'self\'">'
72
+ * ```
73
+ */
74
+ export declare function generateCspMetaTag(directives: CspDirectives, nonce?: string): string;
75
+ /**
76
+ * Get a CSP preset configuration by name
77
+ *
78
+ * @param preset - Name of the preset
79
+ * @returns CSP configuration object
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * const config = getCspPreset('strict')
84
+ * // Returns full CspConfig with strict directives
85
+ * ```
86
+ */
87
+ export declare function getCspPreset(preset: CspPreset): CspConfig;
88
+ /**
89
+ * Merge two CSP directive configurations
90
+ *
91
+ * Sources from the second config are added to the first.
92
+ * Boolean directives are OR'd together.
93
+ *
94
+ * @param base - Base CSP directives
95
+ * @param override - Override/additional directives
96
+ * @returns Merged CSP directives
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * const merged = mergeCspDirectives(
101
+ * { 'default-src': ["'self'"], 'script-src': ["'self'"] },
102
+ * { 'script-src': ['https://cdn.example.com'], 'img-src': ['https:'] }
103
+ * )
104
+ * // Result: {
105
+ * // 'default-src': ["'self'"],
106
+ * // 'script-src': ["'self'", "https://cdn.example.com"],
107
+ * // 'img-src': ["https:"]
108
+ * // }
109
+ * ```
110
+ */
111
+ export declare function mergeCspDirectives(base: CspDirectives, override: CspDirectives): CspDirectives;
112
+ /**
113
+ * Inject CSP meta tag into HTML head
114
+ *
115
+ * @param html - HTML content
116
+ * @param config - CSP configuration
117
+ * @param context - Request context for nonce scoping
118
+ * @returns HTML with CSP meta tag injected
119
+ */
120
+ export declare function injectCspMetaTag(html: string, config: CspConfig, context?: object): string;
121
+ /**
122
+ * Add nonce attribute to all inline script and style tags
123
+ *
124
+ * @param html - HTML content
125
+ * @param nonce - Nonce value to add
126
+ * @returns HTML with nonce attributes added
127
+ */
128
+ export declare function addNonceToInlineContent(html: string, nonce: string): string;
129
+ /**
130
+ * Process CSP-related directives in templates
131
+ *
132
+ * Handles:
133
+ * - @csp - Insert CSP meta tag
134
+ * - @cspNonce - Output current nonce value
135
+ *
136
+ * @param template - Template content
137
+ * @param context - Template context
138
+ * @param _filePath - Source file path
139
+ * @param options - STX options
140
+ * @returns Processed template
141
+ */
142
+ export declare function processCspDirectives(template: string, context: Record<string, any>, _filePath: string, options: StxOptions): string;
143
+ /**
144
+ * Register CSP-related custom directives
145
+ *
146
+ * @returns Array of custom directives for CSP
147
+ */
148
+ export declare function registerCspDirectives(): CustomDirective[];
149
+ /**
150
+ * Validate CSP directive configuration
151
+ *
152
+ * @param directives - CSP directives to validate
153
+ * @returns Array of validation warnings
154
+ *
155
+ * @example
156
+ * ```typescript
157
+ * const warnings = validateCspDirectives({
158
+ * 'script-src': ["'unsafe-inline'", "'unsafe-eval'"],
159
+ * })
160
+ * // Returns warnings about unsafe usage
161
+ * ```
162
+ */
163
+ export declare function validateCspDirectives(directives: CspDirectives): string[];
164
+ /**
165
+ * Get the appropriate CSP header name based on configuration
166
+ *
167
+ * @param reportOnly - Whether to use report-only mode
168
+ * @returns Header name string
169
+ */
170
+ export declare function getCspHeaderName(reportOnly?: boolean): string;
171
+ /**
172
+ * Create CSP headers object for HTTP response
173
+ *
174
+ * @param config - CSP configuration
175
+ * @param context - Request context for nonce scoping
176
+ * @returns Headers object ready to spread into response
177
+ *
178
+ * @example
179
+ * ```typescript
180
+ * const headers = createCspHeaders(cspConfig, requestContext)
181
+ * return new Response(body, { headers: { ...headers } })
182
+ * ```
183
+ */
184
+ export declare function createCspHeaders(config: CspConfig, context?: object): Record<string, string>;
185
+ /**
186
+ * Strict CSP preset - Maximum security, may require nonces for inline content
187
+ *
188
+ * - No unsafe-inline or unsafe-eval
189
+ * - Uses strict-dynamic for scripts
190
+ * - Blocks object/embed
191
+ * - Restricts form actions to same origin
192
+ */
193
+ export declare const strictCspPreset: CspDirectives;
194
+ /**
195
+ * Moderate CSP preset - Balanced security and compatibility
196
+ *
197
+ * - Allows unsafe-inline for styles (common requirement)
198
+ * - Blocks unsafe-eval
199
+ * - Allows data: URIs for images
200
+ */
201
+ export declare const moderateCspPreset: CspDirectives;
202
+ /**
203
+ * Relaxed CSP preset - Basic protection, maximum compatibility
204
+ *
205
+ * - Allows unsafe-inline for both scripts and styles
206
+ * - Still blocks unsafe-eval and object embeds
207
+ */
208
+ export declare const relaxedCspPreset: CspDirectives;
209
+ /**
210
+ * API-only CSP preset - For JSON API responses
211
+ *
212
+ * - Blocks all content loading (APIs shouldn't render HTML)
213
+ * - Prevents framing
214
+ */
215
+ export declare const apiCspPreset: CspDirectives;
216
+ /**
217
+ * CSP meta tag directive
218
+ * Usage: @csp
219
+ */
220
+ export declare const cspDirective: CustomDirective;
221
+ /**
222
+ * CSP nonce directive
223
+ * Usage: @cspNonce
224
+ */
225
+ export declare const cspNonceDirective: CustomDirective;
226
+ /**
227
+ * Default CSP configuration - moderate preset
228
+ */
229
+ export declare const defaultCspConfig: CspConfig;
@@ -0,0 +1,407 @@
1
+ import type { StxOptions } from './types';
2
+ /**
3
+ * Configure database connections
4
+ *
5
+ * @param config - Database configuration
6
+ *
7
+ * @example
8
+ * configureDatabase({
9
+ * default: 'sqlite',
10
+ * connections: {
11
+ * sqlite: { driver: 'sqlite', database: './database.db' }
12
+ * }
13
+ * })
14
+ */
15
+ export declare function configureDatabase(config: Partial<DatabaseConfig>): void;
16
+ /**
17
+ * Get current database configuration
18
+ */
19
+ export declare function getDatabaseConfig(): DatabaseConfig;
20
+ /**
21
+ * Reset database configuration to defaults
22
+ */
23
+ export declare function resetDatabaseConfig(): void;
24
+ /**
25
+ * Register a custom database adapter
26
+ *
27
+ * @param name - Connection name
28
+ * @param adapter - Database adapter instance
29
+ */
30
+ export declare function registerAdapter(name: string, adapter: DatabaseAdapter): void;
31
+ /**
32
+ * Get database adapter for connection
33
+ *
34
+ * @param connection - Connection name (defaults to default connection)
35
+ */
36
+ export declare function getAdapter(connection?: string): DatabaseAdapter;
37
+ /**
38
+ * Create a new query builder for a table
39
+ *
40
+ * @param table - Table name
41
+ * @returns Query builder instance
42
+ *
43
+ * @example
44
+ * const users = await query('users')
45
+ * .where('active', true)
46
+ * .orderBy('name')
47
+ * .get()
48
+ */
49
+ export declare function query(table: string): QueryBuilder;
50
+ /**
51
+ * Alias for query()
52
+ */
53
+ export declare function table(name: string): QueryBuilder;
54
+ /**
55
+ * Create a raw SQL expression
56
+ */
57
+ export declare function raw(sql: string, bindings?: unknown[]): RawExpression;
58
+ /**
59
+ * Define a model
60
+ *
61
+ * @param name - Model name
62
+ * @param definition - Model definition
63
+ * @returns Model instance
64
+ *
65
+ * @example
66
+ * const User = defineModel('User', {
67
+ * table: 'users',
68
+ * primaryKey: 'id',
69
+ * fillable: ['name', 'email'],
70
+ * hidden: ['password'],
71
+ * relationships: {
72
+ * posts: { type: 'hasMany', model: 'Post', foreignKey: 'user_id' }
73
+ * }
74
+ * })
75
+ */
76
+ export declare function defineModel(name: string, definition: ModelDefinition): Model;
77
+ /**
78
+ * Get a registered model by name
79
+ */
80
+ export declare function getModel(name: string): Model;
81
+ /**
82
+ * Check if a model is registered
83
+ */
84
+ export declare function hasModel(name: string): boolean;
85
+ /**
86
+ * Run a callback within a transaction
87
+ *
88
+ * @param callback - Function to run within transaction
89
+ * @param connection - Optional connection name
90
+ *
91
+ * @example
92
+ * await transaction(async () => {
93
+ * await query('users').insert({ name: 'John' })
94
+ * await query('profiles').insert({ user_id: 1, bio: 'Hello' })
95
+ * })
96
+ */
97
+ export declare function transaction<T>(callback: () => Promise<T>, connection?: string): Promise<T>;
98
+ /**
99
+ * Clear all query cache
100
+ */
101
+ export declare function clearQueryCache(): void;
102
+ /**
103
+ * Get query cache statistics
104
+ */
105
+ export declare function getQueryCacheStats(): { size: number, keys: string[] };
106
+ /**
107
+ * Get query log
108
+ */
109
+ export declare function getQueryLog(): typeof queryLog;
110
+ /**
111
+ * Clear query log
112
+ */
113
+ export declare function clearQueryLog(): void;
114
+ /**
115
+ * Enable or disable query logging
116
+ */
117
+ export declare function enableQueryLogging(enabled?: boolean): void;
118
+ /**
119
+ * Process @db directive in templates
120
+ *
121
+ * Syntax: @db('table')->method()->method()
122
+ *
123
+ * @example
124
+ * @db('users')->where('active', true)->get()
125
+ * @db('posts')->orderBy('created_at', 'desc')->limit(5)->get()
126
+ */
127
+ export declare function processDbDirective(template: string, context: Record<string, any>, _filePath: string, _options: StxOptions): Promise<string>;
128
+ /**
129
+ * Process @model directive in templates
130
+ *
131
+ * Syntax: @model('ModelName')->method()
132
+ *
133
+ * @example
134
+ * @model('User')->find(1)
135
+ * @model('Post')->where('published', true)->get()
136
+ */
137
+ export declare function processModelDirective(template: string, context: Record<string, any>, _filePath: string, _options: StxOptions): Promise<string>;
138
+ /**
139
+ * Process @query directive for inline SQL
140
+ *
141
+ * Syntax: @query('SELECT * FROM users WHERE id = ?', [1])
142
+ */
143
+ export declare function processQueryDirective(template: string, context: Record<string, any>, _filePath: string, _options: StxOptions): Promise<string>;
144
+ /**
145
+ * Process all database-related directives in a template
146
+ */
147
+ export declare function processDatabaseDirectives(template: string, context: Record<string, any>, filePath: string, options: StxOptions): Promise<string>;
148
+ /**
149
+ * Get schema builder
150
+ */
151
+ export declare function schema(): SchemaBuilder;
152
+ /**
153
+ * Database connection configuration
154
+ */
155
+ export declare interface ConnectionConfig {
156
+ driver: DatabaseDriver
157
+ database: string
158
+ host?: string
159
+ port?: number
160
+ username?: string
161
+ password?: string
162
+ poolSize?: number
163
+ timeout?: number
164
+ ssl?: boolean | Record<string, unknown>
165
+ options?: Record<string, unknown>
166
+ }
167
+ /**
168
+ * Database configuration
169
+ */
170
+ export declare interface DatabaseConfig {
171
+ default: string
172
+ connections: Record<string, ConnectionConfig>
173
+ logging?: boolean
174
+ cacheTTL?: number
175
+ maxCacheSize?: number
176
+ }
177
+ /**
178
+ * Where clause condition
179
+ */
180
+ export declare interface WhereCondition {
181
+ column: string
182
+ operator: QueryOperator
183
+ value: unknown
184
+ boolean: 'and' | 'or'
185
+ }
186
+ /**
187
+ * Order by clause
188
+ */
189
+ export declare interface OrderByClause {
190
+ column: string
191
+ direction: 'asc' | 'desc'
192
+ }
193
+ /**
194
+ * Join clause
195
+ */
196
+ export declare interface JoinClause {
197
+ type: 'inner' | 'left' | 'right' | 'cross'
198
+ table: string
199
+ first: string
200
+ operator: string
201
+ second: string
202
+ }
203
+ /**
204
+ * Raw SQL expression
205
+ */
206
+ export declare interface RawExpression {
207
+ __raw: true
208
+ sql: string
209
+ bindings: unknown[]
210
+ }
211
+ /**
212
+ * Relationship definition
213
+ */
214
+ export declare interface RelationshipDefinition {
215
+ type: 'hasOne' | 'hasMany' | 'belongsTo' | 'belongsToMany'
216
+ model: string
217
+ foreignKey?: string
218
+ localKey?: string
219
+ pivotTable?: string
220
+ pivotForeignKey?: string
221
+ pivotRelatedKey?: string
222
+ }
223
+ /**
224
+ * Model definition
225
+ */
226
+ export declare interface ModelDefinition {
227
+ table: string
228
+ primaryKey?: string
229
+ fillable?: string[]
230
+ hidden?: string[]
231
+ timestamps?: { createdAt?: string, updatedAt?: string } | boolean
232
+ softDeletes?: string | boolean
233
+ defaults?: Record<string, unknown>
234
+ casts?: Record<string, 'string' | 'number' | 'boolean' | 'date' | 'json' | 'array'>
235
+ relationships?: Record<string, RelationshipDefinition>
236
+ scopes?: Record<string, (query: QueryBuilder) => QueryBuilder>
237
+ }
238
+ /**
239
+ * Model instance
240
+ */
241
+ export declare interface ModelInstance {
242
+ get: (key: string) => unknown
243
+ set: (key: string, value: unknown) => void
244
+ toJSON: () => Row
245
+ save: () => Promise<void>
246
+ delete: () => Promise<void>
247
+ refresh: () => Promise<void>
248
+ exists: boolean
249
+ original: Row
250
+ attributes: Row
251
+ isDirty: (key?: string) => boolean
252
+ }
253
+ /**
254
+ * Model class
255
+ */
256
+ export declare interface Model {
257
+ name: string
258
+ definition: ModelDefinition
259
+ find: (id: unknown) => Promise<ModelInstance | null>
260
+ findOrFail: (id: unknown) => Promise<ModelInstance>
261
+ all: () => Promise<ModelInstance[]>
262
+ create: (attributes: Row) => Promise<ModelInstance>
263
+ update: (attributes: Row) => Promise<number>
264
+ destroy: (ids: unknown | unknown[]) => Promise<number>
265
+ query: () => QueryBuilder
266
+ where: (column: string, operatorOrValue: QueryOperator | unknown, value?: unknown) => QueryBuilder
267
+ first: () => Promise<ModelInstance | null>
268
+ get: () => Promise<ModelInstance[]>
269
+ count: () => Promise<number>
270
+ }
271
+ /**
272
+ * Database adapter interface
273
+ */
274
+ export declare interface DatabaseAdapter {
275
+ connect: () => Promise<void>
276
+ disconnect: () => Promise<void>
277
+ query: <T = Row>(sql: string, bindings?: unknown[]) => Promise<T[]>
278
+ insert: (sql: string, bindings?: unknown[]) => Promise<unknown>
279
+ execute: (sql: string, bindings?: unknown[]) => Promise<number>
280
+ beginTransaction: () => Promise<void>
281
+ commit: () => Promise<void>
282
+ rollback: () => Promise<void>
283
+ isConnected: () => boolean
284
+ }
285
+ /**
286
+ * Supported database drivers
287
+ */
288
+ export type DatabaseDriver = 'sqlite' | 'postgres' | 'mysql' | 'custom'
289
+ /**
290
+ * Query operator types
291
+ */
292
+ export type QueryOperator = '=' | '!=' | '<' | '<=' | '>' | '>=' | 'like' | 'in' | 'not in' | 'between' | 'is null' | 'is not null'
293
+ /**
294
+ * Query result row
295
+ */
296
+ export type Row = Record<string, unknown>
297
+ /**
298
+ * Fluent query builder class
299
+ */
300
+ export declare class QueryBuilder {
301
+ private _table: string;
302
+ private _columns: (string | RawExpression)[];
303
+ private _wheres: WhereCondition[];
304
+ private _orders: OrderByClause[];
305
+ private _joins: JoinClause[];
306
+ private _groupBy: string[];
307
+ private _having: WhereCondition[];
308
+ private _limit?: number;
309
+ private _offset?: number;
310
+ private _distinct: boolean;
311
+ private _connection?: string;
312
+ private _bindings: unknown[];
313
+ private _modelDefinition?: ModelDefinition;
314
+ constructor(table?: string);
315
+ table(name: string): this;
316
+ from(name: string): this;
317
+ connection(name: string): this;
318
+ select(columns: (string | RawExpression)[]): this;
319
+ addSelect(columns: (string | RawExpression)[]): this;
320
+ distinct(): this;
321
+ where(column: string, operatorOrValue: QueryOperator | unknown, value?: unknown): this;
322
+ orWhere(column: string, operatorOrValue: QueryOperator | unknown, value?: unknown): this;
323
+ whereIn(column: string, values: unknown[]): this;
324
+ whereNotIn(column: string, values: unknown[]): this;
325
+ whereNull(column: string): this;
326
+ whereNotNull(column: string): this;
327
+ whereBetween(column: string, min: unknown, max: unknown): this;
328
+ whereLike(column: string, pattern: string): this;
329
+ join(table: string, first: string, operator: string, second: string): this;
330
+ leftJoin(table: string, first: string, operator: string, second: string): this;
331
+ rightJoin(table: string, first: string, operator: string, second: string): this;
332
+ orderBy(column: string, direction?: 'asc' | 'desc'): this;
333
+ orderByDesc(column: string): this;
334
+ groupBy(columns: string[]): this;
335
+ having(column: string, operator: QueryOperator, value: unknown): this;
336
+ limit(count: number): this;
337
+ take(count: number): this;
338
+ offset(count: number): this;
339
+ skip(count: number): this;
340
+ forPage(page: number, perPage?: number): this;
341
+ get(): Promise<Row[]>;
342
+ first(): Promise<Row | null>;
343
+ firstOrFail(): Promise<Row>;
344
+ find(id: unknown, primaryKey?: string): Promise<Row | null>;
345
+ value(column: string): Promise<unknown>;
346
+ pluck(column: string): Promise<unknown[]>;
347
+ exists(): Promise<boolean>;
348
+ doesntExist(): Promise<boolean>;
349
+ count(column?: string): Promise<number>;
350
+ max(column: string): Promise<number | null>;
351
+ min(column: string): Promise<number | null>;
352
+ sum(column: string): Promise<number>;
353
+ avg(column: string): Promise<number | null>;
354
+ insert(data: Row): Promise<unknown>;
355
+ insertAll(rows: Row[]): Promise<void>;
356
+ update(data: Row): Promise<number>;
357
+ increment(column: string, amount?: number): Promise<number>;
358
+ decrement(column: string, amount?: number): Promise<number>;
359
+ delete(): Promise<number>;
360
+ truncate(): Promise<void>;
361
+ toSql(): { sql: string, bindings: unknown[] };
362
+ private buildWhereClause(): string;
363
+ private getCacheKey(sql: string, bindings: unknown[]): string;
364
+ clone(): QueryBuilder;
365
+ }
366
+ /**
367
+ * Database error with query context
368
+ */
369
+ export declare class DatabaseError extends Error {
370
+ public sql?: string;
371
+ public bindings?: unknown[];
372
+ constructor(message: string, sql?: string, bindings?: unknown[]);
373
+ }
374
+ /**
375
+ * Schema builder for database migrations
376
+ */
377
+ export declare class SchemaBuilder {
378
+ private _connection?: string;
379
+ connection(name: string): this;
380
+ create(table: string, callback: (blueprint: Blueprint) => void): Promise<void>;
381
+ drop(table: string): Promise<void>;
382
+ rename(from: string, to: string): Promise<void>;
383
+ hasTable(table: string): Promise<boolean>;
384
+ }
385
+ /**
386
+ * Table blueprint for schema definitions
387
+ */
388
+ export declare class Blueprint {
389
+ private columns: string[];
390
+ private indices: string[];
391
+ private table: string;
392
+ constructor(table: string);
393
+ id(name?: string): this;
394
+ string(name: string, length?: number): this;
395
+ text(name: string): this;
396
+ integer(name: string): this;
397
+ boolean(name: string): this;
398
+ datetime(name: string): this;
399
+ timestamps(): this;
400
+ softDeletes(): this;
401
+ json(name: string): this;
402
+ foreignId(name: string): this;
403
+ index(columns: string | string[]): this;
404
+ unique(columns: string | string[]): this;
405
+ toCreateSQL(): string;
406
+ getIndexSQL(): string[];
407
+ }
@@ -0,0 +1,5 @@
1
+ // @bun
2
+ var Q=import.meta.require;var $={default:"sqlite",connections:{},logging:!1,cacheTTL:0,maxCacheSize:1000},V={},A={},L=new Map,S=[];function o(z){$={...$,...z}}function r(){return{...$}}function a(){$={default:"sqlite",connections:{},logging:!1,cacheTTL:0,maxCacheSize:1000};for(let z of Object.keys(V))delete V[z];L.clear(),S.length=0}function t(z,H){V[z]=H}function F(z){let H=z||$.default;if(V[H])return V[H];let U=$.connections[H];if(!U)throw Error(`Database connection "${H}" not configured`);let W=h(U);return V[H]=W,W}function h(z){switch(z.driver){case"sqlite":return q(z);case"postgres":return y(z);case"mysql":return f(z);default:throw Error(`Unsupported database driver: ${z.driver}`)}}function q(z){let H=null,U=!1;return{async connect(){if(U)return;let{Database:W}=await import("bun:sqlite");H=new W(z.database,{create:!0,readwrite:!0}),U=!0},async disconnect(){if(H)H.close(),H=null,U=!1},async query(W,J=[]){if(!U)await this.connect();let X=performance.now();try{let Y=H.prepare(W).all(...J);if($.logging)B(W,J,performance.now()-X);return Y}catch(Z){throw new O(`Query failed: ${Z}`,W,J)}},async insert(W,J=[]){if(!U)await this.connect();let X=performance.now();try{let Y=H.prepare(W).run(...J);if($.logging)B(W,J,performance.now()-X);return Y.lastInsertRowid}catch(Z){throw new O(`Insert failed: ${Z}`,W,J)}},async execute(W,J=[]){if(!U)await this.connect();let X=performance.now();try{let Y=H.prepare(W).run(...J);if($.logging)B(W,J,performance.now()-X);return Y.changes}catch(Z){throw new O(`Execute failed: ${Z}`,W,J)}},async beginTransaction(){if(!U)await this.connect();H.run("BEGIN TRANSACTION")},async commit(){H.run("COMMIT")},async rollback(){H.run("ROLLBACK")},isConnected(){return U}}}function y(z){let H=!1,U=null;return{async connect(){if(H)return;try{let{Client:W}=await import("pg");U=new W({host:z.host||"localhost",port:z.port||5432,database:z.database,user:z.username,password:z.password,ssl:z.ssl}),await U.connect(),H=!0}catch(W){throw Error(`PostgreSQL connection failed. Install 'pg' package: ${W}`)}},async disconnect(){if(U)await U.end(),U=null,H=!1},async query(W,J=[]){if(!H)await this.connect();let X=performance.now();try{let Z=await U.query(W,J);if($.logging)B(W,J,performance.now()-X);return Z.rows}catch(Z){throw new O(`Query failed: ${Z}`,W,J)}},async insert(W,J=[]){if(!H)await this.connect();let X=performance.now();try{let Z=await U.query(`${W} RETURNING id`,J);if($.logging)B(W,J,performance.now()-X);return Z.rows[0]?.id}catch(Z){throw new O(`Insert failed: ${Z}`,W,J)}},async execute(W,J=[]){if(!H)await this.connect();let X=performance.now();try{let Z=await U.query(W,J);if($.logging)B(W,J,performance.now()-X);return Z.rowCount||0}catch(Z){throw new O(`Execute failed: ${Z}`,W,J)}},async beginTransaction(){if(!H)await this.connect();await U.query("BEGIN")},async commit(){await U.query("COMMIT")},async rollback(){await U.query("ROLLBACK")},isConnected(){return H}}}function f(z){let H=!1,U=null;return{async connect(){if(H)return;try{U=(await import("mysql2/promise")).createPool({host:z.host||"localhost",port:z.port||3306,database:z.database,user:z.username,password:z.password,waitForConnections:!0,connectionLimit:z.poolSize||10,queueLimit:0}),H=!0}catch(W){throw Error(`MySQL connection failed. Install 'mysql2' package: ${W}`)}},async disconnect(){if(U)await U.end(),U=null,H=!1},async query(W,J=[]){if(!H)await this.connect();let X=performance.now();try{let[Z]=await U.execute(W,J);if($.logging)B(W,J,performance.now()-X);return Z}catch(Z){throw new O(`Query failed: ${Z}`,W,J)}},async insert(W,J=[]){if(!H)await this.connect();let X=performance.now();try{let[Z]=await U.execute(W,J);if($.logging)B(W,J,performance.now()-X);return Z.insertId}catch(Z){throw new O(`Insert failed: ${Z}`,W,J)}},async execute(W,J=[]){if(!H)await this.connect();let X=performance.now();try{let[Z]=await U.execute(W,J);if($.logging)B(W,J,performance.now()-X);return Z.affectedRows||0}catch(Z){throw new O(`Execute failed: ${Z}`,W,J)}},async beginTransaction(){if(!H)await this.connect();let W=await U.getConnection();return await W.beginTransaction(),W},async commit(){await U.execute("COMMIT")},async rollback(){await U.execute("ROLLBACK")},isConnected(){return H}}}class D{_table="";_columns=["*"];_wheres=[];_orders=[];_joins=[];_groupBy=[];_having=[];_limit;_offset;_distinct=!1;_connection;_bindings=[];_modelDefinition;constructor(z){if(z)this._table=z}table(z){return this._table=z,this}from(z){return this.table(z)}connection(z){return this._connection=z,this}select(...z){return this._columns=z.length>0?z:["*"],this}addSelect(...z){if(this._columns[0]==="*")this._columns=z;else this._columns.push(...z);return this}distinct(){return this._distinct=!0,this}where(z,H,U){let W="=",J=H;if(U!==void 0)W=H,J=U;return this._wheres.push({column:z,operator:W,value:J,boolean:"and"}),this}orWhere(z,H,U){let W="=",J=H;if(U!==void 0)W=H,J=U;return this._wheres.push({column:z,operator:W,value:J,boolean:"or"}),this}whereIn(z,H){return this._wheres.push({column:z,operator:"in",value:H,boolean:"and"}),this}whereNotIn(z,H){return this._wheres.push({column:z,operator:"not in",value:H,boolean:"and"}),this}whereNull(z){return this._wheres.push({column:z,operator:"is null",value:null,boolean:"and"}),this}whereNotNull(z){return this._wheres.push({column:z,operator:"is not null",value:null,boolean:"and"}),this}whereBetween(z,H,U){return this._wheres.push({column:z,operator:"between",value:[H,U],boolean:"and"}),this}whereLike(z,H){return this._wheres.push({column:z,operator:"like",value:H,boolean:"and"}),this}join(z,H,U,W){return this._joins.push({type:"inner",table:z,first:H,operator:U,second:W}),this}leftJoin(z,H,U,W){return this._joins.push({type:"left",table:z,first:H,operator:U,second:W}),this}rightJoin(z,H,U,W){return this._joins.push({type:"right",table:z,first:H,operator:U,second:W}),this}orderBy(z,H="asc"){return this._orders.push({column:z,direction:H}),this}orderByDesc(z){return this.orderBy(z,"desc")}groupBy(...z){return this._groupBy.push(...z),this}having(z,H,U){return this._having.push({column:z,operator:H,value:U,boolean:"and"}),this}limit(z){return this._limit=z,this}take(z){return this.limit(z)}offset(z){return this._offset=z,this}skip(z){return this.offset(z)}forPage(z,H=15){return this.offset((z-1)*H).limit(H)}async get(){let{sql:z,bindings:H}=this.toSql();if($.cacheTTL&&$.cacheTTL>0){let J=this.getCacheKey(z,H),X=g(J);if(X!==void 0)return X}let W=await F(this._connection).query(z,H);if($.cacheTTL&&$.cacheTTL>0){let J=this.getCacheKey(z,H);m(J,W,$.cacheTTL)}return W}async first(){return(await this.limit(1).get())[0]||null}async firstOrFail(){let z=await this.first();if(!z)throw Error("No results found");return z}async find(z,H="id"){return this.where(H,z).first()}async value(z){let H=await this.select(z).first();return H?H[z]:null}async pluck(z){return(await this.select(z).get()).map((U)=>U[z])}async exists(){return(await this.select(E("1")).limit(1).get()).length>0}async doesntExist(){return!await this.exists()}async count(z="*"){let H=await this.select(E(`COUNT(${z}) as count`)).first();return Number(H?.count||0)}async max(z){return(await this.select(E(`MAX(${z}) as max`)).first())?.max}async min(z){return(await this.select(E(`MIN(${z}) as min`)).first())?.min}async sum(z){let H=await this.select(E(`SUM(${z}) as sum`)).first();return Number(H?.sum||0)}async avg(z){return(await this.select(E(`AVG(${z}) as avg`)).first())?.avg}async insert(z){let H=Object.keys(z),U=H.map(()=>"?").join(", "),W=Object.values(z),J=`INSERT INTO ${this._table} (${H.join(", ")}) VALUES (${U})`,X=F(this._connection);return P(this._table),X.insert(J,W)}async insertAll(z){if(z.length===0)return;let H=Object.keys(z[0]),U=z.map(()=>`(${H.map(()=>"?").join(", ")})`).join(", "),W=z.flatMap((Z)=>Object.values(Z)),J=`INSERT INTO ${this._table} (${H.join(", ")}) VALUES ${U}`,X=F(this._connection);P(this._table),await X.execute(J,W)}async update(z){this._bindings=[];let H=this.buildWhereClause(),U=[...this._bindings],W=Object.keys(z).map((Y)=>`${Y} = ?`).join(", "),J=[...Object.values(z),...U],X=`UPDATE ${this._table} SET ${W}${H}`,Z=F(this._connection);return P(this._table),Z.execute(X,J)}async increment(z,H=1){this._bindings=[];let U=this.buildWhereClause(),W=`UPDATE ${this._table} SET ${z} = ${z} + ?${U}`,J=F(this._connection);return P(this._table),J.execute(W,[H,...this._bindings])}async decrement(z,H=1){return this.increment(z,-H)}async delete(){this._bindings=[];let z=this.buildWhereClause(),H=`DELETE FROM ${this._table}${z}`,U=F(this._connection);return P(this._table),U.execute(H,this._bindings)}async truncate(){let z=F(this._connection);P(this._table),await z.execute(`DELETE FROM ${this._table}`)}toSql(){this._bindings=[];let z="SELECT ";if(this._distinct)z+="DISTINCT ";z+=this._columns.map((H)=>{if(typeof H==="object"&&H.__raw)return H.sql;return H}).join(", "),z+=` FROM ${this._table}`;for(let H of this._joins)z+=` ${H.type.toUpperCase()} JOIN ${H.table} ON ${H.first} ${H.operator} ${H.second}`;if(z+=this.buildWhereClause(),this._groupBy.length>0)z+=` GROUP BY ${this._groupBy.join(", ")}`;if(this._having.length>0){let H=this._having.map((U,W)=>{let J=W===0?"":` ${U.boolean.toUpperCase()} `;return this._bindings.push(U.value),`${J}${U.column} ${U.operator} ?`});z+=` HAVING ${H.join("")}`}if(this._orders.length>0)z+=` ORDER BY ${this._orders.map((H)=>`${H.column} ${H.direction.toUpperCase()}`).join(", ")}`;if(this._limit!==void 0)z+=` LIMIT ${this._limit}`;if(this._offset!==void 0)z+=` OFFSET ${this._offset}`;return{sql:z,bindings:this._bindings}}buildWhereClause(){if(this._wheres.length===0)return"";return this._wheres.map((H,U)=>{let W=U===0?" WHERE ":` ${H.boolean.toUpperCase()} `;switch(H.operator){case"in":{let J=H.value,X=J.map(()=>"?").join(", ");return this._bindings.push(...J),`${W}${H.column} IN (${X})`}case"not in":{let J=H.value,X=J.map(()=>"?").join(", ");return this._bindings.push(...J),`${W}${H.column} NOT IN (${X})`}case"between":{let[J,X]=H.value;return this._bindings.push(J,X),`${W}${H.column} BETWEEN ? AND ?`}case"is null":return`${W}${H.column} IS NULL`;case"is not null":return`${W}${H.column} IS NOT NULL`;default:return this._bindings.push(H.value),`${W}${H.column} ${H.operator} ?`}}).join("")}getCacheKey(z,H){return`${this._table}:${z}:${JSON.stringify(H)}`}clone(){let z=new D(this._table);return z._columns=[...this._columns],z._wheres=[...this._wheres],z._orders=[...this._orders],z._joins=[...this._joins],z._groupBy=[...this._groupBy],z._having=[...this._having],z._limit=this._limit,z._offset=this._offset,z._distinct=this._distinct,z._connection=this._connection,z}}function G(z){return new D(z)}function n(z){return G(z)}function E(z,H=[]){return{__raw:!0,sql:z,bindings:H}}function e(z,H){let U=H.primaryKey||"id",W={name:z,definition:H,async find(J){let X=await G(H.table).where(U,J).first();return X?N(W,X):null},async findOrFail(J){let X=await this.find(J);if(!X)throw Error(`${z} not found with ${U} = ${J}`);return X},async all(){return(await G(H.table).get()).map((X)=>N(W,X))},async create(J){let X={...H.defaults,...J},Z=H.fillable?Object.fromEntries(Object.entries(X).filter(([_])=>H.fillable.includes(_))):X;if(H.timestamps!==!1){let _=new Date().toISOString(),R=typeof H.timestamps==="object"?H.timestamps.createdAt||"created_at":"created_at",T=typeof H.timestamps==="object"?H.timestamps.updatedAt||"updated_at":"updated_at";Z[R]=_,Z[T]=_}let Y=await G(H.table).insert(Z);return this.findOrFail(Y)},async update(J){return G(H.table).update(J)},async destroy(J){let X=Array.isArray(J)?J:[J];return G(H.table).whereIn(U,X).delete()},query(){return G(H.table)},where(J,X,Z){return this.query().where(J,X,Z)},async first(){let J=await this.query().first();return J?N(W,J):null},async get(){return(await this.query().get()).map((X)=>N(W,X))},async count(){return this.query().count()}};return A[z]=W,W}function k(z){let H=A[z];if(!H)throw Error(`Model "${z}" not defined. Use defineModel() first.`);return H}function zz(z){return z in A}function N(z,H){let{definition:U}=z,W=U.primaryKey||"id",J={...H},X={...H};if(U.casts){for(let[Y,_]of Object.entries(U.casts))if(Y in X)X[Y]=p(X[Y],_)}let Z={exists:!0,original:J,attributes:X,get(Y){return X[Y]},set(Y,_){X[Y]=_},toJSON(){let Y={...X};if(U.hidden)for(let _ of U.hidden)delete Y[_];return Y},async save(){let Y={};for(let _ of Object.keys(X))if(X[_]!==J[_])Y[_]=X[_];if(Object.keys(Y).length>0){if(U.timestamps!==!1){let _=typeof U.timestamps==="object"?U.timestamps.updatedAt||"updated_at":"updated_at";Y[_]=new Date().toISOString()}await G(U.table).where(W,J[W]).update(Y),Object.assign(J,Y)}},async delete(){if(U.softDeletes){let Y=typeof U.softDeletes==="string"?U.softDeletes:"deleted_at";await G(U.table).where(W,J[W]).update({[Y]:new Date().toISOString()})}else await G(U.table).where(W,J[W]).delete();Z.exists=!1},async refresh(){let Y=await G(U.table).where(W,J[W]).first();if(Y)Object.assign(J,Y),Object.assign(X,Y)},isDirty(Y){if(Y)return X[Y]!==J[Y];return Object.keys(X).some((_)=>X[_]!==J[_])}};if(U.relationships)for(let[Y,_]of Object.entries(U.relationships))Object.defineProperty(Z,Y,{value:async()=>{return b(Z,_,z)},enumerable:!1});return new Proxy(Z,{get(Y,_){if(_ in Y)return Y[_];return X[_]},set(Y,_,R){if(_ in Y)Y[_]=R;else X[_]=R;return!0}})}async function b(z,H,U){let W=k(H.model),J=U.definition.primaryKey||"id";switch(H.type){case"hasOne":{let X=H.foreignKey||`${U.name.toLowerCase()}_id`,Z=await G(W.definition.table).where(X,z.get(J)).first();return Z?N(W,Z):null}case"hasMany":{let X=H.foreignKey||`${U.name.toLowerCase()}_id`;return(await G(W.definition.table).where(X,z.get(J)).get()).map((Y)=>N(W,Y))}case"belongsTo":{let X=H.foreignKey||`${H.model.toLowerCase()}_id`,Z=H.localKey||"id",Y=await G(W.definition.table).where(Z,z.get(X)).first();return Y?N(W,Y):null}case"belongsToMany":{let X=H.pivotTable||[U.name,H.model].sort().join("_").toLowerCase(),Z=H.pivotForeignKey||`${U.name.toLowerCase()}_id`,Y=H.pivotRelatedKey||`${H.model.toLowerCase()}_id`,_=W.definition.primaryKey||"id";return(await G(W.definition.table).join(X,`${W.definition.table}.${_}`,"=",`${X}.${Y}`).where(`${X}.${Z}`,z.get(J)).get()).map((T)=>N(W,T))}default:return null}}function p(z,H){if(z===null||z===void 0)return z;switch(H){case"string":return String(z);case"number":return Number(z);case"boolean":return Boolean(z);case"date":return new Date(z);case"json":case"array":return typeof z==="string"?JSON.parse(z):z;default:return z}}async function Hz(z,H){let U=F(H);await U.beginTransaction();try{let W=await z();return await U.commit(),W}catch(W){throw await U.rollback(),W}}function g(z){let H=L.get(z);if(!H)return;if(Date.now()-H.timestamp>H.ttl*1000){L.delete(z);return}return H.result}function m(z,H,U){if(L.size>=($.maxCacheSize||1000)){let W=L.keys().next().value;if(W)L.delete(W)}L.set(z,{result:H,timestamp:Date.now(),ttl:U})}function P(z){for(let H of L.keys())if(H.startsWith(`${z}:`))L.delete(H)}function Jz(){L.clear()}function Uz(){return{size:L.size,keys:[...L.keys()]}}function B(z,H,U){if(S.push({sql:z,bindings:H,duration:U,timestamp:new Date}),S.length>1000)S.shift()}function Wz(){return[...S]}function Xz(){S.length=0}function Yz(z=!0){$.logging=z}class O extends Error{sql;bindings;constructor(z,H,U){super(z);this.sql=H;this.bindings=U;this.name="DatabaseError"}}async function u(z,H,U,W){let J=/@db\(\s*['"]([^'"]+)['"]\s*\)((?:->\w+\([^)]*\))*)/g,X=z,Z=[...z.matchAll(J)];for(let Y of Z){let[_,R,T]=Y;try{let j=await s(R,T),I=`$${R}`;H[I]=j,X=X.replace(_,"")}catch(j){X=X.replace(_,`<!-- DB Error: ${j instanceof Error?j.message:String(j)} -->`)}}return X}async function d(z,H,U,W){let J=/@model\(\s*['"]([^'"]+)['"]\s*\)((?:->\w+\([^)]*\))*)/g,X=z,Z=[...z.matchAll(J)];for(let Y of Z){let[_,R,T]=Y;try{let j=k(R),I=await l(j,T),K=`$${R.toLowerCase()}`;H[K]=I,X=X.replace(_,"")}catch(j){X=X.replace(_,`<!-- Model Error: ${j instanceof Error?j.message:String(j)} -->`)}}return X}async function c(z,H,U,W){let J=/@query\(\s*['"]([^'"]+)['"]\s*(?:,\s*(\[[^\]]*\]))?\s*\)\s*as\s+\$(\w+)/g,X=z,Z=[...z.matchAll(J)];for(let Y of Z){let[_,R,T,j]=Y;try{let I=T?JSON.parse(T):[],v=await F().query(R,I);H[`$${j}`]=v,X=X.replace(_,"")}catch(I){X=X.replace(_,`<!-- Query Error: ${I instanceof Error?I.message:String(I)} -->`)}}return X}async function s(z,H){let U=G(z),W=/->(\w+)\(([^)]*)\)/g,J=[...H.matchAll(W)],X=U;for(let[,Z,Y]of J){let _=M(Y);if(typeof X[Z]==="function"){if(X=X[Z](..._),X instanceof Promise){X=await X;break}}}if(X instanceof D)X=await X.get();return X}async function l(z,H){let U=/->(\w+)\(([^)]*)\)/g,W=[...H.matchAll(U)],J=z;for(let[,X,Z]of W){let Y=M(Z);if(typeof J[X]==="function"){if(J=J[X](...Y),J instanceof Promise)J=await J}else if(J instanceof D){if(typeof J[X]==="function"){if(J=J[X](...Y),J instanceof Promise)J=await J}}}if(J instanceof D)J=await J.get();return J}function M(z){if(!z.trim())return[];let H=[],U="",W=0,J=!1,X="";for(let Z=0;Z<z.length;Z++){let Y=z[Z];if(!J&&(Y==='"'||Y==="'"))J=!0,X=Y,U+=Y;else if(J&&Y===X)J=!1,U+=Y;else if(!J&&(Y==="["||Y==="{"||Y==="("))W++,U+=Y;else if(!J&&(Y==="]"||Y==="}"||Y===")"))W--,U+=Y;else if(!J&&W===0&&Y===",")H.push(x(U.trim())),U="";else U+=Y}if(U.trim())H.push(x(U.trim()));return H}function x(z){if(z.startsWith('"')&&z.endsWith('"')||z.startsWith("'")&&z.endsWith("'"))return z.slice(1,-1);if(z==="true")return!0;if(z==="false")return!1;if(z==="null")return null;let H=Number(z);if(!Number.isNaN(H))return H;try{return JSON.parse(z)}catch{return z}}async function Zz(z,H,U,W){let J=z;return J=await c(J,H,U,W),J=await d(J,H,U,W),J=await u(J,H,U,W),J}class w{_connection;connection(z){return this._connection=z,this}async create(z,H){let U=new C(z);H(U);let W=U.toCreateSQL();await F(this._connection).execute(W)}async drop(z){await F(this._connection).execute(`DROP TABLE IF EXISTS ${z}`)}async rename(z,H){await F(this._connection).execute(`ALTER TABLE ${z} RENAME TO ${H}`)}async hasTable(z){let H=F(this._connection);try{return await H.query(`SELECT 1 FROM ${z} LIMIT 1`),!0}catch{return!1}}}class C{table;columns=[];indices=[];constructor(z){this.table=z}id(z="id"){return this.columns.push(`${z} INTEGER PRIMARY KEY AUTOINCREMENT`),this}string(z,H=255){return this.columns.push(`${z} VARCHAR(${H})`),this}text(z){return this.columns.push(`${z} TEXT`),this}integer(z){return this.columns.push(`${z} INTEGER`),this}boolean(z){return this.columns.push(`${z} BOOLEAN DEFAULT 0`),this}datetime(z){return this.columns.push(`${z} DATETIME`),this}timestamps(){return this.columns.push("created_at DATETIME DEFAULT CURRENT_TIMESTAMP"),this.columns.push("updated_at DATETIME DEFAULT CURRENT_TIMESTAMP"),this}softDeletes(){return this.columns.push("deleted_at DATETIME"),this}json(z){return this.columns.push(`${z} TEXT`),this}foreignId(z){return this.columns.push(`${z} INTEGER`),this}index(z){let H=Array.isArray(z)?z:[z],U=`idx_${this.table}_${H.join("_")}`;return this.indices.push(`CREATE INDEX ${U} ON ${this.table} (${H.join(", ")})`),this}unique(z){let H=Array.isArray(z)?z:[z],U=`uniq_${this.table}_${H.join("_")}`;return this.indices.push(`CREATE UNIQUE INDEX ${U} ON ${this.table} (${H.join(", ")})`),this}toCreateSQL(){return`CREATE TABLE IF NOT EXISTS ${this.table} (
3
+ ${this.columns.join(`,
4
+ `)}
5
+ )`}getIndexSQL(){return this.indices}}function _z(){return new w}export{Hz as transaction,n as table,_z as schema,a as resetDatabaseConfig,t as registerAdapter,E as raw,G as query,c as processQueryDirective,d as processModelDirective,u as processDbDirective,Zz as processDatabaseDirectives,zz as hasModel,Wz as getQueryLog,Uz as getQueryCacheStats,k as getModel,r as getDatabaseConfig,F as getAdapter,Yz as enableQueryLogging,e as defineModel,o as configureDatabase,Xz as clearQueryLog,Jz as clearQueryCache,w as SchemaBuilder,D as QueryBuilder,O as DatabaseError,C as Blueprint};
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Process @defer directives in template
3
+ */
4
+ export declare function processDeferDirectives(template: string, _context: Record<string, unknown>, _filePath: string): string;