@sequencemedia/drive 0.0.16 → 0.0.18
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 +3 -3
- package/src/installed/index.mjs +149 -0
- package/src/upload/index.mjs +70 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sequencemedia/drive",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.18",
|
|
4
4
|
"main": "./src/index.mjs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./src/index.d.mts",
|
|
@@ -24,11 +24,11 @@
|
|
|
24
24
|
"@babel/core": "^7.26.0",
|
|
25
25
|
"@babel/preset-env": "^7.26.0",
|
|
26
26
|
"@sequencemedia/eslint-config-standard": "^0.2.9",
|
|
27
|
-
"@sequencemedia/eslint-config-typescript": "^0.1.
|
|
27
|
+
"@sequencemedia/eslint-config-typescript": "^0.1.13",
|
|
28
28
|
"@types/debug": "^4.1.12",
|
|
29
29
|
"@types/nconf": "^0.10.7",
|
|
30
30
|
"@types/node": "^22.10.5",
|
|
31
|
-
"core-js": "^3.
|
|
31
|
+
"core-js": "^3.40.0",
|
|
32
32
|
"eslint": "^9.17.0",
|
|
33
33
|
"globals": "^15.14.0",
|
|
34
34
|
"husky": "^9.1.7"
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import('google-auth-library').OAuth2Client} OAuth2Client
|
|
3
|
+
* @typedef {import('google-auth-library').JWTInput} UserRefreshClient
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
readFile,
|
|
8
|
+
writeFile
|
|
9
|
+
} from 'fs/promises'
|
|
10
|
+
import {
|
|
11
|
+
authenticate
|
|
12
|
+
} from '@google-cloud/local-auth'
|
|
13
|
+
import {
|
|
14
|
+
google
|
|
15
|
+
} from 'googleapis'
|
|
16
|
+
|
|
17
|
+
import getKeyFile, {
|
|
18
|
+
getInstalled
|
|
19
|
+
} from '#common/getKeyFile'
|
|
20
|
+
|
|
21
|
+
const KEY_FILE_PATH = './src/installed/key-file.json'
|
|
22
|
+
|
|
23
|
+
// If modifying these scopes, delete user-refresh-client.json.
|
|
24
|
+
const SCOPES = [
|
|
25
|
+
'https://www.googleapis.com/auth/drive.metadata.readonly'
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
// The file user-refresh-client.json stores the user's access and refresh tokens, and is
|
|
29
|
+
// created automatically when the authorization flow completes for the first
|
|
30
|
+
// time.
|
|
31
|
+
const USER_REFRESH_CLIENT_PATH = './user-refresh-client.json'
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Deserialises `UserRefreshClient` from a file
|
|
35
|
+
*
|
|
36
|
+
* @return {Promise<UserRefreshClient | null>}
|
|
37
|
+
*/
|
|
38
|
+
async function getUserRefreshClient () {
|
|
39
|
+
try {
|
|
40
|
+
const fileData = await readFile(USER_REFRESH_CLIENT_PATH)
|
|
41
|
+
return (
|
|
42
|
+
JSON.parse(fileData)
|
|
43
|
+
)
|
|
44
|
+
} catch {
|
|
45
|
+
return null
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Serializes `UserRefreshClient` to a file
|
|
51
|
+
*
|
|
52
|
+
* @param {UserRefreshClient} userRefreshClient
|
|
53
|
+
* @return {Promise<void>}
|
|
54
|
+
*/
|
|
55
|
+
async function setUserRefreshClient (userRefreshClient) {
|
|
56
|
+
const fileData = JSON.stringify(userRefreshClient)
|
|
57
|
+
await writeFile(USER_REFRESH_CLIENT_PATH, fileData)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Transforms `UserRefreshClient` to `OAuth2Client`
|
|
62
|
+
*
|
|
63
|
+
* @param {UserRefreshClient} userRefreshClient
|
|
64
|
+
* @returns {OAuth2Client}
|
|
65
|
+
*/
|
|
66
|
+
function toAuthClient (userRefreshClient) {
|
|
67
|
+
return (
|
|
68
|
+
google.auth.fromJSON(userRefreshClient)
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Transforms `OAuth2Client` to `UserRefreshClient`
|
|
74
|
+
*
|
|
75
|
+
* @param {OAuth2Client} authClient
|
|
76
|
+
* @return {Promise<UserRefreshClient>}
|
|
77
|
+
*/
|
|
78
|
+
async function toUserRefreshClient (credentials, authClient) {
|
|
79
|
+
const {
|
|
80
|
+
client_id: clientId,
|
|
81
|
+
client_secret: clientSecret
|
|
82
|
+
} = credentials
|
|
83
|
+
|
|
84
|
+
const {
|
|
85
|
+
credentials: {
|
|
86
|
+
refresh_token: refreshToken
|
|
87
|
+
}
|
|
88
|
+
} = authClient
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
type: 'authorized_user',
|
|
92
|
+
client_id: clientId,
|
|
93
|
+
client_secret: clientSecret,
|
|
94
|
+
refresh_token: refreshToken
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Load or request or authorization to call APIs.
|
|
100
|
+
*
|
|
101
|
+
* @return {OAuth2Client}
|
|
102
|
+
*/
|
|
103
|
+
async function authorize () {
|
|
104
|
+
const userRefreshClient = await getUserRefreshClient()
|
|
105
|
+
if (userRefreshClient) {
|
|
106
|
+
return (
|
|
107
|
+
toAuthClient(userRefreshClient)
|
|
108
|
+
)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const authClient = await authenticate({
|
|
112
|
+
scopes: SCOPES,
|
|
113
|
+
keyfilePath: KEY_FILE_PATH
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
await setUserRefreshClient(await toUserRefreshClient(getInstalled(await getKeyFile(KEY_FILE_PATH)), authClient))
|
|
117
|
+
|
|
118
|
+
return authClient
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Lists the names and IDs of up to 10 files.
|
|
123
|
+
*
|
|
124
|
+
* @param {OAuth2Client} authClient An authorized OAuth2 client.
|
|
125
|
+
*/
|
|
126
|
+
async function listFiles (authClient) {
|
|
127
|
+
try {
|
|
128
|
+
const drive = google.drive({ version: 'v3', auth: authClient })
|
|
129
|
+
const {
|
|
130
|
+
data: {
|
|
131
|
+
files = []
|
|
132
|
+
}
|
|
133
|
+
} = await drive.files.list({
|
|
134
|
+
pageSize: 10,
|
|
135
|
+
fields: 'nextPageToken, files(id, name)'
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
if (files.length === 0) {
|
|
139
|
+
console.log('No files.')
|
|
140
|
+
return
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
console.table(files)
|
|
144
|
+
} catch (e) {
|
|
145
|
+
console.error(e)
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
authorize().then(listFiles).catch(console.error)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import('google-auth-library').OAuth2Client} OAuth2Client
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
readFile
|
|
7
|
+
} from 'fs/promises'
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
google
|
|
11
|
+
} from 'googleapis'
|
|
12
|
+
|
|
13
|
+
import getKeyFile from '#common/getKeyFile'
|
|
14
|
+
|
|
15
|
+
const KEY_FILE_PATH = './src/upload/key-file.json'
|
|
16
|
+
|
|
17
|
+
const SCOPES = [
|
|
18
|
+
'https://www.googleapis.com/auth/drive.file'
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Authorize with service account and get jwt client
|
|
23
|
+
*
|
|
24
|
+
*/
|
|
25
|
+
async function authorize () {
|
|
26
|
+
const {
|
|
27
|
+
client_email: clientEmail,
|
|
28
|
+
private_key: privateKey
|
|
29
|
+
} = await getKeyFile(KEY_FILE_PATH)
|
|
30
|
+
|
|
31
|
+
const authClient = new google.auth.JWT(
|
|
32
|
+
clientEmail,
|
|
33
|
+
null,
|
|
34
|
+
privateKey,
|
|
35
|
+
SCOPES
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
await authClient.authorize()
|
|
39
|
+
|
|
40
|
+
return authClient
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Create a JSON file in Google Drive
|
|
45
|
+
*
|
|
46
|
+
* @param {string} id JSON file identifier
|
|
47
|
+
* @param {string} body JSON file contents
|
|
48
|
+
* @param {OAuth2Client} authClient An authorized OAuth2 client.
|
|
49
|
+
*/
|
|
50
|
+
async function createJsonFile (id, body, authClient) {
|
|
51
|
+
try {
|
|
52
|
+
const drive = google.drive({ version: 'v3', auth: authClient })
|
|
53
|
+
const response = await drive.files.create({
|
|
54
|
+
fields: 'id',
|
|
55
|
+
requestBody: {
|
|
56
|
+
name: `${id}.json`
|
|
57
|
+
},
|
|
58
|
+
media: {
|
|
59
|
+
mimeType: 'application/json',
|
|
60
|
+
body
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
console.table(response.data)
|
|
65
|
+
} catch (e) {
|
|
66
|
+
console.error(e)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
authorize().then((authClient) => readFile('./src/upload/data.json').then((fileData) => createJsonFile('file-id', fileData.toString('utf8'), authClient))).catch(console.error)
|