@page-scanner/cli 0.1.1 → 0.2.1

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 (55) hide show
  1. package/README.md +58 -4
  2. package/dist/api.d.ts +82 -2
  3. package/dist/api.d.ts.map +1 -1
  4. package/dist/api.js +147 -18
  5. package/dist/api.js.map +1 -1
  6. package/dist/batch.d.ts +60 -0
  7. package/dist/batch.d.ts.map +1 -0
  8. package/dist/batch.js +116 -0
  9. package/dist/batch.js.map +1 -0
  10. package/dist/cli/args.d.ts +27 -4
  11. package/dist/cli/args.d.ts.map +1 -1
  12. package/dist/cli/args.js +129 -10
  13. package/dist/cli/args.js.map +1 -1
  14. package/dist/cli/commands.d.ts +2 -0
  15. package/dist/cli/commands.d.ts.map +1 -1
  16. package/dist/cli/commands.js +170 -14
  17. package/dist/cli/commands.js.map +1 -1
  18. package/dist/daemon/rpc-server.d.ts.map +1 -1
  19. package/dist/daemon/rpc-server.js +17 -1
  20. package/dist/daemon/rpc-server.js.map +1 -1
  21. package/dist/diff/image.d.ts +42 -0
  22. package/dist/diff/image.d.ts.map +1 -0
  23. package/dist/diff/image.js +144 -0
  24. package/dist/diff/image.js.map +1 -0
  25. package/dist/diff/index.d.ts +46 -0
  26. package/dist/diff/index.d.ts.map +1 -0
  27. package/dist/diff/index.js +108 -0
  28. package/dist/diff/index.js.map +1 -0
  29. package/dist/diff/png.d.ts +12 -0
  30. package/dist/diff/png.d.ts.map +1 -0
  31. package/dist/diff/png.js +169 -0
  32. package/dist/diff/png.js.map +1 -0
  33. package/dist/diff/text.d.ts +54 -0
  34. package/dist/diff/text.d.ts.map +1 -0
  35. package/dist/diff/text.js +198 -0
  36. package/dist/diff/text.js.map +1 -0
  37. package/dist/index.d.ts +6 -3
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +6 -3
  40. package/dist/index.js.map +1 -1
  41. package/dist/output.d.ts +10 -0
  42. package/dist/output.d.ts.map +1 -1
  43. package/dist/output.js +24 -4
  44. package/dist/output.js.map +1 -1
  45. package/dist/protocol.d.ts +37 -2
  46. package/dist/protocol.d.ts.map +1 -1
  47. package/dist/protocol.js +23 -2
  48. package/dist/protocol.js.map +1 -1
  49. package/dist/verify.d.ts +31 -0
  50. package/dist/verify.d.ts.map +1 -0
  51. package/dist/verify.js +115 -0
  52. package/dist/verify.js.map +1 -0
  53. package/dist/version.d.ts +1 -1
  54. package/dist/version.js +1 -1
  55. package/package.json +3 -2
@@ -17,9 +17,12 @@
17
17
  export declare const BRIDGE_PROTOCOL_VERSION = 1;
18
18
  /** Ping cadence. Chrome resets the service worker's idle timer on every frame. */
19
19
  export declare const BRIDGE_PING_INTERVAL_MS = 20000;
20
- /** Mirrors EXPORT_FORMAT_IDS in `extension/src/lib/export/formats.ts`. */
20
+ /** Mirrors BRIDGE_FORMAT_IDS in `extension/src/lib/bridge/protocol.ts`. */
21
21
  export declare const EXPORT_FORMAT_IDS: readonly ["pdf", "png", "jpeg"];
22
22
  export type ExportFormatId = (typeof EXPORT_FORMAT_IDS)[number];
23
+ /** Mirrors STRUCTURED_MODES: the page's text beside the file, or instead of it (#61). */
24
+ export declare const STRUCTURED_MODES: readonly ["alongside", "only"];
25
+ export type StructuredMode = (typeof STRUCTURED_MODES)[number];
23
26
  /** Mirrors the keys of PAGE_SIZE_LABELS in `extension/src/lib/pdf/layout.ts`. */
24
27
  export declare const PAGE_SIZE_IDS: readonly ["auto", "a4", "letter"];
25
28
  export type PageSizeId = (typeof PAGE_SIZE_IDS)[number];
@@ -28,6 +31,16 @@ export declare const DEFAULT_PAGE_SIZE: PageSizeId;
28
31
  /** Mirrors VIDEO_HANDLINGS in `extension/src/lib/capture/viewport-units.ts`. */
29
32
  export declare const VIDEO_HANDLINGS: readonly ["frame", "blank"];
