Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(backend): Upload theme on Windows #224

Merged
merged 1 commit into from
Feb 20, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 61 additions & 32 deletions backend/src/admin/core/themes/upload/upload.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as fs from "fs";
import * as fsPromises from "fs/promises";
import { join } from "path";
import { writeFile } from "fs/promises";

Expand All @@ -13,18 +13,44 @@ import { generateRandomString } from "@/functions/generate-random-string";
import { currentDate } from "@/functions/date";
import { CustomError } from "@/utils/errors/CustomError";
import { core_themes } from "../../database/schema/themes";
import { FileUpload } from "@/utils/graphql-upload/Upload";

@Injectable()
export class UploadAdminThemesService {
constructor(private databaseService: DatabaseService) {}

protected path: string = join("..", "frontend", "themes");
protected tempFolder: string = `temp--${generateRandomString(5)}-${currentDate()}`;
protected tempPath: string = join(this.path, this.tempFolder);
protected tempFolderName: string = `${generateRandomString(5)}${currentDate()}`;
protected tempPath: string = join(process.cwd(), "temp", "themes");

protected async getThemeConfig({
tgz
}: {
tgz: FileUpload;
}): Promise<ConfigTheme> {
// Create folders
const path = join(this.tempPath, this.tempFolderName);
await fsPromises.mkdir(path, { recursive: true });

// Upload to temp folder
await new Promise((resolve, reject) => {
tgz
.createReadStream()
.pipe(
tar.x({
cwd: path
})
)
.on("error", err => {
reject(err.message);
})
.on("finish", () => {
resolve("success");
});
});

protected getThemeConfig(): ConfigTheme {
const pathThemeJSON = join(this.tempPath, "theme.json");
const themeFile = fs.readFileSync(pathThemeJSON, "utf8");
const pathThemeJSON = join(path, "theme.json");
const themeFile = await fsPromises.readFile(pathThemeJSON, "utf8");
const config: ConfigTheme = JSON.parse(themeFile);

// Check if variables exists
Expand All @@ -42,50 +68,53 @@ export class UploadAdminThemesService {
});
}

// Delete temp folder
await fsPromises.rm(path, { recursive: true });

return config;
}

async upload({ file }: UploadAdminThemesArgs): Promise<string> {
const tgz = await file;
const config = await this.getThemeConfig({ tgz });

// Create theme in database
const theme = await this.databaseService.db
.insert(core_themes)
.values({
name: config.name,
version: config.version,
version_code: config.version_code,
created: currentDate(),
author: config.author,
author_url: config.author_url
})
.returning();

// Create theme folder in frontend
const newPath = join(this.path, `${theme[0].id}`);
await fsPromises.mkdir(newPath);

// Unpack theme to temp folder
fs.mkdirSync(this.tempPath);

await new Promise((resolve, reject) => {
tgz
.createReadStream()
.pipe(
tar.x({
cwd: this.tempPath
cwd: newPath
})
)
.on("error", function (err) {
.on("error", err => {
reject(err.message);
})
.on("finish", async () => {
const config = this.getThemeConfig();

// Create theme in database
const theme = await this.databaseService.db
.insert(core_themes)
.values({
name: config.name,
version: config.version,
version_code: config.version_code,
created: currentDate(),
author: config.author,
author_url: config.author_url
})
.returning();

// Update theme folder name
// Update the global.scss file
try {
const newPath = join(this.path, theme[0].id.toString());
fs.renameSync(this.tempPath, newPath);

// Update the global.scss file
const pathSCSSFile = `${newPath}/core/layout/global.scss`;
const pathSCSSFileContent = fs.readFileSync(pathSCSSFile, "utf8");
const pathSCSSFile = join(newPath, "core", "layout", "global.scss");
const pathSCSSFileContent = await fsPromises.readFile(
pathSCSSFile,
"utf8"
);
await writeFile(
pathSCSSFile,
pathSCSSFileContent.replace(
Expand Down
Loading