@genoacms/adapter-gcp 0.5.2-fix.1 → 0.5.2-fix.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,47 +1,63 @@
1
1
  import config from '../../config.js';
2
2
  import { getBucket } from '../storage/storage.js';
3
3
  import { readdir, lstat } from 'node:fs/promises';
4
- import { createReadStream } from 'node:fs';
4
+ import { createReadStream, createWriteStream } from 'node:fs';
5
5
  import { join } from 'node:path';
6
6
  import { CloudFunctionsServiceClient } from '@google-cloud/functions';
7
+ import archiver from 'archiver';
7
8
  const functionsClient = new CloudFunctionsServiceClient({
8
9
  credentials: config.deployment.credentials
9
10
  });
10
11
  const projectId = config.deployment.projectId;
11
12
  const region = config.deployment.region;
12
- async function uploadDirectory(bucketName, directoryPath, prefix = '') {
13
+ async function uploadFile(bucketName, filePath, destination) {
13
14
  const bucket = getBucket(bucketName);
15
+ const fileStream = createReadStream(filePath);
16
+ const gcsFile = bucket.file(destination);
17
+ await new Promise((resolve, reject) => {
18
+ fileStream
19
+ .pipe(gcsFile.createWriteStream())
20
+ .on('error', reject)
21
+ .on('finish', resolve);
22
+ });
23
+ }
24
+ async function uploadFileOrDirectory(bucketName, path, prefix = '') {
25
+ const isDirectory = (await lstat(path)).isDirectory();
26
+ if (isDirectory) {
27
+ await uploadDirectory(bucketName, path, prefix);
28
+ }
29
+ else {
30
+ await uploadFile(bucketName, path, prefix);
31
+ }
32
+ }
33
+ async function uploadDirectory(bucketName, directoryPath, prefix = '') {
14
34
  const files = await readdir(directoryPath);
35
+ const promises = [];
15
36
  for (const file of files) {
16
37
  const filePath = join(directoryPath, file);
17
38
  const destination = join(prefix, file);
18
- const isFileDirectory = (await lstat(filePath)).isDirectory();
19
- if (isFileDirectory) {
20
- await uploadDirectory(bucketName, filePath, destination);
21
- }
22
- else {
23
- const fileStream = createReadStream(filePath);
24
- const gcsFile = bucket.file(destination);
25
- await new Promise((resolve, reject) => {
26
- fileStream
27
- .pipe(gcsFile.createWriteStream())
28
- .on('error', reject)
29
- .on('finish', resolve);
30
- });
31
- }
39
+ promises.push(uploadFileOrDirectory(bucketName, filePath, destination));
32
40
  }
41
+ await Promise.all(promises);
33
42
  }
34
- async function uploadSourceCode(bucketName, source, dest) {
35
- const bucket = getBucket(bucketName);
36
- const uploadResponse = await bucket.upload(source, {
37
- gzip: true,
38
- destination: dest
43
+ async function zipDirectory(source, out) {
44
+ await new Promise((resolve, reject) => {
45
+ const output = createWriteStream(out);
46
+ const archive = archiver('zip', { zlib: { level: 9 } });
47
+ output.on('close', () => {
48
+ resolve();
49
+ });
50
+ archive.on('error', (err) => {
51
+ reject(err);
52
+ });
53
+ archive.pipe(output);
54
+ archive.directory(source, false);
55
+ archive.finalize();
39
56
  });
40
- const file = uploadResponse[0];
41
- return file.cloudStorageURI.toString();
42
57
  }
43
- async function deployFunction(name, source) {
58
+ async function deployFunction(functionName, source) {
44
59
  const location = functionsClient.locationPath(projectId, region);
60
+ const name = functionsClient.cloudFunctionPath(projectId, region, functionName);
45
61
  const [response] = await functionsClient.createFunction({
46
62
  location,
47
63
  function: {
@@ -60,8 +76,11 @@ async function deployFunction(name, source) {
60
76
  export default async function () {
61
77
  const bucketName = config.storage.defaultBucket;
62
78
  const assetsPath = '.genoacms/deployment/static';
63
- const buildArchivePath = '.genoacms/deployment/build.zip';
79
+ const buildArchiveSrc = '.build.zip';
80
+ const buildArchiveDest = '.genoacms/deployment/build.zip';
81
+ const buildArchiveRef = `gs://${bucketName}/${buildArchiveDest}`;
82
+ await zipDirectory('./build', buildArchiveSrc);
64
83
  await uploadDirectory(bucketName, './static', assetsPath);
65
- const buildArchiveURI = await uploadSourceCode(bucketName, './build', buildArchivePath);
66
- await deployFunction('genoacms', buildArchiveURI);
84
+ await uploadFile(bucketName, buildArchiveSrc, buildArchiveDest);
85
+ await deployFunction('genoacms', buildArchiveRef);
67
86
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@genoacms/adapter-gcp",
3
- "version": "0.5.2-fix.1",
3
+ "version": "0.5.2-fix.5",
4
4
  "description": "Implementation of abstraction layer of GenoaCMS for GCP",
5
5
  "repository": {
6
6
  "type": "git",
@@ -21,9 +21,11 @@
21
21
  "@google-cloud/firestore": "^7.1.0",
22
22
  "@google-cloud/functions": "^3.2.0",
23
23
  "@google-cloud/resource-manager": "^5.1.0",
24
- "@google-cloud/storage": "^7.7.0"
24
+ "@google-cloud/storage": "^7.7.0",
25
+ "archiver": "^7.0.0"
25
26
  },
26
27
  "devDependencies": {
28
+ "@types/archiver": "^6.0.2",
27
29
  "@typescript-eslint/eslint-plugin": "^6.9.0",
28
30
  "eslint": "^8.52.0",
29
31
  "eslint-config-standard-with-typescript": "^39.1.1",
@@ -35,8 +37,8 @@
35
37
  "vitest": "^1.0.4"
36
38
  },
37
39
  "peerDependencies": {
38
- "@sveltejs/adapter-node": "^4.0.1",
39
- "@google-cloud/functions-framework": "^3.3.0"
40
+ "@google-cloud/functions-framework": "^3.3.0",
41
+ "@sveltejs/adapter-node": "^4.0.1"
40
42
  },
41
43
  "files": [
42
44
  "src",
@@ -1,9 +1,10 @@
1
1
  import config from '../../config.js'
2
2
  import { getBucket } from '../storage/storage.js'
3
3
  import { readdir, lstat } from 'node:fs/promises'
4
- import { createReadStream } from 'node:fs'
4
+ import { createReadStream, createWriteStream } from 'node:fs'
5
5
  import { join } from 'node:path'
6
6
  import { CloudFunctionsServiceClient } from '@google-cloud/functions'
7
+ import archiver from 'archiver'
7
8
 
8
9
  const functionsClient = new CloudFunctionsServiceClient({
9
10
  credentials: config.deployment.credentials
@@ -11,43 +12,62 @@ const functionsClient = new CloudFunctionsServiceClient({
11
12
  const projectId = config.deployment.projectId
12
13
  const region = config.deployment.region
13
14
 
14
- async function uploadDirectory (bucketName: string, directoryPath: string, prefix = ''): Promise<void> {
15
+ async function uploadFile (bucketName: string, filePath: string, destination: string): Promise<void> {
15
16
  const bucket = getBucket(bucketName)
17
+ const fileStream = createReadStream(filePath)
18
+ const gcsFile = bucket.file(destination)
19
+
20
+ await new Promise((resolve, reject) => {
21
+ fileStream
22
+ .pipe(gcsFile.createWriteStream())
23
+ .on('error', reject)
24
+ .on('finish', resolve)
25
+ })
26
+ }
27
+
28
+ async function uploadFileOrDirectory (bucketName: string, path: string, prefix = ''): Promise<void> {
29
+ const isDirectory = (await lstat(path)).isDirectory()
30
+ if (isDirectory) {
31
+ await uploadDirectory(bucketName, path, prefix)
32
+ } else {
33
+ await uploadFile(bucketName, path, prefix)
34
+ }
35
+ }
36
+
37
+ async function uploadDirectory (bucketName: string, directoryPath: string, prefix = ''): Promise<void> {
16
38
  const files = await readdir(directoryPath)
39
+ const promises = []
17
40
 
18
41
  for (const file of files) {
19
42
  const filePath = join(directoryPath, file)
20
43
  const destination = join(prefix, file)
21
-
22
- const isFileDirectory = (await lstat(filePath)).isDirectory()
23
- if (isFileDirectory) {
24
- await uploadDirectory(bucketName, filePath, destination)
25
- } else {
26
- const fileStream = createReadStream(filePath)
27
- const gcsFile = bucket.file(destination)
28
-
29
- await new Promise((resolve, reject) => {
30
- fileStream
31
- .pipe(gcsFile.createWriteStream())
32
- .on('error', reject)
33
- .on('finish', resolve)
34
- })
35
- }
44
+ promises.push(uploadFileOrDirectory(bucketName, filePath, destination))
36
45
  }
46
+ await Promise.all(promises)
37
47
  }
38
48
 
39
- async function uploadSourceCode (bucketName: string, source: string, dest: string): Promise<string> {
40
- const bucket = getBucket(bucketName)
41
- const uploadResponse = await bucket.upload(source, {
42
- gzip: true,
43
- destination: dest
49
+ async function zipDirectory (source: string, out: string): Promise<void> {
50
+ await new Promise<void>((resolve, reject) => {
51
+ const output = createWriteStream(out)
52
+ const archive = archiver('zip', { zlib: { level: 9 } })
53
+
54
+ output.on('close', () => {
55
+ resolve()
56
+ })
57
+
58
+ archive.on('error', (err) => {
59
+ reject(err)
60
+ })
61
+
62
+ archive.pipe(output)
63
+ archive.directory(source, false)
64
+ archive.finalize()
44
65
  })
45
- const file = uploadResponse[0]
46
- return file.cloudStorageURI.toString()
47
66
  }
48
67
 
49
- async function deployFunction (name: string, source: string): Promise<void> {
68
+ async function deployFunction (functionName: string, source: string): Promise<void> {
50
69
  const location = functionsClient.locationPath(projectId, region)
70
+ const name = functionsClient.cloudFunctionPath(projectId, region, functionName)
51
71
  const [response] = await functionsClient.createFunction({
52
72
  location,
53
73
  function: {
@@ -67,8 +87,11 @@ async function deployFunction (name: string, source: string): Promise<void> {
67
87
  export default async function (): Promise<void> {
68
88
  const bucketName = config.storage.defaultBucket
69
89
  const assetsPath = '.genoacms/deployment/static'
70
- const buildArchivePath = '.genoacms/deployment/build.zip'
90
+ const buildArchiveSrc = '.build.zip'
91
+ const buildArchiveDest = '.genoacms/deployment/build.zip'
92
+ const buildArchiveRef = `gs://${bucketName}/${buildArchiveDest}`
93
+ await zipDirectory('./build', buildArchiveSrc)
71
94
  await uploadDirectory(bucketName, './static', assetsPath)
72
- const buildArchiveURI = await uploadSourceCode(bucketName, './build', buildArchivePath)
73
- await deployFunction('genoacms', buildArchiveURI)
95
+ await uploadFile(bucketName, buildArchiveSrc, buildArchiveDest)
96
+ await deployFunction('genoacms', buildArchiveRef)
74
97
  }