@genoacms/adapter-gcp 0.4.2 → 0.5.2-fix.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ export default function (): Promise<void>;
@@ -0,0 +1,78 @@
1
+ import config from '../../config.js';
2
+ import { getBucket } from '../storage/storage.js';
3
+ import { readdir, lstat } from 'node:fs/promises';
4
+ import { createReadStream, createWriteStream } from 'node:fs';
5
+ import { join } from 'node:path';
6
+ import { CloudFunctionsServiceClient } from '@google-cloud/functions';
7
+ import archiver from 'archiver';
8
+ const functionsClient = new CloudFunctionsServiceClient({
9
+ credentials: config.deployment.credentials
10
+ });
11
+ const projectId = config.deployment.projectId;
12
+ const region = config.deployment.region;
13
+ async function uploadDirectory(bucketName, directoryPath, prefix = '') {
14
+ const bucket = getBucket(bucketName);
15
+ const files = await readdir(directoryPath);
16
+ for (const file of files) {
17
+ const filePath = join(directoryPath, file);
18
+ const destination = join(prefix, file);
19
+ const isFileDirectory = (await lstat(filePath)).isDirectory();
20
+ if (isFileDirectory) {
21
+ await uploadDirectory(bucketName, filePath, destination);
22
+ }
23
+ else {
24
+ const fileStream = createReadStream(filePath);
25
+ const gcsFile = bucket.file(destination);
26
+ await new Promise((resolve, reject) => {
27
+ fileStream
28
+ .pipe(gcsFile.createWriteStream())
29
+ .on('error', reject)
30
+ .on('finish', resolve);
31
+ });
32
+ }
33
+ }
34
+ }
35
+ async function zipDirectory(source, out) {
36
+ await new Promise((resolve, reject) => {
37
+ const output = createWriteStream(out);
38
+ const archive = archiver('zip', { zlib: { level: 9 } });
39
+ output.on('close', () => {
40
+ resolve();
41
+ });
42
+ archive.on('error', (err) => {
43
+ reject(err);
44
+ });
45
+ archive.pipe(output);
46
+ archive.directory(source, false);
47
+ archive.finalize();
48
+ });
49
+ }
50
+ async function deployFunction(functionName, source) {
51
+ const location = functionsClient.locationPath(projectId, region);
52
+ const name = functionsClient.cloudFunctionPath(projectId, region, functionName);
53
+ const [response] = await functionsClient.createFunction({
54
+ location,
55
+ function: {
56
+ name,
57
+ sourceUploadUrl: source,
58
+ entryPoint: 'handler',
59
+ runtime: 'nodejs20',
60
+ httpsTrigger: {},
61
+ environmentVariables: {
62
+ NODE_ENV: 'production'
63
+ }
64
+ }
65
+ }, {});
66
+ console.log(response);
67
+ }
68
+ export default async function () {
69
+ const bucketName = config.storage.defaultBucket;
70
+ const assetsPath = '.genoacms/deployment/static';
71
+ const buildArchiveSrc = '.build.zip';
72
+ const buildArchiveDest = '.genoacms/deployment/build.zip';
73
+ const buildArchiveRef = `gs://${bucketName}/${buildArchiveDest}`;
74
+ await zipDirectory('./build', buildArchiveSrc);
75
+ await uploadDirectory(bucketName, './static', assetsPath);
76
+ await uploadDirectory(bucketName, buildArchiveSrc, buildArchiveDest);
77
+ await deployFunction('genoacms', buildArchiveRef);
78
+ }
@@ -0,0 +1,4 @@
1
+ import type { Adapter } from '@genoacms/cloudabstraction/deployment';
2
+ declare const svelteKitAdapter: Adapter.svelteKitAdapter;
3
+ declare const deployProcedure: Adapter.deployProcedure;
4
+ export { svelteKitAdapter, deployProcedure };
@@ -0,0 +1,6 @@
1
+ const svelteKitAdapter = '@sveltejs/adapter-node';
2
+ const deployProcedure = async () => {
3
+ const deploy = (await import('./deploy.js')).default;
4
+ await deploy();
5
+ };
6
+ export { svelteKitAdapter, deployProcedure };
@@ -1,14 +1,4 @@
1
- import { Storage } from '@google-cloud/storage';
2
- import config from '../../config.js';
3
- const storage = new Storage({
4
- credentials: config.storage.credentials
5
- });
6
- const getBucket = (name) => {
7
- if (!config.storage.buckets.includes(name))
8
- throw new Error('bucket-unregistered');
9
- const bucket = storage.bucket(name);
10
- return bucket;
11
- };
1
+ import { getBucket } from './storage.js';
12
2
  const getObject = async ({ bucket, name }) => {
13
3
  const bucketInstance = getBucket(bucket);
14
4
  const file = bucketInstance.file(name);
@@ -32,10 +22,10 @@ const getSignedURL = async ({ bucket, name }) => {
32
22
  });
33
23
  return url;
