@dominikcz/greg 0.9.27

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 (183) hide show
  1. package/README.md +397 -0
  2. package/bin/greg.js +241 -0
  3. package/bin/init.js +351 -0
  4. package/bin/templates/docs/getting-started.md +47 -0
  5. package/bin/templates/docs/index.md +11 -0
  6. package/bin/templates/greg.config.js +39 -0
  7. package/bin/templates/greg.config.ts +38 -0
  8. package/bin/templates/index.html +16 -0
  9. package/bin/templates/src/App.svelte +5 -0
  10. package/bin/templates/src/app.css +20 -0
  11. package/bin/templates/src/main.js +9 -0
  12. package/bin/templates/svelte.config.js +1 -0
  13. package/bin/templates/tsconfig.json +21 -0
  14. package/bin/templates/vite.config.js +23 -0
  15. package/docs/__partials/markdown/examples/basic.md +4 -0
  16. package/docs/__partials/markdown/examples/diff.md +10 -0
  17. package/docs/__partials/markdown/examples/focus.md +5 -0
  18. package/docs/__partials/markdown/examples/language-title.md +3 -0
  19. package/docs/__partials/markdown/examples/line-highlighting.md +5 -0
  20. package/docs/__partials/markdown/examples/line-numbers.md +5 -0
  21. package/docs/__partials/note.md +4 -0
  22. package/docs/guide/__shared-warning.md +4 -0
  23. package/docs/guide/asset-handling.md +88 -0
  24. package/docs/guide/deploying.md +162 -0
  25. package/docs/guide/getting-started.md +334 -0
  26. package/docs/guide/index.md +23 -0
  27. package/docs/guide/localization.md +290 -0
  28. package/docs/guide/markdown/code.md +95 -0
  29. package/docs/guide/markdown/components-and-mermaid.md +43 -0
  30. package/docs/guide/markdown/containers.md +110 -0
  31. package/docs/guide/markdown/header-anchors.md +34 -0
  32. package/docs/guide/markdown/includes.md +84 -0
  33. package/docs/guide/markdown/index.md +20 -0
  34. package/docs/guide/markdown/inline-attributes.md +21 -0
  35. package/docs/guide/markdown/links-and-toc.md +64 -0
  36. package/docs/guide/markdown/math.md +54 -0
  37. package/docs/guide/markdown/syntax-highlighting.md +75 -0
  38. package/docs/guide/routing.md +150 -0
  39. package/docs/guide/using-svelte.md +88 -0
  40. package/docs/guide/versioning.md +281 -0
  41. package/docs/incompatibilities.md +48 -0
  42. package/docs/index.md +43 -0
  43. package/docs/reference/badge.md +100 -0
  44. package/docs/reference/carbon-ads.md +46 -0
  45. package/docs/reference/code-group.md +126 -0
  46. package/docs/reference/home-page.md +232 -0
  47. package/docs/reference/index.md +18 -0
  48. package/docs/reference/markdowndocs.md +275 -0
  49. package/docs/reference/outline.md +79 -0
  50. package/docs/reference/search.md +263 -0
  51. package/docs/reference/steps.md +200 -0
  52. package/docs/reference/team-page.md +189 -0
  53. package/docs/reference/theme.md +150 -0
  54. package/fakeDocsGenerator/generate_docs.js +310 -0
  55. package/package.json +92 -0
  56. package/scripts/build-versions.js +609 -0
  57. package/scripts/generate-static.js +79 -0
  58. package/scripts/render-markdown.js +420 -0
  59. package/src/lib/MarkdownDocs/AiChat.svelte +936 -0
  60. package/src/lib/MarkdownDocs/BackToTop.svelte +68 -0
  61. package/src/lib/MarkdownDocs/Breadcrumb.svelte +68 -0
  62. package/src/lib/MarkdownDocs/DocsNavigation.svelte +149 -0
  63. package/src/lib/MarkdownDocs/DocsSiteHeader.svelte +758 -0
  64. package/src/lib/MarkdownDocs/DocsVersionSwitcher.svelte +103 -0
  65. package/src/lib/MarkdownDocs/MarkdownDocs.svelte +2115 -0
  66. package/src/lib/MarkdownDocs/MarkdownRenderer.svelte +487 -0
  67. package/src/lib/MarkdownDocs/Outline.svelte +238 -0
  68. package/src/lib/MarkdownDocs/PrevNext.svelte +115 -0
  69. package/src/lib/MarkdownDocs/SearchModal.svelte +1241 -0
  70. package/src/lib/MarkdownDocs/TreeView.svelte +32 -0
  71. package/src/lib/MarkdownDocs/TreeViewItem.svelte +219 -0
  72. package/src/lib/MarkdownDocs/VersionOutdatedNotice.svelte +72 -0
  73. package/src/lib/MarkdownDocs/__tests__/codeDirectives.test.js +54 -0
  74. package/src/lib/MarkdownDocs/__tests__/common.test.js +41 -0
  75. package/src/lib/MarkdownDocs/__tests__/docsExamplesLint.test.js +77 -0
  76. package/src/lib/MarkdownDocs/__tests__/fixtures/docs/markdown/__partial-basic.md +3 -0
  77. package/src/lib/MarkdownDocs/__tests__/fixtures/docs/markdown/snippet.js +9 -0
  78. package/src/lib/MarkdownDocs/__tests__/fixtures/includes/part.md +11 -0
  79. package/src/lib/MarkdownDocs/__tests__/fixtures/includes/wrapper.md +5 -0
  80. package/src/lib/MarkdownDocs/__tests__/fixtures/snippets/sample.js +8 -0
  81. package/src/lib/MarkdownDocs/__tests__/fixtures/snippets/sample.md +5 -0
  82. package/src/lib/MarkdownDocs/__tests__/helpers.js +67 -0
  83. package/src/lib/MarkdownDocs/__tests__/localeUtils.test.js +204 -0
  84. package/src/lib/MarkdownDocs/__tests__/markdown.test.js +704 -0
  85. package/src/lib/MarkdownDocs/__tests__/markdownRendererRuntime.test.js +65 -0
  86. package/src/lib/MarkdownDocs/__tests__/searchIndexBuilder.test.js +117 -0
  87. package/src/lib/MarkdownDocs/__tests__/sqliteStore.test.js +202 -0
  88. package/src/lib/MarkdownDocs/__tests__/useRouter.test.js +16 -0
  89. package/src/lib/MarkdownDocs/ai/adapters/customAdapter.js +14 -0
  90. package/src/lib/MarkdownDocs/ai/adapters/customAdapter.ts +43 -0
  91. package/src/lib/MarkdownDocs/ai/adapters/ollamaAdapter.js +81 -0
  92. package/src/lib/MarkdownDocs/ai/adapters/ollamaAdapter.ts +116 -0
  93. package/src/lib/MarkdownDocs/ai/adapters/openaiAdapter.js +92 -0
  94. package/src/lib/MarkdownDocs/ai/adapters/openaiAdapter.ts +137 -0
  95. package/src/lib/MarkdownDocs/ai/aiProvider.ts +31 -0
  96. package/src/lib/MarkdownDocs/ai/characters.js +52 -0
  97. package/src/lib/MarkdownDocs/ai/characters.ts +69 -0
  98. package/src/lib/MarkdownDocs/ai/chunkStore.ts +25 -0
  99. package/src/lib/MarkdownDocs/ai/chunker.js +85 -0
  100. package/src/lib/MarkdownDocs/ai/chunker.ts +135 -0
  101. package/src/lib/MarkdownDocs/ai/docLinker.js +26 -0
  102. package/src/lib/MarkdownDocs/ai/docLinker.ts +36 -0
  103. package/src/lib/MarkdownDocs/ai/promptBuilder.js +33 -0
  104. package/src/lib/MarkdownDocs/ai/promptBuilder.ts +53 -0
  105. package/src/lib/MarkdownDocs/ai/ragPipeline.js +54 -0
  106. package/src/lib/MarkdownDocs/ai/ragPipeline.ts +106 -0
  107. package/src/lib/MarkdownDocs/ai/stores/memoryStore.js +88 -0
  108. package/src/lib/MarkdownDocs/ai/stores/memoryStore.ts +112 -0
  109. package/src/lib/MarkdownDocs/ai/stores/sqliteStore.ts +372 -0
  110. package/src/lib/MarkdownDocs/ai/types.ts +71 -0
  111. package/src/lib/MarkdownDocs/aiServer.js +288 -0
  112. package/src/lib/MarkdownDocs/codeDirectives.js +191 -0
  113. package/src/lib/MarkdownDocs/codeFenceInfo.js +45 -0
  114. package/src/lib/MarkdownDocs/codeGroup.ts +46 -0
  115. package/src/lib/MarkdownDocs/common.ts +47 -0
  116. package/src/lib/MarkdownDocs/docsUtils.js +281 -0
  117. package/src/lib/MarkdownDocs/index.plugins.js +22 -0
  118. package/src/lib/MarkdownDocs/layouts/LayoutDoc.svelte +8 -0
  119. package/src/lib/MarkdownDocs/layouts/LayoutHome.svelte +58 -0
  120. package/src/lib/MarkdownDocs/layouts/LayoutPage.svelte +9 -0
  121. package/src/lib/MarkdownDocs/loadGregConfig.js +82 -0
  122. package/src/lib/MarkdownDocs/localeUtils.ts +682 -0
  123. package/src/lib/MarkdownDocs/markdownRendererRuntime.ts +314 -0
  124. package/src/lib/MarkdownDocs/mermaidThemes.js +319 -0
  125. package/src/lib/MarkdownDocs/navigationUtils.js +22 -0
  126. package/src/lib/MarkdownDocs/rehypeCodeGroup.js +326 -0
  127. package/src/lib/MarkdownDocs/rehypeCodeTitle.js +96 -0
  128. package/src/lib/MarkdownDocs/rehypeToc.js +170 -0
  129. package/src/lib/MarkdownDocs/remarkCodeMeta.js +22 -0
  130. package/src/lib/MarkdownDocs/remarkContainers.js +329 -0
  131. package/src/lib/MarkdownDocs/remarkCustomAnchors.js +42 -0
  132. package/src/lib/MarkdownDocs/remarkEscapeSvelte.js +33 -0
  133. package/src/lib/MarkdownDocs/remarkGlobalComponents.js +65 -0
  134. package/src/lib/MarkdownDocs/remarkImports.js +461 -0
  135. package/src/lib/MarkdownDocs/remarkImportsBrowser.js +349 -0
  136. package/src/lib/MarkdownDocs/remarkInlineAttrs.js +95 -0
  137. package/src/lib/MarkdownDocs/remarkMathToHtml.js +138 -0
  138. package/src/lib/MarkdownDocs/searchIndexBuilder.js +497 -0
  139. package/src/lib/MarkdownDocs/searchServer.js +263 -0
  140. package/src/lib/MarkdownDocs/treeViewTypes.ts +11 -0
  141. package/src/lib/MarkdownDocs/useRouter.svelte.ts +114 -0
  142. package/src/lib/MarkdownDocs/useSplitter.svelte.ts +33 -0
  143. package/src/lib/MarkdownDocs/versioningDefaults.js +20 -0
  144. package/src/lib/MarkdownDocs/vitePluginAiServer.js +204 -0
  145. package/src/lib/MarkdownDocs/vitePluginCopyDocs.js +153 -0
  146. package/src/lib/MarkdownDocs/vitePluginFrontmatter.js +109 -0
  147. package/src/lib/MarkdownDocs/vitePluginGregConfig.js +108 -0
  148. package/src/lib/MarkdownDocs/vitePluginSearchIndex.js +57 -0
  149. package/src/lib/MarkdownDocs/vitePluginSearchServer.js +190 -0
  150. package/src/lib/components/Badge.svelte +59 -0
  151. package/src/lib/components/Button.svelte +138 -0
  152. package/src/lib/components/CarbonAds.svelte +99 -0
  153. package/src/lib/components/CodeGroup.svelte +102 -0
  154. package/src/lib/components/Feature.svelte +209 -0
  155. package/src/lib/components/Features.svelte +123 -0
  156. package/src/lib/components/Hero.svelte +399 -0
  157. package/src/lib/components/Image.svelte +128 -0
  158. package/src/lib/components/Link.svelte +105 -0
  159. package/src/lib/components/SocialLink.svelte +84 -0
  160. package/src/lib/components/SocialLinks.svelte +33 -0
  161. package/src/lib/components/Steps.svelte +143 -0
  162. package/src/lib/components/TeamMember.svelte +273 -0
  163. package/src/lib/components/TeamMembers.svelte +81 -0
  164. package/src/lib/components/TeamPage.svelte +65 -0
  165. package/src/lib/components/TeamPageSection.svelte +108 -0
  166. package/src/lib/components/TeamPageTitle.svelte +89 -0
  167. package/src/lib/components/index.js +24 -0
  168. package/src/lib/portal/context.js +12 -0
  169. package/src/lib/portal/index.js +3 -0
  170. package/src/lib/portal/portal.svelte +14 -0
  171. package/src/lib/portal/slot.svelte +8 -0
  172. package/src/lib/scss/__code.scss +128 -0
  173. package/src/lib/scss/__containers.scss +99 -0
  174. package/src/lib/scss/__markdown.scss +447 -0
  175. package/src/lib/scss/__scrollbar.scss +60 -0
  176. package/src/lib/scss/__steps.scss +100 -0
  177. package/src/lib/scss/__theme.scss +238 -0
  178. package/src/lib/scss/__toc.scss +55 -0
  179. package/src/lib/scss/__utilities.scss +7 -0
  180. package/src/lib/scss/greg.scss +9 -0
  181. package/src/lib/spinner/spinner.svelte +42 -0
  182. package/svelte.config.js +146 -0
  183. package/types/index.d.ts +456 -0
