@monokle/synchronizer
Advanced tools
Comparing version 0.14.1 to 0.14.2
@@ -133,2 +133,7 @@ import { SuppressionStatus } from '@monokle/types'; | ||
}; | ||
export declare type ApiToggleSuppressionData = { | ||
data: { | ||
toggleSuppression: ApiSuppression; | ||
}; | ||
}; | ||
export declare class ApiHandler { | ||
@@ -149,3 +154,3 @@ private _apiUrl; | ||
getRepoId(projectSlug: string, repoOwner: string, repoName: string, tokenInfo: TokenInfo): Promise<ApiRepoIdData | undefined>; | ||
toggleSuppression(fingerprint: string, repoId: string, description: string, location: string | undefined, tokenInfo: TokenInfo): Promise<ApiSuppressionsData | undefined>; | ||
toggleSuppression(fingerprint: string, repoId: string, description: string, location: string | undefined, tokenInfo: TokenInfo): Promise<ApiToggleSuppressionData | undefined>; | ||
generateDeepLink(path: string): string; | ||
@@ -152,0 +157,0 @@ queryApi<OUT>(query: string, tokenInfo: TokenInfo, variables?: {}): Promise<OUT | undefined>; |
@@ -67,3 +67,3 @@ /// <reference types="node" /> | ||
private readCacheMetadata; | ||
private dropCacheMetadata; | ||
private dropCache; | ||
private getPolicyFileName; | ||
@@ -70,0 +70,0 @@ private getSuppressionsFileName; |
@@ -64,3 +64,3 @@ "use strict"; | ||
toggleSuppression(tokenInfo, fingerprint, description, location, rootPath, projectSlug) { | ||
var _a, _b, _c, _d, _e; | ||
var _a, _b, _c, _d; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
@@ -70,3 +70,3 @@ if (!((_a = tokenInfo === null || tokenInfo === void 0 ? void 0 : tokenInfo.accessToken) === null || _a === void 0 ? void 0 : _a.length)) { | ||
} | ||
const repoData = yield this.getRootGitData(rootPath); | ||
const repoData = yield this.getRootGitData(rootPath, projectSlug); | ||
let { id } = this.getRepositoryData(rootPath, projectSlug); | ||
@@ -89,5 +89,11 @@ let { slug } = this.getProjectInfo(rootPath, projectSlug); | ||
const suppressionResult = yield this._apiHandler.toggleSuppression(fingerprint, id, description, location, tokenInfo); | ||
if ((_e = (_d = (_c = suppressionResult === null || suppressionResult === void 0 ? void 0 : suppressionResult.data) === null || _c === void 0 ? void 0 : _c.getSuppressions) === null || _d === void 0 ? void 0 : _d.data) === null || _e === void 0 ? void 0 : _e.length) { | ||
const existingSuppressions = yield this.readSuppressions(repoData); | ||
const allSuppressions = this.mergeSuppressions(existingSuppressions, suppressionResult.data.getSuppressions.data); | ||
if ((_c = suppressionResult === null || suppressionResult === void 0 ? void 0 : suppressionResult.data) === null || _c === void 0 ? void 0 : _c.toggleSuppression) { | ||
let existingSuppressions = []; | ||
try { | ||
existingSuppressions = yield this.readSuppressions(repoData); | ||
} | ||
catch (err) { | ||
existingSuppressions = this.getRepositorySuppressions(rootPath, projectSlug); | ||
} | ||
const allSuppressions = this.mergeSuppressions(existingSuppressions, [(_d = suppressionResult === null || suppressionResult === void 0 ? void 0 : suppressionResult.data) === null || _d === void 0 ? void 0 : _d.toggleSuppression]); | ||
yield this.storeSuppressions(allSuppressions, repoData); | ||
@@ -107,3 +113,3 @@ const cacheId = this.getCacheId(rootPath, projectSlug); | ||
} | ||
const repoData = yield this.getRootGitData(rootPath); | ||
const repoData = yield this.getRootGitData(rootPath, projectSlug); | ||
const ownerProjectSlug = projectSlug !== null && projectSlug !== void 0 ? projectSlug : (_b = (yield this.getMatchingProject(repoData, tokenInfo))) === null || _b === void 0 ? void 0 : _b.slug; | ||
@@ -132,4 +138,8 @@ const cacheId = this.getCacheId(rootPath, projectSlug); | ||
} | ||
if (resyncDueToError) { | ||
yield this.dropCacheMetadata(repoData); | ||
const cacheMetadata = yield this.readCacheMetadata(repoData); | ||
const isCachedProjectMatching = ownerProjectSlug === (cacheMetadata === null || cacheMetadata === void 0 ? void 0 : cacheMetadata.projectSlug); | ||
if (!isCachedProjectMatching || resyncDueToError) { | ||
existingSuppressions = []; | ||
existingPolicy = {}; | ||
yield this.dropCache(rootPath, projectSlug); | ||
} | ||
@@ -173,4 +183,3 @@ const projectValidationData = yield this.refetchProjectValidationData(repoData, projectDetails.data.getProject.projectRepository.id, projectDetails.data.getProject.policy.updatedAt, ownerProjectSlug, tokenInfo); | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const repoData = yield this.getRootGitData(rootPath); | ||
yield this.dropCacheMetadata(repoData); | ||
yield this.dropCache(rootPath, projectSlug); | ||
return this.synchronize(tokenInfo, rootPath, projectSlug); | ||
@@ -236,3 +245,3 @@ }); | ||
} | ||
getRootGitData(rootPath) { | ||
getRootGitData(rootPath, projectSlug) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
@@ -243,2 +252,5 @@ const repoData = yield this._gitHandler.getRepoRemoteData(rootPath); | ||
} | ||
if (projectSlug) { | ||
repoData.ownerProjectSlug = projectSlug; | ||
} | ||
return repoData; | ||
@@ -301,5 +313,10 @@ }); | ||
} | ||
dropCacheMetadata(repoData) { | ||
dropCache(rootPath, projectSlug) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this._storageHandlerJsonCache.emptyStoreData(this.getMetadataFileName(repoData)); | ||
const cacheId = this.getCacheId(rootPath, projectSlug); | ||
delete this._dataCache[cacheId]; | ||
const repoData = yield this.getRootGitData(rootPath, projectSlug); | ||
yield this._storageHandlerJsonCache.emptyStoreData(this.getMetadataFileName(repoData)); | ||
yield this._storageHandlerJsonCache.emptyStoreData(this.getSuppressionsFileName(repoData)); | ||
yield this._storageHandlerPolicy.emptyStoreData(this.getPolicyFileName(repoData)); | ||
}); | ||
@@ -311,6 +328,6 @@ } | ||
getSuppressionsFileName(repoData) { | ||
return this.getFileName(repoData, 'suppressions'); | ||
return this.getFileName(repoData, 'suppressions', 'json'); | ||
} | ||
getMetadataFileName(repoData) { | ||
return this.getFileName(repoData, 'metadata'); | ||
return this.getFileName(repoData, 'metadata', 'json'); | ||
} | ||
@@ -325,5 +342,9 @@ getFileName(repoData, suffix, ext = 'yaml') { | ||
}); | ||
return `${provider}-${repoData.owner}-${repoData.name}.${suffix}.${ext}`; | ||
let projectSuffix = ''; | ||
if (repoData.ownerProjectSlug) { | ||
projectSuffix = `.${repoData.ownerProjectSlug}`; | ||
} | ||
return `${provider}-${repoData.owner}-${repoData.name}${projectSuffix}.${suffix}.${ext}`; | ||
} | ||
} | ||
exports.ProjectSynchronizer = ProjectSynchronizer; |
@@ -60,2 +60,5 @@ import { dirname, resolve } from 'path'; | ||
assert.equal(callsCounter.getSuppression, 1); | ||
const suppressions1 = synchronizer.getRepositorySuppressions(storagePath); | ||
assert.isArray(suppressions1); | ||
assert.equal(suppressions1.length, 1); | ||
await synchronizer.synchronize({ | ||
@@ -68,2 +71,5 @@ accessToken: 'SAMPLE_TOKEN' | ||
assert.equal(callsCounter.getSuppression, 2); | ||
const suppressions2 = synchronizer.getRepositorySuppressions(storagePath); | ||
assert.isArray(suppressions2); | ||
assert.equal(suppressions2.length, 2); | ||
await synchronizer.forceSynchronize({ | ||
@@ -76,3 +82,36 @@ accessToken: 'SAMPLE_TOKEN' | ||
assert.equal(callsCounter.getSuppression, 3); | ||
// We force sync and 3rd stubbed getSuppressions call returns no suppressions. | ||
// This checks if memory and file cache was purged properly. | ||
const suppressions3 = synchronizer.getRepositorySuppressions(storagePath); | ||
assert.isArray(suppressions3); | ||
assert.equal(suppressions3.length, 0); | ||
}); | ||
it('refetches whole data when repo owner project changes', async () => { | ||
const storagePath = await createTmpConfigDir(); | ||
const synchronizer = createSynchronizer(storagePath, stubs); | ||
const callsCounter = stubApi(synchronizer, stubs); | ||
await synchronizer.synchronize({ | ||
accessToken: 'SAMPLE_TOKEN' | ||
}, storagePath); | ||
assert.equal(callsCounter.getUser, 1); | ||
assert.equal(callsCounter.getProject, 1); | ||
assert.equal(callsCounter.getPolicy, 1); | ||
assert.equal(callsCounter.getSuppression, 1); | ||
const suppressions1 = synchronizer.getRepositorySuppressions(storagePath); | ||
assert.isArray(suppressions1); | ||
assert.equal(suppressions1.length, 1); | ||
assert.isTrue(suppressions1[0].isAccepted); | ||
await synchronizer.synchronize({ | ||
accessToken: 'SAMPLE_TOKEN' | ||
}, storagePath, 'new-project'); | ||
assert.equal(callsCounter.getUser, 1); // Since we pass project slug. | ||
assert.equal(callsCounter.getProject, 2); | ||
assert.equal(callsCounter.getPolicy, 2); | ||
assert.equal(callsCounter.getSuppression, 2); | ||
const suppressions2 = synchronizer.getRepositorySuppressions(storagePath, 'new-project'); | ||
assert.isArray(suppressions2); | ||
assert.equal(suppressions2.length, 2); | ||
assert.isTrue(suppressions2[0].isAccepted); | ||
assert.isTrue(suppressions2[1].isUnderReview); | ||
}); | ||
it('synchronizes correctly', async () => { | ||
@@ -79,0 +118,0 @@ const storagePath = await createTmpConfigDir(); |
@@ -133,2 +133,7 @@ import { SuppressionStatus } from '@monokle/types'; | ||
}; | ||
export declare type ApiToggleSuppressionData = { | ||
data: { | ||
toggleSuppression: ApiSuppression; | ||
}; | ||
}; | ||
export declare class ApiHandler { | ||
@@ -149,3 +154,3 @@ private _apiUrl; | ||
getRepoId(projectSlug: string, repoOwner: string, repoName: string, tokenInfo: TokenInfo): Promise<ApiRepoIdData | undefined>; | ||
toggleSuppression(fingerprint: string, repoId: string, description: string, location: string | undefined, tokenInfo: TokenInfo): Promise<ApiSuppressionsData | undefined>; | ||
toggleSuppression(fingerprint: string, repoId: string, description: string, location: string | undefined, tokenInfo: TokenInfo): Promise<ApiToggleSuppressionData | undefined>; | ||
generateDeepLink(path: string): string; | ||
@@ -152,0 +157,0 @@ queryApi<OUT>(query: string, tokenInfo: TokenInfo, variables?: {}): Promise<OUT | undefined>; |
@@ -67,3 +67,3 @@ /// <reference types="node" /> | ||
private readCacheMetadata; | ||
private dropCacheMetadata; | ||
private dropCache; | ||
private getPolicyFileName; | ||
@@ -70,0 +70,0 @@ private getSuppressionsFileName; |
@@ -52,3 +52,3 @@ import slugify from 'slugify'; | ||
} | ||
const repoData = await this.getRootGitData(rootPath); | ||
const repoData = await this.getRootGitData(rootPath, projectSlug); | ||
let { id } = this.getRepositoryData(rootPath, projectSlug); | ||
@@ -71,5 +71,11 @@ let { slug } = this.getProjectInfo(rootPath, projectSlug); | ||
const suppressionResult = await this._apiHandler.toggleSuppression(fingerprint, id, description, location, tokenInfo); | ||
if (suppressionResult?.data?.getSuppressions?.data?.length) { | ||
const existingSuppressions = await this.readSuppressions(repoData); | ||
const allSuppressions = this.mergeSuppressions(existingSuppressions, suppressionResult.data.getSuppressions.data); | ||
if (suppressionResult?.data?.toggleSuppression) { | ||
let existingSuppressions = []; | ||
try { | ||
existingSuppressions = await this.readSuppressions(repoData); | ||
} | ||
catch (err) { | ||
existingSuppressions = this.getRepositorySuppressions(rootPath, projectSlug); | ||
} | ||
const allSuppressions = this.mergeSuppressions(existingSuppressions, [suppressionResult?.data?.toggleSuppression]); | ||
await this.storeSuppressions(allSuppressions, repoData); | ||
@@ -86,3 +92,3 @@ const cacheId = this.getCacheId(rootPath, projectSlug); | ||
} | ||
const repoData = await this.getRootGitData(rootPath); | ||
const repoData = await this.getRootGitData(rootPath, projectSlug); | ||
const ownerProjectSlug = projectSlug ?? (await this.getMatchingProject(repoData, tokenInfo))?.slug; | ||
@@ -114,4 +120,8 @@ const cacheId = this.getCacheId(rootPath, projectSlug); | ||
} | ||
if (resyncDueToError) { | ||
await this.dropCacheMetadata(repoData); | ||
const cacheMetadata = await this.readCacheMetadata(repoData); | ||
const isCachedProjectMatching = ownerProjectSlug === cacheMetadata?.projectSlug; | ||
if (!isCachedProjectMatching || resyncDueToError) { | ||
existingSuppressions = []; | ||
existingPolicy = {}; | ||
await this.dropCache(rootPath, projectSlug); | ||
} | ||
@@ -153,4 +163,3 @@ const projectValidationData = await this.refetchProjectValidationData(repoData, projectDetails.data.getProject.projectRepository.id, projectDetails.data.getProject.policy.updatedAt, ownerProjectSlug, tokenInfo); | ||
async forceSynchronize(tokenInfo, rootPath, projectSlug) { | ||
const repoData = await this.getRootGitData(rootPath); | ||
await this.dropCacheMetadata(repoData); | ||
await this.dropCache(rootPath, projectSlug); | ||
return this.synchronize(tokenInfo, rootPath, projectSlug); | ||
@@ -207,3 +216,3 @@ } | ||
} | ||
async getRootGitData(rootPath) { | ||
async getRootGitData(rootPath, projectSlug) { | ||
const repoData = await this._gitHandler.getRepoRemoteData(rootPath); | ||
@@ -213,2 +222,5 @@ if (!repoData) { | ||
} | ||
if (projectSlug) { | ||
repoData.ownerProjectSlug = projectSlug; | ||
} | ||
return repoData; | ||
@@ -256,4 +268,9 @@ } | ||
} | ||
async dropCacheMetadata(repoData) { | ||
return this._storageHandlerJsonCache.emptyStoreData(this.getMetadataFileName(repoData)); | ||
async dropCache(rootPath, projectSlug) { | ||
const cacheId = this.getCacheId(rootPath, projectSlug); | ||
delete this._dataCache[cacheId]; | ||
const repoData = await this.getRootGitData(rootPath, projectSlug); | ||
await this._storageHandlerJsonCache.emptyStoreData(this.getMetadataFileName(repoData)); | ||
await this._storageHandlerJsonCache.emptyStoreData(this.getSuppressionsFileName(repoData)); | ||
await this._storageHandlerPolicy.emptyStoreData(this.getPolicyFileName(repoData)); | ||
} | ||
@@ -264,6 +281,6 @@ getPolicyFileName(repoData) { | ||
getSuppressionsFileName(repoData) { | ||
return this.getFileName(repoData, 'suppressions'); | ||
return this.getFileName(repoData, 'suppressions', 'json'); | ||
} | ||
getMetadataFileName(repoData) { | ||
return this.getFileName(repoData, 'metadata'); | ||
return this.getFileName(repoData, 'metadata', 'json'); | ||
} | ||
@@ -278,4 +295,8 @@ getFileName(repoData, suffix, ext = 'yaml') { | ||
}); | ||
return `${provider}-${repoData.owner}-${repoData.name}.${suffix}.${ext}`; | ||
let projectSuffix = ''; | ||
if (repoData.ownerProjectSlug) { | ||
projectSuffix = `.${repoData.ownerProjectSlug}`; | ||
} | ||
return `${provider}-${repoData.owner}-${repoData.name}${projectSuffix}.${suffix}.${ext}`; | ||
} | ||
} |
{ | ||
"name": "@monokle/synchronizer", | ||
"version": "0.14.1", | ||
"version": "0.14.2", | ||
"description": "Monokle Cloud synchronizer", | ||
@@ -5,0 +5,0 @@ "author": "Kubeshop", |
295249
6488