30
33
  export type VideoHandling = (typeof VIDEO_HANDLINGS)[number];
34
+ /** Mirrors COLOR_SCHEME_PREFERENCES in `extension/src/lib/capture/color-scheme.ts`. */
35
+ export declare const COLOR_SCHEME_PREFERENCES: readonly ["auto", "light", "dark"];
36
+ export type ColorSchemePreference = (typeof COLOR_SCHEME_PREFERENCES)[number];
37
+ /** Mirrors DEFAULT_COLOR_SCHEME in `extension/src/lib/capture/color-scheme.ts`. */
38
+ export declare const DEFAULT_COLOR_SCHEME: ColorSchemePreference;
39
+ /** Mirrors CAPTURE_WIDTHS in `extension/src/lib/capture/page-width.ts`. */
40
+ export declare const CAPTURE_WIDTHS: readonly ["window", "a4", "letter"];
41
+ export type CaptureWidth = (typeof CAPTURE_WIDTHS)[number];
42
+ /** Mirrors DEFAULT_CAPTURE_WIDTH in `extension/src/lib/capture/page-width.ts`. */
43
+ export declare const DEFAULT_CAPTURE_WIDTH: CaptureWidth;
31
44
  /** First frame the extension sends. The server answers `hello-ok` or closes. */