@@ -0,0 +1,310 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * FakeDocGen - Fake documentation generator
4
+ *
5
+ * Creates a folder structure with Markdown files containing random text
6
+ * resembling technical documentation.
7
+ */
8
+
9
+ import { mkdirSync, writeFileSync } from 'node:fs';
10
+ import { join } from 'node:path';
11
+ import { parseArgs } from 'node:util';
12
+
13
+ // ── Word lists ────────────────────────────────────────────────────────────────
14
+
15
+ const WORDS = [
16
+ 'application', 'system', 'user', 'configuration', 'installation', 'documentation',
17
+ 'function', 'module', 'component', 'interface', 'service', 'database', 'data', 'structure',
18
+ 'project', 'version', 'update', 'parameter', 'value', 'option', 'setting',
19
+ 'platform', 'environment', 'tool', 'process', 'mechanism', 'architecture',
20
+ 'implementation', 'solution', 'method', 'algorithm', 'protocol', 'format',
21
+ 'file', 'directory', 'path', 'resource', 'element', 'object', 'class', 'variable',
22
+ 'feature', 'capability', 'requirement', 'specification', 'standard', 'rule',
23
+ 'procedure', 'operation', 'execution', 'startup', 'behavior', 'action',
24
+ 'property', 'attribute', 'access', 'permission', 'security', 'authorization',
25
+ 'authentication', 'verification', 'validation', 'control', 'monitoring', 'logging',
26
+ 'performance', 'optimization', 'scalability', 'reliability', 'availability',
27
+ 'compatibility', 'integration', 'communication', 'synchronization', 'replication',
28
+ 'creation', 'editing', 'deletion', 'modification', 'management', 'administration',
29
+ 'maintenance', 'support', 'guide', 'instruction', 'reference', 'overview',
30
+ ];
31
+
32
+ const CONNECTORS = [
33
+ 'and', 'or', 'but', 'however', 'therefore', 'thus', 'because', 'since',
34
+ 'when', 'if', 'while', 'during', 'after', 'before', 'according to',
35
+ 'based on', 'in order to', 'so that', 'as well as', 'in addition to',
36
+ ];
37
+
38
+ // ── Utilities ─────────────────────────────────────────────────────────────────
39
+
40
+ function sample(arr, n) {
41
+ const copy = [...arr];
42
+ for (let i = copy.length - 1; i > 0; i--) {
43
+ const j = Math.floor(Math.random() * (i + 1));
44
+ [copy[i], copy[j]] = [copy[j], copy[i]];
45
+ }
46
+ return copy.slice(0, n);
47
+ }
48
+
49
+ function randInt(min, max) {
50
+ return Math.floor(Math.random() * (max - min + 1)) + min;
51
+ }
52
+
53
+ function capitalize(str) {
54
+ return str.charAt(0).toUpperCase() + str.slice(1);
55
+ }
56
+
57
+ // ── Name generators ───────────────────────────────────────────────────────────
58
+
59
+ function generateFilename(maxLength = 20, existingNames = new Set()) {
60
+ for (let attempt = 0; attempt < 100; attempt++) {
61
+ const numWords = randInt(1, 3);
62
+ const words = sample(WORDS, numWords);
63
+ let name = words.join('-');
64
+ if (name.length > maxLength) name = name.slice(0, maxLength).replace(/-+$/, '');
65
+ const filename = `${name}.md`;
66
+ if (!existingNames.has(filename)) {
67
+ existingNames.add(filename);
68
+ return filename;
69
+ }
70
+ }
71
+ // Fallback
72
+ let counter = 1;
73
+ const base = WORDS[0].slice(0, maxLength - 3);
74
+ while (true) {
75
+ const filename = `${base}-${counter}.md`;
76
+ if (!existingNames.has(filename)) { existingNames.add(filename); return filename; }
77
+ counter++;
78
+ }
79
+ }
80
+
81
+ function generateFoldername(maxLength = 20, existingNames = new Set()) {
82
+ for (let attempt = 0; attempt < 100; attempt++) {
83
+ const numWords = randInt(1, 2);
84
+ const words = sample(WORDS, numWords);
85
+ let name = words.join('-');
86
+ if (name.length > maxLength) name = name.slice(0, maxLength).replace(/-+$/, '');
87
+ if (!existingNames.has(name)) {
88
+ existingNames.add(name);
89
+ return name;
90
+ }
91
+ }
92
+ // Fallback
93
+ let counter = 1;
94
+ const base = WORDS[0].slice(0, maxLength - 3);
95
+ while (true) {
96
+ const name = `${base}-${counter}`;
97
+ if (!existingNames.has(name)) { existingNames.add(name); return name; }
98
+ counter++;
99
+ }
100
+ }
101
+
102
+ // ── Content generators ────────────────────────────────────────────────────────
103
+
104
+ function generateSentence() {
105
+ const length = randInt(5, 15);
106
+ const words = Array.from({ length }, () => WORDS[Math.floor(Math.random() * WORDS.length)]);
107
+ if (words.length > 3 && Math.random() > 0.5) {
108
+ const pos = randInt(2, words.length - 2);
109
+ words.splice(pos, 0, CONNECTORS[Math.floor(Math.random() * CONNECTORS.length)]);
110
+ }
111
+ return capitalize(words.join(' ')) + '.';
112
+ }
113
+
114
+ function generateParagraph() {
115
+ return Array.from({ length: randInt(3, 8) }, generateSentence).join(' ');
116
+ }
117
+
118
+ function generateMarkdownContent(targetSizeKb) {
119
+ const targetSize = targetSizeKb * 1024;
120
+ const lines = [];
121
+ let currentSize = 0;
122
+
123
+ const titleWords = [sample(WORDS, 1)[0], sample(WORDS, 1)[0]];
124
+ const titleText = titleWords.map(capitalize).join(' ');
125
+
126
+ const frontmatter = `---\ntitle: ${titleText}\n---`;
127
+ lines.push(frontmatter, '');
128
+ currentSize += frontmatter.length + 2;
129
+
130
+ lines.push(`# ${titleText}`, '');
131
+ currentSize += titleText.length + 4;
132
+
133
+ let sectionCount = 0;
134
+ while (currentSize < targetSize) {
135
+ if (sectionCount % 3 === 0) {
136
+ const sectionTitle = `## ${capitalize(sample(WORDS, 1)[0])} ${sample(WORDS, 1)[0]}`;
137
+ lines.push(sectionTitle, '');
138
+ currentSize += sectionTitle.length + 2;
139
+ }
140
+
141
+ const paragraph = generateParagraph();
142
+ lines.push(paragraph, '');
143
+ currentSize += paragraph.length + 2;
144
+ sectionCount++;
145
+
146
+ if (Math.random() > 0.7) {
147
+ const itemCount = randInt(3, 6);
148
+ for (let i = 0; i < itemCount; i++) {
149
+ const item = `- ${generateSentence()}`;
150
+ lines.push(item);
151
+ currentSize += item.length + 1;
152
+ }
153
+ lines.push('');
154
+ }
155
+ }
156
+
157
+ return lines.join('\n');
158
+ }
159
+
160
+ // ── Folder builder ────────────────────────────────────────────────────────────
161
+
162
+ function createFolderRecursive(folderPath, currentDepth, opts, stats) {
163
+ const { maxDepth, minDepth, filesPerFolder, filesSpread, minSizeKb, maxSizeKb, maxFilenameLength, filesLimit, indent = '' } = opts;
164
+
165
+ mkdirSync(folderPath, { recursive: true });
166
+ stats.totalFolders++;
167
+
168
+ const numFiles = randInt(Math.max(1, filesPerFolder - filesSpread), filesPerFolder + filesSpread);
169
+ const existingNames = new Set();
170
+
171
+ for (let j = 0; j < numFiles; j++) {
172
+ if (filesLimit != null && stats.totalFiles >= filesLimit) {
173
+ process.stdout.write(`\nāš ļø File limit reached: ${filesLimit}\nā¹ļø Stopping\n`);
174
+ return true; // signal: limit reached
175
+ }
176
+
177
+ const fileSizeKb = randInt(minSizeKb, maxSizeKb);
178
+ const filename = generateFilename(maxFilenameLength, existingNames);
179
+ const filePath = join(folderPath, filename);
180
+ const content = generateMarkdownContent(fileSizeKb);
181
+ writeFileSync(filePath, content, 'utf8');
182
+ const actualSizeKb = content.length / 1024;
183
+ stats.totalSize += actualSizeKb;
184
+ stats.totalFiles++;
185
+ process.stdout.write(`${indent} āœ“ ${filename} (${actualSizeKb.toFixed(1)} KB)\n`);
186
+ }
187
+
188
+ let shouldDescend = false;
189
+ if (currentDepth < maxDepth) {
190
+ shouldDescend = currentDepth < minDepth || Math.random() > 0.4;
191
+ }
192
+
193
+ if (shouldDescend) {
194
+ const numSubfolders = randInt(1, 4);
195
+ const existingSubfolderNames = new Set();
196
+
197
+ for (let i = 0; i < numSubfolders; i++) {
198
+ const subfolderName = generateFoldername(maxFilenameLength, existingSubfolderNames);
199
+ const subfolderPath = join(folderPath, subfolderName);
200
+ process.stdout.write(`${indent}šŸ“ ${subfolderName}/\n`);
201
+
202
+ const limitReached = createFolderRecursive(
203
+ subfolderPath,
204
+ currentDepth + 1,
205
+ { ...opts, indent: indent + ' ' },
206
+ stats,
207
+ );
208
+ if (limitReached) return true;
209
+ }
210
+ }
211
+
212
+ return false;
213
+ }
214
+
215
+ // ── Main ──────────────────────────────────────────────────────────────────────
216
+
217
+ function createDocumentationStructure(cfg) {
218
+ const {
219
+ output, numFolders, filesPerFolder, filesSpread,
220
+ minSizeKb, maxSizeKb, minDepth, maxDepth,
221
+ maxFilenameLength, filesLimit,
222
+ } = cfg;
223
+
224
+ mkdirSync(output, { recursive: true });
225
+
226
+ console.log();
227
+ console.log(' ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•— ā–ˆā–ˆā–ˆā–ˆā–ˆā•— ā–ˆā–ˆā•— ā–ˆā–ˆā•—ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•— ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•— ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•— ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•— ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•— ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•—ā–ˆā–ˆā–ˆā•— ā–ˆā–ˆā•—');
228
+ console.log(' ā–ˆā–ˆā•”ā•ā•ā•ā•ā•ā–ˆā–ˆā•”ā•ā•ā–ˆā–ˆā•—ā–ˆā–ˆā•‘ ā–ˆā–ˆā•”ā•ā–ˆā–ˆā•”ā•ā•ā•ā•ā• ā–ˆā–ˆā•”ā•ā•ā–ˆā–ˆā•—ā–ˆā–ˆā•”ā•ā•ā•ā–ˆā–ˆā•—ā–ˆā–ˆā•”ā•ā•ā•ā•ā• ā–ˆā–ˆā•”ā•ā•ā•ā•ā• ā–ˆā–ˆā•”ā•ā•ā•ā•ā•ā–ˆā–ˆā–ˆā–ˆā•— ā–ˆā–ˆā•‘');
229
+ console.log(' ā–ˆā–ˆā–ˆā–ˆā–ˆā•— ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•‘ā–ˆā–ˆā–ˆā–ˆā–ˆā•”ā• ā–ˆā–ˆā–ˆā–ˆā–ˆā•— ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ ā–ˆā–ˆā–ˆā•—ā–ˆā–ˆā–ˆā–ˆā–ˆā•— ā–ˆā–ˆā•”ā–ˆā–ˆā•— ā–ˆā–ˆā•‘');
230
+ console.log(' ā–ˆā–ˆā•”ā•ā•ā• ā–ˆā–ˆā•”ā•ā•ā–ˆā–ˆā•‘ā–ˆā–ˆā•”ā•ā–ˆā–ˆā•— ā–ˆā–ˆā•”ā•ā•ā• ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ā–ˆā–ˆā•”ā•ā•ā• ā–ˆā–ˆā•‘ā•šā–ˆā–ˆā•—ā–ˆā–ˆā•‘');
231
+ console.log(' ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ ā–ˆā–ˆā•‘ā–ˆā–ˆā•‘ ā–ˆā–ˆā•—ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•— ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•”ā•ā•šā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•”ā•ā•šā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•— ā•šā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•”ā•ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā•—ā–ˆā–ˆā•‘ ā•šā–ˆā–ˆā–ˆā–ˆā•‘');
232
+ console.log(' ā•šā•ā• ā•šā•ā• ā•šā•ā•ā•šā•ā• ā•šā•ā•ā•šā•ā•ā•ā•ā•ā•ā• ā•šā•ā•ā•ā•ā•ā• ā•šā•ā•ā•ā•ā•ā• ā•šā•ā•ā•ā•ā•ā• ā•šā•ā•ā•ā•ā•ā• ā•šā•ā•ā•ā•ā•ā•ā•ā•šā•ā• ā•šā•ā•ā•ā•');
233
+ console.log();
234
+ console.log(`šŸš€ Output path: ${output}`);
235
+ console.log(`šŸ“ Top-level folders: ${numFolders}`);
236
+ console.log(`šŸ“„ Files per folder: ${filesPerFolder} (±${filesSpread})`);
237
+ console.log(`šŸ’¾ File size: ${minSizeKb}–${maxSizeKb} KB`);
238
+ console.log(`🌳 Nesting depth: ${minDepth}–${maxDepth}`);
239
+ console.log(`šŸ“ Max name length: ${maxFilenameLength} chars`);
240
+ if (filesLimit != null) console.log(`šŸ”¢ File limit: ${filesLimit}`);
241
+ console.log();
242
+
243
+ const stats = { totalFiles: 0, totalSize: 0, totalFolders: 0 };
244
+ const existingFolderNames = new Set();
245
+
246
+ // If filesLimit is provided, treat numFolders as a minimum starting point
247
+ // and keep adding top-level folders until the file limit is reached.
248
+ for (let i = 0; i < numFolders || (filesLimit != null && stats.totalFiles < filesLimit); i++) {
249
+ const folderName = generateFoldername(maxFilenameLength, existingFolderNames);
250
+ const folderPath = join(output, folderName);
251
+ process.stdout.write(`šŸ“ ${folderName}/\n`);
252
+
253
+ const limitReached = createFolderRecursive(folderPath, 1, {
254
+ maxDepth, minDepth, filesPerFolder, filesSpread,
255
+ minSizeKb, maxSizeKb, maxFilenameLength, filesLimit, indent: '',
256
+ }, stats);
257
+
258
+ if (limitReached) break;
259
+ }
260
+
261
+ console.log(`\n✨ Done!`);
262
+ console.log(`šŸ“Š Created: ${stats.totalFiles} files in ${stats.totalFolders} folders`);
263
+ console.log(`šŸ’½ Total size: ${stats.totalSize.toFixed(1)} KB (${(stats.totalSize / 1024).toFixed(2)} MB)`);
264
+ }
265
+
266
+ // ── CLI ───────────────────────────────────────────────────────────────────────
267
+
268
+ const { values: args, positionals } = parseArgs({
269
+ allowPositionals: true,
270
+ options: {
271
+ output: { type: 'string', short: 'o', default: 'docs/fake-docs' },
272
+ folders: { type: 'string', short: 'f', default: '100' },
273
+ files: { type: 'string', short: 'n', default: '100' },
274
+ 'files-spread': { type: 'string', default: '2' },
275
+ 'min-size': { type: 'string', default: '1' },
276
+ 'max-size': { type: 'string', default: '10' },
277
+ 'min-depth': { type: 'string', default: '1' },
278
+ 'max-depth': { type: 'string', default: '1' },
279
+ 'max-filename-length': { type: 'string', default: '20' },
280
+ 'files-limit': { type: 'string', default: undefined },
281
+ },
282
+ });
283
+
284
+ // Allow: npm run gen:docs -- 100 (single positional = files-limit)
285
+ // Allow: npm run gen:docs -- 100 ./docs (positional 1 = limit, 2 = output)
286
+ if (positionals[0] != null && args['files-limit'] == null) {
287
+ args['files-limit'] = positionals[0];
288
+ }
289
+ if (positionals[1] != null) {
290
+ args.output = positionals[1];
291
+ }
292
+
293
+ const minDepth = parseInt(args['min-depth']);
294
+ const maxDepth = parseInt(args['max-depth']);
295
+
296
+ if (minDepth < 1) { console.error('āŒ --min-depth must be >= 1'); process.exit(1); }
297
+ if (maxDepth < minDepth) { console.error('āŒ --max-depth cannot be less than --min-depth'); process.exit(1); }
298
+
299
+ createDocumentationStructure({
300
+ output: args.output,
301
+ numFolders: parseInt(args.folders),
302
+ filesPerFolder: parseInt(args.files),
303
+ filesSpread: parseInt(args['files-spread']),
304
+ minSizeKb: parseInt(args['min-size']),
305
+ maxSizeKb: parseInt(args['max-size']),
306
+ minDepth,
307
+ maxDepth,
308
+ maxFilenameLength: parseInt(args['max-filename-length']),
309
+ filesLimit: args['files-limit'] != null ? parseInt(args['files-limit']) : null,
310
+ });
package/package.json ADDED
@@ -0,0 +1,92 @@
1
+ {
2
+ "name": "@dominikcz/greg",
3
+ "version": "0.9.27",
4
+ "type": "module",
5
+ "types": "./types/index.d.ts",
6
+ "bin": {
7
+ "greg": "bin/greg.js"
8
+ },
9
+ "exports": {
10
+ ".": {
11
+ "types": "./types/index.d.ts",
12
+ "svelte": "./src/lib/MarkdownDocs/MarkdownDocs.svelte",
13
+ "default": "./src/lib/MarkdownDocs/MarkdownDocs.svelte"
14
+ },
15
+ "./types": "./types/index.d.ts",
16
+ "./components": "./src/lib/components/index.js",
17
+ "./plugins": "./src/lib/MarkdownDocs/index.plugins.js",
18
+ "./svelte.config": "./svelte.config.js"
19
+ },
20
+ "files": [
21
+ "bin",
22
+ "scripts/generate-static.js",
23
+ "scripts/build-versions.js",
24
+ "scripts/render-markdown.js",
25
+ "src/lib",
26
+ "types",
27
+ "svelte.config.js",
28
+ "docs/guide",
29
+ "docs/reference",
30
+ "docs/__partials",
31
+ "docs/index.md",
32
+ "docs/incompatibilities.md",
33
+ "fakeDocsGenerator"
34
+ ],
35
+ "scripts": {
36
+ "dev": "node ./bin/greg.js dev",
37
+ "build": "node ./bin/greg.js build",
38
+ "build:static": "node ./bin/greg.js build:static",
39
+ "build:markdown": "node ./bin/greg.js build:markdown",
40
+ "preview": "node ./bin/greg.js preview",
41
+ "test": "vitest run",
42
+ "test:watch": "vitest",
43
+ "fakedocs": "node fakeDocsGenerator/generate_docs.js"
44
+ },
45
+ "devDependencies": {
46
+ "@sveltejs/vite-plugin-svelte": "^6.2.4",
47
+ "@types/better-sqlite3": "^7.6.13",
48
+ "@types/js-yaml": "^4.0.9",
49
+ "better-sqlite3": "^12.6.2",
50
+ "sqlite-vec": "^0.1.7-alpha.2",
51
+ "svelte": "^5.53.7",
52
+ "vite": "^7.3.1",
53
+ "vitest": "^4.0.18"
54
+ },
55
+ "dependencies": {
56
+ "@clack/prompts": "^0.9.1",
57
+ "@lucide/svelte": "^0.575.0",
58
+ "esbuild": "^0.25.10",
59
+ "fuse.js": "^7.1.0",
60
+ "js-yaml": "^4.1.1",
61
+ "mdsvex": "^0.12.6",
62
+ "mermaid": "^11.12.3",
63
+ "rehype-autolink-headings": "^7.1.0",
64
+ "rehype-mathjax": "^7.1.0",
65
+ "rehype-slug": "^6.0.0",
66
+ "rehype-stringify": "^10.0.1",
67
+ "remark-gfm": "^4.0.1",
68
+ "remark-math": "^6.0.0",
69
+ "remark-parse": "^11.0.0",
70
+ "remark-rehype": "^11.1.2",
71
+ "sass-embedded": "^1.97.3",
72
+ "shiki": "^4.0.1",
73
+ "unified": "^11.0.5",
74
+ "unist-util-visit": "^5.1.0"
75
+ },
76
+ "peerDependencies": {
77
+ "better-sqlite3": "^11.0.0",
78
+ "sqlite-vec": "^0.1.0"
79
+ },
80
+ "peerDependenciesMeta": {
81
+ "better-sqlite3": {
82
+ "optional": true
83
+ },
84
+ "sqlite-vec": {
85
+ "optional": true
86
+ }
87
+ },
88
+ "overrides": {
89
+ "dompurify": ">=3.3.2",
90
+ "immutable": ">=5.1.5"
91
+ }
92
+ }