@chat-js/cli 0.6.0 → 0.6.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/dist/index.js
CHANGED
|
@@ -3844,7 +3844,7 @@ var {
|
|
|
3844
3844
|
// package.json
|
|
3845
3845
|
var package_default = {
|
|
3846
3846
|
name: "@chat-js/cli",
|
|
3847
|
-
version: "0.6.
|
|
3847
|
+
version: "0.6.1",
|
|
3848
3848
|
description: "CLI for creating and extending ChatJS apps",
|
|
3849
3849
|
license: "Apache-2.0",
|
|
3850
3850
|
repository: {
|
|
@@ -3883,9 +3883,10 @@ var package_default = {
|
|
|
3883
3883
|
},
|
|
3884
3884
|
scripts: {
|
|
3885
3885
|
start: "bun src/index.ts",
|
|
3886
|
-
build: "bun build ./src/index.ts --target=node --format=esm --outfile ./dist/index.js",
|
|
3886
|
+
build: "bun run template:sync && bun build ./src/index.ts --target=node --format=esm --outfile ./dist/index.js",
|
|
3887
|
+
"test:unit": "bun run template:sync && bun test src",
|
|
3887
3888
|
"template:sync": "bun ../../scripts/sync-template.ts",
|
|
3888
|
-
prepublishOnly: "bun run
|
|
3889
|
+
prepublishOnly: "bun run build && node ./dist/index.js --help >/dev/null"
|
|
3889
3890
|
},
|
|
3890
3891
|
type: "module",
|
|
3891
3892
|
devDependencies: {
|
|
@@ -19748,9 +19749,134 @@ async function promptInstall(packageManager, skipPrompt) {
|
|
|
19748
19749
|
// src/helpers/scaffold.ts
|
|
19749
19750
|
import { existsSync } from "node:fs";
|
|
19750
19751
|
import { cp, readFile, rm, writeFile } from "node:fs/promises";
|
|
19751
|
-
import { dirname, join, resolve } from "node:path";
|
|
19752
|
+
import { dirname, join, relative, resolve, sep } from "node:path";
|
|
19752
19753
|
import { fileURLToPath } from "node:url";
|
|
19753
19754
|
|
|
19755
|
+
// src/helpers/package-manifest.ts
|
|
19756
|
+
var ESBUILD_VERSION = "^0.28.0";
|
|
19757
|
+
var BETTER_AUTH_PACKAGES = [
|
|
19758
|
+
"@better-auth/core",
|
|
19759
|
+
"@better-auth/electron",
|
|
19760
|
+
"better-auth"
|
|
19761
|
+
];
|
|
19762
|
+
function toExactVersion(range) {
|
|
19763
|
+
return range.replace(/^[~^]/, "");
|
|
19764
|
+
}
|
|
19765
|
+
function resolveBetterAuthVersion(packageJson) {
|
|
19766
|
+
for (const dependencyGroup of [
|
|
19767
|
+
packageJson.dependencies,
|
|
19768
|
+
packageJson.devDependencies
|
|
19769
|
+
]) {
|
|
19770
|
+
if (!dependencyGroup) {
|
|
19771
|
+
continue;
|
|
19772
|
+
}
|
|
19773
|
+
for (const packageName of BETTER_AUTH_PACKAGES) {
|
|
19774
|
+
const version2 = dependencyGroup[packageName];
|
|
19775
|
+
if (version2) {
|
|
19776
|
+
return toExactVersion(version2);
|
|
19777
|
+
}
|
|
19778
|
+
}
|
|
19779
|
+
}
|
|
19780
|
+
return null;
|
|
19781
|
+
}
|
|
19782
|
+
function pinBetterAuthVersions(dependencyGroup, version2) {
|
|
19783
|
+
if (!dependencyGroup) {
|
|
19784
|
+
return;
|
|
19785
|
+
}
|
|
19786
|
+
for (const packageName of BETTER_AUTH_PACKAGES) {
|
|
19787
|
+
if (dependencyGroup[packageName]) {
|
|
19788
|
+
dependencyGroup[packageName] = version2;
|
|
19789
|
+
}
|
|
19790
|
+
}
|
|
19791
|
+
}
|
|
19792
|
+
function normalizeChatAppScripts(scripts) {
|
|
19793
|
+
const defaultBranchName = "$" + "{1:-dev-local}";
|
|
19794
|
+
scripts.prebuild = "tsx scripts/check-env.ts";
|
|
19795
|
+
scripts.dev = "tsx scripts/check-env.ts && bash scripts/with-db.sh next dev";
|
|
19796
|
+
scripts["dev:inspect"] = "tsx scripts/check-env.ts && bash scripts/with-db.sh next dev --inspect";
|
|
19797
|
+
scripts.prod = "tsx scripts/check-env.ts && tsx lib/db/migrate.ts && next build && next start";
|
|
19798
|
+
scripts.lint = "ultracite check";
|
|
19799
|
+
scripts.format = "ultracite fix";
|
|
19800
|
+
scripts["check-env"] = "tsx scripts/check-env.ts";
|
|
19801
|
+
scripts["db:migrate"] = "export VERCEL_ENV=production && bash scripts/with-db.sh tsx lib/db/migrate.ts";
|
|
19802
|
+
scripts["db:backfill-parts"] = "tsx lib/db/backfill-parts.ts";
|
|
19803
|
+
scripts["db:branch:start"] = `bash -c 'N=${defaultBranchName}; bash scripts/db-branch-create.sh "$N" && bash scripts/db-branch-use.sh "$N"' --`;
|
|
19804
|
+
scripts["db:branch:stop"] = `bash -c 'N=${defaultBranchName}; bash scripts/db-branch-use.sh main && bash scripts/db-branch-delete.sh "$N"' --`;
|
|
19805
|
+
scripts["db:branch:list"] = "npx neonctl branches list";
|
|
19806
|
+
scripts["skiller:apply"] = "npx skiller@latest apply";
|
|
19807
|
+
scripts.test = "export PLAYWRIGHT=True && playwright test --workers=4 && vitest run";
|
|
19808
|
+
scripts["test:e2e"] = "export PLAYWRIGHT=True && playwright test --workers=4";
|
|
19809
|
+
scripts["ai:devtools"] = "npx @ai-sdk/devtools";
|
|
19810
|
+
scripts["fetch:models"] = "tsx scripts/fetch-models.ts && ultracite fix";
|
|
19811
|
+
}
|
|
19812
|
+
function normalizeElectronScripts(scripts) {
|
|
19813
|
+
const prebuild = "tsx scripts/write-branding.ts && tsx scripts/generate-icons.ts";
|
|
19814
|
+
const build = "esbuild src/main.ts --bundle --platform=node --format=cjs --outfile=dist/main.js --external:electron --external:electron-updater --alias:@=.. && esbuild src/preload.ts --bundle --platform=browser --format=cjs --outfile=dist/preload.js --external:electron --alias:@=..";
|
|
19815
|
+
scripts.forge = "node ./scripts/run-forge.cjs";
|
|
19816
|
+
scripts["generate-icons"] = "tsx scripts/generate-icons.ts";
|
|
19817
|
+
scripts.prebuild = prebuild;
|
|
19818
|
+
scripts.build = build;
|
|
19819
|
+
scripts.start = "node ./scripts/run-forge.cjs start";
|
|
19820
|
+
scripts.dev = "node ./scripts/run-forge.cjs start";
|
|
19821
|
+
scripts.package = "node ./scripts/run-forge.cjs package";
|
|
19822
|
+
scripts.make = "node ./scripts/run-forge.cjs make";
|
|
19823
|
+
scripts["make:mac"] = "node ./scripts/run-forge.cjs make --platform=darwin --arch=universal";
|
|
19824
|
+
scripts["make:win"] = "node ./scripts/run-forge.cjs make --platform=win32 --arch=x64";
|
|
19825
|
+
scripts["make:linux"] = "node ./scripts/run-forge.cjs make --platform=linux --arch=x64";
|
|
19826
|
+
scripts.publish = "node ./scripts/run-forge.cjs publish";
|
|
19827
|
+
scripts["electron:build"] = build;
|
|
19828
|
+
scripts["electron:dev"] = scripts.dev;
|
|
19829
|
+
scripts["electron:make"] = scripts.make;
|
|
19830
|
+
scripts["electron:publish"] = scripts.publish;
|
|
19831
|
+
delete scripts["dist:mac"];
|
|
19832
|
+
delete scripts["dist:win"];
|
|
19833
|
+
delete scripts["dist:linux"];
|
|
19834
|
+
delete scripts["publish:mac"];
|
|
19835
|
+
delete scripts["publish:win"];
|
|
19836
|
+
}
|
|
19837
|
+
function normalizeElectronDevDependencies(devDependencies, tsxVersion) {
|
|
19838
|
+
if (!devDependencies) {
|
|
19839
|
+
return;
|
|
19840
|
+
}
|
|
19841
|
+
devDependencies.esbuild = ESBUILD_VERSION;
|
|
19842
|
+
if (tsxVersion) {
|
|
19843
|
+
devDependencies.tsx = tsxVersion;
|
|
19844
|
+
}
|
|
19845
|
+
}
|
|
19846
|
+
function normalizeScaffoldedPackageJson(packageJson, options) {
|
|
19847
|
+
const betterAuthVersion = resolveBetterAuthVersion(packageJson);
|
|
19848
|
+
if (betterAuthVersion) {
|
|
19849
|
+
pinBetterAuthVersions(packageJson.dependencies, betterAuthVersion);
|
|
19850
|
+
pinBetterAuthVersions(packageJson.devDependencies, betterAuthVersion);
|
|
19851
|
+
packageJson.overrides = {
|
|
19852
|
+
...packageJson.overrides ?? {},
|
|
19853
|
+
"@better-auth/core": betterAuthVersion
|
|
19854
|
+
};
|
|
19855
|
+
}
|
|
19856
|
+
switch (options?.template) {
|
|
19857
|
+
case "chat-app":
|
|
19858
|
+
if (packageJson.scripts) {
|
|
19859
|
+
normalizeChatAppScripts(packageJson.scripts);
|
|
19860
|
+
}
|
|
19861
|
+
break;
|
|
19862
|
+
case "electron":
|
|
19863
|
+
if (packageJson.scripts) {
|
|
19864
|
+
normalizeElectronScripts(packageJson.scripts);
|
|
19865
|
+
}
|
|
19866
|
+
normalizeElectronDevDependencies(packageJson.devDependencies, options?.tsxVersion);
|
|
19867
|
+
break;
|
|
19868
|
+
default:
|
|
19869
|
+
break;
|
|
19870
|
+
}
|
|
19871
|
+
if (options?.persistPackageManager !== false) {
|
|
19872
|
+
const packageManager = options?.packageManager ?? "bun";
|
|
19873
|
+
if (packageManager !== "bun") {
|
|
19874
|
+
delete packageJson.packageManager;
|
|
19875
|
+
}
|
|
19876
|
+
}
|
|
19877
|
+
return packageJson;
|
|
19878
|
+
}
|
|
19879
|
+
|
|
19754
19880
|
// src/utils/run-command.ts
|
|
19755
19881
|
import { spawn as spawn2 } from "node:child_process";
|
|
19756
19882
|
async function runCommand(command, args, cwd) {
|
|
@@ -19772,26 +19898,273 @@ ${stderr.join("")}`.trim()));
|
|
|
19772
19898
|
}
|
|
19773
19899
|
|
|
19774
19900
|
// src/helpers/scaffold.ts
|
|
19775
|
-
|
|
19901
|
+
var CHAT_APP_EXCLUDED_SEGMENTS = new Set([
|
|
19902
|
+
"node_modules",
|
|
19903
|
+
".next",
|
|
19904
|
+
".turbo",
|
|
19905
|
+
"playwright",
|
|
19906
|
+
"playwright-report",
|
|
19907
|
+
"test-results",
|
|
19908
|
+
"blob-report",
|
|
19909
|
+
"dist",
|
|
19910
|
+
"build"
|
|
19911
|
+
]);
|
|
19912
|
+
var CHAT_APP_EXCLUDED_FILES = new Set([
|
|
19913
|
+
".env.local",
|
|
19914
|
+
".DS_Store",
|
|
19915
|
+
"bun.lock",
|
|
19916
|
+
"bun.lockb"
|
|
19917
|
+
]);
|
|
19918
|
+
var ELECTRON_EXCLUDED_SEGMENTS = new Set([
|
|
19919
|
+
"node_modules",
|
|
19920
|
+
".turbo",
|
|
19921
|
+
"build",
|
|
19922
|
+
"dist",
|
|
19923
|
+
"release"
|
|
19924
|
+
]);
|
|
19925
|
+
var ELECTRON_EXCLUDED_FILES = new Set([
|
|
19926
|
+
".DS_Store",
|
|
19927
|
+
"bun.lock",
|
|
19928
|
+
"bun.lockb",
|
|
19929
|
+
"branding.json"
|
|
19930
|
+
]);
|
|
19931
|
+
function getCliPackageRoot() {
|
|
19776
19932
|
const __dir = dirname(fileURLToPath(import.meta.url));
|
|
19777
|
-
for (const
|
|
19778
|
-
const candidate = resolve(__dir,
|
|
19779
|
-
if (existsSync(candidate))
|
|
19933
|
+
for (const relative2 of ["..", "../.."]) {
|
|
19934
|
+
const candidate = resolve(__dir, relative2);
|
|
19935
|
+
if (existsSync(join(candidate, "package.json"))) {
|
|
19780
19936
|
return candidate;
|
|
19937
|
+
}
|
|
19938
|
+
}
|
|
19939
|
+
throw new Error("Could not locate the @chat-js/cli package root.");
|
|
19940
|
+
}
|
|
19941
|
+
function getRepoRoot() {
|
|
19942
|
+
return resolve(getCliPackageRoot(), "../..");
|
|
19943
|
+
}
|
|
19944
|
+
function findTemplateDir(name) {
|
|
19945
|
+
const cliRoot = getCliPackageRoot();
|
|
19946
|
+
const candidate = join(cliRoot, "templates", name);
|
|
19947
|
+
return existsSync(candidate) ? candidate : null;
|
|
19948
|
+
}
|
|
19949
|
+
function shouldCopyChatAppFilePath(sourceDir, filePath) {
|
|
19950
|
+
const relativePath = relative(sourceDir, filePath);
|
|
19951
|
+
const segments = relativePath.split(sep);
|
|
19952
|
+
if (segments.some((segment) => CHAT_APP_EXCLUDED_SEGMENTS.has(segment))) {
|
|
19953
|
+
return false;
|
|
19781
19954
|
}
|
|
19782
|
-
|
|
19955
|
+
const fileName = segments.at(-1);
|
|
19956
|
+
return !(fileName && CHAT_APP_EXCLUDED_FILES.has(fileName));
|
|
19957
|
+
}
|
|
19958
|
+
function shouldCopyElectronFilePath(sourceDir, filePath) {
|
|
19959
|
+
const relativePath = relative(sourceDir, filePath);
|
|
19960
|
+
const segments = relativePath.split(sep);
|
|
19961
|
+
if (segments.some((segment) => ELECTRON_EXCLUDED_SEGMENTS.has(segment))) {
|
|
19962
|
+
return false;
|
|
19963
|
+
}
|
|
19964
|
+
const fileName = segments.at(-1);
|
|
19965
|
+
return !(fileName && ELECTRON_EXCLUDED_FILES.has(fileName));
|
|
19966
|
+
}
|
|
19967
|
+
function runScript(packageManager, script) {
|
|
19968
|
+
return `${packageManager} run ${script}`;
|
|
19969
|
+
}
|
|
19970
|
+
function execCommand(packageManager) {
|
|
19971
|
+
switch (packageManager) {
|
|
19972
|
+
case "bun":
|
|
19973
|
+
return "bunx";
|
|
19974
|
+
case "pnpm":
|
|
19975
|
+
return "pnpm dlx";
|
|
19976
|
+
case "yarn":
|
|
19977
|
+
return "yarn dlx";
|
|
19978
|
+
case "npm":
|
|
19979
|
+
return "npx";
|
|
19980
|
+
}
|
|
19981
|
+
}
|
|
19982
|
+
async function replaceInFile(filePath, replacements) {
|
|
19983
|
+
if (!existsSync(filePath)) {
|
|
19984
|
+
return;
|
|
19985
|
+
}
|
|
19986
|
+
let content = await readFile(filePath, "utf8");
|
|
19987
|
+
for (const [search, replacement] of replacements) {
|
|
19988
|
+
content = content.replaceAll(search, replacement);
|
|
19989
|
+
}
|
|
19990
|
+
await writeFile(filePath, content);
|
|
19991
|
+
}
|
|
19992
|
+
async function applyChatTemplateSourceTransforms(destination) {
|
|
19993
|
+
await Promise.all(["components/github-link.tsx", "components/docs-link.tsx"].map((file2) => rm(join(destination, file2), { force: true })));
|
|
19994
|
+
const headerPath = join(destination, "components", "header-actions.tsx");
|
|
19995
|
+
await replaceInFile(headerPath, [
|
|
19996
|
+
[`import { DocsLink } from "@/components/docs-link";
|
|
19997
|
+
`, ""],
|
|
19998
|
+
[`import { GitHubLink } from "@/components/github-link";
|
|
19999
|
+
`, ""],
|
|
20000
|
+
["<DocsLink />", ""],
|
|
20001
|
+
["<GitHubLink />", ""]
|
|
20002
|
+
]);
|
|
20003
|
+
const globalsCssPath = join(destination, "app", "globals.css");
|
|
20004
|
+
await replaceInFile(globalsCssPath, [
|
|
20005
|
+
[
|
|
20006
|
+
`@source "../node_modules/streamdown/dist/*.js";
|
|
20007
|
+
@source "../../../node_modules/streamdown/dist/*.js";`,
|
|
20008
|
+
'@source "../node_modules/streamdown/dist/*.js";'
|
|
20009
|
+
]
|
|
20010
|
+
]);
|
|
20011
|
+
const repoPackageJsonPath = join(getRepoRoot(), "package.json");
|
|
20012
|
+
const rootPackageJson = JSON.parse(await readFile(repoPackageJsonPath, "utf8"));
|
|
20013
|
+
const packageJsonPath = join(destination, "package.json");
|
|
20014
|
+
const packageJson = JSON.parse(await readFile(packageJsonPath, "utf8"));
|
|
20015
|
+
packageJson.packageManager = rootPackageJson.packageManager;
|
|
20016
|
+
await writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
|
|
20017
|
+
`);
|
|
19783
20018
|
}
|
|
19784
|
-
async function
|
|
20019
|
+
async function applyElectronTemplateSourceTransforms(destination) {
|
|
20020
|
+
const tsconfigPath = join(destination, "tsconfig.json");
|
|
20021
|
+
await replaceInFile(tsconfigPath, [['"../chat/*"', '"../*"']]);
|
|
20022
|
+
const packageJsonPath = join(destination, "package.json");
|
|
20023
|
+
await replaceInFile(packageJsonPath, [
|
|
20024
|
+
['"name": "@chatjs/electron"', '"name": "__PROJECT_NAME__-electron"'],
|
|
20025
|
+
[
|
|
20026
|
+
'"url": "https://github.com/FranciscoMoretti/chat-js.git"',
|
|
20027
|
+
'"url": "https://github.com/__GITHUB_OWNER__/__GITHUB_REPO__.git"'
|
|
20028
|
+
]
|
|
20029
|
+
]);
|
|
20030
|
+
}
|
|
20031
|
+
async function copyChatTemplateFromRepoSource(destination) {
|
|
20032
|
+
const sourceDir = join(getRepoRoot(), "apps", "chat");
|
|
20033
|
+
await cp(sourceDir, destination, {
|
|
20034
|
+
recursive: true,
|
|
20035
|
+
filter: (filePath) => shouldCopyChatAppFilePath(sourceDir, filePath)
|
|
20036
|
+
});
|
|
20037
|
+
await applyChatTemplateSourceTransforms(destination);
|
|
20038
|
+
}
|
|
20039
|
+
async function copyElectronTemplateFromRepoSource(destination) {
|
|
20040
|
+
const sourceDir = join(getRepoRoot(), "apps", "electron");
|
|
20041
|
+
await cp(sourceDir, destination, {
|
|
20042
|
+
recursive: true,
|
|
20043
|
+
filter: (filePath) => shouldCopyElectronFilePath(sourceDir, filePath)
|
|
20044
|
+
});
|
|
20045
|
+
await applyElectronTemplateSourceTransforms(destination);
|
|
20046
|
+
}
|
|
20047
|
+
async function normalizeChatAppFiles(destination, packageManager) {
|
|
20048
|
+
await replaceInFile(join(destination, "playwright.config.ts"), [
|
|
20049
|
+
['command: "bun dev"', `command: "${runScript(packageManager, "dev")}"`]
|
|
20050
|
+
]);
|
|
20051
|
+
await replaceInFile(join(destination, "scripts", "check-env.ts"), [
|
|
20052
|
+
[
|
|
20053
|
+
" * Run via `bun run check-env` or automatically in prebuild.",
|
|
20054
|
+
` * Run via \`${runScript(packageManager, "check-env")}\` or automatically in prebuild.`
|
|
20055
|
+
],
|
|
20056
|
+
[
|
|
20057
|
+
"bun fetch:models",
|
|
20058
|
+
runScript(packageManager, "fetch:models")
|
|
20059
|
+
]
|
|
20060
|
+
]);
|
|
20061
|
+
await replaceInFile(join(destination, "lib", "ai", "gateways", "fallback-models.ts"), [
|
|
20062
|
+
[
|
|
20063
|
+
"bun fetch:models",
|
|
20064
|
+
runScript(packageManager, "fetch:models")
|
|
20065
|
+
]
|
|
20066
|
+
]);
|
|
20067
|
+
await replaceInFile(join(destination, "scripts", "with-db.sh"), [
|
|
20068
|
+
["bunx neonctl", `${execCommand(packageManager)} neonctl`],
|
|
20069
|
+
["filter out bun's package resolution output", `filter out ${execCommand(packageManager)} resolution output`],
|
|
20070
|
+
[
|
|
20071
|
+
"Run: bun db:branch:use main (to switch back to main)",
|
|
20072
|
+
"Run: bash scripts/db-branch-use.sh main (to switch back to main)"
|
|
20073
|
+
]
|
|
20074
|
+
]);
|
|
20075
|
+
await replaceInFile(join(destination, "scripts", "db-branch-create.sh"), [
|
|
20076
|
+
["bunx neonctl", `${execCommand(packageManager)} neonctl`],
|
|
20077
|
+
[
|
|
20078
|
+
'echo "To use it: bun db:branch:use $BRANCH_NAME"',
|
|
20079
|
+
'echo "To use it: bash scripts/db-branch-use.sh $BRANCH_NAME"'
|
|
20080
|
+
]
|
|
20081
|
+
]);
|
|
20082
|
+
await replaceInFile(join(destination, "scripts", "db-branch-use.sh"), [
|
|
20083
|
+
["bunx neonctl", `${execCommand(packageManager)} neonctl`],
|
|
20084
|
+
['echo "Usage: bun db:branch:use <branch-name>"', 'echo "Usage: bash scripts/db-branch-use.sh <branch-name>"'],
|
|
20085
|
+
[
|
|
20086
|
+
'echo " bun db:branch:use main (switch to production)"',
|
|
20087
|
+
'echo " bash scripts/db-branch-use.sh main (switch to production)"'
|
|
20088
|
+
],
|
|
20089
|
+
['echo "Available branches: bun db:branch:list"', `echo "Available branches: ${execCommand(packageManager)} neonctl branches list"`],
|
|
20090
|
+
['echo "Create branch: bun db:branch:create"', 'echo "Create branch: bash scripts/db-branch-create.sh"']
|
|
20091
|
+
]);
|
|
20092
|
+
await replaceInFile(join(destination, "scripts", "db-branch-delete.sh"), [
|
|
20093
|
+
["bunx neonctl", `${execCommand(packageManager)} neonctl`]
|
|
20094
|
+
]);
|
|
20095
|
+
await replaceInFile(join(destination, "scripts", "worktree-setup.sh"), [
|
|
20096
|
+
["bun i", `${packageManager} install`]
|
|
20097
|
+
]);
|
|
20098
|
+
const vercelJsonPath = join(destination, "vercel.json");
|
|
20099
|
+
const vercelJson = JSON.parse(await readFile(vercelJsonPath, "utf8"));
|
|
20100
|
+
vercelJson.installCommand = `${packageManager} install`;
|
|
20101
|
+
vercelJson.buildCommand = runScript(packageManager, "build");
|
|
20102
|
+
await writeFile(vercelJsonPath, `${JSON.stringify(vercelJson, null, 2)}
|
|
20103
|
+
`);
|
|
20104
|
+
}
|
|
20105
|
+
async function normalizeElectronFiles(destination, packageManager) {
|
|
20106
|
+
const scriptPlaceholder = "$" + "{script}";
|
|
20107
|
+
await replaceInFile(join(destination, "forge.config.ts"), [
|
|
20108
|
+
["Run \\`bun run prebuild\\`", "Run \\`" + runScript(packageManager, "prebuild") + "\\`"],
|
|
20109
|
+
["function runBunScript", "function runPackageManagerScript"],
|
|
20110
|
+
['spawnSync("bun", ["run", script], {', `spawnSync("${packageManager}", ["run", script], {`],
|
|
20111
|
+
[`bun run ${scriptPlaceholder} failed`, `${packageManager} run ${scriptPlaceholder} failed`],
|
|
20112
|
+
[' runBunScript("prebuild");', ' runPackageManagerScript("prebuild");'],
|
|
20113
|
+
[
|
|
20114
|
+
' runBunScript("build", { NODE_ENV: "development" });',
|
|
20115
|
+
' runPackageManagerScript("build", { NODE_ENV: "development" });'
|
|
20116
|
+
],
|
|
20117
|
+
[
|
|
20118
|
+
' runBunScript("build", { NODE_ENV: "production" });',
|
|
20119
|
+
' runPackageManagerScript("build", { NODE_ENV: "production" });'
|
|
20120
|
+
]
|
|
20121
|
+
]);
|
|
20122
|
+
await replaceInFile(join(destination, "README.md"), [
|
|
20123
|
+
["bun install", `${packageManager} install`],
|
|
20124
|
+
["bun run dev", runScript(packageManager, "dev")],
|
|
20125
|
+
["bun run generate-icons", runScript(packageManager, "generate-icons")],
|
|
20126
|
+
["bun run make:mac", runScript(packageManager, "make:mac")],
|
|
20127
|
+
["bun run make:win", runScript(packageManager, "make:win")],
|
|
20128
|
+
["bun run make:linux", runScript(packageManager, "make:linux")]
|
|
20129
|
+
]);
|
|
20130
|
+
}
|
|
20131
|
+
async function scaffoldFromTemplate(destination, options) {
|
|
20132
|
+
const packageManager = options?.packageManager ?? "bun";
|
|
19785
20133
|
const templateDir = findTemplateDir("chat-app");
|
|
19786
|
-
|
|
20134
|
+
if (templateDir) {
|
|
20135
|
+
await cp(templateDir, destination, { recursive: true });
|
|
20136
|
+
} else {
|
|
20137
|
+
await copyChatTemplateFromRepoSource(destination);
|
|
20138
|
+
}
|
|
20139
|
+
const packageJsonPath = join(destination, "package.json");
|
|
20140
|
+
const packageJson = normalizeScaffoldedPackageJson(JSON.parse(await readFile(packageJsonPath, "utf8")), {
|
|
20141
|
+
packageManager,
|
|
20142
|
+
template: "chat-app"
|
|
20143
|
+
});
|
|
20144
|
+
await writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
|
|
20145
|
+
`);
|
|
20146
|
+
await normalizeChatAppFiles(destination, packageManager);
|
|
19787
20147
|
}
|
|
19788
20148
|
async function scaffoldElectron(projectDir, opts) {
|
|
19789
|
-
const
|
|
20149
|
+
const packageManager = opts.packageManager ?? "bun";
|
|
20150
|
+
const rootPackageJsonPath = join(projectDir, "package.json");
|
|
20151
|
+
const rootPackageJson = JSON.parse(await readFile(rootPackageJsonPath, "utf8"));
|
|
19790
20152
|
const destination = join(projectDir, "electron");
|
|
19791
|
-
|
|
20153
|
+
const templateDir = findTemplateDir("electron");
|
|
20154
|
+
if (templateDir) {
|
|
20155
|
+
await cp(templateDir, destination, { recursive: true });
|
|
20156
|
+
} else {
|
|
20157
|
+
await copyElectronTemplateFromRepoSource(destination);
|
|
20158
|
+
}
|
|
19792
20159
|
const packageJsonPath = join(destination, "package.json");
|
|
19793
|
-
const packageJson = (await readFile(packageJsonPath, "utf8")).replace("__PROJECT_NAME__-electron", `${opts.projectName}-electron`).replace("__GITHUB_OWNER__", "your-github-username").replace("__GITHUB_REPO__", opts.projectName)
|
|
19794
|
-
|
|
20160
|
+
const packageJson = normalizeScaffoldedPackageJson(JSON.parse((await readFile(packageJsonPath, "utf8")).replace("__PROJECT_NAME__-electron", `${opts.projectName}-electron`).replace("__GITHUB_OWNER__", "your-github-username").replace("__GITHUB_REPO__", opts.projectName)), {
|
|
20161
|
+
packageManager,
|
|
20162
|
+
template: "electron",
|
|
20163
|
+
tsxVersion: rootPackageJson.devDependencies?.tsx
|
|
20164
|
+
});
|
|
20165
|
+
await writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
|
|
20166
|
+
`);
|
|
20167
|
+
await normalizeElectronFiles(destination, packageManager);
|
|
19795
20168
|
}
|
|
19796
20169
|
async function scaffoldFromGit(url2, destination) {
|
|
19797
20170
|
await runCommand("git", ["clone", "--depth", "1", url2, destination], process.cwd());
|
|
@@ -21197,15 +21570,16 @@ var createOptionsSchema = exports_external.object({
|
|
|
21197
21570
|
yes: exports_external.boolean(),
|
|
21198
21571
|
install: exports_external.boolean(),
|
|
21199
21572
|
electron: exports_external.boolean().optional(),
|
|
21200
|
-
fromGit: exports_external.string().optional()
|
|
21573
|
+
fromGit: exports_external.string().optional(),
|
|
21574
|
+
packageManager: exports_external.enum(["bun", "npm", "pnpm", "yarn"]).optional()
|
|
21201
21575
|
});
|
|
21202
|
-
var create = new Command().name("create").description("scaffold a new ChatJS chat application").argument("[directory]", "target directory for the project").option("-y, --yes", "skip prompts and use defaults", false).option("--no-install", "skip dependency installation").option("--electron", "include the Electron desktop app").option("--no-electron", "do not include the Electron desktop app").option("--from-git <url>", "clone from a git repository instead of the built-in scaffold").action(async (directory, opts) => {
|
|
21576
|
+
var create = new Command().name("create").description("scaffold a new ChatJS chat application").argument("[directory]", "target directory for the project").option("-y, --yes", "skip prompts and use defaults", false).option("--no-install", "skip dependency installation").option("--electron", "include the Electron desktop app").option("--no-electron", "do not include the Electron desktop app").option("--package-manager <manager>", "package manager for install + next steps (bun, npm, pnpm, yarn)").option("--from-git <url>", "clone from a git repository instead of the built-in scaffold").action(async (directory, opts) => {
|
|
21203
21577
|
try {
|
|
21204
21578
|
const options = createOptionsSchema.parse({
|
|
21205
21579
|
target: directory,
|
|
21206
21580
|
...opts
|
|
21207
21581
|
});
|
|
21208
|
-
const packageManager = inferPackageManager();
|
|
21582
|
+
const packageManager = options.packageManager ?? inferPackageManager();
|
|
21209
21583
|
if (!options.yes) {
|
|
21210
21584
|
mt("Create ChatJS App");
|
|
21211
21585
|
}
|
|
@@ -21225,11 +21599,12 @@ var create = new Command().name("create").description("scaffold a new ChatJS cha
|
|
|
21225
21599
|
if (options.fromGit) {
|
|
21226
21600
|
await scaffoldFromGit(options.fromGit, targetDir);
|
|
21227
21601
|
} else {
|
|
21228
|
-
await scaffoldFromTemplate(targetDir);
|
|
21602
|
+
await scaffoldFromTemplate(targetDir, { packageManager });
|
|
21229
21603
|
}
|
|
21230
21604
|
if (withElectron) {
|
|
21231
21605
|
await scaffoldElectron(targetDir, {
|
|
21232
|
-
projectName
|
|
21606
|
+
projectName,
|
|
21607
|
+
packageManager
|
|
21233
21608
|
});
|
|
21234
21609
|
}
|
|
21235
21610
|
scaffoldSpinner.succeed("Project scaffolded.");
|
|
@@ -21287,7 +21662,7 @@ var create = new Command().name("create").description("scaffold a new ChatJS cha
|
|
|
21287
21662
|
if (withElectron) {
|
|
21288
21663
|
logger.break();
|
|
21289
21664
|
logger.info("Electron desktop app:");
|
|
21290
|
-
logger.log(` Run the web app first, then: ${highlighter.info(`cd electron &&
|
|
21665
|
+
logger.log(` Run the web app first, then: ${highlighter.info(`cd electron && ${packageManager} install && ${packageManager} run dev`)}`);
|
|
21291
21666
|
}
|
|
21292
21667
|
logger.break();
|
|
21293
21668
|
printEnvChecklist(envEntries);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chat-js/cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "CLI for creating and extending ChatJS apps",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -39,9 +39,10 @@
|
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"start": "bun src/index.ts",
|
|
42
|
-
"build": "bun build ./src/index.ts --target=node --format=esm --outfile ./dist/index.js",
|
|
42
|
+
"build": "bun run template:sync && bun build ./src/index.ts --target=node --format=esm --outfile ./dist/index.js",
|
|
43
|
+
"test:unit": "bun run template:sync && bun test src",
|
|
43
44
|
"template:sync": "bun ../../scripts/sync-template.ts",
|
|
44
|
-
"prepublishOnly": "bun run
|
|
45
|
+
"prepublishOnly": "bun run build && node ./dist/index.js --help >/dev/null"
|
|
45
46
|
},
|
|
46
47
|
"type": "module",
|
|
47
48
|
"devDependencies": {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, readFileSync
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { spawnSync } from "node:child_process";
|
|
4
4
|
import type { ForgeConfig } from "@electron-forge/shared-types";
|
|
@@ -61,10 +61,6 @@ function ensurePrebuild(): void {
|
|
|
61
61
|
prebuildComplete = true;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
function removeLocalNodeModules(): void {
|
|
65
|
-
rmSync(join(appRoot, "node_modules"), { recursive: true, force: true });
|
|
66
|
-
}
|
|
67
|
-
|
|
68
64
|
function createForgeConfig(): ForgeConfig {
|
|
69
65
|
const branding = loadBranding();
|
|
70
66
|
const { appName, appPrefix, orgName, orgEmail } = branding;
|
|
@@ -146,7 +142,6 @@ function createForgeConfig(): ForgeConfig {
|
|
|
146
142
|
},
|
|
147
143
|
prePackage: async () => {
|
|
148
144
|
runBunScript("build", { NODE_ENV: "production" });
|
|
149
|
-
removeLocalNodeModules();
|
|
150
145
|
},
|
|
151
146
|
},
|
|
152
147
|
};
|