@genoacms/adapter-gcp 0.8.2-1 → 0.9.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.
Files changed (52) hide show
  1. package/dist/authentication/identity-platform/descriptor.d.ts +18 -0
  2. package/dist/authentication/identity-platform/descriptor.js +14 -0
  3. package/dist/authentication/identity-platform/runtime.d.ts +4 -0
  4. package/dist/authentication/identity-platform/runtime.js +140 -0
  5. package/dist/database/descriptor.d.ts +16 -0
  6. package/dist/database/descriptor.js +7 -0
  7. package/dist/database/runtime.d.ts +5 -0
  8. package/dist/database/runtime.js +68 -0
  9. package/dist/deployment/archive.d.ts +4 -0
  10. package/dist/deployment/archive.js +46 -0
  11. package/dist/deployment/descriptor.d.ts +24 -0
  12. package/dist/deployment/descriptor.js +20 -0
  13. package/dist/deployment/functions.d.ts +16 -0
  14. package/dist/deployment/functions.js +66 -0
  15. package/dist/deployment/procedure.d.ts +4 -0
  16. package/dist/deployment/procedure.js +16 -0
  17. package/dist/deployment/settings.d.ts +22 -0
  18. package/dist/deployment/settings.js +58 -0
  19. package/dist/secrets/descriptor.d.ts +14 -0
  20. package/dist/secrets/descriptor.js +7 -0
  21. package/dist/secrets/runtime.d.ts +14 -0
  22. package/dist/secrets/runtime.js +147 -0
  23. package/dist/shared/serviceAccount.d.ts +16 -0
  24. package/dist/shared/serviceAccount.js +12 -0
  25. package/dist/storage/descriptor.d.ts +14 -0
  26. package/dist/storage/descriptor.js +7 -0
  27. package/dist/storage/runtime.d.ts +8 -0
  28. package/dist/storage/runtime.js +178 -0
  29. package/package.json +46 -27
  30. package/deployment/snippets/index.js +0 -8
  31. package/dist/config.d.ts +0 -2
  32. package/dist/config.js +0 -2
  33. package/dist/services/authorization/index.d.ts +0 -3
  34. package/dist/services/authorization/index.js +0 -24
  35. package/dist/services/database/index.d.ts +0 -7
  36. package/dist/services/database/index.js +0 -63
  37. package/dist/services/deployment/deploy.d.ts +0 -2
  38. package/dist/services/deployment/deploy.js +0 -115
  39. package/dist/services/deployment/index.d.ts +0 -4
  40. package/dist/services/deployment/index.js +0 -6
  41. package/dist/services/storage/index.d.ts +0 -12
  42. package/dist/services/storage/index.js +0 -87
  43. package/dist/services/storage/storage.d.ts +0 -3
  44. package/dist/services/storage/storage.js +0 -20
  45. package/src/config.ts +0 -4
  46. package/src/genoa.config.d.ts +0 -51
  47. package/src/services/authorization/index.ts +0 -28
  48. package/src/services/database/index.ts +0 -88
  49. package/src/services/deployment/deploy.ts +0 -125
  50. package/src/services/deployment/index.ts +0 -13
  51. package/src/services/storage/index.ts +0 -119
  52. package/src/services/storage/storage.ts +0 -27
