Skip to content

Commit

Permalink
Merge pull request #1563 from Genez-io/release_v3_0_1
Browse files Browse the repository at this point in the history
Release v3.0.1
  • Loading branch information
andreia-oca authored Dec 5, 2024
2 parents 9b7c032 + 1507177 commit 4db9f04
Show file tree
Hide file tree
Showing 10 changed files with 219 additions and 10 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "genezio",
"version": "3.0.0",
"version": "3.0.1",
"description": "Command line utility to interact with Genezio infrastructure.",
"exports": "./index.js",
"type": "module",
Expand Down
18 changes: 18 additions & 0 deletions src/commands/analyze/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
isGenezioTypesafe,
hasPostgresDependency,
hasMongoDependency,
isNestjsComponent,
} from "./frameworks.js";
import { generateDatabaseName, readOrAskConfig } from "../deploy/utils.js";
import { getPackageManager, PackageManagerType } from "../../packageManagers/packageManager.js";
Expand Down Expand Up @@ -299,6 +300,23 @@ export async function analyzeCommand(options: GenezioAnalyzeOptions) {
continue;
}

if (await isNestjsComponent(contents)) {
await addSSRComponentToConfig(
options.config,
{
path: componentPath,
packageManager: getPackageManager().command as PackageManagerType,
scripts: {
deploy: [`${getPackageManager().command} install`],
},
},
SSRFrameworkComponentType.nestjs,
);
frameworksDetected.ssr = frameworksDetected.ssr || [];
frameworksDetected.ssr.push("nest");
continue;
}

