diff --git a/packages/oc-azure-storage-adapter/__test__/azure.test.ts b/packages/oc-azure-storage-adapter/__test__/azure.test.ts index a3c407b..3a64f93 100644 --- a/packages/oc-azure-storage-adapter/__test__/azure.test.ts +++ b/packages/oc-azure-storage-adapter/__test__/azure.test.ts @@ -15,7 +15,8 @@ const validOptions = { privateContainerName: 'privcon', accountName: 'name', accountKey: 'key', - path: '/' + path: '/', + componentsDir: 'components' }; test('should expose the correct methods', () => { diff --git a/packages/oc-azure-storage-adapter/__test__/privateFilesExclusion.test.ts b/packages/oc-azure-storage-adapter/__test__/privateFilesExclusion.test.ts index 4bf4c7c..490306f 100644 --- a/packages/oc-azure-storage-adapter/__test__/privateFilesExclusion.test.ts +++ b/packages/oc-azure-storage-adapter/__test__/privateFilesExclusion.test.ts @@ -7,7 +7,8 @@ test('put directory recognizes server.js and .env to be private', async () => { privateContainerName: 'privcon', accountName: 'name', accountKey: 'key', - path: '/' + path: '/', + componentsDir: 'components' }); const mockResult = (await client.putDir('.', '.')) as Array<{ diff --git a/packages/oc-azure-storage-adapter/src/index.ts b/packages/oc-azure-storage-adapter/src/index.ts index 451b3db..a95236b 100644 --- a/packages/oc-azure-storage-adapter/src/index.ts +++ b/packages/oc-azure-storage-adapter/src/index.ts @@ -58,16 +58,21 @@ export default function azureAdapter(conf: AzureConfig): StorageAdapter { refreshInterval: conf.refreshInterval }); + let client: BlobServiceClient | undefined = undefined; + const getClient = () => { - const sharedKeyCredential = new StorageSharedKeyCredential( - conf.accountName, - conf.accountKey - ); - const blobServiceClient = new BlobServiceClient( - `https://${conf.accountName}.blob.core.windows.net`, - sharedKeyCredential - ); - return blobServiceClient; + if (!client) { + const sharedKeyCredential = new StorageSharedKeyCredential( + conf.accountName, + conf.accountKey + ); + client = new BlobServiceClient( + `https://${conf.accountName}.blob.core.windows.net`, + sharedKeyCredential + ); + + } + return client; }; const getFile = async (filePath: string, force = false) => { @@ -158,6 +163,7 @@ export default function azureAdapter(conf: AzureConfig): StorageAdapter { const paths = await getPaths(dirInput); const packageJsonFile = path.join(dirInput, 'package.json'); const files = paths.files.filter(file => file !== packageJsonFile); + const client = getClient(); const filesResults = await Promise.all( files.map((file: string) => { @@ -170,7 +176,8 @@ export default function azureAdapter(conf: AzureConfig): StorageAdapter { return putFile( file, url, - privateFilePatterns.some(r => r.test(relativeFile)) + privateFilePatterns.some(r => r.test(relativeFile)), + client ); }) ); @@ -179,7 +186,8 @@ export default function azureAdapter(conf: AzureConfig): StorageAdapter { const packageJsonFileResult = await putFile( packageJsonFile, `${dirOutput}/package.json`.replace(/\\/g, '/'), - false + false, + client ); return [...filesResults, packageJsonFileResult]; @@ -188,7 +196,8 @@ export default function azureAdapter(conf: AzureConfig): StorageAdapter { const putFileContent = async ( fileContent: string | fs.ReadStream, fileName: string, - isPrivate: boolean + isPrivate: boolean, + client: BlobServiceClient ) => { const content = typeof fileContent === 'string' @@ -208,8 +217,8 @@ export default function azureAdapter(conf: AzureConfig): StorageAdapter { if (fileInfo.gzip) { blobHTTPHeaders.blobContentEncoding = 'gzip'; } - - const containerClient = getClient().getContainerClient(containerName); + const localClient = client ? client : getClient(); + const containerClient = localClient.getContainerClient(containerName); const blockBlobClient = containerClient.getBlockBlobClient(fileName); return blockBlobClient.uploadData(content, { @@ -224,9 +233,9 @@ export default function azureAdapter(conf: AzureConfig): StorageAdapter { return result; }; - const putFile = (filePath: string, fileName: string, isPrivate: boolean) => { + const putFile = (filePath: string, fileName: string, isPrivate: boolean, client: BlobServiceClient) => { const stream = fs.createReadStream(filePath); - return putFileContent(stream, fileName, isPrivate); + return putFileContent(stream, fileName, isPrivate, client); }; return { diff --git a/packages/oc-gs-storage-adapter/__test__/gs.test.ts b/packages/oc-gs-storage-adapter/__test__/gs.test.ts index 0dbe3d4..317a7be 100644 --- a/packages/oc-gs-storage-adapter/__test__/gs.test.ts +++ b/packages/oc-gs-storage-adapter/__test__/gs.test.ts @@ -28,7 +28,8 @@ global.Date.now = _Date.now; const validOptions = { bucket: 'test', projectId: '12345', - path: '/' + path: '/', + componentsDir: 'components' }; test('should expose the correct methods', () => { diff --git a/packages/oc-gs-storage-adapter/__test__/privateFilesExclusion.test.ts b/packages/oc-gs-storage-adapter/__test__/privateFilesExclusion.test.ts index b9ccfdc..b51ac87 100644 --- a/packages/oc-gs-storage-adapter/__test__/privateFilesExclusion.test.ts +++ b/packages/oc-gs-storage-adapter/__test__/privateFilesExclusion.test.ts @@ -24,7 +24,8 @@ test('put directory recognizes server.js and .env to be private', async () => { const options = { bucket: 'test', projectId: '12345', - path: 'somepath' + path: 'somepath', + componentsDir: 'components' }; const client = gs(options); diff --git a/packages/oc-gs-storage-adapter/src/index.ts b/packages/oc-gs-storage-adapter/src/index.ts index f257ab9..83c615a 100644 --- a/packages/oc-gs-storage-adapter/src/index.ts +++ b/packages/oc-gs-storage-adapter/src/index.ts @@ -143,6 +143,7 @@ export default function gsAdapter(conf: GsConfig): StorageAdapter { const paths = await getPaths(dirInput); const packageJsonFile = path.join(dirInput, 'package.json'); const files = paths.files.filter(file => file !== packageJsonFile); + const client = getClient(); const filesResults = await Promise.all( files.map((file: string) => { @@ -155,7 +156,8 @@ export default function gsAdapter(conf: GsConfig): StorageAdapter { return putFile( file, url, - privateFilePatterns.some(r => r.test(relativeFile)) + privateFilePatterns.some(r => r.test(relativeFile)), + client ); }) ); @@ -164,7 +166,8 @@ export default function gsAdapter(conf: GsConfig): StorageAdapter { const packageJsonFileResult = await putFile( packageJsonFile, `${dirOutput}/package.json`.replace(/\\/g, '/'), - false + false, + client ); return [...filesResults, packageJsonFileResult]; @@ -173,14 +176,15 @@ export default function gsAdapter(conf: GsConfig): StorageAdapter { const putFileContent = async ( fileContent: string, fileName: string, - isPrivate: boolean + isPrivate: boolean, + client: Storage ) => { const tmpobj = tmp.fileSync(); fs.writeFileSync(tmpobj.name, fileContent); try { - const result = await putFile(tmpobj.name, fileName, isPrivate); + const result = await putFile(tmpobj.name, fileName, isPrivate, client); return result; } finally { tmpobj.removeCallback(); @@ -190,7 +194,8 @@ export default function gsAdapter(conf: GsConfig): StorageAdapter { const putFile = async ( filePath: string, fileName: string, - isPrivate: boolean + isPrivate: boolean, + client: Storage ) => { const fileInfo = getFileInfo(fileName); const obj: { @@ -222,11 +227,12 @@ export default function gsAdapter(conf: GsConfig): StorageAdapter { }; } + const localClient = client ? client : getClient(); try { - await getClient().bucket(bucketName).upload(filePath, options); + await localClient.bucket(bucketName).upload(filePath, options); if (obj.ACL === 'public-read') { - await getClient().bucket(bucketName).file(fileName).makePublic(); + await localClient.bucket(bucketName).file(fileName).makePublic(); } return obj; diff --git a/packages/oc-riak-storage-adapter/__test__/s3.test.ts b/packages/oc-riak-storage-adapter/__test__/s3.test.ts index 1e12632..8a9b4ad 100644 --- a/packages/oc-riak-storage-adapter/__test__/s3.test.ts +++ b/packages/oc-riak-storage-adapter/__test__/s3.test.ts @@ -14,7 +14,8 @@ const validOptions = { region: 'region-test', key: 'test-key', secret: 'test-secret', - path: '/' + path: '/', + componentsDir: 'components' }; test('should expose the correct methods', () => { diff --git a/packages/oc-s3-storage-adapter/__test__/privateFilesExclusion.test.ts b/packages/oc-s3-storage-adapter/__test__/privateFilesExclusion.test.ts index b330633..bb6c75e 100644 --- a/packages/oc-s3-storage-adapter/__test__/privateFilesExclusion.test.ts +++ b/packages/oc-s3-storage-adapter/__test__/privateFilesExclusion.test.ts @@ -7,7 +7,8 @@ test('put directory recognizes server.js and .env to be private', async () => { region: 'region-test', key: 'test-key', secret: 'test-secret', - path: '/' + path: '/', + componentsDir: 'components' }; const client = s3(options); diff --git a/packages/oc-s3-storage-adapter/src/index.ts b/packages/oc-s3-storage-adapter/src/index.ts index 974cb19..2652407 100644 --- a/packages/oc-s3-storage-adapter/src/index.ts +++ b/packages/oc-s3-storage-adapter/src/index.ts @@ -95,22 +95,27 @@ export default function s3Adapter(conf: S3Config): StorageAdapter { requestHandler = new NodeHttpHandler(handlerOptions); } + let client: S3 | undefined = undefined; + const getClient = () => { - const configOpts: S3ClientConfig = { - logger: conf.debug ? (console.log as any) : undefined, - tls: sslEnabled, - requestHandler, - endpoint: conf.endpoint, - region, - forcePathStyle: s3ForcePathStyle - } - if (accessKeyId && secretAccessKey) { - configOpts.credentials = { - accessKeyId, - secretAccessKey - }; + if (!client) { + const configOpts: S3ClientConfig = { + logger: conf.debug ? (console as any) : undefined, + tls: sslEnabled, + requestHandler, + endpoint: conf.endpoint, + region, + forcePathStyle: s3ForcePathStyle + } + if (accessKeyId && secretAccessKey) { + configOpts.credentials = { + accessKeyId, + secretAccessKey + }; + } + client = new S3(configOpts); } - return new S3(configOpts); + return client; }; const getFile = async (filePath: string, force = false) => { @@ -197,6 +202,7 @@ export default function s3Adapter(conf: S3Config): StorageAdapter { const paths = await getPaths(dirInput); const packageJsonFile = path.join(dirInput, 'package.json'); const files = paths.files.filter(file => file !== packageJsonFile); + const client = getClient(); const filesResults = await Promise.all( files.map((file: string) => { @@ -209,7 +215,8 @@ export default function s3Adapter(conf: S3Config): StorageAdapter { return putFile( file, url, - privateFilePatterns.some(r => r.test(relativeFile)) + privateFilePatterns.some(r => r.test(relativeFile)), + client ); }) ); @@ -218,7 +225,8 @@ export default function s3Adapter(conf: S3Config): StorageAdapter { const packageJsonFileResult = await putFile( packageJsonFile, `${dirOutput}/package.json`.replace(/\\/g, '/'), - false + false, + client ); return [...filesResults, packageJsonFileResult]; @@ -227,11 +235,13 @@ export default function s3Adapter(conf: S3Config): StorageAdapter { const putFileContent = async ( fileContent: string | fs.ReadStream, fileName: string, - isPrivate: boolean + isPrivate: boolean, + client: S3 ) => { const fileInfo = getFileInfo(fileName); + const localClient = client ? client : getClient(); - return getClient().putObject({ + return localClient.putObject({ Bucket: bucket, Key: fileName, Body: fileContent, @@ -243,10 +253,10 @@ export default function s3Adapter(conf: S3Config): StorageAdapter { }); }; - const putFile = (filePath: string, fileName: string, isPrivate: boolean) => { + const putFile = (filePath: string, fileName: string, isPrivate: boolean, client: S3) => { const stream = fs.createReadStream(filePath); - return putFileContent(stream, fileName, isPrivate); + return putFileContent(stream, fileName, isPrivate, client); }; return { diff --git a/packages/oc-storage-adapters-utils/src/index.ts b/packages/oc-storage-adapters-utils/src/index.ts index 6844700..ade0cec 100644 --- a/packages/oc-storage-adapters-utils/src/index.ts +++ b/packages/oc-storage-adapters-utils/src/index.ts @@ -21,12 +21,14 @@ export interface StorageAdapter { putFile( filePath: string, fileName: string, - isPrivate: boolean + isPrivate: boolean, + client?: unknown ): Promise; putFileContent( data: unknown, path: string, - isPrivate: boolean + isPrivate: boolean, + client?: unknown ): Promise; isValid: () => boolean; }