uti 8.2.3 → 8.3.0

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/dist/uti.d.mts ADDED
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Registry of UTIs.
3
+ * @property {Map<string,UTI>} registry
4
+ * @property {Map<string,UTI>} utiByMimeType
5
+ * @property {Map<string,UTI>} utiByFileNameExtension
6
+ */
7
+ export class UTIController {
8
+ registry: Map<any, any>;
9
+ utiByMimeType: Map<any, any>;
10
+ utiByFileNameExtension: Map<any, any>;
11
+ /**
12
+ * Registers additional types.
13
+ * @param {Object[]} types
14
+ */
15
+ register(types: any[]): void;
16
+ /**
17
+ * Lookup a given UTI.
18
+ * @param {string} name UTI
19
+ * @return {string} UTI for the given name or undefined if UTI is not present.
20
+ */
21
+ getUTI(name: string): string;
22
+ /**
23
+ * Lookup a UTIs for a mime type.
24
+ * @param {string} mimeType mime type to get UTIs for
25
+ * @return {string} UTI for the given mime type or undefined if no UTI is registerd for the mime type
26
+ */
27
+ getUTIsForMimeType(mimeType: string): string;
28
+ /**
29
+ * Lookup a UTI for a file name.
30
+ * First the file name extension is extracted.
31
+ * Then a lookup in the reistered UTIs for file name extions is executed.
32
+ * @param {string} fileName file to detect UTI for
33
+ * @return {string[]} UTI for the given fileName or undefined if no UTI is registerd for the file names extension
34
+ */
35
+ getUTIsForFileName(fileName: string): string[];
36
+ /**
37
+ * Check whenever two UTI are conformant.
38
+ * If a conforms to b and b conforms to c then a also conforms to c.
39
+ * @param {string} a first UTI
40
+ * @param {string} b second UTI
41
+ * @return {boolean} true if UTI a conforms to UTI b.
42
+ */
43
+ conformsTo(a: string, b: string): boolean;
44
+ /**
45
+ * Lookup a UTI for a file name and check conformance.
46
+ * @param {string} fileName file to detect UTI for
47
+ * @param {string} uti to check conformance against
48
+ * @return {boolean} ture if utils for file name are conformant
49
+ */
50
+ fileNameConformsTo(fileName: string, uti: string): boolean;
51
+ assignMimeTypes(name: any, mimTypes: any): void;
52
+ assignExtensions(name: any, extensions: any): void;
53
+ }
@@ -0,0 +1,98 @@
1
+ declare const _default: ({
2
+ name: string;
3
+ conformsTo?: undefined;
4
+ mimeType?: undefined;
5
+ fileNameExtension?: undefined;
6
+ filNameExtension?: undefined;
7
+ } | {
8
+ name: string;
9
+ conformsTo: string;
10
+ mimeType?: undefined;
11
+ fileNameExtension?: undefined;
12
+ filNameExtension?: undefined;
13
+ } | {
14
+ name: string;
15
+ conformsTo: string[];
16
+ mimeType: string;
17
+ fileNameExtension: string;
18
+ filNameExtension?: undefined;
19
+ } | {
20
+ name: string;
21
+ conformsTo: string[];
22
+ fileNameExtension: string;
23
+ mimeType?: undefined;
24
+ filNameExtension?: undefined;
25
+ } | {
26
+ name: string;
27
+ conformsTo: string[];
28
+ mimeType?: undefined;
29
+ fileNameExtension?: undefined;
30
+ filNameExtension?: undefined;
31
+ } | {
32
+ name: string;
33
+ conformsTo: string;
34
+ fileNameExtension: string;
35
+ mimeType: string;
36
+ filNameExtension?: undefined;
37
+ } | {
38
+ name: string;
39
+ conformsTo: string;
40
+ fileNameExtension: string;
41
+ mimeType?: undefined;
42
+ filNameExtension?: undefined;
43
+ } | {
44
+ name: string;
45
+ conformsTo: string;
46
+ fileNameExtension: string[];
47
+ mimeType: string;
48
+ filNameExtension?: undefined;
49
+ } | {
50
+ name: string;
51
+ conformsTo: string;
52
+ fileNameExtension: string;
53
+ mimeType: string[];
54
+ filNameExtension?: undefined;
55
+ } | {
56
+ name: string;
57
+ conformsTo: string;
58
+ fileNameExtension: string[];
59
+ mimeType?: undefined;
60
+ filNameExtension?: undefined;
61
+ } | {
62
+ name: string;
63
+ conformsTo: string[];
64
+ fileNameExtension: string[];
65
+ mimeType: string[];
66
+ filNameExtension?: undefined;
67
+ } | {
68
+ name: string;
69
+ conformsTo: string;
70
+ fileNameExtension: string[];
71
+ mimeType: string[];
72
+ filNameExtension?: undefined;
73
+ } | {
74
+ name: string;
75
+ conformsTo: string[];
76
+ fileNameExtension: string[];
77
+ mimeType?: undefined;
78
+ filNameExtension?: undefined;
79
+ } | {
80
+ name: string;
81
+ conformsTo: string[];
82
+ mimeType: string;
83
+ fileNameExtension: string[];
84
+ filNameExtension?: undefined;
85
+ } | {
86
+ name: string;
87
+ conformsTo: string;
88
+ filNameExtension: string;
89
+ mimeType: string;
90
+ fileNameExtension?: undefined;
91
+ } | {
92
+ name: string;
93
+ fileNameExtension: string[];
94
+ conformsTo?: undefined;
95
+ mimeType?: undefined;
96
+ filNameExtension?: undefined;
97
+ })[];
98
+ export default _default;
package/package.json CHANGED
@@ -1,12 +1,15 @@
1
1
  {
2
2
  "name": "uti",
3
- "version": "8.2.3",
3
+ "version": "8.3.0",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "provenance": true
7
7
  },
