@antelopejs/dms 0.8.1 → 0.8.2

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.8.2
4
+
5
+ [compare changes](https://github.com/AntelopeJS/dms/compare/v0.8.1...v0.8.2)
6
+
7
+ ### 🩹 Fixes
8
+
9
+ - **links:** Open a row field holding a whole URL as written ([#273](https://github.com/AntelopeJS/dms/pull/273))
10
+
11
+ ### ❤️ Contributors
12
+
13
+ - Antony Rizzitelli <rizzitelli.antony@pm.me>
14
+
3
15
  ## v0.8.1
4
16
 
5
17
  [compare changes](https://github.com/AntelopeJS/dms/compare/v0.8.0...v0.8.1)
@@ -3,6 +3,10 @@ import { get } from "@nuxt/ui/runtime/utils/index.js";
3
3
  // A row field is named `{{row.<field>}}` (a dotted path reaching into it), as
4
4
  // the page's values are `{{params.X}}` / `{{query.X}}`, filled elsewhere.
5
5
  const ROW_TOKEN = /\{\{\s*row\.([^{}\s]+)\s*\}\}/g;
6
+ // A template that is one row token and nothing else takes a whole URL from the
7
+ // row (`{{row.invoiceUrl}}`): encoding it would turn its `/` and `?` into
8
+ // `%2F` and `%3F`, leaving no URL to open.
9
+ const WHOLE_ROW_TOKEN = new RegExp(`^\\s*${ROW_TOKEN.source}\\s*$`);
6
10
 
7
11
  /** Whether a template names a field of a row (`{{row.X}}`). */
8
12
  export const namesRowField = (template: string): boolean =>
@@ -30,18 +34,25 @@ function hasSafeScheme(url: string): boolean {
30
34
  return scheme === undefined || SAFE_SCHEMES.has(scheme.toLowerCase());
31
35
  }
32
36
 
37
+ const fillRowTokens = (url: string, data: Record<string, unknown>): string => {
38
+ const wholeKey = WHOLE_ROW_TOKEN.exec(url)?.[1];
39
+ if (wholeKey !== undefined) return rowValue(data, wholeKey);
40
+ return url.replace(ROW_TOKEN, (_, key: string) =>
41
+ encodeURIComponent(rowValue(data, key)).replace(ENCODED_COLON, ":"),
42
+ );
43
+ };
44
+
33
45
  /**
34
46
  * Fills the `{{row.field}}` tokens of a URL template with encoded row values,
35
- * a field the row lacks left empty. A result with a scheme other than http,
36
- * https or mailto comes back empty.
47
+ * a field the row lacks left empty. A template that is a single token takes
48
+ * the field as the whole URL, unencoded. A result with a scheme other than
49
+ * http, https or mailto comes back empty.
37
50
  */
38
51
  export const interpolateUrl = (
39
52
  url: string,
40
53
  data: Record<string, unknown>,
41
54
  ): string => {
42
- const interpolated = url.replace(ROW_TOKEN, (_, key: string) =>
43
- encodeURIComponent(rowValue(data, key)).replace(ENCODED_COLON, ":"),
44
- );
55
+ const interpolated = fillRowTokens(url, data);
45
56
  return hasSafeScheme(interpolated) ? interpolated : REFUSED_URL;
46
57
  };
47
58
 
@@ -4,7 +4,10 @@ import { interpolateUrl } from "../layers/dms-core/app/utils/url-interpolation";
4
4
  describe("interpolateUrl", () => {
5
5
  it("fills row fields into the URL, encoded", () => {
6
6
  expect(
7
- interpolateUrl("/items/{{row._id}}/tag/{{row.name}}", { _id: "a1", name: "a b/c" }),
7
+ interpolateUrl("/items/{{row._id}}/tag/{{row.name}}", {
8
+ _id: "a1",
9
+ name: "a b/c",
10
+ }),
8
11
  ).toBe("/items/a1/tag/a%20b%2Fc");
9
12
  });
10
13
 
@@ -27,6 +30,14 @@ describe("interpolateUrl", () => {
27
30
  );
28
31
  });
29
32
 
33
+ it("takes a field forming the whole URL as it is", () => {
34
+ const url = "https://pay.stripe.com/invoice/acct_1/x/pdf?s=ap";
35
+ expect(interpolateUrl("{{row.invoiceUrl}}", { invoiceUrl: url })).toBe(url);
36
+ expect(
37
+ interpolateUrl(" {{ row.links.self }} ", { links: { self: "/a/b?c=d" } }),
38
+ ).toBe("/a/b?c=d");
39
+ });
40
+
30
41
  it("refuses a scheme the row data brings in", () => {
31
42
  for (const site of [
32
43
  "javascript:alert(1)",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antelopejs/dms",
3
- "version": "0.8.1",
3
+ "version": "0.8.2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/AntelopeJS/dms.git"