@anselmdk/feature-spec-md 0.4.0 → 0.5.0-rc.2

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 (39) hide show
  1. package/README.md +59 -78
  2. package/SPEC_FORMAT.md +38 -78
  3. package/dist/cli.js +75 -81
  4. package/dist/cli.js.map +1 -1
  5. package/dist/featureSpecs.d.ts +1 -1
  6. package/dist/featureSpecs.d.ts.map +1 -1
  7. package/dist/featureSpecs.js +57 -10
  8. package/dist/featureSpecs.js.map +1 -1
  9. package/dist/githubActionDiffReport.d.ts +4 -0
  10. package/dist/githubActionDiffReport.d.ts.map +1 -0
  11. package/dist/githubActionDiffReport.js +159 -0
  12. package/dist/githubActionDiffReport.js.map +1 -0
  13. package/dist/githubActionFtp.d.ts +25 -0
  14. package/dist/githubActionFtp.d.ts.map +1 -0
  15. package/dist/githubActionFtp.js +210 -0
  16. package/dist/githubActionFtp.js.map +1 -0
  17. package/dist/githubActionOutput.d.ts +3 -0
  18. package/dist/githubActionOutput.d.ts.map +1 -0
  19. package/dist/githubActionOutput.js +33 -0
  20. package/dist/githubActionOutput.js.map +1 -0
  21. package/dist/githubActionReport.d.ts +2 -1
  22. package/dist/githubActionReport.d.ts.map +1 -1
  23. package/dist/githubActionReport.js +15 -182
  24. package/dist/githubActionReport.js.map +1 -1
  25. package/dist/index.d.ts +2 -2
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +1 -1
  28. package/dist/index.js.map +1 -1
  29. package/dist/reportTemplate.js +37 -33
  30. package/dist/reportTemplate.js.map +1 -1
  31. package/dist/screenshots.d.ts +3 -1
  32. package/dist/screenshots.d.ts.map +1 -1
  33. package/dist/screenshots.js +23 -0
  34. package/dist/screenshots.js.map +1 -1
  35. package/dist/types.d.ts +11 -1
  36. package/dist/types.d.ts.map +1 -1
  37. package/docs/evidence-policy.md +63 -0
  38. package/docs/spec-driven-flow.md +67 -8
  39. package/package.json +1 -1
