@vforsh/argus-core 0.5.2 → 0.5.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 (37) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +1 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/protocol/http/dom.d.ts +4 -1
  7. package/dist/protocol/http/dom.d.ts.map +1 -1
  8. package/dist/protocol/http/dom.js +2 -0
  9. package/dist/protocol/http/dom.js.map +1 -1
  10. package/dist/protocol/http/domInteraction.d.ts +4 -1
  11. package/dist/protocol/http/domInteraction.d.ts.map +1 -1
  12. package/dist/protocol/http/domInteraction.js +9 -0
  13. package/dist/protocol/http/domInteraction.js.map +1 -1
  14. package/dist/protocol/http/errors.d.ts +1 -1
  15. package/dist/protocol/http/errors.d.ts.map +1 -1
  16. package/dist/protocol/http/errors.js +3 -0
  17. package/dist/protocol/http/errors.js.map +1 -1
  18. package/dist/protocol/http/extension.d.ts +12 -0
  19. package/dist/protocol/http/extension.d.ts.map +1 -1
  20. package/dist/protocol/http/extension.js +18 -1
  21. package/dist/protocol/http/extension.js.map +1 -1
  22. package/dist/protocol/http/navigation.d.ts +128 -0
  23. package/dist/protocol/http/navigation.d.ts.map +1 -0
  24. package/dist/protocol/http/navigation.js +66 -0
  25. package/dist/protocol/http/navigation.js.map +1 -0
  26. package/dist/protocol/http.d.ts +1 -0
  27. package/dist/protocol/http.d.ts.map +1 -1
  28. package/dist/protocol/http.js +1 -0
  29. package/dist/protocol/http.js.map +1 -1
  30. package/dist/protocol/native-messaging.d.ts +28 -3
  31. package/dist/protocol/native-messaging.d.ts.map +1 -1
  32. package/dist/protocol/native-messaging.js +1 -1
  33. package/dist/url/queryParams.d.ts +82 -0
  34. package/dist/url/queryParams.d.ts.map +1 -0
  35. package/dist/url/queryParams.js +146 -0
  36. package/dist/url/queryParams.js.map +1 -0
  37. package/package.json +1 -1
