@roots/bud-build 0.0.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 (306) hide show
  1. package/LICENSE.md +19 -0
  2. package/README.md +120 -0
  3. package/docs/exports.md +13 -0
  4. package/docs/rules.md +32 -0
  5. package/lib/config/bail.d.ts +3 -0
  6. package/lib/config/bail.d.ts.map +1 -0
  7. package/lib/config/bail.js +2 -0
  8. package/lib/config/bail.js.map +1 -0
  9. package/lib/config/cache.d.ts +3 -0
  10. package/lib/config/cache.d.ts.map +1 -0
  11. package/lib/config/cache.js +2 -0
  12. package/lib/config/cache.js.map +1 -0
  13. package/lib/config/context.d.ts +3 -0
  14. package/lib/config/context.d.ts.map +1 -0
  15. package/lib/config/context.js +2 -0
  16. package/lib/config/context.js.map +1 -0
  17. package/lib/config/dependencies.d.ts +3 -0
  18. package/lib/config/dependencies.d.ts.map +1 -0
  19. package/lib/config/dependencies.js +5 -0
  20. package/lib/config/dependencies.js.map +1 -0
  21. package/lib/config/devtool.d.ts +3 -0
  22. package/lib/config/devtool.d.ts.map +1 -0
  23. package/lib/config/devtool.js +2 -0
  24. package/lib/config/devtool.js.map +1 -0
  25. package/lib/config/entry.d.ts +3 -0
  26. package/lib/config/entry.d.ts.map +1 -0
  27. package/lib/config/entry.js +2 -0
  28. package/lib/config/entry.js.map +1 -0
  29. package/lib/config/experiments.d.ts +3 -0
  30. package/lib/config/experiments.d.ts.map +1 -0
  31. package/lib/config/experiments.js +2 -0
  32. package/lib/config/experiments.js.map +1 -0
  33. package/lib/config/externals.d.ts +3 -0
  34. package/lib/config/externals.d.ts.map +1 -0
  35. package/lib/config/externals.js +2 -0
  36. package/lib/config/externals.js.map +1 -0
  37. package/lib/config/externalsType.d.ts +3 -0
  38. package/lib/config/externalsType.d.ts.map +1 -0
  39. package/lib/config/externalsType.js +2 -0
  40. package/lib/config/externalsType.js.map +1 -0
  41. package/lib/config/index.d.ts +35 -0
  42. package/lib/config/index.d.ts.map +1 -0
  43. package/lib/config/index.js +27 -0
  44. package/lib/config/index.js.map +1 -0
  45. package/lib/config/infrastructureLogging.d.ts +3 -0
  46. package/lib/config/infrastructureLogging.d.ts.map +1 -0
  47. package/lib/config/infrastructureLogging.js +14 -0
  48. package/lib/config/infrastructureLogging.js.map +1 -0
  49. package/lib/config/loader.d.ts +3 -0
  50. package/lib/config/loader.d.ts.map +1 -0
  51. package/lib/config/loader.js +2 -0
  52. package/lib/config/loader.js.map +1 -0
  53. package/lib/config/mode.d.ts +3 -0
  54. package/lib/config/mode.d.ts.map +1 -0
  55. package/lib/config/mode.js +2 -0
  56. package/lib/config/mode.js.map +1 -0
  57. package/lib/config/module.d.ts +3 -0
  58. package/lib/config/module.d.ts.map +1 -0
  59. package/lib/config/module.js +23 -0
  60. package/lib/config/module.js.map +1 -0
  61. package/lib/config/name.d.ts +3 -0
  62. package/lib/config/name.d.ts.map +1 -0
  63. package/lib/config/name.js +2 -0
  64. package/lib/config/name.js.map +1 -0
  65. package/lib/config/node.d.ts +3 -0
  66. package/lib/config/node.d.ts.map +1 -0
  67. package/lib/config/node.js +2 -0
  68. package/lib/config/node.js.map +1 -0
  69. package/lib/config/optimization.d.ts +3 -0
  70. package/lib/config/optimization.d.ts.map +1 -0
  71. package/lib/config/optimization.js +11 -0
  72. package/lib/config/optimization.js.map +1 -0
  73. package/lib/config/output/assetModuleFilename.d.ts +8 -0
  74. package/lib/config/output/assetModuleFilename.d.ts.map +1 -0
  75. package/lib/config/output/assetModuleFilename.js +2 -0
  76. package/lib/config/output/assetModuleFilename.js.map +1 -0
  77. package/lib/config/output/chunkFilename.d.ts +8 -0
  78. package/lib/config/output/chunkFilename.d.ts.map +1 -0
  79. package/lib/config/output/chunkFilename.js +4 -0
  80. package/lib/config/output/chunkFilename.js.map +1 -0
  81. package/lib/config/output/filename.d.ts +8 -0
  82. package/lib/config/output/filename.d.ts.map +1 -0
  83. package/lib/config/output/filename.js +3 -0
  84. package/lib/config/output/filename.js.map +1 -0
  85. package/lib/config/output/index.d.ts +3 -0
  86. package/lib/config/output/index.d.ts.map +1 -0
  87. package/lib/config/output/index.js +18 -0
  88. package/lib/config/output/index.js.map +1 -0
  89. package/lib/config/parallelism.d.ts +3 -0
  90. package/lib/config/parallelism.d.ts.map +1 -0
  91. package/lib/config/parallelism.js +3 -0
  92. package/lib/config/parallelism.js.map +1 -0
  93. package/lib/config/performance.d.ts +3 -0
  94. package/lib/config/performance.d.ts.map +1 -0
  95. package/lib/config/performance.js +2 -0
  96. package/lib/config/performance.js.map +1 -0
  97. package/lib/config/plugins.d.ts +3 -0
  98. package/lib/config/plugins.d.ts.map +1 -0
  99. package/lib/config/plugins.js +2 -0
  100. package/lib/config/plugins.js.map +1 -0
  101. package/lib/config/profile.d.ts +3 -0
  102. package/lib/config/profile.d.ts.map +1 -0
  103. package/lib/config/profile.js +2 -0
  104. package/lib/config/profile.js.map +1 -0
  105. package/lib/config/recordsPath.d.ts +3 -0
  106. package/lib/config/recordsPath.d.ts.map +1 -0
  107. package/lib/config/recordsPath.js +2 -0
  108. package/lib/config/recordsPath.js.map +1 -0
  109. package/lib/config/resolve.d.ts +3 -0
  110. package/lib/config/resolve.d.ts.map +1 -0
  111. package/lib/config/resolve.js +30 -0
  112. package/lib/config/resolve.js.map +1 -0
  113. package/lib/config/stats.d.ts +3 -0
  114. package/lib/config/stats.d.ts.map +1 -0
  115. package/lib/config/stats.js +17 -0
  116. package/lib/config/stats.js.map +1 -0
  117. package/lib/config/target.d.ts +3 -0
  118. package/lib/config/target.d.ts.map +1 -0
  119. package/lib/config/target.js +4 -0
  120. package/lib/config/target.js.map +1 -0
  121. package/lib/handlers/index.d.ts +19 -0
  122. package/lib/handlers/index.d.ts.map +1 -0
  123. package/lib/handlers/index.js +6 -0
  124. package/lib/handlers/index.js.map +1 -0
  125. package/lib/handlers/items/items.d.ts +47 -0
  126. package/lib/handlers/items/items.d.ts.map +1 -0
  127. package/lib/handlers/items/items.js +69 -0
  128. package/lib/handlers/items/items.js.map +1 -0
  129. package/lib/handlers/loaders/loaders.d.ts +12 -0
  130. package/lib/handlers/loaders/loaders.d.ts.map +1 -0
  131. package/lib/handlers/loaders/loaders.js +11 -0
  132. package/lib/handlers/loaders/loaders.js.map +1 -0
  133. package/lib/handlers/register.d.ts +14 -0
  134. package/lib/handlers/register.d.ts.map +1 -0
  135. package/lib/handlers/register.js +26 -0
  136. package/lib/handlers/register.js.map +1 -0
  137. package/lib/handlers/rules/css.d.ts +3 -0
  138. package/lib/handlers/rules/css.d.ts.map +1 -0
  139. package/lib/handlers/rules/css.js +5 -0
  140. package/lib/handlers/rules/css.js.map +1 -0
  141. package/lib/handlers/rules/css.module.d.ts +3 -0
  142. package/lib/handlers/rules/css.module.d.ts.map +1 -0
  143. package/lib/handlers/rules/css.module.js +5 -0
  144. package/lib/handlers/rules/css.module.js.map +1 -0
  145. package/lib/handlers/rules/csv.d.ts +3 -0
  146. package/lib/handlers/rules/csv.d.ts.map +1 -0
  147. package/lib/handlers/rules/csv.js +5 -0
  148. package/lib/handlers/rules/csv.js.map +1 -0
  149. package/lib/handlers/rules/font.d.ts +3 -0
  150. package/lib/handlers/rules/font.d.ts.map +1 -0
  151. package/lib/handlers/rules/font.inline.d.ts +3 -0
  152. package/lib/handlers/rules/font.inline.d.ts.map +1 -0
  153. package/lib/handlers/rules/font.inline.js +6 -0
  154. package/lib/handlers/rules/font.inline.js.map +1 -0
  155. package/lib/handlers/rules/font.js +5 -0
  156. package/lib/handlers/rules/font.js.map +1 -0
  157. package/lib/handlers/rules/html.d.ts +3 -0
  158. package/lib/handlers/rules/html.d.ts.map +1 -0
  159. package/lib/handlers/rules/html.js +5 -0
  160. package/lib/handlers/rules/html.js.map +1 -0
  161. package/lib/handlers/rules/image.d.ts +3 -0
  162. package/lib/handlers/rules/image.d.ts.map +1 -0
  163. package/lib/handlers/rules/image.inline.d.ts +3 -0
  164. package/lib/handlers/rules/image.inline.d.ts.map +1 -0
  165. package/lib/handlers/rules/image.inline.js +6 -0
  166. package/lib/handlers/rules/image.inline.js.map +1 -0
  167. package/lib/handlers/rules/image.js +5 -0
  168. package/lib/handlers/rules/image.js.map +1 -0
  169. package/lib/handlers/rules/index.d.ts +19 -0
  170. package/lib/handlers/rules/index.d.ts.map +1 -0
  171. package/lib/handlers/rules/index.js +35 -0
  172. package/lib/handlers/rules/index.js.map +1 -0
  173. package/lib/handlers/rules/js.d.ts +3 -0
  174. package/lib/handlers/rules/js.d.ts.map +1 -0
  175. package/lib/handlers/rules/js.js +5 -0
  176. package/lib/handlers/rules/js.js.map +1 -0
  177. package/lib/handlers/rules/json.d.ts +3 -0
  178. package/lib/handlers/rules/json.d.ts.map +1 -0
  179. package/lib/handlers/rules/json.js +7 -0
  180. package/lib/handlers/rules/json.js.map +1 -0
  181. package/lib/handlers/rules/svg.d.ts +3 -0
  182. package/lib/handlers/rules/svg.d.ts.map +1 -0
  183. package/lib/handlers/rules/svg.inline.d.ts +5 -0
  184. package/lib/handlers/rules/svg.inline.d.ts.map +1 -0
  185. package/lib/handlers/rules/svg.inline.js +9 -0
  186. package/lib/handlers/rules/svg.inline.js.map +1 -0
  187. package/lib/handlers/rules/svg.js +5 -0
  188. package/lib/handlers/rules/svg.js.map +1 -0
  189. package/lib/handlers/rules/toml.d.ts +3 -0
  190. package/lib/handlers/rules/toml.d.ts.map +1 -0
  191. package/lib/handlers/rules/toml.js +7 -0
  192. package/lib/handlers/rules/toml.js.map +1 -0
  193. package/lib/handlers/rules/webp.d.ts +3 -0
  194. package/lib/handlers/rules/webp.d.ts.map +1 -0
  195. package/lib/handlers/rules/webp.js +5 -0
  196. package/lib/handlers/rules/webp.js.map +1 -0
  197. package/lib/handlers/rules/xml.d.ts +3 -0
  198. package/lib/handlers/rules/xml.d.ts.map +1 -0
  199. package/lib/handlers/rules/xml.js +5 -0
  200. package/lib/handlers/rules/xml.js.map +1 -0
  201. package/lib/handlers/rules/yml.d.ts +3 -0
  202. package/lib/handlers/rules/yml.d.ts.map +1 -0
  203. package/lib/handlers/rules/yml.js +5 -0
  204. package/lib/handlers/rules/yml.js.map +1 -0
  205. package/lib/helpers/isMjs.d.ts +3 -0
  206. package/lib/helpers/isMjs.d.ts.map +1 -0
  207. package/lib/helpers/isMjs.js +2 -0
  208. package/lib/helpers/isMjs.js.map +1 -0
  209. package/lib/helpers/scriptExtension.d.ts +3 -0
  210. package/lib/helpers/scriptExtension.d.ts.map +1 -0
  211. package/lib/helpers/scriptExtension.js +5 -0
  212. package/lib/helpers/scriptExtension.js.map +1 -0
  213. package/lib/index.d.ts +12 -0
  214. package/lib/index.d.ts.map +1 -0
  215. package/lib/index.js +14 -0
  216. package/lib/index.js.map +1 -0
  217. package/lib/item/index.d.ts +84 -0
  218. package/lib/item/index.d.ts.map +1 -0
  219. package/lib/item/index.js +165 -0
  220. package/lib/item/index.js.map +1 -0
  221. package/lib/loader/index.d.ts +26 -0
  222. package/lib/loader/index.d.ts.map +1 -0
  223. package/lib/loader/index.js +28 -0
  224. package/lib/loader/index.js.map +1 -0
  225. package/lib/rule/index.d.ts +118 -0
  226. package/lib/rule/index.d.ts.map +1 -0
  227. package/lib/rule/index.js +261 -0
  228. package/lib/rule/index.js.map +1 -0
  229. package/lib/service.d.ts +84 -0
  230. package/lib/service.d.ts.map +1 -0
  231. package/lib/service.js +212 -0
  232. package/lib/service.js.map +1 -0
  233. package/lib/shared/base.d.ts +20 -0
  234. package/lib/shared/base.d.ts.map +1 -0
  235. package/lib/shared/base.js +43 -0
  236. package/lib/shared/base.js.map +1 -0
  237. package/lib/types.d.ts +52 -0
  238. package/lib/types.d.ts.map +1 -0
  239. package/lib/types.js +4 -0
  240. package/lib/types.js.map +1 -0
  241. package/package.json +97 -0
  242. package/src/config/bail.ts +4 -0
  243. package/src/config/cache.ts +4 -0
  244. package/src/config/context.ts +3 -0
  245. package/src/config/dependencies.ts +11 -0
  246. package/src/config/devtool.ts +4 -0
  247. package/src/config/entry.ts +4 -0
  248. package/src/config/experiments.ts +4 -0
  249. package/src/config/externals.ts +4 -0
  250. package/src/config/externalsType.ts +3 -0
  251. package/src/config/index.test.ts +129 -0
  252. package/src/config/index.ts +67 -0
  253. package/src/config/infrastructureLogging.ts +18 -0
  254. package/src/config/loader.ts +4 -0
  255. package/src/config/mode.ts +4 -0
  256. package/src/config/module.ts +45 -0
  257. package/src/config/name.ts +4 -0
  258. package/src/config/node.ts +4 -0
  259. package/src/config/optimization.ts +20 -0
  260. package/src/config/output/assetModuleFilename.ts +9 -0
  261. package/src/config/output/chunkFilename.ts +18 -0
  262. package/src/config/output/filename.ts +14 -0
  263. package/src/config/output/index.ts +28 -0
  264. package/src/config/parallelism.ts +6 -0
  265. package/src/config/performance.ts +4 -0
  266. package/src/config/plugins.ts +4 -0
  267. package/src/config/profile.ts +4 -0
  268. package/src/config/recordsPath.ts +7 -0
  269. package/src/config/resolve.ts +45 -0
  270. package/src/config/stats.ts +22 -0
  271. package/src/config/target.ts +9 -0
  272. package/src/handlers/index.ts +22 -0
  273. package/src/handlers/items/items.ts +93 -0
  274. package/src/handlers/loaders/loaders.ts +31 -0
  275. package/src/handlers/register.ts +47 -0
  276. package/src/handlers/rules/css.module.ts +7 -0
  277. package/src/handlers/rules/css.ts +7 -0
  278. package/src/handlers/rules/csv.test.ts +28 -0
  279. package/src/handlers/rules/csv.ts +7 -0
  280. package/src/handlers/rules/font.inline.ts +8 -0
  281. package/src/handlers/rules/font.ts +7 -0
  282. package/src/handlers/rules/html.ts +7 -0
  283. package/src/handlers/rules/image.inline.ts +8 -0
  284. package/src/handlers/rules/image.ts +7 -0
  285. package/src/handlers/rules/index.ts +35 -0
  286. package/src/handlers/rules/js.ts +7 -0
  287. package/src/handlers/rules/json.ts +10 -0
  288. package/src/handlers/rules/svg.inline.test.ts +30 -0
  289. package/src/handlers/rules/svg.inline.ts +13 -0
  290. package/src/handlers/rules/svg.ts +7 -0
  291. package/src/handlers/rules/toml.test.ts +22 -0
  292. package/src/handlers/rules/toml.ts +10 -0
  293. package/src/handlers/rules/webp.ts +7 -0
  294. package/src/handlers/rules/xml.test.ts +27 -0
  295. package/src/handlers/rules/xml.ts +7 -0
  296. package/src/handlers/rules/yml.ts +7 -0
  297. package/src/helpers/isMjs.ts +4 -0
  298. package/src/helpers/scriptExtension.ts +11 -0
  299. package/src/index.ts +17 -0
  300. package/src/item/index.ts +179 -0
  301. package/src/loader/index.ts +38 -0
  302. package/src/rule/index.test.ts +88 -0
  303. package/src/rule/index.ts +257 -0
  304. package/src/service.ts +204 -0
  305. package/src/shared/base.ts +37 -0
  306. package/src/types.ts +57 -0
