@rohal12/twee-ts 1.6.0 → 1.8.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/dist/bin/twee-ts.js +329 -2
- package/dist/bin/twee-ts.js.map +1 -1
- package/dist/{chunk-HXL3JC4L.js → chunk-N2OR5KHL.js} +2 -2
- package/dist/{chunk-HXL3JC4L.js.map → chunk-N2OR5KHL.js.map} +1 -1
- package/dist/index.cjs +142 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +56 -1
- package/dist/index.d.ts +56 -1
- package/dist/index.js +138 -1
- package/dist/index.js.map +1 -1
- package/dist/plugins/rollup.js +1 -1
- package/dist/plugins/vite.js +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -261,6 +261,45 @@ interface BrokenLink {
|
|
|
261
261
|
*/
|
|
262
262
|
declare function storyInspect(story: Story): StoryMap;
|
|
263
263
|
|
|
264
|
+
/**
|
|
265
|
+
* Lint mode: compile + inspect story structure without producing output.
|
|
266
|
+
* Surfaces broken links, dead ends, orphans, and compilation diagnostics.
|
|
267
|
+
*/
|
|
268
|
+
|
|
269
|
+
interface LintResult {
|
|
270
|
+
/** Compilation diagnostics (errors and warnings). */
|
|
271
|
+
diagnostics: Diagnostic[];
|
|
272
|
+
/** Compilation statistics. */
|
|
273
|
+
stats: CompileStats;
|
|
274
|
+
/** Story format name from StoryData (e.g. "SugarCube"). */
|
|
275
|
+
formatName: string;
|
|
276
|
+
/** Story format version from StoryData (e.g. "2.37.3"). */
|
|
277
|
+
formatVersion: string;
|
|
278
|
+
/** The configured start passage name. */
|
|
279
|
+
start: string;
|
|
280
|
+
/** Total passage count. */
|
|
281
|
+
passages: number;
|
|
282
|
+
/** Story passage count (excludes StoryData, StoryTitle, scripts, etc.). */
|
|
283
|
+
storyPassages: number;
|
|
284
|
+
/** Info/special passage count. */
|
|
285
|
+
infoPassages: number;
|
|
286
|
+
/** Broken links: link targets that don't exist as passages. */
|
|
287
|
+
brokenLinks: BrokenLink[];
|
|
288
|
+
/** Story passages with no outgoing links. */
|
|
289
|
+
deadEnds: string[];
|
|
290
|
+
/** Story passages that no other passage links to. */
|
|
291
|
+
orphans: string[];
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Lint a story: compile without output rendering, then inspect structure.
|
|
295
|
+
* Uses JSON output mode internally to avoid format resolution.
|
|
296
|
+
*/
|
|
297
|
+
declare function lint(options: Omit<CompileOptions, 'outputMode'>): Promise<LintResult>;
|
|
298
|
+
/**
|
|
299
|
+
* Format a lint result as a human-readable report string.
|
|
300
|
+
*/
|
|
301
|
+
declare function formatLintReport(result: LintResult): string;
|
|
302
|
+
|
|
264
303
|
/**
|
|
265
304
|
* Passage helpers and output methods.
|
|
266
305
|
* Ported from passage.go / passagedata.go.
|
|
@@ -372,5 +411,21 @@ declare function fetchDirectFormat(url: string): Promise<StoryFormatInfo>;
|
|
|
372
411
|
declare function resolveRemoteFormat(name: string, version: string, indices?: string[], urls?: string[]): Promise<StoryFormatInfo | undefined>;
|
|
373
412
|
/** Discover all cached remote formats. Returns a Map like discoverFormats(). */
|
|
374
413
|
declare function discoverCachedFormats(): Map<string, StoryFormatInfo>;
|
|
414
|
+
/** Info about a cached format entry with size and modification date. */
|
|
415
|
+
interface CachedFormatEntry {
|
|
416
|
+
readonly name: string;
|
|
417
|
+
readonly version: string;
|
|
418
|
+
readonly sizeBytes: number;
|
|
419
|
+
readonly modifiedAt: Date;
|
|
420
|
+
}
|
|
421
|
+
/** List all cached formats with size and modification date. */
|
|
422
|
+
declare function listCachedFormats(): readonly CachedFormatEntry[];
|
|
423
|
+
/** Clear all cached formats, or only those matching a given name. Returns the number of entries removed. */
|
|
424
|
+
declare function clearCachedFormats(name?: string): number;
|
|
425
|
+
/** Get total cache size in bytes and format count. */
|
|
426
|
+
declare function getCacheSize(): {
|
|
427
|
+
totalBytes: number;
|
|
428
|
+
count: number;
|
|
429
|
+
};
|
|
375
430
|
|
|
376
|
-
export { type BrokenLink, CONFIG_FILENAME, type CompileOptions, type CompileResult, type CompileStats, type CompileToFileOptions, type Diagnostic, type InlineSource, ItemType, type LexerItem, type OutputMode, type Passage, type PassageMetadata, type SFAIndex, type SFAIndexEntry, type SourceInput, type SourceLocation, type Story, type StoryFormatInfo, type StoryMap, TweeLexer, type TweeTsConfig, TweeTsError, type WatchOptions, applyTagAliases, compile, compileToFile, discoverCachedFormats, discoverFormats, fetchAndCacheFormat, fetchDirectFormat, generateIFID, getCacheDir, getFormatSearchDirs, loadConfig, loadConfigFile, parseFormatJSON, parseSemver, parseTwee, resolveRemoteFormat, scaffoldConfig, semverCompare, storyInspect, tweeLexer, validateConfig, validateIFID, watch };
|
|
431
|
+
export { type BrokenLink, CONFIG_FILENAME, type CachedFormatEntry, type CompileOptions, type CompileResult, type CompileStats, type CompileToFileOptions, type Diagnostic, type InlineSource, ItemType, type LexerItem, type LintResult, type OutputMode, type Passage, type PassageMetadata, type SFAIndex, type SFAIndexEntry, type SourceInput, type SourceLocation, type Story, type StoryFormatInfo, type StoryMap, TweeLexer, type TweeTsConfig, TweeTsError, type WatchOptions, applyTagAliases, clearCachedFormats, compile, compileToFile, discoverCachedFormats, discoverFormats, fetchAndCacheFormat, fetchDirectFormat, formatLintReport, generateIFID, getCacheDir, getCacheSize, getFormatSearchDirs, lint, listCachedFormats, loadConfig, loadConfigFile, parseFormatJSON, parseSemver, parseTwee, resolveRemoteFormat, scaffoldConfig, semverCompare, storyInspect, tweeLexer, validateConfig, validateIFID, watch };
|
package/dist/index.d.ts
CHANGED
|
@@ -261,6 +261,45 @@ interface BrokenLink {
|
|
|
261
261
|
*/
|
|
262
262
|
declare function storyInspect(story: Story): StoryMap;
|
|
263
263
|
|
|
264
|
+
/**
|
|
265
|
+
* Lint mode: compile + inspect story structure without producing output.
|
|
266
|
+
* Surfaces broken links, dead ends, orphans, and compilation diagnostics.
|
|
267
|
+
*/
|
|
268
|
+
|
|
269
|
+
interface LintResult {
|
|
270
|
+
/** Compilation diagnostics (errors and warnings). */
|
|
271
|
+
diagnostics: Diagnostic[];
|
|
272
|
+
/** Compilation statistics. */
|
|
273
|
+
stats: CompileStats;
|
|
274
|
+
/** Story format name from StoryData (e.g. "SugarCube"). */
|
|
275
|
+
formatName: string;
|
|
276
|
+
/** Story format version from StoryData (e.g. "2.37.3"). */
|
|
277
|
+
formatVersion: string;
|
|
278
|
+
/** The configured start passage name. */
|
|
279
|
+
start: string;
|
|
280
|
+
/** Total passage count. */
|
|
281
|
+
passages: number;
|
|
282
|
+
/** Story passage count (excludes StoryData, StoryTitle, scripts, etc.). */
|
|
283
|
+
storyPassages: number;
|
|
284
|
+
/** Info/special passage count. */
|
|
285
|
+
infoPassages: number;
|
|
286
|
+
/** Broken links: link targets that don't exist as passages. */
|
|
287
|
+
brokenLinks: BrokenLink[];
|
|
288
|
+
/** Story passages with no outgoing links. */
|
|
289
|
+
deadEnds: string[];
|
|
290
|
+
/** Story passages that no other passage links to. */
|
|
291
|
+
orphans: string[];
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Lint a story: compile without output rendering, then inspect structure.
|
|
295
|
+
* Uses JSON output mode internally to avoid format resolution.
|
|
296
|
+
*/
|
|
297
|
+
declare function lint(options: Omit<CompileOptions, 'outputMode'>): Promise<LintResult>;
|
|
298
|
+
/**
|
|
299
|
+
* Format a lint result as a human-readable report string.
|
|
300
|
+
*/
|
|
301
|
+
declare function formatLintReport(result: LintResult): string;
|
|
302
|
+
|
|
264
303
|
/**
|
|
265
304
|
* Passage helpers and output methods.
|
|
266
305
|
* Ported from passage.go / passagedata.go.
|
|
@@ -372,5 +411,21 @@ declare function fetchDirectFormat(url: string): Promise<StoryFormatInfo>;
|
|
|
372
411
|
declare function resolveRemoteFormat(name: string, version: string, indices?: string[], urls?: string[]): Promise<StoryFormatInfo | undefined>;
|
|
373
412
|
/** Discover all cached remote formats. Returns a Map like discoverFormats(). */
|
|
374
413
|
declare function discoverCachedFormats(): Map<string, StoryFormatInfo>;
|
|
414
|
+
/** Info about a cached format entry with size and modification date. */
|
|
415
|
+
interface CachedFormatEntry {
|
|
416
|
+
readonly name: string;
|
|
417
|
+
readonly version: string;
|
|
418
|
+
readonly sizeBytes: number;
|
|
419
|
+
readonly modifiedAt: Date;
|
|
420
|
+
}
|
|
421
|
+
/** List all cached formats with size and modification date. */
|
|
422
|
+
declare function listCachedFormats(): readonly CachedFormatEntry[];
|
|
423
|
+
/** Clear all cached formats, or only those matching a given name. Returns the number of entries removed. */
|
|
424
|
+
declare function clearCachedFormats(name?: string): number;
|
|
425
|
+
/** Get total cache size in bytes and format count. */
|
|
426
|
+
declare function getCacheSize(): {
|
|
427
|
+
totalBytes: number;
|
|
428
|
+
count: number;
|
|
429
|
+
};
|
|
375
430
|
|
|
376
|
-
export { type BrokenLink, CONFIG_FILENAME, type CompileOptions, type CompileResult, type CompileStats, type CompileToFileOptions, type Diagnostic, type InlineSource, ItemType, type LexerItem, type OutputMode, type Passage, type PassageMetadata, type SFAIndex, type SFAIndexEntry, type SourceInput, type SourceLocation, type Story, type StoryFormatInfo, type StoryMap, TweeLexer, type TweeTsConfig, TweeTsError, type WatchOptions, applyTagAliases, compile, compileToFile, discoverCachedFormats, discoverFormats, fetchAndCacheFormat, fetchDirectFormat, generateIFID, getCacheDir, getFormatSearchDirs, loadConfig, loadConfigFile, parseFormatJSON, parseSemver, parseTwee, resolveRemoteFormat, scaffoldConfig, semverCompare, storyInspect, tweeLexer, validateConfig, validateIFID, watch };
|
|
431
|
+
export { type BrokenLink, CONFIG_FILENAME, type CachedFormatEntry, type CompileOptions, type CompileResult, type CompileStats, type CompileToFileOptions, type Diagnostic, type InlineSource, ItemType, type LexerItem, type LintResult, type OutputMode, type Passage, type PassageMetadata, type SFAIndex, type SFAIndexEntry, type SourceInput, type SourceLocation, type Story, type StoryFormatInfo, type StoryMap, TweeLexer, type TweeTsConfig, TweeTsError, type WatchOptions, applyTagAliases, clearCachedFormats, compile, compileToFile, discoverCachedFormats, discoverFormats, fetchAndCacheFormat, fetchDirectFormat, formatLintReport, generateIFID, getCacheDir, getCacheSize, getFormatSearchDirs, lint, listCachedFormats, loadConfig, loadConfigFile, parseFormatJSON, parseSemver, parseTwee, resolveRemoteFormat, scaffoldConfig, semverCompare, storyInspect, tweeLexer, validateConfig, validateIFID, watch };
|
package/dist/index.js
CHANGED
|
@@ -1853,7 +1853,7 @@ function modifyHead(html, modulePaths, headFile, diagnostics) {
|
|
|
1853
1853
|
}
|
|
1854
1854
|
|
|
1855
1855
|
// src/remote-formats.ts
|
|
1856
|
-
import { mkdirSync, readFileSync as readFileSync3, writeFileSync, existsSync, readdirSync as readdirSync3, statSync as statSync4 } from "fs";
|
|
1856
|
+
import { mkdirSync, readFileSync as readFileSync3, writeFileSync, existsSync, readdirSync as readdirSync3, statSync as statSync4, rmSync } from "fs";
|
|
1857
1857
|
import { join as join4 } from "path";
|
|
1858
1858
|
import { homedir as homedir2 } from "os";
|
|
1859
1859
|
var DEFAULT_SFA_INDICES = [
|
|
@@ -2084,6 +2084,75 @@ function discoverCachedFormats() {
|
|
|
2084
2084
|
}
|
|
2085
2085
|
return formats;
|
|
2086
2086
|
}
|
|
2087
|
+
function listCachedFormats() {
|
|
2088
|
+
const cacheDir = getCacheDir();
|
|
2089
|
+
const entries = [];
|
|
2090
|
+
try {
|
|
2091
|
+
if (!existsSync(cacheDir)) return entries;
|
|
2092
|
+
} catch {
|
|
2093
|
+
return entries;
|
|
2094
|
+
}
|
|
2095
|
+
let names;
|
|
2096
|
+
try {
|
|
2097
|
+
names = readdirSync3(cacheDir);
|
|
2098
|
+
} catch {
|
|
2099
|
+
return entries;
|
|
2100
|
+
}
|
|
2101
|
+
for (const name of names) {
|
|
2102
|
+
const nameDir = join4(cacheDir, name);
|
|
2103
|
+
try {
|
|
2104
|
+
if (!statSync4(nameDir).isDirectory()) continue;
|
|
2105
|
+
} catch {
|
|
2106
|
+
continue;
|
|
2107
|
+
}
|
|
2108
|
+
let versions;
|
|
2109
|
+
try {
|
|
2110
|
+
versions = readdirSync3(nameDir);
|
|
2111
|
+
} catch {
|
|
2112
|
+
continue;
|
|
2113
|
+
}
|
|
2114
|
+
for (const version of versions) {
|
|
2115
|
+
const formatPath = join4(nameDir, version, "format.js");
|
|
2116
|
+
try {
|
|
2117
|
+
const stat = statSync4(formatPath);
|
|
2118
|
+
entries.push({
|
|
2119
|
+
name,
|
|
2120
|
+
version,
|
|
2121
|
+
sizeBytes: stat.size,
|
|
2122
|
+
modifiedAt: stat.mtime
|
|
2123
|
+
});
|
|
2124
|
+
} catch {
|
|
2125
|
+
}
|
|
2126
|
+
}
|
|
2127
|
+
}
|
|
2128
|
+
return entries;
|
|
2129
|
+
}
|
|
2130
|
+
function clearCachedFormats(name) {
|
|
2131
|
+
const cacheDir = getCacheDir();
|
|
2132
|
+
if (!existsSync(cacheDir)) return 0;
|
|
2133
|
+
if (!name) {
|
|
2134
|
+
const entries = listCachedFormats();
|
|
2135
|
+
const count2 = entries.length;
|
|
2136
|
+
rmSync(cacheDir, { recursive: true, force: true });
|
|
2137
|
+
return count2;
|
|
2138
|
+
}
|
|
2139
|
+
const nameDir = join4(cacheDir, name);
|
|
2140
|
+
if (!existsSync(nameDir)) return 0;
|
|
2141
|
+
let versions;
|
|
2142
|
+
try {
|
|
2143
|
+
versions = readdirSync3(nameDir);
|
|
2144
|
+
} catch {
|
|
2145
|
+
return 0;
|
|
2146
|
+
}
|
|
2147
|
+
const count = versions.length;
|
|
2148
|
+
rmSync(nameDir, { recursive: true, force: true });
|
|
2149
|
+
return count;
|
|
2150
|
+
}
|
|
2151
|
+
function getCacheSize() {
|
|
2152
|
+
const entries = listCachedFormats();
|
|
2153
|
+
const totalBytes = entries.reduce((sum, e) => sum + e.sizeBytes, 0);
|
|
2154
|
+
return { totalBytes, count: entries.length };
|
|
2155
|
+
}
|
|
2087
2156
|
|
|
2088
2157
|
// src/compiler.ts
|
|
2089
2158
|
var CREATOR_NAME3 = "Twee-ts";
|
|
@@ -2386,6 +2455,69 @@ function storyInspect(story) {
|
|
|
2386
2455
|
};
|
|
2387
2456
|
}
|
|
2388
2457
|
|
|
2458
|
+
// src/lint.ts
|
|
2459
|
+
async function lint(options) {
|
|
2460
|
+
const result = await compile({ ...options, outputMode: "json" });
|
|
2461
|
+
const map = storyInspect(result.story);
|
|
2462
|
+
return {
|
|
2463
|
+
diagnostics: result.diagnostics,
|
|
2464
|
+
stats: result.stats,
|
|
2465
|
+
formatName: result.story.twine2.format,
|
|
2466
|
+
formatVersion: result.story.twine2.formatVersion,
|
|
2467
|
+
start: map.start,
|
|
2468
|
+
passages: map.passages.length,
|
|
2469
|
+
storyPassages: map.storyPassages.length,
|
|
2470
|
+
infoPassages: map.infoPassages.length,
|
|
2471
|
+
brokenLinks: map.brokenLinks,
|
|
2472
|
+
deadEnds: map.deadEnds,
|
|
2473
|
+
orphans: map.orphans
|
|
2474
|
+
};
|
|
2475
|
+
}
|
|
2476
|
+
function formatLintReport(result) {
|
|
2477
|
+
const lines = [];
|
|
2478
|
+
const formatStr = result.formatName ? `${result.formatName}${result.formatVersion ? " " + result.formatVersion : ""}` : "unknown";
|
|
2479
|
+
lines.push(`Format: ${formatStr}`);
|
|
2480
|
+
lines.push(
|
|
2481
|
+
`Passages: ${result.passages} total (${result.storyPassages} story, ${result.infoPassages} info), ${result.stats.words.toLocaleString()} words, ${result.stats.files.length} files`
|
|
2482
|
+
);
|
|
2483
|
+
lines.push(`Start: ${result.start}`);
|
|
2484
|
+
if (result.brokenLinks.length > 0) {
|
|
2485
|
+
lines.push("");
|
|
2486
|
+
lines.push(`Broken links (${result.brokenLinks.length}):`);
|
|
2487
|
+
for (const link of result.brokenLinks) {
|
|
2488
|
+
lines.push(` ${link.from} -> ${link.to} (passage "${link.to}" does not exist)`);
|
|
2489
|
+
}
|
|
2490
|
+
}
|
|
2491
|
+
if (result.deadEnds.length > 0) {
|
|
2492
|
+
lines.push("");
|
|
2493
|
+
lines.push(`Dead ends (${result.deadEnds.length}): ${result.deadEnds.join(", ")}`);
|
|
2494
|
+
}
|
|
2495
|
+
if (result.orphans.length > 0) {
|
|
2496
|
+
lines.push("");
|
|
2497
|
+
lines.push(`Orphans (${result.orphans.length}): ${result.orphans.join(", ")}`);
|
|
2498
|
+
}
|
|
2499
|
+
const errors = result.diagnostics.filter((d) => d.level === "error");
|
|
2500
|
+
const warnings = result.diagnostics.filter((d) => d.level === "warning");
|
|
2501
|
+
if (errors.length > 0 || warnings.length > 0) {
|
|
2502
|
+
lines.push("");
|
|
2503
|
+
lines.push(`Diagnostics: ${errors.length} error(s), ${warnings.length} warning(s)`);
|
|
2504
|
+
for (const d of errors) {
|
|
2505
|
+
lines.push(` error: ${d.message}`);
|
|
2506
|
+
}
|
|
2507
|
+
for (const d of warnings) {
|
|
2508
|
+
lines.push(` warning: ${d.message}`);
|
|
2509
|
+
}
|
|
2510
|
+
}
|
|
2511
|
+
lines.push("");
|
|
2512
|
+
const hasErrors = errors.length > 0 || result.brokenLinks.length > 0;
|
|
2513
|
+
if (hasErrors) {
|
|
2514
|
+
lines.push("Lint failed.");
|
|
2515
|
+
} else {
|
|
2516
|
+
lines.push("Lint passed.");
|
|
2517
|
+
}
|
|
2518
|
+
return lines.join("\n");
|
|
2519
|
+
}
|
|
2520
|
+
|
|
2389
2521
|
// src/config.ts
|
|
2390
2522
|
import { readFileSync as readFileSync4, existsSync as existsSync2 } from "fs";
|
|
2391
2523
|
import { join as join5 } from "path";
|
|
@@ -2491,15 +2623,20 @@ export {
|
|
|
2491
2623
|
TweeLexer,
|
|
2492
2624
|
TweeTsError,
|
|
2493
2625
|
applyTagAliases,
|
|
2626
|
+
clearCachedFormats,
|
|
2494
2627
|
compile,
|
|
2495
2628
|
compileToFile,
|
|
2496
2629
|
discoverCachedFormats,
|
|
2497
2630
|
discoverFormats,
|
|
2498
2631
|
fetchAndCacheFormat,
|
|
2499
2632
|
fetchDirectFormat,
|
|
2633
|
+
formatLintReport,
|
|
2500
2634
|
generateIFID,
|
|
2501
2635
|
getCacheDir,
|
|
2636
|
+
getCacheSize,
|
|
2502
2637
|
getFormatSearchDirs,
|
|
2638
|
+
lint,
|
|
2639
|
+
listCachedFormats,
|
|
2503
2640
|
loadConfig,
|
|
2504
2641
|
loadConfigFile,
|
|
2505
2642
|
parseFormatJSON,
|