naider 1.7.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 (359) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +884 -0
  3. package/SPEC-X.nx +276 -0
  4. package/SPEC.naide +431 -0
  5. package/bin/naide.js +519 -0
  6. package/examples/ai-app.naide +21 -0
  7. package/examples/ai-app.nx +21 -0
  8. package/examples/async.naide +50 -0
  9. package/examples/async.nx +40 -0
  10. package/examples/crud.naide +79 -0
  11. package/examples/crud.nx +64 -0
  12. package/examples/fullapp.naide +74 -0
  13. package/examples/fullapp.nx +74 -0
  14. package/examples/hello.naide +33 -0
  15. package/examples/hello.nx +29 -0
  16. package/examples/model.naide +44 -0
  17. package/examples/server.naide +28 -0
  18. package/examples/server.nx +27 -0
  19. package/examples/sql-app.naide +23 -0
  20. package/examples/sql-app.nx +23 -0
  21. package/examples/todo-api.naide +34 -0
  22. package/examples/todo-api.nx +31 -0
  23. package/lsp/server.js +172 -0
  24. package/package.json +56 -0
  25. package/src/generator.js +1313 -0
  26. package/src/index.js +41 -0
  27. package/src/lexer.js +402 -0
  28. package/src/parser.js +1671 -0
  29. package/src/preprocess.js +308 -0
  30. package/src/runtime.js +969 -0
  31. package/src/tokens.js +218 -0
  32. package/vscode-naide/README.md +38 -0
  33. package/vscode-naide/extension.js +41 -0
  34. package/vscode-naide/language-configuration-naide.json +32 -0
  35. package/vscode-naide/language-configuration-nx.json +32 -0
  36. package/vscode-naide/naide-lang-1.1.0.vsix +0 -0
  37. package/vscode-naide/node_modules/.bin/semver +16 -0
  38. package/vscode-naide/node_modules/.bin/semver.cmd +17 -0
  39. package/vscode-naide/node_modules/.bin/semver.ps1 +28 -0
  40. package/vscode-naide/node_modules/.package-lock.json +86 -0
  41. package/vscode-naide/node_modules/balanced-match/.github/FUNDING.yml +2 -0
  42. package/vscode-naide/node_modules/balanced-match/LICENSE.md +21 -0
  43. package/vscode-naide/node_modules/balanced-match/README.md +97 -0
  44. package/vscode-naide/node_modules/balanced-match/index.js +62 -0
  45. package/vscode-naide/node_modules/balanced-match/package.json +48 -0
  46. package/vscode-naide/node_modules/brace-expansion/.github/FUNDING.yml +2 -0
  47. package/vscode-naide/node_modules/brace-expansion/LICENSE +21 -0
  48. package/vscode-naide/node_modules/brace-expansion/README.md +157 -0
  49. package/vscode-naide/node_modules/brace-expansion/index.js +394 -0
  50. package/vscode-naide/node_modules/brace-expansion/package.json +49 -0
  51. package/vscode-naide/node_modules/minimatch/LICENSE +15 -0
  52. package/vscode-naide/node_modules/minimatch/README.md +296 -0
  53. package/vscode-naide/node_modules/minimatch/changelog.md +35 -0
  54. package/vscode-naide/node_modules/minimatch/lib/path.js +4 -0
  55. package/vscode-naide/node_modules/minimatch/minimatch.js +996 -0
  56. package/vscode-naide/node_modules/minimatch/package.json +35 -0
  57. package/vscode-naide/node_modules/semver/LICENSE +15 -0
  58. package/vscode-naide/node_modules/semver/README.md +680 -0
  59. package/vscode-naide/node_modules/semver/bin/semver.js +195 -0
  60. package/vscode-naide/node_modules/semver/classes/comparator.js +143 -0
  61. package/vscode-naide/node_modules/semver/classes/index.js +7 -0
  62. package/vscode-naide/node_modules/semver/classes/range.js +577 -0
  63. package/vscode-naide/node_modules/semver/classes/semver.js +350 -0
  64. package/vscode-naide/node_modules/semver/functions/clean.js +8 -0
  65. package/vscode-naide/node_modules/semver/functions/cmp.js +54 -0
  66. package/vscode-naide/node_modules/semver/functions/coerce.js +62 -0
  67. package/vscode-naide/node_modules/semver/functions/compare-build.js +9 -0
  68. package/vscode-naide/node_modules/semver/functions/compare-loose.js +5 -0
  69. package/vscode-naide/node_modules/semver/functions/compare.js +7 -0
  70. package/vscode-naide/node_modules/semver/functions/diff.js +60 -0
  71. package/vscode-naide/node_modules/semver/functions/eq.js +5 -0
  72. package/vscode-naide/node_modules/semver/functions/gt.js +5 -0
  73. package/vscode-naide/node_modules/semver/functions/gte.js +5 -0
  74. package/vscode-naide/node_modules/semver/functions/inc.js +21 -0
  75. package/vscode-naide/node_modules/semver/functions/lt.js +5 -0
  76. package/vscode-naide/node_modules/semver/functions/lte.js +5 -0
  77. package/vscode-naide/node_modules/semver/functions/major.js +5 -0
  78. package/vscode-naide/node_modules/semver/functions/minor.js +5 -0
  79. package/vscode-naide/node_modules/semver/functions/neq.js +5 -0
  80. package/vscode-naide/node_modules/semver/functions/parse.js +18 -0
  81. package/vscode-naide/node_modules/semver/functions/patch.js +5 -0
  82. package/vscode-naide/node_modules/semver/functions/prerelease.js +8 -0
  83. package/vscode-naide/node_modules/semver/functions/rcompare.js +5 -0
  84. package/vscode-naide/node_modules/semver/functions/rsort.js +5 -0
  85. package/vscode-naide/node_modules/semver/functions/satisfies.js +12 -0
  86. package/vscode-naide/node_modules/semver/functions/sort.js +5 -0
  87. package/vscode-naide/node_modules/semver/functions/truncate.js +48 -0
  88. package/vscode-naide/node_modules/semver/functions/valid.js +8 -0
  89. package/vscode-naide/node_modules/semver/index.js +93 -0
  90. package/vscode-naide/node_modules/semver/internal/constants.js +37 -0
  91. package/vscode-naide/node_modules/semver/internal/debug.js +11 -0
  92. package/vscode-naide/node_modules/semver/internal/identifiers.js +29 -0
  93. package/vscode-naide/node_modules/semver/internal/lrucache.js +42 -0
  94. package/vscode-naide/node_modules/semver/internal/parse-options.js +17 -0
  95. package/vscode-naide/node_modules/semver/internal/re.js +223 -0
  96. package/vscode-naide/node_modules/semver/package.json +78 -0
  97. package/vscode-naide/node_modules/semver/preload.js +4 -0
  98. package/vscode-naide/node_modules/semver/range.bnf +17 -0
  99. package/vscode-naide/node_modules/semver/ranges/gtr.js +6 -0
  100. package/vscode-naide/node_modules/semver/ranges/intersects.js +9 -0
  101. package/vscode-naide/node_modules/semver/ranges/ltr.js +6 -0
  102. package/vscode-naide/node_modules/semver/ranges/max-satisfying.js +27 -0
  103. package/vscode-naide/node_modules/semver/ranges/min-satisfying.js +26 -0
  104. package/vscode-naide/node_modules/semver/ranges/min-version.js +63 -0
  105. package/vscode-naide/node_modules/semver/ranges/outside.js +82 -0
  106. package/vscode-naide/node_modules/semver/ranges/simplify.js +49 -0
  107. package/vscode-naide/node_modules/semver/ranges/subset.js +249 -0
  108. package/vscode-naide/node_modules/semver/ranges/to-comparators.js +10 -0
  109. package/vscode-naide/node_modules/semver/ranges/valid.js +13 -0
  110. package/vscode-naide/node_modules/vscode-jsonrpc/License.txt +11 -0
  111. package/vscode-naide/node_modules/vscode-jsonrpc/README.md +69 -0
  112. package/vscode-naide/node_modules/vscode-jsonrpc/browser.d.ts +6 -0
  113. package/vscode-naide/node_modules/vscode-jsonrpc/browser.js +7 -0
  114. package/vscode-naide/node_modules/vscode-jsonrpc/lib/browser/main.d.ts +17 -0
  115. package/vscode-naide/node_modules/vscode-jsonrpc/lib/browser/main.js +76 -0
  116. package/vscode-naide/node_modules/vscode-jsonrpc/lib/browser/ril.d.ts +12 -0
  117. package/vscode-naide/node_modules/vscode-jsonrpc/lib/browser/ril.js +156 -0
  118. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/api.d.ts +14 -0
  119. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/api.js +81 -0
  120. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/cancellation.d.ts +32 -0
  121. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/cancellation.js +96 -0
  122. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/connection.d.ts +358 -0
  123. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/connection.js +1212 -0
  124. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/disposable.d.ts +9 -0
  125. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/disposable.js +16 -0
  126. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/encoding.d.ts +52 -0
  127. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/encoding.js +70 -0
  128. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/events.d.ts +39 -0
  129. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/events.js +128 -0
  130. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/is.d.ts +7 -0
  131. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/is.js +35 -0
  132. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/linkedMap.d.ts +53 -0
  133. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/linkedMap.js +398 -0
  134. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/messageBuffer.d.ts +18 -0
  135. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/messageBuffer.js +152 -0
  136. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/messageReader.d.ts +77 -0
  137. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/messageReader.js +197 -0
  138. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/messageWriter.d.ts +60 -0
  139. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/messageWriter.js +115 -0
  140. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/messages.d.ts +369 -0
  141. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/messages.js +306 -0
  142. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/ral.d.ts +74 -0
  143. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/ral.js +23 -0
  144. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/semaphore.d.ts +10 -0
  145. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/semaphore.js +68 -0
  146. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/sharedArrayCancellation.d.ts +15 -0
  147. package/vscode-naide/node_modules/vscode-jsonrpc/lib/common/sharedArrayCancellation.js +76 -0
  148. package/vscode-naide/node_modules/vscode-jsonrpc/lib/node/main.d.ts +63 -0
  149. package/vscode-naide/node_modules/vscode-jsonrpc/lib/node/main.js +257 -0
  150. package/vscode-naide/node_modules/vscode-jsonrpc/lib/node/ril.d.ts +13 -0
  151. package/vscode-naide/node_modules/vscode-jsonrpc/lib/node/ril.js +161 -0
  152. package/vscode-naide/node_modules/vscode-jsonrpc/node.cmd +5 -0
  153. package/vscode-naide/node_modules/vscode-jsonrpc/node.d.ts +6 -0
  154. package/vscode-naide/node_modules/vscode-jsonrpc/node.js +7 -0
  155. package/vscode-naide/node_modules/vscode-jsonrpc/package.json +45 -0
  156. package/vscode-naide/node_modules/vscode-jsonrpc/thirdpartynotices.txt +16 -0
  157. package/vscode-naide/node_modules/vscode-jsonrpc/typings/thenable.d.ts +5 -0
  158. package/vscode-naide/node_modules/vscode-languageclient/License.txt +11 -0
  159. package/vscode-naide/node_modules/vscode-languageclient/README.md +17 -0
  160. package/vscode-naide/node_modules/vscode-languageclient/browser.d.ts +6 -0
  161. package/vscode-naide/node_modules/vscode-languageclient/browser.js +7 -0
  162. package/vscode-naide/node_modules/vscode-languageclient/lib/browser/main.d.ts +8 -0
  163. package/vscode-naide/node_modules/vscode-languageclient/lib/browser/main.js +37 -0
  164. package/vscode-naide/node_modules/vscode-languageclient/lib/common/api.d.ts +36 -0
  165. package/vscode-naide/node_modules/vscode-languageclient/lib/common/api.js +27 -0
  166. package/vscode-naide/node_modules/vscode-languageclient/lib/common/callHierarchy.d.ts +37 -0
  167. package/vscode-naide/node_modules/vscode-languageclient/lib/common/callHierarchy.js +97 -0
  168. package/vscode-naide/node_modules/vscode-languageclient/lib/common/client.d.ts +476 -0
  169. package/vscode-naide/node_modules/vscode-languageclient/lib/common/client.js +1600 -0
  170. package/vscode-naide/node_modules/vscode-languageclient/lib/common/codeAction.d.ts +19 -0
  171. package/vscode-naide/node_modules/vscode-languageclient/lib/common/codeAction.js +99 -0
  172. package/vscode-naide/node_modules/vscode-languageclient/lib/common/codeConverter.d.ts +78 -0
  173. package/vscode-naide/node_modules/vscode-languageclient/lib/common/codeConverter.js +876 -0
  174. package/vscode-naide/node_modules/vscode-languageclient/lib/common/codeLens.d.ts +23 -0
  175. package/vscode-naide/node_modules/vscode-languageclient/lib/common/codeLens.js +78 -0
  176. package/vscode-naide/node_modules/vscode-languageclient/lib/common/colorProvider.d.ts +25 -0
  177. package/vscode-naide/node_modules/vscode-languageclient/lib/common/colorProvider.js +74 -0
  178. package/vscode-naide/node_modules/vscode-languageclient/lib/common/completion.d.ts +20 -0
  179. package/vscode-naide/node_modules/vscode-languageclient/lib/common/completion.js +126 -0
  180. package/vscode-naide/node_modules/vscode-languageclient/lib/common/configuration.d.ts +69 -0
  181. package/vscode-naide/node_modules/vscode-languageclient/lib/common/configuration.js +209 -0
  182. package/vscode-naide/node_modules/vscode-languageclient/lib/common/declaration.d.ts +16 -0
  183. package/vscode-naide/node_modules/vscode-languageclient/lib/common/declaration.js +54 -0
  184. package/vscode-naide/node_modules/vscode-languageclient/lib/common/definition.d.ts +16 -0
  185. package/vscode-naide/node_modules/vscode-languageclient/lib/common/definition.js +55 -0
  186. package/vscode-naide/node_modules/vscode-languageclient/lib/common/diagnostic.d.ts +122 -0
  187. package/vscode-naide/node_modules/vscode-languageclient/lib/common/diagnostic.js +814 -0
  188. package/vscode-naide/node_modules/vscode-languageclient/lib/common/documentHighlight.d.ts +15 -0
  189. package/vscode-naide/node_modules/vscode-languageclient/lib/common/documentHighlight.js +50 -0
  190. package/vscode-naide/node_modules/vscode-languageclient/lib/common/documentLink.d.ts +19 -0
  191. package/vscode-naide/node_modules/vscode-languageclient/lib/common/documentLink.js +71 -0
  192. package/vscode-naide/node_modules/vscode-languageclient/lib/common/documentSymbol.d.ts +17 -0
  193. package/vscode-naide/node_modules/vscode-languageclient/lib/common/documentSymbol.js +104 -0
  194. package/vscode-naide/node_modules/vscode-languageclient/lib/common/executeCommand.d.ts +21 -0
  195. package/vscode-naide/node_modules/vscode-languageclient/lib/common/executeCommand.js +72 -0
  196. package/vscode-naide/node_modules/vscode-languageclient/lib/common/features.d.ts +418 -0
  197. package/vscode-naide/node_modules/vscode-languageclient/lib/common/features.js +291 -0
  198. package/vscode-naide/node_modules/vscode-languageclient/lib/common/fileOperations.d.ts +116 -0
  199. package/vscode-naide/node_modules/vscode-languageclient/lib/common/fileOperations.js +333 -0
  200. package/vscode-naide/node_modules/vscode-languageclient/lib/common/fileSystemWatcher.d.ts +18 -0
  201. package/vscode-naide/node_modules/vscode-languageclient/lib/common/fileSystemWatcher.js +95 -0
  202. package/vscode-naide/node_modules/vscode-languageclient/lib/common/foldingRange.d.ts +19 -0
  203. package/vscode-naide/node_modules/vscode-languageclient/lib/common/foldingRange.js +65 -0
  204. package/vscode-naide/node_modules/vscode-languageclient/lib/common/formatting.d.ts +39 -0
  205. package/vscode-naide/node_modules/vscode-languageclient/lib/common/formatting.js +182 -0
  206. package/vscode-naide/node_modules/vscode-languageclient/lib/common/hover.d.ts +16 -0
  207. package/vscode-naide/node_modules/vscode-languageclient/lib/common/hover.js +58 -0
  208. package/vscode-naide/node_modules/vscode-languageclient/lib/common/implementation.d.ts +16 -0
  209. package/vscode-naide/node_modules/vscode-languageclient/lib/common/implementation.js +54 -0
  210. package/vscode-naide/node_modules/vscode-languageclient/lib/common/inlayHint.d.ts +20 -0
  211. package/vscode-naide/node_modules/vscode-languageclient/lib/common/inlayHint.js +92 -0
  212. package/vscode-naide/node_modules/vscode-languageclient/lib/common/inlineCompletion.d.ts +18 -0
  213. package/vscode-naide/node_modules/vscode-languageclient/lib/common/inlineCompletion.js +54 -0
  214. package/vscode-naide/node_modules/vscode-languageclient/lib/common/inlineValue.d.ts +18 -0
  215. package/vscode-naide/node_modules/vscode-languageclient/lib/common/inlineValue.js +65 -0
  216. package/vscode-naide/node_modules/vscode-languageclient/lib/common/linkedEditingRange.d.ts +21 -0
  217. package/vscode-naide/node_modules/vscode-languageclient/lib/common/linkedEditingRange.js +53 -0
  218. package/vscode-naide/node_modules/vscode-languageclient/lib/common/notebook.d.ts +96 -0
  219. package/vscode-naide/node_modules/vscode-languageclient/lib/common/notebook.js +851 -0
  220. package/vscode-naide/node_modules/vscode-languageclient/lib/common/progress.d.ts +11 -0
  221. package/vscode-naide/node_modules/vscode-languageclient/lib/common/progress.js +44 -0
  222. package/vscode-naide/node_modules/vscode-languageclient/lib/common/progressPart.d.ts +24 -0
  223. package/vscode-naide/node_modules/vscode-languageclient/lib/common/progressPart.js +96 -0
  224. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolCallHierarchyItem.d.ts +6 -0
  225. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolCallHierarchyItem.js +16 -0
  226. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolCodeAction.d.ts +6 -0
  227. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolCodeAction.js +14 -0
  228. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolCodeLens.d.ts +5 -0
  229. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolCodeLens.js +13 -0
  230. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolCompletionItem.d.ts +11 -0
  231. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolCompletionItem.js +13 -0
  232. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolConverter.d.ts +167 -0
  233. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolConverter.js +1134 -0
  234. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolDiagnostic.d.ts +18 -0
  235. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolDiagnostic.js +25 -0
  236. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolDocumentLink.d.ts +5 -0
  237. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolDocumentLink.js +13 -0
  238. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolInlayHint.d.ts +5 -0
  239. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolInlayHint.js +13 -0
  240. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolTypeHierarchyItem.d.ts +6 -0
  241. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolTypeHierarchyItem.js +16 -0
  242. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolWorkspaceSymbol.d.ts +7 -0
  243. package/vscode-naide/node_modules/vscode-languageclient/lib/common/protocolWorkspaceSymbol.js +18 -0
  244. package/vscode-naide/node_modules/vscode-languageclient/lib/common/reference.d.ts +20 -0
  245. package/vscode-naide/node_modules/vscode-languageclient/lib/common/reference.js +53 -0
  246. package/vscode-naide/node_modules/vscode-languageclient/lib/common/rename.d.ts +27 -0
  247. package/vscode-naide/node_modules/vscode-languageclient/lib/common/rename.js +113 -0
  248. package/vscode-naide/node_modules/vscode-languageclient/lib/common/selectionRange.d.ts +16 -0
  249. package/vscode-naide/node_modules/vscode-languageclient/lib/common/selectionRange.js +57 -0
  250. package/vscode-naide/node_modules/vscode-languageclient/lib/common/semanticTokens.d.ts +33 -0
  251. package/vscode-naide/node_modules/vscode-languageclient/lib/common/semanticTokens.js +179 -0
  252. package/vscode-naide/node_modules/vscode-languageclient/lib/common/signatureHelp.d.ts +16 -0
  253. package/vscode-naide/node_modules/vscode-languageclient/lib/common/signatureHelp.js +71 -0
  254. package/vscode-naide/node_modules/vscode-languageclient/lib/common/textSynchronization.d.ts +101 -0
  255. package/vscode-naide/node_modules/vscode-languageclient/lib/common/textSynchronization.js +402 -0
  256. package/vscode-naide/node_modules/vscode-languageclient/lib/common/typeDefinition.d.ts +16 -0
  257. package/vscode-naide/node_modules/vscode-languageclient/lib/common/typeDefinition.js +55 -0
  258. package/vscode-naide/node_modules/vscode-languageclient/lib/common/typeHierarchy.d.ts +31 -0
  259. package/vscode-naide/node_modules/vscode-languageclient/lib/common/typeHierarchy.js +96 -0
  260. package/vscode-naide/node_modules/vscode-languageclient/lib/common/utils/async.d.ts +41 -0
  261. package/vscode-naide/node_modules/vscode-languageclient/lib/common/utils/async.js +276 -0
  262. package/vscode-naide/node_modules/vscode-languageclient/lib/common/utils/is.d.ts +12 -0
  263. package/vscode-naide/node_modules/vscode-languageclient/lib/common/utils/is.js +57 -0
  264. package/vscode-naide/node_modules/vscode-languageclient/lib/common/utils/uuid.d.ts +22 -0
  265. package/vscode-naide/node_modules/vscode-languageclient/lib/common/utils/uuid.js +97 -0
  266. package/vscode-naide/node_modules/vscode-languageclient/lib/common/workspaceFolder.d.ts +30 -0
  267. package/vscode-naide/node_modules/vscode-languageclient/lib/common/workspaceFolder.js +148 -0
  268. package/vscode-naide/node_modules/vscode-languageclient/lib/common/workspaceSymbol.d.ts +19 -0
  269. package/vscode-naide/node_modules/vscode-languageclient/lib/common/workspaceSymbol.js +79 -0
  270. package/vscode-naide/node_modules/vscode-languageclient/lib/node/main.d.ts +100 -0
  271. package/vscode-naide/node_modules/vscode-languageclient/lib/node/main.js +570 -0
  272. package/vscode-naide/node_modules/vscode-languageclient/lib/node/processes.d.ts +6 -0
  273. package/vscode-naide/node_modules/vscode-languageclient/lib/node/processes.js +47 -0
  274. package/vscode-naide/node_modules/vscode-languageclient/lib/node/terminateProcess.sh +16 -0
  275. package/vscode-naide/node_modules/vscode-languageclient/node.cmd +5 -0
  276. package/vscode-naide/node_modules/vscode-languageclient/node.d.ts +6 -0
  277. package/vscode-naide/node_modules/vscode-languageclient/node.js +7 -0
  278. package/vscode-naide/node_modules/vscode-languageclient/package.json +50 -0
  279. package/vscode-naide/node_modules/vscode-languageserver-protocol/License.txt +11 -0
  280. package/vscode-naide/node_modules/vscode-languageserver-protocol/README.md +16 -0
  281. package/vscode-naide/node_modules/vscode-languageserver-protocol/browser.d.ts +6 -0
  282. package/vscode-naide/node_modules/vscode-languageserver-protocol/browser.js +7 -0
  283. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/browser/main.d.ts +4 -0
  284. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/browser/main.js +28 -0
  285. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/api.d.ts +58 -0
  286. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/api.js +77 -0
  287. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/connection.d.ts +187 -0
  288. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/connection.js +15 -0
  289. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/messages.d.ts +51 -0
  290. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/messages.js +44 -0
  291. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.$.d.ts +1 -0
  292. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.$.js +43 -0
  293. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.callHierarchy.d.ts +86 -0
  294. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.callHierarchy.js +42 -0
  295. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.colorProvider.d.ts +66 -0
  296. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.colorProvider.js +32 -0
  297. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.configuration.d.ts +35 -0
  298. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.configuration.js +24 -0
  299. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.d.ts +3252 -0
  300. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.declaration.d.ts +37 -0
  301. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.declaration.js +22 -0
  302. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.diagnostic.d.ts +341 -0
  303. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.diagnostic.js +74 -0
  304. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.fileOperations.d.ts +306 -0
  305. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.fileOperations.js +101 -0
  306. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.foldingRange.d.ts +109 -0
  307. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.foldingRange.js +30 -0
  308. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.implementation.d.ts +38 -0
  309. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.implementation.js +21 -0
  310. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.inlayHint.d.ts +110 -0
  311. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.inlayHint.js +43 -0
  312. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.inlineCompletion.d.ts +57 -0
  313. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.inlineCompletion.js +22 -0
  314. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.inlineValue.d.ts +86 -0
  315. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.inlineValue.js +30 -0
  316. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.js +943 -0
  317. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.linkedEditingRange.d.ts +52 -0
  318. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.linkedEditingRange.js +19 -0
  319. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.moniker.d.ts +106 -0
  320. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.moniker.js +68 -0
  321. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.notebook.d.ts +400 -0
  322. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.notebook.js +214 -0
  323. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.progress.d.ts +107 -0
  324. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.progress.js +37 -0
  325. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.selectionRange.d.ts +41 -0
  326. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.selectionRange.js +20 -0
  327. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.semanticTokens.d.ts +223 -0
  328. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.semanticTokens.js +57 -0
  329. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.showDocument.d.ts +72 -0
  330. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.showDocument.js +22 -0
  331. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.typeDefinition.d.ts +38 -0
  332. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.typeDefinition.js +21 -0
  333. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.typeHierarchy.d.ts +83 -0
  334. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.typeHierarchy.js +42 -0
  335. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.workspaceFolder.d.ts +74 -0
  336. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/protocol.workspaceFolder.js +27 -0
  337. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/utils/is.d.ts +9 -0
  338. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/common/utils/is.js +46 -0
  339. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/node/main.d.ts +6 -0
  340. package/vscode-naide/node_modules/vscode-languageserver-protocol/lib/node/main.js +28 -0
  341. package/vscode-naide/node_modules/vscode-languageserver-protocol/metaModel.schema.json +783 -0
  342. package/vscode-naide/node_modules/vscode-languageserver-protocol/node.cmd +5 -0
  343. package/vscode-naide/node_modules/vscode-languageserver-protocol/node.d.ts +6 -0
  344. package/vscode-naide/node_modules/vscode-languageserver-protocol/node.js +7 -0
  345. package/vscode-naide/node_modules/vscode-languageserver-protocol/package.json +45 -0
  346. package/vscode-naide/node_modules/vscode-languageserver-protocol/thirdpartynotices.txt +31 -0
  347. package/vscode-naide/node_modules/vscode-languageserver-types/License.txt +11 -0
  348. package/vscode-naide/node_modules/vscode-languageserver-types/README.md +17 -0
  349. package/vscode-naide/node_modules/vscode-languageserver-types/lib/esm/main.d.ts +3139 -0
  350. package/vscode-naide/node_modules/vscode-languageserver-types/lib/esm/main.js +2222 -0
  351. package/vscode-naide/node_modules/vscode-languageserver-types/lib/esm/package.json +3 -0
  352. package/vscode-naide/node_modules/vscode-languageserver-types/lib/umd/main.d.ts +3139 -0
  353. package/vscode-naide/node_modules/vscode-languageserver-types/lib/umd/main.js +2272 -0
  354. package/vscode-naide/node_modules/vscode-languageserver-types/package.json +38 -0
  355. package/vscode-naide/node_modules/vscode-languageserver-types/thirdpartynotices.txt +16 -0
  356. package/vscode-naide/package-lock.json +96 -0
  357. package/vscode-naide/package.json +59 -0
  358. package/vscode-naide/syntaxes/naide.tmLanguage.json +194 -0
  359. package/vscode-naide/syntaxes/naidex.tmLanguage.json +287 -0
