@anselmdk/feature-spec-md 0.3.1 → 0.5.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.
@@ -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":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAgBzD,MAAM,UAAU,SAAS,CAAC,OAA4B;IACpD,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,uBAAuB,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,uBAAuB,CAAC,CAAC;IACpE,MAAM,QAAQ,GAAG,QAAQ,CACvB,OAAO,EACP,cAAc,EACd,2BAA2B,CAC5B,CAAC;IACF,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,8BAA8B,CAAC,CAAC;IAC9E,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,EAAE,gBAAgB,EAAE,6BAA6B,CAAC,IAAI,EAAE,CAAC;IACxF,MAAM,WAAW,GACf,KAAK,CAAC,OAAO,EAAE,cAAc,EAAE,2BAA2B,CAAC;QAC3D,KAAK,CAAC,OAAO,EAAE,cAAc,EAAE,mBAAmB,CAAC;QACnD,OAAO,CAAC;IACV,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,EAAE,WAAW,EAAE,wBAAwB,CAAC,CAAC;IACvE,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,YAAY,EAAE,yBAAyB,CAAC,CAAC,CAAC;IACrF,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,EAAE,UAAU,EAAE,uBAAuB,CAAC,CAAC;IAEjE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,oDAAoD,WAAW,EAAE,CAAC,CAAC;IACrF,CAAC;IACD,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,2DAA2D,QAAQ,EAAE,CAAC,CAAC;IACzF,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC;AAC3F,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAAgB,EAChB,SAAiB,EACjB,MAAiB;IAEjB,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,CAAC;IACxC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,uCAAuC,QAAQ,EAAE,CAAC,CAAC;IACrE,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,QAAQ,CACzB,SAAS,EACT,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAC9C,CAAC;QACF,MAAM,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,SAAiB,EACjB,UAAkB,EAClB,MAAiB;IAEjB,MAAM,OAAO,CAAC;QACZ,UAAU;QACV,cAAc;QACd,QAAQ;QACR,mBAAmB;QACnB,IAAI;QACJ,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,QAAQ,EAAE;QACnC,IAAI;QACJ,SAAS;QACT,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC;KAC3B,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,UAAkB,EAClB,SAAiB,EACjB,MAAiB;IAEjB,MAAM,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,MAAM,OAAO,CAAC;QACZ,UAAU;QACV,cAAc;QACd,QAAQ;QACR,IAAI;QACJ,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,QAAQ,EAAE;QACnC,IAAI;QACJ,SAAS;QACT,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC;KAC3B,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,SAAiB,EAAE,MAAiB;IAC5E,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC;IAChE,MAAM,UAAU,GAAG;QACjB,UAAU;QACV,cAAc;QACd,QAAQ;QACR,IAAI;QACJ,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,QAAQ,EAAE;KACpC,CAAC;IAEF,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,CAAC,GAAG,UAAU,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC,CAAC,GAAG,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC;IAChD,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,SAAiB,EACjB,MAAiB;IAEjB,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,KAAK,CAAC,SAAS,CAAC,CAAC;IACvB,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;IAEpB,KAAK,UAAU,KAAK,CAAC,GAAW;QAC9B,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACvD,MAAM,OAAO,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;QAC/C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,IAAI;gBAAE,SAAS;YAC9C,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACnC,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAClB,SAAS;YACX,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,KAAK,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;YAAC,MAAM,CAAC;gBACP,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACpB,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,qCAAqC,CAAC,OAAe;IACnE,OAAO,OAAO;SACX,KAAK,CAAC,OAAO,CAAC;SACd,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QAChB,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAC3B,IAAI,CAAC,QAAQ,CAAC,gCAAgC,CAAC,EAC/C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CACpB,CAAC;QACF,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAExD,OAAO,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;IAC3E,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,SAAiB,EAAE,MAAiB;IACzE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAC7D,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,qCAAqC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,GAAG,KAAe;IACzC,MAAM,MAAM,GAAG,KAAK;SACjB,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;SAClC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI,KAAK,GAAG,CAAC;SACtC,IAAI,CAAC,GAAG,CAAC,CAAC;IACb,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,OAAe,EAAE,GAAG,KAAe;IAC3D,MAAM,IAAI,GAAG,KAAK;SACf,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;SAClC,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC,kBAAkB,CAAC;SACvB,IAAI,CAAC,GAAG,CAAC,CAAC;IACb,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;AACrF,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAc;IAC1C,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC7C,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QACzE,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YAChC,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC7B,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YAChC,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC7B,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1B,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACf,OAAO,CAAC,MAAM,CAAC,CAAC;gBAChB,OAAO;YACT,CAAC;YACD,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,2BAA2B,IAAI,EAAE,CAAC,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,GAAW;IAClC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QAC1B,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,KAAK,CAAC,WAAW,EAAE;YAAE,OAAO,SAAS,CAAC,QAAQ,CAAC,CAAC;QACpD,IAAI,KAAK,CAAC,MAAM,EAAE;YAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QACtC,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC,CACH,CAAC;IACF,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC;AAED,SAAS,qBAAqB,CAAC,OAAe;IAC5C,OAAO,OAAO;SACX,KAAK,CAAC,OAAO,CAAC;SACd,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SAC7C,MAAM,CAAC,OAAO,CAAC,CAAC;AACrB,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,MAAM,CAAC,MAAiB,EAAE,UAAkB;IACnD,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;IAChD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAClD,MAAM,gBAAgB,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAClD,MAAM,WAAW,GAAG,UAAU;SAC3B,KAAK,CAAC,GAAG,CAAC;SACV,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC,kBAAkB,CAAC;SACvB,IAAI,CAAC,GAAG,CAAC,CAAC;IACb,MAAM,cAAc,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACnD,OAAO,GAAG,QAAQ,MAAM,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,WAAW,GAAG,cAAc,EAAE,CAAC;AAC/E,CAAC;AAED,SAAS,eAAe,CAAC,UAAkB;IACzC,MAAM,IAAI,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;IAClC,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;AAChC,CAAC;AAED,SAAS,QAAQ,CAAC,OAA4B,EAAE,GAAW,EAAE,MAAc;IACzE,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,OAAO,MAAM,GAAG,CAAC,CAAC;IAC/E,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,KAAK,CAAC,OAA4B,EAAE,GAAW,EAAE,MAAc;IACtE,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,YAAY,CAAC,KAAyB;IAC7C,OAAO,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,KAAK,CAAC;AAC9D,CAAC"}
@@ -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"}
@@ -1,7 +1,8 @@
1
- import { spawn } from "node:child_process";
2
- import { mkdir, readdir, readFile, writeFile } from "node:fs/promises";
3
- import { dirname, join, relative, sep } from "node:path";
1
+ import { writeFile } from "node:fs/promises";
2
+ import { join } from "node:path";
4
3
  import { tmpdir } from "node:os";
