@abreen/tada 1.0.2 → 1.2.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 (146) hide show
  1. package/README.md +96 -48
  2. package/bin/tada.ts +621 -0
  3. package/bin/validators.test.ts +205 -0
  4. package/bin/validators.ts +85 -0
  5. package/{webpack/apply-base-path-plugin.js → build/apply-base-path-plugin.ts} +37 -17
  6. package/build/build-manifest.test.ts +349 -0
  7. package/build/build-manifest.ts +165 -0
  8. package/build/bundle.ts +116 -0
  9. package/{webpack/code.test.js → build/code.test.ts} +10 -7
  10. package/build/colors.ts +25 -0
  11. package/build/content-watch.ts +107 -0
  12. package/build/copy.ts +118 -0
  13. package/{webpack/deflist-id-plugin.js → build/deflist-id-plugin.ts} +7 -6
  14. package/{webpack/external-links-plugin.js → build/external-links-plugin.ts} +14 -5
  15. package/build/features.ts +11 -0
  16. package/build/generate-content-assets.ts +320 -0
  17. package/build/generate-favicon.ts +172 -0
  18. package/build/generate-fonts.ts +31 -0
  19. package/build/generate-katex-assets.ts +35 -0
  20. package/{webpack/generate-manifest-plugin.js → build/generate-manifest.ts} +29 -36
  21. package/build/globals.test.ts +99 -0
  22. package/build/globals.ts +88 -0
  23. package/{webpack/heading-subtitle-plugin.js → build/heading-subtitle-plugin.ts} +4 -2
  24. package/build/json-schema.test.ts +57 -0
  25. package/build/json-schema.ts +33 -0
  26. package/build/log.test.ts +111 -0
  27. package/build/log.ts +167 -0
  28. package/build/markdown-plugins.test.ts +396 -0
  29. package/{webpack/pagefind-plugin.test.js → build/pagefind.test.ts} +74 -13
  30. package/build/pagefind.ts +339 -0
  31. package/build/pdf-text.test.ts +52 -0
  32. package/{webpack/pdf-text.js → build/pdf-text.ts} +47 -27
  33. package/build/pipeline.ts +120 -0
  34. package/{webpack/reachability.test.js → build/reachability.test.ts} +3 -3
  35. package/{webpack/reachability.js → build/reachability.ts} +77 -34
  36. package/build/serve.ts +112 -0
  37. package/build/site-variables.ts +68 -0
  38. package/{webpack/templates.js → build/templates.ts} +38 -35
  39. package/{webpack/text-to-id.js → build/text-to-id.ts} +2 -2
  40. package/build/toc-plugin.test.ts +105 -0
  41. package/{webpack/toc-plugin.js → build/toc-plugin.ts} +32 -13
  42. package/build/types.ts +181 -0
  43. package/build/util.ts +26 -0
  44. package/{webpack/utils/code.js → build/utils/code.ts} +119 -60
  45. package/{webpack/utils/content-files.js → build/utils/content-files.ts} +40 -35
  46. package/build/utils/derive-theme.test.ts +111 -0
  47. package/build/utils/derive-theme.ts +85 -0
  48. package/build/utils/file-types.test.ts +61 -0
  49. package/build/utils/file-types.ts +13 -0
  50. package/build/utils/front-matter.test.ts +77 -0
  51. package/{webpack/utils/front-matter.js → build/utils/front-matter.ts} +22 -9
  52. package/{webpack → build}/utils/jdi-runner/LiterateRunner.java +1 -1
  53. package/{webpack/utils/literate-java.js → build/utils/literate-java.ts} +68 -38
  54. package/{webpack/utils/markdown.js → build/utils/markdown.ts} +126 -49
  55. package/build/utils/paths.test.ts +91 -0
  56. package/{webpack/utils/paths.js → build/utils/paths.ts} +18 -22
  57. package/{webpack/utils/render.js → build/utils/render.ts} +208 -130
  58. package/build/utils/shiki-highlighter.ts +29 -0
  59. package/build/validate-internal-links-plugin.test.ts +106 -0
  60. package/{webpack/validate-internal-links-plugin.js → build/validate-internal-links-plugin.ts} +47 -20
  61. package/{webpack/watch-reachability-state.test.js → build/watch-reachability-state.test.ts} +8 -8
  62. package/{webpack/watch-reachability-state.js → build/watch-reachability-state.ts} +63 -24
  63. package/{webpack/watch-reload-client.js → build/watch-reload-client.ts} +3 -1
  64. package/build/watch.ts +549 -0
  65. package/fonts/google-sans-code/woff2/GoogleSansCodeVariable-Italic.woff2 +0 -0
  66. package/fonts/google-sans-code/woff2/GoogleSansCodeVariable.woff2 +0 -0
  67. package/fonts/inter/woff2/InterVariable-Italic.woff2 +0 -0
  68. package/fonts/inter/woff2/InterVariable.woff2 +0 -0
  69. package/{content → init/content}/index.md +9 -3
  70. package/{content → init/content}/lectures/index.md +1 -1
  71. package/{content → init/content}/markdown.md +28 -8
  72. package/init/content/problem_sets/index.html +14 -0
  73. package/package.json +33 -22
  74. package/{templates → schema}/nav.schema.json +1 -2
  75. package/{webpack → schema}/site.schema.json +4 -12
  76. package/src/_alerts.scss +96 -0
  77. package/src/_base.scss +145 -0
  78. package/src/{layout.scss → _layout.scss} +36 -1
  79. package/src/anchor/index.ts +0 -1
  80. package/src/anchor/style.scss +1 -9
  81. package/src/code/index.ts +3 -3
  82. package/src/code.scss +1 -1
  83. package/src/critical.scss +5 -0
  84. package/src/header/_base.scss +129 -0
  85. package/src/header/style.scss +3 -131
  86. package/src/index.ts +4 -5
  87. package/src/question/style.scss +1 -1
  88. package/src/search/index.test.ts +203 -0
  89. package/src/search/index.ts +38 -93
  90. package/src/search/pdf-utils.ts +79 -0
  91. package/src/search/style.scss +8 -28
  92. package/src/style.scss +15 -326
  93. package/src/timezone/index.ts +5 -6
  94. package/src/toc/style.scss +5 -39
  95. package/src/util.ts +9 -6
  96. package/templates/_theme.scss +38 -14
  97. package/templates/_top.html +1 -1
  98. package/tsconfig.json +10 -6
  99. package/types/dev.d.ts +1 -0
  100. package/types/file-system-access.d.ts +5 -0
  101. package/types/markdown-it-plugins.d.ts +11 -0
  102. package/types/site-variables.d.ts +6 -10
  103. package/types/untyped-modules.d.ts +47 -0
  104. package/bin/tada.js +0 -361
  105. package/config/authors.json +0 -1
  106. package/config/nav.json +0 -28
  107. package/content/problem_sets/index.md +0 -6
  108. package/types/dev.ts +0 -3
  109. package/webpack/build-state.js +0 -97
  110. package/webpack/colors.js +0 -15
  111. package/webpack/config.base.js +0 -151
  112. package/webpack/config.dev.js +0 -23
  113. package/webpack/config.prod.js +0 -32
  114. package/webpack/content-watch-plugin.js +0 -153
  115. package/webpack/features.js +0 -5
  116. package/webpack/generate-content-assets-plugin.js +0 -308
  117. package/webpack/generate-favicon-plugin.js +0 -198
  118. package/webpack/generate-fonts-plugin.js +0 -69
  119. package/webpack/globals.js +0 -74
  120. package/webpack/json-schema.js +0 -19
  121. package/webpack/log.js +0 -143
  122. package/webpack/markdown-plugins.test.js +0 -203
  123. package/webpack/pagefind-plugin.js +0 -379
  124. package/webpack/print-flair-plugin.js +0 -22
  125. package/webpack/serve.js +0 -104
  126. package/webpack/site-variables.js +0 -53
  127. package/webpack/util.js +0 -49
  128. package/webpack/utils/define-plugin.js +0 -20
  129. package/webpack/utils/file-types.js +0 -26
  130. package/webpack/utils/parse-hsl.js +0 -8
  131. package/webpack/utils/shiki-highlighter.js +0 -26
  132. package/webpack/watch.js +0 -166
  133. /package/{webpack → build}/flair.json +0 -0
  134. /package/{webpack → build}/utils/jdi-runner/LiterateRunner.class +0 -0
  135. /package/fonts/google-sans-code/{GoogleSansCodeVariable-Italic.ttf → ttf/GoogleSansCodeVariable-Italic.ttf} +0 -0
  136. /package/fonts/google-sans-code/{GoogleSansCodeVariable.ttf → ttf/GoogleSansCodeVariable.ttf} +0 -0
  137. /package/fonts/inter/{InterVariable-Italic.ttf → ttf/InterVariable-Italic.ttf} +0 -0
  138. /package/fonts/inter/{InterVariable.ttf → ttf/InterVariable.ttf} +0 -0
  139. /package/{content → init/content}/lectures/01/Pair.java.md +0 -0
  140. /package/{content → init/content}/lectures/01/Rectangle.java +0 -0
  141. /package/{content → init/content}/lectures/01/demo.py +0 -0
  142. /package/{content → init/content}/lectures/01/index.md +0 -0
  143. /package/{content → init/content}/lectures/01/lecture1.pdf +0 -0
  144. /package/{public → init/public}/avatars/alex.jpg +0 -0
  145. /package/{public → init/public}/test.txt +0 -0
  146. /package/{templates → schema}/authors.schema.json +0 -0
