@reliverse/rempts 2.2.9 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +213 -1431
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +51 -0
- package/dist/create-project.d.ts +14 -0
- package/dist/create-project.js +84 -0
- package/dist/create.d.ts +11 -0
- package/dist/create.js +62 -0
- package/dist/mod.d.ts +4 -6
- package/dist/mod.js +7 -6
- package/dist/template-engine.d.ts +27 -0
- package/dist/template-engine.js +145 -0
- package/dist/types.d.ts +45 -0
- package/package.json +41 -39
- package/src/cli.ts +64 -0
- package/templates/advanced/README.md +118 -0
- package/templates/advanced/dler.config.ts +41 -0
- package/templates/advanced/package.json +42 -0
- package/templates/advanced/src/commands/config.ts +157 -0
- package/templates/advanced/src/commands/init.ts +149 -0
- package/templates/advanced/src/commands/serve.ts +172 -0
- package/templates/advanced/src/commands/validate.ts +130 -0
- package/templates/advanced/src/mod.ts +44 -0
- package/templates/advanced/src/utils/config.ts +83 -0
- package/templates/advanced/src/utils/constants.ts +12 -0
- package/templates/advanced/src/utils/glob.ts +49 -0
- package/templates/advanced/src/utils/validator.ts +128 -0
- package/templates/advanced/template.json +40 -0
- package/templates/advanced/tsconfig.json +23 -0
- package/templates/basic/README.md +41 -0
- package/templates/basic/dler.config.ts +40 -0
- package/templates/basic/package.json +31 -0
- package/templates/basic/src/commands/hello.ts +26 -0
- package/templates/basic/src/mod.ts +13 -0
- package/templates/basic/template.json +27 -0
- package/templates/basic/tsconfig.json +19 -0
- package/templates/monorepo/README.md +74 -0
- package/templates/monorepo/dler.config.ts +45 -0
- package/templates/monorepo/package.json +30 -0
- package/templates/monorepo/packages/cli/package.json +40 -0
- package/templates/monorepo/packages/cli/src/mod.ts +22 -0
- package/templates/monorepo/packages/cli/tsconfig.json +13 -0
- package/templates/monorepo/packages/core/package.json +33 -0
- package/templates/monorepo/packages/core/scripts/build.ts +18 -0
- package/templates/monorepo/packages/core/src/commands/analyze.ts +87 -0
- package/templates/monorepo/packages/core/src/commands/process.ts +57 -0
- package/templates/monorepo/packages/core/src/mod.ts +3 -0
- package/templates/monorepo/packages/core/src/types.ts +21 -0
- package/templates/monorepo/packages/core/tsconfig.json +14 -0
- package/templates/monorepo/packages/utils/package.json +27 -0
- package/templates/monorepo/packages/utils/scripts/build.ts +17 -0
- package/templates/monorepo/packages/utils/src/format.ts +29 -0
- package/templates/monorepo/packages/utils/src/json.ts +11 -0
- package/templates/monorepo/packages/utils/src/logger.ts +19 -0
- package/templates/monorepo/packages/utils/src/mod.ts +3 -0
- package/templates/monorepo/packages/utils/tsconfig.json +13 -0
- package/templates/monorepo/template.json +27 -0
- package/templates/monorepo/tsconfig.json +14 -0
- package/templates/monorepo/turbo.json +28 -0
- package/LICENSE +0 -21
- package/cleanup.mjs +0 -33
- package/dist/cancel.d.ts +0 -31
- package/dist/cancel.js +0 -28
- package/dist/ffi.d.ts +0 -1
- package/dist/ffi.js +0 -165
- package/dist/group.d.ts +0 -16
- package/dist/group.js +0 -22
- package/dist/launcher/command.d.ts +0 -8
- package/dist/launcher/command.js +0 -10
- package/dist/launcher/discovery.d.ts +0 -3
- package/dist/launcher/discovery.js +0 -207
- package/dist/launcher/errors.d.ts +0 -15
- package/dist/launcher/errors.js +0 -31
- package/dist/launcher/help.d.ts +0 -3
- package/dist/launcher/help.js +0 -145
- package/dist/launcher/mod.d.ts +0 -12
- package/dist/launcher/mod.js +0 -222
- package/dist/launcher/parser.d.ts +0 -14
- package/dist/launcher/parser.js +0 -255
- package/dist/launcher/registry.d.ts +0 -10
- package/dist/launcher/registry.js +0 -42
- package/dist/launcher/types.d.ts +0 -78
- package/dist/launcher/validator.d.ts +0 -3
- package/dist/launcher/validator.js +0 -39
- package/dist/prompt.d.ts +0 -13
- package/dist/prompt.js +0 -53
- package/dist/selection.d.ts +0 -92
- package/dist/selection.js +0 -191
- package/dist/spinner.d.ts +0 -26
- package/dist/spinner.js +0 -141
- package/dist/utils.d.ts +0 -3
- package/dist/utils.js +0 -11
- /package/dist/{launcher/types.js → types.js} +0 -0
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { createApp, defineCommand, option } from "@reliverse/rempts-core";
|
|
3
|
+
import { type } from "arktype";
|
|
4
|
+
import { create } from "./create.js";
|
|
5
|
+
const cli = await createApp({
|
|
6
|
+
config: {
|
|
7
|
+
name: "rempts",
|
|
8
|
+
version: "0.1.0",
|
|
9
|
+
description: "Scaffold new Rempts CLI projects"
|
|
10
|
+
},
|
|
11
|
+
defaultCommand: "create"
|
|
12
|
+
});
|
|
13
|
+
cli.command(
|
|
14
|
+
defineCommand({
|
|
15
|
+
description: "Create a new Rempts CLI project",
|
|
16
|
+
options: {
|
|
17
|
+
name: option(type("string | undefined"), { description: "Project name" }),
|
|
18
|
+
template: option(type("string | undefined"), {
|
|
19
|
+
short: "t",
|
|
20
|
+
description: "Project template (basic, advanced, monorepo, or github:user/repo)"
|
|
21
|
+
}),
|
|
22
|
+
dir: option(type("string | undefined"), {
|
|
23
|
+
short: "d",
|
|
24
|
+
description: "Directory to create project in"
|
|
25
|
+
}),
|
|
26
|
+
git: option(type("boolean | undefined"), {
|
|
27
|
+
short: "g",
|
|
28
|
+
description: "Initialize git repository"
|
|
29
|
+
}),
|
|
30
|
+
install: option(type("boolean | undefined"), {
|
|
31
|
+
short: "i",
|
|
32
|
+
description: "Install dependencies"
|
|
33
|
+
}),
|
|
34
|
+
offline: option(type("boolean | undefined"), {
|
|
35
|
+
description: "Use cached templates when available"
|
|
36
|
+
})
|
|
37
|
+
},
|
|
38
|
+
handler: async (context) => {
|
|
39
|
+
const options = {
|
|
40
|
+
name: context.flags.name,
|
|
41
|
+
template: context.flags.template ?? "basic",
|
|
42
|
+
dir: context.flags.dir,
|
|
43
|
+
git: context.flags.git ?? true,
|
|
44
|
+
install: context.flags.install ?? true,
|
|
45
|
+
offline: context.flags.offline ?? false
|
|
46
|
+
};
|
|
47
|
+
return create({ ...context, flags: options });
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
);
|
|
51
|
+
await cli.run();
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { RemptsUtils } from "@reliverse/rempts-utils";
|
|
2
|
+
import type { CreateOptions } from "./types.js";
|
|
3
|
+
interface CreateProjectOptions extends Omit<CreateOptions, "name" | "dir" | "offline"> {
|
|
4
|
+
name: string;
|
|
5
|
+
dir: string;
|
|
6
|
+
template: string;
|
|
7
|
+
offline: boolean;
|
|
8
|
+
prompt: RemptsUtils["prompt"];
|
|
9
|
+
spinner: RemptsUtils["spinner"];
|
|
10
|
+
colors: typeof import("@reliverse/relico").relico;
|
|
11
|
+
shell: typeof Bun.$;
|
|
12
|
+
}
|
|
13
|
+
export declare function createProject(options: CreateProjectOptions): Promise<void>;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { relico } from "@reliverse/relico";
|
|
2
|
+
import {
|
|
3
|
+
getBundledTemplatePath,
|
|
4
|
+
isLocalTemplate,
|
|
5
|
+
processTemplate,
|
|
6
|
+
resolveTemplateSource
|
|
7
|
+
} from "./template-engine.js";
|
|
8
|
+
export async function createProject(options) {
|
|
9
|
+
const { name, dir, template, git, install, prompt, spinner, colors, shell, offline } = options;
|
|
10
|
+
try {
|
|
11
|
+
await shell`test -d ${dir}`.quiet();
|
|
12
|
+
const overwrite = await prompt.confirm(`Directory ${dir} already exists. Overwrite?`, {
|
|
13
|
+
default: false
|
|
14
|
+
});
|
|
15
|
+
if (!overwrite) {
|
|
16
|
+
console.log(relico.red("Cancelled"));
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
await shell`rm -rf ${dir}`;
|
|
20
|
+
} catch {
|
|
21
|
+
}
|
|
22
|
+
const spin = spinner("Creating project structure...");
|
|
23
|
+
spin.start();
|
|
24
|
+
await shell`mkdir -p ${dir}`;
|
|
25
|
+
try {
|
|
26
|
+
let templateSource = template;
|
|
27
|
+
if (await isLocalTemplate(template)) {
|
|
28
|
+
templateSource = getBundledTemplatePath(template);
|
|
29
|
+
} else {
|
|
30
|
+
templateSource = resolveTemplateSource(template);
|
|
31
|
+
}
|
|
32
|
+
const { manifest } = await processTemplate({
|
|
33
|
+
source: templateSource,
|
|
34
|
+
dir,
|
|
35
|
+
offline,
|
|
36
|
+
variables: {
|
|
37
|
+
name,
|
|
38
|
+
version: "0.1.0",
|
|
39
|
+
description: "A CLI built with Rempts",
|
|
40
|
+
author: "",
|
|
41
|
+
license: "MIT",
|
|
42
|
+
year: (/* @__PURE__ */ new Date()).getFullYear().toString()
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
spin.succeed("Project structure created");
|
|
46
|
+
if (git) {
|
|
47
|
+
const gitSpin = spinner("Initializing git repository...");
|
|
48
|
+
gitSpin.start();
|
|
49
|
+
try {
|
|
50
|
+
await shell`cd ${dir} && git init`.quiet();
|
|
51
|
+
await shell`cd ${dir} && git add .`.quiet();
|
|
52
|
+
await shell`cd ${dir} && git commit -m "feat: initialize ${name} CLI project with Rempts
|
|
53
|
+
|
|
54
|
+
- Generated using @reliverse/rempts template
|
|
55
|
+
- Includes basic CLI structure with commands directory
|
|
56
|
+
- Configured with Rempts build system and TypeScript
|
|
57
|
+
- Ready for development with bun run dev"`;
|
|
58
|
+
gitSpin.succeed("Git repository initialized");
|
|
59
|
+
} catch (error) {
|
|
60
|
+
gitSpin.fail("Failed to initialize git repository");
|
|
61
|
+
console.error(relico.dim(` ${error}`));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (install) {
|
|
65
|
+
const installSpin = spinner("Installing dependencies...");
|
|
66
|
+
installSpin.start();
|
|
67
|
+
try {
|
|
68
|
+
await shell`cd ${dir} && bun install`;
|
|
69
|
+
installSpin.succeed("Dependencies installed");
|
|
70
|
+
} catch (_error) {
|
|
71
|
+
installSpin.fail("Failed to install dependencies");
|
|
72
|
+
console.error(relico.dim(" You can install them manually by running: bun install"));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
} catch (error) {
|
|
76
|
+
spin.fail("Failed to create project");
|
|
77
|
+
console.error(relico.red(`Error: ${error}`));
|
|
78
|
+
try {
|
|
79
|
+
await shell`rm -rf ${dir}`.quiet();
|
|
80
|
+
} catch {
|
|
81
|
+
}
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
}
|
package/dist/create.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { HandlerArgs } from "@reliverse/rempts-core";
|
|
2
|
+
interface CreateOptions {
|
|
3
|
+
name: string | undefined;
|
|
4
|
+
template: string;
|
|
5
|
+
dir: string | undefined;
|
|
6
|
+
git: boolean;
|
|
7
|
+
install: boolean;
|
|
8
|
+
offline: boolean | undefined;
|
|
9
|
+
}
|
|
10
|
+
export declare function create(context: HandlerArgs<CreateOptions>): Promise<void>;
|
|
11
|
+
export {};
|
package/dist/create.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { relico } from "@reliverse/relico";
|
|
3
|
+
import { createProject } from "./create-project.js";
|
|
4
|
+
export async function create(context) {
|
|
5
|
+
const { flags, positional, prompt, spinner, colors, shell } = context;
|
|
6
|
+
let projectName = positional[0] || flags.name;
|
|
7
|
+
if (!projectName) {
|
|
8
|
+
projectName = await prompt("Project name:", {
|
|
9
|
+
validate: (value) => {
|
|
10
|
+
if (!value) {
|
|
11
|
+
return "Project name is required";
|
|
12
|
+
}
|
|
13
|
+
if (!/^[a-z0-9-]+$/.test(value)) {
|
|
14
|
+
return "Project name must only contain lowercase letters, numbers, and hyphens";
|
|
15
|
+
}
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
} else if (!/^[a-z0-9-]+$/.test(projectName)) {
|
|
20
|
+
console.error(
|
|
21
|
+
relico.red("Project name must only contain lowercase letters, numbers, and hyphens")
|
|
22
|
+
);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
const projectDir = flags.dir || path.join(process.cwd(), projectName);
|
|
26
|
+
console.log();
|
|
27
|
+
console.log(relico.bold("Creating Rempts project:"));
|
|
28
|
+
console.log(relico.dim(" Name: ") + relico.cyan(projectName));
|
|
29
|
+
console.log(relico.dim(" Template: ") + relico.cyan(flags.template));
|
|
30
|
+
console.log(relico.dim(" Location: ") + relico.cyan(projectDir));
|
|
31
|
+
console.log(relico.dim(" Git: ") + relico.cyan(flags.git ? "Yes" : "No"));
|
|
32
|
+
console.log(relico.dim(" Install: ") + relico.cyan(flags.install ? "Yes" : "No"));
|
|
33
|
+
console.log();
|
|
34
|
+
const confirmed = await prompt.confirm("Continue?", { default: true });
|
|
35
|
+
if (!confirmed) {
|
|
36
|
+
console.log(relico.red("Cancelled"));
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
console.log();
|
|
40
|
+
await createProject({
|
|
41
|
+
name: projectName,
|
|
42
|
+
dir: projectDir,
|
|
43
|
+
template: flags.template,
|
|
44
|
+
git: flags.git,
|
|
45
|
+
install: flags.install,
|
|
46
|
+
offline: flags.offline ?? false,
|
|
47
|
+
prompt,
|
|
48
|
+
spinner,
|
|
49
|
+
colors,
|
|
50
|
+
shell
|
|
51
|
+
});
|
|
52
|
+
console.log();
|
|
53
|
+
console.log(relico.green("\u2728 Project created successfully!"));
|
|
54
|
+
console.log();
|
|
55
|
+
console.log("Next steps:");
|
|
56
|
+
console.log(relico.gray(` cd ${path.relative(process.cwd(), projectDir)}`));
|
|
57
|
+
if (!flags.install) {
|
|
58
|
+
console.log(relico.gray(" bun install"));
|
|
59
|
+
}
|
|
60
|
+
console.log(relico.gray(" bun run dev"));
|
|
61
|
+
console.log();
|
|
62
|
+
}
|
package/dist/mod.d.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export * from "./selection.js";
|
|
6
|
-
export * from "./spinner.js";
|
|
1
|
+
export { createProject } from "./create-project.js";
|
|
2
|
+
export { isLocalTemplate, processTemplate, resolveTemplateSource, } from "./template-engine.js";
|
|
3
|
+
export type { CreateOptions, ProjectConfig, TemplateManifest, TemplateVariable, } from "./types.js";
|
|
4
|
+
export declare const version = "0.1.0";
|
package/dist/mod.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
export { createProject } from "./create-project.js";
|
|
2
|
+
export {
|
|
3
|
+
isLocalTemplate,
|
|
4
|
+
processTemplate,
|
|
5
|
+
resolveTemplateSource
|
|
6
|
+
} from "./template-engine.js";
|
|
7
|
+
export const version = "0.1.0";
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { TemplateManifest } from "./types.js";
|
|
2
|
+
export interface TemplateOptions {
|
|
3
|
+
source: string;
|
|
4
|
+
type?: "github" | "npm" | "local" | "bundled";
|
|
5
|
+
dir: string;
|
|
6
|
+
offline?: boolean;
|
|
7
|
+
variables?: Record<string, string>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Download and process a template
|
|
11
|
+
*/
|
|
12
|
+
export declare function processTemplate(options: TemplateOptions): Promise<{
|
|
13
|
+
dir: string;
|
|
14
|
+
manifest: TemplateManifest | null;
|
|
15
|
+
}>;
|
|
16
|
+
/**
|
|
17
|
+
* Resolve template source to giget-compatible format
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveTemplateSource(template: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Get bundled template path
|
|
22
|
+
*/
|
|
23
|
+
export declare function getBundledTemplatePath(name: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Check if template exists locally (for development)
|
|
26
|
+
*/
|
|
27
|
+
export declare function isLocalTemplate(template: string): Promise<boolean>;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { readdir } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { downloadTemplate } from "giget";
|
|
4
|
+
export async function processTemplate(options) {
|
|
5
|
+
const { source, dir, offline, variables = {} } = options;
|
|
6
|
+
let templateDir;
|
|
7
|
+
if (source.startsWith("/") || source.startsWith("./") || source.startsWith("../")) {
|
|
8
|
+
const sourceDir = source.startsWith("/") ? source : join(process.cwd(), source);
|
|
9
|
+
await Bun.spawn(["cp", "-r", `${sourceDir}/.`, dir], {
|
|
10
|
+
stdout: "inherit",
|
|
11
|
+
stderr: "inherit"
|
|
12
|
+
}).exited;
|
|
13
|
+
templateDir = dir;
|
|
14
|
+
} else {
|
|
15
|
+
const result = await downloadTemplate(source, {
|
|
16
|
+
dir,
|
|
17
|
+
offline: offline ?? false,
|
|
18
|
+
preferOffline: true,
|
|
19
|
+
force: true
|
|
20
|
+
});
|
|
21
|
+
templateDir = result.dir;
|
|
22
|
+
}
|
|
23
|
+
const manifest = await loadTemplateManifest(templateDir);
|
|
24
|
+
if (manifest?.files || Object.keys(variables).length > 0) {
|
|
25
|
+
await processTemplateFiles(templateDir, variables, manifest);
|
|
26
|
+
}
|
|
27
|
+
if (manifest?.hooks?.postInstall) {
|
|
28
|
+
await runPostInstallHooks(templateDir, manifest.hooks.postInstall);
|
|
29
|
+
}
|
|
30
|
+
return { dir: templateDir, manifest };
|
|
31
|
+
}
|
|
32
|
+
async function loadTemplateManifest(dir) {
|
|
33
|
+
const possiblePaths = [
|
|
34
|
+
join(dir, "template.json"),
|
|
35
|
+
join(dir, ".template.json"),
|
|
36
|
+
join(dir, "template.yaml"),
|
|
37
|
+
join(dir, ".template.yaml")
|
|
38
|
+
];
|
|
39
|
+
for (const path of possiblePaths) {
|
|
40
|
+
const file = Bun.file(path);
|
|
41
|
+
if (await file.exists()) {
|
|
42
|
+
const content = await file.text();
|
|
43
|
+
if (path.endsWith(".json")) {
|
|
44
|
+
const manifest = JSON.parse(content);
|
|
45
|
+
try {
|
|
46
|
+
await Bun.spawn(["rm", "-f", path], {
|
|
47
|
+
stdout: "ignore",
|
|
48
|
+
stderr: "ignore"
|
|
49
|
+
}).exited;
|
|
50
|
+
} catch {
|
|
51
|
+
}
|
|
52
|
+
return manifest;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
async function processTemplateFiles(dir, variables, manifest) {
|
|
59
|
+
const files = await getFilesToProcess(dir, manifest);
|
|
60
|
+
for (const file of files) {
|
|
61
|
+
const filePath = join(dir, file);
|
|
62
|
+
const content = await Bun.file(filePath).text();
|
|
63
|
+
let processedContent = content;
|
|
64
|
+
for (const [key, value] of Object.entries(variables)) {
|
|
65
|
+
processedContent = processedContent.replaceAll(`{{${key}}}`, value).replaceAll(`<%= ${key} %>`, value).replaceAll(`$${key}`, value).replaceAll(`__${key}__`, value);
|
|
66
|
+
}
|
|
67
|
+
let newFilePath = filePath;
|
|
68
|
+
for (const [key, value] of Object.entries(variables)) {
|
|
69
|
+
newFilePath = newFilePath.replaceAll(`__${key}__`, value);
|
|
70
|
+
}
|
|
71
|
+
await Bun.write(newFilePath, processedContent);
|
|
72
|
+
if (newFilePath !== filePath) {
|
|
73
|
+
await Bun.spawn(["rm", filePath]).exited;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async function getFilesToProcess(dir, manifest) {
|
|
78
|
+
if (manifest?.files?.include) {
|
|
79
|
+
return manifest.files.include;
|
|
80
|
+
}
|
|
81
|
+
const files = [];
|
|
82
|
+
async function walk(currentDir, prefix = "") {
|
|
83
|
+
const entries = await readdir(currentDir, { withFileTypes: true });
|
|
84
|
+
for (const entry of entries) {
|
|
85
|
+
const path = join(prefix, entry.name);
|
|
86
|
+
if (entry.isDirectory()) {
|
|
87
|
+
if (!["node_modules", ".git", ".next", "dist", "build"].includes(entry.name)) {
|
|
88
|
+
await walk(join(currentDir, entry.name), path);
|
|
89
|
+
}
|
|
90
|
+
} else {
|
|
91
|
+
if (!path.match(/^(template\.json|\.template\.json|\.DS_Store|Thumbs\.db)$/) || path === ".gitignore") {
|
|
92
|
+
files.push(path);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
await walk(dir);
|
|
98
|
+
if (manifest?.files?.exclude) {
|
|
99
|
+
return files.filter((file) => {
|
|
100
|
+
return !manifest.files?.exclude?.some((pattern) => {
|
|
101
|
+
const regexPattern = pattern.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*").replace(/\?/g, "[^/]");
|
|
102
|
+
const regex = new RegExp(`^${regexPattern}$`);
|
|
103
|
+
return regex.test(file);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return files;
|
|
108
|
+
}
|
|
109
|
+
async function runPostInstallHooks(dir, hooks) {
|
|
110
|
+
for (const hook of hooks) {
|
|
111
|
+
const proc = Bun.spawn(hook.split(" "), {
|
|
112
|
+
cwd: dir,
|
|
113
|
+
stdout: "inherit",
|
|
114
|
+
stderr: "inherit"
|
|
115
|
+
});
|
|
116
|
+
await proc.exited;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
export function resolveTemplateSource(template) {
|
|
120
|
+
const specialTemplates = {
|
|
121
|
+
basic: "github:rempts/templates/basic",
|
|
122
|
+
advanced: "github:rempts/templates/advanced",
|
|
123
|
+
monorepo: "github:rempts/templates/monorepo"
|
|
124
|
+
};
|
|
125
|
+
if (specialTemplates[template]) {
|
|
126
|
+
return specialTemplates[template];
|
|
127
|
+
}
|
|
128
|
+
if (template.startsWith("npm:")) {
|
|
129
|
+
return template.replace("npm:", "npm:/");
|
|
130
|
+
}
|
|
131
|
+
if (template.includes("/") && !template.includes(":")) {
|
|
132
|
+
return `github:${template}`;
|
|
133
|
+
}
|
|
134
|
+
return template;
|
|
135
|
+
}
|
|
136
|
+
export function getBundledTemplatePath(name) {
|
|
137
|
+
return join(import.meta.dir, "..", "templates", name);
|
|
138
|
+
}
|
|
139
|
+
export async function isLocalTemplate(template) {
|
|
140
|
+
if (template.startsWith("file:") || template.startsWith("./") || template.startsWith("../")) {
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
const bundledPath = getBundledTemplatePath(template);
|
|
144
|
+
return await Bun.file(join(bundledPath, "package.json")).exists();
|
|
145
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export interface CreateOptions {
|
|
2
|
+
template?: string;
|
|
3
|
+
install?: boolean;
|
|
4
|
+
git?: boolean;
|
|
5
|
+
offline?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface ProjectConfig {
|
|
8
|
+
name: string;
|
|
9
|
+
template: string;
|
|
10
|
+
install: boolean;
|
|
11
|
+
git: boolean;
|
|
12
|
+
offline?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface TemplateManifest {
|
|
15
|
+
name?: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
variables?: TemplateVariable[];
|
|
18
|
+
files?: {
|
|
19
|
+
include?: string[];
|
|
20
|
+
exclude?: string[];
|
|
21
|
+
};
|
|
22
|
+
hooks?: {
|
|
23
|
+
postInstall?: string[];
|
|
24
|
+
};
|
|
25
|
+
requirements?: {
|
|
26
|
+
node?: string;
|
|
27
|
+
bun?: string;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export interface TemplateVariable {
|
|
31
|
+
name: string;
|
|
32
|
+
message: string;
|
|
33
|
+
type?: "string" | "boolean" | "number" | "select";
|
|
34
|
+
default?: any;
|
|
35
|
+
choices?: Array<{
|
|
36
|
+
label: string;
|
|
37
|
+
value: any;
|
|
38
|
+
}>;
|
|
39
|
+
validate?: (value: any) => boolean | string;
|
|
40
|
+
}
|
|
41
|
+
export interface Template {
|
|
42
|
+
name: string;
|
|
43
|
+
description: string;
|
|
44
|
+
files: Record<string, string>;
|
|
45
|
+
}
|
package/package.json
CHANGED
|
@@ -1,51 +1,53 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reliverse/rempts",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"
|
|
5
|
-
"type": "module",
|
|
6
|
-
"exports": {
|
|
7
|
-
".": {
|
|
8
|
-
"types": "./dist/mod.d.ts",
|
|
9
|
-
"default": "./dist/mod.js"
|
|
10
|
-
}
|
|
11
|
-
},
|
|
12
|
-
"description": "",
|
|
13
|
-
"files": [
|
|
14
|
-
"dist",
|
|
15
|
-
"release",
|
|
16
|
-
"cleanup.mjs",
|
|
17
|
-
"package.json"
|
|
18
|
-
],
|
|
3
|
+
"version": "2.3.1",
|
|
4
|
+
"description": "Scaffold new Rempts CLI projects with ease",
|
|
19
5
|
"keywords": [
|
|
20
|
-
"bun"
|
|
6
|
+
"bun",
|
|
7
|
+
"cli",
|
|
8
|
+
"create",
|
|
9
|
+
"rempts",
|
|
10
|
+
"scaffold",
|
|
11
|
+
"starter",
|
|
12
|
+
"template",
|
|
13
|
+
"typescript"
|
|
21
14
|
],
|
|
22
|
-
"
|
|
23
|
-
|
|
15
|
+
"homepage": "https://github.com/reliverse/dler#readme",
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/reliverse/dler/issues"
|
|
24
18
|
},
|
|
25
19
|
"license": "MIT",
|
|
26
|
-
"
|
|
20
|
+
"author": "blefnk",
|
|
27
21
|
"repository": {
|
|
28
22
|
"type": "git",
|
|
29
|
-
"url": "
|
|
30
|
-
"directory": "packages/
|
|
23
|
+
"url": "https://github.com/reliverse/dler.git",
|
|
24
|
+
"directory": "packages/rempts"
|
|
25
|
+
},
|
|
26
|
+
"bin": {
|
|
27
|
+
"rempts": "./src/cli.ts"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"dist",
|
|
31
|
+
"templates"
|
|
32
|
+
],
|
|
33
|
+
"type": "module",
|
|
34
|
+
"module": "./src/mod.ts",
|
|
35
|
+
"types": "./src/mod.ts",
|
|
36
|
+
"exports": {
|
|
37
|
+
".": {
|
|
38
|
+
"types": "./dist/mod.d.ts",
|
|
39
|
+
"import": "./dist/mod.js"
|
|
40
|
+
}
|
|
31
41
|
},
|
|
32
|
-
"bugs": "https://github.com/reliverse/dler/issues",
|
|
33
|
-
"author": "Nazar Kornienko <blefnk@gmail.com>",
|
|
34
42
|
"dependencies": {
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
"
|
|
44
|
-
"pretty-bytes": "^7.1.0",
|
|
45
|
-
"pretty-ms": "^9.3.0",
|
|
46
|
-
"@reliverse/relico": "2.2.9",
|
|
47
|
-
"@reliverse/relinka": "2.2.9",
|
|
48
|
-
"@reliverse/mapkit": "2.2.9",
|
|
49
|
-
"@reliverse/helpers": "2.2.13"
|
|
43
|
+
"@reliverse/relico": "2.3.1",
|
|
44
|
+
"@reliverse/rempts-core": "2.3.1",
|
|
45
|
+
"@reliverse/rempts-test": "2.3.1",
|
|
46
|
+
"@reliverse/rempts-utils": "2.3.1",
|
|
47
|
+
"arktype": "^2.1.29",
|
|
48
|
+
"giget": "^2.0.0"
|
|
49
|
+
},
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"access": "public"
|
|
50
52
|
}
|
|
51
53
|
}
|
package/src/cli.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { createApp, defineCommand, option } from "@reliverse/rempts-core";
|
|
3
|
+
import { type } from "arktype";
|
|
4
|
+
import { create } from "./create";
|
|
5
|
+
|
|
6
|
+
const cli = await createApp({
|
|
7
|
+
config: {
|
|
8
|
+
name: "rempts",
|
|
9
|
+
version: "0.1.0",
|
|
10
|
+
description: "Scaffold new Rempts CLI projects",
|
|
11
|
+
},
|
|
12
|
+
defaultCommand: "create",
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
// Use type assertion to access internal command() method
|
|
16
|
+
// This is needed for the @reliverse/rempts CLI itself which registers commands programmatically
|
|
17
|
+
(cli as any).command(
|
|
18
|
+
defineCommand({
|
|
19
|
+
description: "Create a new Rempts CLI project",
|
|
20
|
+
options: {
|
|
21
|
+
name: option(type("string | undefined"), { description: "Project name" }),
|
|
22
|
+
template: option(type("string | undefined"), {
|
|
23
|
+
short: "t",
|
|
24
|
+
description: "Project template (basic, advanced, monorepo, or github:user/repo)",
|
|
25
|
+
}),
|
|
26
|
+
dir: option(type("string | undefined"), {
|
|
27
|
+
short: "d",
|
|
28
|
+
description: "Directory to create project in",
|
|
29
|
+
}),
|
|
30
|
+
git: option(type("boolean | undefined"), {
|
|
31
|
+
short: "g",
|
|
32
|
+
description: "Initialize git repository",
|
|
33
|
+
}),
|
|
34
|
+
install: option(type("boolean | undefined"), {
|
|
35
|
+
short: "i",
|
|
36
|
+
description: "Install dependencies",
|
|
37
|
+
}),
|
|
38
|
+
offline: option(type("boolean | undefined"), {
|
|
39
|
+
description: "Use cached templates when available",
|
|
40
|
+
}),
|
|
41
|
+
},
|
|
42
|
+
handler: async (context) => {
|
|
43
|
+
// Apply defaults
|
|
44
|
+
const options = {
|
|
45
|
+
name: context.flags.name,
|
|
46
|
+
template: context.flags.template ?? "basic",
|
|
47
|
+
dir: context.flags.dir,
|
|
48
|
+
git: context.flags.git ?? true,
|
|
49
|
+
install: context.flags.install ?? true,
|
|
50
|
+
offline: context.flags.offline ?? false,
|
|
51
|
+
} as {
|
|
52
|
+
name: string | undefined;
|
|
53
|
+
template: string;
|
|
54
|
+
dir: string | undefined;
|
|
55
|
+
git: boolean;
|
|
56
|
+
install: boolean;
|
|
57
|
+
offline: boolean;
|
|
58
|
+
};
|
|
59
|
+
return create({ ...context, flags: options });
|
|
60
|
+
},
|
|
61
|
+
})
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
await cli.run();
|