4
+ import { ftpConfig, listBuildNumbers, pathJoin, publicUrl, uploadDirectory, uploadFile, } from "./githubActionFtp.js";
5
+ import { writeGithubOutput, writeGithubSummary } from "./githubActionOutput.js";
5
6
  export async function publishGithubActionReport(options) {
6
7
  const reportDir = value(options, "report-dir", "FEATURE_SPEC_REPORT_DIR") ??
7
8
  "test-results/spec-report";
@@ -15,13 +16,13 @@ export async function publishGithubActionReport(options) {
15
16
  "## Feature Spec Report",
16
17
  "",
17
18
  `<p><strong>Hosted HTML report:</strong> <a href=\"${escapeHtml(reportUrl)}\">${escapeHtml(reportName)}</a></p>`,
18
- `<p><strong>Report index:</strong> <a href=\"${escapeHtml(indexUrl(config.baseUrl))}\">all builds</a></p>`,
19
+ `<p><strong>Build report index:</strong> <a href=\"${escapeHtml(buildIndexUrl(config.baseUrl))}\">all builds</a></p>`,
19
20
  "",
20
21
  ].join("\n"));
21
22
  await writeGithubOutput({
22
23
  "upload-github-artifact": "false",
23
24
  "report-url": reportUrl,
24
- "index-url": indexUrl(config.baseUrl),
25
+ "index-url": buildIndexUrl(config.baseUrl),
25
26
  });