34
24
  };
35
- const uploadObject = async ({ bucket, name }, stream) => {
25
+ const uploadObject = async ({ bucket, name }, stream, options) => {
36
26
  const bucketInstance = getBucket(bucket);
37
27
  const file = bucketInstance.file(name);
38
- await file.save(stream);
28
+ await file.save(stream, options);
39
29
  };
40
30
  const deleteObject = async ({ bucket, name }) => {
41
31
  const bucketInstance = getBucket(bucket);
@@ -0,0 +1,3 @@
1
+ import { type Bucket } from '@google-cloud/storage';
2
+ declare const getBucket: (name: string) => Bucket;
3
+ export { getBucket };
@@ -0,0 +1,12 @@
1
+ import config from '../../config.js';
2
+ import { Storage } from '@google-cloud/storage';
3
+ const storage = new Storage({
4
+ credentials: config.storage.credentials
5
+ });
6
+ const getBucket = (name) => {
7
+ if (!config.storage.buckets.includes(name))
8
+ throw new Error('bucket-unregistered');
9
+ const bucket = storage.bucket(name);
10
+ return bucket;
11
+ };
12
+ export { getBucket };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@genoacms/adapter-gcp",
3
- "version": "0.4.2",
3
+ "version": "0.5.2-fix.2",
4
4
  "description": "Implementation of abstraction layer of GenoaCMS for GCP",
5
5
  "repository": {
6
6
  "type": "git",
@@ -17,12 +17,15 @@
17
17
  "homepage": "https://github.com/GenoaCMS/adapter-gcp#readme",
18
18
  "type": "module",
19
19
  "dependencies": {
20
- "@genoacms/cloudabstraction": "0.4.2-fix.2",
20
+ "@genoacms/cloudabstraction": "^0.5.2",
21
21
  "@google-cloud/firestore": "^7.1.0",
22
+ "@google-cloud/functions": "^3.2.0",
22
23
  "@google-cloud/resource-manager": "^5.1.0",
23
- "@google-cloud/storage": "^7.7.0"
24
+ "@google-cloud/storage": "^7.7.0",
25
+ "archiver": "^7.0.0"
24
26
  },
25
27
  "devDependencies": {
28
+ "@types/archiver": "^6.0.2",
26
29
  "@typescript-eslint/eslint-plugin": "^6.9.0",
27
30
  "eslint": "^8.52.0",
28
31
  "eslint-config-standard-with-typescript": "^39.1.1",
@@ -33,6 +36,10 @@
33
36
  "typescript": "^5.2.2",
34
37
  "vitest": "^1.0.4"
35
38
  },
39
+ "peerDependencies": {
40
+ "@google-cloud/functions-framework": "^3.3.0",
41
+ "@sveltejs/adapter-node": "^4.0.1"
42
+ },
36
43
  "files": [
37
44
  "src",
38
45
  "dist"
@@ -46,6 +53,10 @@
46
53
  "import": "./dist/services/database/index.js",
47
54
  "types": "./dist/services/database/index.d.ts"
48
55
  },
56
+ "./deployment": {
57
+ "import": "./dist/services/deployment/index.js",
58
+ "types": "./dist/services/deployment/index.d.ts"
59
+ },
49
60
  "./storage": {
50
61
  "import": "./dist/services/storage/index.js",
51
62
  "types": "./dist/services/storage/index.d.ts"
@@ -0,0 +1,8 @@
1
+ import { HttpFunction } from '@google-cloud/functions-framework'
2
+ import app from './build'
3
+
4
+ const svelteKitApp = HttpFunction(app.handler)
5
+
6
+ export {
7
+ svelteKitApp
8
+ }
@@ -0,0 +1,88 @@
1
+ import config from '../../config.js'
2
+ import { getBucket } from '../storage/storage.js'
3
+ import { readdir, lstat } from 'node:fs/promises'
4
+ import { createReadStream, createWriteStream } from 'node:fs'
5
+ import { join } from 'node:path'
6
+ import { CloudFunctionsServiceClient } from '@google-cloud/functions'
7
+ import archiver from 'archiver'
8
+
9
+ const functionsClient = new CloudFunctionsServiceClient({
10
+ credentials: config.deployment.credentials
11
+ })
12
+ const projectId = config.deployment.projectId
13
+ const region = config.deployment.region
14
+
15
+ async function uploadDirectory (bucketName: string, directoryPath: string, prefix = ''): Promise<void> {
16
+ const bucket = getBucket(bucketName)
17
+ const files = await readdir(directoryPath)
18
+
19
+ for (const file of files) {
20
+ const filePath = join(directoryPath, file)
21
+ const destination = join(prefix, file)
22
+
23
+ const isFileDirectory = (await lstat(filePath)).isDirectory()
24
+ if (isFileDirectory) {
25
+ await uploadDirectory(bucketName, filePath, destination)
26
+ } else {
27
+ const fileStream = createReadStream(filePath)
28
+ const gcsFile = bucket.file(destination)
29
+
30
+ await new Promise((resolve, reject) => {
31
+ fileStream
32
+ .pipe(gcsFile.createWriteStream())
33
+ .on('error', reject)
34
+ .on('finish', resolve)
35
+ })
36
+ }
37
+ }
38
+ }
39
+
40
+ async function zipDirectory (source: string, out: string): Promise<void> {
41
+ await new Promise<void>((resolve, reject) => {
42
+ const output = createWriteStream(out)
43
+ const archive = archiver('zip', { zlib: { level: 9 } })
44
+
45
+ output.on('close', () => {
46
+ resolve()
47
+ })
48
+
49
+ archive.on('error', (err) => {
50
+ reject(err)
51
+ })
52
+
53
+ archive.pipe(output)
54
+ archive.directory(source, false)
55
+ archive.finalize()
56
+ })
57
+ }
58
+
59
+ async function deployFunction (functionName: string, source: string): Promise<void> {
60
+ const location = functionsClient.locationPath(projectId, region)
61
+ const name = functionsClient.cloudFunctionPath(projectId, region, functionName)
62
+ const [response] = await functionsClient.createFunction({
63
+ location,
64
+ function: {
65
+ name,
66
+ sourceUploadUrl: source,
67
+ entryPoint: 'handler',
68
+ runtime: 'nodejs20',
69
+ httpsTrigger: {},
70
+ environmentVariables: {
71
+ NODE_ENV: 'production'
72
+ }
73
+ }
74
+ }, {})
75
+ console.log(response)
76
+ }
77
+
78
+ export default async function (): Promise<void> {
79
+ const bucketName = config.storage.defaultBucket
80
+ const assetsPath = '.genoacms/deployment/static'
81
+ const buildArchiveSrc = '.build.zip'
82
+ const buildArchiveDest = '.genoacms/deployment/build.zip'
83
+ const buildArchiveRef = `gs://${bucketName}/${buildArchiveDest}`
84
+ await zipDirectory('./build', buildArchiveSrc)
85
+ await uploadDirectory(bucketName, './static', assetsPath)
86
+ await uploadDirectory(bucketName, buildArchiveSrc, buildArchiveDest)
87
+ await deployFunction('genoacms', buildArchiveRef)
88
+ }
@@ -0,0 +1,13 @@
1
+ import type { Adapter } from '@genoacms/cloudabstraction/deployment'
2
+
3
+ const svelteKitAdapter: Adapter.svelteKitAdapter = '@sveltejs/adapter-node'
4
+
5
+ const deployProcedure: Adapter.deployProcedure = async () => {
6
+ const deploy = (await import('./deploy.js')).default
7
+ await deploy()
8
+ }
9
+
10
+ export {
11
+ svelteKitAdapter,
12
+ deployProcedure
13
+ }
@@ -2,18 +2,8 @@ import type {
2
2
  Adapter,
3
3
  StorageObject
4
4
  } from '@genoacms/cloudabstraction/storage'
5
- import { type Bucket, Storage, type File } from '@google-cloud/storage'
6
- import config from '../../config.js'
7
-
8
- const storage = new Storage({
9
- credentials: config.storage.credentials
10
- })
11
-
12
- const getBucket = (name: string): Bucket => {
13
- if (!config.storage.buckets.includes(name)) throw new Error('bucket-unregistered')
14
- const bucket = storage.bucket(name)
15
- return bucket
16
- }
5
+ import { type File } from '@google-cloud/storage'
6
+ import { getBucket } from './storage.js'
17
7
 
18
8
  const getObject: Adapter.getObject = async ({ bucket, name }) => {
19
9
  const bucketInstance = getBucket(bucket)
@@ -42,10 +32,10 @@ const getSignedURL: Adapter.getSignedURL = async ({ bucket, name }) => {
42
32
  return url
43
33
  }
44
34
 
45
- const uploadObject: Adapter.uploadObject = async ({ bucket, name }, stream) => {
35
+ const uploadObject: Adapter.uploadObject = async ({ bucket, name }, stream, options) => {
46
36
  const bucketInstance = getBucket(bucket)
47
37
  const file = bucketInstance.file(name)
48
- await file.save(stream)
38
+ await file.save(stream, options)
49
39
  }
50
40
 
51
41
  const deleteObject: Adapter.deleteObject = async ({ bucket, name }) => {
@@ -0,0 +1,16 @@
1
+ import config from '../../config.js'
2
+ import { type Bucket, Storage } from '@google-cloud/storage'
3
+
4
+ const storage = new Storage({
5
+ credentials: config.storage.credentials
6
+ })
7
+
8
+ const getBucket = (name: string): Bucket => {
9
+ if (!config.storage.buckets.includes(name)) throw new Error('bucket-unregistered')
10
+ const bucket = storage.bucket(name)
11
+ return bucket
12
+ }
13
+
14
+ export {
15
+ getBucket
16
+ }