@pi-r/gcp 0.2.2 → 0.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/client/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getProjectId = exports.createBucketRequest = exports.setPredefinedAcl = exports.setPublicRead = exports.executeBatchQuery = exports.executeQuery = exports.deleteObjectsV2 = exports.deleteObjects = exports.setBucketWebsite = exports.setBucketPolicy = exports.createBucketV2 = exports.createBucket = exports.createDatabaseClient = exports.createStorageClient = exports.validateDatabase = exports.validateStorage = exports.isFirebaseApp = void 0;
3
+ exports.CLOUD_UPLOAD_FROMDISK = exports.getProjectId = exports.createBucketRequest = exports.setPredefinedAcl = exports.setPublicRead = exports.executeBatchQuery = exports.executeQuery = exports.deleteObjectsV2 = exports.deleteObjects = exports.setBucketWebsite = exports.setBucketPolicy = exports.createBucketV2 = exports.createBucket = exports.createDatabaseClient = exports.createStorageClient = exports.validateDatabase = exports.validateStorage = exports.isFirebaseApp = void 0;
4
4
  const path = require("path");
5
+ const storage = require("@google-cloud/storage");
6
+ const firestore = require("@google-cloud/firestore");
5
7
  const util_1 = require("@e-mc/cloud/util");
6
8
  const types_1 = require("@e-mc/types");
7
9
  const Module = require("@e-mc/module");
@@ -61,22 +63,29 @@ async function hasBucket(client) {
61
63
  const [exists] = await client.exists().catch(err => isErrorConflict(err) ? [true] : [false]);
62
64
  return exists;
63
65
  }
