boss-css 0.0.1 → 0.0.2

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 (268) hide show
  1. package/README.md +1 -0
  2. package/dist/_virtual/rolldown_runtime.cjs +43 -0
  3. package/dist/_virtual/rolldown_runtime.mjs +20 -0
  4. package/dist/api/browser.cjs +54 -0
  5. package/dist/api/browser.mjs +48 -0
  6. package/dist/api/config.cjs +94 -0
  7. package/dist/api/config.mjs +91 -0
  8. package/dist/api/css.cjs +304 -0
  9. package/dist/api/css.mjs +303 -0
  10. package/dist/api/dictionary.cjs +218 -0
  11. package/dist/api/dictionary.mjs +215 -0
  12. package/dist/api/file/dts.cjs +21 -0
  13. package/dist/api/file/dts.mjs +21 -0
  14. package/dist/api/file/file.cjs +123 -0
  15. package/dist/api/file/file.mjs +120 -0
  16. package/dist/api/file/js.cjs +118 -0
  17. package/dist/api/file/js.mjs +116 -0
  18. package/dist/api/names.cjs +52 -0
  19. package/dist/api/names.mjs +46 -0
  20. package/dist/api/noopCss.cjs +37 -0
  21. package/dist/api/noopCss.mjs +36 -0
  22. package/dist/api/propTree.cjs +54 -0
  23. package/dist/api/propTree.mjs +48 -0
  24. package/dist/api/server.cjs +112 -0
  25. package/dist/api/server.mjs +106 -0
  26. package/dist/cli/build.cjs +1 -0
  27. package/dist/cli/build.mjs +3 -0
  28. package/dist/cli/index.cjs +30 -0
  29. package/dist/cli/index.mjs +29 -0
  30. package/dist/cli/tasks/build.cjs +24 -0
  31. package/dist/cli/tasks/build.mjs +23 -0
  32. package/dist/cli/tasks/choose.cjs +47 -0
  33. package/dist/cli/tasks/choose.mjs +46 -0
  34. package/dist/cli/tasks/compile.cjs +68 -0
  35. package/dist/cli/tasks/compile.mjs +67 -0
  36. package/dist/cli/tasks/dev.cjs +51 -0
  37. package/dist/cli/tasks/dev.mjs +48 -0
  38. package/dist/cli/tasks/init.cjs +1835 -0
  39. package/dist/cli/tasks/init.mjs +1831 -0
  40. package/dist/cli/tasks/watch.cjs +38 -0
  41. package/dist/cli/tasks/watch.mjs +37 -0
  42. package/dist/cli/templates/init.cjs +82 -0
  43. package/dist/cli/templates/init.mjs +78 -0
  44. package/dist/cli/types.cjs +13 -0
  45. package/dist/cli/types.mjs +13 -0
  46. package/dist/cli/utils.cjs +43 -0
  47. package/dist/cli/utils.mjs +41 -0
  48. package/dist/compile/classname-strategy.cjs +79 -0
  49. package/dist/compile/classname-strategy.mjs +77 -0
  50. package/dist/compile/classname.cjs +366 -0
  51. package/dist/compile/classname.mjs +360 -0
  52. package/dist/compile/index.cjs +238 -0
  53. package/dist/compile/index.mjs +235 -0
  54. package/dist/compile/jsx.cjs +803 -0
  55. package/dist/compile/jsx.mjs +800 -0
  56. package/dist/compile/prepared.cjs +88 -0
  57. package/dist/compile/prepared.mjs +87 -0
  58. package/dist/compile/runtime.cjs +33 -0
  59. package/dist/compile/runtime.mjs +32 -0
  60. package/dist/compile/transform.cjs +371 -0
  61. package/dist/compile/transform.mjs +369 -0
  62. package/dist/cx/index.cjs +93 -0
  63. package/dist/cx/index.mjs +85 -0
  64. package/dist/detect-fw/index.cjs +384 -0
  65. package/dist/detect-fw/index.mjs +379 -0
  66. package/dist/dev/client.cjs +39 -0
  67. package/dist/dev/client.mjs +38 -0
  68. package/dist/dev/plugin/browser.cjs +11 -0
  69. package/dist/dev/plugin/browser.mjs +9 -0
  70. package/dist/dev/plugin/server.cjs +86 -0
  71. package/dist/dev/plugin/server.mjs +78 -0
  72. package/dist/dev/port.cjs +46 -0
  73. package/dist/dev/port.mjs +43 -0
  74. package/dist/dev/runtime.cjs +28 -0
  75. package/dist/dev/runtime.mjs +29 -0
  76. package/dist/dev/server.cjs +808 -0
  77. package/dist/dev/server.mjs +805 -0
  78. package/dist/dev/shared.cjs +6 -0
  79. package/dist/dev/shared.mjs +5 -0
  80. package/dist/eslint-plugin/index.cjs +66 -0
  81. package/dist/eslint-plugin/index.mjs +66 -0
  82. package/dist/eslint-plugin/rules/classnames-only.cjs +68 -0
  83. package/dist/eslint-plugin/rules/classnames-only.mjs +68 -0
  84. package/dist/eslint-plugin/rules/format-classnames.cjs +137 -0
  85. package/dist/eslint-plugin/rules/format-classnames.mjs +136 -0
  86. package/dist/eslint-plugin/rules/no-unknown-classes.cjs +119 -0
  87. package/dist/eslint-plugin/rules/no-unknown-classes.mjs +119 -0
  88. package/dist/eslint-plugin/rules/prefer-classnames.cjs +69 -0
  89. package/dist/eslint-plugin/rules/prefer-classnames.mjs +69 -0
  90. package/dist/eslint-plugin/rules/prefer-token-values.cjs +197 -0
  91. package/dist/eslint-plugin/rules/prefer-token-values.mjs +197 -0
  92. package/dist/eslint-plugin/rules/props-only.cjs +115 -0
  93. package/dist/eslint-plugin/rules/props-only.mjs +115 -0
  94. package/dist/eslint-plugin/rules/redundant-cx.cjs +66 -0
  95. package/dist/eslint-plugin/rules/redundant-cx.mjs +66 -0
  96. package/dist/eslint-plugin/rules/require-prop-functions.cjs +130 -0
  97. package/dist/eslint-plugin/rules/require-prop-functions.mjs +130 -0
  98. package/dist/eslint-plugin/utils/api.cjs +30 -0
  99. package/dist/eslint-plugin/utils/api.mjs +29 -0
  100. package/dist/eslint-plugin/utils/ast.cjs +119 -0
  101. package/dist/eslint-plugin/utils/ast.mjs +112 -0
  102. package/dist/eslint-plugin/utils/boss-classes.cjs +185 -0
  103. package/dist/eslint-plugin/utils/boss-classes.mjs +175 -0
  104. package/dist/eslint-plugin/utils/defaults.cjs +99 -0
  105. package/dist/eslint-plugin/utils/defaults.mjs +93 -0
  106. package/dist/eslint-plugin/utils/format.cjs +20 -0
  107. package/dist/eslint-plugin/utils/format.mjs +19 -0
  108. package/dist/eslint-plugin/utils/order.cjs +76 -0
  109. package/dist/eslint-plugin/utils/order.mjs +76 -0
  110. package/dist/eslint-plugin/utils/property-order.cjs +449 -0
  111. package/dist/eslint-plugin/utils/property-order.mjs +448 -0
  112. package/dist/eslint-plugin/utils/static.cjs +36 -0
  113. package/dist/eslint-plugin/utils/static.mjs +35 -0
  114. package/dist/fontsource/directory.cjs +39588 -0
  115. package/dist/fontsource/directory.mjs +39587 -0
  116. package/dist/fontsource/server.cjs +291 -0
  117. package/dist/fontsource/server.mjs +282 -0
  118. package/dist/index.cjs +10 -0
  119. package/dist/index.mjs +6 -0
  120. package/dist/log/browser.cjs +28 -0
  121. package/dist/log/browser.mjs +28 -0
  122. package/dist/log/server.cjs +32 -0
  123. package/dist/log/server.mjs +30 -0
  124. package/dist/merge/index.cjs +590 -0
  125. package/dist/merge/index.mjs +586 -0
  126. package/dist/native/browser.cjs +78 -0
  127. package/dist/native/browser.mjs +77 -0
  128. package/dist/native/server.cjs +180 -0
  129. package/dist/native/server.mjs +176 -0
  130. package/dist/native/styleTypes.cjs +168 -0
  131. package/dist/native/styleTypes.mjs +164 -0
  132. package/dist/parser/classname/server.cjs +239 -0
  133. package/dist/parser/classname/server.mjs +232 -0
  134. package/dist/parser/jsx/browser.cjs +66 -0
  135. package/dist/parser/jsx/browser.mjs +63 -0
  136. package/dist/parser/jsx/extractCode.cjs +99 -0
  137. package/dist/parser/jsx/extractCode.mjs +98 -0
  138. package/dist/parser/jsx/extractPrepared.cjs +123 -0
  139. package/dist/parser/jsx/extractPrepared.mjs +122 -0
  140. package/dist/parser/jsx/extractProps.cjs +234 -0
  141. package/dist/parser/jsx/extractProps.mjs +232 -0
  142. package/dist/parser/jsx/isDOMProp.cjs +17 -0
  143. package/dist/parser/jsx/isDOMProp.mjs +15 -0
  144. package/dist/parser/jsx/native.cjs +110 -0
  145. package/dist/parser/jsx/native.mjs +108 -0
  146. package/dist/parser/jsx/runtime.cjs +4 -0
  147. package/dist/parser/jsx/runtime.mjs +3 -0
  148. package/dist/parser/jsx/server.cjs +278 -0
  149. package/dist/parser/jsx/server.mjs +268 -0
  150. package/dist/postcss/index.cjs +16 -0
  151. package/dist/postcss/index.mjs +16 -0
  152. package/dist/prop/at/runtime-only.cjs +90 -0
  153. package/dist/prop/at/runtime-only.mjs +88 -0
  154. package/dist/prop/at/server.cjs +282 -0
  155. package/dist/prop/at/server.mjs +268 -0
  156. package/dist/prop/at/shared.cjs +153 -0
  157. package/dist/prop/at/shared.mjs +144 -0
  158. package/dist/prop/bosswind/browser.cjs +18 -0
  159. package/dist/prop/bosswind/browser.mjs +16 -0
  160. package/dist/prop/bosswind/runtime-only.cjs +18 -0
  161. package/dist/prop/bosswind/runtime-only.mjs +16 -0
  162. package/dist/prop/bosswind/server.cjs +81 -0
  163. package/dist/prop/bosswind/server.mjs +72 -0
  164. package/dist/prop/bosswind/shared.cjs +861 -0
  165. package/dist/prop/bosswind/shared.mjs +855 -0
  166. package/dist/prop/bosswind/tailwind-theme.cjs +703 -0
  167. package/dist/prop/bosswind/tailwind-theme.mjs +702 -0
  168. package/dist/prop/child/runtime-only.cjs +18 -0
  169. package/dist/prop/child/runtime-only.mjs +15 -0
  170. package/dist/prop/child/server.cjs +81 -0
  171. package/dist/prop/child/server.mjs +72 -0
  172. package/dist/prop/css/getDtsTemplate.cjs +65 -0
  173. package/dist/prop/css/getDtsTemplate.mjs +63 -0
  174. package/dist/prop/css/runtime-only.cjs +14 -0
  175. package/dist/prop/css/runtime-only.mjs +13 -0
  176. package/dist/prop/css/server.cjs +99 -0
  177. package/dist/prop/css/server.mjs +90 -0
  178. package/dist/prop/pseudo/runtime-only.cjs +23 -0
  179. package/dist/prop/pseudo/runtime-only.mjs +21 -0
  180. package/dist/prop/pseudo/server.cjs +91 -0
  181. package/dist/prop/pseudo/server.mjs +82 -0
  182. package/dist/prop/pseudo/shared.cjs +61 -0
  183. package/dist/prop/pseudo/shared.mjs +60 -0
  184. package/dist/reset/server.cjs +34 -0
  185. package/dist/reset/server.mjs +26 -0
  186. package/dist/runtime/index.cjs +119 -0
  187. package/dist/runtime/index.mjs +118 -0
  188. package/dist/runtime/preact.cjs +4 -0
  189. package/dist/runtime/preact.mjs +3 -0
  190. package/dist/runtime/qwik.cjs +21 -0
  191. package/dist/runtime/qwik.mjs +18 -0
  192. package/dist/runtime/react.cjs +4 -0
  193. package/dist/runtime/react.mjs +3 -0
  194. package/dist/runtime/solid.cjs +15 -0
  195. package/dist/runtime/solid.mjs +14 -0
  196. package/dist/runtime/stencil.cjs +25 -0
  197. package/dist/runtime/stencil.mjs +21 -0
  198. package/dist/runtime/style.cjs +14 -0
  199. package/dist/runtime/style.mjs +13 -0
  200. package/dist/shared/boundaries.cjs +288 -0
  201. package/dist/shared/boundaries.mjs +285 -0
  202. package/dist/shared/customCss.cjs +212 -0
  203. package/dist/shared/customCss.mjs +211 -0
  204. package/dist/shared/debug.cjs +76 -0
  205. package/dist/shared/debug.mjs +74 -0
  206. package/dist/shared/file.cjs +21 -0
  207. package/dist/shared/file.mjs +19 -0
  208. package/dist/shared/framework.cjs +10 -0
  209. package/dist/shared/framework.mjs +9 -0
  210. package/dist/shared/json.cjs +58 -0
  211. package/dist/shared/json.mjs +57 -0
  212. package/dist/shared/types.cjs +11 -0
  213. package/dist/shared/types.mjs +10 -0
  214. package/dist/strategy/classic/runtime-only.cjs +190 -0
  215. package/dist/strategy/classic/runtime-only.mjs +186 -0
  216. package/dist/strategy/classname-first/runtime-only.cjs +138 -0
  217. package/dist/strategy/classname-first/runtime-only.mjs +134 -0
  218. package/dist/strategy/classname-first/server.cjs +139 -0
  219. package/dist/strategy/classname-first/server.mjs +133 -0
  220. package/dist/strategy/classname-only/server.cjs +43 -0
  221. package/dist/strategy/classname-only/server.mjs +35 -0
  222. package/dist/strategy/inline-first/browser.cjs +61 -0
  223. package/dist/strategy/inline-first/browser.mjs +58 -0
  224. package/dist/strategy/inline-first/runtime-only.cjs +159 -0
  225. package/dist/strategy/inline-first/runtime-only.mjs +155 -0
  226. package/dist/strategy/inline-first/server.cjs +92 -0
  227. package/dist/strategy/inline-first/server.mjs +83 -0
  228. package/dist/strategy/runtime/runtime-only.cjs +24 -0
  229. package/dist/strategy/runtime/runtime-only.mjs +22 -0
  230. package/dist/strategy/runtime/server.cjs +72 -0
  231. package/dist/strategy/runtime/server.mjs +63 -0
  232. package/dist/strategy/runtime-only/css.cjs +183 -0
  233. package/dist/strategy/runtime-only/css.mjs +181 -0
  234. package/dist/tasks/build.cjs +88 -0
  235. package/dist/tasks/build.mjs +84 -0
  236. package/dist/tasks/compile.cjs +12 -0
  237. package/dist/tasks/compile.mjs +12 -0
  238. package/dist/tasks/postcss.cjs +116 -0
  239. package/dist/tasks/postcss.mjs +113 -0
  240. package/dist/tasks/session.cjs +46 -0
  241. package/dist/tasks/session.mjs +42 -0
  242. package/dist/tasks/watch.cjs +102 -0
  243. package/dist/tasks/watch.mjs +99 -0
  244. package/dist/transform/cache.cjs +24 -0
  245. package/dist/transform/cache.mjs +21 -0
  246. package/dist/transform/processFile.cjs +26 -0
  247. package/dist/transform/processFile.mjs +24 -0
  248. package/dist/use/token/browser.cjs +65 -0
  249. package/dist/use/token/browser.mjs +61 -0
  250. package/dist/use/token/runtime-only.cjs +245 -0
  251. package/dist/use/token/runtime-only.mjs +239 -0
  252. package/dist/use/token/server.cjs +325 -0
  253. package/dist/use/token/server.mjs +313 -0
  254. package/dist/use/token/vars.cjs +47 -0
  255. package/dist/use/token/vars.mjs +46 -0
  256. package/package.json +300 -4
  257. package/src/api/config.d.ts +1 -0
  258. package/src/fontsource/types.d.ts +50 -0
  259. package/src/packages/document-create-element/createElement.browser.js +3 -0
  260. package/src/packages/document-create-element/createElement.js +7 -0
  261. package/src/packages/document-create-element/package.json +17 -0
  262. package/src/packages/is-css-prop/browser.js +13 -0
  263. package/src/packages/is-css-prop/index.js +13 -0
  264. package/src/packages/is-css-prop/package-lock.json +52 -0
  265. package/src/packages/is-css-prop/package.json +17 -0
  266. package/src/prop/css/csstype.json +4387 -0
  267. package/src/prop/css/package.json +3 -0
  268. package/src/reset/reset.css +259 -0
