@stacksjs/stx 0.2.154 → 0.2.156

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 (240) hide show
  1. package/dist/a11y.d.ts +87 -46
  2. package/dist/animation.d.ts +96 -42
  3. package/dist/appearance-bootstrap.d.ts +49 -15
  4. package/dist/asset-roots.d.ts +32 -0
  5. package/dist/asset-roots.js +7 -0
  6. package/dist/assets.d.ts +9 -7
  7. package/dist/async-components.d.ts +78 -56
  8. package/dist/auth.d.ts +3 -0
  9. package/dist/build-externalize.d.ts +40 -0
  10. package/dist/build-externalize.js +63 -0
  11. package/dist/build-id.d.ts +22 -22
  12. package/dist/build-message.d.ts +73 -2
  13. package/dist/build-message.js +47 -8
  14. package/dist/builtins/attrs.d.ts +14 -0
  15. package/dist/builtins/drawer.d.ts +22 -0
  16. package/dist/builtins/icon.d.ts +16 -2
  17. package/dist/builtins/index.d.ts +5 -15
  18. package/dist/builtins/modal.d.ts +24 -0
  19. package/dist/builtins/safe-image.d.ts +42 -0
  20. package/dist/builtins/stx-image.d.ts +27 -0
  21. package/dist/builtins/stx-link.d.ts +9 -0
  22. package/dist/builtins/stx-loading-indicator.d.ts +11 -0
  23. package/dist/builtins/suspense.d.ts +28 -0
  24. package/dist/builtins/toast.d.ts +17 -0
  25. package/dist/builtins/transition-group.d.ts +25 -0
  26. package/dist/caching.d.ts +12 -15
  27. package/dist/cli.js +1798 -908
  28. package/dist/client/directive.d.ts +7 -0
  29. package/dist/client/index.d.ts +0 -1
  30. package/dist/client-script-bundler.d.ts +63 -5
  31. package/dist/client-script-bundler.js +30 -2
  32. package/dist/client-script.d.ts +102 -47
  33. package/dist/client-script.js +15 -3
  34. package/dist/codemod.d.ts +56 -0
  35. package/dist/codemod.js +192 -0
  36. package/dist/color-mode-boot.d.ts +83 -65
  37. package/dist/component-client-factories.d.ts +1 -6
  38. package/dist/component-processing.d.ts +58 -49
  39. package/dist/component-processing.js +1 -1
  40. package/dist/component-registry.d.ts +94 -31
  41. package/dist/component-renderer.d.ts +18 -0
  42. package/dist/composable-loader.d.ts +24 -0
  43. package/dist/composable-loader.js +12 -9
  44. package/dist/composables/index.d.ts +7 -0
  45. package/dist/composables/index.js +1 -0
  46. package/dist/composables/use-fetch.js +30 -2
  47. package/dist/composables/use-form.d.ts +91 -0
  48. package/dist/composables/use-form.js +112 -0
  49. package/dist/composables.d.ts +64 -60
  50. package/dist/computed.d.ts +86 -92
  51. package/dist/conditionals.d.ts +24 -8
  52. package/dist/conditionals.js +16 -0
  53. package/dist/config.d.ts +34 -21
  54. package/dist/config.js +35 -14
  55. package/dist/craft.js +1476 -768
  56. package/dist/crosswind-config.d.ts +58 -0
  57. package/dist/crosswind-config.js +40 -0
  58. package/dist/csp.d.ts +107 -41
  59. package/dist/defer.d.ts +24 -0
  60. package/dist/dev-server/crosswind.d.ts +35 -26
  61. package/dist/dev-server/crosswind.js +2 -18
  62. package/dist/dev-server/serve-app.js +4 -3
  63. package/dist/dev-server/terminal-colors.d.ts +32 -32
  64. package/dist/directive-api.d.ts +86 -43
  65. package/dist/document-shell.d.ts +54 -41
  66. package/dist/dynamic-components.d.ts +9 -0
  67. package/dist/error-boundaries.d.ts +47 -41
  68. package/dist/error-handling.d.ts +1 -1
  69. package/dist/errors/codes.d.ts +51 -43
  70. package/dist/errors/formatter.d.ts +58 -38
  71. package/dist/errors/index.d.ts +5 -61
  72. package/dist/errors/logger.d.ts +114 -40
  73. package/dist/errors/sanitizer.d.ts +53 -23
  74. package/dist/errors/types.d.ts +44 -31
  75. package/dist/events.d.ts +86 -25
  76. package/dist/expressions.d.ts +50 -42
  77. package/dist/forms-validation.d.ts +138 -123
  78. package/dist/forms-validation.js +1 -90
  79. package/dist/forms.d.ts +120 -66
  80. package/dist/forms.js +31 -11
  81. package/dist/fragment-container.d.ts +57 -0
  82. package/dist/fragment-container.js +109 -0
  83. package/dist/framework-composables.d.ts +32 -0
  84. package/dist/head.d.ts +156 -114
  85. package/dist/heatmap.d.ts +152 -72
  86. package/dist/html-masking.d.ts +40 -34
  87. package/dist/hydration-runtime.d.ts +20 -24
  88. package/dist/i18n.d.ts +93 -32
  89. package/dist/image-optimization/auto-sibling.d.ts +32 -4
  90. package/dist/includes.d.ts +69 -7
  91. package/dist/index.d.ts +66 -0
  92. package/dist/index.js +23 -0
  93. package/dist/internal-markdown.d.ts +12 -8
  94. package/dist/island-chunking.d.ts +30 -13
  95. package/dist/keep-alive.d.ts +72 -52
  96. package/dist/layout-types.d.ts +45 -0
  97. package/dist/layout-types.js +56 -0
  98. package/dist/lazy-module.d.ts +10 -0
  99. package/dist/loops.d.ts +66 -0
  100. package/dist/loops.js +47 -6
  101. package/dist/markdown.d.ts +0 -1
  102. package/dist/media/image/component.d.ts +25 -9
  103. package/dist/media/image/directive.d.ts +15 -1
  104. package/dist/media/image/placeholder.d.ts +20 -9
  105. package/dist/media/image/processor/cache.d.ts +40 -18
  106. package/dist/media/image/processor/index.d.ts +1 -10
  107. package/dist/media/image/processor/optimizer.d.ts +12 -1
  108. package/dist/media/image/processor/responsive.d.ts +16 -6
  109. package/dist/media/image/srcset.d.ts +47 -50
  110. package/dist/media/shared/cache.d.ts +51 -31
  111. package/dist/media/shared/hash.d.ts +7 -0
  112. package/dist/media/types.d.ts +1235 -754
  113. package/dist/media/video/directive.d.ts +15 -1
  114. package/dist/media/video/index.d.ts +39 -17
  115. package/dist/media/video/processor/cache.d.ts +42 -19
  116. package/dist/media/video/processor/index.d.ts +1 -18
  117. package/dist/media/video/processor/streaming.d.ts +17 -10
  118. package/dist/media/video/processor/thumbnail.d.ts +21 -15
  119. package/dist/media/video/processor/transcoder.d.ts +11 -1
  120. package/dist/method-spoofing.d.ts +7 -0
  121. package/dist/middleware.d.ts +60 -0
  122. package/dist/owned-routes.d.ts +42 -0
  123. package/dist/owned-routes.js +26 -0
  124. package/dist/page-meta.d.ts +38 -0
  125. package/dist/page-meta.js +16 -0
  126. package/dist/parser/directive-parser.d.ts +57 -45
  127. package/dist/parser/expression-parser.d.ts +33 -35
  128. package/dist/parser/index.d.ts +4 -39
  129. package/dist/parser/tokenizer.d.ts +61 -49
  130. package/dist/partial-hydration.d.ts +82 -50
  131. package/dist/performance-utils.d.ts +217 -124
  132. package/dist/placeholder.d.ts +18 -9
  133. package/dist/plugin-system.d.ts +264 -115
  134. package/dist/process.d.ts +11 -6
  135. package/dist/process.js +21 -4
  136. package/dist/production-builder.js +7 -0
  137. package/dist/prop-sentinels.d.ts +11 -11
  138. package/dist/public-env.d.ts +14 -0
  139. package/dist/pwa/directives.d.ts +12 -3
  140. package/dist/pwa/inject.d.ts +10 -0
  141. package/dist/pwa/precache.d.ts +22 -16
  142. package/dist/pwa/service-worker.d.ts +12 -0
  143. package/dist/pwa.js +1318 -610
  144. package/dist/reactive-bindings.d.ts +34 -11
  145. package/dist/reactive.d.ts +58 -30
  146. package/dist/reactive.js +56 -31
  147. package/dist/render.js +1 -0
  148. package/dist/route-middleware.d.ts +2 -35
  149. package/dist/route-types.d.ts +134 -0
  150. package/dist/route-types.js +24 -0
  151. package/dist/router.d.ts +5 -7
  152. package/dist/routes.d.ts +1 -3
  153. package/dist/runtime-globals.d.ts +147 -24
  154. package/dist/runtime-globals.js +16 -1
  155. package/dist/runtime-injection.d.ts +8 -0
  156. package/dist/runtime-injection.js +33 -24
  157. package/dist/script-emit.d.ts +30 -0
  158. package/dist/script-json.d.ts +36 -0
  159. package/dist/script-json.js +6 -0
  160. package/dist/script-validation.d.ts +21 -4
  161. package/dist/seo.d.ts +118 -47
  162. package/dist/server-bindings.d.ts +21 -0
  163. package/dist/sfc-template.d.ts +8 -8
  164. package/dist/signal-processing.d.ts +35 -15
  165. package/dist/signals-api.d.ts +117 -58
  166. package/dist/signals-api.js +7 -4
  167. package/dist/signals.d.ts +24 -17
  168. package/dist/signals.js +765 -60
  169. package/dist/site-builder/build.js +8 -0
  170. package/dist/site-url.d.ts +46 -0
  171. package/dist/site-url.js +70 -0
  172. package/dist/slots.d.ts +86 -20
  173. package/dist/source-signature.d.ts +45 -0
  174. package/dist/source-signature.js +20 -0
  175. package/dist/ssg.d.ts +285 -142
  176. package/dist/ssg.js +1268 -556
  177. package/dist/state-dir.d.ts +4 -4
  178. package/dist/state-management.d.ts +0 -12
  179. package/dist/state-management.js +8 -25
  180. package/dist/store-imports.d.ts +23 -0
  181. package/dist/store-imports.js +3 -0
  182. package/dist/store-loader.d.ts +10 -0
  183. package/dist/store-loader.js +10 -9
  184. package/dist/story/analytics.d.ts +138 -60
  185. package/dist/story/bookmarks.d.ts +87 -34
  186. package/dist/story/cli.d.ts +123 -69
  187. package/dist/story/collect/scanner.d.ts +4 -0
  188. package/dist/story/collect/tree.d.ts +8 -1
  189. package/dist/story/commands/build.d.ts +11 -6
  190. package/dist/story/commands/dev.d.ts +15 -8
  191. package/dist/story/commands/preview.d.ts +13 -7
  192. package/dist/story/config-watcher.d.ts +20 -13
  193. package/dist/story/config.d.ts +11 -8
  194. package/dist/story/context.d.ts +14 -8
  195. package/dist/story/hmr.d.ts +24 -26
  196. package/dist/story/hot-swap.d.ts +34 -23
  197. package/dist/story/keyboard-shortcuts.d.ts +23 -18
  198. package/dist/story/output.d.ts +46 -44
  199. package/dist/story/performance.d.ts +107 -45
  200. package/dist/story/presets.d.ts +107 -41
  201. package/dist/story/renderer.d.ts +41 -27
  202. package/dist/story/search.d.ts +23 -12
  203. package/dist/story/server.d.ts +21 -11
  204. package/dist/story/setup.d.ts +23 -15
  205. package/dist/story/testing.d.ts +65 -40
  206. package/dist/story/types.d.ts +262 -160
  207. package/dist/streaming.d.ts +119 -57
  208. package/dist/stx-virtual-ts.d.ts +165 -0
  209. package/dist/stx-virtual-ts.js +372 -0
  210. package/dist/stx.d.ts +78 -1
  211. package/dist/style-scoping.d.ts +17 -4
  212. package/dist/suspense.d.ts +67 -52
  213. package/dist/teleport.d.ts +22 -0
  214. package/dist/template-tag-balance.d.ts +22 -6
  215. package/dist/transitions.d.ts +66 -55
  216. package/dist/typecheck.d.ts +77 -0
  217. package/dist/typecheck.js +156 -0
  218. package/dist/types/component-types.d.ts +187 -122
  219. package/dist/types/config-types.d.ts +758 -297
  220. package/dist/types/context-types.d.ts +46 -24
  221. package/dist/types/csp-types.d.ts +70 -66
  222. package/dist/types/directive-types.d.ts +211 -155
  223. package/dist/types/index.d.ts +6 -109
  224. package/dist/types/pwa-types.d.ts +273 -148
  225. package/dist/types.d.ts +0 -1
  226. package/dist/typescript-templates.d.ts +11 -0
  227. package/dist/unresolved-identifiers.d.ts +24 -22
  228. package/dist/unresolved-identifiers.js +2 -0
  229. package/dist/utils.d.ts +24 -21
  230. package/dist/validator.d.ts +28 -26
  231. package/dist/variable-extractor.d.ts +48 -13
  232. package/dist/variable-extractor.js +27 -4
  233. package/dist/view-composers.d.ts +80 -81
  234. package/dist/virtual-scrolling.d.ts +101 -81
  235. package/dist/vue-template.d.ts +23 -0
  236. package/dist/web-components/css-scoping.d.ts +21 -11
  237. package/dist/web-components.d.ts +81 -58
  238. package/dist/x-element.d.ts +0 -1
  239. package/package.json +5 -5
  240. package/stx.d.ts +78 -1
