@nuucognition/flint-cli 0.5.6-dev.7 → 0.6.0-dev.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.
- package/README.md +7 -11
- package/bin/flint-prod.js +0 -2
- package/bin/flint.js +2 -2
- package/dist/index.js +176954 -18043
- package/dist/presets/blank/preset.toml +1 -1
- package/package.json +14 -15
- package/dist/chunk-EQTCR2NT.js +0 -937
- package/dist/chunk-GHFCJKRI.js +0 -8058
- package/dist/chunk-IUKEMLPH.js +0 -465
- package/dist/chunk-JNIJ5JV6.js +0 -233
- package/dist/chunk-JSBRDJBE.js +0 -30
- package/dist/chunk-LLLVBA4Q.js +0 -1629
- package/dist/chunk-RD3WIRZN.js +0 -243
- package/dist/chunk-V7YA5RXL.js +0 -43
- package/dist/dist-7I3XJEIV.js +0 -603
- package/dist/exports-VR7XB6MC-5N77WY3S.js +0 -20
- package/dist/mesh-config-NTGFUNZL-BZ2GO3JY.js +0 -121
- package/dist/metadata-FASTWX6A-ITKM6C62.js +0 -34
- package/dist/plates-XORPQ3RU-JXVRGC23.js +0 -42
- package/dist/registry-5CNUVQN3-PCQZRXLB.js +0 -31
- package/dist/utils-BBA2XQZO-ETTV2PHU.js +0 -9
package/dist/chunk-IUKEMLPH.js
DELETED
|
@@ -1,465 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
readFlintToml
|
|
3
|
-
} from "./chunk-LLLVBA4Q.js";
|
|
4
|
-
|
|
5
|
-
// ../../packages/flint/dist/chunk-NRALZ6JV.js
|
|
6
|
-
import { readdir, readFile, mkdir, writeFile, rm, stat, copyFile } from "fs/promises";
|
|
7
|
-
import { join, basename, dirname, resolve, relative, sep, extname } from "path";
|
|
8
|
-
async function exists(path) {
|
|
9
|
-
try {
|
|
10
|
-
await stat(path);
|
|
11
|
-
return true;
|
|
12
|
-
} catch {
|
|
13
|
-
return false;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
function isPathWithinRoot(root, target) {
|
|
17
|
-
const resolvedRoot = resolve(root);
|
|
18
|
-
const resolvedTarget = resolve(target);
|
|
19
|
-
if (resolvedTarget === resolvedRoot) {
|
|
20
|
-
return true;
|
|
21
|
-
}
|
|
22
|
-
return resolvedTarget.startsWith(resolvedRoot + sep);
|
|
23
|
-
}
|
|
24
|
-
function stripFrontmatter(content) {
|
|
25
|
-
return content.replace(/^---\n[\s\S]*?\n---\n*/, "");
|
|
26
|
-
}
|
|
27
|
-
function getContentWithoutFrontmatter(content) {
|
|
28
|
-
const match = content.match(/^---\n[\s\S]*?\n---\n*/);
|
|
29
|
-
if (match) {
|
|
30
|
-
return content.slice(match[0].length);
|
|
31
|
-
}
|
|
32
|
-
return content;
|
|
33
|
-
}
|
|
34
|
-
async function collectReferencedFiles(content, flintPath, collected = /* @__PURE__ */ new Set(), visited = /* @__PURE__ */ new Set(), depth = -1, currentDepth = 0) {
|
|
35
|
-
if (depth !== -1 && currentDepth >= depth) {
|
|
36
|
-
return collected;
|
|
37
|
-
}
|
|
38
|
-
const contentWithoutFrontmatter = getContentWithoutFrontmatter(content);
|
|
39
|
-
const linkRegex = /!?\[\[([^\]|#]+)(?:#[^\]|]*)?(?:\|[^\]]*)?\]\]/g;
|
|
40
|
-
let match;
|
|
41
|
-
while ((match = linkRegex.exec(contentWithoutFrontmatter)) !== null) {
|
|
42
|
-
const captured = match[1];
|
|
43
|
-
if (!captured) continue;
|
|
44
|
-
const target = captured.trim();
|
|
45
|
-
const sourcePath = await resolveDocument(target, flintPath);
|
|
46
|
-
if (!sourcePath || visited.has(sourcePath)) {
|
|
47
|
-
continue;
|
|
48
|
-
}
|
|
49
|
-
collected.add(sourcePath);
|
|
50
|
-
visited.add(sourcePath);
|
|
51
|
-
if (depth === -1 || currentDepth + 1 < depth) {
|
|
52
|
-
const referencedContent = await readFile(sourcePath, "utf-8");
|
|
53
|
-
await collectReferencedFiles(referencedContent, flintPath, collected, visited, depth, currentDepth + 1);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return collected;
|
|
57
|
-
}
|
|
58
|
-
async function expandEmbeds(content, flintPath, visited = /* @__PURE__ */ new Set()) {
|
|
59
|
-
const embedRegex = /!\[\[([^\]|#]+)(?:#[^\]|]*)?(?:\|[^\]]*)?\]\]/g;
|
|
60
|
-
let result = content;
|
|
61
|
-
let match;
|
|
62
|
-
const matches = [];
|
|
63
|
-
while ((match = embedRegex.exec(content)) !== null) {
|
|
64
|
-
const captured = match[1];
|
|
65
|
-
if (!captured) continue;
|
|
66
|
-
matches.push({ full: match[0], target: captured.trim() });
|
|
67
|
-
}
|
|
68
|
-
for (const { full, target } of matches) {
|
|
69
|
-
const sourcePath = await resolveDocument(target, flintPath);
|
|
70
|
-
if (!sourcePath) {
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
if (visited.has(sourcePath)) {
|
|
74
|
-
result = result.replace(full, `<!-- Circular embed removed: ${target} -->`);
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
|
-
let embeddedContent = await readFile(sourcePath, "utf-8");
|
|
78
|
-
embeddedContent = embeddedContent.replace(/^---\n[\s\S]*?\n---\n*/, "");
|
|
79
|
-
const newVisited = new Set(visited);
|
|
80
|
-
newVisited.add(sourcePath);
|
|
81
|
-
embeddedContent = await expandEmbeds(embeddedContent, flintPath, newVisited);
|
|
82
|
-
const fileName = basename(sourcePath, ".md");
|
|
83
|
-
const quotedContent = embeddedContent.trim().split("\n").map((line) => `> ${line}`).join("\n");
|
|
84
|
-
const formattedEmbed = `> **${fileName}**
|
|
85
|
-
>
|
|
86
|
-
${quotedContent}`;
|
|
87
|
-
result = result.replace(full, formattedEmbed);
|
|
88
|
-
}
|
|
89
|
-
return result;
|
|
90
|
-
}
|
|
91
|
-
async function rewriteWikilinks(content, flintName, exportName, flintPath, exportNameBySourcePath, resolveCache) {
|
|
92
|
-
const wikilinkRegex = /\[\[([^\]|#]+)(#[^\]|]*)?((\|)([^\]]*))?\]\]/g;
|
|
93
|
-
let result = "";
|
|
94
|
-
let lastIndex = 0;
|
|
95
|
-
let match;
|
|
96
|
-
while ((match = wikilinkRegex.exec(content)) !== null) {
|
|
97
|
-
const matchIndex = match.index ?? 0;
|
|
98
|
-
result += content.slice(lastIndex, matchIndex);
|
|
99
|
-
const target = match[1]?.trim();
|
|
100
|
-
const section = match[2] || "";
|
|
101
|
-
const alias = match[5];
|
|
102
|
-
if (!target) {
|
|
103
|
-
result += match[0];
|
|
104
|
-
lastIndex = matchIndex + match[0].length;
|
|
105
|
-
continue;
|
|
106
|
-
}
|
|
107
|
-
const resolvedPath = await resolveDocumentCached(target, flintPath, resolveCache);
|
|
108
|
-
const exportBaseName = resolvedPath ? exportNameBySourcePath.get(resolvedPath) : void 0;
|
|
109
|
-
if (exportBaseName) {
|
|
110
|
-
const dotName = `(Flint) ${flintName} . (Mesh Export) ${exportName} - ${exportBaseName}`;
|
|
111
|
-
const displayAlias = alias || target;
|
|
112
|
-
result += `[[${dotName}${section}|${displayAlias}]]`;
|
|
113
|
-
} else {
|
|
114
|
-
result += match[0];
|
|
115
|
-
}
|
|
116
|
-
lastIndex = matchIndex + match[0].length;
|
|
117
|
-
}
|
|
118
|
-
result += content.slice(lastIndex);
|
|
119
|
-
return result;
|
|
120
|
-
}
|
|
121
|
-
function parseExportDocument(content, name, sourcePath) {
|
|
122
|
-
const files = [];
|
|
123
|
-
let description;
|
|
124
|
-
let depth = 1;
|
|
125
|
-
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
126
|
-
if (frontmatterMatch && frontmatterMatch[1]) {
|
|
127
|
-
const descMatch = frontmatterMatch[1].match(/description:\s*(.+)/);
|
|
128
|
-
if (descMatch && descMatch[1]) {
|
|
129
|
-
description = descMatch[1].trim().replace(/^["']|["']$/g, "");
|
|
130
|
-
}
|
|
131
|
-
const depthMatch = frontmatterMatch[1].match(/export-depth:\s*(-?\d+)/);
|
|
132
|
-
if (depthMatch && depthMatch[1]) {
|
|
133
|
-
depth = parseInt(depthMatch[1], 10);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
const contentWithoutFrontmatter = getContentWithoutFrontmatter(content);
|
|
137
|
-
const wikilinkRegex = /\[\[([^\]|]+)(?:\|[^\]]+)?\]\]/g;
|
|
138
|
-
let match;
|
|
139
|
-
while ((match = wikilinkRegex.exec(contentWithoutFrontmatter)) !== null) {
|
|
140
|
-
if (match[1]) files.push(match[1]);
|
|
141
|
-
}
|
|
142
|
-
const mdLinkRegex = /\[([^\]]+)\]\(([^)]+\.md)\)/g;
|
|
143
|
-
while ((match = mdLinkRegex.exec(contentWithoutFrontmatter)) !== null) {
|
|
144
|
-
if (match[2]) files.push(match[2]);
|
|
145
|
-
}
|
|
146
|
-
return { name, description, depth, files, sourcePath };
|
|
147
|
-
}
|
|
148
|
-
async function findFilesRecursively(dir, fileName, matches = []) {
|
|
149
|
-
try {
|
|
150
|
-
const entries = await readdir(dir, { withFileTypes: true });
|
|
151
|
-
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
152
|
-
for (const entry of entries) {
|
|
153
|
-
const fullPath = join(dir, entry.name);
|
|
154
|
-
if (entry.isFile() && entry.name === fileName) {
|
|
155
|
-
matches.push(fullPath);
|
|
156
|
-
}
|
|
157
|
-
if (entry.isDirectory()) {
|
|
158
|
-
await findFilesRecursively(fullPath, fileName, matches);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
} catch {
|
|
162
|
-
}
|
|
163
|
-
return matches;
|
|
164
|
-
}
|
|
165
|
-
async function resolveDocument(docRef, flintPath) {
|
|
166
|
-
const trimmedRef = docRef.trim();
|
|
167
|
-
if (!trimmedRef) {
|
|
168
|
-
return null;
|
|
169
|
-
}
|
|
170
|
-
const normalizedRef = trimmedRef.replace(/\\/g, "/");
|
|
171
|
-
const hasPath = normalizedRef.includes("/");
|
|
172
|
-
if (hasPath) {
|
|
173
|
-
const cleanedRef = normalizedRef.replace(/^\.?\//, "");
|
|
174
|
-
const withExt = cleanedRef.endsWith(".md") ? cleanedRef : `${cleanedRef}.md`;
|
|
175
|
-
const directCandidate = resolve(flintPath, withExt);
|
|
176
|
-
if (isPathWithinRoot(flintPath, directCandidate) && await exists(directCandidate)) {
|
|
177
|
-
return directCandidate;
|
|
178
|
-
}
|
|
179
|
-
if (!cleanedRef.startsWith("Mesh/")) {
|
|
180
|
-
const meshCandidate = resolve(flintPath, "Mesh", withExt);
|
|
181
|
-
if (isPathWithinRoot(flintPath, meshCandidate) && await exists(meshCandidate)) {
|
|
182
|
-
return meshCandidate;
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
const docName = basename(trimmedRef);
|
|
187
|
-
const fileName = docName.endsWith(".md") ? docName : `${docName}.md`;
|
|
188
|
-
const meshDir = join(flintPath, "Mesh");
|
|
189
|
-
const meshMatches = await findFilesRecursively(meshDir, fileName);
|
|
190
|
-
if (meshMatches.length > 0) {
|
|
191
|
-
meshMatches.sort();
|
|
192
|
-
return meshMatches[0] ?? null;
|
|
193
|
-
}
|
|
194
|
-
const shardsDir = join(flintPath, "Shards");
|
|
195
|
-
const shardMatches = await findFilesRecursively(shardsDir, fileName);
|
|
196
|
-
if (shardMatches.length > 0) {
|
|
197
|
-
shardMatches.sort();
|
|
198
|
-
return shardMatches[0] ?? null;
|
|
199
|
-
}
|
|
200
|
-
return null;
|
|
201
|
-
}
|
|
202
|
-
async function resolveDocumentCached(docRef, flintPath, cache) {
|
|
203
|
-
const key = docRef.trim();
|
|
204
|
-
if (cache.has(key)) {
|
|
205
|
-
return cache.get(key) ?? null;
|
|
206
|
-
}
|
|
207
|
-
const resolved = await resolveDocument(key, flintPath);
|
|
208
|
-
cache.set(key, resolved);
|
|
209
|
-
return resolved;
|
|
210
|
-
}
|
|
211
|
-
function getDisambiguatedExportName(flintPath, sourcePath, baseName) {
|
|
212
|
-
const relativePath = relative(flintPath, sourcePath);
|
|
213
|
-
const relativeDir = dirname(relativePath);
|
|
214
|
-
if (!relativeDir || relativeDir === ".") {
|
|
215
|
-
return baseName;
|
|
216
|
-
}
|
|
217
|
-
const dirLabel = relativeDir.split(sep).join(" - ");
|
|
218
|
-
return `${baseName} (${dirLabel})`;
|
|
219
|
-
}
|
|
220
|
-
async function scanExports(flintPath) {
|
|
221
|
-
const { readFlintToml: readFlintToml2 } = await import("./mesh-config-NTGFUNZL-BZ2GO3JY.js");
|
|
222
|
-
const config = await readFlintToml2(flintPath);
|
|
223
|
-
const declarations = config?.exports?.required;
|
|
224
|
-
if (!declarations || declarations.length === 0) {
|
|
225
|
-
return [];
|
|
226
|
-
}
|
|
227
|
-
return scanExportsFromConfig(flintPath, declarations);
|
|
228
|
-
}
|
|
229
|
-
async function scanExportsFromConfig(flintPath, declarations) {
|
|
230
|
-
const manifests = [];
|
|
231
|
-
for (const decl of declarations) {
|
|
232
|
-
const sourcePath = await resolveDocument(decl.file.replace(/\.md$/, ""), flintPath);
|
|
233
|
-
if (!sourcePath) continue;
|
|
234
|
-
try {
|
|
235
|
-
const content = await readFile(sourcePath, "utf-8");
|
|
236
|
-
const depth = decl.depth ?? 1;
|
|
237
|
-
const manifest = parseExportDocument(content, decl.name, sourcePath);
|
|
238
|
-
manifest.depth = depth;
|
|
239
|
-
manifests.push(manifest);
|
|
240
|
-
} catch {
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
return manifests;
|
|
244
|
-
}
|
|
245
|
-
async function scanExportEligible(flintPath) {
|
|
246
|
-
const meshDir = join(flintPath, "Mesh");
|
|
247
|
-
if (!await exists(meshDir)) return [];
|
|
248
|
-
const { readFlintToml: readFlintToml2 } = await import("./mesh-config-NTGFUNZL-BZ2GO3JY.js");
|
|
249
|
-
const config = await readFlintToml2(flintPath);
|
|
250
|
-
const declared = new Set(
|
|
251
|
-
(config?.exports?.required || []).map((d) => d.file.replace(/\.md$/, "").toLowerCase())
|
|
252
|
-
);
|
|
253
|
-
const eligible = [];
|
|
254
|
-
await findExportTaggedFiles(meshDir, flintPath, declared, eligible);
|
|
255
|
-
return eligible;
|
|
256
|
-
}
|
|
257
|
-
async function findExportTaggedFiles(dir, flintPath, declared, results) {
|
|
258
|
-
try {
|
|
259
|
-
const entries = await readdir(dir, { withFileTypes: true });
|
|
260
|
-
for (const entry of entries) {
|
|
261
|
-
const fullPath = join(dir, entry.name);
|
|
262
|
-
if (entry.isDirectory()) {
|
|
263
|
-
await findExportTaggedFiles(fullPath, flintPath, declared, results);
|
|
264
|
-
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
265
|
-
try {
|
|
266
|
-
const content = await readFile(fullPath, "utf-8");
|
|
267
|
-
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
268
|
-
if (!fmMatch || !fmMatch[1]) continue;
|
|
269
|
-
const hasExportTag = /["']#export["']/.test(fmMatch[1]);
|
|
270
|
-
if (!hasExportTag) continue;
|
|
271
|
-
const fileName = basename(fullPath, ".md");
|
|
272
|
-
if (declared.has(fileName.toLowerCase())) continue;
|
|
273
|
-
results.push({
|
|
274
|
-
filePath: fullPath,
|
|
275
|
-
fileName: entry.name,
|
|
276
|
-
name: fileName
|
|
277
|
-
});
|
|
278
|
-
} catch {
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
} catch {
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
async function collectMediaFiles(content, flintPath, collected) {
|
|
286
|
-
const contentBody = getContentWithoutFrontmatter(content);
|
|
287
|
-
const embedRegex = /!\[\[([^\]|#]+)(?:#[^\]|]*)?(?:\|[^\]]*)?\]\]/g;
|
|
288
|
-
let match;
|
|
289
|
-
while ((match = embedRegex.exec(contentBody)) !== null) {
|
|
290
|
-
const target = match[1]?.trim();
|
|
291
|
-
if (!target) continue;
|
|
292
|
-
if (target.endsWith(".md") || !target.includes(".")) continue;
|
|
293
|
-
const mediaPath = join(flintPath, "Media", target);
|
|
294
|
-
if (await exists(mediaPath)) {
|
|
295
|
-
collected.add(mediaPath);
|
|
296
|
-
continue;
|
|
297
|
-
}
|
|
298
|
-
const mediaDir = join(flintPath, "Media");
|
|
299
|
-
if (await exists(mediaDir)) {
|
|
300
|
-
const matches = await findFilesRecursively(mediaDir, basename(target));
|
|
301
|
-
if (matches.length > 0 && matches[0]) {
|
|
302
|
-
collected.add(matches[0]);
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
async function buildExport(manifest, flintPath) {
|
|
308
|
-
const exportsDir = join(flintPath, "Exports");
|
|
309
|
-
const outputDir = join(exportsDir, `(Mesh Export) ${manifest.name}`);
|
|
310
|
-
const meshOutputDir = join(outputDir, "Mesh");
|
|
311
|
-
const mediaOutputDir = join(outputDir, "Media");
|
|
312
|
-
if (await exists(outputDir)) {
|
|
313
|
-
await rm(outputDir, { recursive: true });
|
|
314
|
-
}
|
|
315
|
-
await mkdir(meshOutputDir, { recursive: true });
|
|
316
|
-
const config = await readFlintToml(flintPath);
|
|
317
|
-
const folderName = basename(flintPath);
|
|
318
|
-
const flintName = config?.flint?.name || folderName.replace(/^\(Mesh\)\s*/, "").replace(/^\(Flint\)\s*/, "");
|
|
319
|
-
const resolvedFiles = [];
|
|
320
|
-
const processedPaths = /* @__PURE__ */ new Set();
|
|
321
|
-
processedPaths.add(manifest.sourcePath);
|
|
322
|
-
const depth = manifest.depth;
|
|
323
|
-
if (depth === -1 || depth > 0) {
|
|
324
|
-
for (const docRef of manifest.files) {
|
|
325
|
-
const sourcePath = await resolveDocument(docRef, flintPath);
|
|
326
|
-
if (!sourcePath || processedPaths.has(sourcePath)) continue;
|
|
327
|
-
resolvedFiles.push({ sourcePath, docRef });
|
|
328
|
-
processedPaths.add(sourcePath);
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
const allReferencedFiles = /* @__PURE__ */ new Set();
|
|
332
|
-
const exportContent = await readFile(manifest.sourcePath, "utf-8");
|
|
333
|
-
await collectReferencedFiles(exportContent, flintPath, allReferencedFiles, new Set(processedPaths), depth, 0);
|
|
334
|
-
for (const { sourcePath } of resolvedFiles) {
|
|
335
|
-
const content = await readFile(sourcePath, "utf-8");
|
|
336
|
-
await collectReferencedFiles(content, flintPath, allReferencedFiles, new Set(processedPaths), depth, 1);
|
|
337
|
-
}
|
|
338
|
-
for (const refPath of allReferencedFiles) {
|
|
339
|
-
if (!processedPaths.has(refPath)) {
|
|
340
|
-
resolvedFiles.push({ sourcePath: refPath, docRef: basename(refPath, ".md") });
|
|
341
|
-
processedPaths.add(refPath);
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
const mediaFiles = /* @__PURE__ */ new Set();
|
|
345
|
-
await collectMediaFiles(exportContent, flintPath, mediaFiles);
|
|
346
|
-
for (const { sourcePath } of resolvedFiles) {
|
|
347
|
-
const content = await readFile(sourcePath, "utf-8");
|
|
348
|
-
await collectMediaFiles(content, flintPath, mediaFiles);
|
|
349
|
-
}
|
|
350
|
-
const allExportFiles = [
|
|
351
|
-
{ sourcePath: manifest.sourcePath, baseName: basename(manifest.sourcePath, ".md") },
|
|
352
|
-
...resolvedFiles.map((f) => ({ sourcePath: f.sourcePath, baseName: basename(f.sourcePath, ".md") }))
|
|
353
|
-
];
|
|
354
|
-
const baseNameCounts = /* @__PURE__ */ new Map();
|
|
355
|
-
for (const { baseName } of allExportFiles) {
|
|
356
|
-
baseNameCounts.set(baseName, (baseNameCounts.get(baseName) || 0) + 1);
|
|
357
|
-
}
|
|
358
|
-
const duplicateBaseNames = new Set(
|
|
359
|
-
Array.from(baseNameCounts.entries()).filter(([, count]) => count > 1).map(([name]) => name)
|
|
360
|
-
);
|
|
361
|
-
const exportNameBySourcePath = /* @__PURE__ */ new Map();
|
|
362
|
-
for (const { sourcePath, baseName } of allExportFiles) {
|
|
363
|
-
const name = duplicateBaseNames.has(baseName) ? getDisambiguatedExportName(flintPath, sourcePath, baseName) : baseName;
|
|
364
|
-
exportNameBySourcePath.set(sourcePath, name);
|
|
365
|
-
}
|
|
366
|
-
const dotPrefix = `(Flint) ${flintName} . (Mesh Export) ${manifest.name}`;
|
|
367
|
-
let filesCopied = 0;
|
|
368
|
-
const copiedFiles = [];
|
|
369
|
-
const resolveCache = /* @__PURE__ */ new Map();
|
|
370
|
-
let rootContent = await readFile(manifest.sourcePath, "utf-8");
|
|
371
|
-
rootContent = stripFrontmatter(rootContent);
|
|
372
|
-
rootContent = await expandEmbeds(rootContent, flintPath, /* @__PURE__ */ new Set([manifest.sourcePath]));
|
|
373
|
-
rootContent = await rewriteWikilinks(rootContent, flintName, manifest.name, flintPath, exportNameBySourcePath, resolveCache);
|
|
374
|
-
const rootExportName = exportNameBySourcePath.get(manifest.sourcePath) || manifest.name;
|
|
375
|
-
const rootFileName = `${dotPrefix} - ${rootExportName}.md`;
|
|
376
|
-
await writeFile(join(meshOutputDir, rootFileName), rootContent);
|
|
377
|
-
copiedFiles.push(`Mesh/${rootFileName}`);
|
|
378
|
-
filesCopied++;
|
|
379
|
-
for (const { sourcePath } of resolvedFiles) {
|
|
380
|
-
const exportBaseName = exportNameBySourcePath.get(sourcePath) || basename(sourcePath, ".md");
|
|
381
|
-
const fileName = `${dotPrefix} - ${exportBaseName}.md`;
|
|
382
|
-
const destPath = join(meshOutputDir, fileName);
|
|
383
|
-
let content = await readFile(sourcePath, "utf-8");
|
|
384
|
-
content = stripFrontmatter(content);
|
|
385
|
-
content = await expandEmbeds(content, flintPath, /* @__PURE__ */ new Set([sourcePath]));
|
|
386
|
-
content = await rewriteWikilinks(content, flintName, manifest.name, flintPath, exportNameBySourcePath, resolveCache);
|
|
387
|
-
await writeFile(destPath, content);
|
|
388
|
-
copiedFiles.push(`Mesh/${fileName}`);
|
|
389
|
-
filesCopied++;
|
|
390
|
-
}
|
|
391
|
-
if (mediaFiles.size > 0) {
|
|
392
|
-
await mkdir(mediaOutputDir, { recursive: true });
|
|
393
|
-
for (const mediaPath of mediaFiles) {
|
|
394
|
-
const originalName = basename(mediaPath);
|
|
395
|
-
const mediaFileName = `${dotPrefix} - ${originalName}`;
|
|
396
|
-
await copyFile(mediaPath, join(mediaOutputDir, mediaFileName));
|
|
397
|
-
copiedFiles.push(`Media/${mediaFileName}`);
|
|
398
|
-
filesCopied++;
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
const manifestJson = {
|
|
402
|
-
name: manifest.name,
|
|
403
|
-
flint: flintName,
|
|
404
|
-
rootFile: `Mesh/${rootFileName}`,
|
|
405
|
-
builtAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
406
|
-
files: copiedFiles
|
|
407
|
-
};
|
|
408
|
-
await writeFile(
|
|
409
|
-
join(outputDir, "_manifest.json"),
|
|
410
|
-
JSON.stringify(manifestJson, null, 2)
|
|
411
|
-
);
|
|
412
|
-
return {
|
|
413
|
-
name: manifest.name,
|
|
414
|
-
outputPath: outputDir,
|
|
415
|
-
filesCopied
|
|
416
|
-
};
|
|
417
|
-
}
|
|
418
|
-
async function buildExportByName(flintPath, exportName) {
|
|
419
|
-
const manifests = await scanExports(flintPath);
|
|
420
|
-
const manifest = manifests.find((m) => m.name === exportName);
|
|
421
|
-
if (!manifest) {
|
|
422
|
-
return null;
|
|
423
|
-
}
|
|
424
|
-
return buildExport(manifest, flintPath);
|
|
425
|
-
}
|
|
426
|
-
async function cleanupStaleExports(flintPath) {
|
|
427
|
-
const exportsDir = join(flintPath, "Exports");
|
|
428
|
-
const removed = [];
|
|
429
|
-
if (!await exists(exportsDir)) {
|
|
430
|
-
return removed;
|
|
431
|
-
}
|
|
432
|
-
const manifests = await scanExports(flintPath);
|
|
433
|
-
const validFolderNames = new Set(manifests.map((m) => `(Mesh Export) ${m.name}`));
|
|
434
|
-
const entries = await readdir(exportsDir, { withFileTypes: true });
|
|
435
|
-
for (const entry of entries) {
|
|
436
|
-
if (entry.isDirectory() && !validFolderNames.has(entry.name)) {
|
|
437
|
-
try {
|
|
438
|
-
await rm(join(exportsDir, entry.name), { recursive: true });
|
|
439
|
-
removed.push(entry.name);
|
|
440
|
-
} catch {
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
return removed;
|
|
445
|
-
}
|
|
446
|
-
async function buildAllExports(flintPath) {
|
|
447
|
-
const removed = await cleanupStaleExports(flintPath);
|
|
448
|
-
const manifests = await scanExports(flintPath);
|
|
449
|
-
const results = [];
|
|
450
|
-
for (const manifest of manifests) {
|
|
451
|
-
const result = await buildExport(manifest, flintPath);
|
|
452
|
-
results.push(result);
|
|
453
|
-
}
|
|
454
|
-
return { results, removed };
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
export {
|
|
458
|
-
resolveDocument,
|
|
459
|
-
scanExports,
|
|
460
|
-
scanExportEligible,
|
|
461
|
-
buildExport,
|
|
462
|
-
buildExportByName,
|
|
463
|
-
cleanupStaleExports,
|
|
464
|
-
buildAllExports
|
|
465
|
-
};
|
package/dist/chunk-JNIJ5JV6.js
DELETED
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
// ../../packages/flint/dist/chunk-MAL7MTPY.js
|
|
2
|
-
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
3
|
-
import { homedir } from "os";
|
|
4
|
-
import { join, resolve } from "path";
|
|
5
|
-
var REGISTRY_VERSION = 1;
|
|
6
|
-
function getGlobalFlintDir() {
|
|
7
|
-
return join(homedir(), ".nuucognition", "flint");
|
|
8
|
-
}
|
|
9
|
-
function getFlintRegistryPath() {
|
|
10
|
-
return join(getGlobalFlintDir(), "registry.json");
|
|
11
|
-
}
|
|
12
|
-
async function ensureRegistryDir() {
|
|
13
|
-
await mkdir(getGlobalFlintDir(), { recursive: true });
|
|
14
|
-
}
|
|
15
|
-
function createEmptyRegistry() {
|
|
16
|
-
return {
|
|
17
|
-
version: REGISTRY_VERSION,
|
|
18
|
-
flints: []
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
async function getFlintRegistry() {
|
|
22
|
-
try {
|
|
23
|
-
const content = await readFile(getFlintRegistryPath(), "utf-8");
|
|
24
|
-
const registry = JSON.parse(content);
|
|
25
|
-
return registry.flints;
|
|
26
|
-
} catch (error) {
|
|
27
|
-
if (error.code === "ENOENT") {
|
|
28
|
-
return [];
|
|
29
|
-
}
|
|
30
|
-
throw error;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
async function saveRegistry(registry) {
|
|
34
|
-
await ensureRegistryDir();
|
|
35
|
-
await writeFile(getFlintRegistryPath(), JSON.stringify(registry, null, 2));
|
|
36
|
-
}
|
|
37
|
-
async function registerFlint(entry) {
|
|
38
|
-
const normalizedEntry = { ...entry, path: resolve(entry.path) };
|
|
39
|
-
const flints = await getFlintRegistry();
|
|
40
|
-
const existing = flints.find((f) => f.path === normalizedEntry.path);
|
|
41
|
-
if (existing) {
|
|
42
|
-
throw new Error(`Flint already registered at path: ${entry.path}`);
|
|
43
|
-
}
|
|
44
|
-
flints.push(normalizedEntry);
|
|
45
|
-
await saveRegistry({ version: REGISTRY_VERSION, flints });
|
|
46
|
-
}
|
|
47
|
-
async function unregisterFlint(path) {
|
|
48
|
-
const resolvedPath = resolve(path);
|
|
49
|
-
const flints = await getFlintRegistry();
|
|
50
|
-
const filtered = flints.filter((f) => f.path !== resolvedPath);
|
|
51
|
-
if (filtered.length === flints.length) {
|
|
52
|
-
throw new Error(`Flint not found at path: ${path}`);
|
|
53
|
-
}
|
|
54
|
-
await saveRegistry({ version: REGISTRY_VERSION, flints: filtered });
|
|
55
|
-
}
|
|
56
|
-
async function findFlintByPath(path) {
|
|
57
|
-
const resolvedPath = resolve(path);
|
|
58
|
-
const flints = await getFlintRegistry();
|
|
59
|
-
return flints.find((f) => f.path === resolvedPath) ?? null;
|
|
60
|
-
}
|
|
61
|
-
async function findFlintByName(name) {
|
|
62
|
-
const flints = await getFlintRegistry();
|
|
63
|
-
return flints.find((f) => f.name === name) ?? null;
|
|
64
|
-
}
|
|
65
|
-
async function isFlintNameTaken(name) {
|
|
66
|
-
const flints = await getFlintRegistry();
|
|
67
|
-
return flints.find((f) => f.name === name);
|
|
68
|
-
}
|
|
69
|
-
async function upsertFlintEntry(entry) {
|
|
70
|
-
const normalizedEntry = { ...entry, path: resolve(entry.path) };
|
|
71
|
-
const flints = await getFlintRegistry();
|
|
72
|
-
const indexByPath = flints.findIndex((f) => f.path === normalizedEntry.path);
|
|
73
|
-
if (indexByPath !== -1) {
|
|
74
|
-
flints[indexByPath] = normalizedEntry;
|
|
75
|
-
} else {
|
|
76
|
-
flints.push(normalizedEntry);
|
|
77
|
-
}
|
|
78
|
-
await saveRegistry({ version: REGISTRY_VERSION, flints });
|
|
79
|
-
}
|
|
80
|
-
async function updateFlintEntry(path, updates) {
|
|
81
|
-
const resolvedPath = resolve(path);
|
|
82
|
-
const flints = await getFlintRegistry();
|
|
83
|
-
const entry = flints.find((f) => f.path === resolvedPath);
|
|
84
|
-
if (!entry) {
|
|
85
|
-
throw new Error(`Flint not found at path: ${path}`);
|
|
86
|
-
}
|
|
87
|
-
Object.assign(entry, updates);
|
|
88
|
-
await saveRegistry({ version: REGISTRY_VERSION, flints });
|
|
89
|
-
}
|
|
90
|
-
async function isPathRegistered(path) {
|
|
91
|
-
const resolvedPath = resolve(path);
|
|
92
|
-
const flints = await getFlintRegistry();
|
|
93
|
-
return flints.some((f) => f.path === resolvedPath);
|
|
94
|
-
}
|
|
95
|
-
async function cleanRegistryFile() {
|
|
96
|
-
const result = {
|
|
97
|
-
entriesCleaned: 0,
|
|
98
|
-
invalidEntriesRemoved: 0,
|
|
99
|
-
modified: false,
|
|
100
|
-
details: []
|
|
101
|
-
};
|
|
102
|
-
let rawContent;
|
|
103
|
-
try {
|
|
104
|
-
rawContent = await readFile(getFlintRegistryPath(), "utf-8");
|
|
105
|
-
} catch (error) {
|
|
106
|
-
if (error.code === "ENOENT") {
|
|
107
|
-
return result;
|
|
108
|
-
}
|
|
109
|
-
throw error;
|
|
110
|
-
}
|
|
111
|
-
let registry;
|
|
112
|
-
try {
|
|
113
|
-
registry = JSON.parse(rawContent);
|
|
114
|
-
} catch {
|
|
115
|
-
result.details.push("Registry file was corrupted, creating fresh registry");
|
|
116
|
-
result.modified = true;
|
|
117
|
-
await saveRegistry(createEmptyRegistry());
|
|
118
|
-
return result;
|
|
119
|
-
}
|
|
120
|
-
if (!registry || typeof registry !== "object") {
|
|
121
|
-
result.details.push("Registry file had invalid structure, creating fresh registry");
|
|
122
|
-
result.modified = true;
|
|
123
|
-
await saveRegistry(createEmptyRegistry());
|
|
124
|
-
return result;
|
|
125
|
-
}
|
|
126
|
-
if (!Array.isArray(registry.flints)) {
|
|
127
|
-
registry.flints = [];
|
|
128
|
-
result.details.push("Registry was missing flints array");
|
|
129
|
-
result.modified = true;
|
|
130
|
-
}
|
|
131
|
-
const cleanedFlints = [];
|
|
132
|
-
const deprecatedFields = ["id", "created"];
|
|
133
|
-
for (const rawEntry of registry.flints) {
|
|
134
|
-
if (!rawEntry || typeof rawEntry !== "object") {
|
|
135
|
-
result.invalidEntriesRemoved++;
|
|
136
|
-
result.details.push("Removed invalid non-object entry");
|
|
137
|
-
result.modified = true;
|
|
138
|
-
continue;
|
|
139
|
-
}
|
|
140
|
-
const entry = rawEntry;
|
|
141
|
-
if (typeof entry.name !== "string" || typeof entry.path !== "string") {
|
|
142
|
-
result.invalidEntriesRemoved++;
|
|
143
|
-
result.details.push(`Removed invalid entry missing name or path`);
|
|
144
|
-
result.modified = true;
|
|
145
|
-
continue;
|
|
146
|
-
}
|
|
147
|
-
let hadDeprecatedFields = false;
|
|
148
|
-
for (const field of deprecatedFields) {
|
|
149
|
-
if (field in entry) {
|
|
150
|
-
delete entry[field];
|
|
151
|
-
hadDeprecatedFields = true;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
if (hadDeprecatedFields) {
|
|
155
|
-
result.entriesCleaned++;
|
|
156
|
-
result.modified = true;
|
|
157
|
-
}
|
|
158
|
-
const cleanEntry = {
|
|
159
|
-
name: entry.name,
|
|
160
|
-
path: entry.path
|
|
161
|
-
};
|
|
162
|
-
if (entry.source === "local") {
|
|
163
|
-
cleanEntry.source = entry.source;
|
|
164
|
-
}
|
|
165
|
-
if (Array.isArray(entry.tags)) {
|
|
166
|
-
cleanEntry.tags = entry.tags.filter((t) => typeof t === "string");
|
|
167
|
-
}
|
|
168
|
-
if (typeof entry.description === "string") {
|
|
169
|
-
cleanEntry.description = entry.description;
|
|
170
|
-
}
|
|
171
|
-
if (Array.isArray(entry.exports)) {
|
|
172
|
-
cleanEntry.exports = entry.exports.filter((e) => typeof e === "string");
|
|
173
|
-
}
|
|
174
|
-
cleanedFlints.push(cleanEntry);
|
|
175
|
-
}
|
|
176
|
-
if (result.modified) {
|
|
177
|
-
await saveRegistry({ version: REGISTRY_VERSION, flints: cleanedFlints });
|
|
178
|
-
if (result.entriesCleaned > 0) {
|
|
179
|
-
result.details.push(`Removed deprecated fields from ${result.entriesCleaned} entries`);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
return result;
|
|
183
|
-
}
|
|
184
|
-
async function registerFlintByPath(path, options) {
|
|
185
|
-
const { readFlintToml, hasFlintToml } = await import("./mesh-config-NTGFUNZL-BZ2GO3JY.js");
|
|
186
|
-
const isFlint = await hasFlintToml(path);
|
|
187
|
-
if (!isFlint) {
|
|
188
|
-
throw new Error(`Not a valid flint: ${path}
|
|
189
|
-
Missing flint.toml`);
|
|
190
|
-
}
|
|
191
|
-
const toml = await readFlintToml(path);
|
|
192
|
-
if (!toml || !toml.flint?.name) {
|
|
193
|
-
throw new Error(`Invalid flint.toml at ${path}: missing flint.name`);
|
|
194
|
-
}
|
|
195
|
-
const name = toml.flint.name;
|
|
196
|
-
const existing = await findFlintByPath(path);
|
|
197
|
-
if (existing && !options?.force) {
|
|
198
|
-
throw new Error(`Already registered: "${existing.name}" at ${path}`);
|
|
199
|
-
}
|
|
200
|
-
const nameTaken = await isFlintNameTaken(name);
|
|
201
|
-
if (nameTaken && resolve(nameTaken.path) !== resolve(path)) {
|
|
202
|
-
throw new Error(`Name "${name}" is already taken by a flint at ${nameTaken.path}`);
|
|
203
|
-
}
|
|
204
|
-
const entry = {
|
|
205
|
-
name,
|
|
206
|
-
path,
|
|
207
|
-
source: "local"
|
|
208
|
-
};
|
|
209
|
-
if (toml.flint.tags && toml.flint.tags.length > 0) {
|
|
210
|
-
entry.tags = toml.flint.tags;
|
|
211
|
-
}
|
|
212
|
-
if (toml.flint.description) {
|
|
213
|
-
entry.description = toml.flint.description;
|
|
214
|
-
}
|
|
215
|
-
await upsertFlintEntry(entry);
|
|
216
|
-
return entry;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
export {
|
|
220
|
-
getGlobalFlintDir,
|
|
221
|
-
getFlintRegistryPath,
|
|
222
|
-
getFlintRegistry,
|
|
223
|
-
registerFlint,
|
|
224
|
-
unregisterFlint,
|
|
225
|
-
findFlintByPath,
|
|
226
|
-
findFlintByName,
|
|
227
|
-
isFlintNameTaken,
|
|
228
|
-
upsertFlintEntry,
|
|
229
|
-
updateFlintEntry,
|
|
230
|
-
isPathRegistered,
|
|
231
|
-
cleanRegistryFile,
|
|
232
|
-
registerFlintByPath
|
|
233
|
-
};
|