26
27
  console.log(`Feature spec report uploaded to ${reportUrl}`);
27
28
  return;
@@ -39,165 +40,26 @@ export async function publishGithubActionReport(options) {
39
40
  });
40
41
  }
41
42
  async function publishReportToFtp(reportDir, config) {
42
- const buildRemoteDir = pathJoin(config.remoteDir, config.buildNumber);
43
+ const buildsRoot = pathJoin(config.remoteDir, "build");
44
+ const buildRemoteDir = pathJoin(buildsRoot, config.buildNumber);
43
45
  await uploadDirectory(reportDir, buildRemoteDir, config);
44
- const builds = await listBuildNumbers(config.remoteDir, config);
46
+ const builds = await listBuildNumbers(buildsRoot, config);
45
47
  if (!builds.includes(config.buildNumber))
46
48
  builds.push(config.buildNumber);
47
49
  builds.sort((a, b) => Number(b) - Number(a));
48
50
  const localIndex = join(tmpdir(), `feature-spec-md-build-index-${process.pid}.html`);
49
51
  await writeFile(localIndex, renderBuildIndex(config.baseUrl, builds), "utf8");
50
- await uploadFile(localIndex, pathJoin(config.remoteDir, "index.html"), config);
52
+ await uploadFile(localIndex, pathJoin(buildsRoot, "index.html"), config);
51
53
  return buildUrl(config.baseUrl, config.buildNumber);
52
54
  }
53
- async function uploadDirectory(localDir, remoteDir, config) {
54
- const files = await walkFiles(localDir);
55
- if (!files.length) {
56
- throw new Error(`Report directory contains no files: ${localDir}`);
57
- }
58
- for (const file of files) {
59
- const remotePath = pathJoin(remoteDir, relative(localDir, file).split(sep).join("/"));
60
- await uploadFile(file, remotePath, config);
61
- }
62
- }
63
- async function uploadFile(localFile, remotePath, config) {
64
- await runCurl([
65
- "--silent",
66
- "--show-error",
67
- "--fail",
68
- "--ftp-create-dirs",
69
- "-u",
70
- `${config.user}:${config.password}`,
71
- "-T",
72
- localFile,
73
- ftpUrl(config, remotePath),
74
- ]);
75
- }
76
- async function listBuildNumbers(remoteDir, config) {
77
- try {
78
- const listing = await listRemoteDirectory(remoteDir, config);
79
- return Array.from(new Set(parseBuildNumbersFromDirectoryListing(listing)));
80
- }
81
- catch {
82
- return [];
83
- }
84
- }
85
- async function listRemoteDirectory(remoteDir, config) {
86
- const directoryUrl = ftpUrl(config, asDirectoryPath(remoteDir));
87
- const commonArgs = [
88
- "--silent",
89
- "--show-error",
90
- "--fail",
91
- "-u",
92
- `${config.user}:${config.password}`,
93
- ];
94
- try {
95
- return await runCurl([...commonArgs, "--list-only", directoryUrl]);
96
- }
97
- catch {
98
- return runCurl([...commonArgs, directoryUrl]);
99
- }
100
- }
101
- function parseBuildNumbersFromDirectoryListing(listing) {
102
- return listing
103
- .split(/\r?\n/)
104
- .flatMap((line) => {
105
- const hrefBuilds = Array.from(line.matchAll(/href=["'][^"']*?(\d+)\/?["']/gi), (match) => match[1]);
106
- const lastToken = line.trim().split(/\s+/).at(-1) ?? "";
107
- return /^\d+$/.test(lastToken) ? [...hrefBuilds, lastToken] : hrefBuilds;
108
- })
109
- .filter((name) => /^\d+$/.test(name));
110
- }
111
- async function runCurl(args) {
112
- return new Promise((resolve, reject) => {
113
- const child = spawn("curl", args, { stdio: ["ignore", "pipe", "pipe"] });
114
- let stdout = "";
115
- let stderr = "";
116
- child.stdout.on("data", (chunk) => {
117
- stdout += chunk.toString();
118
- });
119
- child.stderr.on("data", (chunk) => {
120
- stderr += chunk.toString();
121
- });
122
- child.on("error", reject);
123
- child.on("close", (code) => {
124
- if (code === 0) {
125
- resolve(stdout);
126
- return;
127
- }
128
- reject(new Error(stderr.trim() || `curl exited with status ${code}`));
129
- });
130
- });
131
- }
132
- async function walkFiles(dir) {
133
- const entries = await readdir(dir, { withFileTypes: true });
134
- const files = await Promise.all(entries.map(async (entry) => {
135
- const fullPath = join(dir, entry.name);
136
- if (entry.isDirectory())
137
- return walkFiles(fullPath);
138
- if (entry.isFile())
139
- return [fullPath];
140
- return [];
141
- }));
142
- return files.flat();
143
- }
144
- function ftpConfig(options) {
145
- const host = required(options, "ftp-host", "FEATURE_SPEC_FTP_HOST");
146
- const user = required(options, "ftp-user", "FEATURE_SPEC_FTP_USER");
147
- const password = required(options, "ftp-password", "FEATURE_SPEC_FTP_PASSWORD");
148
- const baseUrl = required(options, "base-url", "FEATURE_SPEC_REPORT_BASE_URL");
149
- const remoteDir = value(options, "ftp-remote-dir", "FEATURE_SPEC_FTP_REMOTE_DIR") ?? "";
150
- const buildNumber = value(options, "build-number", "GITHUB_RUN_NUMBER") ??
151
- value(options, "build-number", "FEATURE_SPEC_BUILD_NUMBER") ??
152
- "local";
153
- const secure = booleanValue(value(options, "ftp-secure", "FEATURE_SPEC_FTP_SECURE"));
154
- const port = value(options, "ftp-port", "FEATURE_SPEC_FTP_PORT");
155
- if (!/^\d+$/.test(buildNumber)) {
156
- throw new Error(`Build number must be numeric for FTP publishing: ${buildNumber}`);
157
- }
158
- return { host, user, password, port, secure, remoteDir, baseUrl, buildNumber };
159
- }
160
55
  function publishMode(value) {
161
56
  if (value === "ftp" || value === "artifact")
162
57
  return value;
163
58
  throw new Error(`Unknown report publish mode: ${value}`);
164
59
  }