@@ -1,3 +1,25 @@
1
+ /**
2
+ * Dev-mode template tag-balance check (stacksjs/stx#1769).
3
+ *
4
+ * A single dropped closing tag (e.g. a missing `</div>`) is silently
5
+ * auto-closed by the HTML parser at EOF, re-parenting every following sibling
6
+ * INSIDE the unclosed element. Those siblings then inherit the element's
7
+ * `x-show`/`display:none` state and render blank — with zero diagnostics at any
8
+ * layer (the server 200s, hydration succeeds, no console output). The failure
9
+ * is purely structural and only visible by eye.
10
+ *
11
+ * This does a coarse, void- and optional-close-aware open/close COUNT per tag
12
+ * name and reports any mismatch. It intentionally does not attempt a full HTML
13
+ * parse: the goal is a cheap, high-signal dev heads-up, not a validator.
14
+ */
15
+ export interface TagBalanceIssue {
16
+ /** Tag name as written (case preserved, so `<Icon>`/`</Icon>` match). */
17
+ tag: string;
18
+ opened: number;
19
+ closed: number;
20
+ /** 1-based line of the first opening tag of this name (best-effort). */
21
+ firstOpenLine: number;
22
+ }
1
23
  /**
2
24
  * Return the set of tag names whose opening/closing counts don't balance.
3
25
  * Pure and side-effect free.
@@ -8,9 +30,3 @@ export declare function findUnbalancedTags(template: string): TagBalanceIssue[];
8
30
  * diagnostic must never throw and break the build.
9
31
  */
