@wasao/kagemusha 0.1.1 → 0.3.4

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 (155) hide show
  1. package/README.md +168 -79
  2. package/dist/commands/add.d.ts +6 -0
  3. package/dist/commands/add.d.ts.map +1 -0
  4. package/dist/commands/add.js +26 -0
  5. package/dist/commands/add.js.map +1 -0
  6. package/dist/commands/capture.d.ts +3 -2
  7. package/dist/commands/capture.d.ts.map +1 -1
  8. package/dist/commands/capture.js +256 -20
  9. package/dist/commands/capture.js.map +1 -1
  10. package/dist/commands/discover.d.ts +2 -0
  11. package/dist/commands/discover.d.ts.map +1 -0
  12. package/dist/commands/discover.js +62 -0
  13. package/dist/commands/discover.js.map +1 -0
  14. package/dist/commands/edit.d.ts +1 -1
  15. package/dist/commands/edit.d.ts.map +1 -1
  16. package/dist/commands/edit.js +82 -26
  17. package/dist/commands/edit.js.map +1 -1
  18. package/dist/commands/init.d.ts +1 -1
  19. package/dist/commands/init.d.ts.map +1 -1
  20. package/dist/commands/init.js +240 -105
  21. package/dist/commands/init.js.map +1 -1
  22. package/dist/commands/list.d.ts +2 -0
  23. package/dist/commands/list.d.ts.map +1 -0
  24. package/dist/commands/list.js +33 -0
  25. package/dist/commands/list.js.map +1 -0
  26. package/dist/commands/login.d.ts +6 -0
  27. package/dist/commands/login.d.ts.map +1 -0
  28. package/dist/commands/login.js +131 -0
  29. package/dist/commands/login.js.map +1 -0
  30. package/dist/commands/validate.js +1 -1
  31. package/dist/commands/validate.js.map +1 -1
  32. package/dist/editor/inject-script/annotations.d.ts +11 -0
  33. package/dist/editor/inject-script/annotations.d.ts.map +1 -0
  34. package/dist/editor/inject-script/annotations.js +409 -0
  35. package/dist/editor/inject-script/annotations.js.map +1 -0
  36. package/dist/editor/inject-script/bridge.d.ts +13 -0
  37. package/dist/editor/inject-script/bridge.d.ts.map +1 -0
  38. package/dist/editor/inject-script/bridge.js +33 -0
  39. package/dist/editor/inject-script/bridge.js.map +1 -0
  40. package/dist/editor/inject-script/crop.d.ts +9 -0
  41. package/dist/editor/inject-script/crop.d.ts.map +1 -0
  42. package/dist/editor/inject-script/crop.js +236 -0
  43. package/dist/editor/inject-script/crop.js.map +1 -0
  44. package/dist/editor/inject-script/dom.d.ts +7 -0
  45. package/dist/editor/inject-script/dom.d.ts.map +1 -0
  46. package/dist/editor/inject-script/dom.js +32 -0
  47. package/dist/editor/inject-script/dom.js.map +1 -0
  48. package/dist/editor/inject-script/index.d.ts +2 -0
  49. package/dist/editor/inject-script/index.d.ts.map +1 -0
  50. package/dist/editor/inject-script/index.js +56 -0
  51. package/dist/editor/inject-script/index.js.map +1 -0
  52. package/dist/editor/inject-script/record.d.ts +5 -0
  53. package/dist/editor/inject-script/record.d.ts.map +1 -0
  54. package/dist/editor/inject-script/record.js +398 -0
  55. package/dist/editor/inject-script/record.js.map +1 -0
  56. package/dist/editor/inject-script/selector.d.ts +6 -0
  57. package/dist/editor/inject-script/selector.d.ts.map +1 -0
  58. package/dist/editor/inject-script/selector.js +112 -0
  59. package/dist/editor/inject-script/selector.js.map +1 -0
  60. package/dist/editor/inject-script/state.d.ts +27 -0
  61. package/dist/editor/inject-script/state.d.ts.map +1 -0
  62. package/dist/editor/inject-script/state.js +26 -0
  63. package/dist/editor/inject-script/state.js.map +1 -0
  64. package/dist/editor/inject-script/svg.d.ts +7 -0
  65. package/dist/editor/inject-script/svg.d.ts.map +1 -0
  66. package/dist/editor/inject-script/svg.js +39 -0
  67. package/dist/editor/inject-script/svg.js.map +1 -0
  68. package/dist/editor/inject-script/toolbar.d.ts +14 -0
  69. package/dist/editor/inject-script/toolbar.d.ts.map +1 -0
  70. package/dist/editor/inject-script/toolbar.js +240 -0
  71. package/dist/editor/inject-script/toolbar.js.map +1 -0
  72. package/dist/editor/inject-script/types.d.ts +102 -0
  73. package/dist/editor/inject-script/types.d.ts.map +1 -0
  74. package/dist/editor/inject-script/types.js +5 -0
  75. package/dist/editor/inject-script/types.js.map +1 -0
  76. package/dist/editor/inject-script.js +1276 -353
  77. package/dist/index.js +34 -16
  78. package/dist/index.js.map +1 -1
  79. package/dist/lib/annotate.d.ts +2 -2
  80. package/dist/lib/annotate.d.ts.map +1 -1
  81. package/dist/lib/annotate.js +35 -43
  82. package/dist/lib/annotate.js.map +1 -1
  83. package/dist/lib/auth.d.ts +18 -0
  84. package/dist/lib/auth.d.ts.map +1 -0
  85. package/dist/lib/auth.js +45 -0
  86. package/dist/lib/auth.js.map +1 -0
  87. package/dist/lib/aws-error.d.ts +7 -0
  88. package/dist/lib/aws-error.d.ts.map +1 -0
  89. package/dist/lib/aws-error.js +74 -0
  90. package/dist/lib/aws-error.js.map +1 -0
  91. package/dist/lib/canonical.d.ts +54 -0
  92. package/dist/lib/canonical.d.ts.map +1 -0
  93. package/dist/lib/canonical.js +152 -0
  94. package/dist/lib/canonical.js.map +1 -0
  95. package/dist/lib/config.d.ts +2 -0
  96. package/dist/lib/config.d.ts.map +1 -1
  97. package/dist/lib/config.js +23 -13
  98. package/dist/lib/config.js.map +1 -1
  99. package/dist/lib/crawl.d.ts +1 -1
  100. package/dist/lib/crawl.d.ts.map +1 -1
  101. package/dist/lib/crawl.js +213 -20
  102. package/dist/lib/crawl.js.map +1 -1
  103. package/dist/lib/definition.d.ts +2 -0
  104. package/dist/lib/definition.d.ts.map +1 -0
  105. package/dist/lib/definition.js +6 -0
  106. package/dist/lib/definition.js.map +1 -0
  107. package/dist/lib/diff.d.ts +71 -0
  108. package/dist/lib/diff.d.ts.map +1 -0
  109. package/dist/lib/diff.js +40 -0
  110. package/dist/lib/diff.js.map +1 -0
  111. package/dist/lib/login-error.d.ts +10 -0
  112. package/dist/lib/login-error.d.ts.map +1 -0
  113. package/dist/lib/login-error.js +13 -0
  114. package/dist/lib/login-error.js.map +1 -0
  115. package/dist/lib/page-ready.d.ts +18 -0
  116. package/dist/lib/page-ready.d.ts.map +1 -0
  117. package/dist/lib/page-ready.js +19 -0
  118. package/dist/lib/page-ready.js.map +1 -0
  119. package/dist/lib/screenshot.d.ts +11 -2
  120. package/dist/lib/screenshot.d.ts.map +1 -1
  121. package/dist/lib/screenshot.js +73 -64
  122. package/dist/lib/screenshot.js.map +1 -1
  123. package/dist/lib/staging.d.ts +7 -0
  124. package/dist/lib/staging.d.ts.map +1 -0
  125. package/dist/lib/staging.js +21 -0
  126. package/dist/lib/staging.js.map +1 -0
  127. package/dist/types.d.ts +10 -23
  128. package/dist/types.d.ts.map +1 -1
  129. package/package.json +20 -3
  130. package/dist/commands/preview.d.ts +0 -6
  131. package/dist/commands/preview.d.ts.map +0 -1
  132. package/dist/commands/preview.js +0 -33
  133. package/dist/commands/preview.js.map +0 -1
  134. package/dist/commands/run.d.ts +0 -6
  135. package/dist/commands/run.d.ts.map +0 -1
  136. package/dist/commands/run.js +0 -39
  137. package/dist/commands/run.js.map +0 -1
  138. package/dist/editor/editor/editor.html +0 -313
  139. package/dist/editor/editor/inject.ts +0 -385
  140. package/dist/editor/editor.html +0 -338
  141. package/dist/editor/inject-script.cjs +0 -398
  142. package/dist/editor/inject-script.cjs.map +0 -1
  143. package/dist/editor/inject-script.d.cts +0 -2
  144. package/dist/editor/inject-script.d.cts.map +0 -1
  145. package/dist/editor/inject-script.d.ts +0 -2
  146. package/dist/editor/inject-script.d.ts.map +0 -1
  147. package/dist/editor/inject-script.js.map +0 -1
  148. package/dist/editor/inject.d.ts +0 -2
  149. package/dist/editor/inject.d.ts.map +0 -1
  150. package/dist/editor/inject.js +0 -385
  151. package/dist/editor/inject.js.map +0 -1
  152. package/dist/lib/upload.d.ts +0 -9
  153. package/dist/lib/upload.d.ts.map +0 -1
  154. package/dist/lib/upload.js +0 -43
  155. package/dist/lib/upload.js.map +0 -1
