@@ -4,6 +4,10 @@ import { deepEqual } from 'fast-equals'
44import { existsSync , mkdirSync , readFileSync , writeFileSync } from 'fs'
55import { Artifact , CacheFile } from '../../exports'
66import { cwd } from 'process'
7+ import { formatBytes , get } from '../../core/util'
8+ import { FLYTRAP_API_BASE } from '../../core/config'
9+ import { log } from '../../core/logging'
10+ import { batchedArtifactsUpload } from './batchedArtifactsUpload'
711
812export const getCacheFilePath = ( projectId : string ) => {
913 if ( process . env . NODE_ENV === 'test' ) {
@@ -22,6 +26,7 @@ function _createCacheFile(projectId: string): string {
2226 createdTimestamp : Date . now ( ) ,
2327 artifactCacheEntries : [ ]
2428 }
29+ log . info ( 'cache' , `Creating cache file at path ${ cacheFilePath } .` )
2530 writeFileSync ( cacheFilePath , JSON . stringify ( cache , null , 2 ) )
2631 }
2732 return cacheFilePath
@@ -38,6 +43,65 @@ const _getCacheFile = (projectId: string): CacheFile => {
3843 return JSON . parse ( cacheFileContents ) as CacheFile
3944}
4045
46+ const _populateCache = async ( projectId : string , secretApiKey : string ) : Promise < CacheFile > => {
47+ const artifacts = await _fetchUploadedArtifacts ( projectId , secretApiKey )
48+ const cache = _getCacheFile ( projectId )
49+ for ( let i = 0 ; i < artifacts . length ; i ++ ) {
50+ cache . artifactCacheEntries . push ( {
51+ artifact : artifacts [ i ] ,
52+ timestamp : Date . now ( ) ,
53+ uploadStatus : 'uploaded'
54+ } )
55+ }
56+ _saveCacheFile ( projectId , cache )
57+ return cache
58+ }
59+
60+ async function _getArtifactsToUpload (
61+ projectId : string ,
62+ secretApiKey : string ,
63+ artifacts : Artifact [ ]
64+ ) {
65+ const alreadyUploadedArtifacts = await _fetchUploadedArtifacts ( projectId , secretApiKey )
66+ const artifactsToUpload : Artifact [ ] = [ ]
67+ for ( let i = 0 ; i < artifacts . length ; i ++ ) {
68+ const existingArtifactIndex = _indexOfArtifactWithId (
69+ alreadyUploadedArtifacts ,
70+ artifacts [ i ] . functionOrCallId
71+ )
72+ if ( existingArtifactIndex !== - 1 ) {
73+ // Exists, check if they're the same
74+ if ( ! deepEqual ( alreadyUploadedArtifacts [ existingArtifactIndex ] , artifacts [ i ] ) ) {
75+ artifactsToUpload . push ( artifacts [ i ] )
76+ continue
77+ }
78+ } else {
79+ // Doesn't exist in uploaded artifacts
80+ artifactsToUpload . push ( artifacts [ i ] )
81+ }
82+ }
83+ return artifactsToUpload
84+ }
85+
86+ export async function upsertArtifacts (
87+ projectId : string ,
88+ secretApiKey : string ,
89+ artifacts : Artifact [ ]
90+ ) {
91+ const artifactsToUpload = await _getArtifactsToUpload ( projectId , secretApiKey , artifacts )
92+ // Upload artifacts
93+ const uploadedBatches = await batchedArtifactsUpload ( artifactsToUpload , secretApiKey , projectId )
94+ log . info (
95+ 'storage' ,
96+ `Pushed ${ artifactsToUpload . length } artifacts in ${
97+ uploadedBatches ?. length
98+ } batches to the Flytrap API. Payload Size: ${ formatBytes (
99+ JSON . stringify ( artifactsToUpload ) . length
100+ ) } `
101+ )
102+ return uploadedBatches
103+ }
104+
41105const _indexOfArtifactWithId = ( haystack : Artifact [ ] , functionOrCallId : string ) =>
42106 haystack . findIndex ( ( h ) => h . functionOrCallId === functionOrCallId )
43107
@@ -96,3 +160,21 @@ export function getArtifactsToUpload(projectId: string) {
96160 . filter ( ( a ) => a . uploadStatus !== 'uploaded' )
97161 . reduce ( ( acc , curr ) => [ ...acc , curr . artifact ] , [ ] as Artifact [ ] )
98162}
163+
164+ async function _fetchUploadedArtifacts ( projectId : string , secretApiKey : string ) {
165+ const { data, error } = await get < Artifact [ ] > (
166+ `${ FLYTRAP_API_BASE } /v1/artifacts/${ projectId } ` ,
167+ undefined ,
168+ {
169+ headers : new Headers ( {
170+ Authorization : `Bearer ${ secretApiKey } ` ,
171+ 'Content-Type' : 'application/json'
172+ } )
173+ }
174+ )
175+ if ( error || data === null ) {
176+ throw error
177+ }
178+
179+ return data
180+ }
0 commit comments