@@ -1,115 +0,0 @@
1
- import { createReadStream, createWriteStream } from 'node:fs';
2
- import { resolve, dirname, basename } from 'node:path';
3
- import { fileURLToPath } from 'node:url';
4
- import { v2 } from '@google-cloud/functions';
5
- import archiver from 'archiver';
6
- import { getProvider } from '@genoacms/cloudabstraction';
7
- const ADAPTER_PATH = '@genoacms/adapter-gcp/deployment';
8
- const { FunctionServiceClient } = v2;
9
- const provider = getProvider('deployment', ADAPTER_PATH);
10
- const functionsClient = new FunctionServiceClient({
11
- credentials: provider.credentials
12
- });
13
- const { projectId, region, functionName } = provider;
14
- const currentDir = dirname(fileURLToPath(import.meta.url));
15
- async function createZip(source, injectPaths, ignorePaths, out) {
16
- await new Promise((resolve, reject) => {
17
- const output = createWriteStream(out);
18
- const archive = archiver('zip', { zlib: { level: 9 } });
19
- output.on('close', () => {
20
- resolve();
21
- });
22
- archive.on('error', (err) => {
23
- reject(err);
24
- });
25
- archive.pipe(output);
26
- archive.glob(source, { ignore: ignorePaths, follow: true });
27
- for (const path of injectPaths) {
28
- archive.file(path, { name: basename(path) });
29
- }
30
- archive.finalize();
31
- });
32
- }
33
- async function uploadSource(sourceArchivePath) {
34
- const location = functionsClient.locationPath(projectId, region);
35
- const [urlResponse] = await functionsClient.generateUploadUrl({ parent: location });
36
- const uploadUrl = urlResponse.uploadUrl;
37
- const storageSource = urlResponse.storageSource;
38
- if (!uploadUrl || !storageSource)
39
- throw new Error('Upload URL not found');
40
- const sourceArchiveStream = createReadStream(sourceArchivePath);
41
- await fetch(uploadUrl, {
42
- method: 'PUT',
43
- // @ts-expect-error: invalid typings
44
- body: sourceArchiveStream,
45
- duplex: 'half',
46
- headers: {
47
- 'Content-Type': 'application/zip'
48
- }
49
- });
50
- return storageSource;
51
- }
52
- async function deployFunction(functionName, storageSource) {
53
- const location = functionsClient.locationPath(projectId, region);
54
- const name = functionsClient.functionPath(projectId, region, functionName);
55
- let isFunctionExisting;
56
- try {
57
- await functionsClient.getFunction({ name });
58
- isFunctionExisting = true;
59
- }
60
- catch (error) {
61
- isFunctionExisting = false;
62
- }
63
- const operationParams = {
64
- functionId: functionName,
65
- parent: location,
66
- function: {
67
- name,
68
- buildConfig: {
69
- entryPoint: 'genoacms',
70
- runtime: 'nodejs20',
71
- source: {
72
- storageSource
73
- }
74
- },
75
- serviceConfig: {
76
- minInstanceCount: 0,
77
- maxInstanceCount: 1,
78
- ingressSettings: 1, // ALLOW_ALL
79
- environmentVariables: {
80
- NODE_ENV: 'production'
81
- }
82
- }
83
- }
84
- };
85
- let response;
86
- if (isFunctionExisting) {
87
- [response] = await functionsClient.updateFunction(operationParams);
88
- }
89
- else {
90
- [response] = await functionsClient.createFunction(operationParams);
91
- }
92
- console.log(response);
93
- }
94
- async function deploy() {
95
- const buildDirectoryPath = '**';
96
- const buildArchivePath = resolve(currentDir, '../../../../../../.genoacms/build.zip');
97
- const functionEntryScriptPath = resolve(currentDir, '../../../deployment/snippets/index.js');
98
- const builderScriptPath = resolve(currentDir, '../../../deployment/snippets/build.js');
99
- const ignoreArchivePaths = [
100
- 'node_modules/**',
101
- '.git/**',
102
- '.github/**',
103
- '.gitignore',
104
- '.genoacms/**',
105
- 'build/**'
106
- ];
107
- const injectArchivePaths = [
108
- functionEntryScriptPath,
109
- builderScriptPath
110
- ];
111
- await createZip(buildDirectoryPath, injectArchivePaths, ignoreArchivePaths, buildArchivePath);
112
- const functionStorageSource = await uploadSource(buildArchivePath);
113
- await deployFunction(functionName ?? 'genoacms', functionStorageSource);
114
- }
115
- export default deploy;
@@ -1,4 +0,0 @@
1
- import type { Adapter } from '@genoacms/cloudabstraction/deployment';
2
- declare const svelteKitAdapter: Adapter['svelteKitAdapter'];
3
- declare const deployProcedure: Adapter['deployProcedure'];
4
- export { svelteKitAdapter, deployProcedure };
@@ -1,6 +0,0 @@
1
- const svelteKitAdapter = '@genoacms/sveltekit-adapter-cloud-run-functions';
2
- const deployProcedure = async () => {
3
- const deploy = (await import('./deploy.js')).default;
4
- await deploy();
5
- };
6
- export { svelteKitAdapter, deployProcedure };
@@ -1,12 +0,0 @@
1
- import type { Adapter } from '@genoacms/cloudabstraction/storage';
2
- declare const getObject: Adapter['getObject'];
3
- declare const getPublicURL: Adapter['getPublicURL'];
4
- declare const getSignedURL: Adapter['getSignedURL'];
5
- declare const uploadObject: Adapter['uploadObject'];
6
- declare const moveObject: Adapter['moveObject'];
7
- declare const deleteObject: Adapter['deleteObject'];
8
- declare const listDirectory: Adapter['listDirectory'];
9
- declare const createDirectory: Adapter['createDirectory'];
10
- declare const deleteDirectory: Adapter['deleteDirectory'];
11
- declare const moveDirectory: Adapter['moveDirectory'];
12
- export { getObject, getPublicURL, getSignedURL, uploadObject, moveObject, deleteObject, listDirectory, createDirectory, deleteDirectory, moveDirectory };
@@ -1,87 +0,0 @@
1
- import { getBucket } from './storage.js';
2
- const getObject = async ({ bucket, name }) => {
3
- const bucketInstance = getBucket(bucket);
4
- const file = bucketInstance.file(name);
5
- return {
6
- data: file.createReadStream()
7
- };
8
- };
9
- const getPublicURL = async ({ bucket, name }) => {
10
- const bucketInstance = getBucket(bucket);
11
- const file = bucketInstance.file(name);
12
- return file.publicUrl();
13
- };
14
- const getSignedURL = async ({ bucket, name }, expires) => {
15
- const bucketInstance = getBucket(bucket);
16
- const file = bucketInstance.file(name);
17
- const [url] = await file.getSignedUrl({
18
- action: 'read',
19
- expires
20
- });
21
- return url;
22
- };
23
- const uploadObject = async ({ bucket, name }, stream, options) => {
24
- const bucketInstance = getBucket(bucket);
25
- const file = bucketInstance.file(name);
26
- await file.save(stream, options);
27
- };
28
- const moveObject = async ({ bucket, name }, newName) => {
29
- const bucketInstance = getBucket(bucket);
30
- const file = bucketInstance.file(name);
31
- await file.move(newName);
32
- };
33
- const deleteObject = async ({ bucket, name }) => {
34
- const bucketInstance = getBucket(bucket);
35
- const file = bucketInstance.file(name);
36
- await file.delete();
37
- };
38
- const listDirectory = async ({ bucket, name }, listingParams = {}) => {
39
- const bucketInstance = getBucket(bucket);
40
- const options = {
41
- autoPaginate: false,
42
- prefix: name,
43
- maxResults: listingParams?.limit,
44
- startOffset: listingParams?.startAfter,
45
- delimiter: '/'
46
- };
47
- let [files, , apiResponse] = (await bucketInstance.getFiles(options));
48
- files = files.filter((file) => !file.name.endsWith('.folderPlaceholder'));
49
- return {
50
- files: files.filter(f => f.name !== name).map((file) => {
51
- return {
52
- name: file.name,
53
- // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
54
- size: file.metadata.size ? parseInt(file.metadata.size) : 0,
55
- lastModified: new Date(file.metadata.updated)
56
- };
57
- }),
58
- directories: (apiResponse?.prefixes ?? []).filter((item) => item !== name).map(i => {
59
- const object = {
60
- bucket,
61
- name: i
62
- };
63
- return object;
64
- })
65
- };
66
- };
67
- const createDirectory = async ({ bucket, name }) => {
68
- const bucketInstance = getBucket(bucket);
69
- const file = bucketInstance.file(`${name}/.folderPlaceholder`);
70
- await file.save('');
71
- };
72
- const deleteDirectory = async ({ bucket, name }) => {
73
- const bucketInstance = getBucket(bucket);
74
- const [files] = await bucketInstance.getFiles({ prefix: name });
75
- const deletePromises = files.map(async (file) => await file.delete());
76
- await Promise.all(deletePromises);
77
- };
78
- const moveDirectory = async ({ bucket, name }, newName) => {
79
- const bucketInstance = getBucket(bucket);
80
- const [files] = await bucketInstance.getFiles({ prefix: name });
81
- const movePromises = files.map(async (file) => {
82
- const newFileName = file.name.replace(name, newName);
83
- await file.move(newFileName);
84
- });
85
- await Promise.all(movePromises);
86
- };
87
- export { getObject, getPublicURL, getSignedURL, uploadObject, moveObject, deleteObject, listDirectory, createDirectory, deleteDirectory, moveDirectory };
@@ -1,3 +0,0 @@
1
- import { type Bucket } from '@google-cloud/storage';
2
- declare const getBucket: (name: string) => Bucket;
3
- export { getBucket };
@@ -1,20 +0,0 @@
1
- import { Storage } from '@google-cloud/storage';
2
- import { getProvider } from '@genoacms/cloudabstraction';
3
- import config from '../../config.js';
4
- const ADAPTER_PATH = '@genoacms/adapter-gcp/storage';
5
- const provider = getProvider('storage', ADAPTER_PATH);
6
- const storage = new Storage({
7
- credentials: provider.credentials
8
- });
9
- const hasBucket = (name) => {
10
- const has = config.storage.buckets.find((bucket) => bucket.name === name &&
11
- bucket.providerName === provider.name);
12
- return !!has;
13
- };
14
- const getBucket = (name) => {
15
- if (!hasBucket(name))
16
- throw new Error('bucket-unregistered');
17
- const bucket = storage.bucket(name);
18
- return bucket;
19
- };
20
- export { getBucket };
package/src/config.ts DELETED
@@ -1,4 +0,0 @@
1
- import type { Config } from './genoa.config.js'
2
- import { config } from '@genoacms/cloudabstraction'
3
-
4
- export default config satisfies Config
@@ -1,51 +0,0 @@
1
- import type { Config as ConfigG } from '@genoacms/cloudabstraction/src/genoa.config.js'
2
- import type { AuthorizationProvider as AuthorizationProviderG } from '@genoacms/cloudabstraction/authorization'
3
- import type { DatabaseProvider as DatabaseProviderG } from '@genoacms/cloudabstraction/database'
4
- import type { DeploymentProvider as DeploymentProviderG } from '@genoacms/cloudabstraction/deployment'
5
- import type { StorageProvider as StorageProviderG } from '@genoacms/cloudabstraction/storage'
6
-
7
- interface Credentials {
8
- type: string
9
- 'project_id': string
10
- 'private_key_id': string
11
- 'private_key': string
12
- 'client_email': string
13
- 'client_id': string
14
- 'auth_uri': string
15
- 'token_uri': string
16
- 'auth_provider_x509_cert_url': string
17
- 'client_x509_cert_url': string
18
- 'universe_domain': string
19
- }
20
-
21
- interface AuthorizationProvider extends AuthorizationProviderG {
22
- projectId: string
23
- credentials: Credentials
24
- }
25
-
26
- interface DatabaseProvider extends DatabaseProviderG {
27
- projectId: string
28
- credentials: Credentials
29
- databaseId: string
30
- region: string
31
- }
32
- interface DeploymentProvider extends DeploymentProviderG {
33
- projectId: string
34
- credentials: Credentials
35
- region: string
36
- functionName: string
37
- }
38
-
39
- interface StorageProvider extends StorageProviderG {
40
- credentials: Credentials
41
- }
42
-
43
- interface Config extends ConfigG<object, AuthorizationProvider, DatabaseProvider, StorageProvider> {}
44
-
45
- export type {
46
- Config,
47
- AuthorizationProvider,
48
- DatabaseProvider,
49
- DeploymentProvider,
50
- StorageProvider
51
- }
@@ -1,28 +0,0 @@
1
- import type { Adapter } from '@genoacms/cloudabstraction/authorization'
2
- import type { AuthorizationProvider } from '../../genoa.config.js'
3
- import { getProvider } from '@genoacms/cloudabstraction'
4
- import { ProjectsClient } from '@google-cloud/resource-manager'
5
-
6
- const ADAPTER_PATH = '@genoacms/adapter-gcp/authorization'
7
- const provider = getProvider('authorization', ADAPTER_PATH) as AuthorizationProvider
8
- const projectId = provider.projectId
9
- const resourceManager = new ProjectsClient({
10
- projectId,
11
- credentials: provider.credentials
12
- })
13
-
14
- const isEmailAdmins: Adapter.isEmailAdmins = async (email: string) => {
15
- const resource = `projects/${projectId}`
16
- const role = resource + '/roles/genoacms'
17
- const data = await resourceManager.getIamPolicy({ resource })
18
- const policy = data[0]
19
- if ((policy.bindings) == null) throw new Error('no-bindings')
20
- const adminRole = policy.bindings.find(binding => binding.role === role)
21
- if (adminRole == null) throw new Error('no-admin-role')
22
- if (adminRole.members == null) throw new Error('no-principals')
23
- return adminRole.members.includes(`user:${email}`)
24
- }
25
-
26
- export {
27
- isEmailAdmins
28
- }
@@ -1,88 +0,0 @@
1
- import type {
2
- Adapter,
3
- CollectionSnapshot,
4
- Document,
5
- DocumentReference,
6
- DocumentSnapshot,
7
- UpdateSnapshot
8
- } from '@genoacms/cloudabstraction/database'
9
- import type {
10
- DatabaseProvider
11
- } from '../../genoa.config.js'
12
- import { Firestore } from '@google-cloud/firestore'
13
- import { getProvider } from '@genoacms/cloudabstraction'
14
-
15
- const ADAPTER_PATH = '@genoacms/adapter-gcp/database'
16
- const provider = getProvider('database', ADAPTER_PATH) as DatabaseProvider
17
- const firestore = new Firestore({
18
- credentials: provider.credentials,
19
- databaseId: provider.databaseId,
20
- projectId: provider.projectId
21
- })
22
-
23
- const createDocument: Adapter['createDocument'] = async (reference, data) => {
24
- const document = await firestore.collection(reference.name).add(data)
25
- const documentReference: DocumentReference<typeof reference> = {
26
- collection: reference,
27
- id: document.id
28
- }
29
- return {
30
- reference: documentReference,
31
- data
32
- } satisfies DocumentSnapshot<typeof reference>
33
- }
34
-
35
- const getCollection: Adapter['getCollection'] = async (reference) => {
36
- const collection = await firestore.collection(reference.name).get()
37
- const documents: CollectionSnapshot<typeof reference> = []
38
-
39
- collection.forEach(document => {
40
- const documentData: Document<typeof reference.schema> = {}
41
- Object.keys(reference.schema.properties).forEach(key => {
42
- documentData[key] = document.get(key)
43
- })
44
-
45
- documents.push({
46
- reference: {
47
- collection: reference,
48
- id: document.id
49
- },
50
- data: document.data() as Document<typeof reference.schema>
51
- })
52
- })
53
- return documents
54
- }
55
-
56
- const getDocument: Adapter['getDocument'] = async ({ collection, id }) => {
57
- const document = await firestore.collection(collection.name).doc(id).get()
58
- if (!document.exists) return undefined
59
- const documentReference: DocumentReference<typeof collection> = {
60
- collection,
61
- id
62
- }
63
- const documentSnapshot: DocumentSnapshot<typeof collection> = {
64
- reference: documentReference,
65
- data: document.data() as Document<typeof collection>
66
- }
67
- return documentSnapshot
68
- }
69
-
70
- const updateDocument: Adapter['updateDocument'] = async (reference, document) => {
71
- await firestore.collection(reference.collection.name).doc(reference.id).update(document)
72
- return {
73
- reference,
74
- data: document
75
- } satisfies UpdateSnapshot<typeof reference.collection>
76
- }
77
-
78
- const deleteDocument: Adapter['deleteDocument'] = async (reference) => {
79
- await firestore.collection(reference.collection.name).doc(reference.id).delete()
80
- }
81
-
82
- export {
83
- createDocument,
84
- getDocument,
85
- getCollection,
86
- updateDocument,
87
- deleteDocument
88
- }
@@ -1,125 +0,0 @@
1
- import type { google } from '@google-cloud/functions/build/protos/protos.js'
2
- import { type DeploymentProvider } from '../../genoa.config.js'
3
- import { createReadStream, createWriteStream } from 'node:fs'
4
- import { resolve, dirname, basename } from 'node:path'
5
- import { fileURLToPath } from 'node:url'
6
- import { v2 } from '@google-cloud/functions'
7
- import archiver from 'archiver'
8
- import { getProvider } from '@genoacms/cloudabstraction'
9
- type IStorageSource = google.cloud.functions.v2.IStorageSource
10
-
11
- const ADAPTER_PATH = '@genoacms/adapter-gcp/deployment'
12
- const { FunctionServiceClient } = v2
13
- const provider = getProvider('deployment', ADAPTER_PATH) as DeploymentProvider
14
- const functionsClient = new FunctionServiceClient({
15
- credentials: provider.credentials
16
- })
17
- const { projectId, region, functionName } = provider
18
-
19
- const currentDir = dirname(fileURLToPath(import.meta.url))
20
-
21
- async function createZip (source: string, injectPaths: string[], ignorePaths: string[], out: string): Promise<void> {
22
- await new Promise<void>((resolve, reject) => {
23
- const output = createWriteStream(out)
24
- const archive = archiver('zip', { zlib: { level: 9 } })
25
-
26
- output.on('close', () => {
27
- resolve()
28
- })
29
-
30
- archive.on('error', (err) => {
31
- reject(err)
32
- })
33
-
34
- archive.pipe(output)
35
- archive.glob(source, { ignore: ignorePaths, follow: true })
36
- for (const path of injectPaths) {
37
- archive.file(path, { name: basename(path) })
38
- }
39
- archive.finalize()
40
- })
41
- }
42
-
43
- async function uploadSource (sourceArchivePath: string): Promise<IStorageSource> {
44
- const location = functionsClient.locationPath(projectId, region)
45
- const [urlResponse] = await functionsClient.generateUploadUrl({ parent: location })
46
- const uploadUrl = urlResponse.uploadUrl
47
- const storageSource = urlResponse.storageSource
48
- if (!uploadUrl || !storageSource) throw new Error('Upload URL not found')
49
- const sourceArchiveStream = createReadStream(sourceArchivePath)
50
- await fetch(uploadUrl, {
51
- method: 'PUT',
52
- // @ts-expect-error: invalid typings
53
- body: sourceArchiveStream,
54
- duplex: 'half',
55
- headers: {
56
- 'Content-Type': 'application/zip'
57
- }
58
- })
59
- return storageSource
60
- }
61
-
62
- async function deployFunction (functionName: string, storageSource: IStorageSource): Promise<void> {
63
- const location = functionsClient.locationPath(projectId, region)
64
- const name = functionsClient.functionPath(projectId, region, functionName)
65
- let isFunctionExisting: boolean
66
- try {
67
- await functionsClient.getFunction({ name })
68
- isFunctionExisting = true
69
- } catch (error) {
70
- isFunctionExisting = false
71
- }
72
- const operationParams = {
73
- functionId: functionName,
74
- parent: location,
75
- function: {
76
- name,
77
- buildConfig: {
78
- entryPoint: 'genoacms',
79
- runtime: 'nodejs20',
80
- source: {
81
- storageSource
82
- }
83
- },
84
- serviceConfig: {
85
- minInstanceCount: 0,
86
- maxInstanceCount: 1,
87
- ingressSettings: 1, // ALLOW_ALL
88
- environmentVariables: {
89
- NODE_ENV: 'production'
90
- }
91
- }
92
- }
93
- }
94
- let response
95
- if (isFunctionExisting) {
96
- [response] = await functionsClient.updateFunction(operationParams)
97
- } else {
98
- [response] = await functionsClient.createFunction(operationParams)
99
- }
100
- console.log(response)
101
- }
102
-
103
- async function deploy (): Promise<void> {
104
- const buildDirectoryPath = '**'
105
- const buildArchivePath = resolve(currentDir, '../../../../../../.genoacms/build.zip')
106
- const functionEntryScriptPath = resolve(currentDir, '../../../deployment/snippets/index.js')
107
- const builderScriptPath = resolve(currentDir, '../../../deployment/snippets/build.js')
108
- const ignoreArchivePaths = [
109
- 'node_modules/**',
110
- '.git/**',
111
- '.github/**',
112
- '.gitignore',
113
- '.genoacms/**',
114
- 'build/**'
115
- ]
116
- const injectArchivePaths = [
117
- functionEntryScriptPath,
118
- builderScriptPath
119
- ]
120
- await createZip(buildDirectoryPath, injectArchivePaths, ignoreArchivePaths, buildArchivePath)
121
- const functionStorageSource = await uploadSource(buildArchivePath)
122
- await deployFunction(functionName ?? 'genoacms', functionStorageSource)
123
- }
124
-
125
- export default deploy
@@ -1,13 +0,0 @@
1
- import type { Adapter } from '@genoacms/cloudabstraction/deployment'
2
-
3
- const svelteKitAdapter: Adapter['svelteKitAdapter'] = '@genoacms/sveltekit-adapter-cloud-run-functions'
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
- }
@@ -1,119 +0,0 @@
1
- import type {
2
- Adapter,
3
- ObjectReference,
4
- StorageObject
5
- } from '@genoacms/cloudabstraction/storage'
6
- import { type File } from '@google-cloud/storage'
7
- import { getBucket } from './storage.js'
8
-
9
- const getObject: Adapter['getObject'] = async ({ bucket, name }) => {
10
- const bucketInstance = getBucket(bucket)
11
- const file = bucketInstance.file(name)
12
-
13
- return {
14
- data: file.createReadStream()
15
- }
16
- }
17
-
18
- const getPublicURL: Adapter['getPublicURL'] = async ({ bucket, name }) => {
19
- const bucketInstance = getBucket(bucket)
20
- const file = bucketInstance.file(name)
21
- return file.publicUrl()
22
- }
23
-
24
- const getSignedURL: Adapter['getSignedURL'] = async ({ bucket, name }, expires) => {
25
- const bucketInstance = getBucket(bucket)
26
- const file = bucketInstance.file(name)
27
- const [url] = await file.getSignedUrl({
28
- action: 'read',
29
- expires
30
- })
31
- return url
32
- }
33
-
34
- const uploadObject: Adapter['uploadObject'] = async ({ bucket, name }, stream, options) => {
35
- const bucketInstance = getBucket(bucket)
36
- const file = bucketInstance.file(name)
37
- await file.save(stream, options)
38
- }
39
-
40
- const moveObject: Adapter['moveObject'] = async ({ bucket, name }, newName) => {
41
- const bucketInstance = getBucket(bucket)
42
- const file = bucketInstance.file(name)
43
- await file.move(newName)
44
- }
45
-
46
- const deleteObject: Adapter['deleteObject'] = async ({ bucket, name }) => {
47
- const bucketInstance = getBucket(bucket)
48
- const file = bucketInstance.file(name)
49
- await file.delete()
50
- }
51
-
52
- const listDirectory: Adapter['listDirectory'] = async ({ bucket, name }, listingParams = {}) => {
53
- const bucketInstance = getBucket(bucket)
54
- const options = {
55
- autoPaginate: false,
56
- prefix: name,
57
- maxResults: listingParams?.limit,
58
- startOffset: listingParams?.startAfter,
59
- delimiter: '/'
60
-
61
- }
62
- let [files, , apiResponse] =
63
- (await bucketInstance.getFiles(options)) as [File[], object, { prefixes: string[] } | undefined]
64
- files = files.filter((file) => !file.name.endsWith('.folderPlaceholder'))
65
-
66
- return {
67
- files: files.filter(f => f.name !== name).map((file) => {
68
- return {
69
- name: file.name,
70
- // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
71
- size: file.metadata.size ? parseInt(file.metadata.size as string) : 0,
72
- lastModified: new Date(file.metadata.updated as string)
73
- } satisfies StorageObject
74
- }),
75
- directories: (apiResponse?.prefixes ?? []).filter((item) => item !== name).map(i => {
76
- const object: ObjectReference = {
77
- bucket,
78
- name: i
79
- }
80
- return object
81
- })
82
- }
83
- }
84
-
85
- const createDirectory: Adapter['createDirectory'] = async ({ bucket, name }) => {
86
- const bucketInstance = getBucket(bucket)
87
- const file = bucketInstance.file(`${name}/.folderPlaceholder`)
88
- await file.save('')
89
- }
90
-
91
- const deleteDirectory: Adapter['deleteDirectory'] = async ({ bucket, name }) => {
92
- const bucketInstance = getBucket(bucket)
93
- const [files] = await bucketInstance.getFiles({ prefix: name })
94
- const deletePromises = files.map(async (file) => await file.delete())
95
- await Promise.all(deletePromises)
96
- }
97
-
98
- const moveDirectory: Adapter['moveDirectory'] = async ({ bucket, name }, newName) => {
99
- const bucketInstance = getBucket(bucket)
100
- const [files] = await bucketInstance.getFiles({ prefix: name })
101
- const movePromises = files.map(async (file) => {
102
- const newFileName = file.name.replace(name, newName)
103
- await file.move(newFileName)
104
- })
105
- await Promise.all(movePromises)
106
- }
107
-
108
- export {
109
- getObject,
110
- getPublicURL,
111
- getSignedURL,
112
- uploadObject,
113
- moveObject,
114
- deleteObject,
115
- listDirectory,
116
- createDirectory,
117
- deleteDirectory,
118
- moveDirectory
119
- }