10
32
  export declare function warnUnbalancedTags(template: string, filePath: string): void;
11
- export declare interface TagBalanceIssue {
12
- tag: string
13
- opened: number
14
- closed: number
15
- firstOpenLine: number
16
- }
@@ -1,3 +1,69 @@
1
+ /**
2
+ * STX Transitions
3
+ *
4
+ * Vue-inspired transition system for enter/leave animations.
5
+ * Supports CSS transitions, CSS animations, and JavaScript hooks.
6
+ *
7
+ * @module transitions
8
+ *
9
+ * @example
10
+ * ```html
11
+ * @transition(name: 'fade')
12
+ * @if (visible)
13
+ * <div class="modal">Content</div>
14
+ * @endif
15
+ * @endtransition
16
+ * ```
17
+ *
18
+ * CSS classes applied:
19
+ * - `.fade-enter-from` - Starting state for enter
20
+ * - `.fade-enter-active` - Active state during enter
21
+ * - `.fade-enter-to` - Ending state for enter
22
+ * - `.fade-leave-from` - Starting state for leave
23
+ * - `.fade-leave-active` - Active state during leave
24
+ * - `.fade-leave-to` - Ending state for leave
25
+ */
26
+ export interface TransitionOptions {
27
+ /** Transition name (used for CSS class prefix) */
28
+ name?: string;
29
+ /** Duration in milliseconds */
30
+ duration?: number | {
31
+ enter: number;
32
+ leave: number;
33
+ };
34
+ /** CSS transition timing function */
35
+ easing?: string;
36
+ /** Transition mode: 'in-out' or 'out-in' */
37
+ mode?: 'in-out' | 'out-in' | 'default';
38
+ /** Use CSS animations instead of transitions */
39
+ css?: boolean;
40
+ /** Custom enter class */
41
+ enterClass?: string;
42
+ /** Custom enter-active class */
43
+ enterActiveClass?: string;
44
+ /** Custom enter-to class */
45
+ enterToClass?: string;
46
+ /** Custom leave class */
47
+ leaveClass?: string;
48
+ /** Custom leave-active class */
49
+ leaveActiveClass?: string;
50
+ /** Custom leave-to class */
51
+ leaveToClass?: string;
52
+ /** JavaScript hooks */
53
+ onBeforeEnter?: (el: Element) => void;
54
+ onEnter?: (el: Element, done: () => void) => void;
55
+ onAfterEnter?: (el: Element) => void;
56
+ onEnterCancelled?: (el: Element) => void;
57
+ onBeforeLeave?: (el: Element) => void;
58
+ onLeave?: (el: Element, done: () => void) => void;
59
+ onAfterLeave?: (el: Element) => void;
60
+ onLeaveCancelled?: (el: Element) => void;
61
+ }
62
+ export interface TransitionState {
63
+ isEntering: boolean;
64
+ isLeaving: boolean;
65
+ isCancelled: boolean;
66
+ }
1
67
  /**
2
68
  * Perform an enter transition on an element.
3
69
  */
