k-skill/lck-analytics/scripts/_lib.js
Jeffrey (Dongkyu) Kim 9fad8ae045 Ship LCK analytics inside k-skill's managed release flow
Adapt jerjangmin's upstream lck-analytics skill/package into a new
workspace and skill pack, wire docs/install/release surfaces, and add
regression fixtures/tests plus script smoke coverage so the feature is
verifiable before publish.

Constraint: Upstream package is not published to npm yet
Constraint: Must preserve attribution to original source and author in shipped docs
Rejected: Keep the upstream lck-results install wording in k-skill | conflicts with repo workspace/package naming
Rejected: Ship only the npm package without the local skill scripts | issue explicitly requested the skill as well
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep Changesets as the only version-bump path for lck-analytics; do not hand-edit versions for release
Tested: node --test packages/lck-analytics/test/index.test.js scripts/skill-docs.test.js
Tested: npm run lint --workspace lck-analytics
Tested: npm test --workspace lck-analytics
Tested: live getLckSummary('2026-04-01', { team: '한화', includeStandings: true })
Tested: node lck-analytics/scripts/sync-oracle.js --csv lck-analytics/samples/oracle-lck-sample.csv --cache .tmp/lck-cache && node lck-analytics/scripts/build-match-report.js --date 2026-04-01 --team 한화 --cache .tmp/lck-cache && node lck-analytics/scripts/analyze-live-game.js --game game-1 --window packages/lck-analytics/test/fixtures/live-window-game-1.json --details packages/lck-analytics/test/fixtures/live-details-game-1.json --cache .tmp/lck-cache
Tested: npm run ci
Tested: npx tsc --noEmit --project /Users/jeffrey/Projects/k-skill/tsconfig.json
Not-tested: Riot live feed behavior for arbitrary future game ids outside the fixture-backed smoke path
2026-04-03 18:05:14 +09:00

103 lines
2.6 KiB
JavaScript
Executable file

const fs = require("node:fs");
const path = require("node:path");
const { pathToFileURL } = require("node:url");
async function loadLckResults() {
const candidates = [];
const packageNames = ["lck-analytics", "lck-results"];
if (process.env.GLOBAL_NPM_ROOT) {
for (const packageName of packageNames) {
candidates.push(path.join(process.env.GLOBAL_NPM_ROOT, packageName, "src", "index.js"));
}
}
try {
const globalRoot = await detectGlobalNpmRoot();
for (const packageName of packageNames) {
candidates.push(path.join(globalRoot, packageName, "src", "index.js"));
}
} catch {
// ignore detection failure and continue to local fallback
}
candidates.push(path.resolve(__dirname, "..", "..", "packages", "lck-analytics", "src", "index.js"));
const entryPath = candidates.find((candidate) => fs.existsSync(candidate));
if (!entryPath) {
throw new Error("Could not find lck-analytics package. Install it globally with `npm install -g lck-analytics` or run from the k-skill repo.");
}
return import(pathToFileURL(entryPath).href);
}
function ensureDir(dirPath) {
fs.mkdirSync(dirPath, { recursive: true });
}
function readJson(filePath, fallback = null) {
if (!fs.existsSync(filePath)) {
return fallback;
}
return JSON.parse(fs.readFileSync(filePath, "utf8"));
}
function writeJson(filePath, value) {
ensureDir(path.dirname(filePath));
fs.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`, "utf8");
}
function readText(filePath, fallback = "") {
if (!fs.existsSync(filePath)) {
return fallback;
}
return fs.readFileSync(filePath, "utf8");
}
function parseArgs(argv) {
const args = {};
for (let index = 0; index < argv.length; index += 1) {
const token = argv[index];
if (!token.startsWith("--")) {
continue;
}
const key = token.slice(2);
const next = argv[index + 1];
if (!next || next.startsWith("--")) {
args[key] = true;
continue;
}
args[key] = next;
index += 1;
}
return args;
}
function formatOutput(value) {
return `${JSON.stringify(value, null, 2)}\n`;
}
function resolveCachePaths(baseDir) {
return {
root: baseDir,
historical: path.join(baseDir, "historical-analysis.json"),
live: path.join(baseDir, "live"),
reports: path.join(baseDir, "reports"),
};
}
async function detectGlobalNpmRoot() {
const { execFileSync } = require("node:child_process");
return execFileSync("npm", ["root", "-g"], { encoding: "utf8" }).trim();
}
module.exports = {
ensureDir,
formatOutput,
loadLckResults,
parseArgs,
readJson,
readText,
resolveCachePaths,
writeJson,
};