@greenpandastudios/aug-cli 0.19.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 (414) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +13 -0
  3. package/THIRD_PARTY_NOTICES.md +18 -0
  4. package/bin/aug.mjs +3 -0
  5. package/docs/api/crypto.md +351 -0
  6. package/docs/api/io.md +207 -0
  7. package/docs/api/json.md +21 -0
  8. package/docs/api/memory.md +109 -0
  9. package/docs/api/time.md +54 -0
  10. package/docs/api/web.md +184 -0
  11. package/docs/assets/benchmarks/execution.svg +2978 -0
  12. package/docs/assets/benchmarks/http.svg +1674 -0
  13. package/docs/assets/benchmarks/improvements.svg +2315 -0
  14. package/docs/assets/benchmarks/memory.svg +1891 -0
  15. package/docs/benchmark-baseline.json +1087 -0
  16. package/docs/benchmark-results.json +91123 -0
  17. package/docs/benchmarks.json +38 -0
  18. package/docs/compatibility.md +42 -0
  19. package/docs/concurrency-implementation.md +18 -0
  20. package/docs/diagnostics.md +97 -0
  21. package/docs/docker.md +35 -0
  22. package/docs/example-projects.json +26 -0
  23. package/docs/examples/approved-design/counters.md +253 -0
  24. package/docs/examples/approved-design/dependencies/august/0.19.0/io/contracts.md +395 -0
  25. package/docs/examples/approved-design/domain/app.md +165 -0
  26. package/docs/examples/approved-design/domain/export.md +83 -0
  27. package/docs/examples/approved-design/domain/models.md +80 -0
  28. package/docs/examples/approved-design/domain/numbers.md +248 -0
  29. package/docs/examples/approved-design/index.md +39 -0
  30. package/docs/examples/approved-design/main-yaml.md +24 -0
  31. package/docs/examples/approved-design/main.md +215 -0
  32. package/docs/examples/benchmark/index.md +33 -0
  33. package/docs/examples/benchmark/main-yaml.md +17 -0
  34. package/docs/examples/benchmark/main.md +117 -0
  35. package/docs/examples/cli-args/index.md +32 -0
  36. package/docs/examples/cli-args/main.md +107 -0
  37. package/docs/examples/collections/index.md +32 -0
  38. package/docs/examples/collections/main.md +118 -0
  39. package/docs/examples/collections-benchmark/index.md +34 -0
  40. package/docs/examples/collections-benchmark/main.md +115 -0
  41. package/docs/examples/cpu-benchmark/index.md +34 -0
  42. package/docs/examples/cpu-benchmark/main.md +90 -0
  43. package/docs/examples/developer-workflow/calculator.md +357 -0
  44. package/docs/examples/developer-workflow/dependencies/august/0.19.0/io/contracts.md +395 -0
  45. package/docs/examples/developer-workflow/index.md +37 -0
  46. package/docs/examples/developer-workflow/logging/console.md +124 -0
  47. package/docs/examples/developer-workflow/logging/export.md +70 -0
  48. package/docs/examples/developer-workflow/logging/logger.md +111 -0
  49. package/docs/examples/developer-workflow/main.md +172 -0
  50. package/docs/examples/drop/index.md +33 -0
  51. package/docs/examples/drop/main.md +85 -0
  52. package/docs/examples/drop/resource.md +95 -0
  53. package/docs/examples/errors/errors.md +85 -0
  54. package/docs/examples/errors/index.md +33 -0
  55. package/docs/examples/errors/main.md +92 -0
  56. package/docs/examples/ffi/index.md +33 -0
  57. package/docs/examples/ffi/main.md +75 -0
  58. package/docs/examples/ffi/native.md +93 -0
  59. package/docs/examples/generic-di/dependencies/august/0.19.0/io/contracts.md +395 -0
  60. package/docs/examples/generic-di/index.md +33 -0
  61. package/docs/examples/generic-di/main.md +111 -0
  62. package/docs/examples/generic-di/types.md +180 -0
  63. package/docs/examples/generics/index.md +33 -0
  64. package/docs/examples/generics/main.md +120 -0
  65. package/docs/examples/generics/types.md +189 -0
  66. package/docs/examples/hello/app/export.md +67 -0
  67. package/docs/examples/hello/app/greeter.md +190 -0
  68. package/docs/examples/hello/dependencies/august/0.19.0/io/contracts.md +395 -0
  69. package/docs/examples/hello/index.md +37 -0
  70. package/docs/examples/hello/logging/console.md +121 -0
  71. package/docs/examples/hello/logging/export.md +71 -0
  72. package/docs/examples/hello/logging/logger.md +120 -0
  73. package/docs/examples/hello/main.md +115 -0
  74. package/docs/examples/http-benchmark/index.md +35 -0
  75. package/docs/examples/http-benchmark/main.md +79 -0
  76. package/docs/examples/http-benchmark/routes.md +88 -0
  77. package/docs/examples/index.md +60 -0
  78. package/docs/examples/interceptors/app.md +250 -0
  79. package/docs/examples/interceptors/dependencies/august/0.19.0/io/contracts.md +395 -0
  80. package/docs/examples/interceptors/index.md +35 -0
  81. package/docs/examples/interceptors/interceptors.md +284 -0
  82. package/docs/examples/interceptors/logging.md +155 -0
  83. package/docs/examples/interceptors/main.md +162 -0
  84. package/docs/examples/json-benchmark/data.md +71 -0
  85. package/docs/examples/json-benchmark/dependencies/august/0.19.0/json/contracts.md +103 -0
  86. package/docs/examples/json-benchmark/index.md +35 -0
  87. package/docs/examples/json-benchmark/main.md +131 -0
  88. package/docs/examples/new-syntax/console.md +118 -0
  89. package/docs/examples/new-syntax/dependencies/august/0.19.0/io/contracts.md +395 -0
  90. package/docs/examples/new-syntax/greeter.md +145 -0
  91. package/docs/examples/new-syntax/index.md +36 -0
  92. package/docs/examples/new-syntax/logger.md +111 -0
  93. package/docs/examples/new-syntax/main.md +135 -0
  94. package/docs/examples/new-syntax/math.md +79 -0
  95. package/docs/examples/oidc-login/client/contracts.md +151 -0
  96. package/docs/examples/oidc-login/client/endpoints.md +263 -0
  97. package/docs/examples/oidc-login/client/export.md +107 -0
  98. package/docs/examples/oidc-login/client/login.md +515 -0
  99. package/docs/examples/oidc-login/client/logout.md +249 -0
  100. package/docs/examples/oidc-login/client/protocol.md +595 -0
  101. package/docs/examples/oidc-login/client/session.md +297 -0
  102. package/docs/examples/oidc-login/client/views.md +144 -0
  103. package/docs/examples/oidc-login/common/export.md +115 -0
  104. package/docs/examples/oidc-login/common/headers.md +162 -0
  105. package/docs/examples/oidc-login/common/keys.md +336 -0
  106. package/docs/examples/oidc-login/common/settings.md +116 -0
  107. package/docs/examples/oidc-login/common/views.md +103 -0
  108. package/docs/examples/oidc-login/dependencies/august/0.19.0/crypto/contracts.md +925 -0
  109. package/docs/examples/oidc-login/dependencies/august/0.19.0/crypto/jose.md +434 -0
  110. package/docs/examples/oidc-login/dependencies/august/0.19.0/json/contracts.md +103 -0
  111. package/docs/examples/oidc-login/dependencies/august/0.19.0/memory/store.md +374 -0
  112. package/docs/examples/oidc-login/dependencies/august/0.19.0/time/contracts.md +150 -0
  113. package/docs/examples/oidc-login/dependencies/august/0.19.0/web/contracts.md +532 -0
  114. package/docs/examples/oidc-login/index.md +57 -0
  115. package/docs/examples/oidc-login/main-yaml.md +28 -0
  116. package/docs/examples/oidc-login/main.md +283 -0
  117. package/docs/examples/oidc-login/provider/authorization.md +457 -0
  118. package/docs/examples/oidc-login/provider/contracts.md +267 -0
  119. package/docs/examples/oidc-login/provider/credentials.md +148 -0
  120. package/docs/examples/oidc-login/provider/discovery.md +215 -0
  121. package/docs/examples/oidc-login/provider/export.md +131 -0
  122. package/docs/examples/oidc-login/provider/token.md +364 -0
  123. package/docs/examples/oidc-login/provider/userinfo.md +228 -0
  124. package/docs/examples/oidc-login/provider/views.md +137 -0
  125. package/docs/examples/ownership/counter.md +140 -0
  126. package/docs/examples/ownership/index.md +33 -0
  127. package/docs/examples/ownership/main.md +90 -0
  128. package/docs/examples/ownership-transfer/dependencies/august/0.19.0/io/contracts.md +395 -0
  129. package/docs/examples/ownership-transfer/index.md +33 -0
  130. package/docs/examples/ownership-transfer/main.md +125 -0
  131. package/docs/examples/ownership-transfer/resource.md +150 -0
  132. package/docs/examples/packages-app/dependencies/packages/@example/aug-math/0.1.0/arithmetic.md +117 -0
  133. package/docs/examples/packages-app/index.md +34 -0
  134. package/docs/examples/packages-app/main-yaml.md +18 -0
  135. package/docs/examples/packages-app/main.md +80 -0
  136. package/docs/examples/packages-math/aug-package-json.md +24 -0
  137. package/docs/examples/packages-math/index.md +36 -0
  138. package/docs/examples/packages-math/package-json.md +25 -0
  139. package/docs/examples/packages-math/src/arithmetic.md +121 -0
  140. package/docs/examples/packages-math/src/export.md +63 -0
  141. package/docs/examples/startup-benchmark/index.md +34 -0
  142. package/docs/examples/startup-benchmark/main.md +68 -0
  143. package/docs/examples/visibility/counter.md +142 -0
  144. package/docs/examples/visibility/index.md +33 -0
  145. package/docs/examples/visibility/main.md +96 -0
  146. package/docs/examples.json +47 -0
  147. package/docs/getting-started.md +5 -0
  148. package/docs/grammar.md +136 -0
  149. package/docs/implementation-map.md +106 -0
  150. package/docs/index.md +46 -0
  151. package/docs/language-conformance.md +30 -0
  152. package/docs/language-constructs.md +1461 -0
  153. package/docs/language-design-audit.md +147 -0
  154. package/docs/maintaining-docs.md +43 -0
  155. package/docs/packages.md +184 -0
  156. package/docs/performance.md +535 -0
  157. package/docs/production-readiness.md +39 -0
  158. package/docs/reference.md +361 -0
  159. package/docs/release-review.md +23 -0
  160. package/docs/releasing.md +79 -0
  161. package/docs/roadmap.md +13 -0
  162. package/docs/specifications.md +86 -0
  163. package/docs/testing.md +120 -0
  164. package/docs/tooling.md +197 -0
  165. package/docs/web-implementation-plan.md +39 -0
  166. package/docs/web-library-gaps.md +27 -0
  167. package/docs/web.md +197 -0
  168. package/examples/approved-design/.aug-spec/august/0.19.0/io/contracts.aug +36 -0
  169. package/examples/approved-design/.aug-spec/august/0.19.0/io/contracts.aug.md +316 -0
  170. package/examples/approved-design/.aug-spec/manifest.json +14 -0
  171. package/examples/approved-design/counters.aug +22 -0
  172. package/examples/approved-design/counters.aug.md +177 -0
  173. package/examples/approved-design/domain/app.aug +12 -0
  174. package/examples/approved-design/domain/app.aug.md +97 -0
  175. package/examples/approved-design/domain/export.aug +5 -0
  176. package/examples/approved-design/domain/export.aug.md +25 -0
  177. package/examples/approved-design/domain/models.aug +2 -0
  178. package/examples/approved-design/domain/models.aug.md +30 -0
  179. package/examples/approved-design/domain/numbers.aug +29 -0
  180. package/examples/approved-design/domain/numbers.aug.md +141 -0
  181. package/examples/approved-design/main.aug +26 -0
  182. package/examples/approved-design/main.aug.md +108 -0
  183. package/examples/approved-design/main.yaml +8 -0
  184. package/examples/benchmark/.aug-spec/manifest.json +7 -0
  185. package/examples/benchmark/main.aug +17 -0
  186. package/examples/benchmark/main.aug.md +43 -0
  187. package/examples/benchmark/main.yaml +1 -0
  188. package/examples/cli-args/.aug-spec/manifest.json +7 -0
  189. package/examples/cli-args/main.aug +15 -0
  190. package/examples/cli-args/main.aug.md +38 -0
  191. package/examples/collections/.aug-spec/manifest.json +7 -0
  192. package/examples/collections/main.aug +18 -0
  193. package/examples/collections/main.aug.md +43 -0
  194. package/examples/developer-workflow/.aug-spec/august/0.19.0/io/contracts.aug +36 -0
  195. package/examples/developer-workflow/.aug-spec/august/0.19.0/io/contracts.aug.md +316 -0
  196. package/examples/developer-workflow/.aug-spec/manifest.json +13 -0
  197. package/examples/developer-workflow/calculator.aug +55 -0
  198. package/examples/developer-workflow/calculator.aug.md +228 -0
  199. package/examples/developer-workflow/logging/console.aug +8 -0
  200. package/examples/developer-workflow/logging/console.aug.md +67 -0
  201. package/examples/developer-workflow/logging/export.aug +2 -0
  202. package/examples/developer-workflow/logging/export.aug.md +19 -0
  203. package/examples/developer-workflow/logging/logger.aug +6 -0
  204. package/examples/developer-workflow/logging/logger.aug.md +57 -0
  205. package/examples/developer-workflow/main.aug +25 -0
  206. package/examples/developer-workflow/main.aug.md +79 -0
  207. package/examples/drop/.aug-spec/manifest.json +8 -0
  208. package/examples/drop/main.aug +3 -0
  209. package/examples/drop/main.aug.md +35 -0
  210. package/examples/drop/resource.aug +8 -0
  211. package/examples/drop/resource.aug.md +44 -0
  212. package/examples/errors/.aug-spec/manifest.json +8 -0
  213. package/examples/errors/errors.aug +6 -0
  214. package/examples/errors/errors.aug.md +33 -0
  215. package/examples/errors/main.aug +7 -0
  216. package/examples/errors/main.aug.md +36 -0
  217. package/examples/ffi/.aug-spec/manifest.json +8 -0
  218. package/examples/ffi/main.aug +2 -0
  219. package/examples/ffi/main.aug.md +27 -0
  220. package/examples/ffi/native.aug +6 -0
  221. package/examples/ffi/native.aug.md +43 -0
  222. package/examples/generic-di/.aug-spec/august/0.19.0/io/contracts.aug +36 -0
  223. package/examples/generic-di/.aug-spec/august/0.19.0/io/contracts.aug.md +316 -0
  224. package/examples/generic-di/.aug-spec/manifest.json +10 -0
  225. package/examples/generic-di/main.aug +9 -0
  226. package/examples/generic-di/main.aug.md +49 -0
  227. package/examples/generic-di/types.aug +17 -0
  228. package/examples/generic-di/types.aug.md +124 -0
  229. package/examples/generics/.aug-spec/manifest.json +8 -0
  230. package/examples/generics/main.aug +9 -0
  231. package/examples/generics/main.aug.md +58 -0
  232. package/examples/generics/types.aug +19 -0
  233. package/examples/generics/types.aug.md +132 -0
  234. package/examples/hello/.aug-spec/august/0.19.0/io/contracts.aug +36 -0
  235. package/examples/hello/.aug-spec/august/0.19.0/io/contracts.aug.md +316 -0
  236. package/examples/hello/.aug-spec/manifest.json +14 -0
  237. package/examples/hello/app/export.aug +1 -0
  238. package/examples/hello/app/export.aug.md +17 -0
  239. package/examples/hello/app/greeter.aug +22 -0
  240. package/examples/hello/app/greeter.aug.md +109 -0
  241. package/examples/hello/logging/console.aug +7 -0
  242. package/examples/hello/logging/console.aug.md +65 -0
  243. package/examples/hello/logging/export.aug +2 -0
  244. package/examples/hello/logging/export.aug.md +19 -0
  245. package/examples/hello/logging/logger.aug +9 -0
  246. package/examples/hello/logging/logger.aug.md +59 -0
  247. package/examples/hello/main.aug +9 -0
  248. package/examples/hello/main.aug.md +49 -0
  249. package/examples/interceptors/.aug-spec/august/0.19.0/io/contracts.aug +36 -0
  250. package/examples/interceptors/.aug-spec/august/0.19.0/io/contracts.aug.md +316 -0
  251. package/examples/interceptors/.aug-spec/manifest.json +12 -0
  252. package/examples/interceptors/app.aug +28 -0
  253. package/examples/interceptors/app.aug.md +162 -0
  254. package/examples/interceptors/interceptors.aug +40 -0
  255. package/examples/interceptors/interceptors.aug.md +180 -0
  256. package/examples/interceptors/logging.aug +12 -0
  257. package/examples/interceptors/logging.aug.md +96 -0
  258. package/examples/interceptors/main.aug +22 -0
  259. package/examples/interceptors/main.aug.md +76 -0
  260. package/examples/new-syntax/.aug-spec/august/0.19.0/io/contracts.aug +36 -0
  261. package/examples/new-syntax/.aug-spec/august/0.19.0/io/contracts.aug.md +316 -0
  262. package/examples/new-syntax/.aug-spec/manifest.json +13 -0
  263. package/examples/new-syntax/console.aug +7 -0
  264. package/examples/new-syntax/console.aug.md +63 -0
  265. package/examples/new-syntax/greeter.aug +10 -0
  266. package/examples/new-syntax/greeter.aug.md +89 -0
  267. package/examples/new-syntax/logger.aug +6 -0
  268. package/examples/new-syntax/logger.aug.md +57 -0
  269. package/examples/new-syntax/main.aug +12 -0
  270. package/examples/new-syntax/main.aug.md +64 -0
  271. package/examples/new-syntax/math.aug +3 -0
  272. package/examples/new-syntax/math.aug.md +29 -0
  273. package/examples/oidc-login/.aug-spec/august/0.19.0/crypto/contracts.aug +73 -0
  274. package/examples/oidc-login/.aug-spec/august/0.19.0/crypto/contracts.aug.md +791 -0
  275. package/examples/oidc-login/.aug-spec/august/0.19.0/crypto/jose.aug +68 -0
  276. package/examples/oidc-login/.aug-spec/august/0.19.0/crypto/jose.aug.md +266 -0
  277. package/examples/oidc-login/.aug-spec/august/0.19.0/json/contracts.aug +6 -0
  278. package/examples/oidc-login/.aug-spec/august/0.19.0/json/contracts.aug.md +55 -0
  279. package/examples/oidc-login/.aug-spec/august/0.19.0/memory/store.aug +45 -0
  280. package/examples/oidc-login/.aug-spec/august/0.19.0/memory/store.aug.md +250 -0
  281. package/examples/oidc-login/.aug-spec/august/0.19.0/time/contracts.aug +11 -0
  282. package/examples/oidc-login/.aug-spec/august/0.19.0/time/contracts.aug.md +96 -0
  283. package/examples/oidc-login/.aug-spec/august/0.19.0/web/contracts.aug +58 -0
  284. package/examples/oidc-login/.aug-spec/august/0.19.0/web/contracts.aug.md +420 -0
  285. package/examples/oidc-login/.aug-spec/manifest.json +40 -0
  286. package/examples/oidc-login/README.md +29 -0
  287. package/examples/oidc-login/client/contracts.aug +7 -0
  288. package/examples/oidc-login/client/contracts.aug.md +80 -0
  289. package/examples/oidc-login/client/endpoints.aug +21 -0
  290. package/examples/oidc-login/client/endpoints.aug.md +161 -0
  291. package/examples/oidc-login/client/export.aug +7 -0
  292. package/examples/oidc-login/client/export.aug.md +29 -0
  293. package/examples/oidc-login/client/login.aug +58 -0
  294. package/examples/oidc-login/client/login.aug.md +331 -0
  295. package/examples/oidc-login/client/logout.aug +18 -0
  296. package/examples/oidc-login/client/logout.aug.md +150 -0
  297. package/examples/oidc-login/client/protocol.aug +106 -0
  298. package/examples/oidc-login/client/protocol.aug.md +326 -0
  299. package/examples/oidc-login/client/session.aug +34 -0
  300. package/examples/oidc-login/client/session.aug.md +155 -0
  301. package/examples/oidc-login/client/views.aug +21 -0
  302. package/examples/oidc-login/client/views.aug.md +68 -0
  303. package/examples/oidc-login/common/export.aug +9 -0
  304. package/examples/oidc-login/common/export.aug.md +33 -0
  305. package/examples/oidc-login/common/headers.aug +11 -0
  306. package/examples/oidc-login/common/headers.aug.md +79 -0
  307. package/examples/oidc-login/common/keys.aug +37 -0
  308. package/examples/oidc-login/common/keys.aug.md +207 -0
  309. package/examples/oidc-login/common/settings.aug +4 -0
  310. package/examples/oidc-login/common/settings.aug.md +47 -0
  311. package/examples/oidc-login/common/views.aug +16 -0
  312. package/examples/oidc-login/common/views.aug.md +34 -0
  313. package/examples/oidc-login/main.aug +39 -0
  314. package/examples/oidc-login/main.aug.md +166 -0
  315. package/examples/oidc-login/main.yaml +12 -0
  316. package/examples/oidc-login/provider/authorization.aug +59 -0
  317. package/examples/oidc-login/provider/authorization.aug.md +264 -0
  318. package/examples/oidc-login/provider/contracts.aug +15 -0
  319. package/examples/oidc-login/provider/contracts.aug.md +193 -0
  320. package/examples/oidc-login/provider/credentials.aug +10 -0
  321. package/examples/oidc-login/provider/credentials.aug.md +64 -0
  322. package/examples/oidc-login/provider/discovery.aug +13 -0
  323. package/examples/oidc-login/provider/discovery.aug.md +133 -0
  324. package/examples/oidc-login/provider/export.aug +13 -0
  325. package/examples/oidc-login/provider/export.aug.md +41 -0
  326. package/examples/oidc-login/provider/token.aug +37 -0
  327. package/examples/oidc-login/provider/token.aug.md +223 -0
  328. package/examples/oidc-login/provider/userinfo.aug +26 -0
  329. package/examples/oidc-login/provider/userinfo.aug.md +104 -0
  330. package/examples/oidc-login/provider/views.aug +18 -0
  331. package/examples/oidc-login/provider/views.aug.md +63 -0
  332. package/examples/ownership/.aug-spec/manifest.json +8 -0
  333. package/examples/ownership/counter.aug +14 -0
  334. package/examples/ownership/counter.aug.md +85 -0
  335. package/examples/ownership/main.aug +4 -0
  336. package/examples/ownership/main.aug.md +38 -0
  337. package/examples/ownership-transfer/.aug-spec/august/0.19.0/io/contracts.aug +36 -0
  338. package/examples/ownership-transfer/.aug-spec/august/0.19.0/io/contracts.aug.md +316 -0
  339. package/examples/ownership-transfer/.aug-spec/manifest.json +10 -0
  340. package/examples/ownership-transfer/main.aug +9 -0
  341. package/examples/ownership-transfer/main.aug.md +63 -0
  342. package/examples/ownership-transfer/resource.aug +16 -0
  343. package/examples/ownership-transfer/resource.aug.md +89 -0
  344. package/examples/packages/README.md +15 -0
  345. package/examples/packages/app/.aug-spec/manifest.json +9 -0
  346. package/examples/packages/app/.aug-spec/packages/@example/aug-math/0.1.0/arithmetic.aug +9 -0
  347. package/examples/packages/app/.aug-spec/packages/@example/aug-math/0.1.0/arithmetic.aug.md +63 -0
  348. package/examples/packages/app/main.aug +2 -0
  349. package/examples/packages/app/main.aug.md +33 -0
  350. package/examples/packages/app/main.yaml +2 -0
  351. package/examples/packages/math/.aug-spec/manifest.json +8 -0
  352. package/examples/packages/math/README.md +3 -0
  353. package/examples/packages/math/aug-package.json +8 -0
  354. package/examples/packages/math/package.json +9 -0
  355. package/examples/packages/math/src/arithmetic.aug +8 -0
  356. package/examples/packages/math/src/arithmetic.aug.md +63 -0
  357. package/examples/packages/math/src/export.aug +1 -0
  358. package/examples/packages/math/src/export.aug.md +17 -0
  359. package/examples/visibility/.aug-spec/manifest.json +8 -0
  360. package/examples/visibility/counter.aug +14 -0
  361. package/examples/visibility/counter.aug.md +87 -0
  362. package/examples/visibility/main.aug +7 -0
  363. package/examples/visibility/main.aug.md +39 -0
  364. package/package.json +50 -0
  365. package/runtime/aug_crypto.c +121 -0
  366. package/runtime/aug_html.c +93 -0
  367. package/runtime/aug_http.c +829 -0
  368. package/runtime/aug_json.c +165 -0
  369. package/runtime/aug_runtime.c +792 -0
  370. package/runtime/aug_runtime.h +245 -0
  371. package/runtime/aug_tasks.c +172 -0
  372. package/runtime/aug_time.c +5 -0
  373. package/runtime/aug_values.c +80 -0
  374. package/scripts/bootstrap-native.mjs +121 -0
  375. package/scripts/native-dependencies.lock.json +65 -0
  376. package/scripts/native-home.mjs +11 -0
  377. package/src/actions.js +109 -0
  378. package/src/ast.js +19 -0
  379. package/src/builtins.js +93 -0
  380. package/src/checker.js +2896 -0
  381. package/src/cli.js +344 -0
  382. package/src/codegen.js +1159 -0
  383. package/src/config.js +149 -0
  384. package/src/continuation.js +110 -0
  385. package/src/di.js +24 -0
  386. package/src/documentation.js +27 -0
  387. package/src/editor.js +782 -0
  388. package/src/effects.js +29 -0
  389. package/src/fixes.js +222 -0
  390. package/src/formatter.js +296 -0
  391. package/src/freshness.js +154 -0
  392. package/src/help.js +212 -0
  393. package/src/html.js +27 -0
  394. package/src/http-policies.js +90 -0
  395. package/src/inference.js +16 -0
  396. package/src/interceptors.js +70 -0
  397. package/src/javadoc.js +67 -0
  398. package/src/lexer.js +199 -0
  399. package/src/libraries.js +31 -0
  400. package/src/lsp.js +180 -0
  401. package/src/native.js +144 -0
  402. package/src/navigation.js +162 -0
  403. package/src/openapi.js +220 -0
  404. package/src/ownership.js +232 -0
  405. package/src/package-manager.js +299 -0
  406. package/src/parser.js +1155 -0
  407. package/src/policies.js +130 -0
  408. package/src/project-init.js +19 -0
  409. package/src/project.js +292 -0
  410. package/src/schemas.js +62 -0
  411. package/src/semantic.js +255 -0
  412. package/src/spec.js +738 -0
  413. package/src/testing.js +186 -0
  414. package/src/types.js +10 -0