@@ -0,0 +1,152 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { CopyObjectCommand, GetObjectCommand, NoSuchKey, PutObjectCommand, S3Client, } from "@aws-sdk/client-s3";
4
+ const DEFAULT_OUTPUT_DIR = "screenshots";
5
+ export const getOutputDir = (config, projectRoot) => {
6
+ const configured = config.publish?.outputDir ?? DEFAULT_OUTPUT_DIR;
7
+ return path.isAbsolute(configured)
8
+ ? configured
9
+ : path.join(projectRoot, configured);
10
+ };
11
+ export const getCanonicalPath = (config, projectRoot, id) => path.join(getOutputDir(config, projectRoot), `${id}.png`);
12
+ // Extract AWS region from a virtual-hosted–style S3 URL or s3.<region>.amazonaws.com endpoint.
13
+ // Returns undefined for legacy global URLs (s3.amazonaws.com) or custom CDN domains.
14
+ const extractRegionFromCdnBase = (cdnBaseUrl) => {
15
+ if (!cdnBaseUrl)
16
+ return undefined;
17
+ const m = cdnBaseUrl.match(/\.s3[.-]([a-z0-9-]+)\.amazonaws\.com/i);
18
+ return m?.[1];
19
+ };
20
+ /**
21
+ * S3-backed canonical store.
22
+ * Local mode has no remote — outputDir itself is the source of truth.
23
+ */
24
+ export class S3Canonical {
25
+ bucket;
26
+ cdnBaseUrl;
27
+ client;
28
+ constructor(bucket, cdnBaseUrl) {
29
+ this.bucket = bucket;
30
+ this.cdnBaseUrl = cdnBaseUrl;
31
+ const region = extractRegionFromCdnBase(cdnBaseUrl);
32
+ this.client = new S3Client(region ? { region } : {});
33
+ }
34
+ latestKey(id) {
35
+ return `${id}/latest.png`;
36
+ }
37
+ previousKey(id) {
38
+ return `${id}/previous.png`;
39
+ }
40
+ historyKey(id, timestamp) {
41
+ // Group history snapshots under a sub-prefix so the bucket list
42
+ // shows `latest.png` / `previous.png` cleanly without historical
43
+ // snapshots interleaved alphabetically.
44
+ return `${id}/history/${timestamp}.png`;
45
+ }
46
+ urlFor(key) {
47
+ const base = this.cdnBaseUrl ?? `s3://${this.bucket}`;
48
+ return `${base.replace(/\/$/, "")}/${key}`;
49
+ }
50
+ /** Download canonical for `id` to `localPath`. Returns "not-found" if absent. */
51
+ async fetch(id, localPath) {
52
+ try {
53
+ const res = await this.client.send(new GetObjectCommand({ Bucket: this.bucket, Key: this.latestKey(id) }));
54
+ const bytes = await res.Body?.transformToByteArray();
55
+ if (!bytes)
56
+ return "not-found";
57
+ fs.mkdirSync(path.dirname(localPath), { recursive: true });
58
+ fs.writeFileSync(localPath, bytes);
59
+ return "ok";
60
+ }
61
+ catch (e) {
62
+ if (isNoSuchKey(e))
63
+ return "not-found";
64
+ throw e;
65
+ }
66
+ }
67
+ /**
68
+ * Upload `localPath` as the canonical for `id`.
69
+ *
70
+ * Side effects on S3 for a single push:
71
+ * 1. Copy existing latest.png → previous.png (no-op if missing)
72
+ * 2. Upload localPath → latest.png
73
+ * 3. Upload localPath → history/<timestamp>.png
74
+ *
75
+ * Step 1 must complete first (otherwise the soon-to-be-overwritten latest
76
+ * would be replaced before the snapshot is taken). Steps 2-3 target
77
+ * different keys and run in parallel.
78
+ *
79
+ * Returns URLs (`before` / `after`) so callers can surface them in
80
+ * `reports/summary.json` (= public API). Consumers compare before vs after
81
+ * visually; kagemusha intentionally does not publish a pre-generated diff
82
+ * image (= pixelmatch's red overlay is alarming and adds little vs the
83
+ * raw pair).
84
+ */
85
+ async push(id, localPath) {
86
+ const body = fs.readFileSync(localPath);
87
+ // 1. Snapshot the soon-to-be-overwritten latest as `previous`.
88
+ // Uses CopyObject (= S3-side copy, no local round-trip). First push for
89
+ // this id has no latest yet — we swallow NoSuchKey and report `before:
90
+ // undefined` to the caller.
91
+ let beforeUrl;
92
+ try {
93
+ await this.client.send(new CopyObjectCommand({
94
+ Bucket: this.bucket,
95
+ CopySource: `${this.bucket}/${this.latestKey(id)}`,
96
+ Key: this.previousKey(id),
97
+ MetadataDirective: "REPLACE",
98
+ ContentType: "image/png",
99
+ CacheControl: "no-cache",
100
+ }));
101
+ beforeUrl = this.urlFor(this.previousKey(id));
102
+ }
103
+ catch (e) {
104
+ if (!isNoSuchKey(e))
105
+ throw e;
106
+ // first push for this id — no previous yet, leave beforeUrl undefined
107
+ }
108
+ // 2-3. Independent uploads — run in parallel (= ~2x faster than serial).
109
+ const timestamp = new Date().toISOString().replaceAll(":", "-");
110
+ await Promise.all([
111
+ // 2. latest
112
+ this.client.send(new PutObjectCommand({
113
+ Bucket: this.bucket,
114
+ Key: this.latestKey(id),
115
+ Body: body,
116
+ ContentType: "image/png",
117
+ CacheControl: "no-cache",
118
+ })),
119
+ // 3. history snapshot
120
+ this.client.send(new PutObjectCommand({
121
+ Bucket: this.bucket,
122
+ Key: this.historyKey(id, timestamp),
123
+ Body: body,
124
+ ContentType: "image/png",
125
+ })),
126
+ ]);
127
+ return {
128
+ after: this.urlFor(this.latestKey(id)),
129
+ before: beforeUrl,
130
+ };
131
+ }
132
+ label() {
133
+ return this.cdnBaseUrl ?? `s3://${this.bucket}`;
134
+ }
135
+ }
136
+ const isNoSuchKey = (e) => {
137
+ if (e instanceof NoSuchKey)
138
+ return true;
139
+ const name = e?.name;
140
+ const code = e?.Code;
141
+ return name === "NoSuchKey" || code === "NoSuchKey";
142
+ };
143
+ export const createS3Canonical = (config) => {
144
+ const publish = config.publish;
145
+ if (publish?.destination !== "s3")
146
+ return null;
147
+ if (!publish.cdnBucket) {
148
+ throw new Error("publish.cdnBucket is required for s3 destination");
149
+ }
150
+ return new S3Canonical(publish.cdnBucket, publish.cdnBaseUrl);
151
+ };
152
+ //# sourceMappingURL=canonical.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical.js","sourceRoot":"","sources":["../../src/lib/canonical.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,9 @@
1
1
  import type { KagemushaConfig, Route, ScreenshotDefinition } from "../types.js";
