Skip to content
Merged
Show file tree
Hide file tree
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
File renamed without changes.
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/01-command_bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ body:
options:
- application
- configuration
- docker
- part-base
- part-main
- other
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/02-feature_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ body:
options:
- application
- configuration
- docker
- part-base
- part-main
- other
Expand Down
4 changes: 4 additions & 0 deletions .github/issue-labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ schematics:configuration:
- "### Which schematics is this (bug
report|feature request) for\\?\\n\\nconfiguration\\n"

schematics:docker:
- "### Which schematics is this (bug
report|feature request) for\\?\\n\\ndocker\\n"

schematics:part-base:
- "### Which schematics is this (bug
report|feature request) for\\?\\n\\npart-base\\n"
Expand Down
6 changes: 6 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ schematics:configuration:
- src/libs/configuration/*
- src/libs/configuration/**/*

schematics:docker:
- changed-files:
- any-glob-to-any-file:
- src/libs/docker/*
- src/libs/docker/**/*

schematics:part-base:
- changed-files:
- any-glob-to-any-file:
Expand Down
4 changes: 4 additions & 0 deletions .github/labels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@
description: "Related to configuration schematics"
color: "aaa3dc"

- name: "schematics:docker"
description: "Related to docker schematics"
color: "aaa3dc"

