@cbnventures/nova 0.13.0 → 0.14.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 (332) hide show
  1. package/build/package.json +12 -16
  2. package/build/src/api/node-releases.d.ts +1 -1
  3. package/build/src/api/spdx-licenses.d.ts +1 -1
  4. package/build/src/cli/index.js +155 -39
  5. package/build/src/cli/index.js.map +1 -1
  6. package/build/src/cli/recipe/index.d.ts +3 -0
  7. package/build/src/cli/recipe/index.d.ts.map +1 -0
  8. package/build/src/cli/recipe/index.js +57 -0
  9. package/build/src/cli/recipe/index.js.map +1 -0
  10. package/build/src/cli/recipe/package-json/cleanup.d.ts +8 -0
  11. package/build/src/cli/recipe/package-json/cleanup.d.ts.map +1 -0
  12. package/build/src/cli/recipe/package-json/cleanup.js +174 -0
  13. package/build/src/cli/recipe/package-json/cleanup.js.map +1 -0
  14. package/build/src/cli/recipe/package-json/normalize-artifacts.d.ts +8 -0
  15. package/build/src/cli/recipe/package-json/normalize-artifacts.d.ts.map +1 -0
  16. package/build/src/cli/recipe/package-json/normalize-artifacts.js +242 -0
  17. package/build/src/cli/recipe/package-json/normalize-artifacts.js.map +1 -0
  18. package/build/src/cli/recipe/package-json/normalize-bundler.d.ts +6 -0
  19. package/build/src/cli/recipe/package-json/normalize-bundler.d.ts.map +1 -0
  20. package/build/src/cli/recipe/package-json/normalize-bundler.js +145 -0
  21. package/build/src/cli/recipe/package-json/normalize-bundler.js.map +1 -0
  22. package/build/src/cli/recipe/package-json/normalize-dependencies.d.ts +9 -0
  23. package/build/src/cli/recipe/package-json/normalize-dependencies.d.ts.map +1 -0
  24. package/build/src/cli/recipe/package-json/normalize-dependencies.js +262 -0
  25. package/build/src/cli/recipe/package-json/normalize-dependencies.js.map +1 -0
  26. package/build/src/cli/recipe/package-json/normalize-modules.d.ts +6 -0
  27. package/build/src/cli/recipe/package-json/normalize-modules.d.ts.map +1 -0
  28. package/build/src/cli/recipe/package-json/normalize-modules.js +249 -0
  29. package/build/src/cli/recipe/package-json/normalize-modules.js.map +1 -0
  30. package/build/src/cli/recipe/package-json/normalize-tooling.d.ts +7 -0
  31. package/build/src/cli/recipe/package-json/normalize-tooling.d.ts.map +1 -0
  32. package/build/src/cli/recipe/package-json/normalize-tooling.js +168 -0
  33. package/build/src/cli/recipe/package-json/normalize-tooling.js.map +1 -0
  34. package/build/src/cli/recipe/package-json/sync-environment.d.ts +9 -0
  35. package/build/src/cli/recipe/package-json/sync-environment.d.ts.map +1 -0
  36. package/build/src/cli/recipe/package-json/sync-environment.js +286 -0
  37. package/build/src/cli/recipe/package-json/sync-environment.js.map +1 -0
  38. package/build/src/cli/recipe/package-json/sync-identity.d.ts +6 -0
  39. package/build/src/cli/recipe/package-json/sync-identity.d.ts.map +1 -0
  40. package/build/src/cli/recipe/package-json/sync-identity.js +219 -0
  41. package/build/src/cli/recipe/package-json/sync-identity.js.map +1 -0
  42. package/build/src/cli/recipe/package-json/sync-ownership.d.ts +6 -0
  43. package/build/src/cli/recipe/package-json/sync-ownership.d.ts.map +1 -0
  44. package/build/src/cli/recipe/package-json/sync-ownership.js +349 -0
  45. package/build/src/cli/recipe/package-json/sync-ownership.js.map +1 -0
  46. package/build/src/cli/utility/changelog.d.ts +1 -1
  47. package/build/src/cli/utility/changelog.d.ts.map +1 -1
  48. package/build/src/cli/utility/changelog.js +10 -10
  49. package/build/src/cli/utility/changelog.js.map +1 -1
  50. package/build/src/cli/utility/initialize.d.ts +1 -1
  51. package/build/src/cli/utility/initialize.d.ts.map +1 -1
  52. package/build/src/cli/utility/initialize.js +259 -74
  53. package/build/src/cli/utility/initialize.js.map +1 -1
  54. package/build/src/cli/utility/run-recipes.d.ts +5 -0
  55. package/build/src/cli/utility/run-recipes.d.ts.map +1 -0
  56. package/build/src/cli/utility/run-recipes.js +42 -0
  57. package/build/src/cli/utility/run-recipes.js.map +1 -0
  58. package/build/src/cli/utility/run-scripts.d.ts +10 -0
  59. package/build/src/cli/utility/run-scripts.d.ts.map +1 -0
  60. package/build/src/cli/utility/run-scripts.js +160 -0
  61. package/build/src/cli/utility/run-scripts.js.map +1 -0
  62. package/build/src/cli/utility/transpile.d.ts +9 -0
  63. package/build/src/cli/utility/transpile.d.ts.map +1 -0
  64. package/build/src/cli/utility/transpile.js +59 -0
  65. package/build/src/cli/utility/transpile.js.map +1 -0
  66. package/build/src/cli/utility/type-check.d.ts +1 -1
  67. package/build/src/cli/utility/type-check.d.ts.map +1 -1
  68. package/build/src/cli/utility/type-check.js +3 -3
  69. package/build/src/cli/utility/type-check.js.map +1 -1
  70. package/build/src/cli/utility/version.d.ts +1 -1
  71. package/build/src/cli/utility/version.d.ts.map +1 -1
  72. package/build/src/cli/utility/version.js.map +1 -1
  73. package/build/src/lib/item.d.ts +7 -2
  74. package/build/src/lib/item.d.ts.map +1 -1
  75. package/build/src/lib/item.js +37 -10
  76. package/build/src/lib/item.js.map +1 -1
  77. package/build/src/lib/nova-config.d.ts +2 -2
  78. package/build/src/lib/nova-config.d.ts.map +1 -1
  79. package/build/src/lib/nova-config.js +46 -21
  80. package/build/src/lib/nova-config.js.map +1 -1
  81. package/build/src/lib/utility.d.ts +1 -1
  82. package/build/src/lib/utility.d.ts.map +1 -1
  83. package/build/src/lib/utility.js +9 -6
  84. package/build/src/lib/utility.js.map +1 -1
  85. package/build/src/presets/eslint/dx-code-style.d.mts +1 -1
  86. package/build/src/presets/eslint/dx-ignore.d.mts +1 -1
  87. package/build/src/presets/eslint/env-browser.d.mts +1 -1
  88. package/build/src/presets/eslint/env-edge.d.mts +1 -1
  89. package/build/src/presets/eslint/env-node.d.mts +1 -1
  90. package/build/src/presets/eslint/env-service-worker.d.mts +1 -1
  91. package/build/src/presets/eslint/env-web-worker.d.mts +1 -1
  92. package/build/src/presets/eslint/fw-docusaurus.d.mts +1 -1
  93. package/build/src/presets/eslint/fw-expressjs.d.mts +1 -1
  94. package/build/src/presets/eslint/fw-nextjs.d.mts +1 -1
  95. package/build/src/presets/eslint/lang-javascript.d.mts +1 -1
  96. package/build/src/presets/eslint/lang-mdx.d.mts +1 -1
  97. package/build/src/presets/eslint/lang-typescript.d.mts +1 -1
  98. package/build/src/presets/eslint/platform-cloudflare-workers.d.mts +1 -1
  99. package/build/src/presets/eslint/tool-vite.d.mts +1 -1
  100. package/build/src/rules/eslint/formatting/no-raw-text-in-code.d.ts.map +1 -0
  101. package/build/src/rules/eslint/{no-raw-text-in-code.js → formatting/no-raw-text-in-code.js} +1 -1
  102. package/build/src/rules/eslint/formatting/no-raw-text-in-code.js.map +1 -0
  103. package/build/src/rules/eslint/formatting/require-padding-lines.d.ts +13 -0
  104. package/build/src/rules/eslint/formatting/require-padding-lines.d.ts.map +1 -0
  105. package/build/src/rules/eslint/formatting/require-padding-lines.js +173 -0
  106. package/build/src/rules/eslint/formatting/require-padding-lines.js.map +1 -0
  107. package/build/src/rules/eslint/index.d.ts +14 -5
  108. package/build/src/rules/eslint/index.d.ts.map +1 -1
  109. package/build/src/rules/eslint/index.js +14 -5
  110. package/build/src/rules/eslint/index.js.map +1 -1
  111. package/build/src/rules/eslint/nova/no-logger-dev.d.ts.map +1 -0
  112. package/build/src/rules/eslint/{no-logger-dev.js → nova/no-logger-dev.js} +6 -4
  113. package/build/src/rules/eslint/nova/no-logger-dev.js.map +1 -0
  114. package/build/src/rules/eslint/patterns/no-assign-then-return.d.ts +6 -0
  115. package/build/src/rules/eslint/patterns/no-assign-then-return.d.ts.map +1 -0
  116. package/build/src/rules/eslint/patterns/no-assign-then-return.js +55 -0
  117. package/build/src/rules/eslint/patterns/no-assign-then-return.js.map +1 -0
  118. package/build/src/rules/eslint/patterns/no-bracket-assignment.d.ts +6 -0
  119. package/build/src/rules/eslint/patterns/no-bracket-assignment.d.ts.map +1 -0
  120. package/build/src/rules/eslint/patterns/no-bracket-assignment.js +31 -0
  121. package/build/src/rules/eslint/patterns/no-bracket-assignment.js.map +1 -0
  122. package/build/src/rules/eslint/patterns/no-destructuring.d.ts +13 -0
  123. package/build/src/rules/eslint/patterns/no-destructuring.d.ts.map +1 -0
  124. package/build/src/rules/eslint/patterns/no-destructuring.js +177 -0
  125. package/build/src/rules/eslint/patterns/no-destructuring.js.map +1 -0
  126. package/build/src/rules/eslint/patterns/no-implicit-boolean.d.ts +6 -0
  127. package/build/src/rules/eslint/patterns/no-implicit-boolean.d.ts.map +1 -0
  128. package/build/src/rules/eslint/patterns/no-implicit-boolean.js +62 -0
  129. package/build/src/rules/eslint/patterns/no-implicit-boolean.js.map +1 -0
  130. package/build/src/rules/eslint/patterns/no-ternary-in-template-literal.d.ts +6 -0
  131. package/build/src/rules/eslint/patterns/no-ternary-in-template-literal.d.ts.map +1 -0
  132. package/build/src/rules/eslint/patterns/no-ternary-in-template-literal.js +32 -0
  133. package/build/src/rules/eslint/patterns/no-ternary-in-template-literal.js.map +1 -0
  134. package/build/src/rules/eslint/patterns/switch-case-blocks.d.ts.map +1 -0
  135. package/build/src/rules/eslint/{switch-case-blocks.js → patterns/switch-case-blocks.js} +2 -2
  136. package/build/src/rules/eslint/patterns/switch-case-blocks.js.map +1 -0
  137. package/build/src/rules/eslint/regex/no-regex-literal-flags.d.ts.map +1 -0
  138. package/build/src/rules/eslint/regex/no-regex-literal-flags.js.map +1 -0
  139. package/build/src/rules/eslint/{no-regex-literals.d.ts → regex/no-regex-literals.d.ts} +1 -1
  140. package/build/src/rules/eslint/regex/no-regex-literals.d.ts.map +1 -0
  141. package/build/src/rules/eslint/{no-regex-literals.js → regex/no-regex-literals.js} +4 -4
  142. package/build/src/rules/eslint/regex/no-regex-literals.js.map +1 -0
  143. package/build/src/rules/eslint/typescript/no-catch-unknown-annotation.d.ts +6 -0
  144. package/build/src/rules/eslint/typescript/no-catch-unknown-annotation.d.ts.map +1 -0
  145. package/build/src/rules/eslint/typescript/no-catch-unknown-annotation.js +38 -0
  146. package/build/src/rules/eslint/typescript/no-catch-unknown-annotation.js.map +1 -0
  147. package/build/src/rules/eslint/typescript/no-inline-type-annotation.d.ts +6 -0
  148. package/build/src/rules/eslint/typescript/no-inline-type-annotation.d.ts.map +1 -0
  149. package/build/src/rules/eslint/typescript/no-inline-type-annotation.js +36 -0
  150. package/build/src/rules/eslint/typescript/no-inline-type-annotation.js.map +1 -0
  151. package/build/src/rules/eslint/typescript/no-shared-type-import.d.ts +9 -0
  152. package/build/src/rules/eslint/typescript/no-shared-type-import.d.ts.map +1 -0
  153. package/build/src/rules/eslint/typescript/no-shared-type-import.js +57 -0
  154. package/build/src/rules/eslint/typescript/no-shared-type-import.js.map +1 -0
  155. package/build/src/tests/cli/recipe/package-json/cleanup.test.d.ts +2 -0
  156. package/build/src/tests/cli/recipe/package-json/cleanup.test.d.ts.map +1 -0
  157. package/build/src/tests/cli/recipe/package-json/cleanup.test.js +240 -0
  158. package/build/src/tests/cli/recipe/package-json/cleanup.test.js.map +1 -0
  159. package/build/src/tests/cli/recipe/package-json/normalize-artifacts.test.d.ts +2 -0
  160. package/build/src/tests/cli/recipe/package-json/normalize-artifacts.test.d.ts.map +1 -0
  161. package/build/src/tests/cli/recipe/package-json/normalize-artifacts.test.js +161 -0
  162. package/build/src/tests/cli/recipe/package-json/normalize-artifacts.test.js.map +1 -0
  163. package/build/src/tests/cli/recipe/package-json/normalize-bundler.test.d.ts +2 -0
  164. package/build/src/tests/cli/recipe/package-json/normalize-bundler.test.d.ts.map +1 -0
  165. package/build/src/tests/cli/recipe/package-json/normalize-bundler.test.js +161 -0
  166. package/build/src/tests/cli/recipe/package-json/normalize-bundler.test.js.map +1 -0
  167. package/build/src/tests/cli/recipe/package-json/normalize-dependencies.test.d.ts +2 -0
  168. package/build/src/tests/cli/recipe/package-json/normalize-dependencies.test.d.ts.map +1 -0
  169. package/build/src/tests/cli/recipe/package-json/normalize-dependencies.test.js +175 -0
  170. package/build/src/tests/cli/recipe/package-json/normalize-dependencies.test.js.map +1 -0
  171. package/build/src/tests/cli/recipe/package-json/normalize-modules.test.d.ts +2 -0
  172. package/build/src/tests/cli/recipe/package-json/normalize-modules.test.d.ts.map +1 -0
  173. package/build/src/tests/cli/recipe/package-json/normalize-modules.test.js +164 -0
  174. package/build/src/tests/cli/recipe/package-json/normalize-modules.test.js.map +1 -0
  175. package/build/src/tests/cli/recipe/package-json/normalize-tooling.test.d.ts +2 -0
  176. package/build/src/tests/cli/recipe/package-json/normalize-tooling.test.d.ts.map +1 -0
  177. package/build/src/tests/cli/recipe/package-json/normalize-tooling.test.js +193 -0
  178. package/build/src/tests/cli/recipe/package-json/normalize-tooling.test.js.map +1 -0
  179. package/build/src/tests/cli/recipe/package-json/sync-environment.test.d.ts +2 -0
  180. package/build/src/tests/cli/recipe/package-json/sync-environment.test.d.ts.map +1 -0
  181. package/build/src/tests/cli/recipe/package-json/sync-environment.test.js +158 -0
  182. package/build/src/tests/cli/recipe/package-json/sync-environment.test.js.map +1 -0
  183. package/build/src/tests/cli/recipe/package-json/sync-identity.test.d.ts +2 -0
  184. package/build/src/tests/cli/recipe/package-json/sync-identity.test.d.ts.map +1 -0
  185. package/build/src/tests/cli/recipe/package-json/sync-identity.test.js +156 -0
  186. package/build/src/tests/cli/recipe/package-json/sync-identity.test.js.map +1 -0
  187. package/build/src/tests/cli/recipe/package-json/sync-ownership.test.d.ts +2 -0
  188. package/build/src/tests/cli/recipe/package-json/sync-ownership.test.d.ts.map +1 -0
  189. package/build/src/tests/cli/recipe/package-json/sync-ownership.test.js +164 -0
  190. package/build/src/tests/cli/recipe/package-json/sync-ownership.test.js.map +1 -0
  191. package/build/src/tests/cli/utility/changelog.test.d.ts +2 -0
  192. package/build/src/tests/cli/utility/changelog.test.d.ts.map +1 -0
  193. package/build/src/tests/cli/utility/changelog.test.js +274 -0
  194. package/build/src/tests/cli/utility/changelog.test.js.map +1 -0
  195. package/build/src/tests/cli/utility/initialize.test.d.ts +2 -0
  196. package/build/src/tests/cli/utility/initialize.test.d.ts.map +1 -0
  197. package/build/src/tests/cli/utility/initialize.test.js +27 -0
  198. package/build/src/tests/cli/utility/initialize.test.js.map +1 -0
  199. package/build/src/tests/cli/utility/run-recipes.test.d.ts +2 -0
  200. package/build/src/tests/cli/utility/run-recipes.test.d.ts.map +1 -0
  201. package/build/src/tests/cli/utility/run-recipes.test.js +41 -0
  202. package/build/src/tests/cli/utility/run-recipes.test.js.map +1 -0
  203. package/build/src/tests/cli/utility/run-scripts.test.d.ts +2 -0
  204. package/build/src/tests/cli/utility/run-scripts.test.d.ts.map +1 -0
  205. package/build/src/tests/cli/utility/run-scripts.test.js +153 -0
  206. package/build/src/tests/cli/utility/run-scripts.test.js.map +1 -0
  207. package/build/src/tests/cli/utility/transpile.test.d.ts +2 -0
  208. package/build/src/tests/cli/utility/transpile.test.d.ts.map +1 -0
  209. package/build/src/tests/cli/utility/transpile.test.js +65 -0
  210. package/build/src/tests/cli/utility/transpile.test.js.map +1 -0
  211. package/build/src/tests/cli/utility/type-check.test.d.ts +2 -0
  212. package/build/src/tests/cli/utility/type-check.test.d.ts.map +1 -0
  213. package/build/src/tests/cli/utility/type-check.test.js +63 -0
  214. package/build/src/tests/cli/utility/type-check.test.js.map +1 -0
  215. package/build/src/tests/cli/utility/version.test.d.ts +2 -0
  216. package/build/src/tests/cli/utility/version.test.d.ts.map +1 -0
  217. package/build/src/tests/cli/utility/version.test.js +38 -0
  218. package/build/src/tests/cli/utility/version.test.js.map +1 -0
  219. package/build/src/tests/lib/item.test.js +8 -8
  220. package/build/src/tests/lib/item.test.js.map +1 -1
  221. package/build/src/tests/lib/nova-config.test.js +53 -26
  222. package/build/src/tests/lib/nova-config.test.js.map +1 -1
  223. package/build/src/tests/rules/eslint/formatting/no-raw-text-in-code.test.d.ts.map +1 -0
  224. package/build/src/tests/rules/eslint/{no-raw-text-in-code.test.js → formatting/no-raw-text-in-code.test.js} +1 -1
  225. package/build/src/tests/rules/eslint/formatting/no-raw-text-in-code.test.js.map +1 -0
  226. package/build/src/tests/rules/eslint/formatting/require-padding-lines.test.d.ts +2 -0
  227. package/build/src/tests/rules/eslint/formatting/require-padding-lines.test.d.ts.map +1 -0
  228. package/build/src/tests/rules/eslint/formatting/require-padding-lines.test.js +131 -0
  229. package/build/src/tests/rules/eslint/formatting/require-padding-lines.test.js.map +1 -0
  230. package/build/src/tests/rules/eslint/nova/no-logger-dev.test.d.ts.map +1 -0
  231. package/build/src/tests/rules/eslint/{no-logger-dev.test.js → nova/no-logger-dev.test.js} +1 -1
  232. package/build/src/tests/rules/eslint/nova/no-logger-dev.test.js.map +1 -0
  233. package/build/src/tests/rules/eslint/patterns/no-assign-then-return.test.d.ts +2 -0
  234. package/build/src/tests/rules/eslint/patterns/no-assign-then-return.test.d.ts.map +1 -0
  235. package/build/src/tests/rules/eslint/patterns/no-assign-then-return.test.js +39 -0
  236. package/build/src/tests/rules/eslint/patterns/no-assign-then-return.test.js.map +1 -0
  237. package/build/src/tests/rules/eslint/patterns/no-bracket-assignment.test.d.ts +2 -0
  238. package/build/src/tests/rules/eslint/patterns/no-bracket-assignment.test.d.ts.map +1 -0
  239. package/build/src/tests/rules/eslint/patterns/no-bracket-assignment.test.js +40 -0
  240. package/build/src/tests/rules/eslint/patterns/no-bracket-assignment.test.js.map +1 -0
  241. package/build/src/tests/rules/eslint/patterns/no-destructuring.test.d.ts +2 -0
  242. package/build/src/tests/rules/eslint/patterns/no-destructuring.test.d.ts.map +1 -0
  243. package/build/src/tests/rules/eslint/patterns/no-destructuring.test.js +86 -0
  244. package/build/src/tests/rules/eslint/patterns/no-destructuring.test.js.map +1 -0
  245. package/build/src/tests/rules/eslint/patterns/no-implicit-boolean.test.d.ts +2 -0
  246. package/build/src/tests/rules/eslint/patterns/no-implicit-boolean.test.d.ts.map +1 -0
  247. package/build/src/tests/rules/eslint/patterns/no-implicit-boolean.test.js +76 -0
  248. package/build/src/tests/rules/eslint/patterns/no-implicit-boolean.test.js.map +1 -0
  249. package/build/src/tests/rules/eslint/patterns/no-ternary-in-template-literal.test.d.ts +2 -0
  250. package/build/src/tests/rules/eslint/patterns/no-ternary-in-template-literal.test.d.ts.map +1 -0
  251. package/build/src/tests/rules/eslint/patterns/no-ternary-in-template-literal.test.js +42 -0
  252. package/build/src/tests/rules/eslint/patterns/no-ternary-in-template-literal.test.js.map +1 -0
  253. package/build/src/tests/rules/eslint/patterns/switch-case-blocks.test.d.ts.map +1 -0
  254. package/build/src/tests/rules/eslint/{switch-case-blocks.test.js → patterns/switch-case-blocks.test.js} +1 -1
  255. package/build/src/tests/rules/eslint/patterns/switch-case-blocks.test.js.map +1 -0
  256. package/build/src/tests/rules/eslint/regex/no-regex-literal-flags.test.d.ts.map +1 -0
  257. package/build/src/tests/rules/eslint/{no-regex-literal-flags.test.js → regex/no-regex-literal-flags.test.js} +1 -1
  258. package/build/src/tests/rules/eslint/regex/no-regex-literal-flags.test.js.map +1 -0
  259. package/build/src/tests/rules/eslint/regex/no-regex-literals.test.d.ts.map +1 -0
  260. package/build/src/tests/rules/eslint/{no-regex-literals.test.js → regex/no-regex-literals.test.js} +1 -1
  261. package/build/src/tests/rules/eslint/regex/no-regex-literals.test.js.map +1 -0
  262. package/build/src/tests/rules/eslint/typescript/no-catch-unknown-annotation.test.d.ts +2 -0
  263. package/build/src/tests/rules/eslint/typescript/no-catch-unknown-annotation.test.d.ts.map +1 -0
  264. package/build/src/tests/rules/eslint/typescript/no-catch-unknown-annotation.test.js +34 -0
  265. package/build/src/tests/rules/eslint/typescript/no-catch-unknown-annotation.test.js.map +1 -0
  266. package/build/src/tests/rules/eslint/typescript/no-inline-type-annotation.test.d.ts +2 -0
  267. package/build/src/tests/rules/eslint/typescript/no-inline-type-annotation.test.d.ts.map +1 -0
  268. package/build/src/tests/rules/eslint/typescript/no-inline-type-annotation.test.js +55 -0
  269. package/build/src/tests/rules/eslint/typescript/no-inline-type-annotation.test.js.map +1 -0
  270. package/build/src/tests/rules/eslint/typescript/no-shared-type-import.test.d.ts +2 -0
  271. package/build/src/tests/rules/eslint/typescript/no-shared-type-import.test.d.ts.map +1 -0
  272. package/build/src/tests/rules/eslint/typescript/no-shared-type-import.test.js +51 -0
  273. package/build/src/tests/rules/eslint/typescript/no-shared-type-import.test.js.map +1 -0
  274. package/build/src/toolkit/cli-header.d.ts +1 -1
  275. package/build/src/toolkit/cli-header.js +1 -1
  276. package/build/src/toolkit/logger.d.ts +1 -1
  277. package/build/src/toolkit/markdown-table.d.ts +1 -1
  278. package/package.json +12 -16
  279. package/build/eslint.config.d.ts +0 -34
  280. package/build/eslint.config.d.ts.map +0 -1
  281. package/build/eslint.config.js +0 -40
  282. package/build/eslint.config.js.map +0 -1
  283. package/build/src/cli/recipe/pin-versions.d.ts +0 -7
  284. package/build/src/cli/recipe/pin-versions.d.ts.map +0 -1
  285. package/build/src/cli/recipe/pin-versions.js +0 -145
  286. package/build/src/cli/recipe/pin-versions.js.map +0 -1
  287. package/build/src/cli/recipe/sync-lts-engines.d.ts +0 -6
  288. package/build/src/cli/recipe/sync-lts-engines.d.ts.map +0 -1
  289. package/build/src/cli/recipe/sync-lts-engines.js +0 -118
  290. package/build/src/cli/recipe/sync-lts-engines.js.map +0 -1
  291. package/build/src/cli/recipe/sync-packages.d.ts +0 -18
  292. package/build/src/cli/recipe/sync-packages.d.ts.map +0 -1
  293. package/build/src/cli/recipe/sync-packages.js +0 -1212
  294. package/build/src/cli/recipe/sync-packages.js.map +0 -1
  295. package/build/src/rules/eslint/no-logger-dev.d.ts.map +0 -1
  296. package/build/src/rules/eslint/no-logger-dev.js.map +0 -1
  297. package/build/src/rules/eslint/no-raw-text-in-code.d.ts.map +0 -1
  298. package/build/src/rules/eslint/no-raw-text-in-code.js.map +0 -1
  299. package/build/src/rules/eslint/no-regex-literal-flags.d.ts.map +0 -1
  300. package/build/src/rules/eslint/no-regex-literal-flags.js.map +0 -1
  301. package/build/src/rules/eslint/no-regex-literals.d.ts.map +0 -1
  302. package/build/src/rules/eslint/no-regex-literals.js.map +0 -1
  303. package/build/src/rules/eslint/switch-case-blocks.d.ts.map +0 -1
  304. package/build/src/rules/eslint/switch-case-blocks.js.map +0 -1
  305. package/build/src/tests/cli/recipe/pin-versions.test.d.ts +0 -2
  306. package/build/src/tests/cli/recipe/pin-versions.test.d.ts.map +0 -1
  307. package/build/src/tests/cli/recipe/pin-versions.test.js +0 -197
  308. package/build/src/tests/cli/recipe/pin-versions.test.js.map +0 -1
  309. package/build/src/tests/cli/recipe/sync-lts-engines.test.d.ts +0 -2
  310. package/build/src/tests/cli/recipe/sync-lts-engines.test.d.ts.map +0 -1
  311. package/build/src/tests/cli/recipe/sync-lts-engines.test.js +0 -131
  312. package/build/src/tests/cli/recipe/sync-lts-engines.test.js.map +0 -1
  313. package/build/src/tests/rules/eslint/no-logger-dev.test.d.ts.map +0 -1
  314. package/build/src/tests/rules/eslint/no-logger-dev.test.js.map +0 -1
  315. package/build/src/tests/rules/eslint/no-raw-text-in-code.test.d.ts.map +0 -1
  316. package/build/src/tests/rules/eslint/no-raw-text-in-code.test.js.map +0 -1
  317. package/build/src/tests/rules/eslint/no-regex-literal-flags.test.d.ts.map +0 -1
  318. package/build/src/tests/rules/eslint/no-regex-literal-flags.test.js.map +0 -1
  319. package/build/src/tests/rules/eslint/no-regex-literals.test.d.ts.map +0 -1
  320. package/build/src/tests/rules/eslint/no-regex-literals.test.js.map +0 -1
  321. package/build/src/tests/rules/eslint/switch-case-blocks.test.d.ts.map +0 -1
  322. package/build/src/tests/rules/eslint/switch-case-blocks.test.js.map +0 -1
  323. /package/build/src/rules/eslint/{no-raw-text-in-code.d.ts → formatting/no-raw-text-in-code.d.ts} +0 -0
  324. /package/build/src/rules/eslint/{no-logger-dev.d.ts → nova/no-logger-dev.d.ts} +0 -0
  325. /package/build/src/rules/eslint/{switch-case-blocks.d.ts → patterns/switch-case-blocks.d.ts} +0 -0
  326. /package/build/src/rules/eslint/{no-regex-literal-flags.d.ts → regex/no-regex-literal-flags.d.ts} +0 -0
  327. /package/build/src/rules/eslint/{no-regex-literal-flags.js → regex/no-regex-literal-flags.js} +0 -0
  328. /package/build/src/tests/rules/eslint/{no-raw-text-in-code.test.d.ts → formatting/no-raw-text-in-code.test.d.ts} +0 -0
  329. /package/build/src/tests/rules/eslint/{no-logger-dev.test.d.ts → nova/no-logger-dev.test.d.ts} +0 -0
  330. /package/build/src/tests/rules/eslint/{switch-case-blocks.test.d.ts → patterns/switch-case-blocks.test.d.ts} +0 -0
  331. /package/build/src/tests/rules/eslint/{no-regex-literal-flags.test.d.ts → regex/no-regex-literal-flags.test.d.ts} +0 -0
  332. /package/build/src/tests/rules/eslint/{no-regex-literals.test.d.ts → regex/no-regex-literals.test.d.ts} +0 -0