32
45
  export interface HelloFrame {
33
46
  type: 'hello';
@@ -71,8 +84,28 @@ export interface ScanRequest {
71
84
  /** 0..1, only meaningful for a lossy format. */
72
85
  quality?: number;
73
86
  videoHandling?: VideoHandling;
87
+ /** Which of a page's two themes to capture. Optional and additive. */
88
+ colorScheme?: ColorSchemePreference;
89
+ /** Lay the page out at a sheet's width, so the PDF needs no shrinking. */
90
+ captureWidth?: CaptureWidth;
74
91
  /** Leave the capture open in an editor tab afterwards. Default false. */
75
92
  openEditor?: boolean;
93
+ /** Send the page's text back as well, or instead of the file. Optional and additive. */
94
+ structured?: StructuredMode;
95
+ }
96
+ export interface StructuredHeading {
97
+ level: number;
98
+ text: string;
99
+ }
100
+ /** The page as text: Markdown, and what it is. Mirrors the extension's. */
101
+ export interface StructuredPage {
102
+ markdown: string;
103
+ title: string;
104
+ url: string;
105
+ /** Milliseconds since the epoch. */
106
+ capturedAt: number;
107
+ language: string | null;
108
+ headings: StructuredHeading[];
76
109
  }
77
110
  export interface WindowSummary {
78
111
  windowId: number;
@@ -120,8 +153,10 @@ export interface ScanResultResponse {
120
153
  /** Absent unless the capture stopped short of the whole page. */
121
154
  truncated?: TruncationReport;
122
155
  fileName: string;
123
- /** The built file. Base64 because JSON is the frame format. */
156
+ /** The built file. Base64 because JSON is the frame format. Empty for `structured: 'only'`. */
124
157
  bytesBase64: string;
158
+ /** Present when the request asked for it and the extension knows how. */
159
+ structured?: StructuredPage;
125
160
  }
126
161
  export interface ErrorResponse {
127
162
  type: 'error';
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,sFAAsF;AACtF,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAEzC,kFAAkF;AAClF,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAE9C,2EAA2E;AAC3E,eAAO,MAAM,iBAAiB,iCAAkC,CAAC;AACjE,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhE,yFAAyF;AACzF,eAAO,MAAM,gBAAgB,gCAAiC,CAAC;AAC/D,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/D,iFAAiF;AACjF,eAAO,MAAM,aAAa,mCAAoC,CAAC;AAC/D,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAExD,sEAAsE;AACtE,eAAO,MAAM,iBAAiB,EAAE,UAAiB,CAAC;AAElD,gFAAgF;AAChF,eAAO,MAAM,eAAe,6BAA8B,CAAC;AAC3D,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D,uFAAuF;AACvF,eAAO,MAAM,wBAAwB,oCAAqC,CAAC;AAC3E,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9E,mFAAmF;AACnF,eAAO,MAAM,oBAAoB,EAAE,qBAA8B,CAAC;AAElE,2EAA2E;AAC3E,eAAO,MAAM,cAAc,qCAAsC,CAAC;AAClE,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D,kFAAkF;AAClF,eAAO,MAAM,qBAAqB,EAAE,YAAuB,CAAC;AAE5D,gFAAgF;AAChF,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,iFAAiF;IACjF,SAAS,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,UAAU,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,WAAW,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,UAAU,CAAC;IACrB,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,sEAAsE;IACtE,WAAW,CAAC,EAAE,qBAAqB,CAAC;IACpC,0EAA0E;IAC1E,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,yEAAyE;IACzE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,wFAAwF;IACxF,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,2EAA2E;AAC3E,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,oEAAoE;IACpE,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,wEAAwE;IACxE,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,IAAI,EAAE,UAAU,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,aAAa,CAAC;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,iEAAiE;IACjE,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,+FAA+F;IAC/F,WAAW,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,kBAAkB,GAAG,aAAa,CAAC;AAE/E,qDAAqD;AACrD,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,SAAS,GAAG,cAAc,CAAC;AAmBnE,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAUhE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAE9D;AAkCD,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAUpE;AAkBD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,kBAAkB,CAahF;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAOtE;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,cAAc,CAExE;AAED,yEAAyE;AACzE,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAW7D;AAED,wBAAgB,QAAQ,IAAI,QAAQ,CAEnC;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAExD"}
package/dist/protocol.js CHANGED
@@ -17,14 +17,24 @@
17
17
  export const BRIDGE_PROTOCOL_VERSION = 1;
18
18
  /** Ping cadence. Chrome resets the service worker's idle timer on every frame. */
19
19
  export const BRIDGE_PING_INTERVAL_MS = 20_000;
20
- /** Mirrors EXPORT_FORMAT_IDS in `extension/src/lib/export/formats.ts`. */
20
+ /** Mirrors BRIDGE_FORMAT_IDS in `extension/src/lib/bridge/protocol.ts`. */
21
21
  export const EXPORT_FORMAT_IDS = ['pdf', 'png', 'jpeg'];
22
+ /** Mirrors STRUCTURED_MODES: the page's text beside the file, or instead of it (#61). */
23
+ export const STRUCTURED_MODES = ['alongside', 'only'];
22
24
  /** Mirrors the keys of PAGE_SIZE_LABELS in `extension/src/lib/pdf/layout.ts`. */
23
25
  export const PAGE_SIZE_IDS = ['auto', 'a4', 'letter'];
24
26
  /** Mirrors DEFAULT_PAGE_SIZE in `extension/src/lib/pdf/layout.ts`. */
25
27
  export const DEFAULT_PAGE_SIZE = 'a4';
26
28
  /** Mirrors VIDEO_HANDLINGS in `extension/src/lib/capture/viewport-units.ts`. */
27
29
  export const VIDEO_HANDLINGS = ['frame', 'blank'];
30
+ /** Mirrors COLOR_SCHEME_PREFERENCES in `extension/src/lib/capture/color-scheme.ts`. */
31
+ export const COLOR_SCHEME_PREFERENCES = ['auto', 'light', 'dark'];
32
+ /** Mirrors DEFAULT_COLOR_SCHEME in `extension/src/lib/capture/color-scheme.ts`. */
33
+ export const DEFAULT_COLOR_SCHEME = 'auto';
34
+ /** Mirrors CAPTURE_WIDTHS in `extension/src/lib/capture/page-width.ts`. */
35
+ export const CAPTURE_WIDTHS = ['window', 'a4', 'letter'];
36
+ /** Mirrors DEFAULT_CAPTURE_WIDTH in `extension/src/lib/capture/page-width.ts`. */
37
+ export const DEFAULT_CAPTURE_WIDTH = 'window';
28
38
  function isRecord(value) {
29
39
  return typeof value === 'object' && value !== null && !Array.isArray(value);
30
40
  }
@@ -82,6 +92,16 @@ export function isTabsResponse(value) {
82
92
  Array.isArray(value.tabs) &&
83
93
  value.tabs.every(isTabSummary));
84
94
  }
95
+ function isStructuredPage(value) {
96
+ return (isRecord(value) &&
97
+ typeof value.markdown === 'string' &&
98
+ typeof value.title === 'string' &&
99
+ typeof value.url === 'string' &&
100
+ isFiniteNumber(value.capturedAt) &&
101
+ (value.language === null || typeof value.language === 'string') &&
102
+ Array.isArray(value.headings) &&
103
+ value.headings.every((heading) => isRecord(heading) && isFiniteNumber(heading.level) && typeof heading.text === 'string'));
104
+ }
85
105
  export function isScanResultResponse(value) {
86
106
  return (isRecord(value) &&
87
107
  value.type === 'scan-result' &&
@@ -91,7 +111,8 @@ export function isScanResultResponse(value) {
91
111
  (value.mode === 'vector' || value.mode === 'raster') &&
92
112
  isNonEmptyString(value.fileName) &&
93
113
  typeof value.bytesBase64 === 'string' &&
94
- (value.truncated === undefined || isTruncationReport(value.truncated)));
114
+ (value.truncated === undefined || isTruncationReport(value.truncated)) &&
115
+ (value.structured === undefined || isStructuredPage(value.structured)));
95
116
  }
96
117
  export function isErrorResponse(value) {
97
118
  return (isRecord(value) &&
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ export declare const RECORD_SUFFIX = ".integrity.json";
2
+ export interface VerifyResult {
3
+ /** True when the file matches and, if signed, the signature holds. */
4
+ verified: boolean;
5
+ file: {
6
+ path: string;
7
+ matches: boolean;
8
+ sha256: string;
9
+ bytes: number;
10
+ };
11
+ record: {
12
+ path: string;
13
+ expectedSha256: string;
14
+ expectedBytes: number;
15
+ url: string | null;
16
+ captured: string | null;
17
+ };
18
+ /** Null when the record is not signed. */
19
+ signature: {
20
+ valid: boolean;
21
+ keyThumbprint: string;
22
+ } | null;
23
+ }
24
+ /** The extension's `canonicalJson`: the bytes its signature covers. */
25
+ export declare function canonicalJson(value: unknown): string;
26
+ /** Checks `filePath` against its record, `<file>.integrity.json` unless one is named. */
27
+ export declare function verifyCapture(filePath: string, options?: {
28
+ record?: string;
29
+ cwd?: string;
30
+ }): Promise<VerifyResult>;
31
+ //# sourceMappingURL=verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,aAAa,oBAAoB,CAAC;AAgB/C,MAAM,WAAW,YAAY;IAC3B,sEAAsE;IACtE,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACxE,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,cAAc,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,MAAM,CAAC;QACtB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;KACzB,CAAC;IACF,0CAA0C;IAC1C,SAAS,EAAE;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC7D;AAED,uEAAuE;AACvE,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CASpD;AAiED,yFAAyF;AACzF,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9C,OAAO,CAAC,YAAY,CAAC,CAoCvB"}
package/dist/verify.js ADDED
@@ -0,0 +1,115 @@
1
+ /**
2
+ * `page-scanner verify` (#55): checks a file against the integrity record the
3
+ * extension wrote beside it.
4
+ *
5
+ * Two questions, answered separately. Is this the file that was exported? Its
6
+ * SHA-256 and length against the record's. And, when the record is signed,
7
+ * does the signature hold over the record, with the key the record names?
8
+ * The second only says the holder of that key made the record; whether that
9
+ * key is the person it should be is the thumbprint's to answer, which is why
10
+ * it is printed. Neither says anything about the time, which is the capturing
11
+ * computer's clock, or about what the page showed anyone else.
12
+ *
13
+ * The signed bytes are the record's canonical JSON without `signature`: keys
14
+ * sorted at every depth, no whitespace, the extension's `canonicalJson`.
15
+ */
16
+ import { createHash, webcrypto } from 'node:crypto';
17
+ import { existsSync, readFileSync } from 'node:fs';
18
+ import { resolve } from 'node:path';
19
+ import { PageScannerError } from './errors.js';
20
+ export const RECORD_SUFFIX = '.integrity.json';
21
+ const RECORD_FORMAT = 'page-scanner-integrity/1';
22
+ /** The extension's `canonicalJson`: the bytes its signature covers. */
23
+ export function canonicalJson(value) {
24
+ if (Array.isArray(value))
25
+ return `[${value.map(canonicalJson).join(',')}]`;
26
+ if (value && typeof value === 'object') {
27
+ const entries = Object.entries(value)
28
+ .filter(([, item]) => item !== undefined)
29
+ .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
30
+ return `{${entries.map(([key, item]) => `${JSON.stringify(key)}:${canonicalJson(item)}`).join(',')}}`;
31
+ }
32
+ return JSON.stringify(value);
33
+ }
34
+ function badRequest(message, hint) {
35
+ return new PageScannerError('BAD_REQUEST', message, hint);
36
+ }
37
+ function readRecord(path) {
38
+ let parsed;
39
+ try {
40
+ parsed = JSON.parse(readFileSync(path, 'utf8'));
41
+ }
42
+ catch (error) {
43
+ throw badRequest(`Could not read the record ${path}: ${error instanceof Error ? error.message : String(error)}`);
44
+ }
45
+ const record = parsed;
46
+ if (!record ||
47
+ record.format !== RECORD_FORMAT ||
48
+ typeof record.file?.sha256 !== 'string' ||
49
+ typeof record.file.bytes !== 'number') {
50
+ throw badRequest(`${path} is not a Page Scanner integrity record.`);
51
+ }
52
+ return record;
53
+ }
54
+ async function signatureHolds(record) {
55
+ const { signature, ...signed } = record;
56
+ if (!signature || signature.algorithm !== 'ES256')
57
+ return false;
58
+ try {
59
+ const key = await webcrypto.subtle.importKey('jwk', {
60
+ kty: signature.publicKey.kty,
61
+ crv: signature.publicKey.crv,
62
+ x: signature.publicKey.x,
63
+ y: signature.publicKey.y,
64
+ }, { name: 'ECDSA', namedCurve: 'P-256' }, false, ['verify']);
65
+ const thumbprint = createHash('sha256')
66
+ .update(JSON.stringify({
67
+ crv: signature.publicKey.crv,
68
+ kty: signature.publicKey.kty,
69
+ x: signature.publicKey.x,
70
+ y: signature.publicKey.y,
71
+ }))
72
+ .digest('base64url');
73
+ if (thumbprint !== signature.keyThumbprint)
74
+ return false;
75
+ return await webcrypto.subtle.verify({ name: 'ECDSA', hash: 'SHA-256' }, key, Buffer.from(signature.value, 'base64url'), Buffer.from(canonicalJson(signed), 'utf8'));
76
+ }
77
+ catch {
78
+ return false;
79
+ }
80
+ }
81
+ /** Checks `filePath` against its record, `<file>.integrity.json` unless one is named. */
82
+ export async function verifyCapture(filePath, options = {}) {
83
+ const cwd = options.cwd ?? process.cwd();
84
+ const file = resolve(cwd, filePath);
85
+ const recordPath = resolve(cwd, options.record ?? `${filePath}${RECORD_SUFFIX}`);
86
+ if (!existsSync(recordPath)) {
87
+ throw badRequest(`There is no record at ${recordPath}.`, 'Name it with --record, or export with an integrity record beside the file.');
88
+ }
89
+ const record = readRecord(recordPath);
90
+ let bytes;
91
+ try {
92
+ bytes = readFileSync(file);
93
+ }
94
+ catch (error) {
95
+ throw badRequest(`Could not read ${file}: ${error instanceof Error ? error.message : String(error)}`);
96
+ }
97
+ const sha256 = createHash('sha256').update(bytes).digest('hex');
98
+ const matches = sha256 === record.file.sha256.toLowerCase() && bytes.length === record.file.bytes;
99
+ const signature = record.signature
100
+ ? { valid: await signatureHolds(record), keyThumbprint: record.signature.keyThumbprint }
101
+ : null;
102
+ return {
103
+ verified: matches && (signature === null || signature.valid),
104
+ file: { path: file, matches, sha256, bytes: bytes.length },
105
+ record: {
106
+ path: recordPath,
107
+ expectedSha256: record.file.sha256,
108
+ expectedBytes: record.file.bytes,
109
+ url: record.page?.url ?? null,
110
+ captured: record.captured?.local ?? record.captured?.utc ?? null,
111
+ },
112
+ signature,
113
+ };
114
+ }
115
+ //# sourceMappingURL=verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"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"}
package/dist/version.d.ts CHANGED
@@ -7,5 +7,5 @@
7
7
  * `version.test.ts` asserts this matches package.json, so the copy cannot
8
8
  * drift without a red test.
9
9
  */
10
- export declare const CLI_VERSION = "0.1.1";
10
+ export declare const CLI_VERSION = "0.2.1";
11
11
  //# sourceMappingURL=version.d.ts.map
package/dist/version.js CHANGED
@@ -7,5 +7,5 @@
7
7
  * `version.test.ts` asserts this matches package.json, so the copy cannot
8
8
  * drift without a red test.
9
9
  */
10
- export const CLI_VERSION = '0.1.1';
10
+ export const CLI_VERSION = '0.2.1';
11
11
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@page-scanner/cli",
3
- "version": "0.1.1",
3
+ "version": "0.2.1",
4
4
  "description": "Capture a whole web page from the command line, through the Page Scanner Chrome extension.",
5
5
  "keywords": [
6
6
  "chrome",
@@ -70,6 +70,7 @@
70
70
  "test:coverage": "vitest run --coverage",
71
71
  "ci:checks": "pnpm run typecheck && pnpm run lint && pnpm run format:check && pnpm run test:coverage",
72
72
  "ci:build": "pnpm run build",
73
- "ci": "pnpm run ci:checks && pnpm run ci:build"
73
+ "ci": "pnpm run ci:checks && pnpm run ci:build",
74
+ "doctor": "node scripts/doctor.mjs"
74
75
  }
75
76
  }