@monokle/synchronizer
Advanced tools
Comparing version 0.6.0 to 0.7.0
@@ -29,2 +29,7 @@ export declare type ApiUserProjectRepo = { | ||
}; | ||
export declare type ApiProjectData = { | ||
data: { | ||
getProject: ApiUserProject; | ||
}; | ||
}; | ||
export declare type ApiPolicyData = { | ||
@@ -34,2 +39,3 @@ data: { | ||
id: number; | ||
name: string; | ||
policy: { | ||
@@ -47,2 +53,3 @@ id: string; | ||
getUser(accessToken: string): Promise<ApiUserData | undefined>; | ||
getProject(slug: string, accessToken: string): Promise<ApiProjectData | undefined>; | ||
getPolicy(slug: string, accessToken: string): Promise<ApiPolicyData | undefined>; | ||
@@ -49,0 +56,0 @@ generateDeepLink(path: string): string; |
@@ -43,2 +43,20 @@ "use strict"; | ||
`; | ||
const getProjectQuery = ` | ||
query getProject($slug: String!) { | ||
getProject(input: { slug: $slug }) { | ||
id | ||
name | ||
slug | ||
repositories { | ||
id | ||
projectId | ||
provider | ||
owner | ||
name | ||
prChecks | ||
canEnablePrChecks | ||
} | ||
} | ||
} | ||
`; | ||
const getPolicyQuery = ` | ||
@@ -48,2 +66,3 @@ query getPolicy($slug: String!) { | ||
id | ||
name | ||
policy { | ||
@@ -68,2 +87,7 @@ id | ||
} | ||
getProject(slug, accessToken) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.queryApi(getProjectQuery, accessToken, { slug }); | ||
}); | ||
} | ||
getPolicy(slug, accessToken) { | ||
@@ -70,0 +94,0 @@ return __awaiter(this, void 0, void 0, function* () { |
@@ -13,2 +13,5 @@ /// <reference types="node" /> | ||
}; | ||
export declare type ProjectInputData = { | ||
slug: string; | ||
}; | ||
export declare type PolicyData = { | ||
@@ -33,6 +36,9 @@ valid: boolean; | ||
getProjectInfo(repoData: RepoRemoteData, accessToken: string, forceRefetch?: boolean): Promise<ProjectInfo | null>; | ||
getProjectInfo(projectData: ProjectInputData, accessToken: string, forceRefetch?: boolean): Promise<ProjectInfo | null>; | ||
getPolicy(rootPath: string, forceRefetch?: boolean, accessToken?: string): Promise<PolicyData>; | ||
getPolicy(repoData: RepoRemoteData, forceRefetch?: boolean, accessToken?: string): Promise<PolicyData>; | ||
getPolicy(projectData: ProjectInputData, forceRefetch?: boolean, accessToken?: string): Promise<PolicyData>; | ||
synchronize(rootPath: string, accessToken: string): Promise<PolicyData>; | ||
synchronize(repoData: RepoRemoteData, accessToken: string): Promise<PolicyData>; | ||
synchronize(projectData: ProjectInputData, accessToken: string): Promise<PolicyData>; | ||
generateDeepLinkProjectList(): string; | ||
@@ -42,4 +48,6 @@ generateDeepLinkProject(projectSlug: string): string; | ||
generateDeepLink(path: string): string; | ||
private fetchPolicy; | ||
private fetchPolicyForProject; | ||
private fetchPolicyForRepo; | ||
private getMatchingProject; | ||
private getProject; | ||
private getRootGitData; | ||
@@ -51,2 +59,4 @@ private getPolicyPath; | ||
private getRepoCacheId; | ||
private getRepoOrProjectData; | ||
private isProjectData; | ||
} |
@@ -26,6 +26,6 @@ "use strict"; | ||
} | ||
getProjectInfo(repoDataOrRootPath, accessToken, forceRefetch = false) { | ||
getProjectInfo(rootPathOrRepoDataOrProjectData, accessToken, forceRefetch = false) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const repoData = typeof repoDataOrRootPath === 'string' ? yield this.getRootGitData(repoDataOrRootPath) : repoDataOrRootPath; | ||
const cacheId = this.getRepoCacheId(repoData, accessToken); | ||
const inputData = yield this.getRepoOrProjectData(rootPathOrRepoDataOrProjectData); | ||
const cacheId = this.getRepoCacheId(inputData, accessToken); | ||
const cachedProjectInfo = this._projectDataCache[cacheId]; | ||
@@ -39,3 +39,5 @@ if (cachedProjectInfo && !forceRefetch) { | ||
} | ||
const freshProjectInfo = yield this.getMatchingProject(repoData, accessToken); | ||
const freshProjectInfo = this.isProjectData(inputData) ? | ||
yield this.getProject(inputData, accessToken) : | ||
yield this.getMatchingProject(inputData, accessToken); | ||
return !freshProjectInfo ? null : { | ||
@@ -48,3 +50,3 @@ id: freshProjectInfo.id, | ||
} | ||
getPolicy(repoDataOrRootPath, forceRefetch = false, accessToken = '') { | ||
getPolicy(rootPathOrRepoDataOrProjectData, forceRefetch = false, accessToken = '') { | ||
var _a; | ||
@@ -55,11 +57,11 @@ return __awaiter(this, void 0, void 0, function* () { | ||
} | ||
const repoData = typeof repoDataOrRootPath === 'string' ? yield this.getRootGitData(repoDataOrRootPath) : repoDataOrRootPath; | ||
const inputData = yield this.getRepoOrProjectData(rootPathOrRepoDataOrProjectData); | ||
if (forceRefetch) { | ||
yield this.synchronize(repoData, accessToken); | ||
yield this.synchronize(inputData, accessToken); | ||
} | ||
const policyContent = (_a = (yield this.readPolicy(repoData))) !== null && _a !== void 0 ? _a : {}; | ||
const policyContent = (_a = (yield this.readPolicy(inputData))) !== null && _a !== void 0 ? _a : {}; | ||
const isValidPolicy = Object.keys(policyContent).length > 0; | ||
return { | ||
valid: isValidPolicy, | ||
path: isValidPolicy ? this.getPolicyPath(repoData) : '', | ||
path: isValidPolicy ? this.getPolicyPath(inputData) : '', | ||
policy: policyContent, | ||
@@ -69,3 +71,3 @@ }; | ||
} | ||
synchronize(repoDataOrRootPath, accessToken) { | ||
synchronize(rootPathOrRepoDataOrProjectData, accessToken) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
@@ -75,4 +77,10 @@ if (this._pullPromise) { | ||
} | ||
if (this.isProjectData(rootPathOrRepoDataOrProjectData)) { | ||
const projectData = rootPathOrRepoDataOrProjectData; | ||
this._pullPromise = this.fetchPolicyForProject(projectData, accessToken); | ||
return this._pullPromise; | ||
} | ||
const repoDataOrRootPath = rootPathOrRepoDataOrProjectData; | ||
const repoData = typeof repoDataOrRootPath === 'string' ? yield this.getRootGitData(repoDataOrRootPath) : repoDataOrRootPath; | ||
this._pullPromise = this.fetchPolicy(repoData, accessToken); | ||
this._pullPromise = this.fetchPolicyForRepo(repoData, accessToken); | ||
return this._pullPromise; | ||
@@ -93,3 +101,47 @@ }); | ||
} | ||
fetchPolicy(repoData, accessToken) { | ||
fetchPolicyForProject(projectData, accessToken) { | ||
var _a, _b, _c, _d, _e; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const policyData = { | ||
valid: false, | ||
path: '', | ||
policy: {}, | ||
}; | ||
try { | ||
const repoPolicy = yield this._apiHandler.getPolicy(projectData.slug, accessToken); | ||
const policyUrl = this.generateDeepLinkProjectPolicy(projectData.slug); | ||
if (!((_b = (_a = repoPolicy === null || repoPolicy === void 0 ? void 0 : repoPolicy.data) === null || _a === void 0 ? void 0 : _a.getProject) === null || _b === void 0 ? void 0 : _b.policy)) { | ||
throw new Error(`The '${(_e = (_d = (_c = repoPolicy === null || repoPolicy === void 0 ? void 0 : repoPolicy.data) === null || _c === void 0 ? void 0 : _c.getProject) === null || _d === void 0 ? void 0 : _d.name) !== null && _e !== void 0 ? _e : projectData.slug}' project does not have policy defined. Configure it on ${policyUrl}.`); | ||
} | ||
const cacheId = this.getRepoCacheId(projectData, accessToken); | ||
this._projectDataCache[cacheId] = { | ||
id: repoPolicy.data.getProject.id, | ||
slug: projectData.slug, | ||
name: repoPolicy.data.getProject.name, | ||
repositories: [], | ||
}; | ||
const policyContent = repoPolicy.data.getProject.policy.json; | ||
const comment = [ | ||
` This is remote policy downloaded from ${this._apiHandler.apiUrl}.`, | ||
` You can adjust it on ${policyUrl}.`, | ||
].join('\n'); | ||
const policyPath = yield this.storePolicy(policyContent, projectData, comment); | ||
if (!policyPath) { | ||
throw new Error(`Error storing policy in local filesystem.`); | ||
} | ||
policyData.valid = true; | ||
policyData.path = policyPath; | ||
policyData.policy = policyContent; | ||
return policyData; | ||
} | ||
catch (error) { | ||
throw error; | ||
} | ||
finally { | ||
this._pullPromise = undefined; | ||
this.emit('synchronize', policyData); | ||
} | ||
}); | ||
} | ||
fetchPolicyForRepo(repoData, accessToken) { | ||
var _a, _b; | ||
@@ -161,2 +213,13 @@ return __awaiter(this, void 0, void 0, function* () { | ||
} | ||
getProject(projectData, accessToken) { | ||
var _a, _b, _c, _d; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const projectInfo = yield this._apiHandler.getProject(projectData.slug, accessToken); | ||
if ((_b = (_a = projectInfo === null || projectInfo === void 0 ? void 0 : projectInfo.data) === null || _a === void 0 ? void 0 : _a.getProject) === null || _b === void 0 ? void 0 : _b.id) { | ||
const cacheId = this.getRepoCacheId(projectData, accessToken); | ||
this._projectDataCache[cacheId] = projectInfo.data.getProject; | ||
} | ||
return !((_d = (_c = projectInfo === null || projectInfo === void 0 ? void 0 : projectInfo.data) === null || _c === void 0 ? void 0 : _c.getProject) === null || _d === void 0 ? void 0 : _d.id) ? null : projectInfo.data.getProject; | ||
}); | ||
} | ||
getRootGitData(rootPath) { | ||
@@ -171,16 +234,20 @@ return __awaiter(this, void 0, void 0, function* () { | ||
} | ||
getPolicyPath(repoData) { | ||
return this._storageHandler.getStoreDataFilePath(this.getPolicyFileName(repoData)); | ||
getPolicyPath(inputData) { | ||
return this._storageHandler.getStoreDataFilePath(this.getPolicyFileName(inputData)); | ||
} | ||
storePolicy(policyContent, repoData, comment) { | ||
storePolicy(policyContent, inputData, comment) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this._storageHandler.setStoreData(policyContent, this.getPolicyFileName(repoData), comment); | ||
return this._storageHandler.setStoreData(policyContent, this.getPolicyFileName(inputData), comment); | ||
}); | ||
} | ||
readPolicy(repoData) { | ||
readPolicy(inputData) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this._storageHandler.getStoreData(this.getPolicyFileName(repoData)); | ||
return this._storageHandler.getStoreData(this.getPolicyFileName(inputData)); | ||
}); | ||
} | ||
getPolicyFileName(repoData) { | ||
getPolicyFileName(inputData) { | ||
if (this.isProjectData(inputData)) { | ||
return `${inputData.slug}.policy.yaml`; | ||
} | ||
const repoData = inputData; | ||
const provider = (0, slugify_1.default)(repoData.provider, { | ||
@@ -195,6 +262,21 @@ replacement: '_', | ||
} | ||
getRepoCacheId(repoData, prefix) { | ||
getRepoCacheId(inputData, prefix) { | ||
if (this.isProjectData(inputData)) { | ||
return `${prefix}-${inputData.slug}`; | ||
} | ||
const repoData = inputData; | ||
return `${prefix}-${repoData.provider}-${repoData.owner}-${repoData.name}`; | ||
} | ||
getRepoOrProjectData(inputData) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (this.isProjectData(inputData)) { | ||
return inputData; | ||
} | ||
return typeof inputData === 'string' ? yield this.getRootGitData(inputData) : inputData; | ||
}); | ||
} | ||
isProjectData(projectData) { | ||
return Object.keys(projectData).length === 1 && projectData.slug; | ||
} | ||
} | ||
exports.Synchronizer = Synchronizer; |
@@ -169,2 +169,57 @@ import { dirname, resolve } from 'path'; | ||
}); | ||
it('fetches and returns valid policy based on project slug', async () => { | ||
const storagePath = await createTmpConfigDir(); | ||
const synchronizer = createDefaultMonokleSynchronizer(new StorageHandlerPolicy(storagePath)); | ||
const queryApiStub = sinon.stub(synchronizer._apiHandler, 'queryApi').callsFake(async (...args) => { | ||
const query = args[0]; | ||
if (query.includes('query getPolicy')) { | ||
return { | ||
data: { | ||
getProject: { | ||
id: 6000, | ||
name: 'User6 Project', | ||
policy: { | ||
id: 'user6-proj-policy-id', | ||
json: { | ||
plugins: { | ||
'pod-security-standards': true, | ||
'yaml-syntax': false, | ||
'resource-links': false, | ||
'kubernetes-schema': false, | ||
practices: true, | ||
}, | ||
rules: { | ||
'pod-security-standards/host-process': 'err', | ||
}, | ||
settings: { | ||
'kubernetes-schema': { | ||
schemaVersion: 'v1.27.1', | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}; | ||
} | ||
return {}; | ||
}); | ||
stubs.push(queryApiStub); | ||
const policyData = { | ||
slug: 'user6-proj-abc', | ||
}; | ||
const policy = await synchronizer.getPolicy(policyData); | ||
assert.isFalse(policy.valid); | ||
const newPolicy = await synchronizer.getPolicy(policyData, true, 'SAMPLE_ACCESS_TOKEN'); | ||
assert.isObject(newPolicy); | ||
assert.isTrue(newPolicy.valid); | ||
assert.isNotEmpty(newPolicy.path); | ||
assert.match(newPolicy.path, /user6-proj-abc.policy.yaml$/); | ||
assert.isNotEmpty(newPolicy.policy); | ||
assert.isNotEmpty(newPolicy.policy.plugins); | ||
assert.isNotEmpty(newPolicy.policy.rules); | ||
assert.isNotEmpty(newPolicy.policy.settings); | ||
const getPolicyResult = await synchronizer.getPolicy(policyData); | ||
assert.deepEqual(newPolicy, getPolicyResult); | ||
}); | ||
it('emits synchronize event after policy is fetched', async () => { | ||
@@ -261,3 +316,3 @@ const storagePath = await createTmpConfigDir(); | ||
describe('getProjectInfo', () => { | ||
it('returns valid project info', async () => { | ||
it('returns valid project info (repo data)', async () => { | ||
const storagePath = await createTmpConfigDir(); | ||
@@ -313,2 +368,32 @@ const synchronizer = createDefaultMonokleSynchronizer(new StorageHandlerPolicy(storagePath)); | ||
}); | ||
it('returns valid project info (project data)', async () => { | ||
const storagePath = await createTmpConfigDir(); | ||
const synchronizer = createDefaultMonokleSynchronizer(new StorageHandlerPolicy(storagePath)); | ||
const queryApiStub = sinon.stub(synchronizer._apiHandler, 'queryApi').callsFake(async (...args) => { | ||
const query = args[0]; | ||
if (query.includes('query getProject')) { | ||
return { | ||
data: { | ||
getProject: { | ||
id: 7000, | ||
slug: 'user7-proj-foobar', | ||
name: 'User7 Project', | ||
repositories: [], | ||
}, | ||
}, | ||
}; | ||
} | ||
return {}; | ||
}); | ||
stubs.push(queryApiStub); | ||
const projectData = { | ||
slug: 'user7-proj-foobar', | ||
}; | ||
const projectInfo = await synchronizer.getProjectInfo(projectData, 'SAMPLE_ACCESS_TOKEN'); | ||
assert.isObject(projectInfo); | ||
assert.equal(projectInfo.id, 7000); | ||
assert.equal(projectInfo.slug, 'user7-proj-foobar'); | ||
assert.equal(projectInfo.name, 'User7 Project'); | ||
assert.equal(queryApiStub.callCount, 1); | ||
}); | ||
it('utilizes cache correctly', async () => { | ||
@@ -315,0 +400,0 @@ const storagePath = await createTmpConfigDir(); |
@@ -29,2 +29,7 @@ export declare type ApiUserProjectRepo = { | ||
}; | ||
export declare type ApiProjectData = { | ||
data: { | ||
getProject: ApiUserProject; | ||
}; | ||
}; | ||
export declare type ApiPolicyData = { | ||
@@ -34,2 +39,3 @@ data: { | ||
id: number; | ||
name: string; | ||
policy: { | ||
@@ -47,2 +53,3 @@ id: string; | ||
getUser(accessToken: string): Promise<ApiUserData | undefined>; | ||
getProject(slug: string, accessToken: string): Promise<ApiProjectData | undefined>; | ||
getPolicy(slug: string, accessToken: string): Promise<ApiPolicyData | undefined>; | ||
@@ -49,0 +56,0 @@ generateDeepLink(path: string): string; |
@@ -28,2 +28,20 @@ import normalizeUrl from 'normalize-url'; | ||
`; | ||
const getProjectQuery = ` | ||
query getProject($slug: String!) { | ||
getProject(input: { slug: $slug }) { | ||
id | ||
name | ||
slug | ||
repositories { | ||
id | ||
projectId | ||
provider | ||
owner | ||
name | ||
prChecks | ||
canEnablePrChecks | ||
} | ||
} | ||
} | ||
`; | ||
const getPolicyQuery = ` | ||
@@ -33,2 +51,3 @@ query getPolicy($slug: String!) { | ||
id | ||
name | ||
policy { | ||
@@ -52,2 +71,5 @@ id | ||
} | ||
async getProject(slug, accessToken) { | ||
return this.queryApi(getProjectQuery, accessToken, { slug }); | ||
} | ||
async getPolicy(slug, accessToken) { | ||
@@ -54,0 +76,0 @@ return this.queryApi(getPolicyQuery, accessToken, { slug }); |
@@ -13,2 +13,5 @@ /// <reference types="node" /> | ||
}; | ||
export declare type ProjectInputData = { | ||
slug: string; | ||
}; | ||
export declare type PolicyData = { | ||
@@ -33,6 +36,9 @@ valid: boolean; | ||
getProjectInfo(repoData: RepoRemoteData, accessToken: string, forceRefetch?: boolean): Promise<ProjectInfo | null>; | ||
getProjectInfo(projectData: ProjectInputData, accessToken: string, forceRefetch?: boolean): Promise<ProjectInfo | null>; | ||
getPolicy(rootPath: string, forceRefetch?: boolean, accessToken?: string): Promise<PolicyData>; | ||
getPolicy(repoData: RepoRemoteData, forceRefetch?: boolean, accessToken?: string): Promise<PolicyData>; | ||
getPolicy(projectData: ProjectInputData, forceRefetch?: boolean, accessToken?: string): Promise<PolicyData>; | ||
synchronize(rootPath: string, accessToken: string): Promise<PolicyData>; | ||
synchronize(repoData: RepoRemoteData, accessToken: string): Promise<PolicyData>; | ||
synchronize(projectData: ProjectInputData, accessToken: string): Promise<PolicyData>; | ||
generateDeepLinkProjectList(): string; | ||
@@ -42,4 +48,6 @@ generateDeepLinkProject(projectSlug: string): string; | ||
generateDeepLink(path: string): string; | ||
private fetchPolicy; | ||
private fetchPolicyForProject; | ||
private fetchPolicyForRepo; | ||
private getMatchingProject; | ||
private getProject; | ||
private getRootGitData; | ||
@@ -51,2 +59,4 @@ private getPolicyPath; | ||
private getRepoCacheId; | ||
private getRepoOrProjectData; | ||
private isProjectData; | ||
} |
@@ -15,5 +15,5 @@ import slugify from 'slugify'; | ||
} | ||
async getProjectInfo(repoDataOrRootPath, accessToken, forceRefetch = false) { | ||
const repoData = typeof repoDataOrRootPath === 'string' ? await this.getRootGitData(repoDataOrRootPath) : repoDataOrRootPath; | ||
const cacheId = this.getRepoCacheId(repoData, accessToken); | ||
async getProjectInfo(rootPathOrRepoDataOrProjectData, accessToken, forceRefetch = false) { | ||
const inputData = await this.getRepoOrProjectData(rootPathOrRepoDataOrProjectData); | ||
const cacheId = this.getRepoCacheId(inputData, accessToken); | ||
const cachedProjectInfo = this._projectDataCache[cacheId]; | ||
@@ -27,3 +27,5 @@ if (cachedProjectInfo && !forceRefetch) { | ||
} | ||
const freshProjectInfo = await this.getMatchingProject(repoData, accessToken); | ||
const freshProjectInfo = this.isProjectData(inputData) ? | ||
await this.getProject(inputData, accessToken) : | ||
await this.getMatchingProject(inputData, accessToken); | ||
return !freshProjectInfo ? null : { | ||
@@ -35,24 +37,30 @@ id: freshProjectInfo.id, | ||
} | ||
async getPolicy(repoDataOrRootPath, forceRefetch = false, accessToken = '') { | ||
async getPolicy(rootPathOrRepoDataOrProjectData, forceRefetch = false, accessToken = '') { | ||
if (forceRefetch && (!accessToken || accessToken?.length === 0)) { | ||
throw new Error('Cannot force refetch without access token.'); | ||
} | ||
const repoData = typeof repoDataOrRootPath === 'string' ? await this.getRootGitData(repoDataOrRootPath) : repoDataOrRootPath; | ||
const inputData = await this.getRepoOrProjectData(rootPathOrRepoDataOrProjectData); | ||
if (forceRefetch) { | ||
await this.synchronize(repoData, accessToken); | ||
await this.synchronize(inputData, accessToken); | ||
} | ||
const policyContent = (await this.readPolicy(repoData)) ?? {}; | ||
const policyContent = (await this.readPolicy(inputData)) ?? {}; | ||
const isValidPolicy = Object.keys(policyContent).length > 0; | ||
return { | ||
valid: isValidPolicy, | ||
path: isValidPolicy ? this.getPolicyPath(repoData) : '', | ||
path: isValidPolicy ? this.getPolicyPath(inputData) : '', | ||
policy: policyContent, | ||
}; | ||
} | ||
async synchronize(repoDataOrRootPath, accessToken) { | ||
async synchronize(rootPathOrRepoDataOrProjectData, accessToken) { | ||
if (this._pullPromise) { | ||
return this._pullPromise; | ||
} | ||
if (this.isProjectData(rootPathOrRepoDataOrProjectData)) { | ||
const projectData = rootPathOrRepoDataOrProjectData; | ||
this._pullPromise = this.fetchPolicyForProject(projectData, accessToken); | ||
return this._pullPromise; | ||
} | ||
const repoDataOrRootPath = rootPathOrRepoDataOrProjectData; | ||
const repoData = typeof repoDataOrRootPath === 'string' ? await this.getRootGitData(repoDataOrRootPath) : repoDataOrRootPath; | ||
this._pullPromise = this.fetchPolicy(repoData, accessToken); | ||
this._pullPromise = this.fetchPolicyForRepo(repoData, accessToken); | ||
return this._pullPromise; | ||
@@ -72,3 +80,3 @@ } | ||
} | ||
async fetchPolicy(repoData, accessToken) { | ||
async fetchPolicyForProject(projectData, accessToken) { | ||
const policyData = { | ||
@@ -80,2 +88,43 @@ valid: false, | ||
try { | ||
const repoPolicy = await this._apiHandler.getPolicy(projectData.slug, accessToken); | ||
const policyUrl = this.generateDeepLinkProjectPolicy(projectData.slug); | ||
if (!repoPolicy?.data?.getProject?.policy) { | ||
throw new Error(`The '${repoPolicy?.data?.getProject?.name ?? projectData.slug}' project does not have policy defined. Configure it on ${policyUrl}.`); | ||
} | ||
const cacheId = this.getRepoCacheId(projectData, accessToken); | ||
this._projectDataCache[cacheId] = { | ||
id: repoPolicy.data.getProject.id, | ||
slug: projectData.slug, | ||
name: repoPolicy.data.getProject.name, | ||
repositories: [], | ||
}; | ||
const policyContent = repoPolicy.data.getProject.policy.json; | ||
const comment = [ | ||
` This is remote policy downloaded from ${this._apiHandler.apiUrl}.`, | ||
` You can adjust it on ${policyUrl}.`, | ||
].join('\n'); | ||
const policyPath = await this.storePolicy(policyContent, projectData, comment); | ||
if (!policyPath) { | ||
throw new Error(`Error storing policy in local filesystem.`); | ||
} | ||
policyData.valid = true; | ||
policyData.path = policyPath; | ||
policyData.policy = policyContent; | ||
return policyData; | ||
} | ||
catch (error) { | ||
throw error; | ||
} | ||
finally { | ||
this._pullPromise = undefined; | ||
this.emit('synchronize', policyData); | ||
} | ||
} | ||
async fetchPolicyForRepo(repoData, accessToken) { | ||
const policyData = { | ||
valid: false, | ||
path: '', | ||
policy: {}, | ||
}; | ||
try { | ||
const repoProject = await this.getMatchingProject(repoData, accessToken); | ||
@@ -135,2 +184,10 @@ const repoId = `${repoData.provider}:${repoData.owner}/${repoData.name}`; | ||
} | ||
async getProject(projectData, accessToken) { | ||
const projectInfo = await this._apiHandler.getProject(projectData.slug, accessToken); | ||
if (projectInfo?.data?.getProject?.id) { | ||
const cacheId = this.getRepoCacheId(projectData, accessToken); | ||
this._projectDataCache[cacheId] = projectInfo.data.getProject; | ||
} | ||
return !(projectInfo?.data?.getProject?.id) ? null : projectInfo.data.getProject; | ||
} | ||
async getRootGitData(rootPath) { | ||
@@ -143,12 +200,16 @@ const repoData = await this._gitHandler.getRepoRemoteData(rootPath); | ||
} | ||
getPolicyPath(repoData) { | ||
return this._storageHandler.getStoreDataFilePath(this.getPolicyFileName(repoData)); | ||
getPolicyPath(inputData) { | ||
return this._storageHandler.getStoreDataFilePath(this.getPolicyFileName(inputData)); | ||
} | ||
async storePolicy(policyContent, repoData, comment) { | ||
return this._storageHandler.setStoreData(policyContent, this.getPolicyFileName(repoData), comment); | ||
async storePolicy(policyContent, inputData, comment) { | ||
return this._storageHandler.setStoreData(policyContent, this.getPolicyFileName(inputData), comment); | ||
} | ||
async readPolicy(repoData) { | ||
return this._storageHandler.getStoreData(this.getPolicyFileName(repoData)); | ||
async readPolicy(inputData) { | ||
return this._storageHandler.getStoreData(this.getPolicyFileName(inputData)); | ||
} | ||
getPolicyFileName(repoData) { | ||
getPolicyFileName(inputData) { | ||
if (this.isProjectData(inputData)) { | ||
return `${inputData.slug}.policy.yaml`; | ||
} | ||
const repoData = inputData; | ||
const provider = slugify(repoData.provider, { | ||
@@ -163,5 +224,18 @@ replacement: '_', | ||
} | ||
getRepoCacheId(repoData, prefix) { | ||
getRepoCacheId(inputData, prefix) { | ||
if (this.isProjectData(inputData)) { | ||
return `${prefix}-${inputData.slug}`; | ||
} | ||
const repoData = inputData; | ||
return `${prefix}-${repoData.provider}-${repoData.owner}-${repoData.name}`; | ||
} | ||
async getRepoOrProjectData(inputData) { | ||
if (this.isProjectData(inputData)) { | ||
return inputData; | ||
} | ||
return typeof inputData === 'string' ? await this.getRootGitData(inputData) : inputData; | ||
} | ||
isProjectData(projectData) { | ||
return Object.keys(projectData).length === 1 && projectData.slug; | ||
} | ||
} |
{ | ||
"name": "@monokle/synchronizer", | ||
"version": "0.6.0", | ||
"version": "0.7.0", | ||
"description": "Monokle Cloud synchronizer", | ||
@@ -5,0 +5,0 @@ "author": "Kubeshop", |
137377
3008