2
2
  export declare function findProjectRoot(startDir?: string): string;
3
3
  export declare function loadConfig(projectRoot?: string): KagemushaConfig;
4
+ export declare function getDefinitionsPath(projectRoot?: string): string;
4
5
  export declare function loadDefinitions(projectRoot?: string): ScreenshotDefinition[];
6
+ export declare function saveDefinitions(definitions: ScreenshotDefinition[], projectRoot?: string): void;
5
7
  export declare function loadRouting(projectRoot?: string): Route[];
6
8
  export declare function loadDefinitionById(id: string, projectRoot?: string): ScreenshotDefinition | undefined;
7
9
  export declare function validateConfig(config: KagemushaConfig): string[];
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAMhF,wBAAgB,eAAe,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,CAWxE;AAED,wBAAgB,UAAU,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,eAAe,CAYhE;AAED,wBAAgB,eAAe,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,oBAAoB,EAAE,CAa5E;AAED,wBAAgB,WAAW,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,KAAK,EAAE,CAWzD;AAED,wBAAgB,kBAAkB,CACjC,EAAE,EAAE,MAAM,EACV,WAAW,CAAC,EAAE,MAAM,GAClB,oBAAoB,GAAG,SAAS,CAGlC;AAkBD,wBAAgB,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,EAAE,CAWhE;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,oBAAoB,GAAG,MAAM,EAAE,CActE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAMhF,wBAAgB,eAAe,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,CAWxE;AAED,wBAAgB,UAAU,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,eAAe,CAYhE;AAED,wBAAgB,kBAAkB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAG/D;AAED,wBAAgB,eAAe,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,oBAAoB,EAAE,CAS5E;AAED,wBAAgB,eAAe,CAC9B,WAAW,EAAE,oBAAoB,EAAE,EACnC,WAAW,CAAC,EAAE,MAAM,GAClB,IAAI,CAIN;AAED,wBAAgB,WAAW,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,KAAK,EAAE,CAWzD;AAED,wBAAgB,kBAAkB,CACjC,EAAE,EAAE,MAAM,EACV,WAAW,CAAC,EAAE,MAAM,GAClB,oBAAoB,GAAG,SAAS,CAGlC;AA0BD,wBAAgB,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,EAAE,CAWhE;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,oBAAoB,GAAG,MAAM,EAAE,CAWtE"}
@@ -2,7 +2,7 @@ import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { parse as parseYaml } from "yaml";
4
4
  const CONFIG_FILENAME = "kagemusha.config.yaml";
