@ohos-ports/drivelist 12.0.2-beta.1

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.
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright 2018 Balena.io
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.parse = exports.transform = void 0;
19
+ const path_1 = require("path");
20
+ const _1 = require(".");
21
+ function getMountpoints(children) {
22
+ return children
23
+ .filter((child) => {
24
+ return child.mountpoint;
25
+ })
26
+ .map((child) => {
27
+ return {
28
+ path: child.mountpoint,
29
+ label: child.label || child.partlabel,
30
+ };
31
+ });
32
+ }
33
+ function getDescription(device) {
34
+ const description = [
35
+ device.label || '',
36
+ device.vendor || '',
37
+ device.model || '',
38
+ ];
39
+ if (device.children) {
40
+ let subLabels = device.children
41
+ .filter((c) => (c.label && c.label !== device.label) || c.mountpoint)
42
+ .map((c) => c.label || c.mountpoint);
43
+ subLabels = Array.from(new Set(subLabels));
44
+ if (subLabels.length) {
45
+ description.push(`(${subLabels.join(', ')})`);
46
+ }
47
+ }
48
+ return description.join(' ').replace(/\s+/g, ' ').trim();
49
+ }
50
+ function resolveDeviceName(name) {
51
+ if (!name) {
52
+ return null;
53
+ }
54
+ if (!path_1.posix.isAbsolute(name)) {
55
+ return path_1.posix.resolve('/dev', name);
56
+ }
57
+ return name;
58
+ }
59
+ function transform(data) {
60
+ return data.blockdevices
61
+ .map((device) => Object.assign({}, device, {
62
+ name: resolveDeviceName(device.name),
63
+ kname: resolveDeviceName(device.kname),
64
+ }))
65
+ .filter((device) =>
66
+ // Omit loop devices, CD/DVD drives, and RAM
67
+ !device.name.startsWith('/dev/loop') &&
68
+ !device.name.startsWith('/dev/sr') &&
69
+ !device.name.startsWith('/dev/ram'))
70
+ .map((device) => {
71
+ const isVirtual = device.subsystems
72
+ ? /^(block)$/i.test(device.subsystems)
73
+ : null;
74
+ const isSCSI = device.tran
75
+ ? /^(sata|scsi|ata|ide|pci)$/i.test(device.tran)
76
+ : null;
77
+ const isUSB = device.tran ? /^(usb)$/i.test(device.tran) : null;
78
+ const isReadOnly = Number(device.ro) === 1;
79
+ const isRemovable = Number(device.rm) === 1 ||
80
+ Number(device.hotplug) === 1 ||
81
+ Boolean(isVirtual);
82
+ return {
83
+ enumerator: 'lsblk:json',
84
+ busType: (device.tran || 'UNKNOWN').toUpperCase(),
85
+ busVersion: null,
86
+ device: device.name,
87
+ devicePath: null,
88
+ raw: device.kname || device.name,
89
+ description: getDescription(device),
90
+ error: null,
91
+ size: Number(device.size) || null,
92
+ blockSize: Number(device['phy-sec']) || 512,
93
+ logicalBlockSize: Number(device['log-sec']) || 512,
94
+ mountpoints: device.children
95
+ ? getMountpoints(device.children)
96
+ : getMountpoints([device]),
97
+ isReadOnly,
98
+ isSystem: !isRemovable && !isVirtual,
99
+ isVirtual,
100
+ isRemovable,
101
+ isCard: null,
102
+ isSCSI,
103
+ isUSB,
104
+ isUAS: null,
105
+ partitionTableType: (0, _1.getPartitionTableType)(device.pttype),
106
+ };
107
+ });
108
+ }
109
+ exports.transform = transform;
110
+ function parse(stdout) {
111
+ return transform(JSON.parse(stdout));
112
+ }
113
+ exports.parse = parse;
114
+ //# sourceMappingURL=json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.js","sourceRoot":"","sources":["../../lib/lsblk/json.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Drive } from '..';
2
+ export declare function parse(stdout: string): Drive[];
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright 2018 Balena.io
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.parse = void 0;
19
+ const _1 = require(".");
20
+ function parseLsblkLine(line) {
21
+ const data = {};
22
+ let offset = 0;
23
+ let key = '';
24
+ let value = '';
25
+ const keyChar = /[^"=]/;
26
+ const whitespace = /\s+/;
27
+ const escape = '\\';
28
+ let state = 'key';
29
+ while (offset < line.length) {
30
+ if (state === 'key') {
31
+ while (keyChar.test(line[offset])) {
32
+ key += line[offset];
33
+ offset += 1;
34
+ }
35
+ if (line[offset] === '=') {
36
+ state = 'value';
37
+ offset += 1;
38
+ }
39
+ }
40
+ else if (state === 'value') {
41
+ if (line[offset] !== '"') {
42
+ throw new Error(`Expected '"', saw "${line[offset]}"`);
43
+ }
44
+ offset += 1;
45
+ while (line[offset - 1] === escape ||
46
+ (line[offset - 1] !== escape && line[offset] !== '"')) {
47
+ value += line[offset];
48
+ offset += 1;
49
+ }
50
+ if (line[offset] !== '"') {
51
+ throw new Error(`Expected '"', saw "${line[offset]}"`);
52
+ }
53
+ offset += 1;
54
+ data[key.toLowerCase()] = value.trim();
55
+ key = '';
56
+ value = '';
57
+ state = 'space';
58
+ }
59
+ else if (state === 'space') {
60
+ while (whitespace.test(line[offset])) {
61
+ offset += 1;
62
+ }
63
+ state = 'key';
64
+ }
65
+ else {
66
+ throw new Error(`Undefined state "${state}"`);
67
+ }
68
+ }
69
+ return data;
70
+ }
71
+ function parseLsblk(output) {
72
+ return output.trim().split(/\r?\n/g).map(parseLsblkLine);
73
+ }
74
+ function consolidate(devices) {
75
+ const primaries = devices.filter((device) => {
76
+ return (device.type === 'disk' &&
77
+ !device.name.startsWith('ram') &&
78
+ !device.name.startsWith('sr'));
79
+ });
80
+ return primaries.map((device) => {
81
+ const children = devices.filter((child) => {
82
+ return (['disk', 'part'].includes(child.type) &&
83
+ child.name.startsWith(device.name));
84
+ });
85
+ return Object.assign({}, device, {
86
+ mountpoints: children
87
+ .filter((child) => child.mountpoint)
88
+ .map((child) => {
89
+ return {
90
+ path: child.mountpoint,
91
+ label: child.label,
92
+ };
93
+ }),
94
+ });
95
+ });
96
+ }
97
+ function getDescription(device) {
98
+ const description = [
99
+ device.label || '',
100
+ device.vendor || '',
101
+ device.model || '',
102
+ ];
103
+ if (device.mountpoints.length) {
104
+ let subLabels = device.mountpoints
105
+ .filter((c) => {
106
+ return (c.label && c.label !== device.label) || c.path;
107
+ })
108
+ .map((c) => {
109
+ return c.label || c.path;
110
+ });
111
+ subLabels = Array.from(new Set(subLabels));
112
+ if (subLabels.length) {
113
+ description.push(`(${subLabels.join(', ')})`);
114
+ }
115
+ }
116
+ return description.join(' ').replace(/\s+/g, ' ').trim();
117
+ }
118
+ function parse(stdout) {
119
+ const devices = consolidate(parseLsblk(stdout));
120
+ return devices.map((device) => {
121
+ const isVirtual = device.subsystems
122
+ ? /^block$/i.test(device.subsystems)
123
+ : null;
124
+ const isSCSI = device.tran
125
+ ? /^(?:sata|scsi|ata|ide|pci)$/i.test(device.tran)
126
+ : null;
127
+ const isUSB = device.tran ? /^usb$/i.test(device.tran) : null;
128
+ const isReadOnly = Number(device.ro) === 1;
129
+ const isRemovable = Number(device.rm) === 1 ||
130
+ Number(device.hotplug) === 1 ||
131
+ Boolean(isVirtual);
132
+ return {
133
+ enumerator: 'lsblk:pairs',
134
+ busType: (device.tran || 'UNKNOWN').toUpperCase(),
135
+ busVersion: null,
136
+ device: '/dev/' + device.name,
137
+ devicePath: null,
138
+ raw: '/dev/' + device.name,
139
+ description: getDescription(device) || device.name,
140
+ error: null,
141
+ size: Number(device.size) || null,
142
+ blockSize: Number(device['phy-sec']) || 512,
143
+ logicalBlockSize: Number(device['log-sec']) || 512,
144
+ mountpoints: device.mountpoints,
145
+ isReadOnly,
146
+ isSystem: !isRemovable && !isVirtual,
147
+ isVirtual,
148
+ isRemovable,
149
+ isCard: null,
150
+ isSCSI,
151
+ isUSB,
152
+ isUAS: null,
153
+ partitionTableType: (0, _1.getPartitionTableType)(device.pttype),
154
+ };
155
+ });
156
+ }
157
+ exports.parse = parse;
158
+ //# sourceMappingURL=pairs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pairs.js","sourceRoot":"","sources":["../../lib/lsblk/pairs.ts"],"names":[],"mappings":"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"}
package/lib/index.ts ADDED
@@ -0,0 +1,113 @@
1
+ /*
2
+ * Copyright 2016 Balena.io
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ /**
18
+ * @module drivelist
19
+ */
20
+
21
+ import bindings = require('bindings');
22
+ import { platform } from 'os';
23
+
24
+ import { lsblk } from './lsblk';
25
+
26
+ export interface Mountpoint {
27
+ path: string;
28
+ label: string | null;
29
+ }
30
+
31
+ export interface Drive {
32
+ blockSize: number;
33
+ busType: string;
34
+ busVersion: null;
35
+ description: string;
36
+ device: string;
37
+ devicePath: string | null;
38
+ enumerator: string;
39
+ error: null;
40
+ isCard: null;
41
+ isReadOnly: boolean;
42
+ isRemovable: boolean;
43
+ isSCSI: boolean | null;
44
+ isSystem: boolean;
45
+ isUAS: null;
46
+ isUSB: boolean | null;
47
+ isVirtual: boolean | null;
48
+ logicalBlockSize: number;
49
+ mountpoints: Mountpoint[];
50
+ raw: string;
51
+ size: number | null;
52
+ partitionTableType: 'mbr' | 'gpt' | null;
53
+ }
54
+
55
+ const drivelistBindings = bindings('drivelist');
56
+
57
+ function bindingsList(): Promise<Drive[]> {
58
+ return new Promise((resolve, reject) => {
59
+ drivelistBindings.list((error: Error, drives: Drive[]) => {
60
+ if (error != null) {
61
+ reject(error);
62
+ } else {
63
+ resolve(drives);
64
+ }
65
+ });
66
+ });
67
+ }
68
+
69
+ function handleApfs(disks: Drive[]): void {
70
+ const apfs: Drive[] = [];
71
+ const other: Drive[] = [];
72
+ for (const disk of disks) {
73
+ if (disk.description === 'AppleAPFSMedia') {
74
+ apfs.push(disk);
75
+ } else {
76
+ other.push(disk);
77
+ }
78
+ }
79
+ for (const disk of apfs) {
80
+ const source = other.find(
81
+ (d) => d.devicePath === disk.devicePath && !d.isVirtual,
82
+ );
83
+ if (source !== undefined) {
84
+ source.mountpoints.push(...disk.mountpoints);
85
+ disk.isVirtual = true;
86
+ }
87
+ }
88
+ }
89
+
90
+ /**
91
+ * @summary List available drives
92
+ *
93
+ * @example
94
+ * const drivelist = require('drivelist');
95
+ *
96
+ * const drives = await drivelist.list();
97
+ * drives.forEach((drive) => {
98
+ * console.log(drive);
99
+ * });
100
+ */
101
+ export async function list(): Promise<Drive[]> {
102
+ const plat = platform();
103
+ if (plat === 'win32') {
104
+ return await bindingsList();
105
+ } else if (plat === 'darwin') {
106
+ const disks = await bindingsList();
107
+ handleApfs(disks);
108
+ return disks;
109
+ } else if (plat === 'linux' || plat === 'openharmony') {
110
+ return await lsblk();
111
+ }
112
+ throw new Error(`Your OS is not supported by this module: ${platform()}`);
113
+ }
@@ -0,0 +1,126 @@
1
+ /*
2
+ * Copyright 2018 Balena.io
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { execFile } from 'child_process';
18
+ import { promises as fs } from 'fs';
19
+ import { join, resolve } from 'path';
20
+ import { promisify } from 'util';
21
+
22
+ import { Drive } from '..';
23
+ import { parse as parseJSON } from './json';
24
+ import { parse as parsePairs } from './pairs';
25
+
26
+ const execFileAsync = promisify(execFile);
27
+
28
+ const DISK_PATH_DIR = '/dev/disk/by-path/';
29
+
30
+ let SUPPORTS_JSON = true;
31
+ let SUPPORTS_PTTYPE = true;
32
+
33
+ export function getPartitionTableType(
34
+ pttype?: 'gpt' | 'dos',
35
+ ): 'gpt' | 'mbr' | null {
36
+ if (pttype === 'gpt') {
37
+ return 'gpt';
38
+ } else if (pttype === 'dos') {
39
+ return 'mbr';
40
+ }
41
+ return null;
42
+ }
43
+
44
+ async function getDevicePaths(): Promise<Map<string, string>> {
45
+ const mapping = new Map();
46
+ for (const filename of await fs.readdir(DISK_PATH_DIR)) {
47
+ const linkPath = join(DISK_PATH_DIR, filename);
48
+ let link: string;
49
+ try {
50
+ link = await fs.readlink(linkPath);
51
+ } catch (error) {
52
+ continue;
53
+ }
54
+ const devicePath = resolve(DISK_PATH_DIR, link);
55
+ mapping.set(devicePath, linkPath);
56
+ }
57
+ return mapping;
58
+ }
59
+
60
+ async function addDevicePaths(devices: Drive[]): Promise<void> {
61
+ const devicePaths = await getDevicePaths();
62
+ for (const device of devices) {
63
+ device.devicePath = devicePaths.get(device.device) || null;
64
+ }
65
+ }
66
+
67
+ async function getOutput(command: string, ...args: string[]) {
68
+ const { stdout } = await execFileAsync(command, args);
69
+ return stdout;
70
+ }
71
+
72
+ async function lsblkJSON(): Promise<Drive[]> {
73
+ return parseJSON(
74
+ await getOutput(
75
+ 'lsblk',
76
+ '--bytes',
77
+ '--all',
78
+ '--json',
79
+ '--paths',
80
+ '--output-all',
81
+ ),
82
+ );
83
+ }
84
+
85
+ async function getLsblkPairsOutput() {
86
+ if (SUPPORTS_PTTYPE) {
87
+ try {
88
+ return await getOutput(
89
+ 'lsblk',
90
+ '--bytes',
91
+ '--all',
92
+ '--pairs',
93
+ '-o',
94
+ '+pttype',
95
+ );
96
+ } catch (error) {
97
+ SUPPORTS_PTTYPE = false;
98
+ }
99
+ }
100
+ return await getOutput('lsblk', '--bytes', '--all', '--pairs');
101
+ }
102
+
103
+ async function lsblkPairs(): Promise<Drive[]> {
104
+ return parsePairs(await getLsblkPairsOutput());
105
+ }
106
+
107
+ async function $lsblk(): Promise<Drive[]> {
108
+ if (SUPPORTS_JSON) {
109
+ try {
110
+ return await lsblkJSON();
111
+ } catch (error) {
112
+ SUPPORTS_JSON = false;
113
+ }
114
+ }
115
+ return await lsblkPairs();
116
+ }
117
+
118
+ export async function lsblk(): Promise<Drive[]> {
119
+ const drives = await $lsblk();
120
+ try {
121
+ await addDevicePaths(drives);
122
+ } catch (error) {
123
+ // Couldn't add device paths
124
+ }
125
+ return drives;
126
+ }
@@ -0,0 +1,155 @@
1
+ /*
2
+ * Copyright 2018 Balena.io
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { posix } from 'path';
18
+
19
+ import { getPartitionTableType } from '.';
20
+ import { Drive, Mountpoint } from '..';
21
+
22
+ interface LsblkJsonOutput {
23
+ blockdevices: LsblkJsonOutputDevice[];
24
+ }
25
+
26
+ interface LsblkJsonOutputDevice {
27
+ children: LsblkJsonOutputDeviceChild[];
28
+ hotplug?: string;
29
+ kname?: string;
30
+ label: string | null;
31
+ 'log-sec'?: string;
32
+ model: string | null;
33
+ mountpoint: string | null;
34
+ name: string;
35
+ partlabel: string | null;
36
+ 'phy-sec'?: string;
37
+ rm?: string;
38
+ ro?: string;
39
+ size?: string;
40
+ subsystems?: string;
41
+ tran?: string;
42
+ vendor: string | null;
43
+ pttype?: 'gpt' | 'dos';
44
+ }
45
+
46
+ interface LsblkJsonOutputDeviceChild {
47
+ label: string | null;
48
+ mountpoint?: string;
49
+ partlabel: string | null;
50
+ }
51
+
52
+ function getMountpoints(
53
+ children: Array<LsblkJsonOutputDeviceChild | LsblkJsonOutputDevice>,
54
+ ): Mountpoint[] {
55
+ return children
56
+ .filter((child) => {
57
+ return child.mountpoint;
58
+ })
59
+ .map((child) => {
60
+ return {
61
+ path: child.mountpoint!,
62
+ label: child.label || child.partlabel,
63
+ };
64
+ });
65
+ }
66
+
67
+ function getDescription(device: LsblkJsonOutputDevice): string {
68
+ const description = [
69
+ device.label || '',
70
+ device.vendor || '',
71
+ device.model || '',
72
+ ];
73
+ if (device.children) {
74
+ let subLabels = device.children
75
+ .filter((c) => (c.label && c.label !== device.label) || c.mountpoint)
76
+ .map((c) => c.label || c.mountpoint);
77
+ subLabels = Array.from(new Set(subLabels));
78
+ if (subLabels.length) {
79
+ description.push(`(${subLabels.join(', ')})`);
80
+ }
81
+ }
82
+ return description.join(' ').replace(/\s+/g, ' ').trim();
83
+ }
84
+
85
+ function resolveDeviceName(name?: string): string | null {
86
+ if (!name) {
87
+ return null;
88
+ }
89
+ if (!posix.isAbsolute(name)) {
90
+ return posix.resolve('/dev', name);
91
+ }
92
+ return name;
93
+ }
94
+
95
+ export function transform(data: LsblkJsonOutput): Drive[] {
96
+ return data.blockdevices
97
+ .map((device) =>
98
+ Object.assign({}, device, {
99
+ name: resolveDeviceName(device.name),
100
+ kname: resolveDeviceName(device.kname),
101
+ }),
102
+ )
103
+ .filter(
104
+ (device) =>
105
+ // Omit loop devices, CD/DVD drives, and RAM
106
+ !device.name.startsWith('/dev/loop') &&
107
+ !device.name.startsWith('/dev/sr') &&
108
+ !device.name.startsWith('/dev/ram'),
109
+ )
110
+ .map(
111
+ (device: LsblkJsonOutputDevice): Drive => {
112
+ const isVirtual = device.subsystems
113
+ ? /^(block)$/i.test(device.subsystems)
114
+ : null;
115
+ const isSCSI = device.tran
116
+ ? /^(sata|scsi|ata|ide|pci)$/i.test(device.tran)
117
+ : null;
118
+ const isUSB = device.tran ? /^(usb)$/i.test(device.tran) : null;
119
+ const isReadOnly = Number(device.ro) === 1;
120
+ const isRemovable =
121
+ Number(device.rm) === 1 ||
122
+ Number(device.hotplug) === 1 ||
123
+ Boolean(isVirtual);
124
+ return {
125
+ enumerator: 'lsblk:json',
126
+ busType: (device.tran || 'UNKNOWN').toUpperCase(),
127
+ busVersion: null,
128
+ device: device.name,
129
+ devicePath: null,
130
+ raw: device.kname || device.name,
131
+ description: getDescription(device),
132
+ error: null,
133
+ size: Number(device.size) || null,
134
+ blockSize: Number(device['phy-sec']) || 512,
135
+ logicalBlockSize: Number(device['log-sec']) || 512,
136
+ mountpoints: device.children
137
+ ? getMountpoints(device.children)
138
+ : getMountpoints([device]),
139
+ isReadOnly,
140
+ isSystem: !isRemovable && !isVirtual,
141
+ isVirtual,
142
+ isRemovable,
143
+ isCard: null,
144
+ isSCSI,
145
+ isUSB,
146
+ isUAS: null,
147
+ partitionTableType: getPartitionTableType(device.pttype),
148
+ };
149
+ },
150
+ );
151
+ }
152
+
153
+ export function parse(stdout: string): Drive[] {
154
+ return transform(JSON.parse(stdout));
155
+ }