8
8
  "exports": {
9
- ".": "./src/uti.mjs"
9
+ ".": {
10
+ "types": "./dist/uti.d.mts",
11
+ "default": "./src/uti.mjs"
12
+ }
10
13
  },
11
14
  "description": "javascript implementation of a \"Uniform Type Identifier\" (UTI)",
12
15
  "keywords": [
@@ -22,6 +25,7 @@
22
25
  ],
23
26
  "license": "BSD-2-Clause",
24
27
  "scripts": {
28
+ "prepare": "tsc --allowJs --declaration --emitDeclarationOnly --declarationDir dist -t esnext -m esnext --module nodenext --moduleResolution nodenext ./src**/*.mjs",
25
29
  "test": "npm run test:browser-ava && npm run test:ava",
26
30
  "test:ava": "ava --timeout 4m tests/*-ava.mjs tests/*-ava-node.mjs",
27
31
  "test:browser-ava": "browser-ava --headless --no-keep-open tests/*-ava.mjs tests/*-ava-browser.mjs",
@@ -33,14 +37,14 @@
33
37
  },
34
38
  "devDependencies": {
35
39
  "ava": "^6.1.1",
36
- "browser-ava": "^2.1.10",
40
+ "browser-ava": "^2.1.12",
37
41
  "c8": "^9.1.0",
38
42
  "documentation": "^14.0.3",
39
- "semantic-release": "^23.0.0",
43
+ "semantic-release": "^23.0.2",
40
44
  "typescript": "^5.3.3"
41
45
  },
42
46
  "engines": {
43
- "node": ">=18.18.2",
47
+ "node": ">=20.11.0",
44
48
  "bun": ">=1.0.0"
45
49
  },
46
50
  "repository": {
@@ -55,7 +59,8 @@
55
59
  "inheritFrom": [
56
60
  "arlac77/template-arlac77-github",
57
61
  "arlac77/template-browser-ava",
58
- "arlac77/template-esm-only",
62
+ "arlac77/template-javascript-component",
63
+ "arlac77/template-node-component",
59
64
  "arlac77/template-typescript"
60
65
  ]
61
66
  }
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { spawn } from "node:child_process";
4
+ import wellKnown from "../src/well-known-utis.mjs";
5
+
6
+ function asArray(object) {
7
+ return Array.isArray(object) ? object : object === undefined ? [] : [object];
8
+ }
9
+
10
+ function asScalar(object) {
11
+ if (object !== undefined && object?.size > 0) {
12
+ if (object.size === 1) {
13
+ for (const o of object) {
14
+ return o;
15
+ }
16
+ }
17
+ return [...object];
18
+ }
19
+ }
20
+
21
+ const lsregister = spawn(
22
+ "/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister",
23
+ ["-dump"]
24
+ );
25
+
26
+ let name, conformsTo, tags;
27
+
28
+ for await (const line of lineIterator(lsregister.stdout)) {
29
+ let m = line.match(/^([^:]+):\s+(.+)/);
30
+ if (m) {
31
+ switch (m[1]) {
32
+ case "uti":
33
+ name = m[2];
34
+ break;
35
+ case "conforms to":
36
+ conformsTo = m[2].split(/\s*,\s*/);
37
+ break;
38
+ case "tags":
39
+ tags = m[2].split(/\s*,\s*/);
40
+ break;
41
+ }
42
+ }
43
+
44
+ if (name && line.match(/^-/)) {
45
+ const b = wellKnown.find(u => u.name === name);
46
+ const a = {
47
+ name,
48
+ conformsTo: asScalar([...asArray(conformsTo), ...asArray(b?.conformsTo)]),
49
+ fileNameExtension: asScalar(
50
+ new Set([
51
+ ...asArray(tags?.filter(t => t.match(/^\./))),
52
+ ...asArray(b?.fileNameExtension)
53
+ ])
54
+ ),
55
+ mimeType: asScalar([
56
+ ...asArray(tags?.filter(t => t.match(/^\w+\//))),
57
+ ...asArray(b?.mimeType)
58
+ ])
59
+ };
60
+
61
+ if (b) {
62
+ for (const p of ["conformsTo", "fileNameExtension", "mimeType"]) {
63
+ if (Array.isArray(b[p])) {
64
+ a[p] = b[p];
65
+ }
66
+ }
67
+ } else {
68
+ wellKnown.push(a);
69
+ }
70
+
71
+ name = undefined;
72
+ conformsTo = undefined;
73
+ tags = undefined;
74
+ }
75
+ }
76
+
77
+ console.log(JSON.stringify(wellKnown, undefined, 2));
78
+
79
+ export async function* lineIterator(stream, decoder = new TextDecoder()) {
80
+ const re = /\r?\n/gm;
81
+ let chunk = "";
82
+ let startIndex = 0;
83
+
84
+ for await (const value of stream) {
85
+ chunk += decoder.decode(value);
86
+ while (true) {
87
+ const result = re.exec(chunk);
88
+ if (result) {
89
+ yield chunk.substring(startIndex, result.index);
90
+ startIndex = re.lastIndex;
91
+ } else {
92
+ chunk = chunk.substring(startIndex);
93
+ startIndex = re.lastIndex = 0;
94
+ break;
95
+ }
96
+ }
97
+ }
98
+
99
+ if (startIndex < chunk.length) {
100
+ yield chunk;
101
+ }
102
+ }