- name: "schematics:part-base"
description: "Related to part-base schematics"
color: "aaa3dc"
Expand Down
73 changes: 47 additions & 26 deletions e2e/configuration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,66 +12,87 @@ describe("configuration schematic", () => {
let config: Record<string, any>;

beforeAll(async () => {
tree = await runner.runSchematic("configuration", { name: "my-app" });
config = JSON.parse(tree.readContent("/my-app/nanoforge.config.json"));
tree = await runner.runSchematic("configuration", {
name: "my-name",
});
config = JSON.parse(tree.readContent("/nanoforge.config.json"));
});

it("should generate nanoforge.config.json", () => {
expect(tree.files).toContain("/my-app/nanoforge.config.json");
expect(tree.files).toContain("/nanoforge.config.json");
});

it("should create a valid JSON config file", () => {
expect(() => JSON.parse(tree.readContent("/my-app/nanoforge.config.json"))).not.toThrow();
expect(() => JSON.parse(tree.readContent("/nanoforge.config.json"))).not.toThrow();
});

it("should include default client build config", () => {
expect(config.client).toBeDefined();
expect(config.client.build.entryFile).toBe("client/main.ts");
expect(config.client.build.outDir).toBe(".nanoforge/client");
expect(config.name).toBe("my-name");
expect(config.language).toBe("ts");
expect(config.initFunctions).toBe(false);
});

it("should include default client runtime config", () => {
expect(config.client.runtime.dir).toBe(".nanoforge/client");
it("should include default client build config", () => {
expect(config.client).toBeDefined();
expect(config.client.enable).toBe(true);
});

it("should have server disabled", () => {
expect(config.server.enable).toBe(false);
});
});

describe("with server enabled", () => {
describe("with js", () => {
let tree: UnitTestTree;
let config: Record<string, any>;

beforeAll(async () => {
tree = await runner.runSchematic("configuration", {
name: "my-app",
server: true,
name: "my-name",
language: "js",
initFunctions: true,
});
config = JSON.parse(tree.readContent("/my-app/nanoforge.config.json"));
config = JSON.parse(tree.readContent("/nanoforge.config.json"));
});

it("should generate config file", () => {
expect(tree.files).toContain("/my-app/nanoforge.config.json");
it("should generate nanoforge.config.json", () => {
expect(tree.files).toContain("/nanoforge.config.json");
});

it("should include server config with enable flag", () => {
expect(config.server).toBeDefined();
expect(config.server.enable).toBe(true);
it("should include default client build config", () => {
expect(config.name).toBe("my-name");
expect(config.language).toBe("js");
expect(config.initFunctions).toBe(true);
});

it("should include default client build config", () => {
expect(config.client).toBeDefined();
expect(config.client.build.entry).toBe("client/main.js");
});

it("should include server build config", () => {
expect(config.server.build.entryFile).toBe("server/main.ts");
expect(config.server.build.outDir).toBe(".nanoforge/server");
it("should include default editor config", () => {
expect(config.client.editor.entry).toBe(".nanoforge/editor/client/main.js");
});
});

it("should include server runtime config", () => {
expect(config.server.runtime.dir).toBe(".nanoforge/server");
describe("with server enabled", () => {
let tree: UnitTestTree;
let config: Record<string, any>;

beforeAll(async () => {
tree = await runner.runSchematic("configuration", {
server: true,
});
config = JSON.parse(tree.readContent("/nanoforge.config.json"));
});

it("should still include client config", () => {
expect(config.client).toBeDefined();
expect(config.client.build.entryFile).toBe("client/main.ts");
it("should generate config file", () => {
expect(tree.files).toContain("/nanoforge.config.json");
});

it("should include server config with enable flag", () => {
expect(config.server).toBeDefined();
expect(config.server.enable).toBe(true);
});
});

Expand Down
2 changes: 1 addition & 1 deletion e2e/docker.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe("docker schematic", () => {
(packageManager) => {
beforeAll(async () => {
tree = await runner.runSchematic("docker", {
name: `${packageManager}-test-app`,
directory: `${packageManager}-test-app`,
packageManager,
});
});
Expand Down
8 changes: 4 additions & 4 deletions e2e/part-base.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe("part-base schematic", () => {

beforeAll(async () => {
tree = await runner.runSchematic("part-base", {
name: "my-app",
directory: "my-app",
part: "client",
language: "ts",
});
Expand Down Expand Up @@ -50,7 +50,7 @@ describe("part-base schematic", () => {

beforeAll(async () => {
tree = await runner.runSchematic("part-base", {
name: "my-app",
directory: "my-app",
part: "server",
language: "ts",
});
Expand All @@ -75,7 +75,7 @@ describe("part-base schematic", () => {

beforeAll(async () => {
tree = await runner.runSchematic("part-base", {
name: "my-app",
directory: "my-app",
part: "client",
language: "ts",
initFunctions: true,
Expand All @@ -97,7 +97,7 @@ describe("part-base schematic", () => {

beforeAll(async () => {
tree = await runner.runSchematic("part-base", {
name: "my-app",
directory: "my-app",
part: "client",
language: "js",
});
Expand Down
24 changes: 5 additions & 19 deletions e2e/part-main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ describe("part-main schematic", () => {

beforeAll(async () => {
tree = await runner.runSchematic("part-main", {
name: "my-app",
directory: "my-app",
part: "client",
language: "ts",
saveFile: resolve(tmpDir, "client.save.json"),
Expand Down Expand Up @@ -102,7 +102,7 @@ describe("part-main schematic", () => {

beforeAll(async () => {
tree = await runner.runSchematic("part-main", {
name: "my-app",
directory: "my-app",
part: "server",
language: "ts",
saveFile: resolve(tmpDir, "server.save.json"),
Expand All @@ -124,7 +124,7 @@ describe("part-main schematic", () => {

beforeAll(async () => {
tree = await runner.runSchematic("part-main", {
name: "my-app",
directory: "my-app",
part: "client",
language: "js",
saveFile: resolve(tmpDir, "client.save.json"),
Expand All @@ -147,7 +147,7 @@ describe("part-main schematic", () => {

beforeAll(async () => {
tree = await runner.runSchematic("part-main", {
name: "my-app",
directory: "my-app",
part: "client",
language: "ts",
initFunctions: true,
Expand All @@ -172,26 +172,12 @@ describe("part-main schematic", () => {
});
});

describe("with custom directory", () => {
it("should generate main file in the specified directory", async () => {
const tree = await runner.runSchematic("part-main", {
name: "my-app",
part: "client",
language: "ts",
directory: "custom-dir",
saveFile: resolve(tmpDir, "client.save.json"),
});
expect(tree.files).toContain("/custom-dir/client/main.ts");
expect(tree.files).not.toContain("/my-app/client/main.ts");
});
});

describe("editor mode", () => {
let tree: UnitTestTree;

beforeAll(async () => {
tree = await runner.runSchematic("part-main", {
name: "my-app",
directory: "my-app",
part: "client",
language: "ts",
editor: true,
Expand Down
23 changes: 0 additions & 23 deletions src/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,3 @@ export const DEFAULT_AUTHOR = "";
export const DEFAULT_DESCRIPTION = "";
export const DEFAULT_LANGUAGE = "ts";
export const DEFAULT_PACKAGE_MANAGER = "npm";
export const DEFAULT_CONFIG = {
client: {
build: {
entryFile: "client/main.ts",
outDir: ".nanoforge/client",
},
runtime: {
dir: ".nanoforge/client",
},
},
};
export const DEFAULT_SERVER_CONFIG = {
server: {
enable: true,
build: {
entryFile: "server/main.ts",
outDir: ".nanoforge/server",
},
runtime: {
dir: ".nanoforge/server",
},
},
};
6 changes: 1 addition & 5 deletions src/libs/application/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@
"name": {
"type": "string",
"description": "The name of the application",
"$default": {
"$source": "argv",
"index": 0
},
"x-prompt": "What name would you like to use for the new project ?"
"default": "nanoforge-app"
},
"version": {
"type": "string",
Expand Down
52 changes: 37 additions & 15 deletions src/libs/configuration/configuration.factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,16 @@ import {

import { ConfigDeclarator } from "@utils/config/config.declarator";
import { ConfigFinder } from "@utils/config/config.finder";
import { type Config } from "@utils/config/config.type";
import { type DeepPartial } from "@utils/types";

import { type ConfigurationOptions } from "./configuration.options";
import { type ConfigurationSchema } from "./configuration.schema";

const transform = (schema: ConfigurationSchema): ConfigurationOptions => {
const res: ConfigurationOptions = {
server: {
enable: schema.server ?? false,
},
};

if (schema.language === "js") {
res["client"] = { build: { entryFile: "client/main.js" } };
if (schema.server && "server" in res && res.server)
res.server["build"] = { entryFile: "server/main.js" };
}
void schema;

return res;
return {};
};

const generate = (options: ConfigurationOptions, path: string): Source => {
Expand All @@ -44,7 +36,7 @@ const generate = (options: ConfigurationOptions, path: string): Source => {
]);
};

const addConfiguration = (options: ConfigurationOptions, path: Path) => {
const addConfiguration = (options: DeepPartial<Config>, path: Path) => {
return (tree: Tree) => {
const config = new ConfigFinder(tree).find(path);
if (!config) return tree;
Expand All @@ -59,11 +51,41 @@ const addConfiguration = (options: ConfigurationOptions, path: Path) => {
};
};

const getConfig = (schema: ConfigurationSchema): DeepPartial<Config> => {
const res: DeepPartial<Config> = {
name: schema.name,
language: schema.language,
initFunctions: schema.initFunctions,
client: {
enable: true,
},
server: {
enable: schema.server ?? false,
},
};

if (schema.language === "js") {
if ("client" in res && res.client) {
res.client["build"] = { entry: "client/main.js" };
res.client["editor"] = { entry: ".nanoforge/editor/client/main.js" };
}
if (schema.server && "server" in res && res.server) {
res.server["build"] = { entry: "server/main.js" };
res.server["editor"] = { entry: ".nanoforge/editor/client/main.js" };
}
}

return res;
};

export const main = (schema: ConfigurationSchema): Rule => {
const options = transform(schema);
const directory = schema.directory ?? schema.name;
const directory = schema.directory;

return branchAndMerge(
chain([mergeWith(generate(options, directory)), addConfiguration(options, directory as Path)]),
chain([
mergeWith(generate(options, directory)),
addConfiguration(getConfig(schema), directory as Path),
]),
);
};
Loading
Loading