@@ -0,0 +1,88 @@
1
+ import {factory} from '@repo/test-kit/bud'
2
+ import {beforeAll, describe, expect, it} from 'vitest'
3
+
4
+ import {Rule} from './index.js'
5
+
6
+ describe(`Build Rule`, function () {
7
+ let bud
8
+
9
+ beforeAll(async () => {
10
+ bud = await factory()
11
+ })
12
+
13
+ it(`is constructable`, () => {
14
+ const rule = {test: /.foo$/}
15
+ expect(new Rule(() => bud, rule)).toBeInstanceOf(Rule)
16
+ })
17
+
18
+ it(`make`, () => {
19
+ const rule = {test: /.foo$/}
20
+ expect(new Rule(() => bud, rule).toWebpack()).toEqual({
21
+ test: /.foo$/,
22
+ })
23
+ })
24
+
25
+ it(`getUse`, () => {
26
+ const input = [`md`]
27
+ const rule = new Rule(() => bud, {
28
+ test: /.foo$/,
29
+ // @ts-ignore
30
+ use: input,
31
+ })
32
+
33
+ expect(rule.getUse()).toEqual(input)
34
+ })
35
+
36
+ it(`setUse`, () => {
37
+ const input = [`raw`, `md`]
38
+ const rule = new Rule(() => bud, {test: /.foo$/})
39
+ // @ts-ignore
40
+ rule.setUse(input)
41
+
42
+ expect(rule.use).toEqual(input)
43
+ })
44
+
45
+ it(`getTest`, () => {
46
+ const input = /.foo$/
47
+ const rule = new Rule(() => bud, {test: input})
48
+
49
+ expect(rule.getTest()).toEqual(input)
50
+ })
51
+
52
+ it(`setTest`, () => {
53
+ const input = () => /.js$/
54
+ const rule = new Rule(() => bud, {test: /.foo$/})
55
+ rule.setTest(input)
56
+
57
+ expect(rule.test).toEqual(input)
58
+ })
59
+
60
+ it(`getExclude`, () => {
61
+ const definition = {
62
+ test: /.foo$/,
63
+ exclude: [/.bar$/],
64
+ }
65
+
66
+ const rule = new Rule(() => bud, definition)
67
+
68
+ expect(rule.exclude).toEqual(definition.exclude)
69
+ })
70
+
71
+ it(`setExclude from fn`, () => {
72
+ const rule = new Rule(() => bud, {test: /.foo$/})
73
+
74
+ const mutationFn = () => [/.js$/]
75
+ rule.setExclude(mutationFn)
76
+
77
+ expect(rule.getExclude()).toEqual([/.js$/])
78
+ })
79
+
80
+ it(`setExclude from obj`, () => {
81
+ const rule = new Rule(() => bud, {test: /.foo$/})
82
+
83
+ const mutation = [/.js$/]
84
+ rule.setExclude(mutation)
85
+
86
+ expect(rule.getExclude()).toStrictEqual(mutation)
87
+ })
88
+ })
@@ -0,0 +1,257 @@
1
+ import type {Bud} from '@roots/bud-framework'
2
+ import type {
3
+ Options,
4
+ Output,
5
+ Parser,
6
+ Rule as Interface,
7
+ } from '@roots/bud-framework/services/build/rule'
8
+ import {bind} from '@roots/bud-support/decorators'
9
+ import isFunction from '@roots/bud-support/lodash/isFunction'
10
+ import isString from '@roots/bud-support/lodash/isString'
11
+ import type {RuleSetRule} from '@roots/bud-support/webpack'
12
+
13
+ import Base from '../shared/base.js'
14
+
15
+ /**
16
+ * RuleSetRule
17
+ */
18
+ class Rule extends Base implements Interface {
19
+ /**
20
+ * RuleSetRule test
21
+ */
22
+ public test: Options['test']
23
+
24
+ /**
25
+ * RuleSetRule use
26
+ */
27
+ public use?: Options[`use`]
28
+
29
+ /**
30
+ * RuleSetRule include
31
+ */
32
+ public include?: Options['include']
33
+
34
+ /**
35
+ * RuleSetRule exclude
36
+ */
37
+ public exclude?: Options['exclude']
38
+
39
+ /**
40
+ * RuleSetRule type
41
+ */
42
+ public type?: Options['type']
43
+
44
+ /**
45
+ * RuleSetRule resourceQuery
46
+ */
47
+ public resourceQuery?: Options['resourceQuery']
48
+
49
+ /**
50
+ * RuleSetRule parser
51
+ */
52
+ public parser?: Options['parser']
53
+
54
+ /**
55
+ * RuleSetRule generator
56
+ */
57
+ public generator?: Options['generator']
58
+
59
+ /**
60
+ * Class constructor
61
+ */
62
+ public constructor(_app: () => Bud, options?: Options) {
63
+ super(_app)
64
+ this._app = _app
65
+
66
+ if (!options) return
67
+
68
+ this.setTest(options.test)
69
+ this.setUse(options.use)
70
+ this.setInclude(options.include)
71
+ this.setExclude(options.exclude)
72
+ this.setType(options.type)
73
+ this.setParser(options.parser)
74
+ this.setGenerator(options.generator)
75
+ }
76
+
77
+ /**
78
+ * Test value
79
+ */
80
+ @bind
81
+ public getTest(): Output['test'] {
82
+ return this.unwrap(this.test)
83
+ }
84
+
85
+ /**
86
+ * Set test value
87
+ */
88
+ @bind
89
+ public setTest(test: Options['test']): this {
90
+ this.test = test
91
+ return this
92
+ }
93
+
94
+ /**
95
+ * Get parser value
96
+ */
97
+ @bind
98
+ public getParser(): Output['parser'] {
99
+ return this.unwrap(this.parser)
100
+ }
101
+
102
+ /**
103
+ * Set parser value
104
+ */
105
+ @bind
106
+ public setParser(parser: Interface['parser']): this {
107
+ this.parser = this.wrap(parser)
108
+ return this
109
+ }
110
+
111
+ /**
112
+ * Get use value
113
+ */
114
+ @bind
115
+ public getUse(): Options[`use`] {
116
+ return this.use
117
+ }
118
+
119
+ /**
120
+ * Set use value
121
+ */
122
+ @bind
123
+ public setUse(
124
+ use: Options[`use`] | ((use: Options[`use`]) => Options[`use`]),
125
+ ): this {
126
+ this.use = isFunction(use) ? use(this.getUse()) : use
127
+ return this
128
+ }
129
+
130
+ /**
131
+ * Get include value
132
+ */
133
+ @bind
134
+ public getInclude(): Array<string | RegExp> {
135
+ return this.include?.map(item =>
136
+ isFunction(item) ? item(this.app) : item,
137
+ )
138
+ }
139
+
140
+ /**
141
+ * Set include value
142
+ */
143
+ @bind
144
+ public setInclude(includes: Options['include']): this {
145
+ this.include = isFunction(includes) ? includes(this.include) : includes
146
+ return this
147
+ }
148
+
149
+ /**
150
+ * Get include value
151
+ */
152
+ @bind
153
+ public getResourceQuery(): Output[`resourceQuery`] {
154
+ return this.resourceQuery
155
+ }
156
+
157
+ /**
158
+ * Set include value
159
+ */
160
+ @bind
161
+ public setResourceQuery(query: Options['resourceQuery']): this {
162
+ this.resourceQuery = query
163
+ return this
164
+ }
165
+
166
+ /**
167
+ * Get exclude value
168
+ */
169
+ @bind
170
+ public getExclude(): Array<string | RegExp> {
171
+ return this.exclude?.map(this.unwrap)
172
+ }
173
+
174
+ /**
175
+ * Set exclude value
176
+ */
177
+ @bind
178
+ public setExclude(
179
+ excludes:
180
+ | Options['exclude']
181
+ | ((excludes: Options['exclude']) => Options['exclude']),
182
+ ): this {
183
+ this.exclude = isFunction(excludes) ? excludes(this.exclude) : excludes
184
+ return this
185
+ }
186
+
187
+ /**
188
+ * Get type value
189
+ */
190
+ @bind
191
+ public getType(): string {
192
+ return this.unwrap(this.type)
193
+ }
194
+
195
+ /**
196
+ * Set type value
197
+ */
198
+ @bind
199
+ public setType(type: Options[`type`]): this {
200
+ this.type = type
201
+ return this
202
+ }
203
+
204
+ /**
205
+ * Get generator value
206
+ */
207
+ @bind
208
+ public getGenerator() {
209
+ return this.unwrap(this.generator)
210
+ }
211
+
212
+ /**
213
+ * Set generator value
214
+ */
215
+ @bind
216
+ public setGenerator(generator: Options['generator']): this {
217
+ this.generator = this.wrap(generator)
218
+ return this
219
+ }
220
+
221
+ /**
222
+ * Produce final Base output
223
+ */
224
+ @bind
225
+ public toWebpack(): Output & RuleSetRule {
226
+ const output: Output = Object.entries({
227
+ test: this.getTest(),
228
+ type: this.getType(),
229
+ parser: this.getParser(),
230
+ generator: this.getGenerator(),
231
+ use: this.getUse()
232
+ ?.filter(Boolean)
233
+ .map(item =>
234
+ isString(item) && item in this.app.build.items
235
+ ? this.app.build.items[item]
236
+ : item,
237
+ )
238
+ .filter(Boolean)
239
+ .map(item =>
240
+ !isString(item) && `toWebpack` in item ? item.toWebpack() : item,
241
+ ),
242
+ resourceQuery: this.getResourceQuery(),
243
+ include: this.getInclude(),
244
+ exclude: this.getExclude(),
245
+ }).reduce((a, [k, v]) => {
246
+ if (v === undefined) return a
247
+ return {...a, [k]: v}
248
+ }, {})
249
+
250
+ this.app.info(output)
251
+
252
+ return output
253
+ }
254
+ }
255
+
256
+ export {Rule}
257
+ export {Interface, Options, Output, Parser}
package/src/service.ts ADDED
@@ -0,0 +1,204 @@
1
+ import type {Items, Loaders, Rules} from '@roots/bud-framework'
2
+ import {Service} from '@roots/bud-framework/service'
3
+ import type * as Base from '@roots/bud-framework/services/build'
4
+ import {bind} from '@roots/bud-support/decorators'
5
+ import isFunction from '@roots/bud-support/lodash/isFunction'
6
+ import isUndefined from '@roots/bud-support/lodash/isUndefined'
7
+ import type {Configuration} from '@roots/bud-support/webpack'
8
+
9
+ import type {Records} from './config/index.js'
10
+ import {register} from './handlers/register.js'
11
+ import {Item} from './item/index.js'
12
+ import {Loader} from './loader/index.js'
13
+ import {Options as RuleOptions, Rule} from './rule/index.js'
14
+
15
+ /**
16
+ * Webpack configuration builder class
17
+ */
18
+ export class Build extends Service implements Base.Service {
19
+ /**
20
+ * Built config object
21
+ */
22
+ public config: Partial<Configuration> = {}
23
+
24
+ /**
25
+ * Registered loaders
26
+ *
27
+ * @public
28
+ */
29
+ public loaders: Loaders = {} as Loaders
30
+
31
+ /**
32
+ * Registered rules
33
+ *
34
+ * @public
35
+ */
36
+ public rules: Rules = {} as Rules
37
+
38
+ /**
39
+ * Registered items
40
+ *
41
+ * @public
42
+ */
43
+ public items: Items = {} as Items
44
+
45
+ /**
46
+ * Service register event
47
+ *
48
+ * @remarks
49
+ * `loaders`, `items`, and `rules` are instantiated dumbly
50
+ * because it is painful to think about how to map the typings..
51
+ */
52
+ public override register? = register.bind(this)
53
+
54
+ /**
55
+ * Make webpack configuration
56
+ */
57
+ @bind
58
+ public async make(): Promise<Configuration> {
59
+ this.logger.log(`bud.build.make called`)
60
+ await this.app.hooks.fire(`build.before`, this.app)
61
+
62
+ await import(`./config/index.js`).then(
63
+ async (records: Records) =>
64
+ await Promise.all(
65
+ Object.entries(records).map(async ([prop, factory]) => {
66
+ try {
67
+ const value = await factory(this.app)
68
+ if (isUndefined(value)) return
69
+
70
+ this.config[prop] = value
71
+ this.logger.success(`built`, prop)
72
+ } catch (error) {
73
+ throw error
74
+ }
75
+ }),
76
+ ),
77
+ )
78
+
79
+ this.logger.success(`configuration successfully built`)
80
+ await this.app.hooks.fire(`build.after`, this.app)
81
+
82
+ return this.config
83
+ }
84
+
85
+ /**
86
+ * Get rule
87
+ */
88
+ @bind
89
+ public getRule<K extends `${keyof Rules & string}`>(ident: K): Rules[K] {
90
+ return this.rules[ident]
91
+ }
92
+
93
+ /**
94
+ * Set Rule
95
+ */
96
+ @bind
97
+ public setRule<K extends `${keyof Rules & string}`>(
98
+ name: K,
99
+ input?: RuleOptions | Rule,
100
+ ): this {
101
+ this.rules[name] =
102
+ input instanceof Rule
103
+ ? input
104
+ : isFunction(input)
105
+ ? input(this.makeRule())
106
+ : this.makeRule(input as any)
107
+
108
+ this.logger.success(`set rule:`, name)
109
+ this.logger.info(`\n`, this.rules[name])
110
+
111
+ return this
112
+ }
113
+
114
+ /**
115
+ * Make Rule
116
+ */
117
+ @bind
118
+ public makeRule(options?: RuleOptions): Rule {
119
+ return new Rule(() => this.app, options)
120
+ }
121
+
122
+ /**
123
+ * Get loader
124
+ */
125
+ @bind
126
+ public getLoader(name: string): Loader {
127
+ if (!this.loaders[name])
128
+ this.logger.error(
129
+ `loader ${name} was requested but is not registered`,
130
+ )
131
+
132
+ return this.loaders[name]
133
+ }
134
+ /**
135
+ * Set loader
136
+ */
137
+ @bind
138
+ public setLoader<K extends `${keyof Loaders & string}`>(
139
+ name: K,
140
+ definition?: any,
141
+ ): this {
142
+ const loader = isUndefined(definition)
143
+ ? this.makeLoader(name)
144
+ : definition instanceof Loader
145
+ ? definition
146
+ : this.makeLoader(definition)
147
+
148
+ this.loaders[name] = loader
149
+ this.logger.info(`set loader`, loader)
150
+
151
+ return this
152
+ }
153
+
154
+ /**
155
+ * Make loader
156
+ */
157
+ @bind
158
+ public makeLoader(src?: string): Loader {
159
+ return new Loader(() => this.app, src)
160
+ }
161
+
162
+ /**
163
+ * Get item
164
+ */
165
+ @bind
166
+ public getItem(name: `${keyof Items & string}`): Item {
167
+ if (!this.items[name])
168
+ this.logger.error(
169
+ `loader ${name} was requested but is not registered`,
170
+ )
171
+
172
+ return this.items[name]
173
+ }
174
+
175
+ /**
176
+ * Set item
177
+ */
178
+ @bind
179
+ public setItem<K extends `${keyof Items & string}`>(
180
+ ident: K,
181
+ options?: Items[K]['options'] | ((item: Items[K]) => Items[K]),
182
+ ): this {
183
+ const maybeOptionsCallback = isUndefined(options)
184
+ ? {ident, loader: ident}
185
+ : options
186
+
187
+ const item = isFunction(maybeOptionsCallback)
188
+ ? maybeOptionsCallback(this.makeItem())
189
+ : this.makeItem(maybeOptionsCallback)
190
+
191
+ this.items[ident] = item
192
+ this.logger.info(`set item`, item)
193
+
194
+ return this
195
+ }
196
+
197
+ /**
198
+ * Make item
199
+ */
200
+ @bind
201
+ public makeItem(options?: Partial<Item['options']>): Item {
202
+ return new Item(() => this.app, options)
203
+ }
204
+ }
@@ -0,0 +1,37 @@
1
+ import type {Bud} from '@roots/bud-framework'
2
+ import type {Base as BuildBase} from '@roots/bud-framework/services/build'
3
+ import {bind} from '@roots/bud-support/decorators'
4
+ import isFunction from '@roots/bud-support/lodash/isFunction'
5
+
6
+ export default class Base implements BuildBase {
7
+ /**
8
+ * Application getter
9
+ *
10
+ * @readonly @public
11
+ */
12
+ public get app(): Bud {
13
+ return this._app()
14
+ }
15
+
16
+ /**
17
+ * Constructor
18
+ *
19
+ * @public
20
+ */
21
+ public constructor(public _app: () => Bud) {}
22
+
23
+ @bind
24
+ public wrap<T = any>(input: T | ((app: Bud) => T)): (app: Bud) => T {
25
+ return isFunction(input) ? input : () => input
26
+ }
27
+
28
+ @bind
29
+ public unwrap<T = any>(
30
+ maybeFunction: T | ((app: Bud, ...options: Array<any>) => T),
31
+ ...options: Array<any>
32
+ ): T {
33
+ return isFunction(maybeFunction)
34
+ ? maybeFunction(this.app, ...options)
35
+ : maybeFunction
36
+ }
37
+ }
package/src/types.ts ADDED
@@ -0,0 +1,57 @@
1
+ /// <reference types="@roots/bud-framework" />
2
+ /// <reference types="@roots/bud-hooks" />
3
+
4
+ import type {Item} from './item/index.js'
5
+ import type {Loader} from './loader/index.js'
6
+ import type {Rule} from './rule/index.js'
7
+
8
+ declare module '@roots/bud-framework' {
9
+ interface Loaders {
10
+ css: Loader
11
+ csv: Loader
12
+ file: Loader
13
+ html: Loader
14
+ md: Loader
15
+ minicss: Loader
16
+ raw: Loader
17
+ style: Loader
18
+ url: Loader
19
+ xml: Loader
20
+ yml: Loader
21
+ }
22
+
23
+ interface Items {
24
+ precss: Item
25
+ minicss: Item
26
+ style: Item
27
+ css: Item
28
+ cssModule: Item
29
+ csv: Item
30
+ file: Item
31
+ image: Item
32
+ font: Item
33
+ html: Item
34
+ md: Item
35
+ raw: Item
36
+ xml: Item
37
+ yml: Item
38
+ }
39
+
40
+ interface Rules {
41
+ js: Rule
42
+ css: Rule
43
+ cssModule: Rule
44
+ html: Rule
45
+ svg: Rule
46
+ image: Rule
47
+ font: Rule
48
+ xml: Rule
49
+ json: Rule
50
+ csv: Rule
51
+ yml: Rule
52
+ toml: Rule
53
+ inlineSvg: Rule
54
+ inlineFont: Rule
55
+ inlineImage: Rule
56
+ }
57
+ }