@@ -1,97 +0,0 @@
1
- const watchStateByCompiler = new WeakMap();
2
- const buildDeltaByCompiler = new WeakMap();
3
-
4
- function cloneSet(values) {
5
- return new Set(values || []);
6
- }
7
-
8
- function getEmptyBuildDelta() {
9
- return {
10
- changedSourceFiles: new Set(),
11
- changedHtmlAssetPaths: new Set(),
12
- removedHtmlAssetPaths: new Set(),
13
- templatesChanged: false,
14
- };
15
- }
16
-
17
- function setWatchState(compiler, watchState) {
18
- watchStateByCompiler.set(compiler, {
19
- contentFiles: cloneSet(watchState?.contentFiles),
20
- buildContentFiles: cloneSet(watchState?.buildContentFiles),
21
- changedContentFiles: cloneSet(watchState?.changedContentFiles),
22
- templatesChanged: Boolean(watchState?.templatesChanged),
23
- structureChanged: Boolean(watchState?.structureChanged),
24
- });
25
- }
26
-
27
- function getWatchState(compiler) {
28
- const state = watchStateByCompiler.get(compiler);
29
- if (!state) {
30
- return null;
31
- }
32
-
33
- return {
34
- contentFiles: cloneSet(state.contentFiles),
35
- buildContentFiles: cloneSet(state.buildContentFiles),
36
- changedContentFiles: cloneSet(state.changedContentFiles),
37
- templatesChanged: state.templatesChanged,
38
- structureChanged: state.structureChanged,
39
- };
40
- }
41
-
42
- function setBuildDelta(compiler, buildDelta) {
43
- buildDeltaByCompiler.set(compiler, {
44
- changedSourceFiles: cloneSet(buildDelta?.changedSourceFiles),
45
- changedHtmlAssetPaths: cloneSet(buildDelta?.changedHtmlAssetPaths),
46
- removedHtmlAssetPaths: cloneSet(buildDelta?.removedHtmlAssetPaths),
47
- templatesChanged: Boolean(buildDelta?.templatesChanged),
48
- });
49
- }
50
-
51
- function mergeIntoSet(target, values) {
52
- if (!values) {
53
- return;
54
- }
55
-
56
- for (const value of values) {
57
- target.add(value);
58
- }
59
- }
60
-
61
- function updateBuildDelta(compiler, buildDelta) {
62
- const current = getBuildDelta(compiler);
63
- mergeIntoSet(current.changedSourceFiles, buildDelta?.changedSourceFiles);
64
- mergeIntoSet(
65
- current.changedHtmlAssetPaths,
66
- buildDelta?.changedHtmlAssetPaths,
67
- );
68
- mergeIntoSet(
69
- current.removedHtmlAssetPaths,
70
- buildDelta?.removedHtmlAssetPaths,
71
- );
72
- current.templatesChanged =
73
- current.templatesChanged || Boolean(buildDelta?.templatesChanged);
74
- buildDeltaByCompiler.set(compiler, current);
75
- }
76
-
77
- function getBuildDelta(compiler) {
78
- const delta = buildDeltaByCompiler.get(compiler);
79
- if (!delta) {
80
- return getEmptyBuildDelta();
81
- }
82
-
83
- return {
84
- changedSourceFiles: cloneSet(delta.changedSourceFiles),
85
- changedHtmlAssetPaths: cloneSet(delta.changedHtmlAssetPaths),
86
- removedHtmlAssetPaths: cloneSet(delta.removedHtmlAssetPaths),
87
- templatesChanged: delta.templatesChanged,
88
- };
89
- }
90
-
91
- module.exports = {
92
- getBuildDelta,
93
- getWatchState,
94
- setBuildDelta,
95
- setWatchState,
96
- updateBuildDelta,
97
- };
package/webpack/colors.js DELETED
@@ -1,15 +0,0 @@
1
- const util = require('util');
2
-
3
- const R = (str, ...args) => util.styleText(['red'], String.raw(str, ...args));
4
- const G = (str, ...args) => util.styleText(['green'], String.raw(str, ...args));
5
- const B = (str, ...args) => util.styleText(['blue'], String.raw(str, ...args));
6
- const Y = (str, ...args) =>
7
- util.styleText(['yellow'], String.raw(str, ...args));
8
- const L = (str, ...args) =>
9
- util.styleText(['blackBright'], String.raw(str, ...args));
10
- const P = (str, ...args) =>
11
- util.styleText(['magenta'], String.raw(str, ...args));
12
- const I = (str, ...args) =>
13
- util.styleText(['italic', 'bold'], String.raw(str, ...args));
14
-
15
- module.exports = { R, G, B, Y, L, P, I };
@@ -1,151 +0,0 @@
1
- const fs = require('fs');
2
- const os = require('os');
3
- const path = require('path');
4
- const _ = require('lodash');
5
- const CopyPlugin = require('copy-webpack-plugin');
6
- const MiniCssExtractPlugin = require('mini-css-extract-plugin');
7
- const GenerateContentAssetsPlugin = require('./generate-content-assets-plugin');
8
- const PagefindPlugin = require('./pagefind-plugin');
9
- const GenerateFaviconPlugin = require('./generate-favicon-plugin');
10
- const GenerateManifestPlugin = require('./generate-manifest-plugin');
11
- const GenerateFontsPlugin = require('./generate-fonts-plugin');
12
- const { getDistDir, createDefinePlugin } = require('./util');
13
- const { isFeatureEnabled } = require('./features');
14
- const {
15
- getContentDir,
16
- getPackageDir,
17
- getProjectDir,
18
- getPublicDir,
19
- } = require('./utils/paths');
20
- const { parseHsl } = require('./utils/parse-hsl');
21
-
22
- const distDir = getDistDir();
23
-
24
- function renderThemeScss(siteVariables) {
25
- const templatePath = path.join(getPackageDir(), 'templates/_theme.scss');
26
- const template = fs.readFileSync(templatePath, 'utf-8');
27
- const { hue, saturation, lightness } = parseHsl(siteVariables.themeColor);
28
- const tintHue = siteVariables.tintHue ?? 20;
29
- const tintAmount = siteVariables.tintAmount ?? 100;
30
- const rendered = _.template(template)({
31
- themeHue: hue,
32
- themeSaturation: saturation,
33
- themeLightness: lightness,
34
- tintHue,
35
- tintAmount,
36
- });
37
-
38
- const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'tada-'));
39
- const configDir = path.join(tmpDir, 'config');
40
- fs.mkdirSync(configDir);
41
- fs.writeFileSync(path.join(configDir, '_theme.scss'), rendered);
42
-
43
- return tmpDir;
44
- }
45
-
46
- function createModuleRules(siteVariables) {
47
- const packageDir = getPackageDir();
48
- const themeDir = renderThemeScss(siteVariables);
49
-
50
- return [
51
- { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader' } },
52
- {
53
- test: /\.tsx?$/,
54
- include: path.resolve(packageDir, 'src'),
55
- loader: 'ts-loader',
56
- options: { configFile: path.resolve(packageDir, 'tsconfig.json') },
57
- },
58
- {
59
- test: /\.(sa|sc|c)ss$/,
60
- use: [
61
- MiniCssExtractPlugin.loader,
62
- {
63
- loader: 'css-loader',
64
- options: {
65
- url: {
66
- // Don't bundle fonts (they are handled by GenerateFontsPlugin)
67
- filter: url => !url.endsWith('.woff2'),
68
- },
69
- },
70
- },
71
- {
72
- loader: 'sass-loader',
73
- options: { sassOptions: { loadPaths: [themeDir, getProjectDir()] } },
74
- },
75
- ],
76
- },
77
- ];
78
- }
79
-
80
- async function createPlugins(
81
- siteVariables,
82
- { defineIsDev = false, plugins = [] } = {},
83
- ) {
84
- return [
85
- new GenerateContentAssetsPlugin(siteVariables),
86
- createDefinePlugin(siteVariables, defineIsDev),
87
- new MiniCssExtractPlugin({
88
- filename: '[name].css',
89
- chunkFilename: '[id].css',
90
- }),
91
- new CopyPlugin({
92
- patterns: [
93
- { from: getPublicDir(), to: '.', noErrorOnMissing: true },
94
- {
95
- from: '**/*.{png,jpg,jpeg,gif,svg,txt,zip}',
96
- context: getContentDir(),
97
- to: '[path][name][ext]',
98
- noErrorOnMissing: true,
99
- },
100
- ],
101
- }),
102
- isFeatureEnabled(siteVariables, 'search')
103
- ? new PagefindPlugin(siteVariables)
104
- : null,
105
- isFeatureEnabled(siteVariables, 'favicon')
106
- ? new GenerateFaviconPlugin(siteVariables)
107
- : null,
108
- isFeatureEnabled(siteVariables, 'favicon')
109
- ? new GenerateManifestPlugin(siteVariables)
110
- : null,
111
- new GenerateFontsPlugin(),
112
- ...plugins,
113
- require('./print-flair-plugin'),
114
- ].filter(Boolean);
115
- }
116
-
117
- async function createBaseConfig({
118
- mode,
119
- siteVariables,
120
- entry,
121
- devtool,
122
- defineIsDev = false,
123
- optimization,
124
- plugins,
125
- }) {
126
- const packageDir = getPackageDir();
127
- return {
128
- mode,
129
- entry,
130
- output: {
131
- path: distDir,
132
- publicPath: siteVariables.basePath,
133
- filename: '[name].bundle.js',
134
- },
135
- resolve: { extensions: ['.ts', '.js', '.json'] },
136
- resolveLoader: {
137
- modules: [
138
- path.resolve(packageDir, 'node_modules'),
139
- path.resolve(packageDir, '..', '..'),
140
- 'node_modules',
141
- ],
142
- },
143
- devtool,
144
- module: { rules: createModuleRules(siteVariables) },
145
- ...(optimization && { optimization }),
146
- plugins: await createPlugins(siteVariables, { defineIsDev, plugins }),
147
- stats: 'errors-only',
148
- };
149
- }
150
-
151
- module.exports = { createBaseConfig };
@@ -1,23 +0,0 @@
1
- const path = require('path');
2
- const ContentWatchPlugin = require('./content-watch-plugin');
3
- const { createBaseConfig } = require('./config.base');
4
- const { getDevSiteVariables } = require('./site-variables');
5
- const { getPackageDir } = require('./utils/paths');
6
-
7
- module.exports = async (env = {}) => {
8
- const siteVariables = getDevSiteVariables();
9
- const packageDir = getPackageDir();
10
- const entry = { index: path.resolve(packageDir, 'src/index.ts') };
11
- if (env.watchMode) {
12
- entry.reload = path.resolve(packageDir, 'webpack/watch-reload-client.js');
13
- }
14
-
15
- return createBaseConfig({
16
- mode: 'development',
17
- devtool: 'inline-source-map',
18
- siteVariables,
19
- entry,
20
- defineIsDev: true,
21
- plugins: [new ContentWatchPlugin(siteVariables)],
22
- });
23
- };
@@ -1,32 +0,0 @@
1
- const path = require('path');
2
- const TerserPlugin = require('terser-webpack-plugin');
3
- const { createBaseConfig } = require('./config.base');
4
- const { compileTemplates } = require('./templates');
5
- const { getProdSiteVariables } = require('./site-variables');
6
- const { getPackageDir } = require('./utils/paths');
7
-
8
- const siteVariables = getProdSiteVariables();
9
-
10
- module.exports = async () => {
11
- compileTemplates(siteVariables);
12
-
13
- return createBaseConfig({
14
- mode: 'production',
15
- siteVariables,
16
- entry: { index: path.resolve(getPackageDir(), 'src/index.ts') },
17
- devtool: false,
18
- optimization: {
19
- minimizer: [
20
- /*
21
- * Bun's event loop doesn't track TerserPlugin's worker threads,
22
- * causing a premature exit; set parallel to false to prevent worker
23
- * threads from being used.
24
- */
25
- new TerserPlugin({
26
- parallel: false,
27
- terserOptions: { output: { comments: false } },
28
- }),
29
- ],
30
- },
31
- });
32
- };
@@ -1,153 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- const {
4
- getContentDir,
5
- getContentFiles,
6
- getBuildContentFiles,
7
- } = require('./util');
8
- const { setWatchState } = require('./build-state');
9
- const {
10
- compileTemplates,
11
- getHtmlTemplatesDir,
12
- getJsonDataDir,
13
- JSON_DATA_FILES,
14
- } = require('./templates');
15
- const { getProjectDir } = require('./utils/paths');
16
-
17
- let _needsRestart = false;
18
-
19
- class ContentWatchPlugin {
20
- constructor(siteVariables) {
21
- this.siteVariables = siteVariables;
22
- this.siteConfigPath = path.resolve(
23
- getProjectDir(),
24
- 'config',
25
- 'site.dev.json',
26
- );
27
- }
28
-
29
- apply(compiler) {
30
- let lastSig = null;
31
-
32
- compiler.hooks.make.tap('ContentWatchPlugin', compilation => {
33
- const htmlTemplatesDir = getHtmlTemplatesDir();
34
- const jsonDataDir = getJsonDataDir();
35
-
36
- // Refresh templates cache from disk
37
- try {
38
- compileTemplates(this.siteVariables);
39
- } catch (err) {
40
- compilation.errors.push(err);
41
- for (const fileName of fs.readdirSync(htmlTemplatesDir)) {
42
- compilation.fileDependencies.add(
43
- path.join(htmlTemplatesDir, fileName),
44
- );
45
- }
46
- for (const dataFile of JSON_DATA_FILES) {
47
- const dataPath = path.join(jsonDataDir, dataFile);
48
- if (fs.existsSync(dataPath)) {
49
- compilation.fileDependencies.add(dataPath);
50
- }
51
- }
52
- return;
53
- }
54
-
55
- const contentDir = getContentDir();
56
- const modifiedFiles = new Set(
57
- [...(compiler.modifiedFiles || [])].map(filePath =>
58
- path.resolve(filePath),
59
- ),
60
- );
61
- const normalizedContentDir = path.resolve(contentDir) + path.sep;
62
- const normalizedHtmlDir = path.resolve(htmlTemplatesDir) + path.sep;
63
- const contentFiles = getContentFiles(
64
- contentDir,
65
- Object.keys(this.siteVariables.codeLanguages),
66
- );
67
- const buildContentFiles = getBuildContentFiles(
68
- contentDir,
69
- Object.keys(this.siteVariables.codeLanguages),
70
- );
71
-
72
- // Detect structural changes (files added or deleted) that require a
73
- // fresh compiler with updated content asset caches
74
- const sig = buildContentFiles.slice().sort().join('\0');
75
- let structureChanged = false;
76
- if (lastSig !== null && sig !== lastSig) {
77
- _needsRestart = true;
78
- structureChanged = true;
79
- }
80
- lastSig = sig;
81
-
82
- const changedContentFiles = new Set(
83
- [...modifiedFiles].filter(filePath =>
84
- filePath.startsWith(normalizedContentDir),
85
- ),
86
- );
87
-
88
- // Check if any HTML template or JSON data file changed
89
- const jsonDataPaths = JSON_DATA_FILES.map(f =>
90
- path.resolve(jsonDataDir, f),
91
- );
92
- const templatesChanged = [...modifiedFiles].some(
93
- filePath =>
94
- filePath === path.resolve(htmlTemplatesDir) ||
95
- filePath.startsWith(normalizedHtmlDir) ||
96
- jsonDataPaths.includes(filePath),
97
- );
98
-
99
- setWatchState(compiler, {
100
- contentFiles,
101
- buildContentFiles,
102
- changedContentFiles,
103
- templatesChanged,
104
- structureChanged,
105
- });
106
-
107
- // Tell webpack to watch all content files
108
- for (const filePath of contentFiles) {
109
- compilation.fileDependencies.add(filePath);
110
- }
111
-
112
- // Watch content directories so webpack detects newly added files
113
- function addDirs(dir) {
114
- compilation.contextDependencies.add(dir);
115
- for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
116
- if (entry.isDirectory()) {
117
- addDirs(path.join(dir, entry.name));
118
- }
119
- }
120
- }
121
- addDirs(contentDir);
122
-
123
- // Watch HTML template files from the package
124
- for (const fileName of fs.readdirSync(htmlTemplatesDir)) {
125
- compilation.fileDependencies.add(path.join(htmlTemplatesDir, fileName));
126
- }
127
-
128
- // Watch JSON data files from the project config
129
- for (const dataFile of JSON_DATA_FILES) {
130
- const dataPath = path.join(jsonDataDir, dataFile);
131
- if (fs.existsSync(dataPath)) {
132
- compilation.fileDependencies.add(dataPath);
133
- }
134
- }
135
-
136
- // Watch the site config file and restart when it changes
137
- compilation.fileDependencies.add(this.siteConfigPath);
138
- const siteConfigChanged = modifiedFiles.has(
139
- path.resolve(this.siteConfigPath),
140
- );
141
- if (siteConfigChanged) {
142
- _needsRestart = true;
143
- }
144
- });
145
- }
146
- }
147
-
148
- ContentWatchPlugin.needsRestart = () => _needsRestart;
149
- ContentWatchPlugin.clearRestart = () => {
150
- _needsRestart = false;
151
- };
152
-
153
- module.exports = ContentWatchPlugin;
@@ -1,5 +0,0 @@
1
- function isFeatureEnabled(siteVariables, featureName) {
2
- return siteVariables.features?.[featureName] !== false;
3
- }
4
-
5
- module.exports = { isFeatureEnabled };