@@ -0,0 +1,232 @@
1
+ export const unionOrigins = (...sets) => new Set(sets.flatMap(set => [...set]));
2
+ export const overlap = (left, right) => [...left].some(origin => right.has(origin));
3
+ export const allocationOrigin = (span) => new Set([`new:${span.file}:${span.start}`]);
4
+ /** Stable object origins survive rebinding; loans and branch joins stay private. */
5
+ export class OwnershipFlow {
6
+ places = new Map();
7
+ loans = new Map();
8
+ borrowedInputs = new Set();
9
+ heap = new Map();
10
+ regions = [];
11
+ frozenOrigins = new Set();
12
+ taskLoans = new Map();
13
+ tasks = new Map();
14
+ clone() {
15
+ const copy = new OwnershipFlow();
16
+ copy.places = new Map([...this.places].map(([name, place]) => [name, { ...place }]));
17
+ copy.loans = new Map(this.loans);
18
+ copy.borrowedInputs = new Set(this.borrowedInputs);
19
+ copy.heap = new Map([...this.heap].map(([origin, fields]) => [origin, new Map(fields)]));
20
+ copy.regions = [...this.regions];
21
+ copy.frozenOrigins = new Set(this.frozenOrigins);
22
+ copy.taskLoans = new Map(this.taskLoans);
23
+ copy.tasks = new Map(this.tasks);
24
+ return copy;
25
+ }
26
+ origins(name) { return this.places.get(name)?.origins ?? new Set(); }
27
+ frozen(origins) { return overlap(origins, this.frozenOrigins); }
28
+ freeze(origins, span, report) {
29
+ const reachable = this.reachable(origins);
30
+ if ([...this.loans.values()].some(loan => overlap(loan.origins, reachable)))
31
+ report(span, 'Cannot freeze an active mutable borrow');
32
+ for (const origin of reachable)
33
+ this.frozenOrigins.add(origin);
34
+ for (const place of this.places.values())
35
+ if (overlap(this.reachable(place.origins), reachable))
36
+ place.readonly = true;
37
+ }
38
+ external(name) { return this.places.get(name)?.external; }
39
+ region(origins) { this.regions.push({ origins, outerNames: new Set(this.places.keys()) }); }
40
+ captureTask(task, scope, origins, exclusive, repeated, span, report) {
41
+ const reachable = this.reachable(origins);
42
+ for (const loan of this.taskLoans.values())
43
+ if ((exclusive || loan.exclusive) && overlap(reachable, loan.origins))
44
+ report(span, 'Task captures overlap an active task with mutable access');
45
+ const previous = this.taskLoans.get(task);
46
+ this.taskLoans.set(task, { scope, origins: unionOrigins(previous?.origins ?? new Set(), reachable),
47
+ exclusive: exclusive || !!previous?.exclusive, repeated: repeated || !!previous?.repeated });
48
+ }
49
+ waitTasks(origins, all) {
50
+ const reachable = this.reachable(origins);
51
+ const matches = [...this.tasks.keys()].filter(task => reachable.has(task));
52
+ // A Task<T> read from an indexed collection or branch may have several
53
+ // possible origins. Only a List<Task<T>> wait joins every matching child.
54
+ if (!all && matches.length !== 1)
55
+ return;
56
+ // A static start site in a loop can represent several live children. Waiting for
57
+ // one result cannot prove that earlier children from that site have finished.
58
+ for (const task of matches) {
59
+ if (!this.taskLoans.get(task)?.repeated)
60
+ this.taskLoans.delete(task);
61
+ const value = this.tasks.get(task);
62
+ this.tasks.set(task, { ...value, observed: true });
63
+ }
64
+ }
65
+ registerTask(task, scope, errors) {
66
+ this.tasks.set(task, { scope, errors, observed: false });
67
+ }
68
+ taskErrors(origins) {
69
+ const found = [...this.reachable(origins)].flatMap(origin => this.tasks.has(origin) ? [this.tasks.get(origin)] : []);
70
+ const scopes = new Set(found.map(task => task.scope));
71
+ return found.length ? [...found, ...[...this.tasks.values()].filter(task => !task.observed && scopes.has(task.scope))].flatMap(task => task.errors) : undefined;
72
+ }
73
+ hasTaskCapture(origins) {
74
+ const reachable = this.reachable(origins);
75
+ return [...this.taskLoans.values()].some(loan => overlap(loan.origins, reachable));
76
+ }
77
+ pendingTaskErrors(scope) {
78
+ return [...this.tasks.values()].filter(task => !task.observed && (!scope || task.scope === scope)).flatMap(task => task.errors);
79
+ }
80
+ joinTasks(scope) {
81
+ for (const [task, loan] of this.taskLoans)
82
+ if (loan.scope === scope)
83
+ this.taskLoans.delete(task);
84
+ for (const [task, value] of this.tasks)
85
+ if (value.scope === scope)
86
+ this.tasks.delete(task);
87
+ }
88
+ object(origins, fields) {
89
+ for (const origin of origins) {
90
+ const stored = this.heap.get(origin) ?? new Map();
91
+ for (const field of fields)
92
+ stored.set(field.name, { origins: unionOrigins(stored.get(field.name)?.origins ?? new Set(), field.origins),
93
+ mutable: field.mutable || !!stored.get(field.name)?.mutable });
94
+ this.heap.set(origin, stored);
95
+ }
96
+ }
97
+ field(origins, name) {
98
+ return unionOrigins(...[...origins].map(origin => {
99
+ const fields = this.heap.get(origin);
100
+ if (!fields)
101
+ return new Set([origin]);
102
+ return name === undefined ? unionOrigins(...[...fields.values()].map(field => field.origins)) : fields.get(name)?.origins ?? new Set([origin]);
103
+ }));
104
+ }
105
+ reachable(origins, mutableOnly = false) {
106
+ const output = new Set(origins);
107
+ for (const origin of output)
108
+ for (const field of this.heap.get(origin)?.values() ?? [])
109
+ if (!mutableOnly || field.mutable)
110
+ for (const child of field.origins)
111
+ output.add(child);
112
+ return output;
113
+ }
114
+ declare(name, origins, readonly, options = {}) {
115
+ const source = options.source ? this.places.get(options.source) : undefined;
116
+ const grant = options.source ? this.activeGrant(options.source) : undefined;
117
+ this.places.set(name, { origins, readonly: readonly || !!source?.readonly || this.frozen(origins),
118
+ parent: options.parent, grant, external: options.external ?? source?.external });
119
+ if (options.borrowedInput)
120
+ for (const origin of origins)
121
+ this.borrowedInputs.add(origin);
122
+ }
123
+ rebind(name, origins, readonly, span, report, source) {
124
+ const place = this.places.get(name);
125
+ if (place && !place.parent && [...this.loans.values()].some(loan => overlap(loan.origins, this.reachable(place.origins, true))))
126
+ report(span, `Cannot rebind ${name} while its object is borrowed`);
127
+ if ([...this.loans.values()].some(loan => loan.outerNames.has(name) && overlap(loan.origins, this.reachable(origins))))
128
+ report(span, `A borrowed reference cannot escape into outer variable ${name}`);
129
+ if (this.regions.some(region => region.outerNames.has(name) && overlap(region.origins, this.reachable(origins))))
130
+ report(span, `A scoped reference cannot escape into outer variable ${name}`);
131
+ this.declare(name, origins, readonly, { source, external: place?.parent ? place.external : undefined, parent: place?.parent });
132
+ }
133
+ read(name, span, report) {
134
+ const place = this.places.get(name);
135
+ if (!place)
136
+ return;
137
+ if (![...place.origins].some(origin => this.taskLoans.has(origin)) &&
138
+ [...this.taskLoans.values()].some(loan => loan.exclusive && overlap(loan.origins, this.reachable(place.origins))))
139
+ report(span, `Cannot read ${name} while a task has mutable access; wait for the task first`);
140
+ for (const [borrower, loan] of this.loans) {
141
+ if (overlap(loan.origins, this.reachable(place.origins)) && name !== borrower && place.grant !== borrower && place.parent !== borrower)
142
+ report(span, `Cannot read ${name} while alias ${borrower} is mutably borrowed`);
143
+ }
144
+ }
145
+ borrow(name, span, report, implicit = false) {
146
+ const place = this.places.get(name);
147
+ if (!place)
148
+ return;
149
+ if (place.readonly)
150
+ report(span, `Cannot mutably borrow read-only ${name}`);
151
+ const reachable = this.reachable(place.origins, true);
152
+ if ([...this.taskLoans.values()].some(loan => overlap(loan.origins, reachable)))
153
+ report(span, `Cannot borrow ${name} while a task uses it; wait for the task first`);
154
+ for (const [other, loan] of this.loans)
155
+ if (overlap(loan.origins, reachable) &&
156
+ !(loan.implicit && (other === name || place.parent === other || place.grant === other)))
157
+ report(span, `${name} aliases active exclusive borrow ${other}`);
158
+ this.loans.set(name, { origins: reachable, implicit, outerNames: new Set(this.places.keys()) });
159
+ }
160
+ activeGrant(name) {
161
+ const place = this.places.get(name);
162
+ if (this.loans.has(name))
163
+ return name;
164
+ if (place?.grant && this.loans.has(place.grant))
165
+ return place.grant;
166
+ if (place?.parent && this.loans.has(place.parent))
167
+ return place.parent;
168
+ return undefined;
169
+ }
170
+ assertMove(name, span, report) {
171
+ const place = this.places.get(name);
172
+ if (place && [...this.loans.values()].some(loan => overlap(loan.origins, this.reachable(place.origins, true))))
173
+ report(span, `Cannot move ${name} while it is borrowed`);
174
+ if (place && this.hasTaskCapture(place.origins))
175
+ report(span, `Cannot move ${name} while a task uses it; wait for the task first`);
176
+ }
177
+ escape(origins, span, report, scoped = true, immutable = false) {
178
+ if (immutable)
179
+ return;
180
+ const reachable = this.reachable(origins);
181
+ if ([...reachable].some(origin => this.borrowedInputs.has(origin)) ||
182
+ [...this.loans.values()].some(loan => overlap(loan.origins, reachable)))
183
+ report(span, 'A borrowed reference cannot escape into storage or a return value');
184
+ if (scoped && this.regions.some(region => overlap(region.origins, reachable)))
185
+ report(span, 'A scoped reference cannot escape its composition scope');
186
+ }
187
+ assertDistinct(arguments_, report) {
188
+ arguments_.forEach((argument, index) => {
189
+ for (const other of arguments_.slice(0, index))
190
+ if ((argument.exclusive || other.exclusive) &&
191
+ overlap(this.reachable(argument.origins, argument.exclusive), this.reachable(other.origins, other.exclusive)))
192
+ report(argument.span, 'An exclusive argument aliases another argument in this call');
193
+ });
194
+ }
195
+ join(branches) {
196
+ this.taskLoans = new Map(branches.flatMap(branch => [...branch.taskLoans]));
197
+ this.tasks = new Map([...new Set(branches.flatMap(branch => [...branch.tasks.keys()]))].map(task => {
198
+ const values = branches.flatMap(branch => branch.tasks.has(task) ? [branch.tasks.get(task)] : []);
199
+ return [task, { ...values[0], errors: values.flatMap(value => value.errors), observed: values.every(value => value.observed) }];
200
+ }));
201
+ for (const branch of branches)
202
+ for (const origin of branch.frozenOrigins)
203
+ this.frozenOrigins.add(origin);
204
+ for (const branch of branches)
205
+ for (const [origin, fields] of branch.heap) {
206
+ const current = this.heap.get(origin) ?? new Map();
207
+ for (const [name, field] of fields)
208
+ current.set(name, {
209
+ origins: unionOrigins(current.get(name)?.origins ?? new Set(), field.origins),
210
+ mutable: field.mutable || !!current.get(name)?.mutable,
211
+ });
212
+ this.heap.set(origin, current);
213
+ }
214
+ for (const [name, place] of this.places) {
215
+ const versions = branches.map(branch => branch.places.get(name)).filter((value) => !!value);
216
+ place.origins = unionOrigins(place.origins, ...versions.map(value => value.origins));
217
+ place.readonly ||= versions.some(value => value.readonly);
218
+ if (versions.some(value => value.external !== place.external))
219
+ place.external = undefined;
220
+ }
221
+ }
222
+ signature() {
223
+ return JSON.stringify({ places: [...this.places].map(([name, place]) => [name, [...place.origins].sort(), place.readonly, place.external]),
224
+ tasks: [...this.tasks].map(([task, value]) => [task, value.observed]),
225
+ heap: [...this.heap].map(([origin, fields]) => [origin, [...fields].map(([name, field]) => [name, [...field.origins].sort(), field.mutable])]) });
226
+ }
227
+ }
228
+ export function sourceName(expression) {
229
+ if (expression.kind === 'call' && expression.callee.kind === 'member')
230
+ return sourceName(expression.callee.object);
231
+ return expression.kind === 'name' ? expression.name : expression.kind === 'member' ? sourceName(expression.object) : undefined;
232
+ }
@@ -0,0 +1,299 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, writeFileSync } from 'node:fs';
3
+ import { basename, dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
4
+ import { spawnSync } from 'node:child_process';
5
+ import { loadConfig } from "./config.js";
6
+ export const compilerVersion = () => JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version;
7
+ export const packageAlias = (name) => /^[a-z][a-z0-9_]*$/.test(name) && name !== 'august';
8
+ const version = /^\d+\.\d+\.\d+(?:-[A-Za-z0-9.-]+)?$/;
9
+ const npmName = /^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/;
10
+ const json = (file) => JSON.parse(readFileSync(file, 'utf8'));
11
+ const writeJson = (file, data) => writeFileSync(file, JSON.stringify(data, null, 2) + '\n');
12
+ const inside = (root, file) => file === root || file.startsWith(root + sep);
13
+ const ordered = (values) => Object.fromEntries(Object.entries(values).sort(([a], [b]) => a.localeCompare(b)));
14
+ const sameSpecifications = (left, right) => JSON.stringify(ordered(left)) === JSON.stringify(ordered(right));
15
+ function verifyReference(spec, target) {
16
+ if (spec.startsWith('npm:') && spec !== `npm:${target.name}@${target.version}`)
17
+ throw new Error(`Package lock resolves ${spec} to incompatible ${target.name}@${target.version}`);
18
+ }
19
+ function verifyIdentities(packages) {
20
+ const entries = [...packages], paths = new Map(entries.map(entry => [entry.path, entry]));
21
+ const identities = new Map();
22
+ for (const entry of entries) {
23
+ const dependencies = Object.entries(entry.dependencies).sort(([a], [b]) => a.localeCompare(b)).map(([alias, path]) => {
24
+ const target = paths.get(path);
25
+ if (!target)
26
+ throw new Error('Package lock is missing a transitive dependency');
27
+ return [alias, `${target.name}@${target.version}`, target.digest];
28
+ });
29
+ const key = `${entry.name}@${entry.version}`, fingerprint = JSON.stringify([entry.digest, dependencies]);
30
+ if (identities.has(key) && identities.get(key) !== fingerprint)
31
+ throw new Error(`Conflicting contents or dependencies for ${key}; publish a new version for changed source`);
32
+ identities.set(key, fingerprint);
33
+ }
34
+ }
35
+ export function sourcePaths(root) {
36
+ const result = [];
37
+ for (const entry of readdirSync(root, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
38
+ if (entry.name.startsWith('.') || ['node_modules', 'dist'].includes(entry.name))
39
+ continue;
40
+ const file = join(root, entry.name);
41
+ if (entry.isSymbolicLink())
42
+ throw new Error(`Package source cannot contain a symlink: ${file}`);
43
+ if (entry.isDirectory())
44
+ result.push(...sourcePaths(file));
45
+ else if (entry.isFile() && entry.name.endsWith('.aug'))
46
+ result.push(file);
47
+ }
48
+ return result;
49
+ }
50
+ export function readPackage(directory) {
51
+ const manifest = json(join(directory, 'aug-package.json'));
52
+ if (manifest.format !== 1 || !npmName.test(manifest.name ?? '') || !version.test(manifest.version ?? '') ||
53
+ manifest.compiler !== compilerVersion())
54
+ throw new Error(`Invalid August package or compiler mismatch in ${directory}; expected compiler ${compilerVersion()}`);
55
+ if (typeof manifest.source !== 'string' || !manifest.source || isAbsolute(manifest.source))
56
+ throw new Error('Package source must be a relative folder');
57
+ const sourceRoot = realpathSync(resolve(directory, manifest.source));
58
+ if (!inside(realpathSync(directory), sourceRoot))
59
+ throw new Error('Package source cannot escape its package directory');
60
+ if (!existsSync(join(sourceRoot, 'export.aug')))
61
+ throw new Error(`${manifest.name} requires export.aug in its source folder`);
62
+ for (const [alias, spec] of Object.entries(manifest.dependencies ?? {})) {
63
+ if (!packageAlias(alias) || typeof spec !== 'string')
64
+ throw new Error(`Invalid package dependency ${alias}`);
65
+ normalizeSpecifier(spec, directory, false);
66
+ }
67
+ const published = json(join(directory, 'package.json'));
68
+ if (published.name !== manifest.name || published.version !== manifest.version)
69
+ throw new Error('package.json and aug-package.json names/versions must match');
70
+ const declared = manifest.dependencies ?? {}, actual = published.dependencies ?? {};
71
+ if (Object.keys(actual).length !== Object.keys(declared).length || Object.entries(declared).some(([alias, spec]) => actual[alias] !== spec))
72
+ throw new Error('package.json dependencies must match the August dependency aliases; aug package pack synchronizes them');
73
+ for (const alias of Object.keys(declared))
74
+ assertAlias(sourceRoot, alias);
75
+ return { manifest, sourceRoot };
76
+ }
77
+ function assertAlias(root, alias) {
78
+ if (!packageAlias(alias))
79
+ throw new Error(`Package alias ${alias} must be lowercase and cannot be august or private`);
80
+ if (existsSync(join(root, alias)) || existsSync(join(root, alias + '.aug')))
81
+ throw new Error(`Package alias ${alias} conflicts with a local module`);
82
+ }
83
+ function normalizeSpecifier(spec, root, requirePath = true) {
84
+ if (spec.startsWith('npm:')) {
85
+ const match = /^npm:((?:@[^/]+\/)?[^@]+)@(.+)$/.exec(spec);
86
+ if (!match || !npmName.test(match[1]) || !version.test(match[2]))
87
+ throw new Error(`Use an exact registry version: npm:@owner/package@1.2.3 (${spec})`);
88
+ return spec;
89
+ }
90
+ const path = spec.startsWith('file:') ? spec.slice(5) : spec;
91
+ if (!path.startsWith('.') && !isAbsolute(path))
92
+ throw new Error(`Use a local path or npm:name@version: ${spec}`);
93
+ const absolute = resolve(root, path);
94
+ if (!requirePath)
95
+ return 'file:' + absolute;
96
+ if (!existsSync(absolute))
97
+ throw new Error(`Package path does not exist: ${path}`);
98
+ if (!lstatSync(absolute).isDirectory() && !absolute.endsWith('.tgz'))
99
+ throw new Error('Local packages must be folders or .tgz archives');
100
+ return 'file:' + realpathSync(absolute);
101
+ }
102
+ function packageDigest(directory, sourceRoot) {
103
+ const hash = createHash('sha256');
104
+ for (const file of [join(directory, 'aug-package.json'), join(directory, 'package.json'), ...sourcePaths(sourceRoot)].sort()) {
105
+ hash.update(relative(directory, file).replaceAll('\\', '/'));
106
+ hash.update('\0');
107
+ hash.update(readFileSync(file));
108
+ hash.update('\0');
109
+ }
110
+ return hash.digest('hex');
111
+ }
112
+ /** Compilation reads only a verified installed snapshot. It never fetches dependencies. */
113
+ export function projectPackages(root, specifications, sourceFolder = root) {
114
+ const result = { roots: new Map(), scopes: new Map(), diagnostics: [] };
115
+ if (!Object.keys(specifications).length)
116
+ return result;
117
+ try {
118
+ const lock = json(join(root, 'aug.lock.json'));
119
+ if (lock.format !== 1 || lock.compiler !== compilerVersion() || !sameSpecifications(lock.specifications, specifications))
120
+ throw new Error('Package lock does not match this project/compiler; run aug install');
121
+ const cache = realpathSync(join(root, '.aug-packages'));
122
+ const manifests = new Map();
123
+ for (const entry of lock.packages) {
124
+ if (isAbsolute(entry.path))
125
+ throw new Error('Invalid absolute package lock path');
126
+ const directory = realpathSync(resolve(cache, entry.path));
127
+ if (!inside(cache, directory))
128
+ throw new Error('Package lock path escapes the installed snapshot');
129
+ const { manifest, sourceRoot } = readPackage(directory);
130
+ if (manifest.name !== entry.name || manifest.version !== entry.version || manifest.source !== entry.source ||
131
+ packageDigest(directory, sourceRoot) !== entry.digest)
132
+ throw new Error(`Installed ${entry.name} changed; run aug install`);
133
+ if (result.scopes.has(entry.path))
134
+ throw new Error('Duplicate package lock path');
135
+ manifests.set(entry.path, manifest);
136
+ result.scopes.set(entry.path, { ...entry, directory, sourceRoot });
137
+ }
138
+ verifyIdentities(lock.packages);
139
+ for (const scope of result.scopes.values()) {
140
+ const declared = manifests.get(scope.path).dependencies ?? {};
141
+ if (!sameSpecifications(Object.fromEntries(Object.keys(declared).map(alias => [alias, ''])), Object.fromEntries(Object.keys(scope.dependencies).map(alias => [alias, '']))))
142
+ throw new Error('Package lock dependency aliases changed');
143
+ for (const [alias, path] of Object.entries(scope.dependencies))
144
+ verifyReference(declared[alias], result.scopes.get(path));
145
+ }
146
+ // One package identity has one set of declarations, even when npm installs duplicate copies.
147
+ const canonical = new Map();
148
+ for (const [path, scope] of result.scopes) {
149
+ const identity = `${scope.name}@${scope.version}`;
150
+ if (canonical.has(identity))
151
+ result.scopes.set(path, canonical.get(identity));
152
+ else
153
+ canonical.set(identity, scope);
154
+ }
155
+ for (const [alias, path] of Object.entries(lock.roots)) {
156
+ assertAlias(sourceFolder, alias);
157
+ if (!(alias in specifications))
158
+ throw new Error('Package lock contains an undeclared root dependency');
159
+ const scope = result.scopes.get(path);
160
+ if (!scope)
161
+ throw new Error(`Missing package ${alias}`);
162
+ verifyReference(specifications[alias], scope);
163
+ result.roots.set(alias, scope);
164
+ }
165
+ if (Object.keys(specifications).some(alias => !result.roots.has(alias)))
166
+ throw new Error('Package lock is missing a requested dependency');
167
+ for (const scope of result.scopes.values())
168
+ for (const path of Object.values(scope.dependencies))
169
+ if (!result.scopes.has(path))
170
+ throw new Error('Package lock is missing a transitive dependency');
171
+ }
172
+ catch (error) {
173
+ result.roots.clear();
174
+ result.scopes.clear();
175
+ result.diagnostics.push({ file: join(root, 'main.yaml'), line: 1, column: 1, code: 'PACKAGE',
176
+ message: `${error.message}. Install dependencies with aug install ${root}` });
177
+ }
178
+ return result;
179
+ }
180
+ function npm(args, cwd) {
181
+ const process = spawnSync('npm', args, { cwd, encoding: 'utf8', timeout: 120000 });
182
+ if (process.error || process.status !== 0)
183
+ throw new Error(process.error?.message ?? process.stderr ?? 'npm failed');
184
+ return process.stdout;
185
+ }
186
+ export function installPackages(root, frozen = false, offline = false) {
187
+ const loaded = loadConfig(root);
188
+ if (loaded.diagnostics.length)
189
+ throw new Error(loaded.diagnostics.map(issue => issue.message).join('\n'));
190
+ const library = existsSync(join(root, 'aug-package.json')) ? json(join(root, 'aug-package.json')) : undefined;
191
+ if (library)
192
+ preparePackage(root);
193
+ const specifications = ordered(library?.dependencies ?? loaded.config.packages);
194
+ for (const alias of Object.keys(specifications))
195
+ assertAlias(library ? resolve(root, library.source) : root, alias);
196
+ const lockPath = join(root, 'aug.lock.json');
197
+ const previous = existsSync(lockPath) ? json(lockPath) : undefined;
198
+ const same = previous?.compiler === compilerVersion() && sameSpecifications(previous.specifications, specifications);
199
+ if (frozen && !same)
200
+ throw new Error('Frozen installation requires a matching aug.lock.json');
201
+ const stage = realpathSync(mkdtempSync(join(root, '.aug-install-')));
202
+ try {
203
+ const dependencies = Object.fromEntries(Object.entries(specifications).map(([alias, spec]) => {
204
+ const normalized = normalizeSpecifier(spec, root);
205
+ return [alias, normalized.startsWith('file:') ? 'file:' + relative(stage, normalized.slice(5)).replaceAll('\\', '/') : normalized];
206
+ }));
207
+ writeJson(join(stage, 'package.json'), { name: 'august-project-dependencies', version: '0.0.0', private: true, dependencies });
208
+ if (same && previous?.npm)
209
+ writeJson(join(stage, 'package-lock.json'), previous.npm);
210
+ npm([frozen ? 'ci' : 'install', '--ignore-scripts', '--install-links', '--bin-links=false', '--no-audit', '--no-fund',
211
+ ...(offline ? ['--offline'] : [])], stage);
212
+ const packages = new Map();
213
+ const visit = (directory) => {
214
+ const actual = realpathSync(directory);
215
+ if (!inside(stage, actual))
216
+ throw new Error('Package installer did not create a self-contained snapshot');
217
+ const path = relative(stage, actual).replaceAll('\\', '/');
218
+ if (packages.has(path))
219
+ return path;
220
+ const { manifest, sourceRoot } = readPackage(actual);
221
+ const entry = { path, name: manifest.name, version: manifest.version, source: manifest.source,
222
+ digest: packageDigest(actual, sourceRoot), dependencies: {} };
223
+ packages.set(path, entry);
224
+ for (const alias of Object.keys(manifest.dependencies ?? {})) {
225
+ let owner = actual;
226
+ while (inside(stage, owner) && !existsSync(join(owner, 'node_modules', alias, 'aug-package.json')))
227
+ owner = dirname(owner);
228
+ if (!inside(stage, owner))
229
+ throw new Error(`${manifest.name} is missing dependency ${alias}`);
230
+ entry.dependencies[alias] = visit(join(owner, 'node_modules', alias));
231
+ verifyReference(manifest.dependencies[alias], packages.get(entry.dependencies[alias]));
232
+ }
233
+ return path;
234
+ };
235
+ const roots = Object.fromEntries(Object.keys(specifications).map(alias => [alias, visit(join(stage, 'node_modules', alias))]));
236
+ const lock = { format: 1, compiler: compilerVersion(), specifications, roots,
237
+ packages: [...packages.values()].sort((a, b) => a.path.localeCompare(b.path)), npm: json(join(stage, 'package-lock.json')) };
238
+ verifyIdentities(lock.packages);
239
+ for (const [alias, path] of Object.entries(roots))
240
+ verifyReference(specifications[alias], packages.get(path));
241
+ if (frozen && JSON.stringify(lock.packages) !== JSON.stringify(previous.packages))
242
+ throw new Error('Frozen package contents changed; update the lock explicitly with aug install');
243
+ const cache = join(root, '.aug-packages'), backup = join(root, '.aug-packages-old');
244
+ if (existsSync(backup))
245
+ throw new Error('Previous package install backup exists; inspect .aug-packages-old before installing');
246
+ if (existsSync(cache))
247
+ renameSync(cache, backup);
248
+ try {
249
+ renameSync(stage, cache);
250
+ writeJson(lockPath + '.tmp', lock);
251
+ renameSync(lockPath + '.tmp', lockPath);
252
+ }
253
+ catch (error) {
254
+ rmSync(cache, { recursive: true, force: true });
255
+ if (existsSync(backup))
256
+ renameSync(backup, cache);
257
+ throw error;
258
+ }
259
+ rmSync(backup, { recursive: true, force: true });
260
+ return lock;
261
+ }
262
+ finally {
263
+ rmSync(stage, { recursive: true, force: true });
264
+ }
265
+ }
266
+ export function initPackage(directory, name) {
267
+ if (!npmName.test(name))
268
+ throw new Error('Package name must be an npm name, for example @owner/aug-math');
269
+ if (existsSync(directory) && readdirSync(directory).length)
270
+ throw new Error('Package init requires a new or empty directory');
271
+ mkdirSync(join(directory, 'src'), { recursive: true });
272
+ const manifest = { format: 1, name, version: '0.1.0', compiler: compilerVersion(), source: 'src', dependencies: {} };
273
+ writeJson(join(directory, 'aug-package.json'), manifest);
274
+ writeJson(join(directory, 'package.json'), { name, version: manifest.version, description: 'An August source library',
275
+ files: ['src', '.aug-spec', 'aug-package.json', 'README.md', 'LICENSE'], exports: { './aug-package.json': './aug-package.json' }, dependencies: {} });
276
+ writeFileSync(join(directory, 'src/export.aug'), 'export add from arithmetic\n');
277
+ writeFileSync(join(directory, 'src/arithmetic.aug'), '/** Add two integers. @param left First value. @param right Second value. @return Their sum. */\nadd(int left, int right) returns int {\n return left + right\n}\n\ntest add {\n when addition {\n it adds_two_integers {\n assert(add(left=2, right=3) == 5)\n }\n }\n}\n');
278
+ writeFileSync(join(directory, 'README.md'), `# ${name}\n\nAugust ${compilerVersion()} source library. Public exports live in src/export.aug.\n`);
279
+ writeFileSync(join(directory, '.gitignore'), '.aug-build/\n.aug-packages/\n.aug-install-*/\nnode_modules/\n*.tgz\n');
280
+ }
281
+ /** Synchronize transport metadata; August's manifest owns dependency aliases. */
282
+ export function preparePackage(root) {
283
+ const manifest = json(join(root, 'aug-package.json'));
284
+ const transport = json(join(root, 'package.json'));
285
+ transport.name = manifest.name;
286
+ transport.version = manifest.version;
287
+ transport.dependencies = manifest.dependencies ?? {};
288
+ transport.files = [...new Set([...(Array.isArray(transport.files) ? transport.files : ['README.md', 'LICENSE']), manifest.source, '.aug-spec', 'aug-package.json'])];
289
+ writeJson(join(root, 'package.json'), transport);
290
+ readPackage(root);
291
+ }
292
+ export function packPackage(root) {
293
+ const destination = join(root, '.aug-build/packages');
294
+ mkdirSync(destination, { recursive: true });
295
+ const result = JSON.parse(npm(['pack', '--ignore-scripts', '--json', '--pack-destination', destination], root))[0];
296
+ if (!result?.filename)
297
+ throw new Error('npm pack returned no archive');
298
+ return join(destination, basename(result.filename));
299
+ }