sfc-utils 1.4.77 → 1.4.79
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/copy/googleauth.js +52 -39
- package/copy/sheets.js +134 -59
- package/package.json +1 -1
package/copy/googleauth.js
CHANGED
|
@@ -8,49 +8,57 @@ var os = require("os");
|
|
|
8
8
|
var path = require("path");
|
|
9
9
|
var url = require("url");
|
|
10
10
|
var fs = require("fs");
|
|
11
|
-
var writeFile = require(
|
|
11
|
+
var writeFile = require("write");
|
|
12
12
|
|
|
13
13
|
// Prep the service account for drive
|
|
14
|
-
var serviceAccountCreds = path.join(
|
|
14
|
+
var serviceAccountCreds = path.join(
|
|
15
|
+
os.homedir(),
|
|
16
|
+
"service-account-google-creds.json"
|
|
17
|
+
);
|
|
15
18
|
var tokenLocation = path.join(os.homedir(), ".google_oauth_token");
|
|
16
19
|
|
|
17
|
-
var fallbackAuth = function() {
|
|
20
|
+
var fallbackAuth = function () {
|
|
18
21
|
// If it's coming from EC2, pull from project
|
|
19
|
-
if (process.env.GOOGLE_OAUTH_SYSTEM === "EC2"){
|
|
22
|
+
if (process.env.GOOGLE_OAUTH_SYSTEM === "EC2") {
|
|
20
23
|
tokenLocation = "../.google_oauth_token";
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
try {
|
|
24
27
|
var tokens = fs.readFileSync(tokenLocation, "utf-8");
|
|
25
28
|
tokens = JSON.parse(tokens);
|
|
26
|
-
auth = new google.auth.OAuth2(
|
|
29
|
+
auth = new google.auth.OAuth2(
|
|
30
|
+
process.env.GOOGLE_OAUTH_CLIENT_ID,
|
|
31
|
+
process.env.GOOGLE_OAUTH_CONSUMER_SECRET
|
|
32
|
+
);
|
|
27
33
|
auth.setCredentials(tokens);
|
|
28
34
|
|
|
29
|
-
auth.on("tokens", function(update) {
|
|
35
|
+
auth.on("tokens", function (update) {
|
|
30
36
|
Object.assign(tokens, update);
|
|
31
37
|
fs.writeFileSync(tokenLocation, JSON.stringify(tokens, null, 2));
|
|
32
38
|
});
|
|
33
|
-
} catch(err){
|
|
39
|
+
} catch (err) {
|
|
34
40
|
// If we error here, fire up local (as long as we're on on EC2)
|
|
35
|
-
if (process.env.GOOGLE_OAUTH_SYSTEM !== "EC2"){
|
|
36
|
-
task()
|
|
41
|
+
if (process.env.GOOGLE_OAUTH_SYSTEM !== "EC2") {
|
|
42
|
+
task();
|
|
37
43
|
}
|
|
38
44
|
}
|
|
39
45
|
return auth;
|
|
40
|
-
}
|
|
46
|
+
};
|
|
41
47
|
|
|
42
|
-
var authenticate = function({fallback}) {
|
|
43
|
-
if (fallback){
|
|
48
|
+
var authenticate = function ({ fallback }) {
|
|
49
|
+
if (fallback) {
|
|
44
50
|
return new Promise((resolve, reject) => {
|
|
45
|
-
console.log(
|
|
51
|
+
console.log(
|
|
52
|
+
"Service account failed, falling back to regular token (to use the service account, share this sheet or doc with sfchronicle-gatsby@zinc-proton-250521.iam.gserviceaccount.com)"
|
|
53
|
+
);
|
|
46
54
|
resolve(fallbackAuth());
|
|
47
|
-
})
|
|
55
|
+
});
|
|
48
56
|
}
|
|
49
57
|
// Try to use the service account first
|
|
50
58
|
return new Promise((resolve, reject) => {
|
|
51
59
|
try {
|
|
52
60
|
// If it's coming from EC2, pull from project
|
|
53
|
-
if (process.env.GOOGLE_OAUTH_SYSTEM === "EC2"){
|
|
61
|
+
if (process.env.GOOGLE_OAUTH_SYSTEM === "EC2") {
|
|
54
62
|
serviceAccountCreds = "../service-account-google-creds.json";
|
|
55
63
|
}
|
|
56
64
|
|
|
@@ -63,52 +71,56 @@ var authenticate = function({fallback}) {
|
|
|
63
71
|
null,
|
|
64
72
|
serviceAccountJSON.private_key,
|
|
65
73
|
[
|
|
66
|
-
|
|
67
|
-
|
|
74
|
+
"https://www.googleapis.com/auth/spreadsheets",
|
|
75
|
+
"https://www.googleapis.com/auth/drive",
|
|
68
76
|
]
|
|
69
77
|
);
|
|
70
78
|
//authenticate request
|
|
71
79
|
jwtClient.authorize(function (err, tokens) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
+
if (err) {
|
|
81
|
+
console.log("Stage 1 error, fallback auth");
|
|
82
|
+
resolve(fallbackAuth());
|
|
83
|
+
} else {
|
|
84
|
+
console.log("Successfully connected to service account!");
|
|
85
|
+
// Return the jwtClient as auth
|
|
86
|
+
resolve(jwtClient);
|
|
87
|
+
}
|
|
80
88
|
});
|
|
81
|
-
} catch (err){
|
|
89
|
+
} catch (err) {
|
|
82
90
|
// It's ok if it errors, we have the fallback
|
|
83
91
|
console.log("Stage 2 error, fallback auth");
|
|
84
92
|
resolve(fallbackAuth());
|
|
85
93
|
}
|
|
86
|
-
})
|
|
94
|
+
});
|
|
87
95
|
};
|
|
88
96
|
|
|
89
|
-
var task = function() {
|
|
97
|
+
var task = function () {
|
|
90
98
|
// var done = this.async();
|
|
91
99
|
|
|
92
100
|
var clientID = process.env.GOOGLE_OAUTH_CLIENT_ID;
|
|
93
101
|
var secret = process.env.GOOGLE_OAUTH_CONSUMER_SECRET;
|
|
94
102
|
|
|
95
|
-
var client = new google.auth.OAuth2(
|
|
103
|
+
var client = new google.auth.OAuth2(
|
|
104
|
+
clientID,
|
|
105
|
+
secret,
|
|
106
|
+
"http://localhost:8000/authenticate/"
|
|
107
|
+
);
|
|
96
108
|
google.options({
|
|
97
|
-
auth: client
|
|
109
|
+
auth: client,
|
|
98
110
|
});
|
|
99
111
|
|
|
100
112
|
var scopes = [
|
|
101
113
|
"https://www.googleapis.com/auth/drive",
|
|
102
|
-
"https://www.googleapis.com/auth/spreadsheets"
|
|
114
|
+
"https://www.googleapis.com/auth/spreadsheets",
|
|
103
115
|
];
|
|
104
116
|
|
|
105
117
|
var authURL = client.generateAuthUrl({
|
|
106
118
|
access_type: "offline",
|
|
107
119
|
scope: scopes.join(" "),
|
|
108
|
-
prompt: "consent"
|
|
120
|
+
prompt: "consent",
|
|
109
121
|
});
|
|
110
122
|
|
|
111
|
-
var onRequest = function(request, response) {
|
|
123
|
+
var onRequest = function (request, response) {
|
|
112
124
|
response.setHeader("Connection", "close");
|
|
113
125
|
if (request.url.indexOf("authenticate") > -1) {
|
|
114
126
|
return onAuthenticated(request, response);
|
|
@@ -121,15 +133,16 @@ var task = function() {
|
|
|
121
133
|
response.end();
|
|
122
134
|
};
|
|
123
135
|
|
|
124
|
-
var onAuthenticated = async function(request, response) {
|
|
125
|
-
var requestURL =
|
|
136
|
+
var onAuthenticated = async function (request, response) {
|
|
137
|
+
var requestURL =
|
|
138
|
+
request.url[0] == "/" ? "localhost:8000" + request.url : request.url;
|
|
126
139
|
var query = new url.URL(requestURL).searchParams;
|
|
127
140
|
var code = query.get("code");
|
|
128
141
|
if (!code) return;
|
|
129
142
|
try {
|
|
130
143
|
var token = await client.getToken(code);
|
|
131
144
|
var tokens = token.tokens;
|
|
132
|
-
writeFile(tokenLocation, JSON.stringify(tokens, null, 2), function(err) {
|
|
145
|
+
writeFile(tokenLocation, JSON.stringify(tokens, null, 2), function (err) {
|
|
133
146
|
if (err) {
|
|
134
147
|
console.log(err);
|
|
135
148
|
} else {
|
|
@@ -144,10 +157,10 @@ var task = function() {
|
|
|
144
157
|
|
|
145
158
|
var server = http.createServer(onRequest);
|
|
146
159
|
server.listen(8000, () => opn("http://localhost:8000/authorize"));
|
|
147
|
-
}
|
|
160
|
+
};
|
|
148
161
|
|
|
149
162
|
let fullAuth = {
|
|
150
163
|
task: task,
|
|
151
|
-
authenticate: authenticate
|
|
152
|
-
}
|
|
164
|
+
authenticate: authenticate,
|
|
165
|
+
};
|
|
153
166
|
module.exports = fullAuth;
|
package/copy/sheets.js
CHANGED
|
@@ -14,7 +14,7 @@ var writeFile = require("write");
|
|
|
14
14
|
var authObj = require("./googleauth");
|
|
15
15
|
|
|
16
16
|
var cast = function (str, forceStr) {
|
|
17
|
-
if (!forceStr){
|
|
17
|
+
if (!forceStr) {
|
|
18
18
|
if (typeof str !== "string") {
|
|
19
19
|
if (typeof str.value == "string") {
|
|
20
20
|
str = str.value;
|
|
@@ -30,37 +30,45 @@ var cast = function (str, forceStr) {
|
|
|
30
30
|
if (str.toLowerCase() == "true" || str.toLowerCase() == "false") {
|
|
31
31
|
return str.toLowerCase() == "true" ? true : false;
|
|
32
32
|
}
|
|
33
|
-
}
|
|
33
|
+
}
|
|
34
34
|
// To force string, just return string
|
|
35
35
|
|
|
36
36
|
return str;
|
|
37
37
|
};
|
|
38
38
|
|
|
39
39
|
let googleAuth = (project, directory = null, forceStr = false) => {
|
|
40
|
-
return new Promise(resolveFinal => {
|
|
40
|
+
return new Promise((resolveFinal) => {
|
|
41
41
|
var auth = null;
|
|
42
|
-
authObj
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
42
|
+
authObj
|
|
43
|
+
.authenticate({ fallback: false })
|
|
44
|
+
.then((resp) => {
|
|
45
|
+
auth = resp;
|
|
46
|
+
grabSheets(auth, project, directory, forceStr)
|
|
47
|
+
.then(() => resolveFinal())
|
|
48
|
+
.catch(() => {
|
|
49
|
+
// If the first attempt failed, then make another req using the fallback
|
|
50
|
+
authObj.authenticate({ fallback: true }).then((resp) => {
|
|
51
|
+
auth = resp;
|
|
52
|
+
grabSheets(auth, project, directory, forceStr).then(() =>
|
|
53
|
+
resolveFinal()
|
|
54
|
+
);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
})
|
|
58
|
+
.catch(() => {
|
|
59
|
+
// Failure if we fall back but there's no token
|
|
60
|
+
auth = authObj.task();
|
|
61
|
+
grabSheets(auth, project, directory, forceStr).then(() =>
|
|
62
|
+
resolveFinal()
|
|
63
|
+
);
|
|
50
64
|
});
|
|
51
|
-
|
|
52
|
-
.catch(() => {
|
|
53
|
-
// Failure if we fall back but there's no token
|
|
54
|
-
auth = authObj.task();
|
|
55
|
-
grabSheets(auth, project, directory, forceStr).then(() => resolveFinal());
|
|
56
|
-
});
|
|
57
|
-
})
|
|
65
|
+
});
|
|
58
66
|
};
|
|
59
67
|
|
|
60
68
|
let grabSheets = (auth, project, directory, forceStr) => {
|
|
61
69
|
return new Promise((resolveAll, rejectAll) => {
|
|
62
70
|
var sheetKeys = project.GOOGLE_SHEETS;
|
|
63
|
-
if (!sheetKeys){
|
|
71
|
+
if (!sheetKeys) {
|
|
64
72
|
// Try the old way
|
|
65
73
|
sheetKeys = project.sheets;
|
|
66
74
|
}
|
|
@@ -75,7 +83,15 @@ let grabSheets = (auth, project, directory, forceStr) => {
|
|
|
75
83
|
let promiseStack = [];
|
|
76
84
|
for (var spreadsheetId of sheetKeys) {
|
|
77
85
|
let promiseItem = new Promise((resolve, reject) => {
|
|
78
|
-
getSheet(
|
|
86
|
+
getSheet(
|
|
87
|
+
resolve,
|
|
88
|
+
reject,
|
|
89
|
+
auth,
|
|
90
|
+
spreadsheetId,
|
|
91
|
+
directory,
|
|
92
|
+
forceStr,
|
|
93
|
+
project
|
|
94
|
+
);
|
|
79
95
|
});
|
|
80
96
|
promiseStack.push(promiseItem);
|
|
81
97
|
}
|
|
@@ -91,7 +107,15 @@ let grabSheets = (auth, project, directory, forceStr) => {
|
|
|
91
107
|
});
|
|
92
108
|
};
|
|
93
109
|
|
|
94
|
-
let getSheet = async (
|
|
110
|
+
let getSheet = async (
|
|
111
|
+
resolve,
|
|
112
|
+
reject,
|
|
113
|
+
auth,
|
|
114
|
+
spreadsheetId,
|
|
115
|
+
directory,
|
|
116
|
+
forceStr,
|
|
117
|
+
project
|
|
118
|
+
) => {
|
|
95
119
|
let output = await api.spreadsheets
|
|
96
120
|
.get({
|
|
97
121
|
auth,
|
|
@@ -106,52 +130,103 @@ let getSheet = async (resolve, reject, auth, spreadsheetId, directory, forceStr)
|
|
|
106
130
|
}
|
|
107
131
|
var book = output.data;
|
|
108
132
|
var { sheets, spreadsheetId } = book;
|
|
133
|
+
console.log("SHEETS", sheets);
|
|
134
|
+
let languageSwap;
|
|
135
|
+
if (project.LANGUAGE_SWAP) {
|
|
136
|
+
languageSwap = project.LANGUAGE_SWAP;
|
|
137
|
+
}
|
|
138
|
+
console.log("language swap:", languageSwap);
|
|
139
|
+
// Process all other sheets with the language swap
|
|
109
140
|
for (var sheet of sheets) {
|
|
110
141
|
if (sheet.properties.title[0] == "_") continue;
|
|
111
|
-
|
|
142
|
+
await processSheetData(
|
|
112
143
|
auth,
|
|
113
144
|
spreadsheetId,
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
145
|
+
sheet,
|
|
146
|
+
forceStr,
|
|
147
|
+
directory,
|
|
148
|
+
languageSwap
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
resolve("Complete");
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const processSheetData = async (
|
|
155
|
+
auth,
|
|
156
|
+
spreadsheetId,
|
|
157
|
+
sheet,
|
|
158
|
+
forceStr,
|
|
159
|
+
directory,
|
|
160
|
+
languageSwap = null
|
|
161
|
+
) => {
|
|
162
|
+
var response = await api.spreadsheets.values.get({
|
|
163
|
+
auth,
|
|
164
|
+
spreadsheetId,
|
|
165
|
+
range: `${sheet.properties.title}!A:AAA`,
|
|
166
|
+
majorDimension: "ROWS",
|
|
167
|
+
});
|
|
168
|
+
var { values } = response.data;
|
|
169
|
+
var header = values.shift();
|
|
170
|
+
var swapIndexes = [];
|
|
171
|
+
if (languageSwap) {
|
|
172
|
+
for (var i = 0; i < header.length; i++) {
|
|
173
|
+
var lastIndex = header[i].lastIndexOf("_");
|
|
174
|
+
if (lastIndex > -1) {
|
|
175
|
+
// It has an underscore! Check for match
|
|
176
|
+
var substring = header[i].substring(lastIndex + 1).toLowerCase();
|
|
177
|
+
if (substring === languageSwap) {
|
|
178
|
+
// Match! Save the swap index
|
|
179
|
+
swapIndexes.push(i - 1);
|
|
132
180
|
}
|
|
133
|
-
});
|
|
134
|
-
// If only values in row are garbage or blank-ish, skip
|
|
135
|
-
if (rowSkip) continue;
|
|
136
|
-
// Handle actual value
|
|
137
|
-
if (isKeyed) {
|
|
138
|
-
out[obj.key] = isValued ? obj.value : obj;
|
|
139
|
-
} else {
|
|
140
|
-
out.push(obj);
|
|
141
181
|
}
|
|
142
182
|
}
|
|
143
|
-
|
|
144
|
-
//set alternate dir if we have it
|
|
145
|
-
directory = directory || "src/data/";
|
|
146
|
-
var file_path = `${directory}${sheet.properties.title.replace(
|
|
147
|
-
/\s+/g,
|
|
148
|
-
"_"
|
|
149
|
-
)}.sheet.json`;
|
|
150
|
-
console.log(`Saving sheet to ${file_path}`);
|
|
151
|
-
// grunt.file.write(filename, JSON.stringify(out, null, 2));
|
|
152
|
-
writeFile(file_path, JSON.stringify(out, null, 2));
|
|
153
183
|
}
|
|
154
|
-
|
|
184
|
+
var isKeyed = header.indexOf("key") > -1;
|
|
185
|
+
var isValued = header.indexOf("value") > -1;
|
|
186
|
+
var out = isKeyed ? {} : [];
|
|
187
|
+
for (var row of values) {
|
|
188
|
+
// skip blank rows
|
|
189
|
+
if (!row.length) continue;
|
|
190
|
+
var obj = {};
|
|
191
|
+
var rowSkip = true;
|
|
192
|
+
row.forEach(function (value, i) {
|
|
193
|
+
var key = header[i];
|
|
194
|
+
// Handle language swap
|
|
195
|
+
if (swapIndexes.indexOf(i) > -1) {
|
|
196
|
+
// If we have a swap index, swap the value
|
|
197
|
+
// NOTE: This assumes the translation is ALWAYS one cell to the right
|
|
198
|
+
try {
|
|
199
|
+
if (row[i + 1]) {
|
|
200
|
+
value = row[i + 1];
|
|
201
|
+
}
|
|
202
|
+
} catch (err) {
|
|
203
|
+
// Not great but ok
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
obj[key] = cast(value, forceStr);
|
|
207
|
+
if (value && value !== "FALSE") {
|
|
208
|
+
rowSkip = false;
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
// If only values in row are garbage or blank-ish, skip
|
|
212
|
+
if (rowSkip) continue;
|
|
213
|
+
// Handle actual value
|
|
214
|
+
if (isKeyed) {
|
|
215
|
+
out[obj.key] = isValued ? obj.value : obj;
|
|
216
|
+
} else {
|
|
217
|
+
out.push(obj);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
//set alternate dir if we have it
|
|
222
|
+
directory = directory || "src/data/";
|
|
223
|
+
var file_path = `${directory}${sheet.properties.title.replace(
|
|
224
|
+
/\s+/g,
|
|
225
|
+
"_"
|
|
226
|
+
)}.sheet.json`;
|
|
227
|
+
console.log(`Saving sheet to ${file_path}`);
|
|
228
|
+
// grunt.file.write(filename, JSON.stringify(out, null, 2));
|
|
229
|
+
writeFile(file_path, JSON.stringify(out, null, 2));
|
|
155
230
|
};
|
|
156
231
|
|
|
157
232
|
module.exports = { googleAuth };
|