64
- function updatePredefinedAcl(acl, values, metadata) {
65
- const { generation, userProject } = metadata;
66
+ function updatePredefinedAcl(acl, values, metadata = {}) {
66
67
  const items = [];
68
+ let projectNumber;
69
+ if ('projectNumber' in metadata || 'defaultObjectAcl' in metadata) {
70
+ let defaultObjectAcl;
71
+ ({ projectNumber, defaultObjectAcl } = metadata);
72
+ if (projectNumber === undefined && (0, types_1.isArray)(defaultObjectAcl)) {
73
+ const target = defaultObjectAcl.find(item => item.projectTeam?.projectNumber);
74
+ if (target !== undefined) {
75
+ projectNumber = target.projectTeam.projectNumber;
76
+ }
77
+ }
78
+ }
67
79
  for (const target of acl.default ? [acl, acl.default] : [acl]) {
68
80
  items.push(...values.map(async (value) => {
69
- if (generation !== undefined) {
70
- value.generation ?? (value.generation = +generation);
71
- }
72
- if (userProject) {
73
- value.userProject || (value.userProject = userProject);
74
- }
75
81
  const entity = await target.get({ entity: value.entity }).catch(() => null);
76
82
  if (entity) {
77
83
  return (0, types_1.isString)(value.role) ? target.update(value) : target.delete(value);
78
84
  }
79
85
  if ((0, types_1.isString)(value.role)) {
86
+ if (projectNumber !== undefined) {
87
+ value.userProject || (value.userProject = projectNumber.toString());
88
+ }
80
89
  return target.add(value);
81
90
  }
82
91
  }));
@@ -99,8 +108,8 @@ function setUniformBucketLevel(bucket, enabled) {
99
108
  const getFirebasePackageName = (credential) => credential.apiKey && credential.authDomain ? 'firebase' : 'firebase-admin';
100
109
  const hasKeyFile = (credential) => !!(credential.keyFile || credential.keyFilename || process.env.GOOGLE_APPLICATION_CREDENTIALS);
101
110
  const isErrorConflict = (err) => (err instanceof Error) && err.code === 409;
102
- function isFirebaseApp(credential, storage, admin) {
103
- return !!(credential.apiKey && credential.authDomain && (storage || credential.databaseURL) || credential.product === 'firebase' && process.env.GOOGLE_APPLICATION_CREDENTIALS) && (!admin || !credential.admin);
111
+ function isFirebaseApp(credential, store, admin) {
112
+ return !!(credential.apiKey && credential.authDomain && (store || credential.databaseURL) || credential.product === 'firebase' && process.env.GOOGLE_APPLICATION_CREDENTIALS) && (!admin || !credential.admin);
104
113
  }
105
114
  exports.isFirebaseApp = isFirebaseApp;
106
115
  function validateStorage(credential) {
@@ -112,59 +121,60 @@ function validateDatabase(credential, data) {
112
121
  }
113
122
  exports.validateDatabase = validateDatabase;
114
123
  function createStorageClient(credential, bucket) {
115
- let packageName = '';
116
- try {
117
- if (isFirebaseApp(credential, true)) {
124
+ if (isFirebaseApp(credential, true)) {
125
+ let packageName = '';
126
+ try {
118
127
  if (bucket) {
119
128
  credential.storageBucket = bucket;
120
129
  }
121
130
  packageName = getFirebasePackageName(credential);
122
131
  return getApp(credential, false);
123
132
  }
124
- credential.projectId || (credential.projectId = getProjectId(credential));
125
- const { Storage } = require(packageName = '@google-cloud/storage');
126
- return new Storage(credential);
127
- }
128
- catch (err) {
129
- this.checkPackage(err, packageName, { passThrough: true });
130
- throw err;
133
+ catch (err) {
134
+ this.checkPackage(err, packageName, { passThrough: true });
135
+ throw err;
136
+ }
131
137
  }
138
+ credential.projectId || (credential.projectId = getProjectId(credential));
139
+ return new storage.Storage(credential);
132
140
  }
133
141
  exports.createStorageClient = createStorageClient;
134
142
  function createDatabaseClient(credential, data) {
135
143
  let packageName = '';
136
144
  try {
137
- const product = data?.product;
145
+ let product, name, table;
146
+ if (data) {
147
+ ({ product, name, table } = data);
148
+ }
138
149
  if (product === 'firebase' || isFirebaseApp(credential)) {
139
150
  packageName = getFirebasePackageName(credential);
140
151
  return getApp(credential, true);
141
152
  }
142
153
  credential.projectId || (credential.projectId = getProjectId(credential));
143
154
  if (data) {
144
- if (product === 'spanner' || !product && data.name && data.database) {
155
+ if (product === 'spanner' || !product && name && data.database) {
145
156
  const { Spanner } = require(packageName = '@google-cloud/spanner');
146
157
  return new Spanner(credential);
147
158
  }
148
- if (product === 'bigtable' || !product && data.name && data.table) {
159
+ if (product === 'bigtable' || !product && name && table) {
149
160
  const { Bigtable } = require(packageName = '@google-cloud/bigtable');
150
161
  return new Bigtable(credential);
151
162
  }
152
- if (product === 'bigquery' || !product && !data.table && typeof data.query === 'string') {
163
+ if (product === 'bigquery' || !product && !table && typeof data.query === 'string') {
153
164
  const { BigQuery } = require(packageName = '@google-cloud/bigquery');
154
165
  return new BigQuery(credential);
155
166
  }
156
- if (product === 'datastore' || !product && !data.table && (data.keys || data.query)) {
167
+ if (product === 'datastore' || !product && !table && (data.keys || data.query)) {
157
168
  const { Datastore } = require(packageName = '@google-cloud/datastore');
158
169
  return new Datastore(credential);
159
170
  }
160
171
  }
161
- const { Firestore } = require(packageName = '@google-cloud/firestore');
162
- return new Firestore(credential);
163
172
  }
164
173
  catch (err) {
165
174
  this.checkPackage(err, packageName, { passThrough: true });
166
175
  throw err;
167
176
  }
177
+ return new firestore.Firestore(credential);
168
178
  }
169
179
  exports.createDatabaseClient = createDatabaseClient;
170
180
  async function createBucket(credential, bucket, publicRead, service = 'gcp') {
@@ -175,14 +185,14 @@ async function createBucketV2(credential, bucket, acl, options, service = 'gcp')
175
185
  if (isFirebaseApp(credential, true, true)) {
176
186
  return false;
177
187
  }
178
- const storage = createStorageClient.call(this, credential, bucket);
179
- if (await hasBucket(storage.bucket(bucket))) {
188
+ const instance = createStorageClient.call(this, credential, bucket);
189
+ if (await hasBucket(instance.bucket(bucket))) {
180
190
  if (acl) {
181
191
  await setBucketPolicy.call(this, credential, bucket, { acl }, service);
182
192
  }
183
193
  return true;
184
194
  }
185
- return storage.createBucket(bucket, options)
195
+ return instance.createBucket(bucket, options)
186
196
  .then(async ([target]) => {
187
197
  this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, ["Bucket created" /* VAL_CLOUD.CREATE_BUCKET */, bucket], '', { ...Cloud.LOG_CLOUD_COMMAND });
188
198
  if (acl) {
@@ -205,7 +215,7 @@ async function setBucketPolicy(credential, bucket, options, service = 'gcp') {
205
215
  }
206
216
  const client = createStorageClient.call(this, credential, bucket).bucket(bucket);
207
217
  if (!await hasBucket(client)) {
208
- this.formatFail(64 /* LOG_TYPE.CLOUD */, service, ["Bucket does not exist" /* ERR_CLOUD.EXISTS_BUCKET */, bucket], (0, util_1.formatError)(service, "Bucket does not exist" /* ERR_CLOUD.EXISTS_BUCKET */), { ...Cloud.LOG_CLOUD_FAIL, fatal: false });
218
+ this.formatFail(64 /* LOG_TYPE.CLOUD */, service, ["Bucket does not exist" /* ERR_CLOUD.EXISTS_BUCKET */, bucket], (0, types_1.errorMessage)(service, "Bucket does not exist" /* ERR_CLOUD.EXISTS_BUCKET */), { ...Cloud.LOG_CLOUD_FAIL, fatal: false });
209
219
  return false;
210
220
  }
211
221
  const errors = [];
@@ -216,7 +226,7 @@ async function setBucketPolicy(credential, bucket, options, service = 'gcp') {
216
226
  case 'private':
217
227
  case 'projectPrivate':
218
228
  await client.makePrivate(options).catch(err => !isErrorConflict(err) && errors.push(err));
219
- await setPredefinedAcl.call(this, client.acl, acl, client, '', options.bucket?.metadata);
229
+ await setPredefinedAcl.call(this, client.acl, acl, client, '', options.bucket?.metadata).catch(err => errors.push(err));
220
230
  break;
221
231
  case 'authenticatedRead':
222
232
  await client.makePublic(options).catch(err => !isErrorConflict(err) && errors.push(err));
@@ -243,7 +253,7 @@ async function setBucketPolicy(credential, bucket, options, service = 'gcp') {
243
253
  }
244
254
  }
245
255
  if (options.acl && (options.acl = options.acl.filter(user => (0, types_1.isString)(user.entity))).length) {
246
- errors.push(...await updatePredefinedAcl(client.acl, options.acl, options));
256
+ errors.push(...await updatePredefinedAcl(client.acl, options.acl, options.metadata));
247
257
  }
248
258
  if (errors.length) {
249
259
  this.formatFail(64 /* LOG_TYPE.CLOUD */, service, ["Unable to update bucket policy" /* ERR_CLOUD.POLICY_BUCKET */, bucket], errors[0], { ...Cloud.LOG_CLOUD_FAIL, fatal: false });
@@ -258,11 +268,12 @@ function setBucketWebsite(credential, bucket, options, service = 'gcp') {
258
268
  return Promise.resolve(false);
259
269
  }
260
270
  const website = {};
261
- if ((0, types_1.isString)(options.indexPage)) {
262
- website.mainPageSuffix = options.indexPage;
271
+ const { indexPage, errorPage } = options;
272
+ if ((0, types_1.isString)(indexPage)) {
273
+ website.mainPageSuffix = indexPage;
263
274
  }
264
- if ((0, types_1.isString)(options.errorPage)) {
265
- website.notFoundPage = options.errorPage;
275
+ if ((0, types_1.isString)(errorPage)) {
276
+ website.notFoundPage = errorPage;
266
277
  }
267
278
  return createStorageClient.call(this, credential, bucket).bucket(bucket).setMetadata({ website })
268
279
  .then(() => {
@@ -280,7 +291,7 @@ function deleteObjects(credential, Bucket, service) {
280
291
  }
281
292
  exports.deleteObjects = deleteObjects;
282
293
  async function deleteObjectsV2(credential, bucket, recursive = true, service = 'gcp') {
283
- const storage = createStorageClient.call(this, credential, bucket);
294
+ const instance = createStorageClient.call(this, credential, bucket);
284
295
  const errors = [];
285
296
  let promise;
286
297
  if (isFirebaseApp(credential, true, true)) {
@@ -288,7 +299,7 @@ async function deleteObjectsV2(credential, bucket, recursive = true, service = '
288
299
  const files = [];
289
300
  await (async function recurse(prefix) {
290
301
  try {
291
- const { items, prefixes } = await listAll(ref(storage, prefix));
302
+ const { items, prefixes } = await listAll(ref(instance, prefix));
292
303
  if (items.length) {
293
304
  files.push(...items.map(value => value.fullPath));
294
305
  }
@@ -303,11 +314,11 @@ async function deleteObjectsV2(credential, bucket, recursive = true, service = '
303
314
  }
304
315
  })('');
305
316
  if (files.length) {
306
- promise = Promise.allSettled(files.map(value => deleteObject(ref(storage, value))));
317
+ promise = Promise.allSettled(files.map(value => deleteObject(ref(instance, value))));
307
318
  }
308
319
  }
309
320
  else {
310
- const client = storage.bucket(bucket);
321
+ const client = instance.bucket(bucket);
311
322
  if (await hasBucket(client)) {
312
323
  if (recursive) {
313
324
  return client.deleteFiles({ force: true }).then(() => this.formatMessage(64 /* LOG_TYPE.CLOUD */, service, "Bucket emptied" /* VAL_CLOUD.EMPTY_BUCKET */ + ' (recursive)', bucket, { ...Cloud.LOG_CLOUD_COMMAND }));
@@ -373,9 +384,7 @@ async function executeBatchQuery(credential, batch, sessionKey) {
373
384
  };
374
385
  const closeClient = () => {
375
386
  const fs = clients[3 /* DB.FIRESTORE */];
376
- if (fs) {
377
- fs.terminate();
378
- }
387
+ fs?.terminate();
379
388
  };
380
389
  const getFamily = (data, row, family) => {
381
390
  const familyData = data[family];
@@ -518,29 +527,30 @@ async function executeBatchQuery(credential, batch, sessionKey) {
518
527
  if ((0, types_1.isArray)(orderBy)) {
519
528
  const sort = require('@firebase/database');
520
529
  for (const items of orderBy) {
521
- if ((0, types_1.isArray)(items)) {
522
- const method = items[0];
523
- switch (method) {
524
- case 'orderByChild':
525
- constraints.push(sort.orderByChild(items[1]));
526
- break;
527
- case 'orderByKey':
528
- case 'orderByValue':
529
- case 'orderByPriority':
530
- constraints.push(sort[method]());
531
- break;
532
- case 'limitToFirst':
533
- case 'limitToLast':
534
- constraints.push(sort[method](limiter = +items[1]));
535
- break;
536
- case 'startAt':
537
- case 'startAfter':
538
- case 'endAt':
539
- case 'endBefore':
540
- case 'equalTo':
541
- constraints.push(sort[method](items[1], items[2]));
542
- break;
543
- }
530
+ if (!(0, types_1.isArray)(items)) {
531
+ continue;
532
+ }
533
+ const method = items[0];
534
+ switch (method) {
535
+ case 'orderByChild':
536
+ constraints.push(sort.orderByChild(items[1]));
537
+ break;
538
+ case 'orderByKey':
539
+ case 'orderByValue':
540
+ case 'orderByPriority':
541
+ constraints.push(sort[method]());
542
+ break;
543
+ case 'limitToFirst':
544
+ case 'limitToLast':
545
+ constraints.push(sort[method](limiter = +items[1]));
546
+ break;
547
+ case 'startAt':
548
+ case 'startAfter':
549
+ case 'endAt':
550
+ case 'endBefore':
551
+ case 'equalTo':
552
+ constraints.push(sort[method](items[1], items[2]));
553
+ break;
544
554
  }
545
555
  }
546
556
  }
@@ -586,21 +596,22 @@ async function executeBatchQuery(credential, batch, sessionKey) {
586
596
  else {
587
597
  const task = db.createQuery(item.kind);
588
598
  for (const args of query) {
589
- if ((0, types_1.isArray)(args)) {
590
- const method = args[0];
591
- switch (method) {
592
- case 'end':
593
- case 'filter':
594
- case 'groupBy':
595
- case 'hasAncestor':
596
- case 'limit':
597
- case 'offset':
598
- case 'order':
599
- case 'select':
600
- case 'start':
601
- task[method].apply(task, args.slice(1)); // eslint-disable-line prefer-spread
602
- break;
603
- }
599
+ if (!(0, types_1.isArray)(args)) {
600
+ continue;
601
+ }
602
+ const method = args[0];
603
+ switch (method) {
604
+ case 'end':
605
+ case 'filter':
606
+ case 'groupBy':
607
+ case 'hasAncestor':
608
+ case 'limit':
609
+ case 'offset':
610
+ case 'order':
611
+ case 'select':
612
+ case 'start':
613
+ task[method].apply(task, args.slice(1)); // eslint-disable-line prefer-spread
614
+ break;
604
615
  }
605
616
  }
606
617
  if (limit > 0) {
@@ -641,23 +652,24 @@ async function executeBatchQuery(credential, batch, sessionKey) {
641
652
  }
642
653
  let db = createClient(item, 3 /* DB.FIRESTORE */).collection(table);
643
654
  for (const args of query) {
644
- if ((0, types_1.isArray)(args)) {
645
- const method = args[0];
646
- switch (method) {
647
- case 'endAt':
648
- case 'endBefore':
649
- case 'limit':
650
- case 'limitToLast':
651
- case 'offset':
652
- case 'orderBy':
653
- case 'select':
654
- case 'startAfter':
655
- case 'startAt':
656
- case 'where':
657
- case 'withConverter':
658
- db = db[method].apply(db, args.slice(1)); // eslint-disable-line prefer-spread
659
- break;
660
- }
655
+ if (!(0, types_1.isArray)(args)) {
656
+ continue;
657
+ }
658
+ const method = args[0];
659
+ switch (method) {
660
+ case 'endAt':
661
+ case 'endBefore':
662
+ case 'limit':
663
+ case 'limitToLast':
664
+ case 'offset':
665
+ case 'orderBy':
666
+ case 'select':
667
+ case 'startAfter':
668
+ case 'startAt':
669
+ case 'where':
670
+ case 'withConverter':
671
+ db = db[method].apply(db, args.slice(1)); // eslint-disable-line prefer-spread
672
+ break;
661
673
  }
662
674
  }
663
675
  if ((0, types_1.isArray)(orderBy)) {
@@ -722,25 +734,19 @@ async function setPredefinedAcl(target, value, bucket, pathname = '', metadata =
722
734
  items = [];
723
735
  }
724
736
  else {
725
- if (bucket) {
726
- const [users] = await bucket.acl.get().catch(() => [[]]);
727
- acl = Array.isArray(users) ? users : [users];
728
- }
729
- else {
730
- acl = [];
731
- }
737
+ acl = bucket ? [(await bucket.acl.get())[1]] : [];
732
738
  items = [{ entity: 'allUsers' }, { entity: 'allAuthenticatedUsers' }];
733
739
  }
734
740
  switch (value) {
735
741
  case 'private': {
736
- const owners = new Set(acl.filter(item => item.role === 'OWNER').map(item => item.entity));
742
+ const owners = new Set(acl.filter(item => item.role === 'OWNER' && item.entity).map(item => item.entity));
737
743
  if (owner) {
738
744
  owners.add(owner);
739
745
  }
740
746
  if (owners.size) {
741
747
  for (const user of acl) {
742
748
  const entity = user.entity;
743
- if (!owners.has(entity)) {
749
+ if (entity && !owners.has(entity)) {
744
750
  items.push({ entity });
745
751
  }
746
752
  }
@@ -750,19 +756,18 @@ async function setPredefinedAcl(target, value, bucket, pathname = '', metadata =
750
756
  case 'projectPrivate':
751
757
  for (const user of acl) {
752
758
  const entity = user.entity;
753
- if (entity.startsWith('project-')) {
754
- items.push({ ...user, role: entity.startsWith('project-editors-') || entity.startsWith('project-owners-') ? 'OWNER' : 'READER' });
755
- }
756
- else {
757
- items.push({ ...user, role: undefined });
759
+ if (entity) {
760
+ const role = entity.startsWith('project-') ? entity.startsWith('project-editors-') || entity.startsWith('project-owners-') ? 'OWNER' : 'READER' : '';
761
+ items.push({ entity, role });
758
762
  }
759
763
  }
760
764
  break;
761
765
  case 'bucketOwnerRead':
762
766
  if (bucket && owner) {
763
767
  for (const user of acl) {
764
- if (user.entity !== owner) {
765
- items.push({ entity: user.entity, role: 'READER' });
768
+ const entity = user.entity;
769
+ if (entity && entity !== owner) {
770
+ items.push({ entity, role: 'READER' });
766
771
  }
767
772
  }
768
773
  }
@@ -791,6 +796,7 @@ function createBucketRequest(credential) {
791
796
  for (const attr in credential) {
792
797
  switch (attr) {
793
798
  case 'archive':
799
+ case 'autoclass':
794
800
  case 'coldline':
795
801
  case 'cors':
796
802
  case 'customPlacementConfig':
@@ -828,3 +834,4 @@ function getProjectId(credential) {
828
834
  return '';
829
835
  }
830
836
  exports.getProjectId = getProjectId;
837
+ exports.CLOUD_UPLOAD_FROMDISK = true;
package/download/index.js CHANGED
@@ -3,10 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const path = require("path");
4
4
  const fs = require("fs");
5
5
  const https = require("https");
6
- const client_1 = require("../client");
7
6
  const types_1 = require("@e-mc/types");
8
7
  const Module = require("@e-mc/module");
9
8
  const Cloud = require("@e-mc/cloud");
9
+ const client_1 = require("../client");
10
10
  function download(credential, service = 'gcp') {
11
11
  const storage = client_1.createStorageClient.call(this, credential);
12
12
  return (data, callback) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-r/gcp",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "description": "Google (GCP) cloud functions for E-mc.",
5
5
  "main": "client/index.js",
6
6
  "publishConfig": {
@@ -20,10 +20,10 @@
20
20
  "license": "MIT",
21
21
  "homepage": "https://github.com/anpham6/pi-r#readme",
22
22
  "dependencies": {
23
- "@e-mc/cloud": "^0.5.3",
24
- "@e-mc/module": "^0.5.3",
25
- "@e-mc/types": "^0.5.3",
26
- "@google-cloud/firestore": "^6.5.0",
27
- "@google-cloud/storage": "^6.10.1"
23
+ "@e-mc/cloud": "^0.6.0",
24
+ "@e-mc/module": "^0.6.0",
25
+ "@e-mc/types": "^0.6.0",
26
+ "@google-cloud/firestore": "^6.7.0",
27
+ "@google-cloud/storage": "^7.0.0"
28
28
  }
29
29
  }
package/upload/index.js CHANGED
@@ -2,11 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const path = require("path");
4
4
  const fs = require("fs");
5
- const client_1 = require("../client");
6
5
  const util_1 = require("@e-mc/cloud/util");
7
6
  const types_1 = require("@e-mc/types");
8
7
  const Module = require("@e-mc/module");
9
8
  const Cloud = require("@e-mc/cloud");
9
+ const client_1 = require("../client");
10
10
  const BUCKET_SESSION = new Set();
11
11
  const BUCKET_RESPONSE = {};
12
12
  const getBucketKey = (credential, bucket, acl = '') => Module.asString(credential, true) + bucket + '_' + acl;