@@ -0,0 +1,1835 @@
1
+ const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
2
+ const require_api_server = require('../../api/server.cjs');
3
+ const require_json = require('../../shared/json.cjs');
4
+ const require_utils = require('../utils.cjs');
5
+ const require_detect_fw_index = require('../../detect-fw/index.cjs');
6
+ const require_parser_jsx_server = require('../../parser/jsx/server.cjs');
7
+ const require_parser_classname_server = require('../../parser/classname/server.cjs');
8
+ const require_prop_pseudo_server = require('../../prop/pseudo/server.cjs');
9
+ const require_prop_at_server = require('../../prop/at/server.cjs');
10
+ const require_prop_child_server = require('../../prop/child/server.cjs');
11
+ const require_prop_css_server = require('../../prop/css/server.cjs');
12
+ const require_prop_bosswind_server = require('../../prop/bosswind/server.cjs');
13
+ const require_strategy_inline_first_server = require('../../strategy/inline-first/server.cjs');
14
+ const require_server = require('../../strategy/classname-first/server.cjs');
15
+ const require_strategy_runtime_server = require('../../strategy/runtime/server.cjs');
16
+ const require_strategy_classname_only_server = require('../../strategy/classname-only/server.cjs');
17
+ const require_reset_server = require('../../reset/server.cjs');
18
+ const require_fontsource_server = require('../../fontsource/server.cjs');
19
+ const require_use_token_server = require('../../use/token/server.cjs');
20
+ const require_dev_plugin_server = require('../../dev/plugin/server.cjs');
21
+ const require_init = require('../templates/init.cjs');
22
+ const require_types = require('../../shared/types.cjs');
23
+ const require_types$1 = require('../types.cjs');
24
+ let node_fs_promises = require("node:fs/promises");
25
+ node_fs_promises = require_rolldown_runtime.__toESM(node_fs_promises);
26
+ let node_path = require("node:path");
27
+ node_path = require_rolldown_runtime.__toESM(node_path);
28
+ let _clack_prompts = require("@clack/prompts");
29
+ let pluvo = require("pluvo");
30
+ pluvo = require_rolldown_runtime.__toESM(pluvo);
31
+
32
+ //#region src/cli/tasks/init.ts
33
+ const EXTENSIONS = "html,js,jsx,mjs,cjs,ts,tsx,mdx,md";
34
+ const INIT_COMMENT_STYLES = {
35
+ line: pluvo.DEFAULT_COMMENT_STYLES.line.filter((marker) => !("value" in marker) || marker.value !== "'"),
36
+ block: pluvo.DEFAULT_COMMENT_STYLES.block
37
+ };
38
+ const AVAILABLE_PLUGINS = [
39
+ {
40
+ id: "fontsource",
41
+ label: "Fontsource fonts",
42
+ importName: "fontsource",
43
+ importPath: "boss-css/fontsource/server",
44
+ defaultEnabled: true
45
+ },
46
+ {
47
+ id: "reset",
48
+ label: "Reset CSS",
49
+ importName: "reset",
50
+ importPath: "boss-css/reset/server",
51
+ defaultEnabled: true
52
+ },
53
+ {
54
+ id: "bosswind",
55
+ label: "Bosswind (Tailwind-style aliases)",
56
+ importName: "bosswind",
57
+ importPath: "boss-css/prop/bosswind/server",
58
+ defaultEnabled: false
59
+ },
60
+ {
61
+ id: "token",
62
+ label: "Tokens",
63
+ importName: "token",
64
+ importPath: "boss-css/use/token/server",
65
+ defaultEnabled: true
66
+ },
67
+ {
68
+ id: "at",
69
+ label: "Media queries (@at)",
70
+ importName: "at",
71
+ importPath: "boss-css/prop/at/server",
72
+ defaultEnabled: true
73
+ },
74
+ {
75
+ id: "child",
76
+ label: "Child selectors",
77
+ importName: "child",
78
+ importPath: "boss-css/prop/child/server",
79
+ defaultEnabled: true
80
+ },
81
+ {
82
+ id: "css",
83
+ label: "CSS props",
84
+ importName: "css",
85
+ importPath: "boss-css/prop/css/server",
86
+ defaultEnabled: true
87
+ },
88
+ {
89
+ id: "pseudo",
90
+ label: "Pseudo selectors",
91
+ importName: "pseudo",
92
+ importPath: "boss-css/prop/pseudo/server",
93
+ defaultEnabled: true
94
+ },
95
+ {
96
+ id: "classname",
97
+ label: "Classname parser",
98
+ importName: "classname",
99
+ importPath: "boss-css/parser/classname/server",
100
+ defaultEnabled: true
101
+ },
102
+ {
103
+ id: "jsx",
104
+ label: "JSX parser",
105
+ importName: "jsx",
106
+ importPath: "boss-css/parser/jsx/server",
107
+ defaultEnabled: true
108
+ },
109
+ {
110
+ id: "devtools",
111
+ label: "Devtools (experimental)",
112
+ importName: "devtools",
113
+ importPath: "boss-css/dev/plugin/server",
114
+ defaultEnabled: false
115
+ }
116
+ ];
117
+ const AVAILABLE_STRATEGIES = [
118
+ {
119
+ id: "inline-first",
120
+ label: "Inline-first strategy",
121
+ importName: "inlineFirst",
122
+ importPath: "boss-css/strategy/inline-first/server",
123
+ defaultEnabled: true
124
+ },
125
+ {
126
+ id: "classname-first",
127
+ label: "Classname-first strategy",
128
+ importName: "classnameFirst",
129
+ importPath: "boss-css/strategy/classname-first/server",
130
+ defaultEnabled: false
131
+ },
132
+ {
133
+ id: "classname-only",
134
+ label: "Classname-only strategy (no runtime)",
135
+ importName: "classnameOnly",
136
+ importPath: "boss-css/strategy/classname-only/server",
137
+ defaultEnabled: false
138
+ },
139
+ {
140
+ id: "runtime-only",
141
+ label: "Runtime-only strategy (client CSS only)",
142
+ importName: "runtime",
143
+ importPath: "boss-css/strategy/runtime/server",
144
+ defaultEnabled: false
145
+ },
146
+ {
147
+ id: "runtime-hybrid",
148
+ label: "Runtime hybrid strategy (server + client)",
149
+ importName: "runtime",
150
+ importPath: "boss-css/strategy/runtime/server",
151
+ defaultEnabled: false
152
+ }
153
+ ];
154
+ const PLUGIN_MODULES = {
155
+ bosswind: require_prop_bosswind_server.server_exports,
156
+ reset: require_reset_server.server_exports,
157
+ fontsource: require_fontsource_server.server_exports,
158
+ token: require_use_token_server.server_exports,
159
+ at: require_prop_at_server.server_exports,
160
+ child: require_prop_child_server.server_exports,
161
+ css: require_prop_css_server.server_exports,
162
+ pseudo: require_prop_pseudo_server.server_exports,
163
+ classname: require_parser_classname_server.server_exports,
164
+ jsx: require_parser_jsx_server.server_exports,
165
+ "inline-first": require_strategy_inline_first_server.server_exports,
166
+ "classname-first": require_server.server_exports,
167
+ "classname-only": require_strategy_classname_only_server.server_exports,
168
+ "runtime-only": require_strategy_runtime_server.server_exports,
169
+ "runtime-hybrid": require_strategy_runtime_server.server_exports,
170
+ devtools: require_dev_plugin_server.server_exports
171
+ };
172
+ const DEFAULT_PLUGIN_IDS = AVAILABLE_PLUGINS.filter((plugin) => plugin.defaultEnabled).map((plugin) => plugin.id);
173
+ const DEFAULT_STRATEGY_ID = AVAILABLE_STRATEGIES.find((strategy) => strategy.defaultEnabled)?.id ?? "inline-first";
174
+ const STRATEGY_IDS = new Set(AVAILABLE_STRATEGIES.map((strategy) => strategy.id));
175
+ const STRATEGY_ALIASES = new Map([
176
+ ["runtime", "runtime-only"],
177
+ ["hybrid", "runtime-hybrid"],
178
+ ["runtime-hybrid", "runtime-hybrid"],
179
+ ["runtime-only", "runtime-only"]
180
+ ]);
181
+ const POSTCSS_CONFIG_FILES = [
182
+ "postcss.config.js",
183
+ "postcss.config.cjs",
184
+ "postcss.config.mjs",
185
+ ".postcssrc",
186
+ ".postcssrc.json",
187
+ ".postcssrc.js",
188
+ ".postcssrc.cjs",
189
+ ".postcssrc.mjs"
190
+ ];
191
+ const ESLINT_CONFIG_FILES = [
192
+ {
193
+ file: "eslint.config.js",
194
+ type: "flat"
195
+ },
196
+ {
197
+ file: "eslint.config.cjs",
198
+ type: "flat"
199
+ },
200
+ {
201
+ file: "eslint.config.mjs",
202
+ type: "flat"
203
+ },
204
+ {
205
+ file: ".eslintrc",
206
+ type: "eslintrc"
207
+ },
208
+ {
209
+ file: ".eslintrc.json",
210
+ type: "eslintrc"
211
+ },
212
+ {
213
+ file: ".eslintrc.js",
214
+ type: "eslintrc-js"
215
+ },
216
+ {
217
+ file: ".eslintrc.cjs",
218
+ type: "eslintrc-js"
219
+ },
220
+ {
221
+ file: ".eslintrc.mjs",
222
+ type: "eslintrc-js"
223
+ },
224
+ {
225
+ file: ".eslintrc.yaml",
226
+ type: "yaml"
227
+ },
228
+ {
229
+ file: ".eslintrc.yml",
230
+ type: "yaml"
231
+ }
232
+ ];
233
+ const init = async (config) => {
234
+ return [{ prompt: async () => {
235
+ _clack_prompts.log.info("boss init will scaffold configuration for this project.");
236
+ const cwd = process.cwd();
237
+ const { data: packageJson, indent, newline } = await readPackageJson(cwd);
238
+ if (!packageJson) {
239
+ _clack_prompts.log.error("No package.json found. Run boss init from a project root.");
240
+ return false;
241
+ }
242
+ const flags = parseFlags(config.argv);
243
+ const isNext = hasDependency(packageJson, "next");
244
+ const framework = await require_detect_fw_index.detectFramework({
245
+ cwd,
246
+ packageJson
247
+ });
248
+ const isStencil = framework.id === "stencil";
249
+ const cssAutoLoad = !isStencil;
250
+ const detectedSrcRoot = await detectSrcRoot(cwd);
251
+ const normalizedSrcRoot = normalizeRelativePath(await resolveTextValue({
252
+ label: "Where is your source root?",
253
+ value: flags.srcRoot,
254
+ fallback: detectedSrcRoot,
255
+ yes: flags.yes
256
+ }), cwd);
257
+ const defaultConfigFolder = ".bo$$";
258
+ const defaultConfigDir = normalizeRelativePath(node_path.default.join(normalizedSrcRoot, defaultConfigFolder), cwd);
259
+ const normalizedConfigDir = normalizeRelativePath(await resolveTextValue({
260
+ label: `Where should the ${defaultConfigFolder} folder live?`,
261
+ value: flags.configDir,
262
+ fallback: defaultConfigDir,
263
+ yes: flags.yes
264
+ }), cwd);
265
+ const configFolder = formatConfigFolder(normalizedConfigDir);
266
+ const selectedStrategyId = await resolveStrategySelection({
267
+ value: flags.strategy,
268
+ plugins: flags.plugins,
269
+ yes: flags.yes
270
+ });
271
+ const selectedPluginIds = await resolvePluginSelection({
272
+ value: flags.plugins,
273
+ yes: flags.yes,
274
+ frameworkId: framework.id,
275
+ selectedStrategyId
276
+ });
277
+ const postcssDetection = await detectPostcss(cwd, packageJson);
278
+ const postcssMode = isStencil ? "skip" : await resolvePostcssMode({
279
+ detection: postcssDetection,
280
+ yes: flags.yes,
281
+ value: flags.postcss
282
+ });
283
+ const globalsEnabled = selectedStrategyId === "classname-only" ? false : await resolveGlobalsEnabled({
284
+ value: flags.globals,
285
+ yes: flags.yes
286
+ });
287
+ const eslintDetection = await detectEslint(cwd, packageJson);
288
+ const shouldConfigureEslint = eslintDetection.hasDependency || eslintDetection.hasConfig || flags.eslintPlugin !== void 0;
289
+ const useEslintPlugin = await resolveEslintPlugin({
290
+ value: flags.eslintPlugin,
291
+ yes: flags.yes,
292
+ enabled: shouldConfigureEslint
293
+ });
294
+ const outputDir = node_path.default.resolve(cwd, normalizedConfigDir);
295
+ if (!await confirmOverwriteIfExists(outputDir, flags.yes)) return false;
296
+ const contentGlobs = buildContentGlobs({
297
+ srcRoot: normalizedSrcRoot,
298
+ isNext
299
+ });
300
+ const pluginState = buildPluginState({
301
+ selectedPluginIds,
302
+ selectedStrategyId
303
+ });
304
+ const packageUpdate = updatePackageJson(packageJson, {
305
+ configDir: normalizedConfigDir,
306
+ srcRoot: normalizedSrcRoot,
307
+ addBossCss: true,
308
+ bossCssVersion: await resolveBossCssVersion(),
309
+ addPostcss: postcssMode === "auto" && !postcssDetection.hasDependency,
310
+ includePostcssPlugin: postcssMode === "auto" && (postcssDetection.hasPackageConfig || !postcssDetection.hasConfigFile),
311
+ addEslintPlugin: useEslintPlugin === true
312
+ });
313
+ let packageData = packageUpdate.data;
314
+ let eslintUpdated = false;
315
+ let packageJsonChanged = packageUpdate.changed;
316
+ if (shouldConfigureEslint && (globalsEnabled || useEslintPlugin !== void 0)) {
317
+ const eslintUpdate = await configureEslint({
318
+ detection: eslintDetection,
319
+ globalsEnabled,
320
+ useEslintPlugin: useEslintPlugin === true,
321
+ allowReactGlobalsRule: shouldAllowReactGlobalsRule(packageData),
322
+ packageJson: packageData
323
+ });
324
+ eslintUpdated = eslintUpdate.updated;
325
+ if (eslintUpdate.packageJsonChanged) {
326
+ packageData = eslintUpdate.packageJson;
327
+ packageJsonChanged = true;
328
+ }
329
+ }
330
+ if (packageJsonChanged) await writePackageJson(cwd, packageData, indent, newline);
331
+ await writeInitFiles({
332
+ outputDir,
333
+ configFolder,
334
+ contentGlobs,
335
+ pluginState,
336
+ selectedStrategyId,
337
+ isNext,
338
+ postcssMode,
339
+ postcssDetection,
340
+ includeAutoprefixer: hasDependency(packageJson, "autoprefixer"),
341
+ packageJson: packageData,
342
+ dirDependencies: true,
343
+ usePostcssOptions: false,
344
+ srcRoot: normalizedSrcRoot,
345
+ configDir: normalizedConfigDir,
346
+ globalsEnabled,
347
+ cssAutoLoad
348
+ });
349
+ await generateRuntime({
350
+ outputDir,
351
+ configFolder,
352
+ pluginState,
353
+ contentGlobs,
354
+ globalsEnabled,
355
+ cssAutoLoad,
356
+ selectedStrategyId
357
+ });
358
+ if (isStencil) await ensureStencilSetup({
359
+ cwd,
360
+ srcRoot: normalizedSrcRoot,
361
+ configDir: normalizedConfigDir,
362
+ packageJson: packageData
363
+ });
364
+ const packageManager = await detectPackageManager(cwd, config.runtimeType);
365
+ const installCommand = packageUpdate.bossCssAdded ? formatInstallCommand(packageManager) : null;
366
+ logInitSummary({
367
+ configDir: normalizedConfigDir,
368
+ isNext,
369
+ postcssMode,
370
+ postcssDetection,
371
+ configFolder,
372
+ srcRoot: normalizedSrcRoot,
373
+ globalsEnabled,
374
+ eslintUpdated,
375
+ useEslintPlugin: useEslintPlugin === true,
376
+ frameworkId: framework.id,
377
+ selectedStrategyId,
378
+ cssAutoLoad,
379
+ installCommand
380
+ });
381
+ return true;
382
+ } }];
383
+ };
384
+ const resolveTextValue = async ({ label, value, fallback, yes }) => {
385
+ if (value) return value;
386
+ if (yes) return fallback;
387
+ const response = await (0, _clack_prompts.text)({
388
+ message: label,
389
+ initialValue: fallback,
390
+ validate: (input) => input?.trim() ? void 0 : "Value is required"
391
+ });
392
+ require_utils.cancelIf(response);
393
+ return response;
394
+ };
395
+ const resolveStrategySelection = async ({ value, plugins, yes }) => {
396
+ const normalizedValue = value ? normalizeStrategyId(value) : void 0;
397
+ if (normalizedValue) {
398
+ if (STRATEGY_IDS.has(normalizedValue)) return normalizedValue;
399
+ _clack_prompts.log.warn(`Unknown strategy "${value}". Falling back to the default strategy.`);
400
+ }
401
+ const pluginStrategies = (plugins ?? []).map(normalizeStrategyId).filter((id) => STRATEGY_IDS.has(id));
402
+ if (pluginStrategies.length > 1) {
403
+ _clack_prompts.log.warn(`Multiple strategies provided (${pluginStrategies.join(", ")}). Using "${pluginStrategies[0]}".`);
404
+ return pluginStrategies[0];
405
+ }
406
+ if (pluginStrategies.length === 1) return pluginStrategies[0];
407
+ if (yes) return DEFAULT_STRATEGY_ID;
408
+ const selection = await (0, _clack_prompts.select)({
409
+ message: "Select output strategy.",
410
+ options: AVAILABLE_STRATEGIES.map((strategy) => ({
411
+ value: strategy.id,
412
+ label: strategy.label
413
+ })),
414
+ initialValue: DEFAULT_STRATEGY_ID
415
+ });
416
+ require_utils.cancelIf(selection);
417
+ return selection;
418
+ };
419
+ const resolvePluginSelection = async ({ value, yes, frameworkId, selectedStrategyId }) => {
420
+ const isClassnameOnly = selectedStrategyId === "classname-only";
421
+ const disallowedPlugins = isClassnameOnly ? new Set(["jsx", "devtools"]) : null;
422
+ const defaults = isClassnameOnly ? DEFAULT_PLUGIN_IDS.filter((id) => !(disallowedPlugins && disallowedPlugins.has(id))) : DEFAULT_PLUGIN_IDS;
423
+ if (value?.length) {
424
+ const normalized = value.map(normalizePluginId);
425
+ const filtered = normalized.filter((id) => !STRATEGY_IDS.has(id));
426
+ if (filtered.length !== normalized.length) _clack_prompts.log.info("Strategies are selected separately. Use --strategy to choose the output strategy.");
427
+ const selected = filtered.filter((id) => AVAILABLE_PLUGINS.some((plugin) => plugin.id === id));
428
+ const allowed = disallowedPlugins ? selected.filter((id) => !disallowedPlugins.has(id)) : selected;
429
+ if (selected.length && disallowedPlugins && allowed.length !== selected.length) _clack_prompts.log.warn("Classname-only strategy ignores jsx and devtools plugins.");
430
+ if (!allowed.length) {
431
+ _clack_prompts.log.warn("No matching plugins found for the provided flags. Falling back to defaults.");
432
+ return defaults;
433
+ }
434
+ return allowed;
435
+ }
436
+ if (yes) return defaults;
437
+ const selection = await (0, _clack_prompts.multiselect)({
438
+ message: "Select Boss CSS plugins and features.",
439
+ options: (disallowedPlugins ? AVAILABLE_PLUGINS.filter((plugin) => !disallowedPlugins.has(plugin.id)) : AVAILABLE_PLUGINS).map((plugin) => ({
440
+ value: plugin.id,
441
+ label: plugin.label
442
+ })),
443
+ initialValues: defaults
444
+ });
445
+ require_utils.cancelIf(selection);
446
+ return selection;
447
+ };
448
+ const buildPluginState = ({ selectedPluginIds, selectedStrategyId }) => {
449
+ const disallowedPlugins = selectedStrategyId === "classname-only" ? new Set(["jsx", "devtools"]) : null;
450
+ const pluginState = AVAILABLE_PLUGINS.map((plugin) => ({
451
+ ...plugin,
452
+ enabled: selectedPluginIds.includes(plugin.id) && !(disallowedPlugins && disallowedPlugins.has(plugin.id))
453
+ }));
454
+ const strategyState = {
455
+ ...AVAILABLE_STRATEGIES.find((strategy) => strategy.id === selectedStrategyId) ?? AVAILABLE_STRATEGIES[0],
456
+ enabled: true
457
+ };
458
+ const devtoolsIndex = pluginState.findIndex((plugin) => plugin.id === "devtools");
459
+ if (devtoolsIndex === -1) return [...pluginState, strategyState];
460
+ return [
461
+ ...pluginState.slice(0, devtoolsIndex),
462
+ strategyState,
463
+ ...pluginState.slice(devtoolsIndex)
464
+ ];
465
+ };
466
+ const normalizePluginId = (id) => {
467
+ return id.trim().replace(/_/g, "-").replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
468
+ };
469
+ const normalizeStrategyId = (id) => {
470
+ const normalized = normalizePluginId(id);
471
+ return STRATEGY_ALIASES.get(normalized) ?? normalized;
472
+ };
473
+ const resolvePostcssMode = async ({ detection, yes, value }) => {
474
+ if (value) return value;
475
+ if (detection.hasDependency || detection.hasConfigFile || detection.hasPackageConfig) return "auto";
476
+ if (yes) return "auto";
477
+ const shouldInstall = await (0, _clack_prompts.confirm)({
478
+ message: "PostCSS was not detected. Install and configure it automatically?",
479
+ initialValue: true
480
+ });
481
+ require_utils.cancelIf(shouldInstall);
482
+ return shouldInstall ? "auto" : "manual";
483
+ };
484
+ const resolveGlobalsEnabled = async ({ value, yes }) => {
485
+ if (value !== void 0) return value;
486
+ if (yes) return true;
487
+ const enableGlobals = await (0, _clack_prompts.confirm)({
488
+ message: "Enable global $$ (no import needed)?",
489
+ initialValue: true
490
+ });
491
+ require_utils.cancelIf(enableGlobals);
492
+ return enableGlobals;
493
+ };
494
+ const resolveEslintPlugin = async ({ value, yes, enabled }) => {
495
+ if (!enabled && value === void 0) return void 0;
496
+ if (value !== void 0) return value;
497
+ if (yes) return true;
498
+ const usePlugin = await (0, _clack_prompts.confirm)({
499
+ message: "Use the Boss ESLint plugin for Boss-specific linting?",
500
+ initialValue: true
501
+ });
502
+ require_utils.cancelIf(usePlugin);
503
+ return usePlugin;
504
+ };
505
+ const parseFlags = (argv) => {
506
+ return {
507
+ yes: argv.y === true || argv.yes === true,
508
+ srcRoot: getStringArg(argv, ["srcRoot", "src-root"]),
509
+ configDir: getStringArg(argv, [
510
+ "configDir",
511
+ "config-dir",
512
+ "bossDir",
513
+ "boss-dir"
514
+ ]),
515
+ plugins: parseListArg(getArg(argv, ["plugins", "plugin"])),
516
+ strategy: getStringArg(argv, ["strategy"]),
517
+ postcss: normalizePostcssMode(getArg(argv, ["postcss"])) ?? void 0,
518
+ globals: normalizeBooleanArg(getArg(argv, ["globals"])),
519
+ eslintPlugin: normalizeBooleanArg(getArg(argv, ["eslintPlugin", "eslint-plugin"]))
520
+ };
521
+ };
522
+ const getArg = (argv, keys) => {
523
+ for (const key of keys) if (Object.prototype.hasOwnProperty.call(argv, key)) return argv[key];
524
+ };
525
+ const getStringArg = (argv, keys) => {
526
+ const value = getArg(argv, keys);
527
+ if (typeof value === "string" && value.trim()) return value.trim();
528
+ };
529
+ const normalizeBooleanArg = (value) => {
530
+ if (typeof value === "boolean") return value;
531
+ if (typeof value === "string") {
532
+ const normalized = value.trim().toLowerCase();
533
+ if (normalized === "true" || normalized === "1" || normalized === "yes") return true;
534
+ if (normalized === "false" || normalized === "0" || normalized === "no") return false;
535
+ }
536
+ };
537
+ const parseListArg = (value) => {
538
+ if (!value) return void 0;
539
+ const parsed = (Array.isArray(value) ? value : [value]).flatMap((item) => typeof item === "string" ? item.split(",") : []).map((item) => item.trim()).filter(Boolean);
540
+ return parsed.length ? parsed : void 0;
541
+ };
542
+ const normalizePostcssMode = (value) => {
543
+ if (value === true) return "auto";
544
+ if (value === false) return "skip";
545
+ if (typeof value === "string") {
546
+ const normalized = value.toLowerCase().trim();
547
+ if (normalized === "auto" || normalized === "manual" || normalized === "skip") return normalized;
548
+ }
549
+ };
550
+ const detectSrcRoot = async (cwd) => {
551
+ for (const candidate of [
552
+ "src",
553
+ "app",
554
+ "pages",
555
+ "lib",
556
+ "components"
557
+ ]) if (await exists(node_path.default.join(cwd, candidate))) return candidate;
558
+ return "src";
559
+ };
560
+ const normalizeRelativePath = (input, cwd) => {
561
+ const trimmed = input.trim();
562
+ if (!trimmed) return ".";
563
+ return (node_path.default.isAbsolute(trimmed) ? node_path.default.relative(cwd, trimmed) : trimmed).replace(/\\/g, "/").replace(/\/+$/g, "") || ".";
564
+ };
565
+ const normalizeImportPath = (input) => {
566
+ const normalized = input.replace(/\\/g, "/");
567
+ if (!normalized || normalized === ".") return ".";
568
+ if (normalized.startsWith("./") || normalized.startsWith("../")) return normalized;
569
+ if (normalized.startsWith(".")) return `./${normalized}`;
570
+ return `./${normalized}`;
571
+ };
572
+ const formatConfigFolder = (configDir) => {
573
+ if (configDir === ".") return "./.bo$$";
574
+ if (configDir.startsWith("./") || configDir.startsWith("../")) return configDir;
575
+ if (configDir.startsWith("/")) return configDir;
576
+ return `./${configDir}`;
577
+ };
578
+ const buildContentGlobs = ({ srcRoot, isNext }) => {
579
+ if (isNext) return [`{src,pages,app,lib,components}/**/*.{${EXTENSIONS}}`];
580
+ if (srcRoot === "." || srcRoot === "") return [`{src,app,lib,components}/**/*.{${EXTENSIONS}}`];
581
+ return [`${srcRoot}/**/*.{${EXTENSIONS}}`];
582
+ };
583
+ const detectPostcss = async (cwd, packageJson) => {
584
+ let configFilePath;
585
+ for (const file of POSTCSS_CONFIG_FILES) {
586
+ const fullPath = node_path.default.join(cwd, file);
587
+ if (await exists(fullPath)) {
588
+ configFilePath = fullPath;
589
+ break;
590
+ }
591
+ }
592
+ return {
593
+ hasDependency: hasDependency(packageJson, "postcss"),
594
+ hasConfigFile: Boolean(configFilePath),
595
+ hasPackageConfig: Boolean(packageJson.postcss),
596
+ configFilePath
597
+ };
598
+ };
599
+ const detectEslint = async (cwd, packageJson) => {
600
+ const hasEslintDependency = hasDependency(packageJson, "eslint");
601
+ for (const config of ESLINT_CONFIG_FILES) {
602
+ const fullPath = node_path.default.join(cwd, config.file);
603
+ if (await exists(fullPath)) {
604
+ let configFormat;
605
+ if (config.type === "flat" || config.type === "eslintrc-js") configFormat = inferEslintConfigFormat(await node_fs_promises.default.readFile(fullPath, "utf-8"), fullPath);
606
+ return {
607
+ hasDependency: hasEslintDependency,
608
+ hasConfig: true,
609
+ configFilePath: fullPath,
610
+ configType: config.type,
611
+ configFormat
612
+ };
613
+ }
614
+ }
615
+ if (packageJson.eslintConfig && typeof packageJson.eslintConfig === "object") return {
616
+ hasDependency: hasEslintDependency,
617
+ hasConfig: true,
618
+ configType: "package"
619
+ };
620
+ return {
621
+ hasDependency: hasEslintDependency,
622
+ hasConfig: false
623
+ };
624
+ };
625
+ const inferEslintConfigFormat = (content, filePath) => {
626
+ if (filePath.endsWith(".cjs")) return "cjs";
627
+ if (filePath.endsWith(".mjs")) return "esm";
628
+ if (/\bmodule\.exports\b/.test(content) || /\brequire\(/.test(content)) return "cjs";
629
+ if (/\bexport\s+default\b/.test(content) || /\bimport\s+/.test(content)) return "esm";
630
+ return "esm";
631
+ };
632
+ const updatePackageJson = (packageJson, options) => {
633
+ let changed = false;
634
+ let bossCssAdded = false;
635
+ const nextPackageJson = { ...packageJson };
636
+ if (shouldStoreConfigDir(options.configDir, options.srcRoot)) {
637
+ const boConfig = { ...nextPackageJson.bo$$ ?? {} };
638
+ if (boConfig.configDir !== options.configDir) {
639
+ boConfig.configDir = options.configDir;
640
+ nextPackageJson.bo$$ = boConfig;
641
+ changed = true;
642
+ }
643
+ }
644
+ if (options.addBossCss && !hasDependency(nextPackageJson, "boss-css")) {
645
+ const { updated, next } = ensureDependency(nextPackageJson, "boss-css", options.bossCssVersion || "latest", "dependencies");
646
+ if (updated) {
647
+ changed = true;
648
+ bossCssAdded = true;
649
+ Object.assign(nextPackageJson, next);
650
+ }
651
+ }
652
+ if (options.addPostcss && !hasDependency(nextPackageJson, "postcss")) {
653
+ const { updated, next } = ensureDependency(nextPackageJson, "postcss", "^8", "devDependencies");
654
+ if (updated) {
655
+ changed = true;
656
+ Object.assign(nextPackageJson, next);
657
+ }
658
+ }
659
+ if (options.includePostcssPlugin) {
660
+ const { updated, next, needsManual } = ensurePackagePostcssPlugin(nextPackageJson, options.postcssPluginOptions);
661
+ if (needsManual) _clack_prompts.log.message("PostCSS config in package.json uses an array; add boss-css/postcss via plugins object map.");
662
+ if (updated) {
663
+ changed = true;
664
+ Object.assign(nextPackageJson, next);
665
+ }
666
+ }
667
+ return {
668
+ changed,
669
+ data: nextPackageJson,
670
+ bossCssAdded
671
+ };
672
+ };
673
+ const shouldStoreConfigDir = (configDir, srcRoot) => {
674
+ if (configDir === ".bo$$") return false;
675
+ const normalizedSrc = srcRoot === "." ? "" : srcRoot.replace(/\/+$/g, "");
676
+ return configDir !== (normalizedSrc ? `${normalizedSrc}/.bo$$` : ".bo$$");
677
+ };
678
+ const ensureDependency = (packageJson, name, version, field) => {
679
+ const next = { ...packageJson };
680
+ const bucket = { ...next[field] ?? {} };
681
+ if (bucket[name]) return {
682
+ updated: false,
683
+ next
684
+ };
685
+ bucket[name] = version;
686
+ next[field] = bucket;
687
+ return {
688
+ updated: true,
689
+ next
690
+ };
691
+ };
692
+ const ensurePackagePostcssPlugin = (packageJson, pluginOptions) => {
693
+ const next = { ...packageJson };
694
+ if (!next.postcss || typeof next.postcss !== "object") return {
695
+ updated: false,
696
+ next
697
+ };
698
+ const postcssConfig = { ...next.postcss };
699
+ const plugins = postcssConfig.plugins;
700
+ if (Array.isArray(plugins)) return {
701
+ updated: false,
702
+ next,
703
+ needsManual: true
704
+ };
705
+ if (plugins && typeof plugins === "object") {
706
+ if (!Object.prototype.hasOwnProperty.call(plugins, "boss-css/postcss")) {
707
+ postcssConfig.plugins = {
708
+ "boss-css/postcss": pluginOptions ?? {},
709
+ ...plugins
710
+ };
711
+ next.postcss = postcssConfig;
712
+ return {
713
+ updated: true,
714
+ next
715
+ };
716
+ }
717
+ if (pluginOptions) {
718
+ postcssConfig.plugins = {
719
+ ...plugins,
720
+ "boss-css/postcss": pluginOptions
721
+ };
722
+ next.postcss = postcssConfig;
723
+ return {
724
+ updated: true,
725
+ next
726
+ };
727
+ }
728
+ return {
729
+ updated: false,
730
+ next
731
+ };
732
+ }
733
+ if (!plugins) {
734
+ postcssConfig.plugins = { "boss-css/postcss": pluginOptions ?? {} };
735
+ next.postcss = postcssConfig;
736
+ return {
737
+ updated: true,
738
+ next
739
+ };
740
+ }
741
+ return {
742
+ updated: false,
743
+ next
744
+ };
745
+ };
746
+ const configureEslint = async ({ detection, globalsEnabled, useEslintPlugin, allowReactGlobalsRule, packageJson }) => {
747
+ if (!detection.hasConfig) {
748
+ if (!globalsEnabled && !useEslintPlugin) return {
749
+ updated: false,
750
+ packageJsonChanged: false,
751
+ packageJson
752
+ };
753
+ const configFile = selectEslintConfigFile(packageJson);
754
+ const configText = createEslintConfigText({
755
+ globalsEnabled,
756
+ useEslintPlugin,
757
+ allowReactGlobalsRule
758
+ });
759
+ if (configText) {
760
+ await writeFile(node_path.default.join(process.cwd(), configFile), configText);
761
+ return {
762
+ updated: true,
763
+ packageJsonChanged: false,
764
+ packageJson
765
+ };
766
+ }
767
+ return {
768
+ updated: false,
769
+ packageJsonChanged: false,
770
+ packageJson
771
+ };
772
+ }
773
+ if (detection.configType === "package") {
774
+ if (!packageJson.eslintConfig || typeof packageJson.eslintConfig !== "object") {
775
+ _clack_prompts.log.warn("package.json eslintConfig is not an object. Skipping ESLint updates.");
776
+ return {
777
+ updated: false,
778
+ packageJsonChanged: false,
779
+ packageJson
780
+ };
781
+ }
782
+ const update = updateEslintConfigObject(packageJson.eslintConfig, {
783
+ globalsEnabled,
784
+ useEslintPlugin,
785
+ allowReactGlobalsRule
786
+ });
787
+ if (update.changed) return {
788
+ updated: true,
789
+ packageJsonChanged: true,
790
+ packageJson: {
791
+ ...packageJson,
792
+ eslintConfig: update.config
793
+ }
794
+ };
795
+ return {
796
+ updated: false,
797
+ packageJsonChanged: false,
798
+ packageJson
799
+ };
800
+ }
801
+ if (!detection.configFilePath) return {
802
+ updated: false,
803
+ packageJsonChanged: false,
804
+ packageJson
805
+ };
806
+ if (detection.configType === "flat") {
807
+ const update = updateFlatEslintConfigContent(await node_fs_promises.default.readFile(detection.configFilePath, "utf-8"), {
808
+ globalsEnabled,
809
+ useEslintPlugin,
810
+ allowReactGlobalsRule,
811
+ configFormat: detection.configFormat ?? "esm"
812
+ });
813
+ if (!update.handled) {
814
+ _clack_prompts.log.warn("Unable to update ESLint config automatically. Add $$ globals manually.");
815
+ return {
816
+ updated: false,
817
+ packageJsonChanged: false,
818
+ packageJson
819
+ };
820
+ }
821
+ if (update.updated) await node_fs_promises.default.writeFile(detection.configFilePath, update.content);
822
+ return {
823
+ updated: update.updated,
824
+ packageJsonChanged: false,
825
+ packageJson
826
+ };
827
+ }
828
+ if (detection.configType === "eslintrc") {
829
+ const content = await node_fs_promises.default.readFile(detection.configFilePath, "utf-8");
830
+ try {
831
+ const update = updateEslintConfigObject(require_json.parseJson(content, {
832
+ filePath: detection.configFilePath,
833
+ allowTrailingCommas: true
834
+ }), {
835
+ globalsEnabled,
836
+ useEslintPlugin,
837
+ allowReactGlobalsRule
838
+ });
839
+ if (update.changed) await node_fs_promises.default.writeFile(detection.configFilePath, JSON.stringify(update.config, null, 2) + "\n");
840
+ return {
841
+ updated: update.changed,
842
+ packageJsonChanged: false,
843
+ packageJson
844
+ };
845
+ } catch (error) {
846
+ _clack_prompts.log.warn("Unable to parse ESLint config JSON. Add $$ globals manually.");
847
+ return {
848
+ updated: false,
849
+ packageJsonChanged: false,
850
+ packageJson
851
+ };
852
+ }
853
+ }
854
+ if (detection.configType === "eslintrc-js") {
855
+ const update = updateEslintObjectConfigContent(await node_fs_promises.default.readFile(detection.configFilePath, "utf-8"), {
856
+ globalsEnabled,
857
+ useEslintPlugin,
858
+ allowReactGlobalsRule
859
+ });
860
+ if (!update.handled) {
861
+ _clack_prompts.log.warn("Unable to update ESLint config automatically. Add $$ globals manually.");
862
+ return {
863
+ updated: false,
864
+ packageJsonChanged: false,
865
+ packageJson
866
+ };
867
+ }
868
+ if (update.updated) await node_fs_promises.default.writeFile(detection.configFilePath, update.content);
869
+ return {
870
+ updated: update.updated,
871
+ packageJsonChanged: false,
872
+ packageJson
873
+ };
874
+ }
875
+ _clack_prompts.log.warn("ESLint config format not supported for automatic updates.");
876
+ return {
877
+ updated: false,
878
+ packageJsonChanged: false,
879
+ packageJson
880
+ };
881
+ };
882
+ const selectEslintConfigFile = (packageJson) => {
883
+ return packageJson.type === "module" ? "eslint.config.js" : "eslint.config.mjs";
884
+ };
885
+ const createEslintConfigText = ({ globalsEnabled, useEslintPlugin, allowReactGlobalsRule }) => {
886
+ const lines = buildEslintManagedArrayEntries({
887
+ includePluginConfig: useEslintPlugin,
888
+ includeGlobals: globalsEnabled && !useEslintPlugin,
889
+ includeAllowGlobalsRule: globalsEnabled && allowReactGlobalsRule
890
+ });
891
+ if (!lines.length) return "";
892
+ if (useEslintPlugin) return `import bossCss from 'boss-css/eslint-plugin'
893
+
894
+ export default [
895
+ ${buildManagedBlock(lines, " ")}
896
+ ]
897
+ `;
898
+ return `export default [
899
+ ${buildManagedBlock(lines, " ")}
900
+ ]
901
+ `;
902
+ };
903
+ const updateEslintConfigObject = (config, { globalsEnabled, useEslintPlugin, allowReactGlobalsRule }) => {
904
+ let changed = false;
905
+ const next = { ...config };
906
+ if (globalsEnabled) {
907
+ const globals = { ...next.globals };
908
+ if (globals.$$ !== "readonly") {
909
+ globals.$$ = "readonly";
910
+ next.globals = globals;
911
+ changed = true;
912
+ }
913
+ if (allowReactGlobalsRule) {
914
+ const allowGlobals = ensureAllowGlobalsRule({ ...next.rules });
915
+ if (allowGlobals.changed) {
916
+ next.rules = allowGlobals.rules;
917
+ changed = true;
918
+ }
919
+ }
920
+ }
921
+ if (useEslintPlugin) {
922
+ const plugins = normalizeToArray(next.plugins);
923
+ if (!plugins.includes("boss-css")) {
924
+ plugins.unshift("boss-css");
925
+ next.plugins = plugins;
926
+ changed = true;
927
+ }
928
+ const extendsList = normalizeToArray(next.extends);
929
+ if (!extendsList.includes("plugin:boss-css/recommended")) {
930
+ extendsList.unshift("plugin:boss-css/recommended");
931
+ next.extends = extendsList;
932
+ changed = true;
933
+ }
934
+ }
935
+ return {
936
+ changed,
937
+ config: next
938
+ };
939
+ };
940
+ const normalizeToArray = (value) => {
941
+ if (!value) return [];
942
+ if (Array.isArray(value)) return value.filter((item) => typeof item === "string");
943
+ if (typeof value === "string") return [value];
944
+ return [];
945
+ };
946
+ const updateFlatEslintConfigContent = (content, { globalsEnabled, useEslintPlugin, allowReactGlobalsRule, configFormat }) => {
947
+ let next = content;
948
+ let updated = false;
949
+ const legacyImportUpdate = replaceLegacyBossEslintImport(next);
950
+ if (legacyImportUpdate !== next) {
951
+ next = legacyImportUpdate;
952
+ updated = true;
953
+ }
954
+ if (useEslintPlugin && !hasBossEslintImport(next)) {
955
+ next = ensureEslintPluginImport(next, configFormat);
956
+ updated = true;
957
+ }
958
+ const hasBlock = hasManagedBlock(next);
959
+ const needsGlobals = globalsEnabled && !hasEslintGlobal(next) && !useEslintPlugin;
960
+ const needsAllowGlobalsRule = globalsEnabled && allowReactGlobalsRule && !hasEslintAllowGlobalsRule(next);
961
+ const needsPluginConfig = useEslintPlugin && !hasBossEslintConfig(next);
962
+ const managedLines = buildEslintManagedArrayEntries({
963
+ includePluginConfig: useEslintPlugin && (needsPluginConfig || hasBlock),
964
+ includeGlobals: globalsEnabled && !useEslintPlugin && (needsGlobals || hasBlock),
965
+ includeAllowGlobalsRule: globalsEnabled && allowReactGlobalsRule && (needsAllowGlobalsRule || hasBlock)
966
+ });
967
+ if (managedLines.length && (needsGlobals || needsAllowGlobalsRule || needsPluginConfig || hasBlock)) {
968
+ const bounds = findExportArrayBounds(next);
969
+ if (!bounds) return {
970
+ updated: false,
971
+ content,
972
+ handled: false
973
+ };
974
+ const insert = upsertManagedBlockIntoArray(next, bounds, managedLines);
975
+ next = insert.content;
976
+ updated = updated || insert.updated;
977
+ }
978
+ return {
979
+ updated,
980
+ content: next,
981
+ handled: true
982
+ };
983
+ };
984
+ const updateEslintObjectConfigContent = (content, { globalsEnabled, useEslintPlugin, allowReactGlobalsRule }) => {
985
+ if (findExportObjectStart(content) === null) return {
986
+ updated: false,
987
+ content,
988
+ handled: false
989
+ };
990
+ let next = content;
991
+ let updated = false;
992
+ if (useEslintPlugin) {
993
+ const pluginEntry = `'boss-css'`;
994
+ const extendEntry = `'plugin:boss-css/recommended'`;
995
+ const pluginsUpdate = ensureArrayEntry(next, "plugins", pluginEntry);
996
+ next = pluginsUpdate.content;
997
+ updated = updated || pluginsUpdate.updated;
998
+ const extendsUpdate = ensureArrayEntry(next, "extends", extendEntry);
999
+ next = extendsUpdate.content;
1000
+ updated = updated || extendsUpdate.updated;
1001
+ }
1002
+ const hasBlock = hasManagedBlock(next);
1003
+ const needsGlobals = globalsEnabled && !hasEslintGlobal(next);
1004
+ const needsAllowGlobalsRule = globalsEnabled && allowReactGlobalsRule && !hasEslintAllowGlobalsRule(next);
1005
+ const managedLines = buildEslintManagedObjectLines({
1006
+ includeGlobals: globalsEnabled && (needsGlobals || hasBlock),
1007
+ includeAllowGlobalsRule: globalsEnabled && allowReactGlobalsRule && (needsAllowGlobalsRule || hasBlock)
1008
+ });
1009
+ if (managedLines.length && (needsGlobals || needsAllowGlobalsRule || hasBlock)) {
1010
+ const insert = upsertManagedBlockInObject(next, managedLines);
1011
+ next = insert.content;
1012
+ updated = updated || insert.updated;
1013
+ }
1014
+ return {
1015
+ updated,
1016
+ content: next,
1017
+ handled: true
1018
+ };
1019
+ };
1020
+ const hasBossEslintConfig = (content) => /bossCss\.configs\./.test(content);
1021
+ const hasBossEslintImport = (content) => /boss-css\/eslint-plugin/.test(content) || /@boss-css\/eslint-plugin-boss-css/.test(content);
1022
+ const replaceLegacyBossEslintImport = (content) => content.replace(/@boss-css\/eslint-plugin-boss-css/g, "boss-css/eslint-plugin");
1023
+ const hasEslintGlobal = (content) => /['"]\$\$['"]\s*:/.test(content);
1024
+ const hasEslintAllowGlobalsRule = (content) => /react\/jsx-no-undef/.test(content) && /allowGlobals\s*:\s*true/.test(content);
1025
+ const hasManagedBlock = (content) => /\/\/\s*bo\$\$:begin/.test(content) && /\/\/\s*bo\$\$:end/.test(content);
1026
+ const ensureEslintPluginImport = (content, configFormat) => {
1027
+ return insertImports(content, [configFormat === "esm" ? "import bossCss from 'boss-css/eslint-plugin'" : "const bossCss = require('boss-css/eslint-plugin')"]);
1028
+ };
1029
+ const findExportArrayBounds = (content) => {
1030
+ const exportMatch = content.match(/export\s+default\s*\[/);
1031
+ const moduleMatch = content.match(/module\.exports\s*=\s*\[/);
1032
+ const match = exportMatch ?? moduleMatch;
1033
+ if (match) {
1034
+ if (match.index == null) return null;
1035
+ const startIndex = match.index + match[0].length - 1;
1036
+ const endIndex = findMatchingIndex(content, startIndex, "[", "]");
1037
+ if (endIndex === -1) return null;
1038
+ return {
1039
+ startIndex,
1040
+ endIndex
1041
+ };
1042
+ }
1043
+ const defineExportMatch = content.match(/export\s+default\s+defineConfig\s*\(/);
1044
+ if (defineExportMatch) {
1045
+ if (defineExportMatch.index == null) return null;
1046
+ return findDefineConfigArrayBounds(content, defineExportMatch.index + defineExportMatch[0].length - 1);
1047
+ }
1048
+ const identifier = findExportIdentifier(content);
1049
+ if (!identifier) return null;
1050
+ return findArrayBoundsByIdentifier(content, identifier) ?? findDefineConfigArrayBoundsByIdentifier(content, identifier);
1051
+ };
1052
+ const findExportObjectStart = (content) => {
1053
+ const exportMatch = content.match(/export\s+default\s*\{/);
1054
+ const moduleMatch = content.match(/module\.exports\s*=\s*\{/);
1055
+ const match = exportMatch ?? moduleMatch;
1056
+ if (match) {
1057
+ if (match.index == null) return null;
1058
+ return match.index + match[0].length - 1;
1059
+ }
1060
+ const identifier = findExportIdentifier(content);
1061
+ if (!identifier) return null;
1062
+ return findObjectStartByIdentifier(content, identifier);
1063
+ };
1064
+ const findExportIdentifier = (content) => {
1065
+ const exportMatch = content.match(/export\s+default\s+([A-Za-z_$][\w$]*)/);
1066
+ if (exportMatch) return exportMatch[1];
1067
+ const moduleMatch = content.match(/module\.exports\s*=\s*([A-Za-z_$][\w$]*)/);
1068
+ if (moduleMatch) return moduleMatch[1];
1069
+ return null;
1070
+ };
1071
+ const findArrayBoundsByIdentifier = (content, identifier) => {
1072
+ const escaped = escapeRegExp(identifier);
1073
+ const match = content.match(/* @__PURE__ */ new RegExp(`\\b(?:const|let|var)\\s+${escaped}\\s*=\\s*\\[`));
1074
+ if (!match) return null;
1075
+ if (match.index == null) return null;
1076
+ const startIndex = match.index + match[0].length - 1;
1077
+ const endIndex = findMatchingIndex(content, startIndex, "[", "]");
1078
+ if (endIndex === -1) return null;
1079
+ return {
1080
+ startIndex,
1081
+ endIndex
1082
+ };
1083
+ };
1084
+ const findDefineConfigArrayBoundsByIdentifier = (content, identifier) => {
1085
+ const escaped = escapeRegExp(identifier);
1086
+ const match = content.match(/* @__PURE__ */ new RegExp(`\\b(?:const|let|var)\\s+${escaped}\\s*=\\s*defineConfig\\s*\\(`));
1087
+ if (!match) return null;
1088
+ if (match.index == null) return null;
1089
+ return findDefineConfigArrayBounds(content, match.index + match[0].length - 1);
1090
+ };
1091
+ const findDefineConfigArrayBounds = (content, callStart) => {
1092
+ const callEnd = findMatchingIndex(content, callStart, "(", ")");
1093
+ if (callEnd === -1) return null;
1094
+ const arrayStart = content.indexOf("[", callStart);
1095
+ if (arrayStart === -1 || arrayStart > callEnd) return null;
1096
+ const arrayEnd = findMatchingIndex(content, arrayStart, "[", "]");
1097
+ if (arrayEnd === -1 || arrayEnd > callEnd) return null;
1098
+ return {
1099
+ startIndex: arrayStart,
1100
+ endIndex: arrayEnd
1101
+ };
1102
+ };
1103
+ const findObjectStartByIdentifier = (content, identifier) => {
1104
+ const escaped = escapeRegExp(identifier);
1105
+ const match = content.match(/* @__PURE__ */ new RegExp(`\\b(?:const|let|var)\\s+${escaped}\\s*=\\s*\\{`));
1106
+ if (!match) return null;
1107
+ if (match.index == null) return null;
1108
+ return match.index + match[0].length - 1;
1109
+ };
1110
+ const buildEslintManagedArrayEntries = ({ includePluginConfig, includeGlobals, includeAllowGlobalsRule }) => {
1111
+ const lines = [];
1112
+ if (includePluginConfig) lines.push("bossCss.configs.recommended,");
1113
+ if (includeGlobals || includeAllowGlobalsRule) {
1114
+ lines.push("{");
1115
+ if (includeGlobals) lines.push(" languageOptions: {", " globals: {", " $$: 'readonly',", " },", " },");
1116
+ if (includeAllowGlobalsRule) lines.push(" rules: {", " 'react/jsx-no-undef': ['error', { allowGlobals: true }],", " },");
1117
+ lines.push("},");
1118
+ }
1119
+ return lines;
1120
+ };
1121
+ const buildEslintManagedObjectLines = ({ includeGlobals, includeAllowGlobalsRule }) => {
1122
+ const lines = [];
1123
+ if (includeGlobals) lines.push("globals: {", " '$$': 'readonly',", "},");
1124
+ if (includeAllowGlobalsRule) lines.push("rules: {", " 'react/jsx-no-undef': ['error', { allowGlobals: true }],", "},");
1125
+ return lines;
1126
+ };
1127
+ const upsertManagedBlockIntoArray = (content, bounds, lines) => {
1128
+ const replaced = replaceManagedBlock(content, lines);
1129
+ if (replaced.found) return {
1130
+ updated: replaced.updated,
1131
+ content: replaced.content
1132
+ };
1133
+ const block = buildManagedBlock(lines, `${getIndentFromIndex(content, bounds.startIndex)} `);
1134
+ const insertion = `${needsArrayComma(content, bounds) ? "," : ""}\n${block}\n`;
1135
+ return {
1136
+ updated: true,
1137
+ content: `${content.slice(0, bounds.endIndex)}${insertion}${content.slice(bounds.endIndex)}`
1138
+ };
1139
+ };
1140
+ const upsertManagedBlockInObject = (content, lines) => {
1141
+ const replaced = replaceManagedBlock(content, lines);
1142
+ if (replaced.found) return {
1143
+ updated: replaced.updated,
1144
+ content: replaced.content
1145
+ };
1146
+ const objectStart = findExportObjectStart(content);
1147
+ if (objectStart === null) return {
1148
+ updated: false,
1149
+ content
1150
+ };
1151
+ const insertion = `\n${buildManagedBlock(lines, `${getIndentFromIndex(content, objectStart)} `)}\n`;
1152
+ return {
1153
+ updated: true,
1154
+ content: `${content.slice(0, objectStart + 1)}${insertion}${content.slice(objectStart + 1)}`
1155
+ };
1156
+ };
1157
+ const buildManagedBlock = (lines, indent = "") => {
1158
+ const start = `${indent}// bo$$:begin`;
1159
+ const end = `${indent}// bo$$:end`;
1160
+ return [
1161
+ start,
1162
+ ...lines.map((line) => line ? `${indent}${line}` : line),
1163
+ end
1164
+ ].join("\n");
1165
+ };
1166
+ const replaceManagedBlock = (content, lines) => {
1167
+ const regex = /(^[ \t]*)\/\/\s*bo\$\$?:begin[\s\S]*?^[ \t]*\/\/\s*bo\$\$?:end/m;
1168
+ const match = regex.exec(content);
1169
+ if (!match) return {
1170
+ updated: false,
1171
+ content,
1172
+ found: false
1173
+ };
1174
+ const block = buildManagedBlock(lines, match[1] ?? "");
1175
+ if (match.index == null) return {
1176
+ updated: false,
1177
+ content,
1178
+ found: false
1179
+ };
1180
+ const next = `${content.slice(0, match.index)}${block}${content.slice(match.index + match[0].length).replace(new RegExp(regex.source, "gm"), "")}`;
1181
+ return {
1182
+ updated: next !== content,
1183
+ content: ensureManagedBlockNewline(next),
1184
+ found: true
1185
+ };
1186
+ };
1187
+ const ensureManagedBlockNewline = (content) => {
1188
+ return content.replace(/(\/\/\s*bo\$\$:end)(?=[^\n])/g, "$1\n");
1189
+ };
1190
+ const needsArrayComma = (content, bounds) => {
1191
+ let index = bounds.endIndex - 1;
1192
+ while (index > bounds.startIndex && /\s/.test(content[index])) index -= 1;
1193
+ const lastChar = content[index];
1194
+ if (!lastChar) return false;
1195
+ return lastChar !== "[" && lastChar !== ",";
1196
+ };
1197
+ const ensureArrayEntry = (content, key, entry) => {
1198
+ const arrayMatch = content.match(/* @__PURE__ */ new RegExp(`${key}\\s*:\\s*\\[`));
1199
+ const stringMatch = !arrayMatch ? content.match(/* @__PURE__ */ new RegExp(`${key}\\s*:\\s*(['"][^'"]+['"])`)) : null;
1200
+ if (stringMatch) {
1201
+ const entryValue$1 = entry.replace(/^['"]|['"]$/g, "");
1202
+ if (stringMatch[1].replace(/^['"]|['"]$/g, "") === entryValue$1) return {
1203
+ updated: false,
1204
+ content
1205
+ };
1206
+ const replacement = `${key}: [${stringMatch[1]}, ${entry}]`;
1207
+ return {
1208
+ updated: true,
1209
+ content: content.replace(stringMatch[0], replacement)
1210
+ };
1211
+ }
1212
+ if (!arrayMatch) {
1213
+ const objectStart = findExportObjectStart(content);
1214
+ if (objectStart === null) return {
1215
+ updated: false,
1216
+ content
1217
+ };
1218
+ const insertion$1 = `\n${`${getIndentFromIndex(content, objectStart)} `}${key}: [${entry}],`;
1219
+ return {
1220
+ updated: true,
1221
+ content: `${content.slice(0, objectStart + 1)}${insertion$1}${content.slice(objectStart + 1)}`
1222
+ };
1223
+ }
1224
+ if (arrayMatch.index == null) return {
1225
+ updated: false,
1226
+ content
1227
+ };
1228
+ const startIndex = arrayMatch.index + arrayMatch[0].length - 1;
1229
+ const endIndex = findMatchingIndex(content, startIndex, "[", "]");
1230
+ if (endIndex === -1) return {
1231
+ updated: false,
1232
+ content
1233
+ };
1234
+ const entryValue = entry.replace(/^['"]|['"]$/g, "");
1235
+ if ((/* @__PURE__ */ new RegExp(`['"]${escapeRegExp(entryValue)}['"]`)).test(content.slice(startIndex, endIndex))) return {
1236
+ updated: false,
1237
+ content
1238
+ };
1239
+ const insertion = `\n${`${getIndentFromIndex(content, startIndex)} `}${entry},`;
1240
+ return {
1241
+ updated: true,
1242
+ content: `${content.slice(0, endIndex)}${insertion}${content.slice(endIndex)}`
1243
+ };
1244
+ };
1245
+ const ensureAllowGlobalsRule = (rules) => {
1246
+ const existing = rules["react/jsx-no-undef"];
1247
+ if (Array.isArray(existing)) {
1248
+ const options = typeof existing[1] === "object" && existing[1] ? { ...existing[1] } : {};
1249
+ if (options.allowGlobals === true) return {
1250
+ changed: false,
1251
+ rules
1252
+ };
1253
+ return {
1254
+ changed: true,
1255
+ rules: {
1256
+ ...rules,
1257
+ "react/jsx-no-undef": [
1258
+ existing[0] ?? "error",
1259
+ {
1260
+ ...options,
1261
+ allowGlobals: true
1262
+ },
1263
+ ...existing.slice(2)
1264
+ ]
1265
+ }
1266
+ };
1267
+ }
1268
+ if (existing !== void 0) return {
1269
+ changed: true,
1270
+ rules: {
1271
+ ...rules,
1272
+ "react/jsx-no-undef": [existing, { allowGlobals: true }]
1273
+ }
1274
+ };
1275
+ return {
1276
+ changed: true,
1277
+ rules: {
1278
+ ...rules,
1279
+ "react/jsx-no-undef": ["error", { allowGlobals: true }]
1280
+ }
1281
+ };
1282
+ };
1283
+ const shouldAllowReactGlobalsRule = (packageJson) => {
1284
+ return hasDependency(packageJson, "eslint-plugin-react") || hasDependency(packageJson, "eslint-config-next") || hasDependency(packageJson, "next");
1285
+ };
1286
+ const findMatchingIndex = (content, startIndex, openChar, closeChar) => {
1287
+ let depth = 0;
1288
+ for (let index = startIndex; index < content.length; index += 1) {
1289
+ const char = content[index];
1290
+ if (char === openChar) depth += 1;
1291
+ else if (char === closeChar) {
1292
+ depth -= 1;
1293
+ if (depth === 0) return index;
1294
+ }
1295
+ }
1296
+ return -1;
1297
+ };
1298
+ const writeInitFiles = async ({ outputDir, configFolder, contentGlobs, pluginState, selectedStrategyId, isNext, postcssMode, postcssDetection, includeAutoprefixer, packageJson, dirDependencies, usePostcssOptions, srcRoot, configDir, globalsEnabled, cssAutoLoad }) => {
1299
+ await node_fs_promises.default.mkdir(outputDir, { recursive: true });
1300
+ const isRuntimeStrategy = selectedStrategyId === "runtime-only" || selectedStrategyId === "runtime-hybrid";
1301
+ const configText = (0, pluvo.default)(require_init.configTemplate, {
1302
+ plugins: pluginState,
1303
+ folder: configFolder,
1304
+ content: contentGlobs,
1305
+ jsxEnabled: pluginState.some((plugin) => plugin.id === "jsx" && plugin.enabled),
1306
+ globalsEnabled,
1307
+ runtimeEnabled: isRuntimeStrategy,
1308
+ runtimeStrategy: "inline-first",
1309
+ runtimeOnly: selectedStrategyId === "runtime-only",
1310
+ cssAutoLoad
1311
+ }, { commentStyles: INIT_COMMENT_STYLES });
1312
+ await writeFile(node_path.default.join(outputDir, "config.js"), configText);
1313
+ await writeFile(node_path.default.join(outputDir, "jsconfig.json"), require_init.jsconfigTemplate);
1314
+ await writeFile(node_path.default.join(outputDir, "package.json"), require_init.packageTemplate);
1315
+ await ensureFile(node_path.default.join(outputDir, "styles.css"));
1316
+ if (postcssMode === "auto") {
1317
+ if (!postcssDetection.hasConfigFile && !postcssDetection.hasPackageConfig) {
1318
+ const postcssText = (0, pluvo.default)(require_init.postcssTemplate, {
1319
+ includeAutoprefixer,
1320
+ dirDependencies,
1321
+ useOptions: usePostcssOptions
1322
+ }, { commentStyles: INIT_COMMENT_STYLES });
1323
+ await writeFile(node_path.default.join(process.cwd(), "postcss.config.js"), postcssText);
1324
+ } else if (postcssDetection.hasConfigFile && postcssDetection.configFilePath) {
1325
+ const update = await updatePostcssConfigFile(postcssDetection.configFilePath, {
1326
+ dirDependencies,
1327
+ useOptions: usePostcssOptions
1328
+ });
1329
+ if (!update.updated && !update.hasBoss) await warnIfPostcssPluginMissing(postcssDetection.configFilePath);
1330
+ } else if (packageJson.postcss && typeof packageJson.postcss === "object") {}
1331
+ }
1332
+ if (isNext && selectedStrategyId !== "classname-only") await ensureNextInstrumentationFiles({
1333
+ srcRoot,
1334
+ configDir,
1335
+ packageJson
1336
+ });
1337
+ };
1338
+ const ensureNextInstrumentationFiles = async ({ srcRoot, configDir, packageJson }) => {
1339
+ const cwd = process.cwd();
1340
+ const existingExt = await detectInstrumentationExtension(cwd, srcRoot);
1341
+ const useTypeScript = existingExt === ".ts" || await exists(node_path.default.join(cwd, "tsconfig.json")) || hasDependency(packageJson, "typescript");
1342
+ const ext = existingExt ?? (useTypeScript ? ".ts" : ".js");
1343
+ const instrumentationDir = node_path.default.resolve(cwd, srcRoot === "." ? "" : srcRoot);
1344
+ const configDirAbs = node_path.default.resolve(cwd, configDir);
1345
+ const importRoot = normalizeImportPath(node_path.default.relative(instrumentationDir, configDirAbs));
1346
+ await ensureInstrumentationFile({
1347
+ filePath: node_path.default.join(instrumentationDir, `instrumentation${ext}`),
1348
+ importPaths: [importRoot],
1349
+ template: (importPath) => `import '${importPath}'\n`
1350
+ });
1351
+ await ensureInstrumentationFile({
1352
+ filePath: node_path.default.join(instrumentationDir, `instrumentation-client${ext}`),
1353
+ importPaths: [importRoot],
1354
+ template: (importPath) => `import '${importPath}'\n`
1355
+ });
1356
+ };
1357
+ const STENCIL_CONFIG_FILES = [
1358
+ "stencil.config.ts",
1359
+ "stencil.config.js",
1360
+ "stencil.config.mjs",
1361
+ "stencil.config.cjs"
1362
+ ];
1363
+ const ensureStencilSetup = async ({ cwd, srcRoot, configDir, packageJson }) => {
1364
+ const stencilConfigPath = await detectStencilConfigPath(cwd);
1365
+ if (!stencilConfigPath) {
1366
+ _clack_prompts.log.warn("Stencil config not found. Add globalScript/globalStyle manually.");
1367
+ return;
1368
+ }
1369
+ const globalScriptPath = await resolveStencilGlobalScriptPath(cwd, srcRoot, packageJson);
1370
+ const globalScriptRelative = normalizeRelativePath(node_path.default.relative(cwd, globalScriptPath), cwd);
1371
+ const globalStyleRelative = node_path.default.join(configDir, "styles.css").replace(/\\/g, "/");
1372
+ const configUpdated = await ensureStencilConfigFields({
1373
+ filePath: stencilConfigPath,
1374
+ fields: [{
1375
+ key: "globalScript",
1376
+ line: `globalScript: '${globalScriptRelative}',`
1377
+ }, {
1378
+ key: "globalStyle",
1379
+ line: `globalStyle: '${globalStyleRelative}',`
1380
+ }]
1381
+ });
1382
+ await ensureStencilGlobalScriptFile({
1383
+ filePath: globalScriptPath,
1384
+ configDirAbs: node_path.default.resolve(cwd, configDir)
1385
+ });
1386
+ if (configUpdated) _clack_prompts.log.message("Stencil config updated with Boss CSS globals.");
1387
+ };
1388
+ const detectStencilConfigPath = async (cwd) => {
1389
+ for (const file of STENCIL_CONFIG_FILES) {
1390
+ const fullPath = node_path.default.join(cwd, file);
1391
+ if (await exists(fullPath)) return fullPath;
1392
+ }
1393
+ return null;
1394
+ };
1395
+ const resolveStencilGlobalScriptPath = async (cwd, srcRoot, packageJson) => {
1396
+ const baseDir = node_path.default.resolve(cwd, srcRoot, "global");
1397
+ const tsPath = node_path.default.join(baseDir, "app.ts");
1398
+ const jsPath = node_path.default.join(baseDir, "app.js");
1399
+ if (await exists(tsPath)) return tsPath;
1400
+ if (await exists(jsPath)) return jsPath;
1401
+ const useTypeScript = await exists(node_path.default.join(cwd, "tsconfig.json")) || hasDependency(packageJson, "typescript");
1402
+ return node_path.default.join(baseDir, `app.${useTypeScript ? "ts" : "js"}`);
1403
+ };
1404
+ const ensureStencilGlobalScriptFile = async ({ filePath, configDirAbs }) => {
1405
+ const importPath = normalizeImportPath(node_path.default.relative(node_path.default.dirname(filePath), configDirAbs));
1406
+ if (!await exists(filePath)) {
1407
+ await writeFile(filePath, `import '${importPath}'\n\nexport default function () {}\n`);
1408
+ return;
1409
+ }
1410
+ const current = await node_fs_promises.default.readFile(filePath, "utf-8");
1411
+ const updated = ensureSideEffectImports(current, [importPath]);
1412
+ if (updated !== current) await node_fs_promises.default.writeFile(filePath, updated);
1413
+ };
1414
+ const ensureStencilConfigFields = async ({ filePath, fields }) => {
1415
+ const current = await node_fs_promises.default.readFile(filePath, "utf-8");
1416
+ const missing = fields.filter((field) => !new RegExp(`^\\s*${field.key}\\s*:`, "m").test(current));
1417
+ if (!missing.length) return false;
1418
+ const lines = current.split("\n");
1419
+ const namespaceIndex = lines.findIndex((line) => /^\s*namespace\s*:/.test(line));
1420
+ let insertIndex = namespaceIndex;
1421
+ if (insertIndex === -1) insertIndex = findStencilConfigInsertIndex(lines);
1422
+ if (insertIndex === -1) {
1423
+ _clack_prompts.log.warn("Unable to update stencil.config. Add globalScript/globalStyle manually.");
1424
+ return false;
1425
+ }
1426
+ const indent = lines[namespaceIndex]?.match(/^\s+/)?.[0] ?? current.match(/^[ \t]+(?=[A-Za-z_])/m)?.[0] ?? " ";
1427
+ const insertLines = missing.map((field) => `${indent}${field.line}`);
1428
+ lines.splice(insertIndex + 1, 0, ...insertLines);
1429
+ await node_fs_promises.default.writeFile(filePath, lines.join("\n"));
1430
+ return true;
1431
+ };
1432
+ const findStencilConfigInsertIndex = (lines) => {
1433
+ const configLineIndex = lines.findIndex((line) => /export\s+const\s+config\b/.test(line) || /\bconst\s+config\b/.test(line));
1434
+ if (configLineIndex === -1) return -1;
1435
+ if (lines[configLineIndex].includes("{")) return configLineIndex;
1436
+ for (let index = configLineIndex + 1; index < lines.length; index += 1) if (lines[index].includes("{")) return index;
1437
+ return configLineIndex;
1438
+ };
1439
+ const detectInstrumentationExtension = async (cwd, srcRoot) => {
1440
+ const baseDir = node_path.default.resolve(cwd, srcRoot === "." ? "" : srcRoot);
1441
+ for (const ext of [".ts", ".js"]) {
1442
+ const serverPath = node_path.default.join(baseDir, `instrumentation${ext}`);
1443
+ const clientPath = node_path.default.join(baseDir, `instrumentation-client${ext}`);
1444
+ if (await exists(serverPath) || await exists(clientPath)) return ext;
1445
+ }
1446
+ };
1447
+ const ensureInstrumentationFile = async ({ filePath, importPaths, template }) => {
1448
+ if (!await exists(filePath)) {
1449
+ await writeFile(filePath, buildManagedBlock([`import '${importPaths[0]}'`]));
1450
+ return;
1451
+ }
1452
+ const current = await node_fs_promises.default.readFile(filePath, "utf-8");
1453
+ const normalized = normalizeInstrumentationImports(current);
1454
+ const replaced = replaceManagedBlock(normalized, [`import '${importPaths[0]}'`]);
1455
+ if (replaced.found) {
1456
+ if (replaced.updated) await writeFile(filePath, replaced.content);
1457
+ return;
1458
+ }
1459
+ const next = insertManagedBlock(stripUnmanagedBossImports(normalized), [`import '${importPaths[0]}'`]);
1460
+ if (next !== current) await writeFile(filePath, next);
1461
+ };
1462
+ const ensureSideEffectImports = (content, importPaths) => {
1463
+ const missing = importPaths.filter((importPath) => !hasImportPath(content, importPath));
1464
+ if (!missing.length) return content;
1465
+ return insertImports(content, missing.map((importPath) => `import '${importPath}'`));
1466
+ };
1467
+ const normalizeInstrumentationImports = (content) => {
1468
+ const replacement = "import './.bo$$'";
1469
+ const lines = content.split("\n");
1470
+ const seen = /* @__PURE__ */ new Set();
1471
+ return lines.map((line) => {
1472
+ const match = line.match(/^\s*import\s+(['"])([^'"]+)\1\s*;?\s*$/);
1473
+ if (!match) return line;
1474
+ let importPath = match[2];
1475
+ if (importPath === ".bo$$" || importPath === "./.bo$$" || importPath === ".bo$$/styles.css") importPath = "./.bo$$";
1476
+ else if (importPath === ".bo$" || importPath === "./.bo$") importPath = "./.bo$$";
1477
+ if (importPath === "./.bo$$") {
1478
+ if (seen.has(importPath)) return "";
1479
+ seen.add(importPath);
1480
+ return replacement;
1481
+ }
1482
+ return line;
1483
+ }).filter((line) => line !== "").join("\n");
1484
+ };
1485
+ const stripUnmanagedBossImports = (content) => {
1486
+ return content.split("\n").filter((line) => !line.match(/^\s*import\s+['"](\.\/)?\.bo\$\$(\/styles\.css)?['"]\s*;?\s*$/)).join("\n");
1487
+ };
1488
+ const insertManagedBlock = (content, lines) => {
1489
+ const blockLines = buildManagedBlock(lines).split("\n");
1490
+ const output = content.split("\n");
1491
+ const insertIndex = getImportInsertIndex(output);
1492
+ const insertLines = insertIndex < output.length && output[insertIndex].trim() !== "" ? [...blockLines, ""] : blockLines;
1493
+ output.splice(insertIndex, 0, ...insertLines);
1494
+ return ensureManagedBlockNewline(output.join("\n"));
1495
+ };
1496
+ const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1497
+ const hasImportPath = (content, importPath) => {
1498
+ const escaped = escapeRegExp(importPath);
1499
+ return (/* @__PURE__ */ new RegExp(`['"]${escaped}['"]`)).test(content);
1500
+ };
1501
+ const insertImports = (content, importLines) => {
1502
+ const lines = content.split("\n");
1503
+ const insertIndex = getImportInsertIndex(lines);
1504
+ const insertLines = insertIndex < lines.length && lines[insertIndex].trim() !== "" ? [...importLines, ""] : importLines;
1505
+ lines.splice(insertIndex, 0, ...insertLines);
1506
+ return lines.join("\n");
1507
+ };
1508
+ const getImportInsertIndex = (lines) => {
1509
+ let index = 0;
1510
+ while (index < lines.length) {
1511
+ const trimmed = lines[index].trim();
1512
+ if (!trimmed) {
1513
+ index += 1;
1514
+ continue;
1515
+ }
1516
+ if (trimmed.startsWith("//") || trimmed.startsWith("/*") || trimmed.startsWith("*") || trimmed.startsWith("*/") || /^['"]use (client|strict)['"];?$/.test(trimmed)) {
1517
+ index += 1;
1518
+ continue;
1519
+ }
1520
+ break;
1521
+ }
1522
+ return index;
1523
+ };
1524
+ const generateRuntime = async ({ outputDir, configFolder, pluginState, contentGlobs, globalsEnabled, cssAutoLoad, selectedStrategyId }) => {
1525
+ if (selectedStrategyId === "classname-only") return;
1526
+ const enabledPlugins = pluginState.filter((plugin) => plugin.enabled);
1527
+ const modules = enabledPlugins.map((plugin) => PLUGIN_MODULES[plugin.id]).filter(Boolean);
1528
+ if (globalsEnabled && enabledPlugins.some((plugin) => plugin.id === "jsx")) require_parser_jsx_server.settings.set?.("globals", true);
1529
+ if (enabledPlugins.some((plugin) => plugin.id === "jsx")) require_parser_jsx_server.settings.set?.("emitRuntime", true);
1530
+ if (enabledPlugins.some((plugin) => plugin.id === "inline-first")) require_strategy_inline_first_server.settings.set?.("emitRuntime", true);
1531
+ if (enabledPlugins.some((plugin) => plugin.id === "classname-first")) require_server.settings.set?.("emitRuntime", true);
1532
+ const api = await require_api_server.createApi({
1533
+ folder: configFolder,
1534
+ plugins: modules,
1535
+ content: contentGlobs,
1536
+ css: cssAutoLoad ? void 0 : { autoLoad: false }
1537
+ }, true);
1538
+ await api.file.js.write();
1539
+ if (api.file.native?.hasContent) await api.file.native.write();
1540
+ };
1541
+ const warnIfPostcssPluginMissing = async (configFilePath) => {
1542
+ if ((await node_fs_promises.default.readFile(configFilePath, "utf-8")).includes("boss-css/postcss")) return;
1543
+ _clack_prompts.log.warn(`PostCSS config detected at ${node_path.default.relative(process.cwd(), configFilePath)} but boss-css/postcss is missing.`);
1544
+ _clack_prompts.log.message("Add boss-css/postcss to your PostCSS plugins to enable Boss CSS.");
1545
+ };
1546
+ const updatePostcssConfigFile = async (configFilePath, options) => {
1547
+ const update = updatePostcssConfigContent(await node_fs_promises.default.readFile(configFilePath, "utf-8"), configFilePath, options);
1548
+ if (update.updated) await node_fs_promises.default.writeFile(configFilePath, update.content);
1549
+ return update;
1550
+ };
1551
+ const updatePostcssConfigContent = (content, configFilePath, options) => {
1552
+ const hasBoss = content.includes("boss-css/postcss");
1553
+ const hasBossCall = /\bboss\s*\(/.test(content);
1554
+ const isEsm = configFilePath.endsWith(".mjs") || /\bexport\s+default\b/.test(content) || /\bimport\b/.test(content);
1555
+ const arrayMatch = content.match(/plugins\s*:\s*\[/);
1556
+ const objectMatch = content.match(/plugins\s*:\s*\{/);
1557
+ const useOptions = options.useOptions;
1558
+ const bossCall = useOptions ? `boss({ dirDependencies: ${options.dirDependencies ? "true" : "false"} })` : "boss()";
1559
+ const bossObject = useOptions ? `{ dirDependencies: ${options.dirDependencies ? "true" : "false"} }` : "{}";
1560
+ const managedEntry = bossCall;
1561
+ if (arrayMatch) {
1562
+ let nextContent = content;
1563
+ const managedLines = [`${managedEntry},`];
1564
+ const replaced = replaceManagedBlock(nextContent, managedLines);
1565
+ if (replaced.found) {
1566
+ nextContent = ensureBossImport(replaced.content, isEsm);
1567
+ return {
1568
+ updated: nextContent !== content,
1569
+ content: nextContent,
1570
+ hasBoss: true
1571
+ };
1572
+ }
1573
+ const replacedArray = replaceBossPluginInArray(nextContent, arrayMatch, bossCall);
1574
+ if (replacedArray.updated) {
1575
+ nextContent = ensureBossImport(replacedArray.content, isEsm);
1576
+ return {
1577
+ updated: nextContent !== content,
1578
+ content: nextContent,
1579
+ hasBoss: true
1580
+ };
1581
+ }
1582
+ if (!hasBoss && !hasBossCall) {
1583
+ if (arrayMatch.index == null) return {
1584
+ updated: false,
1585
+ content,
1586
+ hasBoss: hasBoss || hasBossCall
1587
+ };
1588
+ const insertAt = arrayMatch.index + arrayMatch[0].length;
1589
+ const block = buildManagedBlock(managedLines, `${getIndentFromIndex(content, arrayMatch.index)} `);
1590
+ nextContent = `${content.slice(0, insertAt)}\n${block}${content.slice(insertAt)}`;
1591
+ nextContent = ensureBossImport(nextContent, isEsm);
1592
+ return {
1593
+ updated: nextContent !== content,
1594
+ content: nextContent,
1595
+ hasBoss: true
1596
+ };
1597
+ }
1598
+ if (hasBossCall) {
1599
+ nextContent = ensureBossImport(nextContent, isEsm);
1600
+ return {
1601
+ updated: nextContent !== content,
1602
+ content: nextContent,
1603
+ hasBoss: true
1604
+ };
1605
+ }
1606
+ return {
1607
+ updated: false,
1608
+ content,
1609
+ hasBoss: hasBoss || hasBossCall
1610
+ };
1611
+ }
1612
+ if (objectMatch) {
1613
+ let nextContent = content;
1614
+ const entry = useOptions ? bossObject : "{}";
1615
+ const managedLines = [`'boss-css/postcss': ${entry},`];
1616
+ const replaced = replaceManagedBlock(nextContent, managedLines);
1617
+ if (replaced.found) return {
1618
+ updated: replaced.content !== content,
1619
+ content: replaced.content,
1620
+ hasBoss: true
1621
+ };
1622
+ const objectEntryRegex = /['"]boss-css\/postcss['"]\s*:\s*[^,}]+/;
1623
+ if (hasBoss) {
1624
+ if (useOptions && objectEntryRegex.test(nextContent)) nextContent = nextContent.replace(objectEntryRegex, `'boss-css/postcss': ${entry}`);
1625
+ return {
1626
+ updated: nextContent !== content,
1627
+ content: nextContent,
1628
+ hasBoss: true
1629
+ };
1630
+ }
1631
+ if (objectMatch.index == null) return {
1632
+ updated: false,
1633
+ content,
1634
+ hasBoss
1635
+ };
1636
+ const insertAt = objectMatch.index + objectMatch[0].length;
1637
+ const block = buildManagedBlock(managedLines, `${getIndentFromIndex(content, objectMatch.index)} `);
1638
+ nextContent = `${content.slice(0, insertAt)}\n${block}${content.slice(insertAt)}`;
1639
+ return {
1640
+ updated: nextContent !== content,
1641
+ content: nextContent,
1642
+ hasBoss: true
1643
+ };
1644
+ }
1645
+ return {
1646
+ updated: false,
1647
+ content,
1648
+ hasBoss: hasBoss || hasBossCall
1649
+ };
1650
+ };
1651
+ const replaceBossPluginInArray = (content, arrayMatch, bossCall) => {
1652
+ if (arrayMatch.index === void 0) return {
1653
+ updated: false,
1654
+ content
1655
+ };
1656
+ const arrayIndex = arrayMatch.index + arrayMatch[0].lastIndexOf("[");
1657
+ const arrayEnd = findMatchingIndex(content, arrayIndex, "[", "]");
1658
+ if (arrayEnd === -1) return {
1659
+ updated: false,
1660
+ content
1661
+ };
1662
+ const arrayBody = content.slice(arrayIndex + 1, arrayEnd);
1663
+ const replacedBody = arrayBody.replace(/['"]boss-css\/postcss['"]/, bossCall);
1664
+ if (replacedBody === arrayBody) return {
1665
+ updated: false,
1666
+ content
1667
+ };
1668
+ const next = `${content.slice(0, arrayIndex + 1)}${replacedBody}${content.slice(arrayEnd)}`;
1669
+ return {
1670
+ updated: next !== content,
1671
+ content: next
1672
+ };
1673
+ };
1674
+ const ensureBossImport = (content, isEsm) => {
1675
+ if (content.includes("boss-css/postcss")) {
1676
+ if (isEsm ? /import\s+boss\s+from\s+['"]boss-css\/postcss['"]/.test(content) : /const\s+boss\s*=\s*require\(['"]boss-css\/postcss['"]\)/.test(content)) return content;
1677
+ }
1678
+ if (isEsm) {
1679
+ if (content.includes("import boss from")) return content;
1680
+ return `import boss from 'boss-css/postcss'\n${content}`;
1681
+ }
1682
+ if (content.includes("const boss = require")) return content;
1683
+ return `const boss = require('boss-css/postcss')\n${content}`;
1684
+ };
1685
+ const getIndentFromIndex = (content, index) => {
1686
+ const lineStart = content.lastIndexOf("\n", index);
1687
+ const match = content.slice(lineStart + 1).match(/^\s+/);
1688
+ return match ? match[0] : "";
1689
+ };
1690
+ const confirmOverwriteIfExists = async (dirPath, yes) => {
1691
+ if (!await exists(dirPath)) return true;
1692
+ if (yes) return true;
1693
+ const shouldContinue = await (0, _clack_prompts.confirm)({
1694
+ message: `Existing ${node_path.default.basename(dirPath)} folder detected. Overwrite its contents?`,
1695
+ initialValue: false
1696
+ });
1697
+ require_utils.cancelIf(shouldContinue);
1698
+ return shouldContinue;
1699
+ };
1700
+ const readPackageJson = async (cwd) => {
1701
+ const filePath = node_path.default.join(cwd, "package.json");
1702
+ if (!await exists(filePath)) return {
1703
+ data: null,
1704
+ indent: " ",
1705
+ newline: "\n"
1706
+ };
1707
+ const raw = await node_fs_promises.default.readFile(filePath, "utf-8");
1708
+ return {
1709
+ data: require_json.parseJson(raw, {
1710
+ filePath,
1711
+ allowTrailingCommas: true
1712
+ }),
1713
+ indent: detectIndent(raw),
1714
+ newline: raw.endsWith("\n") ? "\n" : ""
1715
+ };
1716
+ };
1717
+ const writePackageJson = async (cwd, data, indent, newline) => {
1718
+ const filePath = node_path.default.join(cwd, "package.json");
1719
+ const output = JSON.stringify(data, null, indent) + (newline || "\n");
1720
+ await node_fs_promises.default.writeFile(filePath, output);
1721
+ };
1722
+ const writeFile = async (filePath, content) => {
1723
+ await node_fs_promises.default.mkdir(node_path.default.dirname(filePath), { recursive: true });
1724
+ await node_fs_promises.default.writeFile(filePath, content.trimEnd() + "\n");
1725
+ };
1726
+ const ensureFile = async (filePath) => {
1727
+ if (await exists(filePath)) return;
1728
+ await node_fs_promises.default.writeFile(filePath, "");
1729
+ };
1730
+ const detectIndent = (raw) => {
1731
+ const match = raw.match(/^[\t ]+(?=")/m);
1732
+ return match ? match[0] : " ";
1733
+ };
1734
+ const hasDependency = (packageJson, name) => {
1735
+ return Boolean(packageJson.dependencies?.[name] || packageJson.devDependencies?.[name]);
1736
+ };
1737
+ const resolveBossCssVersion = async () => {
1738
+ const root = node_path.default.resolve(__dirname, "..", "..", "..");
1739
+ const filePath = node_path.default.join(root, "package.json");
1740
+ try {
1741
+ const data = require_json.parseJson(await node_fs_promises.default.readFile(filePath, "utf8"), {
1742
+ filePath,
1743
+ allowTrailingCommas: true
1744
+ });
1745
+ if (typeof data?.version === "string" && data.version.trim()) return data.version.trim();
1746
+ } catch {}
1747
+ return "latest";
1748
+ };
1749
+ const detectPackageManager = async (cwd, runtimeType) => {
1750
+ const agent = process.env.npm_config_user_agent;
1751
+ if (agent) {
1752
+ const name = agent.split("/")[0];
1753
+ if (name === require_types$1.PackageManagerType.PNPM) return require_types$1.PackageManagerType.PNPM;
1754
+ if (name === require_types$1.PackageManagerType.YARN) return require_types$1.PackageManagerType.YARN;
1755
+ if (name === require_types$1.PackageManagerType.BUN) return require_types$1.PackageManagerType.BUN;
1756
+ if (name === require_types$1.PackageManagerType.NPM) return require_types$1.PackageManagerType.NPM;
1757
+ }
1758
+ if (runtimeType === require_types.RuntimeType.DENO) return require_types$1.PackageManagerType.NPM;
1759
+ const candidates = [
1760
+ ["pnpm-lock.yaml", require_types$1.PackageManagerType.PNPM],
1761
+ ["yarn.lock", require_types$1.PackageManagerType.YARN],
1762
+ ["bun.lockb", require_types$1.PackageManagerType.BUN],
1763
+ ["package-lock.json", require_types$1.PackageManagerType.NPM]
1764
+ ];
1765
+ for (const [file, manager] of candidates) if (await exists(node_path.default.join(cwd, file))) return manager;
1766
+ return require_types$1.PackageManagerType.NPM;
1767
+ };
1768
+ const formatInstallCommand = (manager) => {
1769
+ switch (manager) {
1770
+ case require_types$1.PackageManagerType.PNPM: return "pnpm install";
1771
+ case require_types$1.PackageManagerType.YARN: return "yarn install";
1772
+ case require_types$1.PackageManagerType.BUN: return "bun install";
1773
+ case require_types$1.PackageManagerType.NPM:
1774
+ default: return "npm install";
1775
+ }
1776
+ };
1777
+ const exists = async (filePath) => {
1778
+ try {
1779
+ await node_fs_promises.default.access(filePath);
1780
+ return true;
1781
+ } catch {
1782
+ return false;
1783
+ }
1784
+ };
1785
+ const logInitSummary = ({ configDir, isNext, postcssMode, postcssDetection, configFolder, srcRoot, globalsEnabled, eslintUpdated, useEslintPlugin, frameworkId, selectedStrategyId, cssAutoLoad, installCommand }) => {
1786
+ _clack_prompts.log.info("boss init complete.");
1787
+ _clack_prompts.log.message(`Generated Boss CSS config in ${configDir}`);
1788
+ if (selectedStrategyId === "classname-only") _clack_prompts.log.message("Classname-only does not auto-load styles. Import styles.css manually.");
1789
+ if (postcssMode === "manual" && !postcssDetection.hasDependency) {
1790
+ _clack_prompts.log.message("Manual PostCSS setup needed:");
1791
+ _clack_prompts.log.message("1) Install PostCSS (npm install -D postcss).");
1792
+ _clack_prompts.log.message("2) Add postcss.config.js with { plugins: { 'boss-css/postcss': {} } }.");
1793
+ }
1794
+ if (installCommand) _clack_prompts.log.message(`Install dependencies before running the app: ${installCommand}`);
1795
+ if (isNext) {
1796
+ _clack_prompts.log.message("Next.js note:");
1797
+ if (selectedStrategyId === "classname-only") {
1798
+ const importRoot = normalizeImportPath(node_path.default.relative(srcRoot, configDir));
1799
+ const importStyles = normalizeImportPath(node_path.default.join(importRoot, "styles.css"));
1800
+ _clack_prompts.log.message(`- Classname-only mode skips instrumentation. Import ${importStyles} in your app entry.`);
1801
+ } else {
1802
+ _clack_prompts.log.message("- Updated instrumentation files with Boss CSS imports.");
1803
+ _clack_prompts.log.message("Boss PostCSS auto-disables dirDependencies when a Turbopack env flag is set.");
1804
+ if (!cssAutoLoad) {
1805
+ const importRoot = normalizeImportPath(node_path.default.relative(srcRoot, configDir));
1806
+ const importStyles = normalizeImportPath(node_path.default.join(importRoot, "styles.css"));
1807
+ _clack_prompts.log.message(`- css.autoLoad is false. Import ${importStyles} in your app entry.`);
1808
+ }
1809
+ }
1810
+ } else {
1811
+ const importRoot = normalizeImportPath(node_path.default.relative(srcRoot, configDir));
1812
+ const importStyles = normalizeImportPath(node_path.default.join(importRoot, "styles.css"));
1813
+ if (selectedStrategyId === "classname-only") {
1814
+ _clack_prompts.log.message("Add the generated stylesheet to your app entrypoint (e.g. src/main.tsx):");
1815
+ _clack_prompts.log.message(`import '${importStyles}'`);
1816
+ } else if (!cssAutoLoad) {
1817
+ _clack_prompts.log.message("Add these to your app entrypoint (e.g. src/main.tsx):");
1818
+ _clack_prompts.log.message(`import '${importRoot}'`);
1819
+ _clack_prompts.log.message(`import '${importStyles}'`);
1820
+ } else {
1821
+ _clack_prompts.log.message("Add this to your app entrypoint (e.g. src/main.tsx):");
1822
+ _clack_prompts.log.message(`import '${importRoot}'`);
1823
+ }
1824
+ }
1825
+ if (frameworkId === "stencil") {
1826
+ _clack_prompts.log.message("Stencil note:");
1827
+ _clack_prompts.log.message("- PostCSS setup is skipped; run `npx boss-css watch` for CSS generation.");
1828
+ }
1829
+ if (globalsEnabled) _clack_prompts.log.message("Global $$ enabled for JSX usage.");
1830
+ if (eslintUpdated) _clack_prompts.log.message(useEslintPlugin ? "ESLint updated with Boss CSS plugin." : "ESLint updated with $$ globals.");
1831
+ };
1832
+ var init_default = init;
1833
+
1834
+ //#endregion
1835
+ exports.default = init_default;