@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
@@ -0,0 +1,91 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+ import path from 'path';
3
+ import {
4
+ getPackageDir,
5
+ getProjectDir,
6
+ getContentDir,
7
+ getDistDir,
8
+ getPublicDir,
9
+ getConfigDir,
10
+ createApplyBasePath,
11
+ normalizeOutputPath,
12
+ } from './paths';
13
+ import type { SiteVariables } from '../types';
14
+
15
+ describe('getPackageDir', () => {
16
+ test('returns an absolute path', () => {
17
+ expect(path.isAbsolute(getPackageDir())).toBe(true);
18
+ });
19
+
20
+ test('points to repo root (contains package.json)', () => {
21
+ const dir = getPackageDir();
22
+ const pkg = path.join(dir, 'package.json');
23
+ expect(Bun.file(pkg).size).toBeGreaterThan(0);
24
+ });
25
+ });
26
+
27
+ describe('getProjectDir', () => {
28
+ test('returns process.cwd()', () => {
29
+ expect(getProjectDir()).toBe(process.cwd());
30
+ });
31
+ });
32
+
33
+ describe('directory getters', () => {
34
+ test('getContentDir ends with /content', () => {
35
+ expect(getContentDir()).toEndWith('/content');
36
+ });
37
+
38
+ test('getDistDir ends with /dist', () => {
39
+ expect(getDistDir()).toEndWith('/dist');
40
+ });
41
+
42
+ test('getPublicDir ends with /public', () => {
43
+ expect(getPublicDir()).toEndWith('/public');
44
+ });
45
+
46
+ test('getConfigDir equals getProjectDir', () => {
47
+ expect(getConfigDir()).toBe(getProjectDir());
48
+ });
49
+ });
50
+
51
+ describe('createApplyBasePath', () => {
52
+ function apply(basePath: string, subPath: string): string {
53
+ const site = { base: '', basePath } as SiteVariables;
54
+ return createApplyBasePath(site)(subPath);
55
+ }
56
+
57
+ test('prepends basePath to subPath', () => {
58
+ expect(apply('/course', '/page.html')).toBe('/course/page.html');
59
+ });
60
+
61
+ test('handles basePath with trailing slash', () => {
62
+ expect(apply('/course/', '/page.html')).toBe('/course/page.html');
63
+ });
64
+
65
+ test('handles root basePath', () => {
66
+ expect(apply('/', '/page.html')).toBe('/page.html');
67
+ });
68
+
69
+ test('throws for subPath without leading slash', () => {
70
+ expect(() => apply('/course', 'page.html')).toThrow('must start with "/"');
71
+ });
72
+ });
73
+
74
+ describe('normalizeOutputPath', () => {
75
+ test('adds leading slash if missing', () => {
76
+ expect(normalizeOutputPath('page.html')).toBe('/page.html');
77
+ });
78
+
79
+ test('preserves leading slash', () => {
80
+ expect(normalizeOutputPath('/page.html')).toBe('/page.html');
81
+ });
82
+
83
+ test('normalizes dot-segments', () => {
84
+ expect(normalizeOutputPath('/a/../b/page.html')).toBe('/b/page.html');
85
+ });
86
+
87
+ test('returns / for empty or dot path', () => {
88
+ expect(normalizeOutputPath('')).toBe('/');
89
+ expect(normalizeOutputPath('.')).toBe('/');
90
+ });
91
+ });
@@ -1,31 +1,38 @@
1
- const path = require('path');
1
+ import path from 'path';
2
+ import type { SiteVariables } from '../types';
2
3
 
3
- function getPackageDir() {
4
+ export function getPackageDir(): string {
4
5
  return path.resolve(__dirname, '..', '..');
5
6
  }
6
7
 
7
- function getProjectDir() {
8
+ export function getProjectDir(): string {
8
9
  return process.cwd();
9
10
  }
10
11
 
11
- function getContentDir() {
12
+ export function getContentDir(): string {
12
13
  return path.resolve(getProjectDir(), 'content');
13
14
  }
14
15
 
15
- function getDistDir() {
16
+ export function getDistDir(): string {
16
17
  return path.resolve(getProjectDir(), 'dist');
17
18
  }
18
19
 
19
- function getPublicDir() {
20
+ export function getProdDistDir(): string {
21
+ return path.resolve(getProjectDir(), 'dist-prod');
22
+ }
23
+
24
+ export function getPublicDir(): string {
20
25
  return path.resolve(getProjectDir(), 'public');
21
26
  }
22
27
 
23
- function getConfigDir() {
24
- return path.resolve(getProjectDir(), 'config');
28
+ export function getConfigDir(): string {
29
+ return getProjectDir();
25
30
  }
26
31
 
27
- function createApplyBasePath(siteVariables) {
28
- return function applyBasePath(subPath) {
32
+ export function createApplyBasePath(
33
+ siteVariables: SiteVariables,
34
+ ): (subPath: string) => string {
35
+ return function applyBasePath(subPath: string): string {
29
36
  if (!subPath.startsWith('/')) {
30
37
  throw new Error('invalid internal path, must start with "/": ' + subPath);
31
38
  }
@@ -38,21 +45,10 @@ function createApplyBasePath(siteVariables) {
38
45
  };
39
46
  }
40
47
 
41
- function normalizeOutputPath(outputPath) {
48
+ export function normalizeOutputPath(outputPath: string): string {
42
49
  const normalized = path.posix.normalize(outputPath);
43
50
  if (normalized === '.' || normalized === '') {
44
51
  return '/';
45
52
  }
46
53
  return normalized.startsWith('/') ? normalized : `/${normalized}`;
47
54
  }
48
-
49
- module.exports = {
50
- createApplyBasePath,
51
- getConfigDir,
52
- getContentDir,
53
- getDistDir,
54
- getPackageDir,
55
- getProjectDir,
56
- getPublicDir,
57
- normalizeOutputPath,
58
- };