if (await isNuxtComponent(contents)) {
await addSSRComponentToConfig(
options.config,
Expand Down
13 changes: 12 additions & 1 deletion src/commands/analyze/frameworks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export async function findEntryFile(

const entryFile = await findFileByPatterns(componentPath, patterns, FUNCTION_EXTENSIONS);
if (entryFile) {
return entryFile;
return path.relative(componentPath, entryFile);
}

return defaultFile;
Expand Down Expand Up @@ -256,6 +256,17 @@ export async function isNextjsComponent(contents: Record<string, string>): Promi
return packageJsonContent ? "next" in (packageJsonContent.dependencies || {}) : false;
}

// Checks if the project is a Nest.js component
// `contents` is a map of important file paths and their contents
export async function isNestjsComponent(contents: Record<string, string>): Promise<boolean> {
if (!contents["package.json"]) {
return false;
}

const packageJsonContent = JSON.parse(contents["package.json"]) as PackageJSON;
return packageJsonContent ? "@nestjs/core" in (packageJsonContent.dependencies || {}) : false;
}

// Checks if the project is a Nuxt component
// `contents` is a map of important file paths and their contents
export async function isNuxtComponent(contents: Record<string, string>): Promise<boolean> {
Expand Down
20 changes: 16 additions & 4 deletions src/commands/analyze/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,22 @@ export async function addServicesToConfig(configPath: string, services: YAMLServ
// to be able to edit it in the least intrusive way
const config = await configIOController.read(/* fillDefaults= */ false);

config.services = {
...config.services,
...services,
};
config.services = config.services || {};

// Ensure unique types are added
const existingDatabases = config.services.databases || [];
const newDatabases = services.databases || [];

// Add only new database types
const mergedDatabases = [
...existingDatabases,
...newDatabases.filter(
(db) => !existingDatabases.some((existingDb) => existingDb.type === db.type),
),
];

// Update services with the merged databases
config.services.databases = mergedDatabases;

await configIOController.write(config);
}
Expand Down
20 changes: 20 additions & 0 deletions src/commands/deploy/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { nuxtNitroDeploy } from "./nuxt/deploy.js";
import { dockerDeploy } from "./docker/deploy.js";
import { PackageManagerType } from "../../packageManagers/packageManager.js";
import { YamlConfigurationIOController } from "../../projectConfiguration/yaml/v2.js";
import { nestJsDeploy } from "./nestjs/deploy.js";

export type SSRFrameworkComponent = {
path: string;
Expand Down Expand Up @@ -47,6 +48,10 @@ export async function deployCommand(options: GenezioDeployOptions) {
debugLogger.debug("Deploying Docker app");
await dockerDeploy(options);
break;
case DeployType.Nest:
debugLogger.debug("Deploying Nest.js app");
await nestJsDeploy(options);
break;
}
}

Expand All @@ -56,6 +61,7 @@ export enum DeployType {
Nitro,
Nuxt,
Docker,
Nest,
}

async function decideDeployType(options: GenezioDeployOptions): Promise<DeployType> {
Expand All @@ -82,6 +88,9 @@ async function decideDeployType(options: GenezioDeployOptions): Promise<DeployTy
if (config.nitro) {
return DeployType.Nitro;
}
if (config.nestjs) {
return DeployType.Nest;
}
}

// Check if next.config.js exists
Expand Down Expand Up @@ -114,6 +123,11 @@ async function decideDeployType(options: GenezioDeployOptions): Promise<DeployTy
return DeployType.Nitro;
}

// Check if nest-cli.json exists
if (fs.existsSync(path.join(cwd, "nest-cli.json"))) {
return DeployType.Nest;
}

// Check if "next" package is present in the project dependencies
if (fs.existsSync(path.join(cwd, "package.json"))) {
const packageJson = JSON.parse(fs.readFileSync(path.join(cwd, "package.json"), "utf-8"));
Expand All @@ -126,6 +140,12 @@ async function decideDeployType(options: GenezioDeployOptions): Promise<DeployTy
if (packageJson.dependencies?.nitropack || packageJson.devDependencies?.nitropack) {
return DeployType.Nitro;
}
if (
packageJson.dependencies?.["@nestjs/core"] ||
packageJson.devDependencies?.["@nestjs/core"]
) {
return DeployType.Nest;
}
}

// Check if a Dockerfile exists in non-genezio project
Expand Down
140 changes: 140 additions & 0 deletions src/commands/deploy/nestjs/deploy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import path from "path";
import fs from "fs";
import colors from "colors";
import { $ } from "execa";
import { GenezioDeployOptions } from "../../../models/commandOptions.js";
import { log } from "../../../utils/logging.js";
import {
attemptToInstallDependencies,
readOrAskConfig,
uploadEnvVarsFromFile,
uploadUserCode,
} from "../utils.js";
import { addSSRComponentToConfig } from "../../analyze/utils.js";
import { getPackageManager, PackageManagerType } from "../../../packageManagers/packageManager.js";
import { SSRFrameworkComponentType } from "../../../models/projectOptions.js";
import { UserError } from "../../../errors.js";
import { YamlProjectConfiguration } from "../../../projectConfiguration/yaml/v2.js";
import { getCloudProvider } from "../../../requests/getCloudProvider.js";
import { functionToCloudInput, getCloudAdapter } from "../genezio.js";
import { FunctionType, Language } from "../../../projectConfiguration/yaml/models.js";
import { ProjectConfiguration } from "../../../models/projectConfiguration.js";

export async function nestJsDeploy(options: GenezioDeployOptions) {
const genezioConfig = await readOrAskConfig(options.config);
const cwd = process.cwd();
const componentPath = genezioConfig.nestjs?.path
? path.resolve(cwd, genezioConfig.nestjs.path)
: cwd;

// Install dependencies
const installDependenciesCommand = await attemptToInstallDependencies([], componentPath);

// Add nestjs component to config
await addSSRComponentToConfig(
options.config,
{
path: componentPath,
packageManager: getPackageManager().command as PackageManagerType,
scripts: {
deploy: [`${installDependenciesCommand.command}`],
},
},
SSRFrameworkComponentType.nestjs,
);

// Build NestJS project
await $({
stdio: "inherit",
cwd: componentPath,
})`npx nest build`.catch(() => {
throw new UserError("Failed to build the NestJS project. Check the logs above.");
});

const result = await deployFunction(genezioConfig, options, componentPath);

await uploadEnvVarsFromFile(
options.env,
result.projectId,
result.projectEnvId,
componentPath,
options.stage || "prod",
genezioConfig,
SSRFrameworkComponentType.nestjs,
);

await uploadUserCode(genezioConfig.name, genezioConfig.region, options.stage, componentPath);

const functionUrl = result.functions.find((f) => f.name === "function-nest")?.cloudUrl;

if (functionUrl) {
log.info(
`The app is being deployed at ${colors.cyan(functionUrl)}. It might take a few moments to be available worldwide.`,
);
} else {
log.warn("No deployment URL was returned.");
}
}

async function deployFunction(
config: YamlProjectConfiguration,
options: GenezioDeployOptions,
cwd: string,
) {
const cloudProvider = await getCloudProvider(config.name);
const cloudAdapter = getCloudAdapter(cloudProvider);
const cwdRelative = path.relative(process.cwd(), cwd) || ".";

await fs.promises
.cp(
path.join(cwdRelative, "node_modules"),
path.join(cwdRelative, "dist", "node_modules"),
{ recursive: true },
)
.catch(() => {
throw new UserError("Failed to copy node_modules to dist directory");
});

const serverFunction = {
path: ".",
name: "nest",
entry: "main.js",
type: FunctionType.httpServer,
};

const deployConfig: YamlProjectConfiguration = {
...config,
backend: {
path: cwdRelative,
language: {
name: Language.js,
runtime: "nodejs20.x",
architecture: "x86_64",
packageManager: PackageManagerType.npm,
},
functions: [serverFunction],
},
};

const projectConfiguration = new ProjectConfiguration(
deployConfig,
await getCloudProvider(deployConfig.name),
{
generatorResponses: [],
classesInfo: [],
},
);

const cloudInputs = await Promise.all(
projectConfiguration.functions.map((f) => functionToCloudInput(f, "dist")),
);

const result = await cloudAdapter.deploy(
cloudInputs,
projectConfiguration,
{ stage: options.stage },
["nestjs"],
);

return result;
}
10 changes: 8 additions & 2 deletions src/commands/deploy/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,16 +279,21 @@ export async function readOrAskProjectName(): Promise<string> {
* @returns A unique database name
*/
export async function generateDatabaseName(prefix: string): Promise<string> {
const defaultDatabaseName = prefix + "-" + "db";
const defaultDatabaseName = "my-" + prefix + "-db";

const databaseExists = await getDatabaseByName(defaultDatabaseName)
.then(() => true)
.then((response) => {
return response !== undefined;
})
.catch(() => false);

if (!databaseExists) {
return defaultDatabaseName;
}

debugLogger.debug(
`Database ${defaultDatabaseName} already exists. Generating a new database name...`,
);
const generatedDatabaseName =
prefix +
"-" +
Expand Down Expand Up @@ -806,6 +811,7 @@ export async function uploadEnvVarsFromFile(
[SSRFrameworkComponentType.next]: configuration.nextjs?.environment,
[SSRFrameworkComponentType.nuxt]: configuration.nitro?.environment,
[SSRFrameworkComponentType.nitro]: configuration.nuxt?.environment,
[SSRFrameworkComponentType.nestjs]: configuration.nuxt?.environment,
backend: configuration.backend?.environment,
}[componentType] ?? configuration.backend?.environment;

Expand Down
1 change: 1 addition & 0 deletions src/models/projectOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export enum SSRFrameworkComponentType {
next = "nextjs",
nitro = "nitro",
nuxt = "nuxt",
nestjs = "nestjs",
}

export enum ContainerComponentType {
Expand Down
1 change: 1 addition & 0 deletions src/projectConfiguration/yaml/v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ function parseGenezioConfig(config: unknown) {
backend: backendSchema.optional(),
services: servicesSchema.optional(),
frontend: zod.array(frontendSchema).or(frontendSchema).optional(),
nestjs: ssrFrameworkSchema.optional(),
nextjs: ssrFrameworkSchema.optional(),
nuxt: ssrFrameworkSchema.optional(),
nitro: ssrFrameworkSchema.optional(),
Expand Down

0 comments on commit 4db9f04

Please sign in to comment.