@knapsack/app
Version:
Build Design Systems on top of knapsack, by Basalt
141 lines (128 loc) • 4.11 kB
text/typescript
import {
KnapsackFile,
KsCloudConfig,
KsCloudSaveBody,
KsFileSaver,
PERMISSIONS,
} from '@knapsack/core';
import { GenericResponse } from '@knapsack/core/types';
import urlJoin from 'url-join';
import { isAbsolute, join, relative } from 'path';
import { error as logError } from '../cli/log';
export class KsCloudConnect {
cloudConfig: KsCloudConfig;
constructor(cloudConfig: KsCloudConfig) {
this.cloudConfig = cloudConfig;
// this.saveFilesToCloud = this.saveFilesToCloud.bind(this);
}
saveFilesToCloud: KsFileSaver = async ({
files,
title = 'New changes',
message,
user,
}) => {
if (!this.cloudConfig) {
return {
ok: false,
message: 'No "cloud" in your "knapsack.config.js"',
};
}
if (!user?.role?.permissions?.includes(PERMISSIONS.WRITE)) {
return {
ok: false,
message: `Your user does not have write permission, sorry.`,
};
}
const {
// apiKey,
apiBase,
repoRoot,
repoName,
repoOwner,
baseBranch = 'master',
alterSavedFilePath,
} = this.cloudConfig;
const repo = `${repoOwner}/${repoName}`;
// @todo re-enable repo access check. disabled b/c adding users to user involved manual api call.
// if (!user.ksRepoAccess.includes(repo)) {
// return {
// ok: false,
// message: `Your user does not have permission to write to the "${repo}" repo, only these: ${user.ksRepoAccess?.join(
// ', ',
// )}`,
// };
// }
function prepFilePath(filePath: string): string {
const fullPath = isAbsolute(filePath)
? filePath
: join(process.cwd(), filePath);
return relative(repoRoot, fullPath);
}
const body: KsCloudSaveBody = {
owner: repoOwner,
repo: repoName,
baseBranch,
title: `${title} from ${user.username}`,
message,
payload: {
files: files.map(file => {
const filePath = alterSavedFilePath
? alterSavedFilePath(file.path)
: prepFilePath(file.path);
if (typeof filePath !== 'string') {
console.log(file);
const msg = `While prepping for file save, this file did not end up as a string, in: "${file.path}", out: "${filePath}".`;
logError(msg, null, 'cloud');
throw new Error(msg);
}
if (isAbsolute(filePath)) {
console.log(file);
const msg = `While prepping for file save, this file did not end up as a relative path, in: "${file.path}", out: "${filePath}".`;
logError(msg, null, 'cloud');
throw new Error(msg);
}
return {
...file,
path: filePath,
};
}),
},
};
// console.log('Sending save request to Knapsack Cloud...');
// console.log('files paths:');
// console.log(body.payload.files.map(file => file.path).join('\n'));
const endpoint = urlJoin(apiBase, 'api/save');
return fetch(endpoint, {
method: 'POST',
body: JSON.stringify(body),
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
// can't add auth just yet, cloud api uses it if present to attempt to authenticate as GitHub user (then falls back to GitHub app); this auth token is currently the AWS Cognito user.
// Authorization: user.Authorization,
// 'x-api-key': apiKey,
},
})
.then(res => {
const { ok, status, statusText } = res;
// console.log({ ok, status, statusText });
if (!ok) {
const result: GenericResponse = {
ok,
message: `${status} - ${statusText}`,
};
return result;
}
return res.json();
})
.catch(e => {
console.error('error saveFilesToCloud');
console.error(e);
const result: GenericResponse = {
ok: false,
message: `thrown error in saveFilesToCloud: ${e.message}`,
};
return result;
});
};
}