@@ -0,0 +1,146 @@
1
+ /**
2
+ * URL rewriting shared by every command that navigates or reloads a page.
3
+ *
4
+ * `page reload --param` (which drives Chrome directly over a target's WebSocket) and
5
+ * `POST /navigate` (which runs inside the watcher) have to agree on what `--param foo=bar`
6
+ * means, and on what `/settings` resolves to. Both once lived only in the CLI, so the
7
+ * watcher had no way to reach them; keeping the rules here — in the dependency-free core —
8
+ * is what lets the two paths stay identical.
9
+ */
10
+ /**
11
+ * Parse a single `--param key=value` argument.
12
+ *
13
+ * The value may contain `=`; only the first one separates key from value. An empty key is
14
+ * rejected rather than silently written as `""`.
15
+ */
16
+ export const parseParamPair = (value) => {
17
+ const eqIdx = value.indexOf('=');
18
+ if (eqIdx === -1) {
19
+ return { error: `Invalid --param "${value}": missing "=".` };
20
+ }
21
+ const key = value.slice(0, eqIdx);
22
+ if (key === '') {
23
+ return { error: `Invalid --param "${value}": empty key.` };
24
+ }
25
+ return { key, value: value.slice(eqIdx + 1) };
26
+ };
27
+ /**
28
+ * Parse a `--params "a=b&c=d"` argument into search params.
29
+ *
30
+ * Keys and values are percent-decoded, matching what a user would have typed into an
31
+ * address bar. An empty string yields empty params rather than an error.
32
+ */
33
+ export const parseParamsString = (value) => {
34
+ const params = new URLSearchParams();
35
+ if (value.trim() === '') {
36
+ return params;
37
+ }
38
+ const pairs = value.split('&');
39
+ for (const pair of pairs) {
40
+ const eqIdx = pair.indexOf('=');
41
+ if (eqIdx === -1) {
42
+ return { error: `Invalid --params "${pair}": missing "=".` };
43
+ }
44
+ const key = pair.slice(0, eqIdx);
45
+ if (key === '') {
46
+ return { error: `Invalid --params "${pair}": empty key.` };
47
+ }
48
+ params.set(decodeURIComponent(key), decodeURIComponent(pair.slice(eqIdx + 1)));
49
+ }
50
+ return params;
51
+ };
52
+ /** True when the URL uses a scheme whose query string Argus is willing to rewrite. */
53
+ export const isHttpUrl = (url) => url.startsWith('http://') || url.startsWith('https://');
54
+ /**
55
+ * Rewrite a URL's query string with overwrite semantics.
56
+ *
57
+ * Existing params the caller did not mention are preserved; ones it did are replaced, never
58
+ * appended. `params` is applied before `param` so a repeated `--param` flag wins over the
59
+ * bulk string when both name the same key.
60
+ *
61
+ * @param baseUrl Absolute http/https URL to rewrite.
62
+ * @param overrides Query overrides. When neither is present, `baseUrl` is returned unchanged.
63
+ * @returns The rewritten URL, or the reason the rewrite was refused (non-http scheme,
64
+ * unparseable URL, malformed pair).
65
+ */
66
+ export const applyQueryParams = (baseUrl, overrides) => {
67
+ const hasParam = (overrides.param?.length ?? 0) > 0;
68
+ const hasParams = overrides.params != null;
69
+ if (!hasParam && !hasParams) {
70
+ return { url: baseUrl };
71
+ }
72
+ if (!isHttpUrl(baseUrl)) {
73
+ return { error: `URL "${baseUrl}" is not http/https. Cannot update query params.` };
74
+ }
75
+ let parsed;
76
+ try {
77
+ parsed = new URL(baseUrl);
78
+ }
79
+ catch {
80
+ return { error: `Invalid URL "${baseUrl}".` };
81
+ }
82
+ if (hasParams) {
83
+ const fromString = parseParamsString(overrides.params);
84
+ if ('error' in fromString) {
85
+ return fromString;
86
+ }
87
+ for (const [key, value] of fromString.entries()) {
88
+ parsed.searchParams.set(key, value);
89
+ }
90
+ }
91
+ for (const pair of overrides.param ?? []) {
92
+ const parsedPair = parseParamPair(pair);
93
+ if ('error' in parsedPair) {
94
+ return parsedPair;
95
+ }
96
+ parsed.searchParams.set(parsedPair.key, parsedPair.value);
97
+ }
98
+ return { url: parsed.toString() };
99
+ };
100
+ /** A scheme followed by `//`, or any other scheme (`about:`, `data:`, `mailto:`). */
101
+ const SCHEME_PATTERN = /^[a-zA-Z][a-zA-Z0-9+.-]*:/;
102
+ /** `host:port` — the one shape that also matches {@link SCHEME_PATTERN} but is not a scheme. */
103
+ const HOST_PORT_PATTERN = /^[^/?#:]+:\d+(?:[/?#]|$)/;
104
+ /** Leading forms that are unambiguously relative to the current document. */
105
+ const RELATIVE_PATTERN = /^[/?#]|^\.\.?(?:[/?#]|$)/;
106
+ /**
107
+ * Resolve what the user typed into an absolute URL to navigate to.
108
+ *
109
+ * Three shapes reach this, and only one of them is a URL already:
110
+ * - relative — anything starting with `/`, `?`, `#`, `./` or `../` is resolved against
111
+ * `currentUrl`. This is why resolution runs in the watcher: it owns the authoritative URL.
112
+ * - absolute (`https://x/y`, `about:blank`) — used verbatim.
113
+ * - scheme-less (`localhost:3000`, `example.com/x`) — gets `http://`, matching what a browser
114
+ * address bar does.
115
+ *
116
+ * The leading character decides, deliberately: a bare token like `settings` becomes
117
+ * `http://settings/` rather than being guessed at, so `argus goto app /settings` and
118
+ * `argus goto app settings` never silently mean the same thing.
119
+ *
120
+ * @param input What the user typed. Whitespace is trimmed.
121
+ * @param currentUrl The page's current top-frame URL, or `null` when nothing is attached.
122
+ * @returns The absolute URL, or the reason it could not be resolved.
123
+ */
124
+ export const resolveNavigationUrl = (input, currentUrl) => {
125
+ const trimmed = input.trim();
126
+ if (trimmed === '') {
127
+ return { error: 'URL must be a non-empty string.' };
128
+ }
129
+ if (RELATIVE_PATTERN.test(trimmed)) {
130
+ if (!currentUrl) {
131
+ return { error: `Cannot resolve relative URL "${trimmed}": the page has no current URL.` };
132
+ }
133
+ try {
134
+ return { url: new URL(trimmed, currentUrl).toString() };
135
+ }
136
+ catch {
137
+ return { error: `Cannot resolve "${trimmed}" against "${currentUrl}".` };
138
+ }
139
+ }
140
+ // `localhost:3000` also matches SCHEME_PATTERN, so the host:port shape is checked first.
141
+ if (HOST_PORT_PATTERN.test(trimmed) || !SCHEME_PATTERN.test(trimmed)) {
142
+ return { url: `http://${trimmed}` };
143
+ }
144
+ return { url: trimmed };
145
+ };
146
+ //# sourceMappingURL=queryParams.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queryParams.js","sourceRoot":"","sources":["../../src/url/queryParams.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vforsh/argus-core",
3
- "version": "0.5.2",
3
+ "version": "0.5.4",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/vforsh/argus.git",