@@ -0,0 +1,159 @@
1
+ import { createHash } from "node:crypto";
2
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
3
+ import { basename, join, relative } from "node:path";
4
+ import { tmpdir } from "node:os";
5
+ import { html } from "./html.js";
6
+ import { downloadRemoteFile, ftpConfig, listBuildNumbers, listRemoteFilesRecursive, pathJoin, publicUrl, uploadDirectory, } from "./githubActionFtp.js";
7
+ import { writeGithubOutput, writeGithubSummary } from "./githubActionOutput.js";
8
+ export async function publishGithubActionDiffReport(options) {
9
+ const config = ftpConfig(options);
10
+ const prNumber = config.prNumber;
11
+ if (!prNumber)
12
+ throw new Error("Missing required option --pr-number or FEATURE_SPEC_PR_NUMBER.");
13
+ const buildsRoot = pathJoin(config.remoteDir, "build");
14
+ const builds = await listBuildNumbers(buildsRoot, config);
15
+ const currentBuild = config.buildNumber;
16
+ const requestedBaseBuild = optionValue(options, "base-build-number", "FEATURE_SPEC_BASE_BUILD_NUMBER");
17
+ const hasRequestedBaseBuild = Boolean(requestedBaseBuild && builds.includes(requestedBaseBuild));
18
+ const baseBuild = hasRequestedBaseBuild ? requestedBaseBuild : previousBuildNumber(builds, currentBuild);
19
+ const baseLabel = hasRequestedBaseBuild ? "main" : baseBuild ? "previous" : "none";
20
+ const report = baseBuild
21
+ ? await compareBuilds(config, baseBuild, currentBuild, prNumber, baseLabel)
22
+ : emptyReport(config, prNumber, currentBuild);
23
+ const localReportDir = join(tmpdir(), `feature-spec-md-pr-diff-${process.pid}-${prNumber}-${currentBuild}`);
24
+ await mkdir(localReportDir, { recursive: true });
25
+ await writeFile(join(localReportDir, "index.html"), renderDiffReport(report), "utf8");
26
+ const remoteReportDir = pathJoin(config.remoteDir, "pr", prNumber, currentBuild);
27
+ await uploadDirectory(localReportDir, remoteReportDir, config);
28
+ const reportUrl = publicUrl(config.baseUrl, "pr", prNumber, currentBuild, "");
29
+ await writeGithubSummary([
30
+ "## Feature Spec PR Diff",
31
+ "",
32
+ `<p><strong>Diff report:</strong> <a href=\"${html(reportUrl)}\">PR #${html(prNumber)} build ${html(currentBuild)}</a></p>`,
33
+ summaryComparisonSentence(report),
34
+ "",
35
+ ].join("\n"));
36
+ await writeGithubOutput({
37
+ "diff-report-url": reportUrl,
38
+ "diff-comment-body": commentBody(report, reportUrl),
39
+ "base-build": report.baseLabel === "main" ? report.baseBuild ?? "" : "",
40
+ "previous-build": report.baseLabel === "previous" ? report.baseBuild ?? "" : "",
41
+ "current-build": currentBuild,
42
+ });
43
+ console.log(`Feature spec PR diff report uploaded to ${reportUrl}`);
44
+ }
45
+ function emptyReport(config, prNumber, currentBuild) {
46
+ return {
47
+ prNumber,
48
+ currentBuild,
49
+ currentBuildUrl: publicUrl(config.baseUrl, "build", currentBuild, ""),
50
+ baseLabel: "none",
51
+ files: [],
52
+ };
53
+ }
54
+ async function compareBuilds(config, baseBuild, currentBuild, prNumber, baseLabel) {
55
+ const baseRoot = pathJoin(config.remoteDir, "build", baseBuild);
56
+ const currentRoot = pathJoin(config.remoteDir, "build", currentBuild);
57
+ const baseFiles = await listRemoteFilesRecursive(baseRoot, config);
58
+ const currentFiles = await listRemoteFilesRecursive(currentRoot, config);
59
+ const baseRelative = new Set(baseFiles.map((file) => relativeRemotePath(baseRoot, file)));
60
+ const currentRelative = new Set(currentFiles.map((file) => relativeRemotePath(currentRoot, file)));
61
+ const allPaths = Array.from(new Set([...baseRelative, ...currentRelative])).sort();
62
+ const localRoot = join(tmpdir(), `feature-spec-md-build-compare-${process.pid}-${baseBuild}-${currentBuild}`);
63
+ const files = [];
64
+ for (const filePath of allPaths) {
65
+ const baseRemote = baseRelative.has(filePath) ? pathJoin(baseRoot, filePath) : undefined;
66
+ const currentRemote = currentRelative.has(filePath) ? pathJoin(currentRoot, filePath) : undefined;
67
+ const baseLocal = baseRemote ? join(localRoot, "base", filePath) : undefined;
68
+ const currentLocal = currentRemote ? join(localRoot, "current", filePath) : undefined;
69
+ if (baseRemote && baseLocal)
70
+ await downloadRemoteFile(baseRemote, baseLocal, config);
71
+ if (currentRemote && currentLocal)
72
+ await downloadRemoteFile(currentRemote, currentLocal, config);
73
+ const baseInfo = baseLocal ? await fileInfo(baseLocal) : undefined;
74
+ const currentInfo = currentLocal ? await fileInfo(currentLocal) : undefined;
75
+ const status = !baseInfo ? "added" : !currentInfo ? "removed" : baseInfo.hash === currentInfo.hash ? "unchanged" : "changed";
76
+ files.push({
77
+ path: filePath,
78
+ kind: fileKind(filePath),
79
+ status,
80
+ previousHash: baseInfo?.hash,
81
+ currentHash: currentInfo?.hash,
82
+ previousSize: baseInfo?.size,
83
+ currentSize: currentInfo?.size,
84
+ });
85
+ }
86
+ return {
87
+ prNumber,
88
+ baseBuild,
89
+ currentBuild,
90
+ baseBuildUrl: publicUrl(config.baseUrl, "build", baseBuild, ""),
91
+ currentBuildUrl: publicUrl(config.baseUrl, "build", currentBuild, ""),
92
+ baseLabel,
93
+ files,
94
+ };
95
+ }
96
+ function previousBuildNumber(builds, currentBuild) {
97
+ const current = Number(currentBuild);
98
+ return builds.map(Number).filter((build) => Number.isFinite(build) && build < current).sort((a, b) => b - a).at(0)?.toString();
99
+ }
100
+ function optionValue(options, key, envKey) {
101
+ return options[key] ?? process.env[envKey];
102
+ }
103
+ async function fileInfo(filePath) {
104
+ const buffer = await readFile(filePath);
105
+ return { hash: createHash("sha256").update(buffer).digest("hex"), size: buffer.byteLength };
106
+ }
107
+ function relativeRemotePath(root, filePath) {
108
+ return relative(root, filePath).split("\\").join("/");
109
+ }
110
+ function fileKind(filePath) {
111
+ const name = basename(filePath).toLowerCase();
112
+ if (name === "index.html" || name.endsWith(".html") || name.endsWith(".json"))
113
+ return "report";
114
+ if (/\.(png|jpe?g|webp|gif)$/i.test(name))
115
+ return "screenshot";
116
+ return "asset";
117
+ }
118
+ function renderDiffReport(report) {
119
+ const changed = report.files.filter((file) => file.status !== "unchanged");
120
+ const byKind = (kind) => changed.filter((file) => file.kind === kind);
121
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Feature spec PR diff</title><style>body{font-family:system-ui,sans-serif;max-width:1180px;margin:0 auto;padding:40px 24px;color:#1f2328}.panel{border:1px solid #d0d7de;border-radius:8px;padding:20px;margin:18px 0}.badge{border:1px solid #d0d7de;border-radius:999px;padding:2px 8px;font-size:12px}.added{color:#1a7f37}.removed{color:#cf222e}.changed{color:#9a6700}.muted{color:#57606a}table{border-collapse:collapse;width:100%;font-size:14px}th,td{border:1px solid #d0d7de;padding:6px 8px;text-align:left;vertical-align:top}th{background:#f6f8fa}a{color:#0969da}</style></head><body><h1>Feature spec PR diff for PR #${html(report.prNumber)}</h1><p>Generated ${html(new Date().toISOString())}.</p><section class="panel"><h2>Compared builds</h2><p>${report.baseBuild ? `${baseLabel(report)}: <a href="${html(report.baseBuildUrl ?? "")}">build ${html(report.baseBuild)}</a>` : "No base build found."}</p><p>PR: <a href="${html(report.currentBuildUrl)}">build ${html(report.currentBuild)}</a></p><p><span class="badge">${changed.length} changed file${changed.length === 1 ? "" : "s"}</span> <span class="muted">${report.files.length} file${report.files.length === 1 ? "" : "s"} checked</span></p></section>${renderFileSection("Report output", byKind("report"))}${renderFileSection("Screenshots", byKind("screenshot"))}${renderFileSection("Other assets", byKind("asset"))}</body></html>`;
122
+ }
123
+ function renderFileSection(title, files) {
124
+ if (!files.length)
125
+ return `<section class="panel"><h2>${html(title)}</h2><p class="muted">No changes.</p></section>`;
126
+ return `<section class="panel"><h2>${html(title)}</h2><table><thead><tr><th>Status</th><th>File</th><th>Size change</th></tr></thead><tbody>${files.map((file) => `<tr><td class="${file.status}">${html(file.status)}</td><td><code>${html(file.path)}</code></td><td>${html(sizeChange(file))}</td></tr>`).join("")}</tbody></table></section>`;
127
+ }
128
+ function sizeChange(file) {
129
+ if (file.previousSize === undefined)
130
+ return `+${file.currentSize ?? 0} bytes`;
131
+ if (file.currentSize === undefined)
132
+ return `-${file.previousSize} bytes`;
133
+ const diff = file.currentSize - file.previousSize;
134
+ return diff === 0 ? "same size" : `${diff > 0 ? "+" : ""}${diff} bytes`;
135
+ }
136
+ function commentBody(report, reportUrl) {
137
+ const changed = report.files.filter((file) => file.status !== "unchanged");
138
+ const reportChanges = changed.filter((file) => file.kind === "report").length;
139
+ const screenshotChanges = changed.filter((file) => file.kind === "screenshot").length;
140
+ return ["## Feature spec PR diff", "", `[Open the diff report](${reportUrl}) for ${comparisonText(report)}.`, "", `Changed files: **${changed.length}** total, **${reportChanges}** report output, **${screenshotChanges}** screenshots.`].join("\n");
141
+ }
142
+ function comparisonText(report) {
143
+ if (!report.baseBuild)
144
+ return `PR build ${report.currentBuild}`;
145
+ return `${baseLabel(report).toLowerCase()} build ${report.baseBuild} → PR build ${report.currentBuild}`;
146
+ }
147
+ function summaryComparisonSentence(report) {
148
+ if (!report.baseBuild)
149
+ return `<p>No base build was found, so this report establishes the first comparison baseline.</p>`;
150
+ return `<p>Compared ${html(baseLabel(report).toLowerCase())} build <strong>${html(report.baseBuild)}</strong> with PR build <strong>${html(report.currentBuild)}</strong>.</p>`;
151
+ }
152
+ function baseLabel(report) {
153
+ if (report.baseLabel === "main")
154
+ return "Main";
155
+ if (report.baseLabel === "previous")
156
+ return "Previous";
157
+ return "Base";
158
+ }
159
+ //# sourceMappingURL=githubActionDiffReport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"githubActionDiffReport.js","sourceRoot":"","sources":["../src/githubActionDiffReport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ export type GithubActionOptions = Record<string, string | undefined>;
2
+ export type FtpConfig = {
3
+ host: string;
4
+ user: string;
5
+ password: string;
6
+ port?: string;
7
+ secure: boolean;
8
+ remoteDir: string;
9
+ baseUrl: string;
10
+ buildNumber: string;
11
+ prNumber?: string;
12
+ };
13
+ export declare function ftpConfig(options: GithubActionOptions): FtpConfig;
14
+ export declare function uploadDirectory(localDir: string, remoteDir: string, config: FtpConfig): Promise<void>;
15
+ export declare function uploadFile(localFile: string, remotePath: string, config: FtpConfig): Promise<void>;
16
+ export declare function downloadRemoteFile(remotePath: string, localFile: string, config: FtpConfig): Promise<void>;
17
+ export declare function listRemoteDirectory(remoteDir: string, config: FtpConfig): Promise<string>;
18
+ export declare function listRemoteFilesRecursive(remoteDir: string, config: FtpConfig): Promise<string[]>;
19
+ export declare function parseBuildNumbersFromDirectoryListing(listing: string): string[];
20
+ export declare function listBuildNumbers(remoteDir: string, config: FtpConfig): Promise<string[]>;
21
+ export declare function pathJoin(...parts: string[]): string;
22
+ export declare function publicUrl(baseUrl: string, ...parts: string[]): string;
23
+ export declare function trimTrailingSlash(value: string): string;
24
+ export declare function runCurl(args: string[]): Promise<string>;
25
+ //# sourceMappingURL=githubActionFtp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"githubActionFtp.d.ts","sourceRoot":"","sources":["../src/githubActionFtp.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAErE,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,wBAAgB,SAAS,CAAC,OAAO,EAAE,mBAAmB,GAAG,SAAS,CA0BjE;AAED,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,SAAS,iBAclB;AAED,wBAAsB,UAAU,CAC9B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,SAAS,iBAalB;AAED,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,SAAS,iBAalB;AAED,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,mBAe7E;AAED,wBAAsB,wBAAwB,CAC5C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,SAAS,qBAuBlB;AAED,wBAAgB,qCAAqC,CAAC,OAAO,EAAE,MAAM,YAapE;AAED,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,qBAO1E;AAED,wBAAgB,QAAQ,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,UAO1C;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,UAO5D;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,UAE9C;AAED,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,mBAoB3C"}
@@ -0,0 +1,210 @@
1
+ import { spawn } from "node:child_process";
2
+ import { mkdir, readdir } from "node:fs/promises";
3
+ import { dirname, join, relative, sep } from "node:path";
4
+ export function ftpConfig(options) {
5
+ const host = required(options, "ftp-host", "FEATURE_SPEC_FTP_HOST");
6
+ const user = required(options, "ftp-user", "FEATURE_SPEC_FTP_USER");
7
+ const password = required(options, "ftp-password", "FEATURE_SPEC_FTP_PASSWORD");
8
+ const baseUrl = required(options, "base-url", "FEATURE_SPEC_REPORT_BASE_URL");
9
+ const remoteDir = value(options, "ftp-remote-dir", "FEATURE_SPEC_FTP_REMOTE_DIR") ?? "";
10
+ const buildNumber = value(options, "build-number", "FEATURE_SPEC_BUILD_NUMBER") ??
11
+ value(options, "build-number", "GITHUB_RUN_NUMBER") ??
12
+ "local";
13
+ const prNumber = value(options, "pr-number", "FEATURE_SPEC_PR_NUMBER");
14
+ const secure = booleanValue(value(options, "ftp-secure", "FEATURE_SPEC_FTP_SECURE"));
15
+ const port = value(options, "ftp-port", "FEATURE_SPEC_FTP_PORT");
16
+ if (!/^\d+$/.test(buildNumber)) {
17
+ throw new Error(`Build number must be numeric for FTP publishing: ${buildNumber}`);
18
+ }
19
+ if (prNumber !== undefined && !/^\d+$/.test(prNumber)) {
20
+ throw new Error(`Pull request number must be numeric for FTP publishing: ${prNumber}`);
21
+ }
22
+ return { host, user, password, port, secure, remoteDir, baseUrl, buildNumber, prNumber };
23
+ }
24
+ export async function uploadDirectory(localDir, remoteDir, config) {
25
+ const files = await walkFiles(localDir);
26
+ if (!files.length) {
27
+ throw new Error(`Report directory contains no files: ${localDir}`);
28
+ }
29
+ for (const file of files) {
30
+ const remotePath = pathJoin(remoteDir, relative(localDir, file).split(sep).join("/"));
31
+ await uploadFile(file, remotePath, config);
32
+ }
33
+ }
34
+ export async function uploadFile(localFile, remotePath, config) {
35
+ await runCurl([
36
+ "--silent",
37
+ "--show-error",
38
+ "--fail",
39
+ "--ftp-create-dirs",
40
+ "-u",
41
+ `${config.user}:${config.password}`,
42
+ "-T",
43
+ localFile,
44
+ ftpUrl(config, remotePath),
45
+ ]);
46
+ }
47
+ export async function downloadRemoteFile(remotePath, localFile, config) {
48
+ await mkdir(dirname(localFile), { recursive: true });
49
+ await runCurl([
50
+ "--silent",
51
+ "--show-error",
52
+ "--fail",
53
+ "-u",
54
+ `${config.user}:${config.password}`,
55
+ "-o",
56
+ localFile,
57
+ ftpUrl(config, remotePath),
58
+ ]);
59
+ }
60
+ export async function listRemoteDirectory(remoteDir, config) {
61
+ const directoryUrl = ftpUrl(config, asDirectoryPath(remoteDir));
62
+ const commonArgs = [
63
+ "--silent",
64
+ "--show-error",
65
+ "--fail",
66
+ "-u",
67
+ `${config.user}:${config.password}`,
68
+ ];
69
+ try {
70
+ return await runCurl([...commonArgs, "--list-only", directoryUrl]);
71
+ }
72
+ catch {
73
+ return runCurl([...commonArgs, directoryUrl]);
74
+ }
75
+ }
76
+ export async function listRemoteFilesRecursive(remoteDir, config) {
77
+ const files = [];
78
+ await visit(remoteDir);
79
+ return files.sort();
80
+ async function visit(dir) {
81
+ const listing = await listRemoteDirectory(dir, config);
82
+ const entries = parseDirectoryListing(listing);
83
+ for (const entry of entries) {
84
+ if (entry === "." || entry === "..")
85
+ continue;
86
+ const child = pathJoin(dir, entry);
87
+ if (looksLikeFile(entry)) {
88
+ files.push(child);
89
+ continue;
90
+ }
91
+ try {
92
+ await visit(child);
93
+ }
94
+ catch {
95
+ files.push(child);
96
+ }
97
+ }
98
+ }
99
+ }
100
+ export function parseBuildNumbersFromDirectoryListing(listing) {
101
+ return listing
102
+ .split(/\r?\n/)
103
+ .flatMap((line) => {
104
+ const hrefBuilds = Array.from(line.matchAll(/href=["'][^"']*?(\d+)\/?["']/gi), (match) => match[1]);
105
+ const lastToken = line.trim().split(/\s+/).at(-1) ?? "";
106
+ return /^\d+$/.test(lastToken) ? [...hrefBuilds, lastToken] : hrefBuilds;
107
+ })
108
+ .filter((name) => /^\d+$/.test(name));
109
+ }
110
+ export async function listBuildNumbers(remoteDir, config) {
111
+ try {
112
+ const listing = await listRemoteDirectory(remoteDir, config);
113
+ return Array.from(new Set(parseBuildNumbersFromDirectoryListing(listing)));
114
+ }
115
+ catch {
116
+ return [];
117
+ }
118
+ }
119
+ export function pathJoin(...parts) {
120
+ const joined = parts
121
+ .flatMap((part) => part.split("/"))
122
+ .map((part) => part.trim())
123
+ .filter((part) => part && part !== ".")
124
+ .join("/");
125
+ return joined;
126
+ }
127
+ export function publicUrl(baseUrl, ...parts) {
128
+ const path = parts
129
+ .flatMap((part) => part.split("/"))
130
+ .filter(Boolean)
131
+ .map(encodeURIComponent)
132
+ .join("/");
133
+ return path ? `${trimTrailingSlash(baseUrl)}/${path}` : trimTrailingSlash(baseUrl);
134
+ }
135
+ export function trimTrailingSlash(value) {
136
+ return value.replace(/\/+$/, "");
137
+ }
138
+ export async function runCurl(args) {
139
+ return new Promise((resolve, reject) => {
140
+ const child = spawn("curl", args, { stdio: ["ignore", "pipe", "pipe"] });
141
+ let stdout = "";
142
+ let stderr = "";
143
+ child.stdout.on("data", (chunk) => {
144
+ stdout += chunk.toString();
145
+ });
146
+ child.stderr.on("data", (chunk) => {
147
+ stderr += chunk.toString();
148
+ });
149
+ child.on("error", reject);
150
+ child.on("close", (code) => {
151
+ if (code === 0) {
152
+ resolve(stdout);
153
+ return;
154
+ }
155
+ reject(new Error(stderr.trim() || `curl exited with status ${code}`));
156
+ });
157
+ });
158
+ }
159
+ async function walkFiles(dir) {
160
+ const entries = await readdir(dir, { withFileTypes: true });
161
+ const files = await Promise.all(entries.map(async (entry) => {
162
+ const fullPath = join(dir, entry.name);
163
+ if (entry.isDirectory())
164
+ return walkFiles(fullPath);
165
+ if (entry.isFile())
166
+ return [fullPath];
167
+ return [];
168
+ }));
169
+ return files.flat();
170
+ }
171
+ function parseDirectoryListing(listing) {
172
+ return listing
173
+ .split(/\r?\n/)
174
+ .map((line) => line.trim())
175
+ .filter(Boolean)
176
+ .map((line) => line.split(/\s+/).at(-1) ?? "")
177
+ .filter(Boolean);
178
+ }
179
+ function looksLikeFile(name) {
180
+ return /\.[a-z0-9]+$/i.test(name);
181
+ }
182
+ function ftpUrl(config, remotePath) {
183
+ const protocol = config.secure ? "ftps" : "ftp";
184
+ const port = config.port ? `:${config.port}` : "";
185
+ const hasTrailingSlash = remotePath.endsWith("/");
186
+ const encodedPath = remotePath
187
+ .split("/")
188
+ .filter(Boolean)
189
+ .map(encodeURIComponent)
190
+ .join("/");
191
+ const directorySlash = hasTrailingSlash ? "/" : "";
192
+ return `${protocol}://${config.host}${port}/${encodedPath}${directorySlash}`;
193
+ }
194
+ function asDirectoryPath(remotePath) {
195
+ const path = pathJoin(remotePath);
196
+ return path ? `${path}/` : "";
197
+ }
198
+ function required(options, key, envKey) {
199
+ const result = value(options, key, envKey);
200
+ if (!result)
201
+ throw new Error(`Missing required option --${key} or ${envKey}.`);
202
+ return result;
203
+ }
204
+ function value(options, key, envKey) {
205
+ return options[key] ?? process.env[envKey];
206
+ }
207
+ function booleanValue(value) {
208
+ return value === "true" || value === "1" || value === "yes";
209
+ }
210
+ //# sourceMappingURL=githubActionFtp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"githubActionFtp.js","sourceRoot":"","sources":["../src/githubActionFtp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function writeGithubSummary(markdown: string): Promise<void>;
2
+ export declare function writeGithubOutput(values: Record<string, string>): Promise<void>;
3
+ //# sourceMappingURL=githubActionOutput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"githubActionOutput.d.ts","sourceRoot":"","sources":["../src/githubActionOutput.ts"],"names":[],"mappings":"AAGA,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,iBAMxD;AAED,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,iBAMrE"}
@@ -0,0 +1,33 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { dirname } from "node:path";
3
+ export async function writeGithubSummary(markdown) {
4
+ const summaryPath = process.env.GITHUB_STEP_SUMMARY;
5
+ if (!summaryPath)
6
+ return;
7
+ await mkdir(dirname(summaryPath), { recursive: true });
8
+ const existing = await readTextIfExists(summaryPath);
9
+ await writeFile(summaryPath, `${existing}${markdown}`, "utf8");
10
+ }
11
+ export async function writeGithubOutput(values) {
12
+ const outputPath = process.env.GITHUB_OUTPUT;
13
+ if (!outputPath)
14
+ return;
15
+ const lines = Object.entries(values).map(([key, value]) => outputLine(key, value));
16
+ const existing = await readTextIfExists(outputPath);
17
+ await writeFile(outputPath, `${existing}${lines.join("\n")}\n`, "utf8");
18
+ }
19
+ function outputLine(key, value) {
20
+ if (!value.includes("\n"))
21
+ return `${key}=${value}`;
22
+ const delimiter = `feature_spec_md_${Math.random().toString(36).slice(2)}`;
23
+ return `${key}<<${delimiter}\n${value}\n${delimiter}`;
24
+ }
25
+ async function readTextIfExists(filePath) {
26
+ try {
27
+ return await readFile(filePath, "utf8");
28
+ }
29
+ catch {
30
+ return "";
31
+ }
32
+ }
33
+ //# sourceMappingURL=githubActionOutput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"githubActionOutput.js","sourceRoot":"","sources":["../src/githubActionOutput.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,QAAgB;IACvD,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;IACpD,IAAI,CAAC,WAAW;QAAE,OAAO;IACzB,MAAM,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,WAAW,CAAC,CAAC;IACrD,MAAM,SAAS,CAAC,WAAW,EAAE,GAAG,QAAQ,GAAG,QAAQ,EAAE,EAAE,MAAM,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,MAA8B;IACpE,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IAC7C,IAAI,CAAC,UAAU;QAAE,OAAO;IACxB,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;IACnF,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,UAAU,CAAC,CAAC;IACpD,MAAM,SAAS,CAAC,UAAU,EAAE,GAAG,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC1E,CAAC;AAED,SAAS,UAAU,CAAC,GAAW,EAAE,KAAa;IAC5C,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC;IACpD,MAAM,SAAS,GAAG,mBAAmB,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3E,OAAO,GAAG,GAAG,KAAK,SAAS,KAAK,KAAK,KAAK,SAAS,EAAE,CAAC;AACxD,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,QAAgB;IAC9C,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
@@ -1,3 +1,4 @@
1
- export type GithubActionReportOptions = Record<string, string | undefined>;
1
+ import { type GithubActionOptions } from "./githubActionFtp.js";
2
+ export type GithubActionReportOptions = GithubActionOptions;
2
3
  export declare function publishGithubActionReport(options: GithubActionReportOptions): Promise<void>;
3
4
  //# sourceMappingURL=githubActionReport.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"githubActionReport.d.ts","sourceRoot":"","sources":["../src/githubActionReport.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,yBAAyB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAe3E,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,yBAAyB,iBA8CnC"}
1
+ {"version":3,"file":"githubActionReport.d.ts","sourceRoot":"","sources":["../src/githubActionReport.ts"],"names":[],"mappings":"AAGA,OAAO,EAOL,KAAK,mBAAmB,EACzB,MAAM,sBAAsB,CAAC;AAG9B,MAAM,MAAM,yBAAyB,GAAG,mBAAmB,CAAC;AAI5D,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,yBAAyB,iBA8CnC"}