@manta-eu/lib 0.1.6 → 0.1.8

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/README.md CHANGED
@@ -3,6 +3,8 @@
3
3
  Small TypeScript helpers shared across the Manta packages — plain functions and types, no
4
4
  framework and no service calls.
5
5
 
6
+ Documentation: [developers.manta.eu](https://developers.manta.eu)
7
+
6
8
  ## Installation
7
9
 
8
10
  ```bash
@@ -19,7 +21,7 @@ import { humanBytes, humanDuration } from "@manta-eu/lib/humanize";
19
21
  ```
20
22
 
21
23
  Modules include `array`, `date`, `number`, `color`, `file`, `enum`, `humanize`, `present`,
22
- `countries` and `ad-platform-links`. `present` carries `isPresent`, which is how this repo checks for
24
+ `countries`, `ad-platform-links` and `connection-string`. `present` carries `isPresent`, which is how this repo checks for
23
25
  a value rather than testing `.length` or truthiness.
24
26
 
25
27
  This package exists so `@manta-eu/client`, `@manta-eu/react` and `@manta-eu/rdf-lib` share one copy
@@ -0,0 +1,8 @@
1
+ export type Backoff = {
2
+ initialMs: number;
3
+ maxMs: number;
4
+ factor?: number;
5
+ jitterRatio?: number;
6
+ };
7
+ export declare function backoffDelayMs(attempt: number, backoff: Backoff, random?: () => number): number;
8
+ //# sourceMappingURL=backoff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backoff.d.ts","sourceRoot":"","sources":["../src/backoff.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,GAAG;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAE,MAAM,MAAoB,GAAG,MAAM,CAK5G"}
@@ -0,0 +1,6 @@
1
+ export function backoffDelayMs(attempt, backoff, random = Math.random) {
2
+ const { initialMs, maxMs, factor = 2, jitterRatio = 0 } = backoff;
3
+ const exponential = initialMs * factor ** Math.max(0, attempt);
4
+ const jitter = random() * exponential * jitterRatio;
5
+ return Math.min(maxMs, exponential + jitter);
6
+ }
@@ -0,0 +1,15 @@
1
+ export type ConnectionString = {
2
+ scheme: string;
3
+ host?: string;
4
+ port?: string;
5
+ username?: string;
6
+ password?: string;
7
+ path: string[];
8
+ params: Record<string, string>;
9
+ };
10
+ export type ParseOptions = {
11
+ semicolonProperties?: boolean;
12
+ };
13
+ export declare function parseConnectionString(input: string, options?: ParseOptions): ConnectionString | undefined;
14
+ export declare function unescapeBracedValue(value: string): string;
15
+ //# sourceMappingURL=connection-string.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection-string.d.ts","sourceRoot":"","sources":["../src/connection-string.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IAEzB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,gBAAgB,GAAG,SAAS,CAoB7G;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGzD"}
@@ -0,0 +1,71 @@
1
+ import { isPresent } from "./present.js";
2
+ export function parseConnectionString(input, options = {}) {
3
+ const { semicolonProperties = false } = options;
4
+ const schemeAndRest = splitScheme(stripJdbcPrefix(input.trim()));
5
+ if (!schemeAndRest)
6
+ return undefined;
7
+ const { scheme, rest } = schemeAndRest;
8
+ const [head, properties] = semicolonProperties ? splitHead(rest) : [rest, ""];
9
+ if (head.includes("\\"))
10
+ return undefined;
11
+ try {
12
+ const { path, query, ...authority } = headParts(scheme, head, semicolonProperties);
13
+ return {
14
+ scheme,
15
+ ...withoutBlankValues(authority),
16
+ path,
17
+ params: Object.fromEntries([...query, ...propertyEntries(properties)]),
18
+ };
19
+ }
20
+ catch {
21
+ return undefined;
22
+ }
23
+ }
24
+ export function unescapeBracedValue(value) {
25
+ const braced = /^\{(.*)\}$/s.exec(value);
26
+ return braced?.[1] === undefined ? value : braced[1].replaceAll("}}", "}");
27
+ }
28
+ function stripJdbcPrefix(input) {
29
+ return input.replace(/^jdbc:/i, "");
30
+ }
31
+ const schemePattern = /^([a-z][a-z0-9+.-]*):\/\//i;
32
+ function splitScheme(text) {
33
+ const match = schemePattern.exec(text);
34
+ if (!match?.[1])
35
+ return undefined;
36
+ return { scheme: match[1].toLowerCase(), rest: text.slice(match[0].length) };
37
+ }
38
+ function splitHead(text) {
39
+ const [head = "", ...properties] = text.split(";");
40
+ return [head, properties.join(";")];
41
+ }
42
+ // The BigQuery JDBC head is an endpoint URL, so a head with its own scheme carries no host.
43
+ function headParts(scheme, head, semicolonProperties) {
44
+ if (!isPresent(head) || (semicolonProperties && head.includes("://")))
45
+ return { path: [], query: [] };
46
+ return urlParts(scheme, head);
47
+ }
48
+ function urlParts(scheme, head) {
49
+ const url = new URL(`${scheme}://${head}`);
50
+ return {
51
+ host: url.hostname.replace(/^\[(.*)\]$/, "$1"),
52
+ port: url.port,
53
+ username: decodeURIComponent(url.username),
54
+ password: decodeURIComponent(url.password),
55
+ path: url.pathname.split("/").filter(Boolean).map(decodeURIComponent),
56
+ query: [...url.searchParams],
57
+ };
58
+ }
59
+ function withoutBlankValues(entries) {
60
+ return Object.fromEntries(Object.entries(entries).filter(([, value]) => isPresent(value)));
61
+ }
62
+ const propertyName = "([^;=]+)";
63
+ // The SQL Server JDBC driver escapes a value in braces, and "}}" in the braces stands for one "}".
64
+ const bracedValue = String.raw `\{(?:[^}]|\}\})*\}`;
65
+ const plainValue = "[^;]*";
66
+ const propertyPattern = new RegExp(String.raw `${propertyName}=\s*(${bracedValue}|${plainValue})`, "g");
67
+ function propertyEntries(text) {
68
+ return [...text.matchAll(propertyPattern)]
69
+ .map(([, name = "", value = ""]) => [name.trim(), value.trim()])
70
+ .filter(([name]) => isPresent(name));
71
+ }
@@ -8,9 +8,8 @@ export declare function humanDimensions({ width, height }: {
8
8
  height: number;
9
9
  }): string;
10
10
  export declare function humanPlural(word: string, count: number): string;
11
- export type HumanListOptions = {
11
+ export type HumanListOptions = Intl.ListFormatOptions & {
12
12
  truncateAt?: number;
13
- conjunction?: string;
14
13
  };
15
14
  export declare function humanList(list: string[], options?: HumanListOptions): string;
16
15
  export type HumanDurationArgs = {
@@ -1 +1 @@
1
- {"version":3,"file":"humanize.d.ts","sourceRoot":"","sources":["../src/humanize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAA0B,MAAM,UAAU,CAAC;AAOhE,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMhD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CASxD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAS1E;AAED,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAE5F;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAc5E;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACrB,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAYF,wBAAgB,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAW7D"}
1
+ {"version":3,"file":"humanize.d.ts","sourceRoot":"","sources":["../src/humanize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAA0B,MAAM,UAAU,CAAC;AAMhE,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMhD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CASxD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAS1E;AAED,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAE5F;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,iBAAiB,GAAG;IACtD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAY5E;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACrB,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAYF,wBAAgB,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAW7D"}
package/dist/humanize.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import { formatDuration, intervalToDuration } from "date-fns";
2
2
  import { filesize } from "filesize";
3
- import humanizeList from "humanize-list";
4
3
  import pluralize from "pluralize";
5
4
  import { isPresent } from "./present.js";
6
5
  export function humanBytes(input) {
@@ -40,16 +39,14 @@ export function humanPlural(word, count) {
40
39
  return pluralize(word, count, false);
41
40
  }
42
41
  export function humanList(list, options) {
43
- const { truncateAt, conjunction = "and" } = options || {};
42
+ const { truncateAt, ...formatOptions } = options || {};
43
+ const listFormat = new Intl.ListFormat("en", formatOptions);
44
44
  if (!truncateAt || list.length <= truncateAt) {
45
- return humanizeList(list, {
46
- oxfordComma: list.length > 2,
47
- conjunction,
48
- });
45
+ return listFormat.format(list);
49
46
  }
50
47
  const remaining = list.length - truncateAt;
51
48
  const truncated = [...list.slice(0, truncateAt), `+${remaining} more`];
52
- return humanizeList(truncated, { oxfordComma: true, conjunction });
49
+ return listFormat.format(truncated);
53
50
  }
54
51
  const periods = ["years", "months", "weeks", "days", "hours", "minutes", "seconds"];
55
52
  function getDurationFormat(duration, largest) {
package/package.json CHANGED
@@ -1,11 +1,19 @@
1
1
  {
2
2
  "name": "@manta-eu/lib",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "Pure TypeScript helpers shared across the Manta packages",
5
+ "homepage": "https://developers.manta.eu",
6
+ "keywords": [
7
+ "manta",
8
+ "knowledge-graph",
9
+ "typescript",
10
+ "utilities"
11
+ ],
5
12
  "license": "MIT",
6
13
  "type": "module",
7
14
  "exports": {
8
15
  "./*": {
16
+ "manta-source": "./src/*.ts",
9
17
  "types": "./dist/*.d.ts",
10
18
  "import": "./dist/*.js"
11
19
  }
@@ -16,7 +24,6 @@
16
24
  "dependencies": {
17
25
  "date-fns": "^4.1.0",
18
26
  "filesize": "^11.0.2",
19
- "humanize-list": "^1.0.1",
20
27
  "pluralize": "^8.0.0",
21
28
  "ramda": "^0.32.0"
22
29
  },