Files
cal.diy/packages/app-store-cli/src/core.ts
T
Eunjae LeeandDevin AI 357c2882ad refactor: apply biome formatting to several packages (#27439)
* refactor: apply biome formatting to Phase 1 packages

Packages formatted:
- packages/app-store-cli
- packages/config
- packages/dayjs
- packages/debugging
- packages/embeds/embed-react
- packages/embeds/embed-snippet
- packages/kysely
- packages/platform/constants
- packages/platform/utils
- packages/testing
- packages/tsconfig

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: restore non-null assertions in embed-snippet to fix type error

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: remove ESM import from CommonJS config file

Biome incorrectly added 'import process from node:process' to a CommonJS
file that uses require(). This breaks Jest which expects CommonJS syntax.
The process global is already available in Node.js without explicit import.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: exclude packages/embeds from Phase 1 formatting

Per user request, reverting all biome formatting changes in packages/embeds
to handle separately.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: restore const enum for BookingLocations

Biome changed 'const enum' to 'enum' which is a semantic change.
Reverting to keep the PR purely formatting-only.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-05 07:24:34 -03:00

140 lines
4.2 KiB
TypeScript

import fs from "node:fs";
import path from "node:path";
import { APP_STORE_PATH, IS_WINDOWS_PLATFORM, TEMPLATES_PATH } from "./constants";
import execSync from "./utils/execSync";
const slugify = (str: string) => {
// A valid dir name
// A valid URL path
// It is okay to not be a valid variable name. This is so that we can use hyphens which look better then underscores in URL and as directory name
return str.replace(/[^a-zA-Z0-9]/g, "-").toLowerCase();
};
export function getSlugFromAppName(appName: string): string {
if (!appName) {
return appName;
}
return slugify(appName);
}
export function getAppDirPath(slug: string, isTemplate: boolean) {
if (!isTemplate) {
return path.join(APP_STORE_PATH, `${slug}`);
}
return path.join(TEMPLATES_PATH, `${slug}`);
}
const updatePackageJson = ({
slug,
appDescription,
appDirPath,
}: {
slug: string;
appDescription: string;
appDirPath: string;
}) => {
const packageJsonConfig = JSON.parse(fs.readFileSync(`${appDirPath}/package.json`).toString());
packageJsonConfig.name = `@calcom/${slug}`;
packageJsonConfig.description = appDescription;
// packageJsonConfig.description = `@calcom/${appName}`;
fs.writeFileSync(`${appDirPath}/package.json`, JSON.stringify(packageJsonConfig, null, 2));
};
const _workspaceDir = path.resolve(__dirname, "..", "..", "..");
export const BaseAppFork = {
create: async ({
category,
editMode = false,
description,
name,
slug,
publisher,
email,
template,
isTemplate,
oldSlug,
}: {
category: string;
editMode?: boolean;
description: string;
name: string;
slug: string;
publisher: string;
email: string;
template: string;
isTemplate: boolean;
oldSlug?: string;
}) => {
const appDirPath = getAppDirPath(slug, isTemplate);
if (!editMode) {
await execSync(IS_WINDOWS_PLATFORM ? `mkdir ${appDirPath}` : `mkdir -p ${appDirPath}`);
await execSync(
IS_WINDOWS_PLATFORM
? `xcopy "${TEMPLATES_PATH}\\${template}\\*" "${appDirPath}" /e /i`
: `cp -r ${TEMPLATES_PATH}/${template}/* ${appDirPath}`
);
} else {
if (!oldSlug) {
throw new Error("oldSlug is required when editMode is true");
}
if (oldSlug !== slug) {
// We need to rename only if they are different
const oldAppDirPath = getAppDirPath(oldSlug, isTemplate);
await execSync(
IS_WINDOWS_PLATFORM ? `move ${oldAppDirPath} ${appDirPath}` : `mv ${oldAppDirPath} ${appDirPath}`
);
}
}
updatePackageJson({ slug, appDirPath, appDescription: description });
const categoryToVariantMap = {
video: "conferencing",
};
let config = {
name: name,
// Plan to remove it. DB already has it and name of dir is also the same.
slug: slug,
type: `${slug}_${category}`,
logo: `icon.svg`,
variant: categoryToVariantMap[category as keyof typeof categoryToVariantMap] || category,
categories: [category],
publisher: publisher,
email: email,
description: description,
// TODO: Use this to avoid edit and delete on the apps created outside of cli
__createdUsingCli: true,
isTemplate,
// Store the template used to create an app
__template: template,
};
const currentConfig = JSON.parse(fs.readFileSync(`${appDirPath}/config.json`).toString());
config = {
...currentConfig,
...config,
};
fs.writeFileSync(`${appDirPath}/config.json`, JSON.stringify(config, null, 2));
fs.writeFileSync(
`${appDirPath}/DESCRIPTION.md`,
fs
.readFileSync(`${appDirPath}/DESCRIPTION.md`)
.toString()
.replace(/_DESCRIPTION_/g, description)
.replace(/_APP_DIR_/g, slug)
);
// New monorepo package has been added, so we need to run yarn again
await execSync("yarn");
},
delete: async ({ slug, isTemplate }: { slug: string; isTemplate: boolean }) => {
const appDirPath = getAppDirPath(slug, isTemplate);
await execSync(IS_WINDOWS_PLATFORM ? `rd /s /q ${appDirPath}` : `rm -rf ${appDirPath}`);
},
};
export const generateAppFiles = async () => {
await execSync(`yarn ts-node --transpile-only src/build.ts`);
};