@@ -1,1212 +0,0 @@
1
- import { dirname, join, relative, sep, } from 'path';
2
- import chalk from 'chalk';
3
- import { NodeReleases } from '../../api/node-releases.js';
4
- import { SpdxLicenses } from '../../api/spdx-licenses.js';
5
- import { itemPackageJsonKeysBundler, itemPackageJsonKeysCorepack, itemPackageJsonKeysNodeJs, itemPackageJsonKeysNpm, itemPackageJsonSortOrder, } from '../../lib/item.js';
6
- import { NovaConfig } from '../../lib/nova-config.js';
7
- import { PATTERN_DIGITS, PATTERN_NAME_AT_VERSION, PATTERN_RANGE_CAPTURE_REMAINDER, PATTERN_RANGE_GREATER_EQUAL_MAJOR, PATTERN_RANGE_MAJOR, PATTERN_SEMVER_STRICT, } from '../../lib/regex.js';
8
- import { isPlainObject, isProjectRoot, loadWorkspaceManifests, pathExists, saveWorkspaceManifest, } from '../../lib/utility.js';
9
- import { Logger } from '../../toolkit/index.js';
10
- export class CLIRecipeSyncPackages {
11
- static async run(options) {
12
- const currentDirectory = process.cwd();
13
- const isAtProjectRoot = await isProjectRoot(currentDirectory);
14
- if (isAtProjectRoot !== true) {
15
- process.exitCode = 1;
16
- return;
17
- }
18
- const isDryRun = options.dryRun === true;
19
- const isIgnoreUnknown = options.ignoreUnknown === true;
20
- const isReplaceFile = options.replaceFile === true;
21
- if (isDryRun === true) {
22
- Logger.customize({
23
- name: 'CLIRecipeSyncPackages.run',
24
- purpose: 'options',
25
- }).warn('Dry run enabled. File changes will not be made in this session.');
26
- }
27
- if (isIgnoreUnknown === true) {
28
- Logger.customize({
29
- name: 'CLIRecipeSyncPackages.run',
30
- purpose: 'options',
31
- }).warn('Ignore unknown enabled. Unknown keys from the "package.json" file will ignored.');
32
- }
33
- if (isReplaceFile === true) {
34
- const replaceFileNotice = (isDryRun) ? 'This option has no effect during a dry run session.' : 'Backup file will not be created.';
35
- Logger.customize({
36
- name: 'CLIRecipeSyncPackages.run',
37
- purpose: 'options',
38
- }).warn(`Replace file enabled. ${replaceFileNotice}`);
39
- }
40
- const novaConfig = new NovaConfig();
41
- const workingFile = await novaConfig.load();
42
- const workingFileWorkspaces = Object.entries(workingFile.workspaces ?? {});
43
- if (workingFileWorkspaces.length === 0) {
44
- Logger.customize({
45
- name: 'CLIRecipeSyncPackages.run',
46
- purpose: 'workspaces',
47
- }).warn('Skipping package sync. No workspaces detected in the "nova.config.json" file.');
48
- return;
49
- }
50
- const workspaces = await loadWorkspaceManifests({
51
- projectRoot: currentDirectory,
52
- workspaces: workingFileWorkspaces,
53
- });
54
- if (workspaces.length === 0) {
55
- Logger.customize({
56
- name: 'CLIRecipeSyncPackages.run',
57
- purpose: 'workspaces',
58
- }).warn('Skipping package sync. No accessible "package.json" files were found for the configured workspaces.');
59
- return;
60
- }
61
- Logger.customize({
62
- name: 'CLIRecipeSyncPackages.run',
63
- purpose: 'summary',
64
- }).info(`Prepared ${workspaces.length} workspace "package.json" file(s) for syncing.`);
65
- for (const workspace of workspaces) {
66
- Logger.customize({
67
- name: 'CLIRecipeSyncPackages.run',
68
- purpose: 'iteration',
69
- }).info(`Syncing the "${workspace.manifest.name}" workspace ...`);
70
- if (isIgnoreUnknown !== true) {
71
- CLIRecipeSyncPackages.handleUnknown(workspace);
72
- }
73
- await CLIRecipeSyncPackages.handleIdentity(workspace, workingFile);
74
- CLIRecipeSyncPackages.handleOwnership(workspace, workingFile);
75
- CLIRecipeSyncPackages.handleRuntime(workspace);
76
- await CLIRecipeSyncPackages.handleArtifacts(workspace);
77
- await CLIRecipeSyncPackages.handlePublish(workspace);
78
- await CLIRecipeSyncPackages.handleTooling(workspace);
79
- CLIRecipeSyncPackages.handleCorepack(workspace);
80
- await CLIRecipeSyncPackages.handleEnvironment(workspace);
81
- await CLIRecipeSyncPackages.handleDependencies(workspace);
82
- CLIRecipeSyncPackages.handleBundler(workspace);
83
- CLIRecipeSyncPackages.handleReorder(workspace);
84
- if (isDryRun === true) {
85
- continue;
86
- }
87
- await saveWorkspaceManifest(workspace, isReplaceFile);
88
- }
89
- }
90
- static async handleIdentity(workspace, workingFile) {
91
- const { fileContents, filePath, manifest } = workspace;
92
- const packageName = fileContents['name'];
93
- const packageVersion = fileContents['version'];
94
- const packageDescription = fileContents['description'];
95
- const packageKeywords = fileContents['keywords'];
96
- const packageLicense = fileContents['license'];
97
- if (typeof packageName !== 'string'
98
- || packageName !== manifest.name) {
99
- Logger.customize({
100
- name: 'CLIRecipeSyncPackages.handleIdentity',
101
- purpose: 'name',
102
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Syncing "name" from workspace manifest ...`);
103
- Reflect.set(fileContents, 'name', manifest.name);
104
- }
105
- if (typeof packageVersion !== 'string'
106
- || !PATTERN_SEMVER_STRICT.test(packageVersion)
107
- || (['freezable'].includes(manifest.policy)
108
- && packageVersion !== '0.0.0') || (['trackable', 'distributable'].includes(manifest.policy)
109
- && packageVersion === '0.0.0')) {
110
- const validVersion = (manifest.policy === 'freezable') ? '0.0.0' : '0.0.1';
111
- Logger.customize({
112
- name: 'CLIRecipeSyncPackages.handleIdentity',
113
- purpose: 'version',
114
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Invalid version detected. Setting it to "${validVersion}" ...`);
115
- Reflect.set(fileContents, 'version', validVersion);
116
- }
117
- if (packageDescription !== undefined
118
- && manifest.policy !== 'distributable') {
119
- Logger.customize({
120
- name: 'CLIRecipeSyncPackages.handleIdentity',
121
- purpose: 'description',
122
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "description". Workspace policy "${manifest.policy}" does not allow it.`);
123
- Reflect.deleteProperty(fileContents, 'description');
124
- }
125
- else {
126
- const validDescription = (workingFile.project !== undefined && workingFile.project.description !== undefined) ? workingFile.project.description.short : undefined;
127
- if ((manifest.policy === 'distributable'
128
- && manifest.syncProperties !== undefined
129
- && manifest.syncProperties.includes('description')
130
- && validDescription !== undefined)
131
- && (typeof packageDescription !== 'string'
132
- || packageDescription !== validDescription)) {
133
- Logger.customize({
134
- name: 'CLIRecipeSyncPackages.handleIdentity',
135
- purpose: 'description',
136
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Syncing "description" from workspace manifest ...`);
137
- Reflect.set(fileContents, 'description', validDescription);
138
- }
139
- if (manifest.policy === 'distributable'
140
- && manifest.syncProperties !== undefined
141
- && manifest.syncProperties.includes('description')
142
- && validDescription === undefined) {
143
- Logger.customize({
144
- name: 'CLIRecipeSyncPackages.handleIdentity',
145
- purpose: 'description',
146
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "description". No description is defined.`);
147
- Reflect.deleteProperty(fileContents, 'description');
148
- }
149
- }
150
- if (packageKeywords !== undefined
151
- && manifest.policy !== 'distributable') {
152
- Logger.customize({
153
- name: 'CLIRecipeSyncPackages.handleIdentity',
154
- purpose: 'keywords',
155
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "keywords". Workspace policy "${manifest.policy}" does not allow it.`);
156
- Reflect.deleteProperty(fileContents, 'keywords');
157
- }
158
- else {
159
- const validKeywords = (workingFile.project !== undefined) ? workingFile.project.keywords : undefined;
160
- if ((manifest.policy === 'distributable'
161
- && manifest.syncProperties !== undefined
162
- && manifest.syncProperties.includes('keywords')
163
- && validKeywords !== undefined)
164
- && (JSON.stringify(packageKeywords) !== JSON.stringify(validKeywords))) {
165
- Logger.customize({
166
- name: 'CLIRecipeSyncPackages.handleIdentity',
167
- purpose: 'keywords',
168
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Syncing "keywords" from workspace manifest ...`);
169
- Reflect.set(fileContents, 'keywords', validKeywords);
170
- }
171
- if (manifest.policy === 'distributable'
172
- && manifest.syncProperties !== undefined
173
- && manifest.syncProperties.includes('keywords')
174
- && validKeywords === undefined) {
175
- Logger.customize({
176
- name: 'CLIRecipeSyncPackages.handleIdentity',
177
- purpose: 'keywords',
178
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "keywords". No keywords are defined.`);
179
- Reflect.deleteProperty(fileContents, 'keywords');
180
- }
181
- }
182
- const spdxLicenses = await SpdxLicenses.fetchLicenses();
183
- if (typeof packageLicense !== 'string'
184
- || (spdxLicenses !== undefined && !spdxLicenses.has(packageLicense))) {
185
- const packageDirectory = dirname(filePath);
186
- const projectRoot = process.cwd();
187
- const licenseCandidates = [
188
- join(packageDirectory, 'LICENSE'),
189
- join(packageDirectory, 'LICENSE.md'),
190
- join(projectRoot, 'LICENSE'),
191
- join(projectRoot, 'LICENSE.md'),
192
- ];
193
- let resolvedLicensePath;
194
- for (const candidate of licenseCandidates) {
195
- if (await pathExists(candidate)) {
196
- resolvedLicensePath = candidate;
197
- break;
198
- }
199
- }
200
- const relativeLicensePath = (resolvedLicensePath !== undefined) ? relative(packageDirectory, resolvedLicensePath) : undefined;
201
- let normalizedLicenseReference;
202
- if (relativeLicensePath !== undefined) {
203
- normalizedLicenseReference = (relativeLicensePath.startsWith('.')) ? relativeLicensePath : `./${relativeLicensePath}`;
204
- }
205
- const fallbackLicense = (normalizedLicenseReference !== undefined) ? `SEE LICENSE IN ${normalizedLicenseReference}` : 'UNLICENSED';
206
- if (packageLicense === fallbackLicense) {
207
- return;
208
- }
209
- Logger.customize({
210
- name: 'CLIRecipeSyncPackages.handleIdentity',
211
- purpose: 'license',
212
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Syncing "license" to "${fallbackLicense}" ...`);
213
- Reflect.set(fileContents, 'license', fallbackLicense);
214
- }
215
- }
216
- static async handleArtifacts(workspace) {
217
- const { fileContents, manifest } = workspace;
218
- const packageFiles = fileContents['files'];
219
- const packageBin = fileContents['bin'];
220
- const packageMan = fileContents['man'];
221
- const packageDirectories = fileContents['directories'];
222
- if (packageFiles !== undefined
223
- && !['package', 'tool'].includes(manifest.role)) {
224
- Logger.customize({
225
- name: 'CLIRecipeSyncPackages.handleArtifacts',
226
- purpose: 'files',
227
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "files". Workspace role "${manifest.role}" does not allow it.`);
228
- Reflect.deleteProperty(fileContents, 'files');
229
- }
230
- else {
231
- if ((manifest.role === 'package' || manifest.role === 'tool')
232
- && packageFiles !== undefined
233
- && CLIRecipeSyncPackages.isEmpty(packageFiles)) {
234
- Logger.customize({
235
- name: 'CLIRecipeSyncPackages.handleArtifacts',
236
- purpose: 'files',
237
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing empty "files" ...`);
238
- Reflect.deleteProperty(fileContents, 'files');
239
- }
240
- }
241
- if (packageBin !== undefined
242
- && !['package', 'tool'].includes(manifest.role)) {
243
- Logger.customize({
244
- name: 'CLIRecipeSyncPackages.handleArtifacts',
245
- purpose: 'bin',
246
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "bin". Workspace role "${manifest.role}" does not allow it.`);
247
- Reflect.deleteProperty(fileContents, 'bin');
248
- }
249
- else {
250
- if ((manifest.role === 'package' || manifest.role === 'tool')
251
- && packageBin !== undefined) {
252
- if (typeof packageBin === 'string') {
253
- const packageName = manifest.name;
254
- const binName = (packageName.includes('/')) ? packageName.split('/').pop() : packageName;
255
- Logger.customize({
256
- name: 'CLIRecipeSyncPackages.handleArtifacts',
257
- purpose: 'bin',
258
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Normalizing "bin" from string to object ...`);
259
- Reflect.set(fileContents, 'bin', {
260
- [binName ?? packageName]: packageBin,
261
- });
262
- }
263
- else if (CLIRecipeSyncPackages.isEmpty(packageBin)) {
264
- Logger.customize({
265
- name: 'CLIRecipeSyncPackages.handleArtifacts',
266
- purpose: 'bin',
267
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing empty "bin" ...`);
268
- Reflect.deleteProperty(fileContents, 'bin');
269
- }
270
- }
271
- }
272
- if (packageMan !== undefined
273
- && !['package', 'tool'].includes(manifest.role)) {
274
- Logger.customize({
275
- name: 'CLIRecipeSyncPackages.handleArtifacts',
276
- purpose: 'man',
277
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "man". Workspace role "${manifest.role}" does not allow it.`);
278
- Reflect.deleteProperty(fileContents, 'man');
279
- }
280
- else {
281
- if ((manifest.role === 'package' || manifest.role === 'tool')
282
- && packageMan !== undefined) {
283
- if (typeof packageMan === 'string') {
284
- Logger.customize({
285
- name: 'CLIRecipeSyncPackages.handleArtifacts',
286
- purpose: 'man',
287
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Normalizing "man" from string to array ...`);
288
- Reflect.set(fileContents, 'man', [packageMan]);
289
- }
290
- else if (CLIRecipeSyncPackages.isEmpty(packageMan)) {
291
- Logger.customize({
292
- name: 'CLIRecipeSyncPackages.handleArtifacts',
293
- purpose: 'man',
294
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing empty "man" ...`);
295
- Reflect.deleteProperty(fileContents, 'man');
296
- }
297
- }
298
- }
299
- if (packageDirectories !== undefined
300
- && !['package', 'tool'].includes(manifest.role)) {
301
- Logger.customize({
302
- name: 'CLIRecipeSyncPackages.handleArtifacts',
303
- purpose: 'directories',
304
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "directories". Workspace role "${manifest.role}" does not allow it.`);
305
- Reflect.deleteProperty(fileContents, 'directories');
306
- }
307
- else {
308
- if ((manifest.role === 'package' || manifest.role === 'tool')
309
- && packageDirectories !== undefined
310
- && CLIRecipeSyncPackages.isEmpty(packageDirectories)) {
311
- Logger.customize({
312
- name: 'CLIRecipeSyncPackages.handleArtifacts',
313
- purpose: 'directories',
314
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing empty "directories" ...`);
315
- Reflect.deleteProperty(fileContents, 'directories');
316
- }
317
- }
318
- }
319
- static async handlePublish(workspace) {
320
- const { fileContents, manifest } = workspace;
321
- const packagePrivate = fileContents['private'];
322
- const packagePublishConfig = fileContents['publishConfig'];
323
- if (typeof packagePrivate !== 'boolean'
324
- || (manifest.policy === 'distributable'
325
- && packagePrivate)
326
- || (manifest.policy !== 'distributable'
327
- && !packagePrivate)) {
328
- const privateValue = (manifest.policy !== 'distributable');
329
- Logger.customize({
330
- name: 'CLIRecipeSyncPackages.handlePublish',
331
- purpose: 'private',
332
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Syncing "private" to "${privateValue}" ...`);
333
- Reflect.set(fileContents, 'private', privateValue);
334
- }
335
- if (packagePublishConfig !== undefined
336
- && manifest.policy !== 'distributable') {
337
- Logger.customize({
338
- name: 'CLIRecipeSyncPackages.handlePublish',
339
- purpose: 'publishConfig',
340
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "publishConfig". Workspace policy "${manifest.policy}" does not allow it.`);
341
- Reflect.deleteProperty(fileContents, 'publishConfig');
342
- }
343
- else {
344
- if (manifest.policy === 'distributable'
345
- && packagePublishConfig !== undefined
346
- && CLIRecipeSyncPackages.isEmpty(packagePublishConfig)) {
347
- Logger.customize({
348
- name: 'CLIRecipeSyncPackages.handlePublish',
349
- purpose: 'publishConfig',
350
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing empty "publishConfig" ...`);
351
- Reflect.deleteProperty(fileContents, 'publishConfig');
352
- }
353
- }
354
- }
355
- static async handleTooling(workspace) {
356
- const { fileContents, filePath, manifest } = workspace;
357
- const packageScripts = fileContents['scripts'];
358
- const packageGypfile = fileContents['gypfile'];
359
- const packageConfig = fileContents['config'];
360
- const packageWorkspaces = fileContents['workspaces'];
361
- const hasBindingGyp = await pathExists(join(dirname(filePath), 'binding.gyp'));
362
- if (packageScripts === undefined) {
363
- Logger.customize({
364
- name: 'CLIRecipeSyncPackages.handleTooling',
365
- purpose: 'scripts',
366
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Adding "scripts" as an empty object ...`);
367
- Reflect.set(fileContents, 'scripts', {});
368
- }
369
- if (packageGypfile !== undefined
370
- && !hasBindingGyp) {
371
- Logger.customize({
372
- name: 'CLIRecipeSyncPackages.handleTooling',
373
- purpose: 'gypfile',
374
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "gypfile". No "binding.gyp" file is found.`);
375
- Reflect.deleteProperty(fileContents, 'gypfile');
376
- }
377
- else {
378
- if (packageGypfile === undefined
379
- && hasBindingGyp
380
- && (!isPlainObject(packageScripts)
381
- || (isPlainObject(packageScripts)
382
- && packageScripts['preinstall'] === undefined
383
- && packageScripts['install'] === undefined))) {
384
- Logger.customize({
385
- name: 'CLIRecipeSyncPackages.handleTooling',
386
- purpose: 'gypfile',
387
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Adding "gypfile" as the npm default ...`);
388
- Reflect.set(fileContents, 'gypfile', true);
389
- }
390
- }
391
- if (packageConfig !== undefined
392
- && CLIRecipeSyncPackages.isEmpty(packageConfig)) {
393
- Logger.customize({
394
- name: 'CLIRecipeSyncPackages.handleTooling',
395
- purpose: 'config',
396
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing empty "config" ...`);
397
- Reflect.deleteProperty(fileContents, 'config');
398
- }
399
- if (packageWorkspaces !== undefined
400
- && manifest.role !== 'project') {
401
- Logger.customize({
402
- name: 'CLIRecipeSyncPackages.handleTooling',
403
- purpose: 'workspaces',
404
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "workspaces". Workspace role "${manifest.role}" does not allow it.`);
405
- Reflect.deleteProperty(fileContents, 'workspaces');
406
- }
407
- else {
408
- if (manifest.role === 'project'
409
- && packageWorkspaces === undefined) {
410
- Logger.customize({
411
- name: 'CLIRecipeSyncPackages.handleTooling',
412
- purpose: 'workspaces',
413
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Adding "workspaces" as an empty array ...`);
414
- Reflect.set(fileContents, 'workspaces', []);
415
- }
416
- }
417
- }
418
- static async handleEnvironment(workspace) {
419
- const { fileContents, manifest } = workspace;
420
- const packageEngines = fileContents['engines'];
421
- const packageOs = fileContents['os'];
422
- const packageCpu = fileContents['cpu'];
423
- const packageLibc = fileContents['libc'];
424
- const packageDevEngines = fileContents['devEngines'];
425
- const ltsConstraint = await NodeReleases.fetchLtsVersions();
426
- if (packageEngines === undefined) {
427
- if (ltsConstraint !== undefined) {
428
- Logger.customize({
429
- name: 'CLIRecipeSyncPackages.handleEnvironment',
430
- purpose: 'engines',
431
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Adding "engines" with "node" set to "${ltsConstraint}" ...`);
432
- Reflect.set(fileContents, 'engines', {
433
- node: ltsConstraint,
434
- });
435
- }
436
- else {
437
- Logger.customize({
438
- name: 'CLIRecipeSyncPackages.handleEnvironment',
439
- purpose: 'engines',
440
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Adding "engines" as an empty object ...`);
441
- Reflect.set(fileContents, 'engines', {});
442
- }
443
- }
444
- else {
445
- if (isPlainObject(packageEngines)
446
- && packageEngines['node'] === undefined
447
- && ltsConstraint !== undefined) {
448
- Logger.customize({
449
- name: 'CLIRecipeSyncPackages.handleEnvironment',
450
- purpose: 'engines',
451
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Adding "engines.node" set to "${ltsConstraint}" ...`);
452
- Reflect.set(packageEngines, 'node', ltsConstraint);
453
- }
454
- }
455
- if (manifest.syncLtsEngines === true
456
- && isPlainObject(fileContents['engines'])
457
- && typeof fileContents['engines']['node'] === 'string'
458
- && ltsConstraint !== undefined) {
459
- const existingNode = fileContents['engines']['node'];
460
- const ltsMatches = [...ltsConstraint.matchAll(new RegExp(PATTERN_DIGITS.source, 'g'))];
461
- if (ltsMatches.length > 0) {
462
- const ltsMajors = ltsMatches.map((match) => parseInt(match[0], 10));
463
- const branches = existingNode.split('||').map((branch) => branch.trim());
464
- const coversAll = ltsMajors.every((major) => {
465
- return branches.some((branch) => {
466
- if (branch === '*') {
467
- return true;
468
- }
469
- const geMatch = branch.match(PATTERN_RANGE_GREATER_EQUAL_MAJOR);
470
- if (geMatch !== null) {
471
- return parseInt(geMatch[1] ?? '', 10) <= major;
472
- }
473
- const majorMatch = branch.match(PATTERN_RANGE_MAJOR);
474
- if (majorMatch !== null) {
475
- return parseInt(majorMatch[1] ?? '', 10) === major;
476
- }
477
- return false;
478
- });
479
- });
480
- if (coversAll !== true) {
481
- Logger.customize({
482
- name: 'CLIRecipeSyncPackages.handleEnvironment',
483
- purpose: 'engines',
484
- }).warn(`${chalk.magenta(`"${manifest.name}" workspace`)} → "engines.node" is "${existingNode}" but must cover all active LTS versions (${ltsMajors.join(', ')}). Run "nova recipe sync-lts-engines" to update.`);
485
- }
486
- }
487
- }
488
- if (packageOs !== undefined
489
- && CLIRecipeSyncPackages.isEmpty(packageOs)) {
490
- Logger.customize({
491
- name: 'CLIRecipeSyncPackages.handleEnvironment',
492
- purpose: 'os',
493
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing empty "os" ...`);
494
- Reflect.deleteProperty(fileContents, 'os');
495
- }
496
- if (packageCpu !== undefined
497
- && CLIRecipeSyncPackages.isEmpty(packageCpu)) {
498
- Logger.customize({
499
- name: 'CLIRecipeSyncPackages.handleEnvironment',
500
- purpose: 'cpu',
501
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing empty "cpu" ...`);
502
- Reflect.deleteProperty(fileContents, 'cpu');
503
- }
504
- if (packageLibc !== undefined
505
- && !(Array.isArray(fileContents['os'])
506
- && fileContents['os'].includes('linux'))) {
507
- Logger.customize({
508
- name: 'CLIRecipeSyncPackages.handleEnvironment',
509
- purpose: 'libc',
510
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "libc". Package "os" does not include "linux".`);
511
- Reflect.deleteProperty(fileContents, 'libc');
512
- }
513
- else {
514
- if (packageLibc === undefined
515
- && (Array.isArray(fileContents['os'])
516
- && fileContents['os'].includes('linux'))) {
517
- Logger.customize({
518
- name: 'CLIRecipeSyncPackages.handleEnvironment',
519
- purpose: 'libc',
520
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Adding "libc" as "glibc" ...`);
521
- Reflect.set(fileContents, 'libc', ['glibc']);
522
- }
523
- }
524
- if (packageDevEngines !== undefined
525
- && CLIRecipeSyncPackages.isEmpty(packageDevEngines)) {
526
- Logger.customize({
527
- name: 'CLIRecipeSyncPackages.handleEnvironment',
528
- purpose: 'devEngines',
529
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing empty "devEngines" ...`);
530
- Reflect.deleteProperty(fileContents, 'devEngines');
531
- }
532
- }
533
- static async handleDependencies(workspace) {
534
- const { fileContents, manifest } = workspace;
535
- const packageDependencies = fileContents['dependencies'];
536
- const packageDevDependencies = fileContents['devDependencies'];
537
- const packagePeerDependencies = fileContents['peerDependencies'];
538
- const packagePeerDependenciesMeta = fileContents['peerDependenciesMeta'];
539
- const packageBundleDependencies = fileContents['bundleDependencies'];
540
- const packageBundledDependencies = fileContents['bundledDependencies'];
541
- const packageOptionalDependencies = fileContents['optionalDependencies'];
542
- const packageOverrides = fileContents['overrides'];
543
- if (packageDependencies !== undefined
544
- && CLIRecipeSyncPackages.isEmpty(packageDependencies)) {
545
- Logger.customize({
546
- name: 'CLIRecipeSyncPackages.handleDependencies',
547
- purpose: 'dependencies',
548
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing empty "dependencies" ...`);
549
- Reflect.deleteProperty(fileContents, 'dependencies');
550
- }
551
- if (packageDevDependencies !== undefined
552
- && CLIRecipeSyncPackages.isEmpty(packageDevDependencies)) {
553
- Logger.customize({
554
- name: 'CLIRecipeSyncPackages.handleDependencies',
555
- purpose: 'devDependencies',
556
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing empty "devDependencies" ...`);
557
- Reflect.deleteProperty(fileContents, 'devDependencies');
558
- }
559
- if (packagePeerDependencies !== undefined
560
- && CLIRecipeSyncPackages.isEmpty(packagePeerDependencies)) {
561
- Logger.customize({
562
- name: 'CLIRecipeSyncPackages.handleDependencies',
563
- purpose: 'peerDependencies',
564
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing empty "peerDependencies" ...`);
565
- Reflect.deleteProperty(fileContents, 'peerDependencies');
566
- }
567
- if (packagePeerDependenciesMeta !== undefined
568
- && CLIRecipeSyncPackages.isEmpty(packagePeerDependenciesMeta)) {
569
- Logger.customize({
570
- name: 'CLIRecipeSyncPackages.handleDependencies',
571
- purpose: 'peerDependenciesMeta',
572
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing empty "peerDependenciesMeta" ...`);
573
- Reflect.deleteProperty(fileContents, 'peerDependenciesMeta');
574
- }
575
- if (packageBundledDependencies !== undefined) {
576
- const bundleDependencies = Array.isArray(packageBundleDependencies) ? packageBundleDependencies : [];
577
- const bundledDependencies = Array.isArray(packageBundledDependencies) ? packageBundledDependencies : [];
578
- const mergedBundleDependencies = [...new Set([...bundleDependencies, ...bundledDependencies])];
579
- Logger.customize({
580
- name: 'CLIRecipeSyncPackages.handleDependencies',
581
- purpose: 'bundleDependencies',
582
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Merging "bundledDependencies" into "bundleDependencies" ...`);
583
- Reflect.set(fileContents, 'bundleDependencies', mergedBundleDependencies);
584
- Logger.customize({
585
- name: 'CLIRecipeSyncPackages.handleDependencies',
586
- purpose: 'bundledDependencies',
587
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "bundledDependencies". "bundledDependencies" is an alias of "bundleDependencies".`);
588
- Reflect.deleteProperty(fileContents, 'bundledDependencies');
589
- }
590
- if (fileContents['bundleDependencies'] !== undefined
591
- && CLIRecipeSyncPackages.isEmpty(fileContents['bundleDependencies'])) {
592
- Logger.customize({
593
- name: 'CLIRecipeSyncPackages.handleDependencies',
594
- purpose: 'bundleDependencies',
595
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing empty "bundleDependencies" ...`);
596
- Reflect.deleteProperty(fileContents, 'bundleDependencies');
597
- }
598
- if (packageOptionalDependencies !== undefined
599
- && CLIRecipeSyncPackages.isEmpty(packageOptionalDependencies)) {
600
- Logger.customize({
601
- name: 'CLIRecipeSyncPackages.handleDependencies',
602
- purpose: 'optionalDependencies',
603
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing empty "optionalDependencies" ...`);
604
- Reflect.deleteProperty(fileContents, 'optionalDependencies');
605
- }
606
- if (packageOverrides !== undefined
607
- && CLIRecipeSyncPackages.isEmpty(packageOverrides)) {
608
- Logger.customize({
609
- name: 'CLIRecipeSyncPackages.handleDependencies',
610
- purpose: 'overrides',
611
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing empty "overrides" ...`);
612
- Reflect.deleteProperty(fileContents, 'overrides');
613
- }
614
- if (manifest.pinVersions === true) {
615
- const depGroups = [
616
- 'dependencies',
617
- 'devDependencies',
618
- ];
619
- for (const depGroup of depGroups) {
620
- const deps = fileContents[depGroup];
621
- if (!isPlainObject(deps)) {
622
- continue;
623
- }
624
- for (const [depName, depVersion] of Object.entries(deps)) {
625
- if (typeof depVersion !== 'string') {
626
- continue;
627
- }
628
- if (PATTERN_RANGE_CAPTURE_REMAINDER.test(depVersion)) {
629
- Logger.customize({
630
- name: 'CLIRecipeSyncPackages.handleDependencies',
631
- purpose: depGroup,
632
- }).warn(`${chalk.magenta(`"${manifest.name}" workspace`)} → "${depName}" has unpinned version "${depVersion}". Run "nova recipe pin-versions" to fix.`);
633
- }
634
- }
635
- }
636
- }
637
- }
638
- static handleUnknown(workspace) {
639
- const allowedKeys = new Set([
640
- ...itemPackageJsonKeysBundler,
641
- ...itemPackageJsonKeysCorepack,
642
- ...itemPackageJsonKeysNodeJs,
643
- ...itemPackageJsonKeysNpm,
644
- ]);
645
- const manifestContents = workspace.fileContents ?? {};
646
- const manifestKeys = Object.keys(manifestContents);
647
- const unknownKeys = manifestKeys.filter((key) => !allowedKeys.has(key));
648
- if (unknownKeys.length === 0) {
649
- return;
650
- }
651
- Logger.customize({
652
- name: 'CLIRecipeSyncPackages.handleUnknown',
653
- purpose: 'unsupported',
654
- }).warn([
655
- `Workspace "${workspace.manifest.name}" contains unsupported "package.json" key(s).`,
656
- 'The unsupported keys are:',
657
- `- "${unknownKeys.join('"\n- "')}"`,
658
- 'Review the references below:',
659
- '- https://cbnventures.github.io/nova/docs/cli/recipes/sync-packages#unsupported-keys',
660
- ].join('\n'));
661
- for (const unknownKey of unknownKeys) {
662
- Logger.customize({
663
- name: 'CLIRecipeSyncPackages.handleUnknown',
664
- purpose: 'removal',
665
- }).info(`Removing unsupported key "${unknownKey}" from workspace "${workspace.manifest.name}".`);
666
- Reflect.deleteProperty(manifestContents, unknownKey);
667
- }
668
- }
669
- static handleOwnership(workspace, workingFile) {
670
- const { fileContents, manifest } = workspace;
671
- const packageHomepage = fileContents['homepage'];
672
- const packageBugs = fileContents['bugs'];
673
- const packageAuthor = fileContents['author'];
674
- const packageContributors = fileContents['contributors'];
675
- const packageFundingSources = fileContents['funding'];
676
- const packageRepository = fileContents['repository'];
677
- if (packageHomepage !== undefined
678
- && manifest.policy !== 'distributable') {
679
- Logger.customize({
680
- name: 'CLIRecipeSyncPackages.handleOwnership',
681
- purpose: 'homepage',
682
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "homepage". Workspace policy "${manifest.policy}" does not allow it.`);
683
- Reflect.deleteProperty(fileContents, 'homepage');
684
- }
685
- else {
686
- const validHomepage = (workingFile.urls !== undefined) ? workingFile.urls.homepage : undefined;
687
- if ((manifest.policy === 'distributable'
688
- && manifest.syncProperties !== undefined
689
- && manifest.syncProperties.includes('homepage')
690
- && validHomepage !== undefined)
691
- && (typeof packageHomepage !== 'string'
692
- || packageHomepage !== validHomepage)) {
693
- Logger.customize({
694
- name: 'CLIRecipeSyncPackages.handleOwnership',
695
- purpose: 'homepage',
696
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Syncing "homepage" from workspace manifest ...`);
697
- Reflect.set(fileContents, 'homepage', validHomepage);
698
- }
699
- if (manifest.policy === 'distributable'
700
- && manifest.syncProperties !== undefined
701
- && manifest.syncProperties.includes('homepage')
702
- && validHomepage === undefined) {
703
- Logger.customize({
704
- name: 'CLIRecipeSyncPackages.handleOwnership',
705
- purpose: 'homepage',
706
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "homepage". No homepage is defined.`);
707
- Reflect.deleteProperty(fileContents, 'homepage');
708
- }
709
- }
710
- if (packageBugs !== undefined
711
- && manifest.policy !== 'distributable') {
712
- Logger.customize({
713
- name: 'CLIRecipeSyncPackages.handleOwnership',
714
- purpose: 'bugs',
715
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "bugs". Workspace policy "${manifest.policy}" does not allow it.`);
716
- Reflect.deleteProperty(fileContents, 'bugs');
717
- }
718
- else {
719
- const validBugs = {
720
- email: (workingFile.emails !== undefined) ? workingFile.emails.bugs : undefined,
721
- url: (workingFile.urls !== undefined) ? workingFile.urls.bugs : undefined,
722
- };
723
- if ((manifest.policy === 'distributable'
724
- && manifest.syncProperties !== undefined
725
- && manifest.syncProperties.includes('bugs')
726
- && (validBugs.email !== undefined
727
- || validBugs.url !== undefined))
728
- && (JSON.stringify(packageBugs) !== JSON.stringify(validBugs))) {
729
- Logger.customize({
730
- name: 'CLIRecipeSyncPackages.handleOwnership',
731
- purpose: 'bugs',
732
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Syncing "bugs" from workspace manifest ...`);
733
- Reflect.set(fileContents, 'bugs', validBugs);
734
- }
735
- if (manifest.policy === 'distributable'
736
- && manifest.syncProperties !== undefined
737
- && manifest.syncProperties.includes('bugs')
738
- && (validBugs.email === undefined
739
- && validBugs.url === undefined)) {
740
- Logger.customize({
741
- name: 'CLIRecipeSyncPackages.handleOwnership',
742
- purpose: 'bugs',
743
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "bugs". No bug contacts are defined.`);
744
- Reflect.deleteProperty(fileContents, 'bugs');
745
- }
746
- }
747
- if (packageAuthor !== undefined
748
- && manifest.policy !== 'distributable') {
749
- Logger.customize({
750
- name: 'CLIRecipeSyncPackages.handleOwnership',
751
- purpose: 'author',
752
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "author". Workspace policy "${manifest.policy}" does not allow it.`);
753
- Reflect.deleteProperty(fileContents, 'author');
754
- }
755
- else {
756
- const validAuthor = (() => {
757
- const entity = (workingFile.entities !== undefined) ? workingFile.entities.find((entity) => {
758
- return Array.isArray(entity.roles) && entity.roles.includes('author');
759
- }) : undefined;
760
- if (entity === undefined) {
761
- return {
762
- name: undefined,
763
- email: undefined,
764
- url: undefined,
765
- };
766
- }
767
- return {
768
- name: entity.name,
769
- email: entity.email,
770
- url: entity.url,
771
- };
772
- })();
773
- if ((manifest.policy === 'distributable'
774
- && manifest.syncProperties !== undefined
775
- && manifest.syncProperties.includes('author')
776
- && (validAuthor.name !== undefined
777
- || validAuthor.email !== undefined
778
- || validAuthor.url !== undefined))
779
- && (JSON.stringify(packageAuthor) !== JSON.stringify(validAuthor))) {
780
- Logger.customize({
781
- name: 'CLIRecipeSyncPackages.handleOwnership',
782
- purpose: 'author',
783
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Syncing "author" from workspace manifest ...`);
784
- Reflect.set(fileContents, 'author', validAuthor);
785
- }
786
- if (manifest.policy === 'distributable'
787
- && manifest.syncProperties !== undefined
788
- && manifest.syncProperties.includes('author')
789
- && (validAuthor.name === undefined
790
- && validAuthor.email === undefined
791
- && validAuthor.url === undefined)) {
792
- Logger.customize({
793
- name: 'CLIRecipeSyncPackages.handleOwnership',
794
- purpose: 'author',
795
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "author". No author is defined.`);
796
- Reflect.deleteProperty(fileContents, 'author');
797
- }
798
- }
799
- if (packageContributors !== undefined
800
- && manifest.policy !== 'distributable') {
801
- Logger.customize({
802
- name: 'CLIRecipeSyncPackages.handleOwnership',
803
- purpose: 'contributors',
804
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "contributors". Workspace policy "${manifest.policy}" does not allow it.`);
805
- Reflect.deleteProperty(fileContents, 'contributors');
806
- }
807
- else {
808
- const validContributors = (() => {
809
- const entities = workingFile.entities ?? [];
810
- return entities
811
- .filter((entity) => Array.isArray(entity.roles) && entity.roles.includes('contributor'))
812
- .map((entity) => ({
813
- name: entity.name,
814
- email: entity.email,
815
- url: entity.url,
816
- }))
817
- .filter((entity) => entity.name !== undefined || entity.email !== undefined || entity.url !== undefined);
818
- })();
819
- if ((manifest.policy === 'distributable'
820
- && manifest.syncProperties !== undefined
821
- && manifest.syncProperties.includes('contributors')
822
- && (validContributors.length > 0))
823
- && (JSON.stringify(packageContributors) !== JSON.stringify(validContributors))) {
824
- Logger.customize({
825
- name: 'CLIRecipeSyncPackages.handleOwnership',
826
- purpose: 'contributors',
827
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Syncing "contributors" from workspace manifest ...`);
828
- Reflect.set(fileContents, 'contributors', validContributors);
829
- }
830
- if (manifest.policy === 'distributable'
831
- && manifest.syncProperties !== undefined
832
- && manifest.syncProperties.includes('contributors')
833
- && (validContributors.length === 0)) {
834
- Logger.customize({
835
- name: 'CLIRecipeSyncPackages.handleOwnership',
836
- purpose: 'contributors',
837
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "contributors". No contributors are defined.`);
838
- Reflect.deleteProperty(fileContents, 'contributors');
839
- }
840
- }
841
- if (packageFundingSources !== undefined
842
- && manifest.policy !== 'distributable') {
843
- Logger.customize({
844
- name: 'CLIRecipeSyncPackages.handleOwnership',
845
- purpose: 'funding',
846
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "funding". Workspace policy "${manifest.policy}" does not allow it.`);
847
- Reflect.deleteProperty(fileContents, 'funding');
848
- }
849
- else {
850
- const validFundingSources = (workingFile.urls !== undefined) ? workingFile.urls.fundSources : undefined;
851
- if ((manifest.policy === 'distributable'
852
- && manifest.syncProperties !== undefined
853
- && manifest.syncProperties.includes('funding')
854
- && validFundingSources !== undefined)
855
- && (JSON.stringify(packageFundingSources) !== JSON.stringify(validFundingSources))) {
856
- Logger.customize({
857
- name: 'CLIRecipeSyncPackages.handleOwnership',
858
- purpose: 'funding',
859
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Syncing "funding" from workspace manifest ...`);
860
- Reflect.set(fileContents, 'funding', validFundingSources);
861
- }
862
- if (manifest.policy === 'distributable'
863
- && manifest.syncProperties !== undefined
864
- && manifest.syncProperties.includes('funding')
865
- && validFundingSources === undefined) {
866
- Logger.customize({
867
- name: 'CLIRecipeSyncPackages.handleOwnership',
868
- purpose: 'funding',
869
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "funding". No funding sources are defined.`);
870
- Reflect.deleteProperty(fileContents, 'funding');
871
- }
872
- }
873
- if (packageRepository !== undefined
874
- && manifest.policy !== 'distributable') {
875
- Logger.customize({
876
- name: 'CLIRecipeSyncPackages.handleOwnership',
877
- purpose: 'repository',
878
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "repository". Workspace policy "${manifest.policy}" does not allow it.`);
879
- Reflect.deleteProperty(fileContents, 'repository');
880
- }
881
- else {
882
- const validRepository = (() => {
883
- const repositoryUrl = (workingFile.urls !== undefined) ? workingFile.urls.repository : undefined;
884
- if (repositoryUrl === undefined) {
885
- return undefined;
886
- }
887
- const projectRoot = process.cwd();
888
- const packageDirectory = dirname(workspace.filePath);
889
- const repositoryDirectory = relative(projectRoot, packageDirectory).replaceAll(sep, '/');
890
- return {
891
- type: 'git',
892
- url: repositoryUrl,
893
- ...(repositoryDirectory !== '' && repositoryDirectory !== '.' ? {
894
- directory: repositoryDirectory,
895
- } : {}),
896
- };
897
- })();
898
- if ((manifest.policy === 'distributable'
899
- && manifest.syncProperties !== undefined
900
- && manifest.syncProperties.includes('repository')
901
- && validRepository !== undefined)
902
- && (JSON.stringify(packageRepository) !== JSON.stringify(validRepository))) {
903
- Logger.customize({
904
- name: 'CLIRecipeSyncPackages.handleOwnership',
905
- purpose: 'repository',
906
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Syncing "repository" from workspace manifest ...`);
907
- Reflect.set(fileContents, 'repository', validRepository);
908
- }
909
- if (manifest.policy === 'distributable'
910
- && manifest.syncProperties !== undefined
911
- && manifest.syncProperties.includes('repository')
912
- && validRepository === undefined) {
913
- Logger.customize({
914
- name: 'CLIRecipeSyncPackages.handleOwnership',
915
- purpose: 'repository',
916
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "repository". No repository url is defined.`);
917
- Reflect.deleteProperty(fileContents, 'repository');
918
- }
919
- }
920
- }
921
- static handleRuntime(workspace) {
922
- const { fileContents, manifest } = workspace;
923
- const packageExports = fileContents['exports'];
924
- const packageMain = fileContents['main'];
925
- const packageType = fileContents['type'];
926
- const packageBrowser = fileContents['browser'];
927
- const packageImports = fileContents['imports'];
928
- if (packageExports !== undefined
929
- && !['config', 'package', 'tool'].includes(manifest.role)) {
930
- Logger.customize({
931
- name: 'CLIRecipeSyncPackages.handleRuntime',
932
- purpose: 'exports',
933
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "exports". Workspace role "${manifest.role}" does not allow it.`);
934
- Reflect.deleteProperty(fileContents, 'exports');
935
- }
936
- else {
937
- if (manifest.role === 'config'
938
- || manifest.role === 'package'
939
- || manifest.role === 'tool') {
940
- if (typeof packageExports === 'string') {
941
- Logger.customize({
942
- name: 'CLIRecipeSyncPackages.handleRuntime',
943
- purpose: 'exports',
944
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Normalizing "exports" from string to object ...`);
945
- Reflect.set(fileContents, 'exports', {
946
- '.': {
947
- default: packageExports,
948
- },
949
- });
950
- }
951
- }
952
- }
953
- if (packageMain !== undefined
954
- && !['config', 'app', 'package', 'tool'].includes(manifest.role)) {
955
- Logger.customize({
956
- name: 'CLIRecipeSyncPackages.handleRuntime',
957
- purpose: 'main',
958
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "main". Workspace role "${manifest.role}" does not allow it.`);
959
- Reflect.deleteProperty(fileContents, 'main');
960
- }
961
- else {
962
- if (manifest.role === 'config'
963
- || manifest.role === 'app'
964
- || manifest.role === 'package'
965
- || manifest.role === 'tool') {
966
- const currentPackageExports = fileContents['exports'];
967
- if (typeof packageMain === 'string'
968
- && (isPlainObject(currentPackageExports)
969
- && isPlainObject(currentPackageExports['.'])
970
- && typeof currentPackageExports['.']['require'] === 'string')
971
- && packageMain !== currentPackageExports['.']['require']) {
972
- Logger.customize({
973
- name: 'CLIRecipeSyncPackages.handleRuntime',
974
- purpose: 'main',
975
- }).warn(`${chalk.magenta(`"${manifest.name}" workspace`)} → "main" differs from "exports['.'].require". No changes applied.`);
976
- }
977
- else if (typeof packageMain === 'string'
978
- && (isPlainObject(currentPackageExports)
979
- && isPlainObject(currentPackageExports['.']))
980
- && typeof currentPackageExports['.']['require'] !== 'string') {
981
- Logger.customize({
982
- name: 'CLIRecipeSyncPackages.handleRuntime',
983
- purpose: 'main',
984
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Syncing "exports['.'].require" from "main" ...`);
985
- Reflect.set(currentPackageExports['.'], 'require', packageMain);
986
- }
987
- else if ((isPlainObject(currentPackageExports)
988
- && isPlainObject(currentPackageExports['.'])
989
- && typeof currentPackageExports['.']['require'] === 'string')
990
- && typeof packageMain !== 'string') {
991
- Logger.customize({
992
- name: 'CLIRecipeSyncPackages.handleRuntime',
993
- purpose: 'main',
994
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Syncing "main" from "exports['.'].require" ...`);
995
- Reflect.set(fileContents, 'main', currentPackageExports['.']['require']);
996
- }
997
- else if (typeof packageMain === 'string'
998
- && isPlainObject(currentPackageExports)
999
- && typeof currentPackageExports['.'] === 'string') {
1000
- Logger.customize({
1001
- name: 'CLIRecipeSyncPackages.handleRuntime',
1002
- purpose: 'main',
1003
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Normalizing "exports['.']" from string to object ...`);
1004
- Reflect.set(currentPackageExports, '.', {
1005
- default: currentPackageExports['.'],
1006
- require: packageMain,
1007
- });
1008
- }
1009
- }
1010
- }
1011
- if (packageType !== undefined
1012
- && !['config', 'app', 'package', 'tool'].includes(manifest.role)) {
1013
- Logger.customize({
1014
- name: 'CLIRecipeSyncPackages.handleRuntime',
1015
- purpose: 'type',
1016
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "type". Workspace role "${manifest.role}" does not allow it.`);
1017
- Reflect.deleteProperty(fileContents, 'type');
1018
- }
1019
- if (packageBrowser !== undefined
1020
- && !['package'].includes(manifest.role)) {
1021
- Logger.customize({
1022
- name: 'CLIRecipeSyncPackages.handleRuntime',
1023
- purpose: 'browser',
1024
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "browser". Workspace role "${manifest.role}" does not allow it.`);
1025
- Reflect.deleteProperty(fileContents, 'browser');
1026
- }
1027
- else {
1028
- if (manifest.role === 'package') {
1029
- const currentPackageExports = fileContents['exports'];
1030
- if (typeof packageBrowser === 'string'
1031
- && (isPlainObject(currentPackageExports)
1032
- && isPlainObject(currentPackageExports['.'])
1033
- && typeof currentPackageExports['.']['browser'] === 'string')
1034
- && packageBrowser !== currentPackageExports['.']['browser']) {
1035
- Logger.customize({
1036
- name: 'CLIRecipeSyncPackages.handleRuntime',
1037
- purpose: 'browser',
1038
- }).warn(`${chalk.magenta(`"${manifest.name}" workspace`)} → "browser" differs from "exports['.'].browser". No changes applied.`);
1039
- }
1040
- else if (typeof packageBrowser === 'string'
1041
- && (isPlainObject(currentPackageExports)
1042
- && isPlainObject(currentPackageExports['.']))
1043
- && typeof currentPackageExports['.']['browser'] !== 'string') {
1044
- Logger.customize({
1045
- name: 'CLIRecipeSyncPackages.handleRuntime',
1046
- purpose: 'browser',
1047
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Syncing "exports['.'].browser" from "browser" ...`);
1048
- Reflect.set(currentPackageExports['.'], 'browser', packageBrowser);
1049
- }
1050
- else if ((isPlainObject(currentPackageExports)
1051
- && isPlainObject(currentPackageExports['.'])
1052
- && typeof currentPackageExports['.']['browser'] === 'string')
1053
- && typeof packageBrowser !== 'string'
1054
- && !isPlainObject(packageBrowser)) {
1055
- Logger.customize({
1056
- name: 'CLIRecipeSyncPackages.handleRuntime',
1057
- purpose: 'browser',
1058
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Syncing "browser" from "exports['.'].browser" ...`);
1059
- Reflect.set(fileContents, 'browser', currentPackageExports['.']['browser']);
1060
- }
1061
- else if (typeof packageBrowser === 'string'
1062
- && isPlainObject(currentPackageExports)
1063
- && typeof currentPackageExports['.'] === 'string') {
1064
- Logger.customize({
1065
- name: 'CLIRecipeSyncPackages.handleRuntime',
1066
- purpose: 'browser',
1067
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Normalizing "exports['.']" from string to object ...`);
1068
- Reflect.set(currentPackageExports, '.', {
1069
- default: currentPackageExports['.'],
1070
- browser: packageBrowser,
1071
- });
1072
- }
1073
- }
1074
- }
1075
- if (packageImports !== undefined
1076
- && !['config', 'app', 'package', 'tool'].includes(manifest.role)) {
1077
- Logger.customize({
1078
- name: 'CLIRecipeSyncPackages.handleRuntime',
1079
- purpose: 'imports',
1080
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "imports". Workspace role "${manifest.role}" does not allow it.`);
1081
- Reflect.deleteProperty(fileContents, 'imports');
1082
- }
1083
- }
1084
- static handleCorepack(workspace) {
1085
- const { fileContents, manifest } = workspace;
1086
- const packageManager = fileContents['packageManager'];
1087
- if (packageManager !== undefined
1088
- && manifest.role !== 'project') {
1089
- Logger.customize({
1090
- name: 'CLIRecipeSyncPackages.handleCorepack',
1091
- purpose: 'packageManager',
1092
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "packageManager". Workspace role "${manifest.role}" does not allow it.`);
1093
- Reflect.deleteProperty(fileContents, 'packageManager');
1094
- }
1095
- else {
1096
- if (manifest.role === 'project'
1097
- && packageManager !== undefined
1098
- && (typeof packageManager !== 'string'
1099
- || !PATTERN_NAME_AT_VERSION.test(packageManager))) {
1100
- Logger.customize({
1101
- name: 'CLIRecipeSyncPackages.handleCorepack',
1102
- purpose: 'packageManager',
1103
- }).warn(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "packageManager". Invalid format detected.`);
1104
- Reflect.deleteProperty(fileContents, 'packageManager');
1105
- }
1106
- }
1107
- }
1108
- static handleBundler(workspace) {
1109
- const { fileContents, manifest } = workspace;
1110
- const packageTypes = fileContents['types'];
1111
- const packageTypings = fileContents['typings'];
1112
- const packageModule = fileContents['module'];
1113
- const packageSideEffects = fileContents['sideEffects'];
1114
- const packageEsnext = fileContents['esnext'];
1115
- if (packageTypings !== undefined) {
1116
- if (packageTypes !== undefined) {
1117
- Logger.customize({
1118
- name: 'CLIRecipeSyncPackages.handleBundler',
1119
- purpose: 'typings',
1120
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Merging "typings" into "types". Keeping existing "types" value.`);
1121
- }
1122
- else {
1123
- Logger.customize({
1124
- name: 'CLIRecipeSyncPackages.handleBundler',
1125
- purpose: 'typings',
1126
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Renaming "typings" to "types" ...`);
1127
- Reflect.set(fileContents, 'types', packageTypings);
1128
- }
1129
- Reflect.deleteProperty(fileContents, 'typings');
1130
- }
1131
- const allowsTypesModule = ['config', 'package', 'tool'].includes(manifest.role);
1132
- const allowsSideEffectsEsnext = ['package'].includes(manifest.role);
1133
- if (fileContents['types'] !== undefined
1134
- && !allowsTypesModule) {
1135
- Logger.customize({
1136
- name: 'CLIRecipeSyncPackages.handleBundler',
1137
- purpose: 'types',
1138
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "types". Workspace role "${manifest.role}" does not allow it.`);
1139
- Reflect.deleteProperty(fileContents, 'types');
1140
- }
1141
- if (packageModule !== undefined
1142
- && !allowsTypesModule) {
1143
- Logger.customize({
1144
- name: 'CLIRecipeSyncPackages.handleBundler',
1145
- purpose: 'module',
1146
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "module". Workspace role "${manifest.role}" does not allow it.`);
1147
- Reflect.deleteProperty(fileContents, 'module');
1148
- }
1149
- if (packageSideEffects !== undefined
1150
- && !allowsSideEffectsEsnext) {
1151
- Logger.customize({
1152
- name: 'CLIRecipeSyncPackages.handleBundler',
1153
- purpose: 'sideEffects',
1154
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "sideEffects". Workspace role "${manifest.role}" does not allow it.`);
1155
- Reflect.deleteProperty(fileContents, 'sideEffects');
1156
- }
1157
- if (packageEsnext !== undefined
1158
- && !allowsSideEffectsEsnext) {
1159
- Logger.customize({
1160
- name: 'CLIRecipeSyncPackages.handleBundler',
1161
- purpose: 'esnext',
1162
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Removing "esnext". Workspace role "${manifest.role}" does not allow it.`);
1163
- Reflect.deleteProperty(fileContents, 'esnext');
1164
- }
1165
- }
1166
- static handleReorder(workspace) {
1167
- const { fileContents, manifest } = workspace;
1168
- const sortedKeys = new Set(itemPackageJsonSortOrder);
1169
- const currentKeys = Object.keys(fileContents);
1170
- const reordered = {};
1171
- for (const key of itemPackageJsonSortOrder) {
1172
- if (key in fileContents) {
1173
- reordered[key] = fileContents[key];
1174
- }
1175
- }
1176
- for (const key of currentKeys) {
1177
- if (!sortedKeys.has(key)) {
1178
- reordered[key] = fileContents[key];
1179
- }
1180
- }
1181
- const reorderedKeys = Object.keys(reordered);
1182
- if (currentKeys.every((key, index) => key === reorderedKeys[index])) {
1183
- return;
1184
- }
1185
- Logger.customize({
1186
- name: 'CLIRecipeSyncPackages.handleReorder',
1187
- purpose: 'reorder',
1188
- }).info(`${chalk.magenta(`"${manifest.name}" workspace`)} → Reordering "package.json" keys ...`);
1189
- for (const key of currentKeys) {
1190
- Reflect.deleteProperty(fileContents, key);
1191
- }
1192
- for (const [key, value] of Object.entries(reordered)) {
1193
- Reflect.set(fileContents, key, value);
1194
- }
1195
- }
1196
- static isEmpty(value) {
1197
- if (value === null || value === undefined) {
1198
- return true;
1199
- }
1200
- if (typeof value === 'string') {
1201
- return value.trim() === '';
1202
- }
1203
- if (Array.isArray(value)) {
1204
- return value.length === 0;
1205
- }
1206
- if (typeof value === 'object') {
1207
- return Object.keys(value).length === 0;
1208
- }
1209
- return false;
1210
- }
1211
- }
1212
- //# sourceMappingURL=sync-packages.js.map