@@ -0,0 +1,1313 @@
1
+ export class Generator {
2
+ constructor(options = {}) {
3
+ this.indent = 0;
4
+ this.output = [];
5
+ this.usesExpress = false;
6
+ this.models = new Map();
7
+ this.runtimeImports = new Set();
8
+ this.schemas = new Map();
9
+ this.needsEventBus = false;
10
+ this.runtimePath = options.runtimePath || 'naider/runtime';
11
+ this.dbDir = null;
12
+ this.authSecret = null;
13
+ this.hasWs = false;
14
+ this.wsNodes = [];
15
+ this.hasTests = false;
16
+ this.hasAsserts = false;
17
+ this.dbSql = false;
18
+ this.sqlDriver = null;
19
+ }
20
+
21
+ generate(ast) {
22
+ this.visitProgram(ast);
23
+
24
+ const preamble = [];
25
+
26
+ if (this.needsEventBus) {
27
+ this.runtimeImports.add('createEventBus');
28
+ }
29
+
30
+ if (this.runtimeImports.size > 0) {
31
+ const imports = [...this.runtimeImports].join(', ');
32
+ preamble.push(`import { ${imports} } from '${this.runtimePath}';`);
33
+ preamble.push('');
34
+ }
35
+
36
+ if (this.hasTests) {
37
+ preamble.push("import { test } from 'node:test';");
38
+ }
39
+ if (this.hasTests || this.hasAsserts) {
40
+ preamble.push("import assert from 'node:assert/strict';");
41
+ if (this.hasTests) preamble.push('');
42
+ }
43
+
44
+ if (this.needsEventBus) {
45
+ preamble.push('const __eventBus = createEventBus();');
46
+ preamble.push('');
47
+ }
48
+
49
+ if (preamble.length > 0) {
50
+ this.output.unshift(...preamble);
51
+ }
52
+
53
+ return this.output.join('\n');
54
+ }
55
+
56
+ emit(line) {
57
+ this.output.push(' '.repeat(this.indent) + line);
58
+ }
59
+
60
+ emitRaw(line) {
61
+ this.output.push(line);
62
+ }
63
+
64
+ visitProgram(node) {
65
+ for (const stmt of node.body) {
66
+ this.visitStatement(stmt);
67
+ }
68
+ }
69
+
70
+ visitStatement(node) {
71
+ switch (node.type) {
72
+ case 'Use': return this.visitUse(node);
73
+ case 'UseDestructured': return this.visitUseDestructured(node);
74
+ case 'Function': return this.visitFunction(node);
75
+ case 'Return': return this.visitReturn(node);
76
+ case 'ReturnStatus': return this.visitReturnStatus(node);
77
+ case 'ReturnMethod': return this.visitReturnMethod(node);
78
+ case 'TypedVar': return this.visitTypedVar(node);
79
+ case 'If': return this.visitIf(node);
80
+ case 'Each': return this.visitEach(node);
81
+ case 'For': return this.visitFor(node);
82
+ case 'While': return this.visitWhile(node);
83
+ case 'Match': return this.visitMatch(node);
84
+ case 'Try': return this.visitTry(node);
85
+ case 'Server': return this.visitServer(node);
86
+ case 'Model': return this.visitModel(node);
87
+ case 'On': return this.visitOn(node);
88
+ case 'Log': return this.visitLog(node);
89
+ case 'Throw': return this.visitThrow(node);
90
+ case 'Break': this.emit('break;'); return;
91
+ case 'Continue': this.emit('continue;'); return;
92
+ case 'Assignment': return this.visitAssignment(node);
93
+ case 'CompoundAssign': return this.visitCompoundAssign(node);
94
+ case 'ExprStatement': this.emit(this.expr(node.expression) + ';'); return;
95
+ case 'DbConnect': return this.visitDbConnect(node);
96
+ case 'DbDir': return this.visitDbDir(node);
97
+ case 'DbSql': return this.visitDbSql(node);
98
+ case 'AwaitAll': return this.visitAwaitAllStatement(node);
99
+ case 'SchemaDecl': return this.visitSchema(node);
100
+ case 'CrudDecl': return this.visitCrudTopLevel(node);
101
+ case 'AuthDecl': return this.visitAuthTopLevel(node);
102
+ case 'CorsDecl': return this.visitCorsTopLevel(node);
103
+ case 'LimitDecl': return this.visitLimitTopLevel(node);
104
+ case 'EnvDecl': return this.visitEnv(node);
105
+ case 'EveryDecl': return this.visitEvery(node);
106
+ case 'WatchDecl': return this.visitWatch(node);
107
+ case 'StaticDecl': return this.visitStaticTopLevel(node);
108
+ case 'WsDecl': return this.visitWsTopLevel(node);
109
+ case 'GroupDecl': return this.visitGroupTopLevel(node);
110
+ case 'ErrorHandler': return this.visitErrorHandlerTopLevel(node);
111
+ case 'CookieDecl': return this.visitCookieTopLevel(node);
112
+ case 'UploadDecl': return this.visitUploadTopLevel(node);
113
+ case 'SessionDecl': return this.visitSessionTopLevel(node);
114
+ case 'ViewDecl': return this.visitViewTopLevel(node);
115
+ case 'SseDecl': return this.visitSseTopLevel(node);
116
+ case 'CacheDecl': return this.visitCacheTopLevel(node);
117
+ case 'MiddlewareRef': return this.visitMiddlewareRefTopLevel(node);
118
+ case 'ReturnRender': return this.visitReturnRender(node);
119
+ case 'ValidateDecl': return this.visitValidateTopLevel(node);
120
+ case 'TestDecl': return this.visitTest(node);
121
+ case 'AssertStmt': return this.visitAssert(node);
122
+ case 'QueueDecl': return this.visitQueue(node);
123
+ case 'OpenapiDecl': return this.visitOpenapiTopLevel(node);
124
+ case 'ReturnRedirect': return this.visitReturnRedirect(node);
125
+ case 'ReturnDownload': return this.visitReturnDownload(node);
126
+ case 'PromptDecl': return this.visitPrompt(node);
127
+ default:
128
+ this.emit(`/* unknown: ${node.type} */`);
129
+ }
130
+ }
131
+
132
+ visitUse(node) {
133
+ const source = node.source ? this.stringValue(node.source) : `'${node.name}'`;
134
+ const alias = node.alias || node.name;
135
+ if (source.includes('express')) this.usesExpress = true;
136
+ this.emit(`import ${alias} from ${this.rewriteNaideImport(source)};`);
137
+ }
138
+
139
+ visitUseDestructured(node) {
140
+ const source = this.stringValue(node.source);
141
+ const names = node.names.map(n => n.alias ? `${n.name} as ${n.alias}` : n.name).join(', ');
142
+ this.emit(`import { ${names} } from ${this.rewriteNaideImport(source)};`);
143
+ }
144
+
145
+ rewriteNaideImport(source) {
146
+ return source.replace(/\.(naide|nx)(['"])/g, '.mjs$2');
147
+ }
148
+
149
+ visitFunction(node) {
150
+ const exp = node.isPublic ? 'export ' : '';
151
+ const async = node.isAsync ? 'async ' : '';
152
+ const params = node.params.map(p => {
153
+ let s = p.spread ? '...' : '';
154
+ s += p.name;
155
+ if (p.defaultValue) s += ` = ${this.expr(p.defaultValue)}`;
156
+ return s;
157
+ }).join(', ');
158
+
159
+ this.emit(`${exp}${async}function ${node.name}(${params}) {`);
160
+ this.indent++;
161
+ for (const stmt of node.body) {
162
+ this.visitStatement(stmt);
163
+ }
164
+ this.indent--;
165
+ this.emit('}');
166
+ this.emitRaw('');
167
+ }
168
+
169
+ visitReturn(node) {
170
+ if (node.value === null) {
171
+ this.emit('return;');
172
+ } else {
173
+ this.emit(`return ${this.expr(node.value)};`);
174
+ }
175
+ }
176
+
177
+ visitReturnStatus(node) {
178
+ this.emit(`return res.status(${this.expr(node.statusCode)}).json(${this.expr(node.body)});`);
179
+ }
180
+
181
+ visitReturnMethod(node) {
182
+ const val = this.expr(node.value);
183
+ switch (node.method) {
184
+ case 'redirect':
185
+ this.emit(`return res.redirect(${val});`);
186
+ break;
187
+ case 'html':
188
+ this.emit(`return res.type('html').send(${val});`);
189
+ break;
190
+ case 'text':
191
+ this.emit(`return res.type('text').send(${val});`);
192
+ break;
193
+ case 'file':
194
+ this.emit(`return res.sendFile(${val});`);
195
+ break;
196
+ default:
197
+ this.emit(`return res.${node.method}(${val});`);
198
+ }
199
+ }
200
+
201
+ visitTypedVar(node) {
202
+ const keyword = node.isMut ? 'let' : 'const';
203
+ const exp = node.isPublic ? 'export ' : '';
204
+ this.emit(`${exp}${keyword} ${node.name} = ${this.expr(node.value)};`);
205
+ }
206
+
207
+ visitAssignment(node) {
208
+ const target = this.expr(node.target);
209
+ const value = this.expr(node.value);
210
+
211
+ if (node.target.type === 'Array') {
212
+ const names = node.target.elements.map(e => this.expr(e)).join(', ');
213
+ this.emit(`const [${names}] = ${value};`);
214
+ } else if (node.target.type === 'Object') {
215
+ const names = node.target.properties.map(p => {
216
+ if (p.type === 'shorthand') return p.key;
217
+ return `${p.key}: ${this.expr(p.value)}`;
218
+ }).join(', ');
219
+ this.emit(`const { ${names} } = ${value};`);
220
+ } else {
221
+ this.emit(`${target} = ${value};`);
222
+ }
223
+ }
224
+
225
+ visitCompoundAssign(node) {
226
+ this.emit(`${this.expr(node.target)} ${node.op} ${this.expr(node.value)};`);
227
+ }
228
+
229
+ visitIf(node) {
230
+ this.emit(`if (${this.expr(node.condition)}) {`);
231
+ this.indent++;
232
+ for (const stmt of node.body) this.visitStatement(stmt);
233
+ this.indent--;
234
+
235
+ for (const elif of node.elifs) {
236
+ this.emit(`} else if (${this.expr(elif.condition)}) {`);
237
+ this.indent++;
238
+ for (const stmt of elif.body) this.visitStatement(stmt);
239
+ this.indent--;
240
+ }
241
+
242
+ if (node.elseBody) {
243
+ this.emit('} else {');
244
+ this.indent++;
245
+ for (const stmt of node.elseBody) this.visitStatement(stmt);
246
+ this.indent--;
247
+ }
248
+ this.emit('}');
249
+ }
250
+
251
+ visitEach(node) {
252
+ const collection = this.expr(node.collection);
253
+ if (node.key) {
254
+ this.emit(`for (const [${node.key}, ${node.value}] of Object.entries(${collection})) {`);
255
+ } else {
256
+ this.emit(`for (const ${node.value} of ${collection}) {`);
257
+ }
258
+ this.indent++;
259
+ for (const stmt of node.body) this.visitStatement(stmt);
260
+ this.indent--;
261
+ this.emit('}');
262
+ }
263
+
264
+ visitFor(node) {
265
+ const varName = node.varName;
266
+ const start = this.expr(node.start);
267
+ const end = this.expr(node.end);
268
+ this.emit(`for (let ${varName} = ${start}; ${varName} < ${end}; ${varName}++) {`);
269
+ this.indent++;
270
+ for (const stmt of node.body) this.visitStatement(stmt);
271
+ this.indent--;
272
+ this.emit('}');
273
+ }
274
+
275
+ visitWhile(node) {
276
+ this.emit(`while (${this.expr(node.condition)}) {`);
277
+ this.indent++;
278
+ for (const stmt of node.body) this.visitStatement(stmt);
279
+ this.indent--;
280
+ this.emit('}');
281
+ }
282
+
283
+ visitMatch(node) {
284
+ this.emit(`switch (${this.expr(node.value)}) {`);
285
+ this.indent++;
286
+ for (const c of node.cases) {
287
+ if (c.pattern.type === 'DefaultPattern') {
288
+ this.emit('default: {');
289
+ } else {
290
+ this.emit(`case ${this.expr(c.pattern)}: {`);
291
+ }
292
+ this.indent++;
293
+ for (const stmt of c.body) this.visitStatement(stmt);
294
+ this.emit('break;');
295
+ this.indent--;
296
+ this.emit('}');
297
+ }
298
+ this.indent--;
299
+ this.emit('}');
300
+ }
301
+
302
+ visitTry(node) {
303
+ this.emit('try {');
304
+ this.indent++;
305
+ for (const stmt of node.body) this.visitStatement(stmt);
306
+ this.indent--;
307
+ if (node.catchBody) {
308
+ const catchParam = node.catchVar || '_err';
309
+ this.emit(`} catch (${catchParam}) {`);
310
+ this.indent++;
311
+ for (const stmt of node.catchBody) this.visitStatement(stmt);
312
+ this.indent--;
313
+ }
314
+ if (node.ensureBody) {
315
+ this.emit('} finally {');
316
+ this.indent++;
317
+ for (const stmt of node.ensureBody) this.visitStatement(stmt);
318
+ this.indent--;
319
+ }
320
+ this.emit('}');
321
+ }
322
+
323
+ visitServer(node) {
324
+ const hasWs = node.routes.some(r => r.type === 'WsDecl');
325
+
326
+ this.emit(`import express from 'express';`);
327
+ if (hasWs) {
328
+ this.emit(`import { WebSocketServer } from 'ws';`);
329
+ }
330
+ this.emitRaw('');
331
+ this.emit(`const ${node.name} = express();`);
332
+ this.emit(`${node.name}.use(express.json());`);
333
+ this.emit(`${node.name}.use(express.urlencoded({ extended: true }));`);
334
+ this.emitRaw('');
335
+
336
+ for (const mid of node.middleware) {
337
+ this.emit(`${node.name}.use(${this.generateMiddleware(mid)});`);
338
+ this.emitRaw('');
339
+ }
340
+
341
+ const wsNodes = [];
342
+ const errorHandlers = [];
343
+
344
+ for (const child of node.routes) {
345
+ if (child.type === 'Route') {
346
+ this.visitRoute(node.name, child);
347
+ } else if (child.type === 'CrudDecl') {
348
+ this.visitCrud(node.name, child);
349
+ } else if (child.type === 'AuthDecl') {
350
+ this.visitAuth(node.name, child);
351
+ } else if (child.type === 'CorsDecl') {
352
+ this.visitCors(node.name, child);
353
+ } else if (child.type === 'LimitDecl') {
354
+ this.visitLimit(node.name, child);
355
+ } else if (child.type === 'StaticDecl') {
356
+ this.visitStatic(node.name, child);
357
+ } else if (child.type === 'WsDecl') {
358
+ wsNodes.push(child);
359
+ } else if (child.type === 'GroupDecl') {
360
+ this.visitGroup(node.name, child);
361
+ } else if (child.type === 'ErrorHandler') {
362
+ errorHandlers.push(child);
363
+ } else if (child.type === 'CookieDecl') {
364
+ this.visitCookie(node.name, child);
365
+ } else if (child.type === 'UploadDecl') {
366
+ this.visitUpload(node.name, child);
367
+ } else if (child.type === 'SessionDecl') {
368
+ this.visitSession(node.name, child);
369
+ } else if (child.type === 'ViewDecl') {
370
+ this.visitView(node.name, child);
371
+ } else if (child.type === 'SseDecl') {
372
+ this.visitSse(node.name, child);
373
+ } else if (child.type === 'CacheDecl') {
374
+ this.visitCache(node.name, child);
375
+ } else if (child.type === 'MiddlewareRef') {
376
+ this.visitMiddlewareRef(node.name, child);
377
+ } else if (child.type === 'ValidateDecl') {
378
+ this.visitValidate(node.name, child);
379
+ } else if (child.type === 'OpenapiDecl') {
380
+ this.visitOpenapi(node.name, child);
381
+ } else if (child.type === 'QueueDecl') {
382
+ this.visitQueue(child);
383
+ } else {
384
+ this.visitStatement(child);
385
+ }
386
+ }
387
+
388
+ for (const eh of errorHandlers) {
389
+ this.visitErrorHandler(node.name, eh);
390
+ }
391
+
392
+ const port = node.port ? this.expr(node.port) : '3000';
393
+ this.emitRaw('');
394
+ if (hasWs) {
395
+ this.emit(`const __server = ${node.name}.listen(${port}, () => {`);
396
+ } else {
397
+ this.emit(`${node.name}.listen(${port}, () => {`);
398
+ }
399
+ this.indent++;
400
+ this.emit(`console.log(\`Server running on port \${${port}}\`);`);
401
+ this.indent--;
402
+ this.emit('});');
403
+
404
+ for (const wsNode of wsNodes) {
405
+ this.emitRaw('');
406
+ this.visitWs(wsNode);
407
+ }
408
+ }
409
+
410
+ visitRoute(appName, route) {
411
+ const method = route.method === 'del' ? 'delete' : route.method;
412
+ const path = this.stringValue(route.path);
413
+ const params = route.params.length > 0 ? route.params.join(', ') : 'req, res';
414
+
415
+ const needsAsync = this.bodyUsesAwait(route.body);
416
+ const asyncPrefix = needsAsync ? 'async ' : '';
417
+
418
+ const midArgs = route.middleware && route.middleware.length > 0
419
+ ? route.middleware.map(m => this.expr(m)).join(', ') + ', '
420
+ : '';
421
+
422
+ this.emit(`${appName}.${method}(${path}, ${midArgs}${asyncPrefix}(${params}) => {`);
423
+ this.indent++;
424
+
425
+ const hasRes = params.includes('res');
426
+
427
+ for (let i = 0; i < route.body.length; i++) {
428
+ const stmt = route.body[i];
429
+ if (stmt.type === 'Return' && stmt.value !== null) {
430
+ if (hasRes || params === 'req, res') {
431
+ this.emit(`res.json(${this.expr(stmt.value)});`);
432
+ } else {
433
+ this.emit(`return ${this.expr(stmt.value)};`);
434
+ }
435
+ } else {
436
+ this.visitStatement(stmt);
437
+ }
438
+ }
439
+
440
+ this.indent--;
441
+ this.emit('});');
442
+ this.emitRaw('');
443
+ }
444
+
445
+ generateMiddleware(mid) {
446
+ const params = mid.params.join(', ');
447
+ let code = `(${params}) => {\n`;
448
+ for (const stmt of mid.body) {
449
+ code += ' ' + this.statementToString(stmt) + '\n';
450
+ }
451
+ code += ' }';
452
+ return code;
453
+ }
454
+
455
+ visitModel(node) {
456
+ this.models.set(node.name, node);
457
+
458
+ const exp = node.isPublic ? 'export ' : '';
459
+ const ext = node.parent ? ` extends ${node.parent}` : '';
460
+ this.emit(`${exp}class ${node.name}${ext} {`);
461
+ this.indent++;
462
+
463
+ if (node.fields.length > 0 || node.parent) {
464
+ const parentModel = node.parent ? this.models.get(node.parent) : null;
465
+ const parentFields = parentModel ? parentModel.fields : [];
466
+ const allFields = [...parentFields, ...node.fields];
467
+
468
+ const constructorParams = allFields.map(f => {
469
+ if (f.defaultValue) return `${f.name} = ${this.expr(f.defaultValue)}`;
470
+ return f.name;
471
+ }).join(', ');
472
+
473
+ this.emit(`constructor(${constructorParams}) {`);
474
+ this.indent++;
475
+ if (node.parent) {
476
+ const superArgs = parentFields.map(f => f.name).join(', ');
477
+ this.emit(`super(${superArgs});`);
478
+ }
479
+ for (const f of node.fields) {
480
+ this.emit(`this.${f.name} = ${f.name};`);
481
+ }
482
+ this.indent--;
483
+ this.emit('}');
484
+ this.emitRaw('');
485
+ }
486
+
487
+ for (const method of node.methods) {
488
+ const async = method.isAsync ? 'async ' : '';
489
+ const params = method.params.map(p => {
490
+ let s = p.spread ? '...' : '';
491
+ s += p.name;
492
+ if (p.defaultValue) s += ` = ${this.expr(p.defaultValue)}`;
493
+ return s;
494
+ }).join(', ');
495
+
496
+ this.emit(`${async}${method.name}(${params}) {`);
497
+ this.indent++;
498
+ for (const stmt of method.body) {
499
+ this.visitStatement(stmt);
500
+ }
501
+ this.indent--;
502
+ this.emit('}');
503
+ this.emitRaw('');
504
+ }
505
+
506
+ this.indent--;
507
+ this.emit('}');
508
+ this.emitRaw('');
509
+ }
510
+
511
+ visitOn(node) {
512
+ const event = this.expr(node.event);
513
+ if (node.event.type === 'MemberAccess') {
514
+ const obj = this.expr(node.event.object);
515
+ const evt = node.event.property;
516
+ this.emit(`${obj}.on('${evt}', () => {`);
517
+ } else {
518
+ this.emit(`${event}(() => {`);
519
+ }
520
+ this.indent++;
521
+ for (const stmt of node.body) this.visitStatement(stmt);
522
+ this.indent--;
523
+ this.emit('});');
524
+ }
525
+
526
+ visitLog(node) {
527
+ const method = node.level === 'log' ? 'log' : node.level;
528
+ const args = node.args.map(a => this.expr(a)).join(', ');
529
+ this.emit(`console.${method}(${args});`);
530
+ }
531
+
532
+ visitThrow(node) {
533
+ const value = this.expr(node.value);
534
+ if (node.value.type === 'String') {
535
+ this.emit(`throw new Error(${value});`);
536
+ } else {
537
+ this.emit(`throw ${value};`);
538
+ }
539
+ }
540
+
541
+ visitDbConnect(node) {
542
+ this.emit(`const db = new Database(${this.expr(node.connectionString)});`);
543
+ }
544
+
545
+ visitDbDir(node) {
546
+ const raw = node.path.raw || node.path.parts?.map(p => p.value).join('') || 'data/';
547
+ this.dbDir = raw.endsWith('/') ? raw : raw + '/';
548
+ }
549
+
550
+ visitDbSql(node) {
551
+ this.dbSql = true;
552
+ const driverRaw = node.driver.raw || node.driver.parts?.map(p => p.value).join('') || 'sqlite';
553
+ this.sqlDriver = driverRaw;
554
+
555
+ if (driverRaw === 'sqlite') {
556
+ this.emit(`import Database from 'better-sqlite3';`);
557
+ const conn = node.connection ? this.stringValue(node.connection) : '"data.db"';
558
+ this.emit(`const __db = new Database(${conn});`);
559
+ this.emit(`__db.pragma('journal_mode = WAL');`);
560
+ } else if (driverRaw === 'postgres' || driverRaw === 'pg') {
561
+ this.emit(`import pg from 'pg';`);
562
+ const conn = node.connection ? this.stringValue(node.connection) : 'process.env.DATABASE_URL';
563
+ this.emit(`const __pool = new pg.Pool({ connectionString: ${conn} });`);
564
+ }
565
+ this.emitRaw('');
566
+ }
567
+
568
+ visitAwaitAllStatement(node) {
569
+ const exprs = node.expressions.map(e => this.expr(e)).join(', ');
570
+ this.emit(`await Promise.all([${exprs}]);`);
571
+ }
572
+
573
+ // ===== High-level features =====
574
+
575
+ visitSchema(node) {
576
+ this.runtimeImports.add('createSchema');
577
+ if (this.dbDir) {
578
+ this.runtimeImports.add('createFileStore');
579
+ } else {
580
+ this.runtimeImports.add('createStore');
581
+ }
582
+
583
+ this.emit(`const ${node.name}Schema = createSchema('${node.name}', {`);
584
+ this.indent++;
585
+
586
+ for (const field of node.fields) {
587
+ const props = [];
588
+
589
+ switch (field.type) {
590
+ case 'auto':
591
+ props.push("type: 'id'", 'auto: true');
592
+ break;
593
+ case 'timestamp':
594
+ props.push("type: 'timestamp'");
595
+ break;
596
+ case 'str':
597
+ props.push("type: 'string'");
598
+ break;
599
+ case 'int':
600
+ props.push("type: 'integer'");
601
+ break;
602
+ case 'num':
603
+ props.push("type: 'number'");
604
+ break;
605
+ case 'bool':
606
+ props.push("type: 'boolean'");
607
+ break;
608
+ case 'enum':
609
+ if (field.enumValues) {
610
+ const vals = field.enumValues.map(v => this.expr(v)).join(', ');
611
+ props.push("type: 'enum'", `values: [${vals}]`);
612
+ } else {
613
+ props.push("type: 'enum'");
614
+ }
615
+ break;
616
+ default:
617
+ props.push(`type: '${field.type}'`);
618
+ break;
619
+ }
620
+
621
+ for (const mod of field.modifiers) {
622
+ switch (mod.name) {
623
+ case 'required': props.push('required: true'); break;
624
+ case 'optional': props.push('required: false'); break;
625
+ case 'unique': props.push('unique: true'); break;
626
+ case 'email': props.push('email: true'); break;
627
+ case 'url': props.push('url: true'); break;
628
+ case 'auto': props.push('auto: true'); break;
629
+ case 'min': props.push(`min: ${this.expr(mod.args[0])}`); break;
630
+ case 'max': props.push(`max: ${this.expr(mod.args[0])}`); break;
631
+ case 'default': props.push(`default: ${this.expr(mod.args[0])}`); break;
632
+ }
633
+ }
634
+
635
+ this.emit(`${field.name}: { ${props.join(', ')} },`);
636
+ }
637
+
638
+ this.indent--;
639
+ this.emit('});');
640
+ if (this.dbSql && this.sqlDriver === 'sqlite') {
641
+ this.runtimeImports.add('createSqliteStore');
642
+ this.emit(`const ${node.name}Store = createSqliteStore(__db, '${node.name}', ${node.name}Schema);`);
643
+ } else if (this.dbDir) {
644
+ this.emit(`const ${node.name}Store = createFileStore(${node.name}Schema, '${this.dbDir}${node.name}.json');`);
645
+ } else {
646
+ this.emit(`const ${node.name}Store = createStore(${node.name}Schema);`);
647
+ }
648
+ this.emitRaw('');
649
+
650
+ this.schemas.set(node.name, node);
651
+ }
652
+
653
+ visitCrud(appName, node) {
654
+ this.runtimeImports.add('registerCrud');
655
+ this.needsEventBus = true;
656
+
657
+ const path = this.stringValue(node.path);
658
+ this.emit(`registerCrud(${appName}, ${path}, ${node.schemaName}Schema, ${node.schemaName}Store, __eventBus);`);
659
+ this.emitRaw('');
660
+ }
661
+
662
+ visitCrudTopLevel(node) {
663
+ this.visitCrud('app', node);
664
+ }
665
+
666
+ visitAuth(appName, node) {
667
+ this.runtimeImports.add('jwtAuth');
668
+
669
+ const secret = this.expr(node.secret);
670
+ this.authSecret = secret;
671
+
672
+ this.emit(`const __authSecret = ${secret};`);
673
+
674
+ const options = [];
675
+ if (node.publicPaths.length > 0) {
676
+ const paths = node.publicPaths.map(p => this.stringValue(p)).join(', ');
677
+ options.push(`public: [${paths}]`);
678
+ }
679
+ const optStr = options.length > 0 ? `, { ${options.join(', ')} }` : '';
680
+
681
+ if (node.protectedPaths.length > 0) {
682
+ const path = this.stringValue(node.protectedPaths[0]);
683
+ this.emit(`${appName}.use(${path}, jwtAuth(${secret}${optStr}));`);
684
+ } else {
685
+ this.emit(`${appName}.use(jwtAuth(${secret}${optStr}));`);
686
+ }
687
+ this.emitRaw('');
688
+ }
689
+
690
+ visitAuthTopLevel(node) {
691
+ this.visitAuth('app', node);
692
+ }
693
+
694
+ visitCors(appName, node) {
695
+ this.runtimeImports.add('corsMiddleware');
696
+
697
+ const origins = this.expr(node.origins);
698
+ if (node.origins.type === 'String') {
699
+ this.emit(`${appName}.use(corsMiddleware([${origins}]));`);
700
+ } else {
701
+ this.emit(`${appName}.use(corsMiddleware(${origins}));`);
702
+ }
703
+ this.emitRaw('');
704
+ }
705
+
706
+ visitCorsTopLevel(node) {
707
+ this.visitCors('app', node);
708
+ }
709
+
710
+ visitLimit(appName, node) {
711
+ this.runtimeImports.add('rateLimit');
712
+
713
+ const path = this.stringValue(node.path);
714
+ const max = this.expr(node.max);
715
+ const window = this.expr(node.window);
716
+ this.emit(`${appName}.use(${path}, rateLimit(${max}, ${window}));`);
717
+ this.emitRaw('');
718
+ }
719
+
720
+ visitLimitTopLevel(node) {
721
+ this.visitLimit('app', node);
722
+ }
723
+
724
+ visitStatic(appName, node) {
725
+ let raw = node.path.raw || node.path.parts?.map(p => p.value).join('') || 'public';
726
+ if (raw.startsWith('/')) raw = raw.slice(1);
727
+ this.emit(`${appName}.use(express.static(${JSON.stringify(raw)}));`);
728
+ this.emitRaw('');
729
+ }
730
+
731
+ visitStaticTopLevel(node) {
732
+ this.visitStatic('app', node);
733
+ }
734
+
735
+ visitWs(node) {
736
+ const path = this.stringValue(node.path);
737
+ this.emit(`const __wss = new WebSocketServer({ server: __server, path: ${path} });`);
738
+ this.emit(`__wss.on('connection', (__ws) => {`);
739
+ this.indent++;
740
+ this.emit(`const send = (d) => __ws.send(typeof d === 'string' ? d : JSON.stringify(d));`);
741
+ this.emit(`const broadcast = (d) => { const m = typeof d === 'string' ? d : JSON.stringify(d); for (const c of __wss.clients) if (c.readyState === 1) c.send(m); };`);
742
+
743
+ const connectEvents = node.events.filter(e => {
744
+ const name = e.name.raw || e.name.parts?.map(p => p.value).join('');
745
+ return name === 'connect' || name === 'open';
746
+ });
747
+ const otherEvents = node.events.filter(e => {
748
+ const name = e.name.raw || e.name.parts?.map(p => p.value).join('');
749
+ return name !== 'connect' && name !== 'open';
750
+ });
751
+
752
+ for (const evt of connectEvents) {
753
+ this.emitRaw('');
754
+ for (const stmt of evt.body) this.visitStatement(stmt);
755
+ }
756
+
757
+ for (const evt of otherEvents) {
758
+ const evtName = evt.name.raw || evt.name.parts?.map(p => p.value).join('');
759
+ this.emitRaw('');
760
+
761
+ if (evtName === 'message') {
762
+ const needsAsync = this.bodyUsesAwait(evt.body);
763
+ const asyncPrefix = needsAsync ? 'async ' : '';
764
+ this.emit(`__ws.on('message', ${asyncPrefix}(__raw) => {`);
765
+ this.indent++;
766
+ const dataParam = evt.params[0] || 'data';
767
+ this.emit(`const ${dataParam} = JSON.parse(__raw);`);
768
+ for (const stmt of evt.body) this.visitStatement(stmt);
769
+ this.indent--;
770
+ this.emit('});');
771
+ } else {
772
+ const params = evt.params.length > 0 ? evt.params.join(', ') : '';
773
+ const needsAsync = this.bodyUsesAwait(evt.body);
774
+ const asyncPrefix = needsAsync ? 'async ' : '';
775
+ this.emit(`__ws.on('${evtName}', ${asyncPrefix}(${params}) => {`);
776
+ this.indent++;
777
+ for (const stmt of evt.body) this.visitStatement(stmt);
778
+ this.indent--;
779
+ this.emit('});');
780
+ }
781
+ }
782
+
783
+ this.indent--;
784
+ this.emit('});');
785
+ }
786
+
787
+ visitWsTopLevel(node) {
788
+ this.visitWs(node);
789
+ }
790
+
791
+ visitGroup(appName, node) {
792
+ const prefix = this.stringValue(node.prefix);
793
+ this.groupCounter = (this.groupCounter || 0) + 1;
794
+ const routerName = `__router${this.groupCounter}`;
795
+ this.emit(`const ${routerName} = express.Router();`);
796
+
797
+ for (const child of node.routes) {
798
+ if (child.type === 'Route') {
799
+ this.visitRoute(routerName, child);
800
+ } else if (child.type === 'CrudDecl') {
801
+ this.visitCrud(routerName, child);
802
+ } else if (child.type === 'AuthDecl') {
803
+ this.visitAuth(routerName, child);
804
+ } else if (child.type === 'GroupDecl') {
805
+ this.visitGroup(routerName, child);
806
+ } else {
807
+ this.visitStatement(child);
808
+ }
809
+ }
810
+
811
+ this.emit(`${appName}.use(${prefix}, ${routerName});`);
812
+ this.emitRaw('');
813
+ }
814
+
815
+ visitGroupTopLevel(node) {
816
+ this.visitGroup('app', node);
817
+ }
818
+
819
+ visitErrorHandler(appName, node) {
820
+ const params = node.params.join(', ');
821
+ this.emit(`${appName}.use((${params}, next) => {`);
822
+ this.indent++;
823
+ for (const stmt of node.body) this.visitStatement(stmt);
824
+ this.indent--;
825
+ this.emit('});');
826
+ this.emitRaw('');
827
+ }
828
+
829
+ visitErrorHandlerTopLevel(node) {
830
+ this.visitErrorHandler('app', node);
831
+ }
832
+
833
+ visitCookie(appName, node) {
834
+ this.runtimeImports.add('cookieParser');
835
+ this.emit(`${appName}.use(cookieParser());`);
836
+ this.emitRaw('');
837
+ }
838
+
839
+ visitCookieTopLevel(node) {
840
+ this.visitCookie('app', node);
841
+ }
842
+
843
+ visitUpload(appName, node) {
844
+ this.runtimeImports.add('uploadMiddleware');
845
+ const path = this.stringValue(node.path);
846
+ const field = this.stringValue(node.fieldName);
847
+ const params = node.params.length > 0 ? node.params.join(', ') : 'req, res';
848
+ const needsAsync = this.bodyUsesAwait(node.body);
849
+ const asyncPrefix = needsAsync ? 'async ' : '';
850
+ this.emit(`${appName}.post(${path}, uploadMiddleware(${field}), ${asyncPrefix}(${params}) => {`);
851
+ this.indent++;
852
+ for (const stmt of node.body) {
853
+ if (stmt.type === 'Return' && stmt.value !== null) {
854
+ this.emit(`res.json(${this.expr(stmt.value)});`);
855
+ } else {
856
+ this.visitStatement(stmt);
857
+ }
858
+ }
859
+ this.indent--;
860
+ this.emit('});');
861
+ this.emitRaw('');
862
+ }
863
+
864
+ visitUploadTopLevel(node) {
865
+ this.visitUpload('app', node);
866
+ }
867
+
868
+ visitSession(appName, node) {
869
+ this.runtimeImports.add('sessionMiddleware');
870
+ const secret = this.expr(node.secret);
871
+ this.emit(`${appName}.use(sessionMiddleware(${secret}));`);
872
+ this.emitRaw('');
873
+ }
874
+
875
+ visitSessionTopLevel(node) {
876
+ this.visitSession('app', node);
877
+ }
878
+
879
+ visitView(appName, node) {
880
+ this.runtimeImports.add('createRenderer');
881
+ const dir = this.stringValue(node.dir);
882
+ this.emit(`const __render = createRenderer(${dir});`);
883
+ this.emitRaw('');
884
+ }
885
+
886
+ visitViewTopLevel(node) {
887
+ this.visitView('app', node);
888
+ }
889
+
890
+ visitSse(appName, node) {
891
+ this.runtimeImports.add('createSseManager');
892
+ const path = this.stringValue(node.path);
893
+ this.emit(`const sse = createSseManager();`);
894
+ this.emit(`${appName}.get(${path}, sse.handler());`);
895
+ this.emitRaw('');
896
+ }
897
+
898
+ visitSseTopLevel(node) {
899
+ this.visitSse('app', node);
900
+ }
901
+
902
+ visitCache(appName, node) {
903
+ this.runtimeImports.add('cacheMiddleware');
904
+ const path = this.stringValue(node.path);
905
+ const duration = this.expr(node.duration);
906
+ this.emit(`${appName}.use(${path}, cacheMiddleware(${duration}));`);
907
+ this.emitRaw('');
908
+ }
909
+
910
+ visitCacheTopLevel(node) {
911
+ this.visitCache('app', node);
912
+ }
913
+
914
+ visitMiddlewareRef(appName, node) {
915
+ if (node.path) {
916
+ this.emit(`${appName}.use(${this.stringValue(node.path)}, ${node.name});`);
917
+ } else {
918
+ this.emit(`${appName}.use(${node.name});`);
919
+ }
920
+ this.emitRaw('');
921
+ }
922
+
923
+ visitMiddlewareRefTopLevel(node) {
924
+ this.visitMiddlewareRef('app', node);
925
+ }
926
+
927
+ visitReturnRender(node) {
928
+ const template = this.expr(node.template);
929
+ const data = node.data ? this.expr(node.data) : '{}';
930
+ this.emit(`return res.type('html').send(__render(${template}, ${data}));`);
931
+ }
932
+
933
+ visitReturnRedirect(node) {
934
+ this.emit(`return res.redirect(${this.expr(node.statusCode)}, ${this.expr(node.url)});`);
935
+ }
936
+
937
+ visitReturnDownload(node) {
938
+ this.emit(`return res.download(${this.expr(node.filePath)}, ${this.expr(node.filename)});`);
939
+ }
940
+
941
+ visitValidate(appName, node) {
942
+ this.runtimeImports.add('validateMiddleware');
943
+ const path = this.stringValue(node.path);
944
+ this.emit(`${appName}.use(${path}, validateMiddleware(${node.schemaName}Schema));`);
945
+ this.emitRaw('');
946
+ }
947
+
948
+ visitValidateTopLevel(node) {
949
+ this.visitValidate('app', node);
950
+ }
951
+
952
+ visitTest(node) {
953
+ this.hasTests = true;
954
+ const name = this.expr(node.name);
955
+ const needsAsync = this.bodyUsesAwait(node.body);
956
+ const asyncPrefix = needsAsync ? 'async ' : '';
957
+ this.emit(`test(${name}, ${asyncPrefix}() => {`);
958
+ this.indent++;
959
+ for (const stmt of node.body) this.visitStatement(stmt);
960
+ this.indent--;
961
+ this.emit('});');
962
+ this.emitRaw('');
963
+ }
964
+
965
+ visitAssert(node) {
966
+ this.hasAsserts = true;
967
+ const exprNode = node.expr;
968
+ if (exprNode.type === 'Binary' && exprNode.op === '===') {
969
+ this.emit(`assert.strictEqual(${this.expr(exprNode.left)}, ${this.expr(exprNode.right)});`);
970
+ } else if (exprNode.type === 'Binary' && exprNode.op === '!==') {
971
+ this.emit(`assert.notStrictEqual(${this.expr(exprNode.left)}, ${this.expr(exprNode.right)});`);
972
+ } else {
973
+ this.emit(`assert.ok(${this.expr(exprNode)});`);
974
+ }
975
+ }
976
+
977
+ visitQueue(node) {
978
+ this.runtimeImports.add('createQueue');
979
+ this.emit(`const ${node.name} = createQueue();`);
980
+ for (const job of node.jobs) {
981
+ const params = job.params.length > 0 ? job.params.join(', ') : 'data';
982
+ const needsAsync = this.bodyUsesAwait(job.body);
983
+ const asyncPrefix = needsAsync ? 'async ' : '';
984
+ this.emit(`${node.name}.register(${this.generateString(job.name)}, ${asyncPrefix}(${params}) => {`);
985
+ this.indent++;
986
+ for (const stmt of job.body) this.visitStatement(stmt);
987
+ this.indent--;
988
+ this.emit('});');
989
+ }
990
+ this.emitRaw('');
991
+ }
992
+
993
+ visitPrompt(node) {
994
+ this.runtimeImports.add('createPrompt');
995
+ const lines = node.lines.map(l => this.generateString(l));
996
+ const template = lines.length === 1 ? lines[0] : `${lines.join(' + "\\n" + ')}`;
997
+ const defaults = node.defaults ? this.expr(node.defaults) : '{}';
998
+ this.emit(`const ${node.name} = createPrompt(${template}, ${defaults});`);
999
+ this.emitRaw('');
1000
+ }
1001
+
1002
+ visitOpenapi(appName, node) {
1003
+ this.runtimeImports.add('buildOpenApiSpec');
1004
+ const path = this.stringValue(node.path);
1005
+ const schemaNames = [...this.schemas.keys()];
1006
+ const schemaArgs = schemaNames.map(n => `${n}Schema`).join(', ');
1007
+ this.emit(`${appName}.get(${path}, (req, res) => {`);
1008
+ this.indent++;
1009
+ this.emit(`res.json(buildOpenApiSpec([${schemaArgs}]));`);
1010
+ this.indent--;
1011
+ this.emit('});');
1012
+ this.emitRaw('');
1013
+ }
1014
+
1015
+ visitOpenapiTopLevel(node) {
1016
+ this.visitOpenapi('app', node);
1017
+ }
1018
+
1019
+ visitEnv(node) {
1020
+ this.runtimeImports.add('loadEnv');
1021
+
1022
+ const names = node.vars.map(v => v.name);
1023
+ this.emit(`const { ${names.join(', ')} } = loadEnv({`);
1024
+ this.indent++;
1025
+
1026
+ for (const v of node.vars) {
1027
+ const props = [];
1028
+
1029
+ switch (v.type) {
1030
+ case 'str': props.push("type: 'string'"); break;
1031
+ case 'int': props.push("type: 'integer'"); break;
1032
+ case 'num': props.push("type: 'number'"); break;
1033
+ case 'bool': props.push("type: 'boolean'"); break;
1034
+ default: props.push(`type: '${v.type}'`); break;
1035
+ }
1036
+
1037
+ for (const mod of v.modifiers) {
1038
+ switch (mod.name) {
1039
+ case 'required': props.push('required: true'); break;
1040
+ case 'default': props.push(`default: ${this.expr(mod.args[0])}`); break;
1041
+ }
1042
+ }
1043
+
1044
+ this.emit(`${v.name}: { ${props.join(', ')} },`);
1045
+ }
1046
+
1047
+ this.indent--;
1048
+ this.emit('});');
1049
+ this.emitRaw('');
1050
+ }
1051
+
1052
+ visitEvery(node) {
1053
+ this.runtimeImports.add('scheduleEvery');
1054
+
1055
+ const interval = this.expr(node.interval);
1056
+ const needsAsync = this.bodyUsesAwait(node.body);
1057
+ const asyncPrefix = needsAsync ? 'async ' : '';
1058
+
1059
+ this.emit(`scheduleEvery(${interval}, ${asyncPrefix}() => {`);
1060
+ this.indent++;
1061
+ for (const stmt of node.body) this.visitStatement(stmt);
1062
+ this.indent--;
1063
+ this.emit('});');
1064
+ this.emitRaw('');
1065
+ }
1066
+
1067
+ visitWatch(node) {
1068
+ this.needsEventBus = true;
1069
+
1070
+ const params = node.params.length > 0 ? node.params.join(', ') : 'event';
1071
+ const needsAsync = this.bodyUsesAwait(node.body);
1072
+ const asyncPrefix = needsAsync ? 'async ' : '';
1073
+
1074
+ this.emit(`__eventBus.on('${node.eventName}', ${asyncPrefix}(${params}) => {`);
1075
+ this.indent++;
1076
+ for (const stmt of node.body) this.visitStatement(stmt);
1077
+ this.indent--;
1078
+ this.emit('});');
1079
+ this.emitRaw('');
1080
+ }
1081
+
1082
+ // ===== Expression generation =====
1083
+
1084
+ expr(node) {
1085
+ if (!node) return 'undefined';
1086
+
1087
+ switch (node.type) {
1088
+ case 'Number': return node.value;
1089
+ case 'String': return this.generateString(node.value);
1090
+ case 'Bool': return node.value ? 'true' : 'false';
1091
+ case 'Null': return 'null';
1092
+ case 'Self': return 'this';
1093
+ case 'Identifier': return node.name;
1094
+
1095
+ case 'Binary':
1096
+ return `(${this.expr(node.left)} ${node.op} ${this.expr(node.right)})`;
1097
+
1098
+ case 'Unary':
1099
+ return `${node.op}${this.expr(node.expr)}`;
1100
+
1101
+ case 'Await':
1102
+ return `await ${this.expr(node.expr)}`;
1103
+
1104
+ case 'AwaitAllExpr':
1105
+ return `await Promise.all(${this.expr(node.expr)})`;
1106
+
1107
+ case 'Spread':
1108
+ return `...${this.expr(node.expr)}`;
1109
+
1110
+ case 'New':
1111
+ return `new ${this.expr(node.expr)}`;
1112
+
1113
+ case 'TypeOf':
1114
+ return `typeof ${this.expr(node.expr)}`;
1115
+
1116
+ case 'MemberAccess':
1117
+ return `${this.expr(node.object)}.${node.property}`;
1118
+
1119
+ case 'OptionalAccess':
1120
+ return `${this.expr(node.object)}?.${node.property}`;
1121
+
1122
+ case 'Call':
1123
+ return this.generateCall(node);
1124
+
1125
+ case 'IndexAccess':
1126
+ return `${this.expr(node.object)}[${this.expr(node.index)}]`;
1127
+
1128
+ case 'Array':
1129
+ return `[${node.elements.map(e => this.expr(e)).join(', ')}]`;
1130
+
1131
+ case 'Object': {
1132
+ const props = node.properties.map(p => {
1133
+ if (p.type === 'spread') return `...${this.expr(p.value)}`;
1134
+ if (p.type === 'shorthand') return p.key;
1135
+ if (typeof p.key === 'string') return `${p.key}: ${this.expr(p.value)}`;
1136
+ if (p.key.type === 'String') return `${this.generateString(p.key.value)}: ${this.expr(p.value)}`;
1137
+ if (p.key.type === 'Computed') return `[${this.expr(p.key.expr)}]: ${this.expr(p.value)}`;
1138
+ return `${this.expr(p.key)}: ${this.expr(p.value)}`;
1139
+ }).join(', ');
1140
+ return `{ ${props} }`;
1141
+ }
1142
+
1143
+ case 'ArrowFn': {
1144
+ const params = node.params.map(p => p.name).join(', ');
1145
+ const body = this.expr(node.body);
1146
+ const wrappedBody = node.body.type === 'Object' ? `(${body})` : body;
1147
+ if (node.params.length === 1) return `${params} => ${wrappedBody}`;
1148
+ return `(${params}) => ${wrappedBody}`;
1149
+ }
1150
+
1151
+ case 'Lambda': {
1152
+ const async = node.isAsync ? 'async ' : '';
1153
+ const params = node.params.map(p => p.name).join(', ');
1154
+ const bodyLines = [];
1155
+ const savedOutput = this.output;
1156
+ const savedIndent = this.indent;
1157
+ this.output = bodyLines;
1158
+ this.indent = 0;
1159
+ for (const stmt of node.body) this.visitStatement(stmt);
1160
+ this.output = savedOutput;
1161
+ this.indent = savedIndent;
1162
+ return `${async}function(${params}) { ${bodyLines.join(' ')} }`;
1163
+ }
1164
+
1165
+ case 'Ternary':
1166
+ return `(${this.expr(node.condition)} ? ${this.expr(node.consequent)} : ${this.expr(node.alternate)})`;
1167
+
1168
+ case 'Pipe':
1169
+ return this.generatePipe(node);
1170
+
1171
+ default:
1172
+ return `/* expr:${node.type} */`;
1173
+ }
1174
+ }
1175
+
1176
+ generateCall(node) {
1177
+ const AUTO_IMPORT = { 'hash': 'hash', 'verify': 'verify', 'uuid': 'uuid' };
1178
+
1179
+ if (node.callee.type === 'Identifier' && AUTO_IMPORT[node.callee.name]) {
1180
+ const runtimeFn = AUTO_IMPORT[node.callee.name];
1181
+ this.runtimeImports.add(runtimeFn);
1182
+ return `${runtimeFn}(${node.args.map(a => this.expr(a)).join(', ')})`;
1183
+ }
1184
+
1185
+ if (node.callee.type === 'Identifier' && node.callee.name === 'sign') {
1186
+ this.runtimeImports.add('jwtSign');
1187
+ const args = node.args.map(a => this.expr(a));
1188
+ if (args.length === 1 && this.authSecret) {
1189
+ return `jwtSign(${args[0]}, __authSecret)`;
1190
+ }
1191
+ return `jwtSign(${args.join(', ')})`;
1192
+ }
1193
+
1194
+ if (node.callee.type === 'MemberAccess' &&
1195
+ node.callee.object.type === 'Identifier' &&
1196
+ node.callee.object.name === 'api') {
1197
+ this.runtimeImports.add('api');
1198
+ }
1199
+
1200
+ if (node.callee.type === 'MemberAccess' &&
1201
+ node.callee.object.type === 'Identifier' &&
1202
+ node.callee.object.name === 'ai') {
1203
+ this.runtimeImports.add('ai');
1204
+ }
1205
+
1206
+ if (node.callee.type === 'MemberAccess' &&
1207
+ node.callee.object.type === 'Identifier' &&
1208
+ node.callee.object.name === 'auth') {
1209
+ if (node.callee.property === 'sign') {
1210
+ this.runtimeImports.add('jwtSign');
1211
+ const args = node.args.map(a => this.expr(a));
1212
+ if (args.length === 1 && this.authSecret) {
1213
+ return `jwtSign(${args[0]}, __authSecret)`;
1214
+ }
1215
+ return `jwtSign(${args.join(', ')})`;
1216
+ }
1217
+ if (node.callee.property === 'verify') {
1218
+ this.runtimeImports.add('jwtVerify');
1219
+ return `jwtVerify(${node.args.map(a => this.expr(a)).join(', ')})`;
1220
+ }
1221
+ }
1222
+
1223
+ return `${this.expr(node.callee)}(${node.args.map(a => this.expr(a)).join(', ')})`;
1224
+ }
1225
+
1226
+ generateString(strData) {
1227
+ if (!strData || !strData.parts) return '""';
1228
+
1229
+ const hasInterpolation = strData.parts.some(p => p.type === 'expr');
1230
+
1231
+ if (!hasInterpolation) {
1232
+ const raw = strData.parts.map(p => p.value).join('');
1233
+ return JSON.stringify(raw);
1234
+ }
1235
+
1236
+ let result = '`';
1237
+ for (const part of strData.parts) {
1238
+ if (part.type === 'text') {
1239
+ result += part.value.replace(/`/g, '\\`').replace(/\$/g, '\\$');
1240
+ } else {
1241
+ const exprCode = part.value.replace(/\bself\b/g, 'this');
1242
+ result += '${' + exprCode + '}';
1243
+ }
1244
+ }
1245
+ result += '`';
1246
+ return result;
1247
+ }
1248
+
1249
+ stringValue(strData) {
1250
+ if (!strData || !strData.parts) return '""';
1251
+ if (strData.raw !== null && strData.raw !== undefined) {
1252
+ return JSON.stringify(strData.raw);
1253
+ }
1254
+ return this.generateString(strData);
1255
+ }
1256
+
1257
+ generatePipe(node) {
1258
+ const steps = [];
1259
+ let current = node;
1260
+ while (current.type === 'Pipe') {
1261
+ steps.unshift(current.right);
1262
+ current = current.left;
1263
+ }
1264
+ steps.unshift(current);
1265
+
1266
+ const ARRAY_METHODS = new Set(['filter', 'map', 'reduce', 'find', 'findIndex', 'some', 'every', 'flat', 'flatMap', 'sort', 'reverse', 'slice', 'splice', 'join', 'includes', 'indexOf', 'forEach']);
1267
+
1268
+ let result = this.expr(steps[0]);
1269
+ for (let i = 1; i < steps.length; i++) {
1270
+ const step = steps[i];
1271
+ if (step.type === 'Call' && step.callee.type === 'Identifier' && ARRAY_METHODS.has(step.callee.name)) {
1272
+ const args = step.args.map(a => this.expr(a)).join(', ');
1273
+ result = `${result}.${step.callee.name}(${args})`;
1274
+ } else if (step.type === 'Identifier' && ARRAY_METHODS.has(step.name)) {
1275
+ result = `${result}.${step.name}()`;
1276
+ } else if (step.type === 'Call') {
1277
+ const callee = this.expr(step.callee);
1278
+ const args = step.args.map(a => this.expr(a)).join(', ');
1279
+ result = `${callee}(${result}${args ? ', ' + args : ''})`;
1280
+ } else if (step.type === 'Identifier') {
1281
+ result = `${step.name}(${result})`;
1282
+ } else {
1283
+ result = `(${this.expr(step)})(${result})`;
1284
+ }
1285
+ }
1286
+ return result;
1287
+ }
1288
+
1289
+ bodyUsesAwait(body) {
1290
+ for (const stmt of body) {
1291
+ if (this.stmtUsesAwait(stmt)) return true;
1292
+ }
1293
+ return false;
1294
+ }
1295
+
1296
+ stmtUsesAwait(node) {
1297
+ if (!node) return false;
1298
+ const json = JSON.stringify(node);
1299
+ return json.includes('"Await"') || json.includes('"AwaitAll"');
1300
+ }
1301
+
1302
+ statementToString(stmt) {
1303
+ const saved = this.output;
1304
+ const savedIndent = this.indent;
1305
+ this.output = [];
1306
+ this.indent = 0;
1307
+ this.visitStatement(stmt);
1308
+ const result = this.output.join('\n');
1309
+ this.output = saved;
1310
+ this.indent = savedIndent;
1311
+ return result;
1312
+ }
1313
+ }