@sequencemedia/drive 0.0.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/package.json +46 -0
- package/src/common/authorize.d.mts +10 -0
- package/src/common/authorize.mjs +41 -0
- package/src/common/config.d.mts +13 -0
- package/src/common/config.mjs +21 -0
- package/src/common/error.d.mts +15 -0
- package/src/common/error.mjs +15 -0
- package/src/common/getKeyFile.d.mts +16 -0
- package/src/common/getKeyFile.mjs +39 -0
- package/src/common/hasKeyFile.d.mts +16 -0
- package/src/common/hasKeyFile.mjs +27 -0
- package/src/common/hasKeyFileJson.d.mts +5 -0
- package/src/common/hasKeyFileJson.mjs +12 -0
- package/src/common/hasKeyFilePath.d.mts +5 -0
- package/src/common/hasKeyFilePath.mjs +20 -0
- package/src/create/index.d.mts +10 -0
- package/src/create/index.mjs +102 -0
- package/src/delete/index.d.mts +8 -0
- package/src/delete/index.mjs +75 -0
- package/src/get/index.d.mts +8 -0
- package/src/get/index.mjs +81 -0
- package/src/get-list/index.d.mts +8 -0
- package/src/get-list/index.mjs +85 -0
- package/src/index.d.mts +9 -0
- package/src/index.mjs +4 -0
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sequencemedia/drive",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"main": "./src/index.mjs",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"types": "./src/index.d.mts",
|
|
7
|
+
"author": {
|
|
8
|
+
"name": "Jonathan Perry for Sequence Media Limited",
|
|
9
|
+
"email": "sequencemedia@sequencemedia.net",
|
|
10
|
+
"url": "https://sequencemedia.net"
|
|
11
|
+
},
|
|
12
|
+
"license": "ISC",
|
|
13
|
+
"scripts": {
|
|
14
|
+
"lint": "eslint .",
|
|
15
|
+
"lint:fix": "npm run lint -- --fix",
|
|
16
|
+
"prepare": "husky"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"debug": "^4.3.7",
|
|
20
|
+
"googleapis": "^144.0.0",
|
|
21
|
+
"nconf": "^0.12.1"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@babel/core": "^7.26.0",
|
|
25
|
+
"@babel/preset-env": "^7.26.0",
|
|
26
|
+
"@sequencemedia/eslint-config-standard": "^0.1.4",
|
|
27
|
+
"@sequencemedia/eslint-config-typescript": "^0.0.2",
|
|
28
|
+
"@types/debug": "^4.1.12",
|
|
29
|
+
"@types/nconf": "^0.10.7",
|
|
30
|
+
"@types/node": "^22.10.1",
|
|
31
|
+
"core-js": "^3.39.0",
|
|
32
|
+
"eslint": "^9.16.0",
|
|
33
|
+
"globals": "^15.13.0",
|
|
34
|
+
"husky": "^9.1.7"
|
|
35
|
+
},
|
|
36
|
+
"imports": {
|
|
37
|
+
"#common": "./src/common/index.mjs",
|
|
38
|
+
"#common/*": "./src/common/*.mjs"
|
|
39
|
+
},
|
|
40
|
+
"exports": {
|
|
41
|
+
"./create": "./src/create/index.mjs",
|
|
42
|
+
"./delete": "./src/delete/index.mjs",
|
|
43
|
+
"./get": "./src/get/index.mjs",
|
|
44
|
+
"./get-list": "./src/get-list/index.mjs"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { JWT } from 'google-auth-library'
|
|
2
|
+
|
|
3
|
+
export function getClientEmail (keyFile: KeyFileType): string | null
|
|
4
|
+
|
|
5
|
+
export function getPrivateKey (keyFile: KeyFileType): string | null
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Authorise using a Service Account (and return a JWT client)
|
|
9
|
+
*/
|
|
10
|
+
export default function authorize (keyFile: KeyFileType, scopes?: string[]): Promise<JWT>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import('google-auth-library').JWT} JWT
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
google
|
|
7
|
+
} from 'googleapis'
|
|
8
|
+
|
|
9
|
+
export function getClientEmail ({
|
|
10
|
+
client_email: clientEmail = null
|
|
11
|
+
}) {
|
|
12
|
+
return clientEmail
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function getPrivateKey ({
|
|
16
|
+
private_key: privateKey = null
|
|
17
|
+
}) {
|
|
18
|
+
return privateKey
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Authorise using a Service Account (and return a JWT client)
|
|
23
|
+
*
|
|
24
|
+
* @param {Record<PropertyKey, string | undefined>} keyFile
|
|
25
|
+
* @param {string[]} scopes
|
|
26
|
+
* @returns {JWT}
|
|
27
|
+
*/
|
|
28
|
+
export default async function authorize (keyFile, scopes = []) {
|
|
29
|
+
if (!keyFile) throw new Error('A key file is required')
|
|
30
|
+
|
|
31
|
+
const authClient = new google.auth.JWT(
|
|
32
|
+
getClientEmail(keyFile),
|
|
33
|
+
null,
|
|
34
|
+
getPrivateKey(keyFile),
|
|
35
|
+
scopes
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
await authClient.authorize()
|
|
39
|
+
|
|
40
|
+
return authClient
|
|
41
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
declare const config: Record<PropertyKey, string | undefined>
|
|
2
|
+
|
|
3
|
+
declare const KEY_FILE_JSON: string | undefined
|
|
4
|
+
declare const KEY_FILE_PATH: string | undefined
|
|
5
|
+
declare const GOOGLE_DRIVE_VERSION: string
|
|
6
|
+
|
|
7
|
+
export default config
|
|
8
|
+
|
|
9
|
+
export {
|
|
10
|
+
KEY_FILE_JSON,
|
|
11
|
+
KEY_FILE_PATH,
|
|
12
|
+
GOOGLE_DRIVE_VERSION
|
|
13
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import nconf from 'nconf'
|
|
2
|
+
|
|
3
|
+
const config = nconf.argv().env().defaults({
|
|
4
|
+
KEY_FILE_JSON: null,
|
|
5
|
+
KEY_FILE_PATH: null,
|
|
6
|
+
GOOGLE_DRIVE_VERSION: 'v3'
|
|
7
|
+
}).get()
|
|
8
|
+
|
|
9
|
+
const {
|
|
10
|
+
KEY_FILE_JSON,
|
|
11
|
+
KEY_FILE_PATH,
|
|
12
|
+
GOOGLE_DRIVE_VERSION
|
|
13
|
+
} = config
|
|
14
|
+
|
|
15
|
+
export default config
|
|
16
|
+
|
|
17
|
+
export {
|
|
18
|
+
KEY_FILE_JSON,
|
|
19
|
+
KEY_FILE_PATH,
|
|
20
|
+
GOOGLE_DRIVE_VERSION
|
|
21
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function hasErrorCode ({ code }: {
|
|
2
|
+
code: number | undefined
|
|
3
|
+
}): boolean
|
|
4
|
+
|
|
5
|
+
export function getErrorCode ({ code }: {
|
|
6
|
+
code: number | undefined
|
|
7
|
+
}): number | undefined
|
|
8
|
+
|
|
9
|
+
export function hasErrorMessage ({ message }: {
|
|
10
|
+
message: string | undefined
|
|
11
|
+
}): boolean
|
|
12
|
+
|
|
13
|
+
export function getErrorMessage ({ message }: {
|
|
14
|
+
message: string | undefined
|
|
15
|
+
}): string | undefined
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function hasErrorCode ({ code }) {
|
|
2
|
+
return Boolean(code)
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function getErrorCode ({ code }) {
|
|
6
|
+
return code
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function hasErrorMessage ({ message }) {
|
|
10
|
+
return Boolean(message)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function getErrorMessage ({ message }) {
|
|
14
|
+
return message
|
|
15
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
KEY_FILE_JSON,
|
|
3
|
+
KEY_FILE_PATH
|
|
4
|
+
} from '#common/config'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @param {string | undefined | null} keyFileJson
|
|
8
|
+
* @param {string | undefined | null} keyFilePath
|
|
9
|
+
* @returns {Promise<KeyFileType>}
|
|
10
|
+
*/
|
|
11
|
+
export default function getKeyFile (keyFileJson: string | undefined | null, keyFilePath: string | undefined | null): Promise<KeyFileType>
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
KEY_FILE_JSON,
|
|
15
|
+
KEY_FILE_PATH
|
|
16
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {
|
|
2
|
+
readFile
|
|
3
|
+
} from 'node:fs/promises'
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
KEY_FILE_JSON,
|
|
7
|
+
KEY_FILE_PATH
|
|
8
|
+
} from '#common/config'
|
|
9
|
+
|
|
10
|
+
import hasKeyFileJson from './hasKeyFileJson.mjs'
|
|
11
|
+
import hasKeyFilePath from './hasKeyFilePath.mjs'
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
KEY_FILE_JSON,
|
|
15
|
+
KEY_FILE_PATH
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param {string | undefined | null} keyFileJson
|
|
20
|
+
* @param {string | undefined | null} keyFilePath
|
|
21
|
+
* @returns {Promise<Record<PropertyKey, string | undefined>>}
|
|
22
|
+
*/
|
|
23
|
+
export default async function getKeyFile (keyFileJson, keyFilePath) {
|
|
24
|
+
if (hasKeyFileJson(keyFileJson)) {
|
|
25
|
+
return (
|
|
26
|
+
JSON.parse(
|
|
27
|
+
keyFileJson
|
|
28
|
+
)
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (await hasKeyFilePath(keyFilePath)) {
|
|
33
|
+
return (
|
|
34
|
+
JSON.parse(
|
|
35
|
+
await readFile(keyFilePath)
|
|
36
|
+
)
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
KEY_FILE_JSON,
|
|
3
|
+
KEY_FILE_PATH
|
|
4
|
+
} from '#common/config'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @param {string | undefined | null} keyFileJson
|
|
8
|
+
* @param {string | undefined | null} keyFilePath
|
|
9
|
+
* @returns {Promise<boolean>}
|
|
10
|
+
*/
|
|
11
|
+
export default function hasKeyFile (keyFileJson: string | undefined | null, keyFilePath: string | undefined | null): Promise<boolean>
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
KEY_FILE_JSON,
|
|
15
|
+
KEY_FILE_PATH
|
|
16
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {
|
|
2
|
+
KEY_FILE_JSON,
|
|
3
|
+
KEY_FILE_PATH
|
|
4
|
+
} from '#common/config'
|
|
5
|
+
|
|
6
|
+
import hasKeyFileJson from './hasKeyFileJson.mjs'
|
|
7
|
+
import hasKeyFilePath from './hasKeyFilePath.mjs'
|
|
8
|
+
|
|
9
|
+
export {
|
|
10
|
+
KEY_FILE_JSON,
|
|
11
|
+
KEY_FILE_PATH
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @param {string | undefined | null} keyFileJson
|
|
16
|
+
* @param {string | undefined | null} keyFilePath
|
|
17
|
+
* @returns {Promise<boolean>}
|
|
18
|
+
*/
|
|
19
|
+
export default async function hasKeyFile (keyFileJson, keyFilePath) {
|
|
20
|
+
try {
|
|
21
|
+
if (hasKeyFileJson(keyFileJson)) return true
|
|
22
|
+
if (hasKeyFilePath(keyFilePath)) return true
|
|
23
|
+
return false
|
|
24
|
+
} catch {
|
|
25
|
+
return false
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {string | undefined | null} keyFileJson
|
|
3
|
+
* @returns {boolean}
|
|
4
|
+
*/
|
|
5
|
+
export default function hasKeyFileJson (keyFileJson = null) {
|
|
6
|
+
try {
|
|
7
|
+
if (keyFileJson && JSON.parse(keyFileJson)) return true
|
|
8
|
+
return false
|
|
9
|
+
} catch {
|
|
10
|
+
return false
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
constants,
|
|
3
|
+
access
|
|
4
|
+
} from 'node:fs/promises'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @param {string | undefined | null} keyFilePath
|
|
8
|
+
* @returns {Promise<boolean>}
|
|
9
|
+
*/
|
|
10
|
+
export default async function hasKeyFilePath (keyFilePath = null) {
|
|
11
|
+
try {
|
|
12
|
+
if (keyFilePath) {
|
|
13
|
+
await access(keyFilePath, constants.R_OK)
|
|
14
|
+
return true
|
|
15
|
+
}
|
|
16
|
+
return false
|
|
17
|
+
} catch {
|
|
18
|
+
return false
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import('google-auth-library').OAuth2Client} AuthClient
|
|
3
|
+
* @typedef {import('googleapis').drive_v3 } DriveV3
|
|
4
|
+
* @typedef {DriveV3.Schema$File} File
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import debug from 'debug'
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
Readable
|
|
11
|
+
} from 'node:stream'
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
google
|
|
15
|
+
} from 'googleapis'
|
|
16
|
+
|
|
17
|
+
import {
|
|
18
|
+
GOOGLE_DRIVE_VERSION
|
|
19
|
+
} from '#common/config'
|
|
20
|
+
|
|
21
|
+
import {
|
|
22
|
+
hasErrorCode,
|
|
23
|
+
getErrorCode,
|
|
24
|
+
getErrorMessage
|
|
25
|
+
} from '#common/error'
|
|
26
|
+
|
|
27
|
+
import authorize from '#common/authorize'
|
|
28
|
+
|
|
29
|
+
const SCOPES = [
|
|
30
|
+
'https://www.googleapis.com/auth/drive.file'
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
const log = debug('@sequencemedia/drive/create')
|
|
34
|
+
const error = debug('@sequencemedia/drive/create:error')
|
|
35
|
+
|
|
36
|
+
log('`@sequencemedia/drive` is awake')
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Create a JSON file in Google Drive
|
|
40
|
+
*
|
|
41
|
+
* @param {string} driveId Drive identifier
|
|
42
|
+
* @param {string} fileName JSON file identifier
|
|
43
|
+
* @param {string} fileData JSON file contents
|
|
44
|
+
* @param {AuthClient} authClient An authorised OAuth2 client
|
|
45
|
+
* @returns {File}
|
|
46
|
+
*/
|
|
47
|
+
async function createJsonFile (driveId, fileName, fileData, authClient) {
|
|
48
|
+
try {
|
|
49
|
+
const drive = google.drive({
|
|
50
|
+
version: GOOGLE_DRIVE_VERSION,
|
|
51
|
+
auth: authClient
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
const {
|
|
55
|
+
data
|
|
56
|
+
} = await drive.files.create({
|
|
57
|
+
supportsAllDrives: true,
|
|
58
|
+
// includeItemsFromAllDrives: true,
|
|
59
|
+
requestBody: {
|
|
60
|
+
fields: 'id, name',
|
|
61
|
+
parents: [
|
|
62
|
+
driveId
|
|
63
|
+
],
|
|
64
|
+
name: fileName
|
|
65
|
+
},
|
|
66
|
+
media: {
|
|
67
|
+
mimeType: 'application/json',
|
|
68
|
+
body: Readable.from(Buffer.from(fileData))
|
|
69
|
+
}
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
return data
|
|
73
|
+
} catch (e) {
|
|
74
|
+
if (hasErrorCode(e)) error(getErrorCode(e))
|
|
75
|
+
error(getErrorMessage(e))
|
|
76
|
+
throw e
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Create a JSON file in Google Drive
|
|
82
|
+
*
|
|
83
|
+
* @param {string} driveId Drive identifier
|
|
84
|
+
* @param {string} fileName JSON file name
|
|
85
|
+
* @param {Buffer} fileData JSON file data
|
|
86
|
+
* @param {Record<PropertyKey, string | undefined>} keyFile Authorisation
|
|
87
|
+
* @param {string[]} scopes Authorisation scopes
|
|
88
|
+
* @returns {File}
|
|
89
|
+
*/
|
|
90
|
+
export default async function createInDrive (driveId, fileName, fileData, keyFile, scopes = SCOPES) {
|
|
91
|
+
return (
|
|
92
|
+
await createJsonFile(
|
|
93
|
+
driveId,
|
|
94
|
+
fileName,
|
|
95
|
+
fileData.toString('utf8'),
|
|
96
|
+
await authorize(
|
|
97
|
+
keyFile,
|
|
98
|
+
scopes
|
|
99
|
+
)
|
|
100
|
+
)
|
|
101
|
+
)
|
|
102
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import('google-auth-library').OAuth2Client} AuthClient
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import debug from 'debug'
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
google
|
|
9
|
+
} from 'googleapis'
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
GOOGLE_DRIVE_VERSION
|
|
13
|
+
} from '#common/config'
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
hasErrorCode,
|
|
17
|
+
getErrorCode,
|
|
18
|
+
getErrorMessage
|
|
19
|
+
} from '#common/error'
|
|
20
|
+
|
|
21
|
+
import authorize from '#common/authorize'
|
|
22
|
+
|
|
23
|
+
const SCOPES = [
|
|
24
|
+
'https://www.googleapis.com/auth/drive.file'
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
const log = debug('@sequencemedia/drive/delete')
|
|
28
|
+
const error = debug('@sequencemedia/drive/delete:error')
|
|
29
|
+
|
|
30
|
+
log('`@sequencemedia/drive` is awake')
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Delete a JSON file from Google Drive
|
|
34
|
+
*
|
|
35
|
+
* @param {string} fileId JSON file identifier
|
|
36
|
+
* @param {AuthClient} authClient An authorised OAuth2 client
|
|
37
|
+
* @returns {Promise<void>}
|
|
38
|
+
*/
|
|
39
|
+
async function deleteJsonFile (fileId, authClient) {
|
|
40
|
+
try {
|
|
41
|
+
const drive = google.drive({
|
|
42
|
+
version: GOOGLE_DRIVE_VERSION,
|
|
43
|
+
auth: authClient
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
await drive.files.delete({
|
|
47
|
+
supportsAllDrives: true,
|
|
48
|
+
// includeItemsFromAllDrives: true,
|
|
49
|
+
fileId
|
|
50
|
+
})
|
|
51
|
+
} catch (e) {
|
|
52
|
+
if (hasErrorCode(e)) error(getErrorCode(e))
|
|
53
|
+
error(getErrorMessage(e))
|
|
54
|
+
throw e
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Delete a JSON file from Google Drive
|
|
60
|
+
*
|
|
61
|
+
* @param {string} fileId JSON file identifier
|
|
62
|
+
* @param {Record<PropertyKey, string | undefined>} keyFile An authorised OAuth2 client
|
|
63
|
+
* @returns {Promise<void>}
|
|
64
|
+
*/
|
|
65
|
+
export default async function deleteFromDrive (fileId, keyFile, scopes = SCOPES) {
|
|
66
|
+
return (
|
|
67
|
+
await deleteJsonFile(
|
|
68
|
+
fileId,
|
|
69
|
+
await authorize(
|
|
70
|
+
keyFile,
|
|
71
|
+
scopes
|
|
72
|
+
)
|
|
73
|
+
)
|
|
74
|
+
)
|
|
75
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import('google-auth-library').OAuth2Client} AuthClient
|
|
3
|
+
* @typedef {import('googleapis').drive_v3 } DriveV3
|
|
4
|
+
* @typedef {DriveV3.Schema$File} File
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import debug from 'debug'
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
google
|
|
11
|
+
} from 'googleapis'
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
GOOGLE_DRIVE_VERSION
|
|
15
|
+
} from '#common/config'
|
|
16
|
+
|
|
17
|
+
import {
|
|
18
|
+
hasErrorCode,
|
|
19
|
+
getErrorCode,
|
|
20
|
+
getErrorMessage
|
|
21
|
+
} from '#common/error'
|
|
22
|
+
|
|
23
|
+
import authorize from '#common/authorize'
|
|
24
|
+
|
|
25
|
+
const SCOPES = [
|
|
26
|
+
'https://www.googleapis.com/auth/drive.file'
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
const log = debug('@sequencemedia/drive/get')
|
|
30
|
+
const error = debug('@sequencemedia/drive/get:error')
|
|
31
|
+
|
|
32
|
+
log('`@sequencemedia/drive` is awake')
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Get a JSON file from Google Drive
|
|
36
|
+
*
|
|
37
|
+
* @param {string} fileId JSON file identifier
|
|
38
|
+
* @param {AuthClient} authClient An authorised OAuth2 client
|
|
39
|
+
* @returns {File}
|
|
40
|
+
*/
|
|
41
|
+
async function getJsonFile (fileId, authClient) {
|
|
42
|
+
try {
|
|
43
|
+
const drive = google.drive({
|
|
44
|
+
version: GOOGLE_DRIVE_VERSION,
|
|
45
|
+
auth: authClient
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
const {
|
|
49
|
+
data
|
|
50
|
+
} = await drive.files.get({
|
|
51
|
+
fileId,
|
|
52
|
+
alt: 'media'
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
return data
|
|
56
|
+
} catch (e) {
|
|
57
|
+
if (hasErrorCode(e)) error(getErrorCode(e))
|
|
58
|
+
error(getErrorMessage(e))
|
|
59
|
+
throw e
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Get a JSON file from Google Drive
|
|
65
|
+
*
|
|
66
|
+
* @param {string} fileId JSON file identifier
|
|
67
|
+
* @param {Record<PropertyKey, string | undefined>} keyFile Authorisation
|
|
68
|
+
* @param {string[]} scopes Authorisation scopes
|
|
69
|
+
* @returns {Promise<File>}
|
|
70
|
+
*/
|
|
71
|
+
export default async function getFromDrive (fileId, keyFile, scopes = SCOPES) {
|
|
72
|
+
return (
|
|
73
|
+
await getJsonFile(
|
|
74
|
+
fileId,
|
|
75
|
+
await authorize(
|
|
76
|
+
keyFile,
|
|
77
|
+
scopes
|
|
78
|
+
)
|
|
79
|
+
)
|
|
80
|
+
)
|
|
81
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import('google-auth-library').OAuth2Client} AuthClient
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import debug from 'debug'
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
google
|
|
9
|
+
} from 'googleapis'
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
GOOGLE_DRIVE_VERSION
|
|
13
|
+
} from '#common/config'
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
hasErrorCode,
|
|
17
|
+
getErrorCode,
|
|
18
|
+
getErrorMessage
|
|
19
|
+
} from '#common/error'
|
|
20
|
+
|
|
21
|
+
import authorize from '#common/authorize'
|
|
22
|
+
|
|
23
|
+
const SCOPES = [
|
|
24
|
+
'https://www.googleapis.com/auth/drive'
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
const log = debug('@sequencemedia/drive/list')
|
|
28
|
+
const error = debug('@sequencemedia/drive/list:error')
|
|
29
|
+
|
|
30
|
+
log('`@sequencemedia/drive` is awake')
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Get a list of the JSON files from Google Drive
|
|
34
|
+
*
|
|
35
|
+
* @param {string} driveId Drive identifier
|
|
36
|
+
* @param {AuthClient} authClient An authorised OAuth2 client
|
|
37
|
+
* @returns {Promise<{id: string, name: string}[]>}
|
|
38
|
+
*/
|
|
39
|
+
async function getJsonFileList (driveId, authClient) {
|
|
40
|
+
try {
|
|
41
|
+
const drive = google.drive({
|
|
42
|
+
version: GOOGLE_DRIVE_VERSION,
|
|
43
|
+
auth: authClient
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
const {
|
|
47
|
+
data: {
|
|
48
|
+
files = []
|
|
49
|
+
}
|
|
50
|
+
} = await drive.files.list({
|
|
51
|
+
supportsAllDrives: true,
|
|
52
|
+
corpora: 'drive',
|
|
53
|
+
includeItemsFromAllDrives: true,
|
|
54
|
+
fields: 'nextPageToken, files(id, name)',
|
|
55
|
+
orderBy: 'createdTime desc',
|
|
56
|
+
driveId
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
return files
|
|
60
|
+
} catch (e) {
|
|
61
|
+
if (hasErrorCode(e)) error(getErrorCode(e))
|
|
62
|
+
error(getErrorMessage(e))
|
|
63
|
+
throw e
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Get a list of the JSON files from Google Drive
|
|
69
|
+
*
|
|
70
|
+
* @param {string} driveId Drive identifier
|
|
71
|
+
* @param {Record<PropertyKey, string | undefined>} keyFile Authorisation
|
|
72
|
+
* @param {string[]} scopes Authorisation scopes
|
|
73
|
+
* @returns {Promise<Array<{id: string, name: string}>>}
|
|
74
|
+
*/
|
|
75
|
+
export default async function getListFromDrive (driveId, keyFile, scopes = SCOPES) {
|
|
76
|
+
return (
|
|
77
|
+
await getJsonFileList(
|
|
78
|
+
driveId,
|
|
79
|
+
await authorize(
|
|
80
|
+
keyFile,
|
|
81
|
+
scopes
|
|
82
|
+
)
|
|
83
|
+
)
|
|
84
|
+
)
|
|
85
|
+
}
|
package/src/index.d.mts
ADDED
package/src/index.mjs
ADDED