5
- const DEFINITIONS_DIR = ".kagemusha/definitions";
5
+ const DEFINITIONS_FILE = ".kagemusha/definitions.json";
6
6
  const ROUTING_FILENAME = ".kagemusha/routing.yaml";
7
7
  export function findProjectRoot(startDir = process.cwd()) {
8
8
  let dir = startDir;
@@ -25,17 +25,22 @@ export function loadConfig(projectRoot) {
25
25
  resolveEnvVars(config);
26
26
  return config;
27
27
  }
28
- export function loadDefinitions(projectRoot) {
28
+ export function getDefinitionsPath(projectRoot) {
29
29
  const root = projectRoot ?? findProjectRoot();
30
- const defsDir = path.join(root, DEFINITIONS_DIR);
31
- if (!fs.existsSync(defsDir)) {
30
+ return path.join(root, DEFINITIONS_FILE);
31
+ }
32
+ export function loadDefinitions(projectRoot) {
33
+ const defsPath = getDefinitionsPath(projectRoot);
34
+ if (!fs.existsSync(defsPath)) {
32
35
  return [];
33
36
  }
34
- const files = fs.readdirSync(defsDir).filter((f) => f.endsWith(".json"));
35
- return files.map((file) => {
36
- const content = fs.readFileSync(path.join(defsDir, file), "utf-8");
37
- return JSON.parse(content);
38
- });
37
+ const content = fs.readFileSync(defsPath, "utf-8");
38
+ return JSON.parse(content);
39
+ }
40
+ export function saveDefinitions(definitions, projectRoot) {
41
+ const defsPath = getDefinitionsPath(projectRoot);
42
+ fs.mkdirSync(path.dirname(defsPath), { recursive: true });
43
+ fs.writeFileSync(defsPath, `${JSON.stringify(definitions, null, 2)}\n`);
39
44
  }
40
45
  export function loadRouting(projectRoot) {
41
46
  const root = projectRoot ?? findProjectRoot();
@@ -57,7 +62,13 @@ function resolveEnvVars(obj) {
57
62
  if (typeof obj === "object") {
58
63
  for (const [key, value] of Object.entries(obj)) {
59
64
  if (typeof value === "string") {
60
- obj[key] = value.replace(/\$\{(\w+)\}/g, (_, envVar) => process.env[envVar] ?? "");
65
+ obj[key] = value.replace(/\$\{(\w+)\}/g, (_, envVar) => {
66
+ const v = process.env[envVar];
67
+ if (v === undefined) {
68
+ throw new Error(`Environment variable \${${envVar}} is referenced in kagemusha.config.yaml but not set.`);
69
+ }
70
+ return v;
71
+ });
61
72
  }
62
73
  else if (typeof value === "object") {
63
74
  resolveEnvVars(value);
@@ -83,9 +94,8 @@ export function validateDefinition(def) {
83
94
  errors.push("url is required");
84
95
  if (!def.capture)
85
96
  errors.push("capture is required");
86
- if (def.capture &&
87
- !["fullPage", "selector", "crop"].includes(def.capture.mode)) {
88
- errors.push(`capture.mode must be "fullPage", "selector", or "crop"`);
97
+ if (def.capture && !["fullPage", "crop"].includes(def.capture.mode)) {
98
+ errors.push(`capture.mode must be "fullPage" or "crop"`);
89
99
  }
90
100
  return errors;
91
101
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
@@ -2,5 +2,5 @@ export interface DiscoveredPage {
2
2
  path: string;
3
3
  title: string;
4
4
  }
5
- export declare function discoverPages(baseUrl: string, maxDepth?: number, maxPages?: number): Promise<DiscoveredPage[]>;
5
+ export declare const discoverPages: (baseUrl: string, projectRoot?: string, maxDepth?: number, maxPages?: number) => Promise<DiscoveredPage[]>;
6
6
  //# sourceMappingURL=crawl.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"crawl.d.ts","sourceRoot":"","sources":["../../src/lib/crawl.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,aAAa,CAClC,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,MAAU,EACpB,QAAQ,GAAE,MAAW,GACnB,OAAO,CAAC,cAAc,EAAE,CAAC,CAqD3B"}
1
+ {"version":3,"file":"crawl.d.ts","sourceRoot":"","sources":["../../src/lib/crawl.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,aAAa,GACzB,SAAS,MAAM,EACf,cAAc,MAAM,EACpB,iBAAY,EACZ,iBAAc,KACZ,OAAO,CAAC,cAAc,EAAE,CA6L1B,CAAC"}
package/dist/lib/crawl.js CHANGED
@@ -1,12 +1,101 @@
1
- export async function discoverPages(baseUrl, maxDepth = 2, maxPages = 50) {
1
+ import fs from "node:fs";
2
+ import chalk from "chalk";
3
+ import { authContextOptions, getAuthMetaPath } from "./auth.js";
4
+ export const discoverPages = async (baseUrl, projectRoot, maxDepth = 3, maxPages = 200) => {
2
5
  const { chromium } = await import("playwright-chromium");
3
6
  const browser = await chromium.launch({ headless: true });
4
- const context = await browser.newContext();
7
+ const context = await browser.newContext(authContextOptions(projectRoot));
5
8
  const origin = new URL(baseUrl).origin;
6
9
  const visited = new Set();
7
10
  const results = [];
8
- const queue = [{ url: baseUrl, depth: 0 }];
11
+ const metaPath = projectRoot ? getAuthMetaPath(projectRoot) : "";
12
+ let startUrl = baseUrl;
13
+ let loginPath = "";
14
+ if (metaPath && fs.existsSync(metaPath)) {
15
+ const meta = JSON.parse(fs.readFileSync(metaPath, "utf-8"));
16
+ if (meta.loginPath) {
17
+ loginPath = meta.loginPath;
18
+ const loginUrl = new URL(meta.loginPath, baseUrl).toString();
19
+ results.push({ path: meta.loginPath, title: "Login" });
20
+ visited.add(normalizeUrl(loginUrl, origin) ?? loginUrl);
21
+ }
22
+ if (meta.landingPath) {
23
+ startUrl = new URL(meta.landingPath, baseUrl).toString();
24
+ }
25
+ }
26
+ const seenPatterns = new Set();
9
27
  try {
28
+ // Phase 1: Click nav elements on start page to discover SPA routes
29
+ console.log(chalk.gray(" Phase 1: Clicking navigation elements...\n"));
30
+ const navUrls = await discoverByClicking(context, startUrl, origin, loginPath);
31
+ // Add start page
32
+ const startNorm = normalizeUrl(startUrl, origin);
33
+ if (startNorm) {
34
+ const startPattern = toPattern(new URL(startNorm).pathname);
35
+ seenPatterns.add(startPattern);
36
+ visited.add(startNorm);
37
+ }
38
+ // Queue nav-discovered URLs for BFS
39
+ const queue = [];
40
+ for (const url of navUrls) {
41
+ const norm = normalizeUrl(url, origin);
42
+ if (!norm || visited.has(norm))
43
+ continue;
44
+ const pat = toPattern(new URL(norm).pathname);
45
+ if (seenPatterns.has(pat))
46
+ continue;
47
+ queue.push({ url: norm, depth: 1 });
48
+ }
49
+ // Also queue startUrl for link collection
50
+ if (startNorm && !visited.has(startNorm)) {
51
+ queue.unshift({ url: startNorm, depth: 0 });
52
+ }
53
+ // Add start page to results
54
+ const startPage = await context.newPage();
55
+ let sessionExpired = false;
56
+ try {
57
+ await startPage.goto(startUrl, {
58
+ waitUntil: "networkidle",
59
+ timeout: 60000,
60
+ });
61
+ const title = await startPage.title();
62
+ const pagePath = new URL(startPage.url()).pathname;
63
+ // Detect expired session
64
+ if (loginPath && pagePath === loginPath) {
65
+ console.log(chalk.yellow(`\n⚠ Redirected to ${loginPath} — session expired? Run "kagemusha login" first.\n`));
66
+ sessionExpired = true;
67
+ }
68
+ else {
69
+ const startPattern = toPattern(pagePath);
70
+ seenPatterns.add(startPattern);
71
+ results.push({ path: pagePath, title: title || pagePath });
72
+ console.log(chalk.gray(` ${pagePath}`) +
73
+ ` ${chalk.green("✓")} ${chalk.white(title)}`);
74
+ // Collect <a href> links from start page
75
+ const links = await collectLinks(startPage, origin);
76
+ for (const link of links) {
77
+ if (visited.has(link))
78
+ continue;
79
+ const linkPattern = toPattern(new URL(link).pathname);
80
+ if (seenPatterns.has(linkPattern))
81
+ continue;
82
+ queue.push({ url: link, depth: 1 });
83
+ }
84
+ }
85
+ }
86
+ catch (e) {
87
+ console.log(chalk.yellow(`\n⚠ Start page failed: ${e instanceof Error ? e.message : e}. Continuing with nav-discovered URLs.\n`));
88
+ }
89
+ finally {
90
+ await startPage.close().catch(() => { });
91
+ }
92
+ if (sessionExpired) {
93
+ return results;
94
+ }
95
+ // Phase 2: BFS crawl from discovered URLs
96
+ if (queue.length > 0) {
97
+ console.log(chalk.gray(`\n Phase 2: Crawling ${queue.length} discovered URLs...\n`));
98
+ }
10
99
  while (queue.length > 0 && results.length < maxPages) {
11
100
  const item = queue.shift();
12
101
  if (!item)
@@ -14,15 +103,29 @@ export async function discoverPages(baseUrl, maxDepth = 2, maxPages = 50) {
14
103
  const normalized = normalizeUrl(item.url, origin);
15
104
  if (!normalized || visited.has(normalized))
16
105
  continue;
106
+ const pattern = toPattern(new URL(normalized).pathname);
107
+ if (seenPatterns.has(pattern))
108
+ continue;
109
+ seenPatterns.add(pattern);
17
110
  visited.add(normalized);
111
+ const urlPath = new URL(normalized).pathname;
112
+ process.stdout.write(chalk.gray(` ${urlPath}`));
113
+ const page = await context.newPage();
18
114
  try {
19
- const page = await context.newPage();
20
115
  await page.goto(normalized, {
21
- waitUntil: "domcontentloaded",
22
- timeout: 10000,
116
+ waitUntil: "networkidle",
117
+ timeout: 60000,
23
118
  });
24
119
  const title = await page.title();
25
120
  const pagePath = new URL(page.url()).pathname;
121
+ // Skip if redirected to a known pattern
122
+ const finalPattern = toPattern(pagePath);
123
+ if (finalPattern !== pattern && seenPatterns.has(finalPattern)) {
124
+ process.stdout.write(chalk.gray(" (skip)\n"));
125
+ continue;
126
+ }
127
+ seenPatterns.add(finalPattern);
128
+ process.stdout.write(` ${chalk.green("✓")} ${chalk.white(title)}\n`);
26
129
  results.push({
27
130
  path: pagePath,
28
131
  title: title || pagePath,
@@ -30,36 +133,128 @@ export async function discoverPages(baseUrl, maxDepth = 2, maxPages = 50) {
30
133
  if (item.depth < maxDepth) {
31
134
  const links = await collectLinks(page, origin);
32
135
  for (const link of links) {
33
- if (!visited.has(link)) {
34
- queue.push({ url: link, depth: item.depth + 1 });
35
- }
136
+ if (visited.has(link))
137
+ continue;
138
+ const linkPattern = toPattern(new URL(link).pathname);
139
+ if (seenPatterns.has(linkPattern))
140
+ continue;
141
+ queue.push({ url: link, depth: item.depth + 1 });
36
142
  }
37
143
  }
38
- await page.close();
39
144
  }
40
145
  catch {
41
- // Skip pages that fail to load
146
+ process.stdout.write(chalk.yellow(" (timeout, skip)\n"));
147
+ }
148
+ finally {
149
+ await page.close().catch(() => { });
42
150
  }
43
151
  }
152
+ if (results.length >= maxPages) {
153
+ console.log(chalk.gray(`\n Reached max ${maxPages} pages, stopping.\n`));
154
+ }
44
155
  }
45
156
  finally {
46
157
  await browser.close();
47
158
  }
48
159
  return results;
49
- }
50
- async function collectLinks(page, origin) {
160
+ };
161
+ // Click nav/sidebar link elements and collect URLs they navigate to.
162
+ // We collect accessible names (text || aria-label) up front, then re-resolve
163
+ // each label by name on every iteration so SPA re-renders don't cause us
164
+ // to click the wrong element.
165
+ const discoverByClicking = async (context, startUrl, origin, loginPath) => {
166
+ const page = await context.newPage();
167
+ try {
168
+ await page.goto(startUrl, { waitUntil: "networkidle", timeout: 60000 });
169
+ // Check if redirected to login
170
+ if (loginPath && new URL(page.url()).pathname === loginPath) {
171
+ return [];
172
+ }
173
+ // Collect accessible labels for nav links first, then page-wide links.
174
+ const candidates = [];
175
+ const seen = new Set();
176
+ // Use accessible name (text || aria-label) so getByRole({ name }) can
177
+ // resolve the element again on click. Other attributes don't participate
178
+ // in accessible name and would be unreachable.
179
+ const collectLabels = async (locator, preferNav) => {
180
+ const count = await locator.count();
181
+ for (let i = 0; i < count; i++) {
182
+ const el = locator.nth(i);
183
+ let name = ((await el.textContent().catch(() => null)) ?? "").trim();
184
+ if (!name) {
185
+ name = ((await el.getAttribute("aria-label").catch(() => null)) ?? "").trim();
186
+ }
187
+ if (!name || seen.has(name))
188
+ continue;
189
+ seen.add(name);
190
+ candidates.push({ name, preferNav });
191
+ }
192
+ };
193
+ await collectLabels(page.getByRole("navigation").getByRole("link"), true);
194
+ await collectLabels(page.getByRole("link"), false);
195
+ console.log(chalk.gray(` Found ${candidates.length} link label(s) to try\n`));
196
+ const discoveredUrls = [];
197
+ for (const { name, preferNav } of candidates) {
198
+ try {
199
+ const root = preferNav
200
+ ? page
201
+ .getByRole("navigation")
202
+ .getByRole("link", { name, exact: true })
203
+ : page.getByRole("link", { name, exact: true });
204
+ const el = root.first();
205
+ if (!(await el.isVisible().catch(() => false)))
206
+ continue;
207
+ const beforeUrl = page.url();
208
+ await el.click({ timeout: 3000 });
209
+ await page
210
+ .waitForLoadState("networkidle", { timeout: 5000 })
211
+ .catch(() => { });
212
+ await page.waitForTimeout(500);
213
+ const afterUrl = page.url();
214
+ if (afterUrl !== beforeUrl && new URL(afterUrl).origin === origin) {
215
+ const afterPath = new URL(afterUrl).pathname;
216
+ if (afterPath !== loginPath) {
217
+ discoveredUrls.push(afterUrl);
218
+ console.log(chalk.green(` + ${afterPath}`) + chalk.gray(` ${name}`));
219
+ }
220
+ await page.goto(startUrl, {
221
+ waitUntil: "networkidle",
222
+ timeout: 10000,
223
+ });
224
+ }
225
+ }
226
+ catch {
227
+ // Skip elements that can't be clicked or text didn't resolve
228
+ }
229
+ }
230
+ return discoveredUrls;
231
+ }
232
+ finally {
233
+ await page.close().catch(() => { });
234
+ }
235
+ };
236
+ // Replace numeric IDs, UUIDs, and hex strings with * to detect same-structure URLs
237
+ const toPattern = (pathname) => pathname
238
+ .split("/")
239
+ .map((seg) => /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(seg)
240
+ ? "*"
241
+ : /^\d+$/.test(seg)
242
+ ? "*"
243
+ : /^[0-9a-f]{8,}$/i.test(seg)
244
+ ? "*"
245
+ : seg)
246
+ .join("/");
247
+ const collectLinks = async (page, origin) => {
51
248
  const hrefs = await page.evaluate(() => Array.from(document.querySelectorAll("a[href]")).map((a) => a.href));
52
249
  return hrefs
53
250
  .map((href) => normalizeUrl(href, origin))
54
251
  .filter((url) => url !== null);
55
- }
56
- function normalizeUrl(url, origin) {
252
+ };
253
+ const normalizeUrl = (url, origin) => {
57
254
  try {
58
255
  const parsed = new URL(url, origin);
59
- // Same origin only
60
256
  if (parsed.origin !== origin)
61
257
  return null;
62
- // Skip non-page resources
63
258
  const skip = [
64
259
  ".js",
65
260
  ".css",
@@ -80,10 +275,8 @@ function normalizeUrl(url, origin) {
80
275
  ];
81
276
  if (skip.some((ext) => parsed.pathname.endsWith(ext)))
82
277
  return null;
83
- // Skip anchors and mailto
84
278
  if (url.startsWith("mailto:") || url.startsWith("tel:"))
85
279
  return null;
86
- // Remove hash and search params for deduplication
87
280
  parsed.hash = "";
88
281
  parsed.search = "";
89
282
  return parsed.toString();
@@ -91,5 +284,5 @@ function normalizeUrl(url, origin) {
91
284
  catch {
92
285
  return null;
93
286
  }
94
- }
287
+ };
95
288
  //# sourceMappingURL=crawl.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"crawl.js","sourceRoot":"","sources":["../../src/lib/crawl.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"crawl.js","sourceRoot":"","sources":["../../src/lib/crawl.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const deriveIdFromPath: (urlPath: string) => string;
2
+ //# sourceMappingURL=definition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/lib/definition.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,GAAI,SAAS,MAAM,KAAG,MAKT,CAAC"}
@@ -0,0 +1,6 @@
1
+ export const deriveIdFromPath = (urlPath) => urlPath
2
+ .replace(/^\//, "")
3
+ .replace(/\.\w+$/, "")
4
+ .replace(/[/\\]/g, "-")
5
+ .replace(/[^a-zA-Z0-9-]/g, "") || "page";
6
+ //# sourceMappingURL=definition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definition.js","sourceRoot":"","sources":["../../src/lib/definition.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAAe,EAAU,EAAE,CAC3D,OAAO;KACL,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;KAClB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;KACrB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;KACtB,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC"}