server/src/plugins/cloudDiagram/api/infraPushCodeApi.js
const assert = require("assert");
const path = require("path");
const { pipe, tap, tryCatch, switchCase, eq, get, or } = require("rubico");
const uuid = require("uuid");
const fs = require("fs");
const pfs = fs.promises;
const os = require("os");
const { contextSet400, contextSetOk } = require("utils/koaCommon");
const { gitPush } = require("../gitUtils");
const { infraFindOne } = require("./infraApi");
const InfraPushCodeApi = ({ models, log }) => ({
create: ({ id }) =>
pipe([
() => infraFindOne({ models })({ id }),
tap((infra) => {
log.debug(`InfraPushCodeApi: ${JSON.stringify({ infra }, null, 4)}`);
}),
tap(async (infra) =>
gitPush({
infra,
dirTemplate: await path.join(
os.tmpdir(),
"grucloud-example-template"
),
dir: await pfs.mkdtemp(path.join(os.tmpdir(), "grucloud-user-dir")),
message: "new infra project",
})
),
])(),
});
exports.InfraPushCodeRestApi = ({ app, models }) => {
const log = require("logfilename")(__filename);
const api = InfraPushCodeApi({ model: models.Infra, models, log });
const apiSpec = {
pathname: "/infra",
middlewares: [
app.server.auth.isAuthenticated /*,app.server.auth.isAuthorized*/,
],
ops: [
{
pathname: "/:id/push_code",
method: "post",
handler: (context) =>
tryCatch(
pipe([
tap(() => {
assert(context.params.id);
assert(context.state.user.user_id);
}),
switchCase([
() => uuid.validate(context.params.id),
// valid id
pipe([
() =>
api.create({
id: context.params.id,
data: context.request.body,
}),
tap(contextSetOk({ context })),
]),
// invalid uuid
contextSet400({ context, message: "invalid uuid" }),
]),
]),
(error) =>
pipe([
tap(() => {
console.error(error);
}),
() => {
context.status = 422;
context.body = { ...error, message: error.toString() };
},
])()
)(),
},
],
};
app.server.createRouter(apiSpec);
return { api: apiSpec };
};