165
- function required(options, key, envKey) {
166
- const result = value(options, key, envKey);
167
- if (!result)
168
- throw new Error(`Missing required option --${key} or ${envKey}.`);
169
- return result;
170
- }
171
60
  function value(options, key, envKey) {
172
61
  return options[key] ?? process.env[envKey];
173
62
  }
174
- function booleanValue(value) {
175
- return value === "true" || value === "1" || value === "yes";
176
- }
177
- function ftpUrl(config, remotePath) {
178
- const protocol = config.secure ? "ftps" : "ftp";
179
- const port = config.port ? `:${config.port}` : "";
180
- const hasTrailingSlash = remotePath.endsWith("/");
181
- const encodedPath = remotePath
182
- .split("/")
183
- .filter(Boolean)
184
- .map(encodeURIComponent)
185
- .join("/");
186
- const directorySlash = hasTrailingSlash ? "/" : "";
187
- return `${protocol}://${config.host}${port}/${encodedPath}${directorySlash}`;
188
- }
189
- function asDirectoryPath(remotePath) {
190
- const path = pathJoin(remotePath);
191
- return path ? `${path}/` : "";
192
- }
193
- function pathJoin(...parts) {
194
- const joined = parts
195
- .flatMap((part) => part.split("/"))
196
- .map((part) => part.trim())
197
- .filter((part) => part && part !== ".")
198
- .join("/");
199
- return joined;
200
- }
201
63
  function renderBuildIndex(baseUrl, builds) {
202
64
  const generatedAt = new Date().toISOString();
203
65
  const rows = builds
@@ -208,14 +70,14 @@ function renderBuildIndex(baseUrl, builds) {
208
70
  <head>
209
71
  <meta charset=\"utf-8\">
210
72
  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">
211
- <title>Feature spec reports</title>
73
+ <title>Feature spec build reports</title>
212
74
  <style>
213
75
  body { font-family: system-ui, sans-serif; max-width: 48rem; margin: 3rem auto; padding: 0 1rem; line-height: 1.5; }
214
76
  li { margin: 0.35rem 0; }
215
77
  </style>
216
78
  </head>
217
79
  <body>
218
- <h1>Feature spec reports</h1>
80
+ <h1>Feature spec build reports</h1>
219
81
  <p>Generated ${escapeHtml(generatedAt)}.</p>
220
82
  <ol>
221
83
  ${rows}
@@ -225,13 +87,10 @@ ${rows}
225
87
  `;
226
88
  }
227
89
  function buildUrl(baseUrl, build) {
228
- return `${trimTrailingSlash(baseUrl)}/${encodeURIComponent(build)}/`;
229
- }
230
- function indexUrl(baseUrl) {
231
- return `${trimTrailingSlash(baseUrl)}/`;
90
+ return publicUrl(baseUrl, "build", build, "");
232
91
  }
233
- function trimTrailingSlash(value) {
234
- return value.replace(/\/+$/, "");
92
+ function buildIndexUrl(baseUrl) {
93
+ return publicUrl(baseUrl, "build", "");
235
94
  }
236
95
  function escapeHtml(value) {
237
96
  return value
@@ -240,30 +99,4 @@ function escapeHtml(value) {
240
99
  .replace(/>/g, "&gt;")
241
100
  .replace(/\"/g, "&quot;");
242
101
  }
243
- async function writeGithubSummary(markdown) {
244
- const summaryPath = process.env.GITHUB_STEP_SUMMARY;
245
- if (!summaryPath)
246
- return;
247
- await mkdir(dirname(summaryPath), { recursive: true });
248
- const existing = await readTextIfExists(summaryPath);
249
- await writeFile(summaryPath, `${existing}${markdown}`, "utf8");
250
- }
251
- async function writeGithubOutput(values) {
252
- const outputPath = process.env.GITHUB_OUTPUT;
253
- if (!outputPath)
254
- return;
255
- const lines = Object.entries(values)
256
- .map(([key, value]) => `${key}=${value}`)
257
- .join("\n");
258
- const existing = await readTextIfExists(outputPath);
259
- await writeFile(outputPath, `${existing}${lines}\n`, "utf8");
260
- }
261
- async function readTextIfExists(filePath) {
262
- try {
263
- return await readFile(filePath, "utf8");
264
- }
265
- catch {
266
- return "";
267
- }
268
- }
269
102
  //# sourceMappingURL=githubActionReport.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"githubActionReport.js","sourceRoot":"","sources":["../src/githubActionReport.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"githubActionReport.js","sourceRoot":"","sources":["../src/githubActionReport.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,9 @@ export type ReportOptions = {
8
8
  validationIssues?: ValidationIssue[];
9
9
  title?: string;
10
10
  generatedAt?: string;
11
+ githubBaseUrl?: string;
12
+ githubRef?: string;
13
+ repositoryUrl?: string;
11
14
  };
12
15
  /** Render a complete self-contained feature spec report as HTML. */
13
16
  export declare function renderHtmlReport(specs: FeatureSpec[], options?: ReportOptions): string;
@@ -1 +1 @@
1
- {"version":3,"file":"reportTemplate.d.ts","sourceRoot":"","sources":["../src/reportTemplate.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAEV,eAAe,EACf,UAAU,EACV,WAAW,EAEX,SAAS,EACT,cAAc,EACd,SAAS,EACT,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,cAAc,EAAE,CAAC;IAC/B,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAOF,oEAAoE;AACpE,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,WAAW,EAAE,EACpB,OAAO,GAAE,aAAkB,UA+D5B"}
1
+ {"version":3,"file":"reportTemplate.d.ts","sourceRoot":"","sources":["../src/reportTemplate.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAEV,eAAe,EACf,UAAU,EACV,WAAW,EAEX,SAAS,EACT,cAAc,EACd,SAAS,EAET,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,cAAc,EAAE,CAAC;IAC/B,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAYF,oEAAoE;AACpE,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,WAAW,EAAE,EACpB,OAAO,GAAE,aAAkB,UAuE5B"}