@microlink/cli 2.1.56 → 2.1.58

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/api.js +56 -11
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@microlink/cli",
3
3
  "description": "Interacting with Microlink API from your terminal.",
4
4
  "homepage": "https://github.com/microlinkhq/cli",
5
- "version": "2.1.56",
5
+ "version": "2.1.58",
6
6
  "main": "src/index.js",
7
7
  "bin": {
8
8
  "microlink": "bin/microlink",
package/src/api.js CHANGED
@@ -21,20 +21,63 @@ const exit = require('./exit')
21
21
  const microlinkUrl = () =>
22
22
  /^https?:\/\/((?!fonts|geolocation\.)[a-z0-9-]+\.)+microlink\.io/
23
23
 
24
- const normalizeInput = input => {
24
+ // Leading-host matcher for the binary's own endpoint (e.g. `microlink-dev` →
25
+ // `http://localhost:3000`, `microlink-next` → `https://next.microlink.io`).
26
+ // Each binary sets its own `cli.flags.endpoint`, so the host we strip is driven
27
+ // by that flag rather than a blanket list shared across every executable.
28
+ const endpointUrl = endpoint => {
29
+ if (!endpoint) return null
30
+ let host
31
+ try {
32
+ ;({ host } = new URL(endpoint))
33
+ } catch {
34
+ return null
35
+ }
36
+ // Require a host boundary (path/query/fragment or end-of-string) after the
37
+ // host so a longer host that merely *starts with* it isn't matched (e.g.
38
+ // endpoint `localhost:3000` must not strip a prefix of `localhost:30001`).
39
+ const escapedHost = host.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
40
+ return new RegExp(`^https?://${escapedHost}(?=[/?#]|$)`)
41
+ }
42
+
43
+ const normalizeInput = (input, endpoint) => {
25
44
  if (!input) return input
26
45
  let normalized = input
27
- const sanitizers = [
28
- microlinkUrl,
29
- () => require('is-local-address/ipv4').regex,
30
- () => require('is-local-address/ipv6').regex
31
- ]
32
-
33
- for (const createRegex of sanitizers) {
34
- normalized = normalized.replace(createRegex(), '')
46
+
47
+ // Recognize API-shaped input (full endpoint URL, or a bare `?url=`/`url=`
48
+ // query string) so a bare target URL is left untouched.
49
+ let isApiInput = /^\??url=/.test(input) || input.startsWith('?')
50
+
51
+ // Always strip a canonical `*.microlink.io` host (users paste these into any
52
+ // binary), plus the binary's own endpoint host when it isn't on microlink.io.
53
+ const sanitizers = [microlinkUrl()]
54
+ const endpointRegex = endpointUrl(endpoint)
55
+ if (endpointRegex) sanitizers.push(endpointRegex)
56
+
57
+ for (const regex of sanitizers) {
58
+ const next = normalized.replace(regex, '')
59
+ if (next !== normalized) {
60
+ isApiInput = true
61
+ normalized = next
62
+ }
35
63
  }
36
64
 
37
- return normalized.replace(/^\??url=/, '')
65
+ if (!isApiInput) return normalized
66
+
67
+ // Drop the leftover path/query separators after the host (e.g. `/?url=…`).
68
+ normalized = normalized.replace(/^\/+/, '').replace(/^\?/, '')
69
+
70
+ // Lift the `url=` param to the front so the caller's `url=${…}`
71
+ // reconstruction keeps every other param intact regardless of their order
72
+ // (e.g. `data.markdown.attr=markdown&embed=markdown&url=…`).
73
+ const params = normalized.split('&')
74
+ const urlIndex = params.findIndex(p => p === 'url' || p.startsWith('url='))
75
+ if (urlIndex === -1) return normalized
76
+
77
+ const urlValue = params[urlIndex].replace(/^url=?/, '')
78
+ return [urlValue, ...params.filter((_, index) => index !== urlIndex)].join(
79
+ '&'
80
+ )
38
81
  }
39
82
 
40
83
  const getInput = input => {
@@ -55,7 +98,9 @@ const fetch = async (cli, gotOpts) => {
55
98
  } = cli.flags
56
99
  const isJson = json || jsonFull
57
100
  const input = getInput(cli.input, endpoint)
58
- const { url, ...queryParams } = toPlainObject(`url=${normalizeInput(input)}`)
101
+ const { url, ...queryParams } = toPlainObject(
102
+ `url=${normalizeInput(input, endpoint)}`
103
+ )
59
104
  const mqlOpts = { endpoint, ...queryParams, ...flags }
60
105
  const spinner = printText.spinner()
61
106
  const shouldSpin = !isJson && pretty