@@ -31,58 +97,3 @@ export declare function generateTransitionRuntime(): string;
31
97
  * <div @transition.slide-up.300="isOpen">Content</div>
32
98
  */
33
99
  export declare function processTransitionAttributes(template: string): string;
34
- /* eslint-disable prefer-const, style/max-statements-per-line, no-super-linear-backtracking, regexp/no-unused-capturing-group */
35
- /**
36
- * STX Transitions
37
- *
38
- * Vue-inspired transition system for enter/leave animations.
39
- * Supports CSS transitions, CSS animations, and JavaScript hooks.
40
- *
41
- * @module transitions
42
- *
43
- * @example
44
- * ```html
45
- * @transition(name: 'fade')
46
- * @if (visible)
47
- * <div class="modal">Content</div>
48
- * @endif
49
- * @endtransition
50
- * ```
51
- *
52
- * CSS classes applied:
53
- * - `.fade-enter-from` - Starting state for enter
54
- * - `.fade-enter-active` - Active state during enter
55
- * - `.fade-enter-to` - Ending state for enter
56
- * - `.fade-leave-from` - Starting state for leave
57
- * - `.fade-leave-active` - Active state during leave
58
- * - `.fade-leave-to` - Ending state for leave
59
- */
60
- // =============================================================================
61
- // Types
62
- // =============================================================================
63
- export declare interface TransitionOptions {
64
- name?: string
65
- duration?: number | { enter: number; leave: number }
66
- easing?: string
67
- mode?: 'in-out' | 'out-in' | 'default'
68
- css?: boolean
69
- enterClass?: string
70
- enterActiveClass?: string
71
- enterToClass?: string
72
- leaveClass?: string
73
- leaveActiveClass?: string
74
- leaveToClass?: string
75
- onBeforeEnter?: (el: Element) => void
76
- onEnter?: (el: Element, done: () => void) => void
77
- onAfterEnter?: (el: Element) => void
78
- onEnterCancelled?: (el: Element) => void
79
- onBeforeLeave?: (el: Element) => void
80
- onLeave?: (el: Element, done: () => void) => void
81
- onAfterLeave?: (el: Element) => void
82
- onLeaveCancelled?: (el: Element) => void
83
- }
84
- export declare interface TransitionState {
85
- isEntering: boolean
86
- isLeaving: boolean
87
- isCancelled: boolean
88
- }
@@ -0,0 +1,77 @@
1
+ import { extractScriptBlocks } from './stx-virtual-ts';
2
+ import type { ScriptBlock, ScriptKind } from './stx-virtual-ts';
3
+ export type { ScriptBlock, ScriptKind } from './stx-virtual-ts';
4
+ /**
5
+ * Build the virtual TypeScript source for one block.
6
+ *
7
+ * The body is prefixed with blank lines so its first line lands on the same line
8
+ * number it occupies in the `.stx` file — which makes every diagnostic's line
9
+ * number directly usable with no mapping table.
10
+ *
11
+ * The trailing `export {}` makes the buffer a MODULE, and that is load-bearing.
12
+ * Without it a block with no imports is a global script, so every top-level
13
+ * declaration collides with the DOM lib: `const name = …` and `const status = …`
14
+ * in a `<script server>` block both reported "Cannot redeclare block-scoped
15
+ * variable", and those are ordinary names for server-rendered page data. It is
16
+ * appended rather than prepended so the line numbers above it are untouched.
17
+ */
18
+ export declare function buildVirtualSource(block: ScriptBlock): string;
19
+ /** Virtual path for a block, stable and traceable back to its origin. */
20
+ export declare function virtualPathFor(filePath: string, kind: DiagnosticOrigin, index: number): string;
21
+ /** Map a virtual path back to the `.stx` file it came from. */
22
+ export declare function sourcePathFor(virtualPath: string): string;
23
+ /**
24
+ * Locate the package's own `stx.d.ts`, which types the runtime globals.
25
+ *
26
+ * Checked rather than assumed: this module runs from `src/` in the repo and
27
+ * from `dist/` when installed, and both sit one level under the package root.
28
+ * Returns `null` when it is genuinely absent so the caller can fall back rather
29
+ * than hand tsc a path to nothing.
30
+ */
31
+ export declare function findRuntimeTypeDeclarations(): string | null;
32
+ /**
33
+ * Type-check `.stx` files.
34
+ *
35
+ * Runs the `tsc` BINARY over generated virtual files rather than driving the
36
+ * compiler API. TypeScript 7 ships as a Go port whose npm package exposes only
37
+ * `version` — no `createProgram`, no `ScriptTarget` — so an API-based checker
38
+ * would work on TS 5 and break on the version this repo actually resolves.
39
+ * Shelling out works across both.
40
+ *
41
+ * TypeScript is not a declared dependency: anyone running a type-check already
42
+ * has it, and making the package depend on a compiler to serve a page would be
43
+ * the wrong trade.
44
+ */
45
+ export declare function typecheckStxFiles(files: string[], options?: TypecheckOptions): Promise<TypecheckResult>;
46
+ /** Render diagnostics the way a CLI should: file:line:col, then the message. */
47
+ export declare function formatTypecheckDiagnostics(diagnostics: TypecheckDiagnostic[]): string;
48
+ export declare interface TypecheckDiagnostic {
49
+ file: string
50
+ line: number
51
+ column: number
52
+ code: number
53
+ message: string
54
+ category: 'error' | 'warning' | 'suggestion' | 'message'
55
+ blockKind: DiagnosticOrigin
56
+ expression?: string
57
+ }
58
+ export declare interface TypecheckOptions {
59
+ extraLibs?: string[]
60
+ client?: boolean
61
+ server?: boolean
62
+ templates?: boolean
63
+ compilerOptions?: Record<string, unknown>
64
+ }
65
+ export declare interface TypecheckResult {
66
+ diagnostics: TypecheckDiagnostic[]
67
+ checkedFiles: string[]
68
+ blockCount: number
69
+ expressionCount: number
70
+ }
71
+ /** Where a diagnostic came from: a script block, or the markup itself. */
72
+ export type DiagnosticOrigin = ScriptKind | 'template';
73
+ export {
74
+ extractScriptBlocks,
75
+ extractTemplateExpressions,
76
+ type TemplateExpression,
77
+ } from './stx-virtual-ts';
@@ -0,0 +1,156 @@
1
+ import { existsSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { STX_RUNTIME_GLOBALS } from "./runtime-globals.js";
4
+ import { stateDir } from "./state-dir.js";
5
+ import {
6
+ buildVirtualTypeScript,
7
+ extractScriptBlocks,
8
+ resolvePosition,
9
+ serverContextDeclarations
10
+ } from "./stx-virtual-ts.js";
11
+ export {
12
+ extractScriptBlocks,
13
+ extractTemplateExpressions
14
+ } from "./stx-virtual-ts.js";
15
+ export function buildVirtualSource(block) {
16
+ return `${(block.startLine > 1 ? `
17
+ `.repeat(block.startLine - 1) : "") + block.code}
18
+ export {}
19
+ `;
20
+ }
21
+ export function virtualPathFor(filePath, kind, index) {
22
+ return `${filePath}.__stx_${kind}${index}.ts`;
23
+ }
24
+ export function sourcePathFor(virtualPath) {
25
+ return virtualPath.replace(/\.__stx_(?:server|client|plain|template)\d+\.ts$/, "");
26
+ }
27
+ export function findRuntimeTypeDeclarations() {
28
+ for (const candidate of [
29
+ path.resolve(import.meta.dir, "..", "stx.d.ts"),
30
+ path.resolve(import.meta.dir, "..", "..", "stx.d.ts")
31
+ ])
32
+ if (existsSync(candidate))
33
+ return candidate;
34
+ return null;
35
+ }
36
+ const TSC_LINE_RE = /^(.*?)\((\d+),(\d+)\):\s+(error|warning)\s+TS(\d+):\s+(.*)$/;
37
+ export async function typecheckStxFiles(files, options = {}) {
38
+ const checkClient = options.client !== !1, checkServer = options.server !== !1, checkTemplates = options.templates !== !1, virtualFiles = new Map, checkedFiles = [];
39
+ let blockCount = 0, expressionCount = 0;
40
+ const runtimeTypes = findRuntimeTypeDeclarations();
41
+ for (const file of files) {
42
+ const source = await Bun.file(file).text(), blocks = extractScriptBlocks(source).filter((b) => {
43
+ if (b.kind === "server")
44
+ return checkServer;
45
+ if (b.kind === "client")
46
+ return checkClient;
47
+ return !1;
48
+ }), templateBuffer = checkTemplates ? buildVirtualTypeScript(source, { runtimeGlobals: !runtimeTypes }) : null, expressions = templateBuffer ? [...templateBuffer.lineMap.values()].filter((m) => m.expression).length : 0;
49
+ if (blocks.length === 0 && expressions === 0)
50
+ continue;
51
+ checkedFiles.push(file);
52
+ blockCount += blocks.length;
53
+ expressionCount += expressions;
54
+ blocks.forEach((block, i) => {
55
+ virtualFiles.set(virtualPathFor(file, block.kind, i), {
56
+ source: buildVirtualSource(block),
57
+ origin: file,
58
+ kind: block.kind
59
+ });
60
+ });
61
+ if (templateBuffer && expressions > 0)
62
+ virtualFiles.set(virtualPathFor(file, "template", 0), {
63
+ source: templateBuffer.text,
64
+ origin: file,
65
+ kind: "template",
66
+ virtual: templateBuffer
67
+ });
68
+ }
69
+ if (virtualFiles.size === 0)
70
+ return { diagnostics: [], checkedFiles, blockCount: 0, expressionCount: 0 };
71
+ const ambient = [...options.extraLibs ?? []];
72
+ if (runtimeTypes)
73
+ ambient.push(runtimeTypes);
74
+ const globalsDts = `${stateDir()}/typecheck/__stx_globals.d.ts`, globalDecls = [
75
+ "// Generated \u2014 the context serve.ts injects into <script server> blocks.",
76
+ serverContextDeclarations(),
77
+ ...runtimeTypes ? [] : ["declare const window: any", ...STX_RUNTIME_GLOBALS.map((name) => `declare const ${name}: any`)]
78
+ ].join(`
79
+ `), workDir = `${stateDir()}/typecheck`;
80
+ await Bun.$`rm -rf ${workDir}`.quiet().nothrow();
81
+ await Bun.$`mkdir -p ${workDir}`.quiet().nothrow();
82
+ await Bun.write(globalsDts, globalDecls);
83
+ const writtenToOrigin = new Map;
84
+ let counter = 0;
85
+ for (const [virtualPath, meta] of virtualFiles) {
86
+ const safe = `${counter++}_${virtualPath.replace(/[^\w.-]+/g, "_")}`;
87
+ await Bun.write(`${workDir}/${safe}`, meta.source);
88
+ writtenToOrigin.set(safe, meta);
89
+ }
90
+ const tsconfig = {
91
+ compilerOptions: {
92
+ target: "ESNext",
93
+ module: "ESNext",
94
+ moduleResolution: "bundler",
95
+ strict: !0,
96
+ noEmit: !0,
97
+ skipLibCheck: !0,
98
+ allowJs: !0,
99
+ esModuleInterop: !0,
100
+ resolveJsonModule: !0,
101
+ lib: ["ESNext", "DOM", "DOM.Iterable"],
102
+ types: [],
103
+ ...options.compilerOptions ?? {}
104
+ },
105
+ files: [...writtenToOrigin.keys()].map((name) => `${workDir}/${name}`).concat(globalsDts, ...ambient)
106
+ }, tsconfigPath = `${workDir}/tsconfig.json`;
107
+ await Bun.write(tsconfigPath, JSON.stringify(tsconfig, null, 2));
108
+ const proc = Bun.spawnSync(["bun", "x", "tsc", "-p", tsconfigPath, "--pretty", "false"], {
109
+ stdout: "pipe",
110
+ stderr: "pipe"
111
+ }), output = new TextDecoder().decode(proc.stdout) + new TextDecoder().decode(proc.stderr), diagnostics = [];
112
+ for (const rawLine of output.split(`
113
+ `)) {
114
+ const m = rawLine.match(TSC_LINE_RE);
115
+ if (!m)
116
+ continue;
117
+ const [, filePart, lineStr, colStr, category, code, message] = m, entry = writtenToOrigin.get(filePart.split("/").pop());
118
+ if (!entry)
119
+ continue;
120
+ let line = Number(lineStr), column = Number(colStr), expression;
121
+ if (entry.virtual) {
122
+ const at = resolvePosition(entry.virtual, line, column);
123
+ if (!at?.expression)
124
+ continue;
125
+ line = at.line;
126
+ column = at.column;
127
+ expression = at.expression.code.trim();
128
+ }
129
+ diagnostics.push({
130
+ file: entry.origin,
131
+ line,
132
+ column,
133
+ code: Number(code),
134
+ message,
135
+ category: category === "error" ? "error" : "warning",
136
+ blockKind: entry.kind,
137
+ expression
138
+ });
139
+ }
140
+ const seen = new Set, unique = diagnostics.filter((d) => {
141
+ const key = `${d.file}:${d.line}:${d.column}:${d.code}:${d.message}`;
142
+ if (seen.has(key))
143
+ return !1;
144
+ seen.add(key);
145
+ return !0;
146
+ });
147
+ unique.sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line || a.column - b.column);
148
+ return { diagnostics: unique, checkedFiles, blockCount, expressionCount };
149
+ }
150
+ export function formatTypecheckDiagnostics(diagnostics) {
151
+ return diagnostics.map((d) => {
152
+ const where = d.blockKind === "template" ? `[template: ${d.expression ?? ""}]` : `[<script ${d.blockKind}>]`;
153
+ return `${d.file}:${d.line}:${d.column} ${d.category} TS${d.code} ${d.message} ${where}`;
154
+ }).join(`
155
+ `);
156
+ }