jsrepo 1.2.4 → 1.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/dist/index.js +745 -380
- package/package.json +1 -1
- package/src/commands/add.ts +85 -166
- package/src/commands/build.ts +7 -7
- package/src/commands/diff.ts +25 -47
- package/src/commands/index.ts +2 -1
- package/src/commands/init.ts +7 -7
- package/src/commands/test.ts +14 -14
- package/src/commands/update.ts +434 -0
- package/src/index.ts +1 -0
- package/src/utils/ascii.ts +12 -0
- package/src/{blocks → utils/blocks}/types/result.ts +1 -1
- package/src/{blocks → utils/blocks}/utils/array-sum.ts +1 -1
- package/src/{blocks → utils/blocks}/utils/lines.ts +1 -1
- package/src/{blocks → utils/blocks}/utils/map-to-array.ts +1 -1
- package/src/{blocks → utils/blocks}/utils/pad.ts +1 -1
- package/src/{blocks → utils/blocks}/utils/strip-ansi.ts +1 -1
- package/src/utils/blocks.ts +123 -0
- package/src/utils/build.ts +3 -3
- package/src/{config/index.ts → utils/config.ts} +1 -1
- package/src/utils/context.ts +1 -1
- package/src/utils/dependencies.ts +49 -0
- package/src/utils/diff.ts +3 -3
- package/src/utils/git-providers.ts +52 -12
- package/src/utils/language-support.ts +4 -4
- package/src/utils/parse-package-name.ts +10 -2
- package/src/utils/prompts.ts +26 -22
- package/src/utils/get-installed-blocks.ts +0 -42
- package/src/utils/index.ts +0 -9
package/dist/index.js
CHANGED
|
@@ -1,35 +1,37 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import fs12 from "node:fs";
|
|
3
|
+
import path12 from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
-
import { program as
|
|
5
|
+
import { program as program6 } from "commander";
|
|
6
6
|
|
|
7
7
|
// src/commands/add.ts
|
|
8
8
|
import fs6 from "node:fs";
|
|
9
9
|
import path6 from "node:path";
|
|
10
10
|
import { cancel, confirm, isCancel, multiselect, outro, spinner as spinner2 } from "@clack/prompts";
|
|
11
|
-
import
|
|
11
|
+
import color7 from "chalk";
|
|
12
12
|
import { Command, program as program2 } from "commander";
|
|
13
|
-
import {
|
|
14
|
-
import { resolveCommand } from "package-manager-detector/commands";
|
|
13
|
+
import { resolveCommand as resolveCommand2 } from "package-manager-detector/commands";
|
|
15
14
|
import { detect } from "package-manager-detector/detect";
|
|
16
15
|
import * as v4 from "valibot";
|
|
17
16
|
|
|
18
|
-
// src/
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
17
|
+
// src/utils/ascii.ts
|
|
18
|
+
import color from "chalk";
|
|
19
|
+
var VERTICAL_LINE = color.gray("\u2502");
|
|
20
|
+
var HORIZONTAL_LINE = color.gray("\u2500");
|
|
21
|
+
var TOP_RIGHT_CORNER = color.gray("\u2510");
|
|
22
|
+
var BOTTOM_RIGHT_CORNER = color.gray("\u2518");
|
|
23
|
+
var JUNCTION_RIGHT = color.gray("\u251C");
|
|
24
|
+
var TOP_LEFT_CORNER = color.gray("\u250C");
|
|
25
|
+
var BOTTOM_LEFT_CORNER = color.gray("\u2514");
|
|
26
|
+
var WARN = color.bgRgb(245, 149, 66).white("WARN");
|
|
27
|
+
var INFO = color.bgBlueBright.white("INFO");
|
|
26
28
|
|
|
27
|
-
// src/
|
|
28
|
-
import
|
|
29
|
-
import
|
|
30
|
-
import
|
|
29
|
+
// src/utils/blocks.ts
|
|
30
|
+
import fs4 from "node:fs";
|
|
31
|
+
import path4 from "node:path";
|
|
32
|
+
import color4 from "chalk";
|
|
31
33
|
|
|
32
|
-
// src/blocks/types/result.ts
|
|
34
|
+
// src/utils/blocks/types/result.ts
|
|
33
35
|
var Result = class {
|
|
34
36
|
_result;
|
|
35
37
|
constructor(result) {
|
|
@@ -667,46 +669,30 @@ var Err = (err) => {
|
|
|
667
669
|
return new Result({ ok: false, err });
|
|
668
670
|
};
|
|
669
671
|
|
|
670
|
-
// src/
|
|
671
|
-
var
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
includeTests: v.boolean(),
|
|
676
|
-
path: v.pipe(v.string(), v.minLength(1)),
|
|
677
|
-
watermark: v.optional(v.boolean(), true)
|
|
678
|
-
});
|
|
679
|
-
var getConfig = (cwd) => {
|
|
680
|
-
if (!fs.existsSync(path.join(cwd, CONFIG_NAME))) {
|
|
681
|
-
return Err("Could not find your configuration file! Please run `init`.");
|
|
682
|
-
}
|
|
683
|
-
const config = v.safeParse(
|
|
684
|
-
schema,
|
|
685
|
-
JSON.parse(fs.readFileSync(path.join(cwd, CONFIG_NAME)).toString())
|
|
686
|
-
);
|
|
687
|
-
if (!config.success) {
|
|
688
|
-
return Err(`There was an error reading your \`${CONFIG_NAME}\` file!`);
|
|
672
|
+
// src/utils/blocks/utils/map-to-array.ts
|
|
673
|
+
var mapToArray = (map, fn) => {
|
|
674
|
+
const items = [];
|
|
675
|
+
for (const [key, value] of map) {
|
|
676
|
+
items.push(fn(key, value));
|
|
689
677
|
}
|
|
690
|
-
return
|
|
678
|
+
return items;
|
|
691
679
|
};
|
|
692
680
|
|
|
681
|
+
// src/utils/git-providers.ts
|
|
682
|
+
import { Octokit } from "octokit";
|
|
683
|
+
import * as v2 from "valibot";
|
|
684
|
+
|
|
693
685
|
// src/utils/build.ts
|
|
694
|
-
import
|
|
695
|
-
import
|
|
686
|
+
import fs3 from "node:fs";
|
|
687
|
+
import path3 from "node:path";
|
|
696
688
|
import color3 from "chalk";
|
|
697
689
|
import { program } from "commander";
|
|
698
|
-
import * as
|
|
699
|
-
|
|
700
|
-
// src/utils/index.ts
|
|
701
|
-
import color from "chalk";
|
|
702
|
-
var OUTPUT_FILE = "jsrepo-manifest.json";
|
|
703
|
-
var WARN = color.bgRgb(245, 149, 66).white("WARN");
|
|
704
|
-
var INFO = color.bgBlueBright.white("INFO");
|
|
690
|
+
import * as v from "valibot";
|
|
705
691
|
|
|
706
692
|
// src/utils/language-support.ts
|
|
707
|
-
import
|
|
693
|
+
import fs2 from "node:fs";
|
|
708
694
|
import { builtinModules } from "node:module";
|
|
709
|
-
import
|
|
695
|
+
import path2 from "node:path";
|
|
710
696
|
import color2 from "chalk";
|
|
711
697
|
import { walk } from "estree-walker";
|
|
712
698
|
import * as sv from "svelte/compiler";
|
|
@@ -714,11 +700,11 @@ import { Project } from "ts-morph";
|
|
|
714
700
|
import validatePackageName from "validate-npm-package-name";
|
|
715
701
|
|
|
716
702
|
// src/utils/package.ts
|
|
717
|
-
import
|
|
718
|
-
import
|
|
703
|
+
import fs from "node:fs";
|
|
704
|
+
import path from "node:path";
|
|
719
705
|
var findNearestPackageJson = (startDir, until) => {
|
|
720
|
-
const packagePath =
|
|
721
|
-
if (
|
|
706
|
+
const packagePath = path.join(startDir, "package.json");
|
|
707
|
+
if (fs.existsSync(packagePath)) return packagePath;
|
|
722
708
|
if (startDir === until) return void 0;
|
|
723
709
|
const segments = startDir.split(/[\/\\]/);
|
|
724
710
|
return findNearestPackageJson(segments.slice(0, segments.length - 1).join("/"), until);
|
|
@@ -768,7 +754,7 @@ ${content}
|
|
|
768
754
|
var svelte = {
|
|
769
755
|
matches: (fileName) => fileName.endsWith(".svelte"),
|
|
770
756
|
resolveDependencies: (filePath, category, isSubDir) => {
|
|
771
|
-
const sourceCode =
|
|
757
|
+
const sourceCode = fs2.readFileSync(filePath).toString();
|
|
772
758
|
const root = sv.parse(sourceCode, { modern: true });
|
|
773
759
|
if (!root.instance) return Ok({ dependencies: [], devDependencies: [], local: [] });
|
|
774
760
|
const localDeps = /* @__PURE__ */ new Set();
|
|
@@ -805,10 +791,10 @@ ${content}
|
|
|
805
791
|
var resolveLocalImport = (mod, category, isSubDir) => {
|
|
806
792
|
if (isSubDir && mod.startsWith("./")) return void 0;
|
|
807
793
|
if (mod.startsWith("./")) {
|
|
808
|
-
return `${category}/${
|
|
794
|
+
return `${category}/${path2.parse(path2.basename(mod)).name}`;
|
|
809
795
|
}
|
|
810
796
|
if (isSubDir && mod.startsWith("../") && !mod.startsWith("../.")) {
|
|
811
|
-
return `${category}/${
|
|
797
|
+
return `${category}/${path2.parse(path2.basename(mod)).name}`;
|
|
812
798
|
}
|
|
813
799
|
const segments = mod.replaceAll("../", "").split("/");
|
|
814
800
|
if (segments.length !== 2) return void 0;
|
|
@@ -818,11 +804,11 @@ var resolveRemoteDeps = (deps, filePath) => {
|
|
|
818
804
|
const filteredDeps = deps.filter(
|
|
819
805
|
(dep) => !builtinModules.includes(dep) && !dep.startsWith("node:")
|
|
820
806
|
);
|
|
821
|
-
const pkgPath = findNearestPackageJson(
|
|
807
|
+
const pkgPath = findNearestPackageJson(path2.dirname(filePath), "");
|
|
822
808
|
const dependencies = /* @__PURE__ */ new Set();
|
|
823
809
|
const devDependencies = /* @__PURE__ */ new Set();
|
|
824
810
|
if (pkgPath) {
|
|
825
|
-
const { devDependencies: packageDevDependencies, dependencies: packageDependencies } = JSON.parse(
|
|
811
|
+
const { devDependencies: packageDevDependencies, dependencies: packageDependencies } = JSON.parse(fs2.readFileSync(pkgPath, "utf-8"));
|
|
826
812
|
for (const dep of filteredDeps) {
|
|
827
813
|
const parsed = parsePackageName(dep);
|
|
828
814
|
if (parsed.isErr()) {
|
|
@@ -864,55 +850,55 @@ var resolveRemoteDeps = (deps, filePath) => {
|
|
|
864
850
|
var languages = [typescript, svelte];
|
|
865
851
|
|
|
866
852
|
// src/utils/build.ts
|
|
867
|
-
var blockSchema =
|
|
868
|
-
name:
|
|
869
|
-
category:
|
|
870
|
-
localDependencies:
|
|
871
|
-
dependencies:
|
|
872
|
-
devDependencies:
|
|
873
|
-
tests:
|
|
853
|
+
var blockSchema = v.object({
|
|
854
|
+
name: v.string(),
|
|
855
|
+
category: v.string(),
|
|
856
|
+
localDependencies: v.array(v.string()),
|
|
857
|
+
dependencies: v.array(v.string()),
|
|
858
|
+
devDependencies: v.array(v.string()),
|
|
859
|
+
tests: v.boolean(),
|
|
874
860
|
/** Where to find the block relative to root */
|
|
875
|
-
directory:
|
|
876
|
-
subdirectory:
|
|
877
|
-
files:
|
|
861
|
+
directory: v.string(),
|
|
862
|
+
subdirectory: v.boolean(),
|
|
863
|
+
files: v.array(v.string())
|
|
878
864
|
});
|
|
879
|
-
var categorySchema =
|
|
880
|
-
name:
|
|
881
|
-
blocks:
|
|
865
|
+
var categorySchema = v.object({
|
|
866
|
+
name: v.string(),
|
|
867
|
+
blocks: v.array(blockSchema)
|
|
882
868
|
});
|
|
883
869
|
var TEST_SUFFIXES = [".test.ts", "_test.ts", ".test.js", "_test.js"];
|
|
884
870
|
var isTestFile = (file) => TEST_SUFFIXES.find((suffix) => file.endsWith(suffix)) !== void 0;
|
|
885
871
|
var buildBlocksDirectory = (blocksPath, cwd) => {
|
|
886
872
|
let paths;
|
|
887
873
|
try {
|
|
888
|
-
paths =
|
|
874
|
+
paths = fs3.readdirSync(blocksPath);
|
|
889
875
|
} catch {
|
|
890
876
|
program.error(color3.red(`Couldn't read the ${color3.bold(blocksPath)} directory.`));
|
|
891
877
|
}
|
|
892
878
|
const categories = [];
|
|
893
879
|
for (const categoryPath of paths) {
|
|
894
|
-
const categoryDir =
|
|
895
|
-
if (
|
|
896
|
-
const categoryName =
|
|
880
|
+
const categoryDir = path3.join(blocksPath, categoryPath);
|
|
881
|
+
if (fs3.statSync(categoryDir).isFile()) continue;
|
|
882
|
+
const categoryName = path3.basename(categoryPath);
|
|
897
883
|
const category = {
|
|
898
884
|
name: categoryName,
|
|
899
885
|
blocks: []
|
|
900
886
|
};
|
|
901
|
-
const files =
|
|
887
|
+
const files = fs3.readdirSync(categoryDir);
|
|
902
888
|
for (const file of files) {
|
|
903
|
-
const blockDir =
|
|
904
|
-
if (
|
|
889
|
+
const blockDir = path3.join(categoryDir, file);
|
|
890
|
+
if (fs3.statSync(blockDir).isFile()) {
|
|
905
891
|
if (isTestFile(file)) continue;
|
|
906
892
|
const lang = languages.find((resolver) => resolver.matches(file));
|
|
907
893
|
if (!lang) {
|
|
908
894
|
console.warn(
|
|
909
895
|
`${WARN} Skipped \`${color3.bold(blockDir)}\` \`${color3.bold(
|
|
910
|
-
|
|
896
|
+
path3.parse(file).ext
|
|
911
897
|
)}\` files are not currently supported!`
|
|
912
898
|
);
|
|
913
899
|
continue;
|
|
914
900
|
}
|
|
915
|
-
const name2 =
|
|
901
|
+
const name2 = path3.parse(path3.basename(file)).name;
|
|
916
902
|
const testsPath = files.find(
|
|
917
903
|
(f) => TEST_SUFFIXES.find((suffix) => f === `${name2}${suffix}`)
|
|
918
904
|
);
|
|
@@ -924,7 +910,7 @@ var buildBlocksDirectory = (blocksPath, cwd) => {
|
|
|
924
910
|
);
|
|
925
911
|
const block = {
|
|
926
912
|
name: name2,
|
|
927
|
-
directory:
|
|
913
|
+
directory: path3.relative(cwd, categoryDir),
|
|
928
914
|
category: categoryName,
|
|
929
915
|
tests: testsPath !== void 0,
|
|
930
916
|
subdirectory: false,
|
|
@@ -939,7 +925,7 @@ var buildBlocksDirectory = (blocksPath, cwd) => {
|
|
|
939
925
|
category.blocks.push(block);
|
|
940
926
|
} else {
|
|
941
927
|
const blockName = file;
|
|
942
|
-
const blockFiles =
|
|
928
|
+
const blockFiles = fs3.readdirSync(blockDir);
|
|
943
929
|
const hasTests = blockFiles.findIndex((f) => isTestFile(f)) !== -1;
|
|
944
930
|
const localDepsSet = /* @__PURE__ */ new Set();
|
|
945
931
|
const depsSet = /* @__PURE__ */ new Set();
|
|
@@ -949,13 +935,13 @@ var buildBlocksDirectory = (blocksPath, cwd) => {
|
|
|
949
935
|
const lang = languages.find((resolver) => resolver.matches(f));
|
|
950
936
|
if (!lang) {
|
|
951
937
|
console.warn(
|
|
952
|
-
`${WARN} Skipped \`${color3.bold(
|
|
953
|
-
|
|
938
|
+
`${WARN} Skipped \`${color3.bold(path3.join(blockDir, f))}\` \`${color3.bold(
|
|
939
|
+
path3.parse(file).ext
|
|
954
940
|
)}\` files are not currently supported!`
|
|
955
941
|
);
|
|
956
942
|
continue;
|
|
957
943
|
}
|
|
958
|
-
const { local, dependencies, devDependencies } = lang.resolveDependencies(
|
|
944
|
+
const { local, dependencies, devDependencies } = lang.resolveDependencies(path3.join(blockDir, f), categoryName, true).match(
|
|
959
945
|
(val) => val,
|
|
960
946
|
(err) => {
|
|
961
947
|
program.error(color3.red(err));
|
|
@@ -973,7 +959,7 @@ var buildBlocksDirectory = (blocksPath, cwd) => {
|
|
|
973
959
|
}
|
|
974
960
|
const block = {
|
|
975
961
|
name: blockName,
|
|
976
|
-
directory:
|
|
962
|
+
directory: path3.relative(cwd, blockDir),
|
|
977
963
|
category: categoryName,
|
|
978
964
|
tests: hasTests,
|
|
979
965
|
subdirectory: true,
|
|
@@ -990,36 +976,10 @@ var buildBlocksDirectory = (blocksPath, cwd) => {
|
|
|
990
976
|
return categories;
|
|
991
977
|
};
|
|
992
978
|
|
|
993
|
-
// src/utils/
|
|
994
|
-
|
|
995
|
-
import path5 from "node:path";
|
|
996
|
-
var getInstalledBlocks = (blocks, config, cwd) => {
|
|
997
|
-
const installedBlocks = [];
|
|
998
|
-
for (const [_, block] of blocks) {
|
|
999
|
-
const baseDir = path5.join(cwd, config.path, block.category);
|
|
1000
|
-
let blockPath = path5.join(baseDir, block.files[0]);
|
|
1001
|
-
if (block.subdirectory) {
|
|
1002
|
-
blockPath = path5.join(baseDir, block.name);
|
|
1003
|
-
}
|
|
1004
|
-
if (fs5.existsSync(blockPath))
|
|
1005
|
-
installedBlocks.push({
|
|
1006
|
-
specifier: `${block.category}/${block.name}`,
|
|
1007
|
-
path: blockPath
|
|
1008
|
-
});
|
|
1009
|
-
}
|
|
1010
|
-
return installedBlocks;
|
|
1011
|
-
};
|
|
1012
|
-
|
|
1013
|
-
// src/utils/get-watermark.ts
|
|
1014
|
-
var getWatermark = (version2, repoUrl) => {
|
|
1015
|
-
return ` jsrepo ${version2}
|
|
1016
|
-
Installed from ${repoUrl}
|
|
1017
|
-
${(/* @__PURE__ */ new Date()).toLocaleDateString().replaceAll("/", "-")}`;
|
|
1018
|
-
};
|
|
979
|
+
// src/utils/context.ts
|
|
980
|
+
var OUTPUT_FILE = "jsrepo-manifest.json";
|
|
1019
981
|
|
|
1020
982
|
// src/utils/git-providers.ts
|
|
1021
|
-
import { Octokit } from "octokit";
|
|
1022
|
-
import * as v3 from "valibot";
|
|
1023
983
|
var octokit = new Octokit({});
|
|
1024
984
|
var github = {
|
|
1025
985
|
name: () => "github",
|
|
@@ -1069,38 +1029,194 @@ var github = {
|
|
|
1069
1029
|
},
|
|
1070
1030
|
matches: (repoPath) => repoPath.toLowerCase().startsWith("https://github.com") || repoPath.toLowerCase().startsWith("github")
|
|
1071
1031
|
};
|
|
1032
|
+
var providers = [github];
|
|
1072
1033
|
var getProviderInfo = async (repo) => {
|
|
1073
|
-
|
|
1074
|
-
|
|
1034
|
+
const provider = providers.find((provider2) => provider2.matches(repo));
|
|
1035
|
+
if (provider) {
|
|
1036
|
+
return Ok(await provider.info(repo));
|
|
1075
1037
|
}
|
|
1076
1038
|
return Err("Only GitHub repositories are supported at this time!");
|
|
1077
1039
|
};
|
|
1078
1040
|
var getManifest = async (url) => {
|
|
1041
|
+
const errorMessage = (err) => {
|
|
1042
|
+
return Err(
|
|
1043
|
+
`There was an error fetching the \`${OUTPUT_FILE}\` from the repository \`${url.href}\` make sure the target repository has a \`${OUTPUT_FILE}\` in its root.
|
|
1044
|
+
Error: ${err}`
|
|
1045
|
+
);
|
|
1046
|
+
};
|
|
1079
1047
|
try {
|
|
1080
1048
|
const response = await fetch(url);
|
|
1081
1049
|
if (!response.ok) {
|
|
1082
|
-
return
|
|
1083
|
-
`There was an error fetching the \`${OUTPUT_FILE}\` from the repository \`${url.href}\` make sure the target repository has a \`${OUTPUT_FILE}\` in its root?`
|
|
1084
|
-
);
|
|
1050
|
+
return errorMessage(`${response.status} ${response.text}`);
|
|
1085
1051
|
}
|
|
1086
|
-
const categories =
|
|
1052
|
+
const categories = v2.parse(v2.array(categorySchema), await response.json());
|
|
1087
1053
|
return Ok(categories);
|
|
1054
|
+
} catch (err) {
|
|
1055
|
+
return errorMessage(`${err}`);
|
|
1056
|
+
}
|
|
1057
|
+
};
|
|
1058
|
+
var fetchBlocks = async (...repos) => {
|
|
1059
|
+
const blocksMap = /* @__PURE__ */ new Map();
|
|
1060
|
+
for (const repo of repos) {
|
|
1061
|
+
const getProviderResult = await getProviderInfo(repo);
|
|
1062
|
+
if (getProviderResult.isErr()) return Err({ message: getProviderResult.unwrapErr(), repo });
|
|
1063
|
+
const providerInfo = getProviderResult.unwrap();
|
|
1064
|
+
const manifestUrl = await providerInfo.provider.resolveRaw(providerInfo, OUTPUT_FILE);
|
|
1065
|
+
const getManifestResult = await getManifest(manifestUrl);
|
|
1066
|
+
if (getManifestResult.isErr()) return Err({ message: getManifestResult.unwrapErr(), repo });
|
|
1067
|
+
const categories = getManifestResult.unwrap();
|
|
1068
|
+
for (const category of categories) {
|
|
1069
|
+
for (const block of category.blocks) {
|
|
1070
|
+
blocksMap.set(
|
|
1071
|
+
`${providerInfo.name}/${providerInfo.owner}/${providerInfo.repoName}/${category.name}/${block.name}`,
|
|
1072
|
+
{
|
|
1073
|
+
...block,
|
|
1074
|
+
sourceRepo: providerInfo
|
|
1075
|
+
}
|
|
1076
|
+
);
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
return Ok(blocksMap);
|
|
1081
|
+
};
|
|
1082
|
+
|
|
1083
|
+
// src/utils/blocks.ts
|
|
1084
|
+
var resolveTree = async (blockSpecifiers, blocksMap, repoPaths) => {
|
|
1085
|
+
const blocks = /* @__PURE__ */ new Map();
|
|
1086
|
+
for (const blockSpecifier of blockSpecifiers) {
|
|
1087
|
+
let block = void 0;
|
|
1088
|
+
if (!blockSpecifier.startsWith("github")) {
|
|
1089
|
+
if (repoPaths.length === 0) {
|
|
1090
|
+
return Err(
|
|
1091
|
+
color4.red(
|
|
1092
|
+
`If your config doesn't repos then you must provide the repo in the block specifier ex: \`${color4.bold(
|
|
1093
|
+
`github/<owner>/<name>/${blockSpecifier}`
|
|
1094
|
+
)}\`!`
|
|
1095
|
+
)
|
|
1096
|
+
);
|
|
1097
|
+
}
|
|
1098
|
+
for (const repo of repoPaths) {
|
|
1099
|
+
const providerInfo = (await getProviderInfo(repo)).unwrap();
|
|
1100
|
+
const tempBlock = blocksMap.get(
|
|
1101
|
+
`${providerInfo.name}/${providerInfo.owner}/${providerInfo.repoName}/${blockSpecifier}`
|
|
1102
|
+
);
|
|
1103
|
+
if (tempBlock === void 0) continue;
|
|
1104
|
+
block = tempBlock;
|
|
1105
|
+
break;
|
|
1106
|
+
}
|
|
1107
|
+
} else {
|
|
1108
|
+
block = blocksMap.get(blockSpecifier);
|
|
1109
|
+
}
|
|
1110
|
+
if (!block) {
|
|
1111
|
+
return Err(`Invalid block! ${color4.bold(blockSpecifier)} does not exist!`);
|
|
1112
|
+
}
|
|
1113
|
+
const fullSpecifier = `${block.sourceRepo.url}/${block.category}/${block.name}`;
|
|
1114
|
+
blocks.set(fullSpecifier, { name: fullSpecifier, subDependency: false, block });
|
|
1115
|
+
if (block.localDependencies && block.localDependencies.length > 0) {
|
|
1116
|
+
const subDeps = await resolveTree(
|
|
1117
|
+
block.localDependencies.filter((dep) => !blocks.has(dep)),
|
|
1118
|
+
blocksMap,
|
|
1119
|
+
repoPaths
|
|
1120
|
+
);
|
|
1121
|
+
if (subDeps.isErr()) return Err(subDeps.unwrapErr());
|
|
1122
|
+
for (const dep of subDeps.unwrap()) {
|
|
1123
|
+
blocks.set(dep.name, dep);
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
return Ok(mapToArray(blocks, (_, val) => val));
|
|
1128
|
+
};
|
|
1129
|
+
var getInstalled = (blocks, config, cwd) => {
|
|
1130
|
+
const installedBlocks = [];
|
|
1131
|
+
for (const [_, block] of blocks) {
|
|
1132
|
+
const baseDir = path4.join(cwd, config.path, block.category);
|
|
1133
|
+
let blockPath = path4.join(baseDir, block.files[0]);
|
|
1134
|
+
if (block.subdirectory) {
|
|
1135
|
+
blockPath = path4.join(baseDir, block.name);
|
|
1136
|
+
}
|
|
1137
|
+
if (fs4.existsSync(blockPath))
|
|
1138
|
+
installedBlocks.push({
|
|
1139
|
+
specifier: `${block.category}/${block.name}`,
|
|
1140
|
+
path: blockPath,
|
|
1141
|
+
block
|
|
1142
|
+
});
|
|
1143
|
+
}
|
|
1144
|
+
return installedBlocks;
|
|
1145
|
+
};
|
|
1146
|
+
|
|
1147
|
+
// src/utils/config.ts
|
|
1148
|
+
import fs5 from "node:fs";
|
|
1149
|
+
import path5 from "node:path";
|
|
1150
|
+
import * as v3 from "valibot";
|
|
1151
|
+
var CONFIG_NAME = "jsrepo.json";
|
|
1152
|
+
var schema = v3.object({
|
|
1153
|
+
$schema: v3.string(),
|
|
1154
|
+
repos: v3.optional(v3.array(v3.string()), []),
|
|
1155
|
+
includeTests: v3.boolean(),
|
|
1156
|
+
path: v3.pipe(v3.string(), v3.minLength(1)),
|
|
1157
|
+
watermark: v3.optional(v3.boolean(), true)
|
|
1158
|
+
});
|
|
1159
|
+
var getConfig = (cwd) => {
|
|
1160
|
+
if (!fs5.existsSync(path5.join(cwd, CONFIG_NAME))) {
|
|
1161
|
+
return Err("Could not find your configuration file! Please run `init`.");
|
|
1162
|
+
}
|
|
1163
|
+
const config = v3.safeParse(
|
|
1164
|
+
schema,
|
|
1165
|
+
JSON.parse(fs5.readFileSync(path5.join(cwd, CONFIG_NAME)).toString())
|
|
1166
|
+
);
|
|
1167
|
+
if (!config.success) {
|
|
1168
|
+
return Err(`There was an error reading your \`${CONFIG_NAME}\` file!`);
|
|
1169
|
+
}
|
|
1170
|
+
return Ok(config.output);
|
|
1171
|
+
};
|
|
1172
|
+
|
|
1173
|
+
// src/utils/dependencies.ts
|
|
1174
|
+
import color5 from "chalk";
|
|
1175
|
+
import { execa } from "execa";
|
|
1176
|
+
import { resolveCommand } from "package-manager-detector";
|
|
1177
|
+
var installDependencies = async ({
|
|
1178
|
+
pm,
|
|
1179
|
+
deps,
|
|
1180
|
+
dev,
|
|
1181
|
+
cwd
|
|
1182
|
+
}) => {
|
|
1183
|
+
let add2;
|
|
1184
|
+
if (dev) {
|
|
1185
|
+
add2 = resolveCommand(pm, "install", [...deps, "-D"]);
|
|
1186
|
+
} else {
|
|
1187
|
+
add2 = resolveCommand(pm, "install", [...deps]);
|
|
1188
|
+
}
|
|
1189
|
+
if (add2 == null) return Err(color5.red(`Could not resolve add command for '${pm}'.`));
|
|
1190
|
+
try {
|
|
1191
|
+
await execa(add2.command, [...add2.args], { cwd });
|
|
1192
|
+
return Ok(deps);
|
|
1088
1193
|
} catch {
|
|
1089
1194
|
return Err(
|
|
1090
|
-
|
|
1195
|
+
color5.red(
|
|
1196
|
+
`Failed to install ${color5.bold(deps.join(", "))}! Failed while running '${color5.bold(
|
|
1197
|
+
`${add2.command} ${add2.args.join(" ")}`
|
|
1198
|
+
)}'`
|
|
1199
|
+
)
|
|
1091
1200
|
);
|
|
1092
1201
|
}
|
|
1093
1202
|
};
|
|
1094
1203
|
|
|
1204
|
+
// src/utils/get-watermark.ts
|
|
1205
|
+
var getWatermark = (version2, repoUrl) => {
|
|
1206
|
+
return ` jsrepo ${version2}
|
|
1207
|
+
Installed from ${repoUrl}
|
|
1208
|
+
${(/* @__PURE__ */ new Date()).toLocaleDateString().replaceAll("/", "-")}`;
|
|
1209
|
+
};
|
|
1210
|
+
|
|
1095
1211
|
// src/utils/prompts.ts
|
|
1096
1212
|
import { intro, spinner } from "@clack/prompts";
|
|
1097
|
-
import
|
|
1213
|
+
import color6 from "chalk";
|
|
1098
1214
|
|
|
1099
|
-
// src/blocks/utils/strip-ansi.ts
|
|
1215
|
+
// src/utils/blocks/utils/strip-ansi.ts
|
|
1100
1216
|
import ansiRegex from "ansi-regex";
|
|
1101
1217
|
var stripAsni = (str) => str.replace(ansiRegex(), "");
|
|
1102
1218
|
|
|
1103
|
-
// src/blocks/utils/pad.ts
|
|
1219
|
+
// src/utils/blocks/utils/pad.ts
|
|
1104
1220
|
var leftPadMin = (str, length, padWith = " ") => {
|
|
1105
1221
|
if (stripAsni(str).length > length)
|
|
1106
1222
|
throw new Error("String length is greater than the length provided.");
|
|
@@ -1116,21 +1232,25 @@ var rightPadMin = (str, length, padWith = " ") => {
|
|
|
1116
1232
|
};
|
|
1117
1233
|
|
|
1118
1234
|
// src/utils/prompts.ts
|
|
1119
|
-
var
|
|
1120
|
-
var HORIZONTAL_BORDER = color4.gray("\u2500");
|
|
1121
|
-
var TOP_RIGHT_CORNER = color4.gray("\u2510");
|
|
1122
|
-
var BOTTOM_RIGHT_CORNER = color4.gray("\u2518");
|
|
1123
|
-
var JUNCTION_RIGHT = color4.gray("\u251C");
|
|
1124
|
-
var runTasks = async (tasks, { verbose = false }) => {
|
|
1235
|
+
var runTasks = async (tasks, { verbose = void 0 }) => {
|
|
1125
1236
|
const loading = spinner();
|
|
1126
1237
|
for (const task of tasks) {
|
|
1127
|
-
if (
|
|
1238
|
+
if (verbose) {
|
|
1239
|
+
verbose(task.loadingMessage);
|
|
1240
|
+
} else {
|
|
1241
|
+
loading.start(task.loadingMessage);
|
|
1242
|
+
}
|
|
1128
1243
|
try {
|
|
1129
1244
|
await task.run();
|
|
1130
1245
|
} catch (err) {
|
|
1246
|
+
loading.stop(`Error while ${task.loadingMessage}`);
|
|
1131
1247
|
console.error(err);
|
|
1132
1248
|
}
|
|
1133
|
-
if (
|
|
1249
|
+
if (verbose) {
|
|
1250
|
+
verbose(task.completedMessage);
|
|
1251
|
+
} else {
|
|
1252
|
+
loading.stop(task.completedMessage);
|
|
1253
|
+
}
|
|
1134
1254
|
}
|
|
1135
1255
|
};
|
|
1136
1256
|
var nextSteps = (steps) => {
|
|
@@ -1140,40 +1260,44 @@ var nextSteps = (steps) => {
|
|
|
1140
1260
|
if (reset.length > max) max = reset.length;
|
|
1141
1261
|
});
|
|
1142
1262
|
const NEXT_STEPS = "Next Steps";
|
|
1143
|
-
let result = `${
|
|
1263
|
+
let result = `${VERTICAL_LINE}
|
|
1144
1264
|
`;
|
|
1145
|
-
result += `${JUNCTION_RIGHT} ${NEXT_STEPS} ${
|
|
1265
|
+
result += `${JUNCTION_RIGHT} ${NEXT_STEPS} ${HORIZONTAL_LINE.repeat(
|
|
1146
1266
|
max - NEXT_STEPS.length - 1
|
|
1147
1267
|
)}${TOP_RIGHT_CORNER}
|
|
1148
1268
|
`;
|
|
1149
|
-
result += `${
|
|
1269
|
+
result += `${VERTICAL_LINE} ${" ".repeat(max)} ${VERTICAL_LINE}
|
|
1150
1270
|
`;
|
|
1151
1271
|
steps.map((step) => {
|
|
1152
|
-
result += `${
|
|
1272
|
+
result += `${VERTICAL_LINE} ${rightPadMin(step, max - 1)} ${VERTICAL_LINE}
|
|
1153
1273
|
`;
|
|
1154
1274
|
});
|
|
1155
|
-
result += `${
|
|
1275
|
+
result += `${VERTICAL_LINE} ${" ".repeat(max)} ${VERTICAL_LINE}
|
|
1156
1276
|
`;
|
|
1157
|
-
result += `${JUNCTION_RIGHT}${
|
|
1277
|
+
result += `${JUNCTION_RIGHT}${HORIZONTAL_LINE.repeat(max + 2)}${BOTTOM_RIGHT_CORNER}
|
|
1158
1278
|
`;
|
|
1159
1279
|
return result;
|
|
1160
1280
|
};
|
|
1161
|
-
var _intro = (version2) => intro(`${
|
|
1281
|
+
var _intro = (version2) => intro(`${color6.bgHex("#f7df1e").black(" jsrepo ")}${color6.gray(` v${version2} `)}`);
|
|
1162
1282
|
|
|
1163
1283
|
// src/commands/add.ts
|
|
1164
1284
|
var schema2 = v4.object({
|
|
1165
|
-
yes: v4.boolean(),
|
|
1166
|
-
verbose: v4.boolean(),
|
|
1167
1285
|
repo: v4.optional(v4.string()),
|
|
1168
1286
|
allow: v4.boolean(),
|
|
1287
|
+
yes: v4.boolean(),
|
|
1288
|
+
verbose: v4.boolean(),
|
|
1169
1289
|
cwd: v4.string()
|
|
1170
1290
|
});
|
|
1171
|
-
var add = new Command("add").argument(
|
|
1291
|
+
var add = new Command("add").argument(
|
|
1292
|
+
"[blocks...]",
|
|
1293
|
+
"Names of the blocks you want to add to your project. ex: (utils/math, github/ieedan/std/utils/math)"
|
|
1294
|
+
).option("--repo <repo>", "Repository to download the blocks from.").option("-A, --allow", "Allow jsrepo to download code from the provided repo.", false).option("-y, --yes", "Skip confirmation prompt.", false).option("--verbose", "Include debug logs.", false).option("--cwd <path>", "The current working directory.", process.cwd()).action(async (blockNames, opts) => {
|
|
1172
1295
|
const options = v4.parse(schema2, opts);
|
|
1296
|
+
_intro(context.package.version);
|
|
1173
1297
|
await _add(blockNames, options);
|
|
1298
|
+
outro(color7.green("All done!"));
|
|
1174
1299
|
});
|
|
1175
1300
|
var _add = async (blockNames, options) => {
|
|
1176
|
-
_intro(context.package.version);
|
|
1177
1301
|
const verbose = (msg) => {
|
|
1178
1302
|
if (options.verbose) {
|
|
1179
1303
|
console.info(`${INFO} ${msg}`);
|
|
@@ -1183,9 +1307,8 @@ var _add = async (blockNames, options) => {
|
|
|
1183
1307
|
const loading = spinner2();
|
|
1184
1308
|
const config = getConfig(options.cwd).match(
|
|
1185
1309
|
(val) => val,
|
|
1186
|
-
(err) => program2.error(
|
|
1310
|
+
(err) => program2.error(color7.red(err))
|
|
1187
1311
|
);
|
|
1188
|
-
const blocksMap = /* @__PURE__ */ new Map();
|
|
1189
1312
|
let repoPaths = config.repos;
|
|
1190
1313
|
if (options.repo) repoPaths = [options.repo];
|
|
1191
1314
|
for (const blockSpecifier of blockNames) {
|
|
@@ -1200,7 +1323,7 @@ var _add = async (blockNames, options) => {
|
|
|
1200
1323
|
if (!repoPaths.find((repoPath) => repoPath === repo)) {
|
|
1201
1324
|
if (!options.allow) {
|
|
1202
1325
|
const result = await confirm({
|
|
1203
|
-
message: `Allow ${
|
|
1326
|
+
message: `Allow ${color7.cyan("jsrepo")} to download and run code from ${color7.cyan(repo)}?`,
|
|
1204
1327
|
initialValue: true
|
|
1205
1328
|
});
|
|
1206
1329
|
if (isCancel(result) || !result) {
|
|
@@ -1213,7 +1336,7 @@ var _add = async (blockNames, options) => {
|
|
|
1213
1336
|
}
|
|
1214
1337
|
if (!options.allow && options.repo) {
|
|
1215
1338
|
const result = await confirm({
|
|
1216
|
-
message: `Allow ${
|
|
1339
|
+
message: `Allow ${color7.cyan("jsrepo")} to download and run code from ${color7.cyan(options.repo)}?`,
|
|
1217
1340
|
initialValue: true
|
|
1218
1341
|
});
|
|
1219
1342
|
if (isCancel(result) || !result) {
|
|
@@ -1221,40 +1344,25 @@ var _add = async (blockNames, options) => {
|
|
|
1221
1344
|
process.exit(0);
|
|
1222
1345
|
}
|
|
1223
1346
|
}
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
(err) => {
|
|
1230
|
-
loading.stop(`Failed fetching blocks from ${color5.cyan(repo)}`);
|
|
1231
|
-
program2.error(color5.red(err));
|
|
1232
|
-
}
|
|
1347
|
+
if (repoPaths.length === 0) {
|
|
1348
|
+
program2.error(
|
|
1349
|
+
color7.red(
|
|
1350
|
+
`There were no repos present in your config and you didn't provide the \`${color7.bold("--repo")}\` flag with a repo.`
|
|
1351
|
+
)
|
|
1233
1352
|
);
|
|
1234
|
-
const manifestUrl = await providerInfo.provider.resolveRaw(providerInfo, OUTPUT_FILE);
|
|
1235
|
-
verbose(`Got info for provider ${color5.cyan(providerInfo.name)}`);
|
|
1236
|
-
const categories = (await getManifest(manifestUrl)).match(
|
|
1237
|
-
(val) => val,
|
|
1238
|
-
(err) => {
|
|
1239
|
-
loading.stop(`Failed fetching blocks from ${color5.cyan(repo)}`);
|
|
1240
|
-
program2.error(color5.red(err));
|
|
1241
|
-
}
|
|
1242
|
-
);
|
|
1243
|
-
for (const category of categories) {
|
|
1244
|
-
for (const block of category.blocks) {
|
|
1245
|
-
blocksMap.set(
|
|
1246
|
-
`${providerInfo.name}/${providerInfo.owner}/${providerInfo.repoName}/${category.name}/${block.name}`,
|
|
1247
|
-
{
|
|
1248
|
-
...block,
|
|
1249
|
-
sourceRepo: providerInfo
|
|
1250
|
-
}
|
|
1251
|
-
);
|
|
1252
|
-
}
|
|
1253
|
-
}
|
|
1254
1353
|
}
|
|
1255
|
-
verbose(`
|
|
1256
|
-
if (!options.verbose) loading.
|
|
1257
|
-
const
|
|
1354
|
+
verbose(`Fetching blocks from ${color7.cyan(repoPaths.join(", "))}`);
|
|
1355
|
+
if (!options.verbose) loading.start(`Fetching blocks from ${color7.cyan(repoPaths.join(", "))}`);
|
|
1356
|
+
const blocksMap = (await fetchBlocks(...repoPaths)).match(
|
|
1357
|
+
(val) => val,
|
|
1358
|
+
({ repo, message }) => {
|
|
1359
|
+
loading.stop(`Failed fetching blocks from ${color7.cyan(repo)}`);
|
|
1360
|
+
program2.error(color7.red(message));
|
|
1361
|
+
}
|
|
1362
|
+
);
|
|
1363
|
+
if (!options.verbose) loading.stop(`Retrieved blocks from ${color7.cyan(repoPaths.join(", "))}`);
|
|
1364
|
+
verbose(`Retrieved blocks from ${color7.cyan(repoPaths.join(", "))}`);
|
|
1365
|
+
const installedBlocks = getInstalled(blocksMap, config, options.cwd).map(
|
|
1258
1366
|
(val) => val.specifier
|
|
1259
1367
|
);
|
|
1260
1368
|
let installingBlockNames = blockNames;
|
|
@@ -1266,14 +1374,14 @@ var _add = async (blockNames, options) => {
|
|
|
1266
1374
|
const blockExists = installedBlocks.findIndex((block) => block === shortName) !== -1;
|
|
1267
1375
|
let label;
|
|
1268
1376
|
if (repoPaths.length > 1) {
|
|
1269
|
-
label = `${
|
|
1377
|
+
label = `${color7.cyan(
|
|
1270
1378
|
`${value.sourceRepo.name}/${value.sourceRepo.owner}/${value.sourceRepo.repoName}/${value.category}`
|
|
1271
1379
|
)}/${value.name}`;
|
|
1272
1380
|
} else {
|
|
1273
|
-
label = `${
|
|
1381
|
+
label = `${color7.cyan(value.category)}/${value.name}`;
|
|
1274
1382
|
}
|
|
1275
1383
|
return {
|
|
1276
|
-
label: blockExists ?
|
|
1384
|
+
label: blockExists ? color7.gray(label) : label,
|
|
1277
1385
|
value: key,
|
|
1278
1386
|
// show hint for `Installed` if block is already installed
|
|
1279
1387
|
hint: blockExists ? "Installed" : void 0
|
|
@@ -1287,9 +1395,12 @@ var _add = async (blockNames, options) => {
|
|
|
1287
1395
|
}
|
|
1288
1396
|
installingBlockNames = promptResult;
|
|
1289
1397
|
}
|
|
1290
|
-
verbose(`Installing blocks ${
|
|
1398
|
+
verbose(`Installing blocks ${color7.cyan(installingBlockNames.join(", "))}`);
|
|
1291
1399
|
if (options.verbose) console.log("Blocks map: ", blocksMap);
|
|
1292
|
-
const installingBlocks = await
|
|
1400
|
+
const installingBlocks = (await resolveTree(installingBlockNames, blocksMap, repoPaths)).match(
|
|
1401
|
+
(val) => val,
|
|
1402
|
+
program2.error
|
|
1403
|
+
);
|
|
1293
1404
|
const pm = (await detect({ cwd: process.cwd() }))?.agent ?? "npm";
|
|
1294
1405
|
const tasks = [];
|
|
1295
1406
|
const devDeps = /* @__PURE__ */ new Set();
|
|
@@ -1298,13 +1409,12 @@ var _add = async (blockNames, options) => {
|
|
|
1298
1409
|
const fullSpecifier = `${block.sourceRepo.url}/${block.category}/${block.name}`;
|
|
1299
1410
|
const watermark = getWatermark(context.package.version, block.sourceRepo.url);
|
|
1300
1411
|
const providerInfo = block.sourceRepo;
|
|
1301
|
-
verbose(`
|
|
1412
|
+
verbose(`Setting up ${fullSpecifier}`);
|
|
1302
1413
|
const directory = path6.join(options.cwd, config.path, block.category);
|
|
1303
|
-
verbose(`Creating directory ${color5.bold(directory)}`);
|
|
1304
1414
|
const blockExists = !block.subdirectory && fs6.existsSync(path6.join(directory, block.files[0])) || block.subdirectory && fs6.existsSync(path6.join(directory, block.name));
|
|
1305
1415
|
if (blockExists && !options.yes) {
|
|
1306
1416
|
const result = await confirm({
|
|
1307
|
-
message: `${
|
|
1417
|
+
message: `${color7.bold(block.name)} already exists in your project would you like to overwrite it?`,
|
|
1308
1418
|
initialValue: false
|
|
1309
1419
|
});
|
|
1310
1420
|
if (isCancel(result) || !result) {
|
|
@@ -1316,15 +1426,16 @@ var _add = async (blockNames, options) => {
|
|
|
1316
1426
|
loadingMessage: `Adding ${fullSpecifier}`,
|
|
1317
1427
|
completedMessage: `Added ${fullSpecifier}`,
|
|
1318
1428
|
run: async () => {
|
|
1429
|
+
verbose(`Creating directory ${color7.bold(directory)}`);
|
|
1319
1430
|
fs6.mkdirSync(directory, { recursive: true });
|
|
1320
1431
|
const files = [];
|
|
1321
1432
|
const getSourceFile = async (filePath) => {
|
|
1322
1433
|
const rawUrl = await providerInfo.provider.resolveRaw(providerInfo, filePath);
|
|
1323
1434
|
const response = await fetch(rawUrl);
|
|
1324
1435
|
if (!response.ok) {
|
|
1325
|
-
loading.stop(
|
|
1436
|
+
loading.stop(color7.red(`Error fetching ${color7.bold(rawUrl.href)}`));
|
|
1326
1437
|
program2.error(
|
|
1327
|
-
|
|
1438
|
+
color7.red(`There was an error trying to get ${fullSpecifier}`)
|
|
1328
1439
|
);
|
|
1329
1440
|
}
|
|
1330
1441
|
return await response.text();
|
|
@@ -1375,31 +1486,7 @@ ${content}`;
|
|
|
1375
1486
|
}
|
|
1376
1487
|
});
|
|
1377
1488
|
}
|
|
1378
|
-
await runTasks(tasks, { verbose: options.verbose });
|
|
1379
|
-
const installDependencies = async (deps2, dev) => {
|
|
1380
|
-
if (!options.verbose) loading.start(`Installing dependencies with ${color5.cyan(pm)}`);
|
|
1381
|
-
let add2;
|
|
1382
|
-
if (dev) {
|
|
1383
|
-
add2 = resolveCommand(pm, "install", [...deps2, "-D"]);
|
|
1384
|
-
} else {
|
|
1385
|
-
add2 = resolveCommand(pm, "install", [...deps2]);
|
|
1386
|
-
}
|
|
1387
|
-
if (add2 == null) {
|
|
1388
|
-
program2.error(color5.red(`Could not resolve add command for '${pm}'.`));
|
|
1389
|
-
}
|
|
1390
|
-
try {
|
|
1391
|
-
await execa(add2.command, [...add2.args], { cwd: options.cwd });
|
|
1392
|
-
} catch {
|
|
1393
|
-
program2.error(
|
|
1394
|
-
color5.red(
|
|
1395
|
-
`Failed to install ${color5.bold("vitest")}! Failed while running '${color5.bold(
|
|
1396
|
-
`${add2.command} ${add2.args.join(" ")}`
|
|
1397
|
-
)}'`
|
|
1398
|
-
)
|
|
1399
|
-
);
|
|
1400
|
-
}
|
|
1401
|
-
if (!options.verbose) loading.stop(`Installed ${color5.cyan(deps2.join(", "))}`);
|
|
1402
|
-
};
|
|
1489
|
+
await runTasks(tasks, { verbose: options.verbose ? verbose : void 0 });
|
|
1403
1490
|
const hasDependencies = deps.size > 0 || devDeps.size > 0;
|
|
1404
1491
|
if (hasDependencies) {
|
|
1405
1492
|
let install = options.yes;
|
|
@@ -1416,24 +1503,56 @@ ${content}`;
|
|
|
1416
1503
|
}
|
|
1417
1504
|
if (install) {
|
|
1418
1505
|
if (deps.size > 0) {
|
|
1419
|
-
|
|
1506
|
+
if (!options.verbose)
|
|
1507
|
+
loading.start(`Installing dependencies with ${color7.cyan(pm)}`);
|
|
1508
|
+
(await installDependencies({
|
|
1509
|
+
pm,
|
|
1510
|
+
deps: Array.from(deps),
|
|
1511
|
+
dev: false,
|
|
1512
|
+
cwd: options.cwd
|
|
1513
|
+
})).match(
|
|
1514
|
+
(installed) => {
|
|
1515
|
+
if (!options.verbose)
|
|
1516
|
+
loading.stop(`Installed ${color7.cyan(installed.join(", "))}`);
|
|
1517
|
+
},
|
|
1518
|
+
(err) => {
|
|
1519
|
+
if (!options.verbose) loading.stop("Failed to install dependencies");
|
|
1520
|
+
program2.error(err);
|
|
1521
|
+
}
|
|
1522
|
+
);
|
|
1420
1523
|
}
|
|
1421
1524
|
if (devDeps.size > 0) {
|
|
1422
|
-
|
|
1525
|
+
if (!options.verbose)
|
|
1526
|
+
loading.start(`Installing dependencies with ${color7.cyan(pm)}`);
|
|
1527
|
+
(await installDependencies({
|
|
1528
|
+
pm,
|
|
1529
|
+
deps: Array.from(devDeps),
|
|
1530
|
+
dev: true,
|
|
1531
|
+
cwd: options.cwd
|
|
1532
|
+
})).match(
|
|
1533
|
+
(installed) => {
|
|
1534
|
+
if (!options.verbose)
|
|
1535
|
+
loading.stop(`Installed ${color7.cyan(installed.join(", "))}`);
|
|
1536
|
+
},
|
|
1537
|
+
(err) => {
|
|
1538
|
+
if (!options.verbose) loading.stop("Failed to install dev dependencies");
|
|
1539
|
+
program2.error(err);
|
|
1540
|
+
}
|
|
1541
|
+
);
|
|
1423
1542
|
}
|
|
1424
1543
|
}
|
|
1425
1544
|
let steps = [];
|
|
1426
1545
|
if (!install) {
|
|
1427
1546
|
if (deps.size > 0) {
|
|
1428
|
-
const cmd =
|
|
1547
|
+
const cmd = resolveCommand2(pm, "install", [...deps]);
|
|
1429
1548
|
steps.push(
|
|
1430
|
-
`Install dependencies \`${
|
|
1549
|
+
`Install dependencies \`${color7.cyan(`${cmd?.command} ${cmd?.args.join(" ")}`)}\``
|
|
1431
1550
|
);
|
|
1432
1551
|
}
|
|
1433
1552
|
if (devDeps.size > 0) {
|
|
1434
|
-
const cmd =
|
|
1553
|
+
const cmd = resolveCommand2(pm, "install", [...devDeps, "-D"]);
|
|
1435
1554
|
steps.push(
|
|
1436
|
-
`Install dev dependencies \`${
|
|
1555
|
+
`Install dev dependencies \`${color7.cyan(`${cmd?.command} ${cmd?.args.join(" ")}`)}\``
|
|
1437
1556
|
);
|
|
1438
1557
|
}
|
|
1439
1558
|
}
|
|
@@ -1441,88 +1560,41 @@ ${content}`;
|
|
|
1441
1560
|
if (!install) {
|
|
1442
1561
|
steps.push("");
|
|
1443
1562
|
}
|
|
1444
|
-
steps.push(`Import the blocks from \`${
|
|
1563
|
+
steps.push(`Import the blocks from \`${color7.cyan(config.path)}\``);
|
|
1445
1564
|
const next = nextSteps(steps);
|
|
1446
1565
|
process.stdout.write(next);
|
|
1447
1566
|
}
|
|
1448
|
-
outro(color5.green("All done!"));
|
|
1449
|
-
};
|
|
1450
|
-
var getBlocks = async (blockSpecifiers, blocksMap, repoPaths, options) => {
|
|
1451
|
-
const blocks = /* @__PURE__ */ new Map();
|
|
1452
|
-
for (const blockSpecifier of blockSpecifiers) {
|
|
1453
|
-
let block = void 0;
|
|
1454
|
-
if (!blockSpecifier.startsWith("github")) {
|
|
1455
|
-
if (repoPaths.length === 0) {
|
|
1456
|
-
program2.error(
|
|
1457
|
-
color5.red(
|
|
1458
|
-
`If your config doesn't repos then you must provide the repo in the block specifier ex: \`${color5.bold(
|
|
1459
|
-
`github/<owner>/<name>/${blockSpecifier}`
|
|
1460
|
-
)}\`!`
|
|
1461
|
-
)
|
|
1462
|
-
);
|
|
1463
|
-
}
|
|
1464
|
-
for (const repo of repoPaths) {
|
|
1465
|
-
const providerInfo = (await getProviderInfo(repo)).unwrap();
|
|
1466
|
-
const tempBlock = blocksMap.get(
|
|
1467
|
-
`${providerInfo.name}/${providerInfo.owner}/${providerInfo.repoName}/${blockSpecifier}`
|
|
1468
|
-
);
|
|
1469
|
-
if (tempBlock === void 0) continue;
|
|
1470
|
-
block = tempBlock;
|
|
1471
|
-
break;
|
|
1472
|
-
}
|
|
1473
|
-
} else {
|
|
1474
|
-
block = blocksMap.get(blockSpecifier);
|
|
1475
|
-
}
|
|
1476
|
-
if (!block) {
|
|
1477
|
-
program2.error(
|
|
1478
|
-
color5.red(`Invalid block! ${color5.bold(blockSpecifier)} does not exist!`)
|
|
1479
|
-
);
|
|
1480
|
-
}
|
|
1481
|
-
const fullSpecifier = `${block.sourceRepo.url}/${block.category}/${block.name}`;
|
|
1482
|
-
blocks.set(fullSpecifier, { name: fullSpecifier, subDependency: false, block });
|
|
1483
|
-
if (block.localDependencies && block.localDependencies.length > 0) {
|
|
1484
|
-
const subDeps = await getBlocks(
|
|
1485
|
-
block.localDependencies.filter((dep) => !blocks.has(dep)),
|
|
1486
|
-
blocksMap,
|
|
1487
|
-
repoPaths,
|
|
1488
|
-
options
|
|
1489
|
-
);
|
|
1490
|
-
for (const dep of subDeps) {
|
|
1491
|
-
blocks.set(dep.name, dep);
|
|
1492
|
-
}
|
|
1493
|
-
}
|
|
1494
|
-
}
|
|
1495
|
-
return mapToArray(blocks, (_, val) => val);
|
|
1496
1567
|
};
|
|
1497
1568
|
|
|
1498
1569
|
// src/commands/build.ts
|
|
1499
1570
|
import fs7 from "node:fs";
|
|
1500
1571
|
import path7 from "node:path";
|
|
1501
1572
|
import { outro as outro2, spinner as spinner3 } from "@clack/prompts";
|
|
1502
|
-
import
|
|
1573
|
+
import color8 from "chalk";
|
|
1503
1574
|
import { Command as Command2 } from "commander";
|
|
1504
1575
|
import * as v5 from "valibot";
|
|
1505
1576
|
var schema3 = v5.object({
|
|
1506
|
-
verbose: v5.boolean(),
|
|
1507
|
-
output: v5.boolean(),
|
|
1508
1577
|
dirs: v5.array(v5.string()),
|
|
1578
|
+
output: v5.boolean(),
|
|
1579
|
+
verbose: v5.boolean(),
|
|
1509
1580
|
cwd: v5.string()
|
|
1510
1581
|
});
|
|
1511
1582
|
var build = new Command2("build").description(`Builds the provided --dirs in the project root into a \`${OUTPUT_FILE}\` file.`).option("--dirs [dirs...]", "The directories containing the blocks.", ["./blocks"]).option("--no-output", `Do not output a \`${OUTPUT_FILE}\` file.`).option("--verbose", "Include debug logs.", false).option("--cwd <path>", "The current working directory.", process.cwd()).action(async (opts) => {
|
|
1512
1583
|
const options = v5.parse(schema3, opts);
|
|
1584
|
+
_intro(context.package.version);
|
|
1513
1585
|
await _build(options);
|
|
1586
|
+
outro2(color8.green("All done!"));
|
|
1514
1587
|
});
|
|
1515
1588
|
var _build = async (options) => {
|
|
1516
|
-
_intro(context.package.version);
|
|
1517
1589
|
const loading = spinner3();
|
|
1518
1590
|
const categories = [];
|
|
1519
1591
|
const outFile = path7.join(options.cwd, OUTPUT_FILE);
|
|
1520
1592
|
for (const dir of options.dirs) {
|
|
1521
1593
|
const dirPath = path7.join(options.cwd, dir);
|
|
1522
|
-
loading.start(`Building ${
|
|
1594
|
+
loading.start(`Building ${color8.cyan(dirPath)}`);
|
|
1523
1595
|
if (options.output && fs7.existsSync(outFile)) fs7.rmSync(outFile);
|
|
1524
1596
|
categories.push(...buildBlocksDirectory(dirPath, options.cwd));
|
|
1525
|
-
loading.stop(`Built ${
|
|
1597
|
+
loading.stop(`Built ${color8.cyan(dirPath)}`);
|
|
1526
1598
|
}
|
|
1527
1599
|
const categoriesMap = /* @__PURE__ */ new Map();
|
|
1528
1600
|
for (const category of categories) {
|
|
@@ -1539,23 +1611,22 @@ var _build = async (options) => {
|
|
|
1539
1611
|
} else {
|
|
1540
1612
|
loading.stop("Built successfully!");
|
|
1541
1613
|
}
|
|
1542
|
-
outro2(color6.green("All done!"));
|
|
1543
1614
|
};
|
|
1544
1615
|
|
|
1545
1616
|
// src/commands/diff.ts
|
|
1546
1617
|
import fs8 from "node:fs";
|
|
1547
1618
|
import path8 from "node:path";
|
|
1548
1619
|
import { cancel as cancel2, confirm as confirm2, isCancel as isCancel2, outro as outro3, spinner as spinner4 } from "@clack/prompts";
|
|
1549
|
-
import
|
|
1620
|
+
import color10 from "chalk";
|
|
1550
1621
|
import { Command as Command3, program as program3 } from "commander";
|
|
1551
1622
|
import { diffLines } from "diff";
|
|
1552
1623
|
import * as v6 from "valibot";
|
|
1553
1624
|
|
|
1554
1625
|
// src/utils/diff.ts
|
|
1555
|
-
import
|
|
1626
|
+
import color9 from "chalk";
|
|
1556
1627
|
import { diffChars } from "diff";
|
|
1557
1628
|
|
|
1558
|
-
// src/blocks/utils/array-sum.ts
|
|
1629
|
+
// src/utils/blocks/utils/array-sum.ts
|
|
1559
1630
|
var arraySum = (arr, fn) => {
|
|
1560
1631
|
let total = 0;
|
|
1561
1632
|
for (const item of arr) {
|
|
@@ -1564,7 +1635,7 @@ var arraySum = (arr, fn) => {
|
|
|
1564
1635
|
return total;
|
|
1565
1636
|
};
|
|
1566
1637
|
|
|
1567
|
-
// src/blocks/utils/lines.ts
|
|
1638
|
+
// src/utils/blocks/utils/lines.ts
|
|
1568
1639
|
import os from "node:os";
|
|
1569
1640
|
var NEW_LINE_REGEX = /\n|\r\n/g;
|
|
1570
1641
|
var get = (str) => str.split(NEW_LINE_REGEX);
|
|
@@ -1601,10 +1672,10 @@ var formatDiff = ({
|
|
|
1601
1672
|
changes,
|
|
1602
1673
|
expand = false,
|
|
1603
1674
|
maxUnchanged = 5,
|
|
1604
|
-
colorRemoved =
|
|
1605
|
-
colorAdded =
|
|
1606
|
-
colorCharsRemoved =
|
|
1607
|
-
colorCharsAdded =
|
|
1675
|
+
colorRemoved = color9.red,
|
|
1676
|
+
colorAdded = color9.green,
|
|
1677
|
+
colorCharsRemoved = color9.bgRed,
|
|
1678
|
+
colorCharsAdded = color9.bgGreen,
|
|
1608
1679
|
prefix,
|
|
1609
1680
|
onUnchanged,
|
|
1610
1681
|
intro: intro2
|
|
@@ -1638,7 +1709,7 @@ var formatDiff = ({
|
|
|
1638
1709
|
onUnchanged,
|
|
1639
1710
|
intro: intro2
|
|
1640
1711
|
});
|
|
1641
|
-
const linePrefix = (line) =>
|
|
1712
|
+
const linePrefix = (line) => color9.gray(`${prefix?.() ?? ""}${leftPadMin(`${line + 1 + lineOffset} `, length)} `);
|
|
1642
1713
|
for (let i = 0; i < changes.length; i++) {
|
|
1643
1714
|
const change = changes[i];
|
|
1644
1715
|
const hasPreviousChange = changes[i - 1]?.added || changes[i - 1]?.removed;
|
|
@@ -1668,8 +1739,8 @@ var formatDiff = ({
|
|
|
1668
1739
|
const count = ls.length - shownLines;
|
|
1669
1740
|
result += `${join(
|
|
1670
1741
|
get(
|
|
1671
|
-
|
|
1672
|
-
`+ ${count} more unchanged (${
|
|
1742
|
+
color9.gray(
|
|
1743
|
+
`+ ${count} more unchanged (${color9.italic("-E to expand")})`
|
|
1673
1744
|
)
|
|
1674
1745
|
),
|
|
1675
1746
|
{
|
|
@@ -1743,37 +1814,36 @@ var formatDiff = ({
|
|
|
1743
1814
|
};
|
|
1744
1815
|
|
|
1745
1816
|
// src/commands/diff.ts
|
|
1746
|
-
var L = color8.gray("\u2502");
|
|
1747
1817
|
var schema4 = v6.object({
|
|
1748
|
-
allow: v6.boolean(),
|
|
1749
1818
|
expand: v6.boolean(),
|
|
1750
1819
|
maxUnchanged: v6.number(),
|
|
1751
1820
|
repo: v6.optional(v6.string()),
|
|
1821
|
+
allow: v6.boolean(),
|
|
1752
1822
|
cwd: v6.string()
|
|
1753
1823
|
});
|
|
1754
|
-
var diff = new Command3("diff").description("Compares local blocks to the blocks in the provided repository.").option("-
|
|
1824
|
+
var diff = new Command3("diff").description("Compares local blocks to the blocks in the provided repository.").option("-E, --expand", "Expands the diff so you see everything.", false).option(
|
|
1755
1825
|
"--max-unchanged <number>",
|
|
1756
1826
|
"Maximum unchanged lines that will show without being collapsed.",
|
|
1757
1827
|
(val) => Number.parseInt(val),
|
|
1758
1828
|
// this is such a dumb api thing
|
|
1759
1829
|
3
|
|
1760
|
-
).option("--cwd <path>", "The current working directory.", process.cwd()).action(async (opts) => {
|
|
1830
|
+
).option("--repo <repo>", "Repository to download the blocks from.").option("-A, --allow", "Allow jsrepo to download code from the provided repo.", false).option("--cwd <path>", "The current working directory.", process.cwd()).action(async (opts) => {
|
|
1761
1831
|
const options = v6.parse(schema4, opts);
|
|
1832
|
+
_intro(context.package.version);
|
|
1762
1833
|
await _diff(options);
|
|
1834
|
+
outro3(color10.green("All done!"));
|
|
1763
1835
|
});
|
|
1764
1836
|
var _diff = async (options) => {
|
|
1765
|
-
_intro(context.package.version);
|
|
1766
1837
|
const loading = spinner4();
|
|
1767
1838
|
const config = getConfig(options.cwd).match(
|
|
1768
1839
|
(val) => val,
|
|
1769
|
-
(err) => program3.error(
|
|
1840
|
+
(err) => program3.error(color10.red(err))
|
|
1770
1841
|
);
|
|
1771
|
-
const blocksMap = /* @__PURE__ */ new Map();
|
|
1772
1842
|
let repoPaths = config.repos;
|
|
1773
1843
|
if (options.repo) repoPaths = [options.repo];
|
|
1774
1844
|
if (!options.allow && options.repo) {
|
|
1775
1845
|
const result = await confirm2({
|
|
1776
|
-
message: `Allow ${
|
|
1846
|
+
message: `Allow ${color10.cyan("jsrepo")} to download and run code from ${color10.cyan(options.repo)}?`,
|
|
1777
1847
|
initialValue: true
|
|
1778
1848
|
});
|
|
1779
1849
|
if (isCancel2(result) || !result) {
|
|
@@ -1781,31 +1851,16 @@ var _diff = async (options) => {
|
|
|
1781
1851
|
process.exit(0);
|
|
1782
1852
|
}
|
|
1783
1853
|
}
|
|
1784
|
-
loading.start(`Fetching blocks from ${
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
(
|
|
1789
|
-
|
|
1790
|
-
const manifestUrl = await providerInfo.provider.resolveRaw(providerInfo, OUTPUT_FILE);
|
|
1791
|
-
const categories = (await getManifest(manifestUrl)).match(
|
|
1792
|
-
(val) => val,
|
|
1793
|
-
(err) => program3.error(color8.red(err))
|
|
1794
|
-
);
|
|
1795
|
-
for (const category of categories) {
|
|
1796
|
-
for (const block of category.blocks) {
|
|
1797
|
-
blocksMap.set(
|
|
1798
|
-
`${providerInfo.name}/${providerInfo.owner}/${providerInfo.repoName}/${category.name}/${block.name}`,
|
|
1799
|
-
{
|
|
1800
|
-
...block,
|
|
1801
|
-
sourceRepo: providerInfo
|
|
1802
|
-
}
|
|
1803
|
-
);
|
|
1804
|
-
}
|
|
1854
|
+
loading.start(`Fetching blocks from ${color10.cyan(repoPaths.join(", "))}`);
|
|
1855
|
+
const blocksMap = (await fetchBlocks(...repoPaths)).match(
|
|
1856
|
+
(val) => val,
|
|
1857
|
+
({ repo, message }) => {
|
|
1858
|
+
loading.stop(`Failed fetching blocks from ${color10.cyan(repo)}`);
|
|
1859
|
+
program3.error(color10.red(message));
|
|
1805
1860
|
}
|
|
1806
|
-
|
|
1807
|
-
loading.stop(`Retrieved blocks from ${
|
|
1808
|
-
const installedBlocks =
|
|
1861
|
+
);
|
|
1862
|
+
loading.stop(`Retrieved blocks from ${color10.cyan(repoPaths.join(", "))}`);
|
|
1863
|
+
const installedBlocks = getInstalled(blocksMap, config, options.cwd);
|
|
1809
1864
|
for (const blockSpecifier of installedBlocks) {
|
|
1810
1865
|
let found = false;
|
|
1811
1866
|
for (const repo of repoPaths) {
|
|
@@ -1813,21 +1868,21 @@ var _diff = async (options) => {
|
|
|
1813
1868
|
const fullSpecifier = `${providerInfo.name}/${providerInfo.owner}/${providerInfo.repoName}/${blockSpecifier.specifier}`;
|
|
1814
1869
|
const block = blocksMap.get(fullSpecifier);
|
|
1815
1870
|
if (block === void 0) continue;
|
|
1871
|
+
const watermark = getWatermark(context.package.version, repo);
|
|
1816
1872
|
found = true;
|
|
1817
|
-
process.stdout.write(`${
|
|
1873
|
+
process.stdout.write(`${VERTICAL_LINE}
|
|
1818
1874
|
`);
|
|
1819
|
-
process.stdout.write(`${
|
|
1875
|
+
process.stdout.write(`${VERTICAL_LINE} ${fullSpecifier}
|
|
1820
1876
|
`);
|
|
1821
|
-
fullSpecifier;
|
|
1822
1877
|
for (const file of block.files) {
|
|
1823
1878
|
if (!config.includeTests && isTestFile(file)) continue;
|
|
1824
|
-
process.stdout.write(`${
|
|
1879
|
+
process.stdout.write(`${VERTICAL_LINE}
|
|
1825
1880
|
`);
|
|
1826
1881
|
const sourcePath = path8.join(block.directory, file);
|
|
1827
1882
|
const rawUrl = await providerInfo.provider.resolveRaw(providerInfo, sourcePath);
|
|
1828
1883
|
const response = await fetch(rawUrl);
|
|
1829
1884
|
if (!response.ok) {
|
|
1830
|
-
program3.error(
|
|
1885
|
+
program3.error(color10.red(`There was an error trying to get ${fullSpecifier}`));
|
|
1831
1886
|
}
|
|
1832
1887
|
let remoteContent = await response.text();
|
|
1833
1888
|
const directory = path8.join(options.cwd, config.path, block.category);
|
|
@@ -1844,7 +1899,6 @@ var _diff = async (options) => {
|
|
|
1844
1899
|
if (config.watermark) {
|
|
1845
1900
|
const lang = languages.find((lang2) => lang2.matches(sourcePath));
|
|
1846
1901
|
if (lang) {
|
|
1847
|
-
const watermark = getWatermark(context.package.version, repo);
|
|
1848
1902
|
const comment = lang.comment(watermark);
|
|
1849
1903
|
remoteContent = `${comment}
|
|
1850
1904
|
|
|
@@ -1863,16 +1917,16 @@ ${remoteContent}`;
|
|
|
1863
1917
|
changes,
|
|
1864
1918
|
expand: options.expand,
|
|
1865
1919
|
maxUnchanged: options.maxUnchanged,
|
|
1866
|
-
colorAdded:
|
|
1867
|
-
colorRemoved:
|
|
1868
|
-
colorCharsAdded:
|
|
1869
|
-
colorCharsRemoved:
|
|
1870
|
-
prefix: () => `${
|
|
1871
|
-
onUnchanged: ({ from: from2, to: to2, prefix }) => `${prefix?.() ?? ""}${
|
|
1920
|
+
colorAdded: color10.greenBright,
|
|
1921
|
+
colorRemoved: color10.redBright,
|
|
1922
|
+
colorCharsAdded: color10.bgGreenBright,
|
|
1923
|
+
colorCharsRemoved: color10.bgRedBright,
|
|
1924
|
+
prefix: () => `${VERTICAL_LINE} `,
|
|
1925
|
+
onUnchanged: ({ from: from2, to: to2, prefix }) => `${prefix?.() ?? ""}${color10.cyan(from2)} \u2192 ${color10.gray(to2)} ${color10.gray("(unchanged)")}
|
|
1872
1926
|
`,
|
|
1873
1927
|
intro: ({ from: from2, to: to2, changes: changes2, prefix }) => {
|
|
1874
1928
|
const totalChanges = changes2.filter((a) => a.added).length;
|
|
1875
|
-
return `${prefix?.() ?? ""}${
|
|
1929
|
+
return `${prefix?.() ?? ""}${color10.cyan(from2)} \u2192 ${color10.gray(to2)} (${totalChanges} change${totalChanges === 1 ? "" : "s"})
|
|
1876
1930
|
${prefix?.() ?? ""}
|
|
1877
1931
|
`;
|
|
1878
1932
|
}
|
|
@@ -1883,25 +1937,24 @@ ${prefix?.() ?? ""}
|
|
|
1883
1937
|
}
|
|
1884
1938
|
if (!found) {
|
|
1885
1939
|
program3.error(
|
|
1886
|
-
|
|
1940
|
+
color10.red(`Invalid block! ${color10.bold(blockSpecifier)} does not exist!`)
|
|
1887
1941
|
);
|
|
1888
1942
|
}
|
|
1889
1943
|
}
|
|
1890
|
-
outro3(color8.green("All done!"));
|
|
1891
1944
|
};
|
|
1892
1945
|
|
|
1893
1946
|
// src/commands/init.ts
|
|
1894
1947
|
import fs9 from "node:fs";
|
|
1895
1948
|
import path9 from "node:path";
|
|
1896
1949
|
import { cancel as cancel3, confirm as confirm3, isCancel as isCancel3, outro as outro4, spinner as spinner5, text } from "@clack/prompts";
|
|
1897
|
-
import
|
|
1950
|
+
import color11 from "chalk";
|
|
1898
1951
|
import { Command as Command4 } from "commander";
|
|
1899
1952
|
import * as v7 from "valibot";
|
|
1900
1953
|
var schema5 = v7.object({
|
|
1901
1954
|
path: v7.optional(v7.string()),
|
|
1902
|
-
tests: v7.optional(v7.boolean()),
|
|
1903
1955
|
repos: v7.optional(v7.array(v7.string())),
|
|
1904
1956
|
watermark: v7.boolean(),
|
|
1957
|
+
tests: v7.optional(v7.boolean()),
|
|
1905
1958
|
cwd: v7.string()
|
|
1906
1959
|
});
|
|
1907
1960
|
var init = new Command4("init").description("Initializes your project with a configuration file.").option("--path <path>", "Path to install the blocks.").option("--repos [repos...]", "Repository to install the blocks from.").option(
|
|
@@ -1909,10 +1962,11 @@ var init = new Command4("init").description("Initializes your project with a con
|
|
|
1909
1962
|
"Will not add a watermark to each file upon adding it to your project."
|
|
1910
1963
|
).option("--tests", "Will include tests with the blocks.").option("--cwd <path>", "The current working directory.", process.cwd()).action(async (opts) => {
|
|
1911
1964
|
const options = v7.parse(schema5, opts);
|
|
1965
|
+
_intro(context.package.version);
|
|
1912
1966
|
await _init(options);
|
|
1967
|
+
outro4(color11.green("All done!"));
|
|
1913
1968
|
});
|
|
1914
1969
|
var _init = async (options) => {
|
|
1915
|
-
_intro(context.package.version);
|
|
1916
1970
|
const initialConfig = getConfig(options.cwd);
|
|
1917
1971
|
const loading = spinner5();
|
|
1918
1972
|
if (!options.path) {
|
|
@@ -1934,7 +1988,8 @@ var _init = async (options) => {
|
|
|
1934
1988
|
while (true) {
|
|
1935
1989
|
const confirmResult = await confirm3({
|
|
1936
1990
|
message: `Add ${options.repos.length > 0 ? "another" : "a"} repo?`,
|
|
1937
|
-
initialValue:
|
|
1991
|
+
initialValue: options.repos.length === 0
|
|
1992
|
+
// default to yes for first repo
|
|
1938
1993
|
});
|
|
1939
1994
|
if (isCancel3(confirmResult)) {
|
|
1940
1995
|
cancel3("Canceled!");
|
|
@@ -1946,7 +2001,7 @@ var _init = async (options) => {
|
|
|
1946
2001
|
placeholder: "github/ieedan/std",
|
|
1947
2002
|
validate: (val) => {
|
|
1948
2003
|
if (!val.startsWith("https://github.com") && !val.startsWith("github/")) {
|
|
1949
|
-
return `Must be a ${
|
|
2004
|
+
return `Must be a ${color11.bold("GitHub")} repository!`;
|
|
1950
2005
|
}
|
|
1951
2006
|
}
|
|
1952
2007
|
});
|
|
@@ -1972,33 +2027,33 @@ var _init = async (options) => {
|
|
|
1972
2027
|
);
|
|
1973
2028
|
fs9.mkdirSync(path9.join(options.cwd, config.path), { recursive: true });
|
|
1974
2029
|
loading.stop(`Wrote config to \`${CONFIG_NAME}\`.`);
|
|
1975
|
-
outro4(color9.green("All done!"));
|
|
1976
2030
|
};
|
|
1977
2031
|
|
|
1978
2032
|
// src/commands/test.ts
|
|
1979
2033
|
import fs10 from "node:fs";
|
|
1980
2034
|
import path10 from "node:path";
|
|
1981
2035
|
import { cancel as cancel4, confirm as confirm4, isCancel as isCancel4, outro as outro5, spinner as spinner6 } from "@clack/prompts";
|
|
1982
|
-
import
|
|
2036
|
+
import color12 from "chalk";
|
|
1983
2037
|
import { Argument, Command as Command5, program as program4 } from "commander";
|
|
1984
2038
|
import { execa as execa2 } from "execa";
|
|
1985
|
-
import { resolveCommand as
|
|
2039
|
+
import { resolveCommand as resolveCommand3 } from "package-manager-detector/commands";
|
|
1986
2040
|
import { detect as detect2 } from "package-manager-detector/detect";
|
|
1987
2041
|
import { Project as Project2 } from "ts-morph";
|
|
1988
2042
|
import * as v8 from "valibot";
|
|
1989
2043
|
var schema6 = v8.object({
|
|
1990
|
-
debug: v8.boolean(),
|
|
1991
|
-
verbose: v8.boolean(),
|
|
1992
2044
|
repo: v8.optional(v8.string()),
|
|
1993
2045
|
allow: v8.boolean(),
|
|
2046
|
+
debug: v8.boolean(),
|
|
2047
|
+
verbose: v8.boolean(),
|
|
1994
2048
|
cwd: v8.string()
|
|
1995
2049
|
});
|
|
1996
|
-
var test = new Command5("test").description("Tests local blocks against most recent remote tests.").addArgument(new Argument("[blocks...]", "The blocks you want to test.").default([])).option("--
|
|
2050
|
+
var test = new Command5("test").description("Tests local blocks against most recent remote tests.").addArgument(new Argument("[blocks...]", "The blocks you want to test.").default([])).option("--repo <repo>", "Repository to download the blocks from.").option("-A, --allow", "Allow jsrepo to download code from the provided repo.", false).option("--debug", "Leaves the temp test file around for debugging upon failure.", false).option("--verbose", "Include debug logs.", false).option("--cwd <path>", "The current working directory.", process.cwd()).action(async (blockNames, opts) => {
|
|
1997
2051
|
const options = v8.parse(schema6, opts);
|
|
2052
|
+
_intro(context.package.version);
|
|
1998
2053
|
await _test(blockNames, options);
|
|
2054
|
+
outro5(color12.green("All done!"));
|
|
1999
2055
|
});
|
|
2000
2056
|
var _test = async (blockNames, options) => {
|
|
2001
|
-
_intro(context.package.version);
|
|
2002
2057
|
const verbose = (msg) => {
|
|
2003
2058
|
if (options.verbose) {
|
|
2004
2059
|
console.info(`${INFO} ${msg}`);
|
|
@@ -2007,7 +2062,7 @@ var _test = async (blockNames, options) => {
|
|
|
2007
2062
|
verbose(`Attempting to test ${JSON.stringify(blockNames)}`);
|
|
2008
2063
|
const config = getConfig(options.cwd).match(
|
|
2009
2064
|
(val) => val,
|
|
2010
|
-
(err) => program4.error(
|
|
2065
|
+
(err) => program4.error(color12.red(err))
|
|
2011
2066
|
);
|
|
2012
2067
|
const loading = spinner6();
|
|
2013
2068
|
const blocksMap = /* @__PURE__ */ new Map();
|
|
@@ -2015,7 +2070,7 @@ var _test = async (blockNames, options) => {
|
|
|
2015
2070
|
if (options.repo) repoPaths = [options.repo];
|
|
2016
2071
|
if (!options.allow && options.repo) {
|
|
2017
2072
|
const result = await confirm4({
|
|
2018
|
-
message: `Allow ${
|
|
2073
|
+
message: `Allow ${color12.cyan("jsrepo")} to download and run code from ${color12.cyan(options.repo)}?`,
|
|
2019
2074
|
initialValue: true
|
|
2020
2075
|
});
|
|
2021
2076
|
if (isCancel4(result) || !result) {
|
|
@@ -2023,21 +2078,21 @@ var _test = async (blockNames, options) => {
|
|
|
2023
2078
|
process.exit(0);
|
|
2024
2079
|
}
|
|
2025
2080
|
}
|
|
2026
|
-
verbose(`Fetching blocks from ${
|
|
2027
|
-
if (!options.verbose) loading.start(`Fetching blocks from ${
|
|
2081
|
+
verbose(`Fetching blocks from ${color12.cyan(repoPaths.join(", "))}`);
|
|
2082
|
+
if (!options.verbose) loading.start(`Fetching blocks from ${color12.cyan(repoPaths.join(", "))}`);
|
|
2028
2083
|
for (const repo of repoPaths) {
|
|
2029
2084
|
const providerInfo = (await getProviderInfo(repo)).match(
|
|
2030
2085
|
(info) => info,
|
|
2031
|
-
(err) => program4.error(
|
|
2086
|
+
(err) => program4.error(color12.red(err))
|
|
2032
2087
|
);
|
|
2033
2088
|
const manifestUrl = await providerInfo.provider.resolveRaw(providerInfo, OUTPUT_FILE);
|
|
2034
|
-
verbose(`Got info for provider ${
|
|
2089
|
+
verbose(`Got info for provider ${color12.cyan(providerInfo.name)}`);
|
|
2035
2090
|
const response = await fetch(manifestUrl);
|
|
2036
2091
|
if (!response.ok) {
|
|
2037
|
-
if (!options.verbose) loading.stop(`Error fetching ${
|
|
2092
|
+
if (!options.verbose) loading.stop(`Error fetching ${color12.cyan(manifestUrl.href)}`);
|
|
2038
2093
|
program4.error(
|
|
2039
|
-
|
|
2040
|
-
`There was an error fetching the \`${OUTPUT_FILE}\` from the repository ${
|
|
2094
|
+
color12.red(
|
|
2095
|
+
`There was an error fetching the \`${OUTPUT_FILE}\` from the repository ${color12.cyan(
|
|
2041
2096
|
repo
|
|
2042
2097
|
)} make sure the target repository has a \`${OUTPUT_FILE}\` in its root?`
|
|
2043
2098
|
)
|
|
@@ -2056,17 +2111,17 @@ var _test = async (blockNames, options) => {
|
|
|
2056
2111
|
}
|
|
2057
2112
|
}
|
|
2058
2113
|
}
|
|
2059
|
-
verbose(`Retrieved blocks from ${
|
|
2060
|
-
if (!options.verbose) loading.stop(`Retrieved blocks from ${
|
|
2114
|
+
verbose(`Retrieved blocks from ${color12.cyan(repoPaths.join(", "))}`);
|
|
2115
|
+
if (!options.verbose) loading.stop(`Retrieved blocks from ${color12.cyan(repoPaths.join(", "))}`);
|
|
2061
2116
|
const tempTestDirectory = path10.resolve(
|
|
2062
2117
|
path10.join(options.cwd, `blocks-tests-temp-${Date.now()}`)
|
|
2063
2118
|
);
|
|
2064
|
-
verbose(`Trying to create the temp directory ${
|
|
2119
|
+
verbose(`Trying to create the temp directory ${color12.bold(tempTestDirectory)}.`);
|
|
2065
2120
|
fs10.mkdirSync(tempTestDirectory, { recursive: true });
|
|
2066
2121
|
const cleanUp = () => {
|
|
2067
2122
|
fs10.rmSync(tempTestDirectory, { recursive: true, force: true });
|
|
2068
2123
|
};
|
|
2069
|
-
const installedBlocks =
|
|
2124
|
+
const installedBlocks = getInstalled(blocksMap, config, options.cwd).map(
|
|
2070
2125
|
(val) => val.specifier
|
|
2071
2126
|
);
|
|
2072
2127
|
let testingBlocks = blockNames;
|
|
@@ -2075,7 +2130,7 @@ var _test = async (blockNames, options) => {
|
|
|
2075
2130
|
}
|
|
2076
2131
|
if (testingBlocks.length === 0) {
|
|
2077
2132
|
cleanUp();
|
|
2078
|
-
program4.error(
|
|
2133
|
+
program4.error(color12.red("There were no blocks found in your project!"));
|
|
2079
2134
|
}
|
|
2080
2135
|
const testingBlocksMapped = [];
|
|
2081
2136
|
for (const blockSpecifier of testingBlocks) {
|
|
@@ -2101,7 +2156,7 @@ var _test = async (blockNames, options) => {
|
|
|
2101
2156
|
}
|
|
2102
2157
|
const providerInfo = (await getProviderInfo(repo)).match(
|
|
2103
2158
|
(val) => val,
|
|
2104
|
-
(err) => program4.error(
|
|
2159
|
+
(err) => program4.error(color12.red(err))
|
|
2105
2160
|
);
|
|
2106
2161
|
const manifestUrl = await providerInfo.provider.resolveRaw(
|
|
2107
2162
|
providerInfo,
|
|
@@ -2109,7 +2164,7 @@ var _test = async (blockNames, options) => {
|
|
|
2109
2164
|
);
|
|
2110
2165
|
const categories = (await getManifest(manifestUrl)).match(
|
|
2111
2166
|
(val) => val,
|
|
2112
|
-
(err) => program4.error(
|
|
2167
|
+
(err) => program4.error(color12.red(err))
|
|
2113
2168
|
);
|
|
2114
2169
|
for (const category of categories) {
|
|
2115
2170
|
for (const block2 of category.blocks) {
|
|
@@ -2127,7 +2182,7 @@ var _test = async (blockNames, options) => {
|
|
|
2127
2182
|
}
|
|
2128
2183
|
if (!block) {
|
|
2129
2184
|
program4.error(
|
|
2130
|
-
|
|
2185
|
+
color12.red(`Invalid block! ${color12.bold(blockSpecifier)} does not exist!`)
|
|
2131
2186
|
);
|
|
2132
2187
|
}
|
|
2133
2188
|
testingBlocksMapped.push({ name: blockSpecifier, block });
|
|
@@ -2135,18 +2190,18 @@ var _test = async (blockNames, options) => {
|
|
|
2135
2190
|
for (const { name: specifier, block } of testingBlocksMapped) {
|
|
2136
2191
|
const providerInfo = block.sourceRepo;
|
|
2137
2192
|
if (!options.verbose) {
|
|
2138
|
-
loading.start(`Setting up test file for ${
|
|
2193
|
+
loading.start(`Setting up test file for ${color12.cyan(specifier)}`);
|
|
2139
2194
|
}
|
|
2140
2195
|
if (!block.tests) {
|
|
2141
|
-
loading.stop(`No tests found for ${
|
|
2196
|
+
loading.stop(`No tests found for ${color12.cyan(specifier)}`);
|
|
2142
2197
|
continue;
|
|
2143
2198
|
}
|
|
2144
2199
|
const getSourceFile = async (filePath) => {
|
|
2145
2200
|
const rawUrl = await providerInfo.provider.resolveRaw(providerInfo, filePath);
|
|
2146
2201
|
const response = await fetch(rawUrl);
|
|
2147
2202
|
if (!response.ok) {
|
|
2148
|
-
loading.stop(
|
|
2149
|
-
program4.error(
|
|
2203
|
+
loading.stop(color12.red(`Error fetching ${color12.bold(rawUrl.href)}`));
|
|
2204
|
+
program4.error(color12.red(`There was an error trying to get ${specifier}`));
|
|
2150
2205
|
}
|
|
2151
2206
|
return await response.text();
|
|
2152
2207
|
};
|
|
@@ -2189,19 +2244,19 @@ var _test = async (blockNames, options) => {
|
|
|
2189
2244
|
}
|
|
2190
2245
|
}
|
|
2191
2246
|
project.saveSync();
|
|
2192
|
-
verbose(`Completed ${
|
|
2247
|
+
verbose(`Completed ${color12.cyan.bold(specifier)} test file`);
|
|
2193
2248
|
if (!options.verbose) {
|
|
2194
|
-
loading.stop(`Completed setup for ${
|
|
2249
|
+
loading.stop(`Completed setup for ${color12.bold(specifier)}`);
|
|
2195
2250
|
}
|
|
2196
2251
|
}
|
|
2197
2252
|
verbose("Beginning testing");
|
|
2198
2253
|
const pm = await detect2({ cwd: options.cwd });
|
|
2199
2254
|
if (pm == null) {
|
|
2200
|
-
program4.error(
|
|
2255
|
+
program4.error(color12.red("Could not detect package manager"));
|
|
2201
2256
|
}
|
|
2202
|
-
const resolved =
|
|
2257
|
+
const resolved = resolveCommand3(pm.agent, "execute", ["vitest", "run", tempTestDirectory]);
|
|
2203
2258
|
if (resolved == null) {
|
|
2204
|
-
program4.error(
|
|
2259
|
+
program4.error(color12.red(`Could not resolve add command for '${pm.agent}'.`));
|
|
2205
2260
|
}
|
|
2206
2261
|
const { command, args } = resolved;
|
|
2207
2262
|
const testCommand = `${command} ${args.join(" ")}`;
|
|
@@ -2215,11 +2270,10 @@ var _test = async (blockNames, options) => {
|
|
|
2215
2270
|
try {
|
|
2216
2271
|
await testingProcess;
|
|
2217
2272
|
cleanUp();
|
|
2218
|
-
outro5(color10.green("All done!"));
|
|
2219
2273
|
} catch (err) {
|
|
2220
2274
|
if (options.debug) {
|
|
2221
2275
|
console.info(
|
|
2222
|
-
`${
|
|
2276
|
+
`${color12.bold("--debug")} flag provided. Skipping cleanup. Run '${color12.bold(
|
|
2223
2277
|
testCommand
|
|
2224
2278
|
)}' to retry tests.
|
|
2225
2279
|
`
|
|
@@ -2227,17 +2281,328 @@ var _test = async (blockNames, options) => {
|
|
|
2227
2281
|
} else {
|
|
2228
2282
|
cleanUp();
|
|
2229
2283
|
}
|
|
2230
|
-
program4.error(
|
|
2284
|
+
program4.error(color12.red(`Tests failed! Error ${err}`));
|
|
2285
|
+
}
|
|
2286
|
+
};
|
|
2287
|
+
|
|
2288
|
+
// src/commands/update.ts
|
|
2289
|
+
import fs11 from "node:fs";
|
|
2290
|
+
import path11 from "node:path";
|
|
2291
|
+
import { cancel as cancel5, confirm as confirm5, isCancel as isCancel5, multiselect as multiselect2, outro as outro6, spinner as spinner7 } from "@clack/prompts";
|
|
2292
|
+
import color13 from "chalk";
|
|
2293
|
+
import { Command as Command6, program as program5 } from "commander";
|
|
2294
|
+
import { diffLines as diffLines2 } from "diff";
|
|
2295
|
+
import { resolveCommand as resolveCommand4 } from "package-manager-detector/commands";
|
|
2296
|
+
import { detect as detect3 } from "package-manager-detector/detect";
|
|
2297
|
+
import * as v9 from "valibot";
|
|
2298
|
+
var schema7 = v9.object({
|
|
2299
|
+
all: v9.boolean(),
|
|
2300
|
+
expand: v9.boolean(),
|
|
2301
|
+
maxUnchanged: v9.number(),
|
|
2302
|
+
repo: v9.optional(v9.string()),
|
|
2303
|
+
allow: v9.boolean(),
|
|
2304
|
+
yes: v9.boolean(),
|
|
2305
|
+
verbose: v9.boolean(),
|
|
2306
|
+
cwd: v9.string()
|
|
2307
|
+
});
|
|
2308
|
+
var update = new Command6("update").argument("[blocks...]", "Names of the blocks you want to update. ex: (utils/math)").option("--all", "Update all installed components.", false).option("-E, --expand", "Expands the diff so you see everything.", false).option(
|
|
2309
|
+
"--max-unchanged <number>",
|
|
2310
|
+
"Maximum unchanged lines that will show without being collapsed.",
|
|
2311
|
+
(val) => Number.parseInt(val),
|
|
2312
|
+
// this is such a dumb api thing
|
|
2313
|
+
3
|
|
2314
|
+
).option("--repo <repo>", "Repository to download the blocks from.").option("-A, --allow", "Allow jsrepo to download code from the provided repo.", false).option("-y, --yes", "Skip confirmation prompt.", false).option("--verbose", "Include debug logs.", false).option("--cwd <path>", "The current working directory.", process.cwd()).action(async (blockNames, opts) => {
|
|
2315
|
+
const options = v9.parse(schema7, opts);
|
|
2316
|
+
_intro(context.package.version);
|
|
2317
|
+
await _update(blockNames, options);
|
|
2318
|
+
outro6(color13.green("All done!"));
|
|
2319
|
+
});
|
|
2320
|
+
var _update = async (blockNames, options) => {
|
|
2321
|
+
const verbose = (msg) => {
|
|
2322
|
+
if (options.verbose) {
|
|
2323
|
+
console.info(`${INFO} ${msg}`);
|
|
2324
|
+
}
|
|
2325
|
+
};
|
|
2326
|
+
verbose(`Attempting to update ${JSON.stringify(blockNames)}`);
|
|
2327
|
+
const loading = spinner7();
|
|
2328
|
+
const config = getConfig(options.cwd).match(
|
|
2329
|
+
(val) => val,
|
|
2330
|
+
(err) => program5.error(color13.red(err))
|
|
2331
|
+
);
|
|
2332
|
+
let repoPaths = config.repos;
|
|
2333
|
+
if (options.repo) repoPaths = [options.repo];
|
|
2334
|
+
for (const blockSpecifier of blockNames) {
|
|
2335
|
+
if (blockSpecifier.startsWith("github")) {
|
|
2336
|
+
program5.error(
|
|
2337
|
+
color13.red(
|
|
2338
|
+
`Invalid value provided for block names \`${color13.bold(blockSpecifier)}\`. Block names are expected to be provided in the format of \`${color13.bold("<category>/<name>")}\``
|
|
2339
|
+
)
|
|
2340
|
+
);
|
|
2341
|
+
}
|
|
2342
|
+
}
|
|
2343
|
+
if (!options.allow && options.repo) {
|
|
2344
|
+
const result = await confirm5({
|
|
2345
|
+
message: `Allow ${color13.cyan("jsrepo")} to download and run code from ${color13.cyan(options.repo)}?`,
|
|
2346
|
+
initialValue: true
|
|
2347
|
+
});
|
|
2348
|
+
if (isCancel5(result) || !result) {
|
|
2349
|
+
cancel5("Canceled!");
|
|
2350
|
+
process.exit(0);
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2353
|
+
verbose(`Fetching blocks from ${color13.cyan(repoPaths.join(", "))}`);
|
|
2354
|
+
if (!options.verbose) loading.start(`Fetching blocks from ${color13.cyan(repoPaths.join(", "))}`);
|
|
2355
|
+
const blocksMap = (await fetchBlocks(...repoPaths)).match(
|
|
2356
|
+
(val) => val,
|
|
2357
|
+
({ repo, message }) => {
|
|
2358
|
+
loading.stop(`Failed fetching blocks from ${color13.cyan(repo)}`);
|
|
2359
|
+
program5.error(color13.red(message));
|
|
2360
|
+
}
|
|
2361
|
+
);
|
|
2362
|
+
if (!options.verbose) loading.stop(`Retrieved blocks from ${color13.cyan(repoPaths.join(", "))}`);
|
|
2363
|
+
verbose(`Retrieved blocks from ${color13.cyan(repoPaths.join(", "))}`);
|
|
2364
|
+
const installedBlocks = getInstalled(blocksMap, config, options.cwd);
|
|
2365
|
+
let updatingBlockNames = blockNames;
|
|
2366
|
+
if (options.all) {
|
|
2367
|
+
updatingBlockNames = installedBlocks.map((block) => block.specifier);
|
|
2368
|
+
}
|
|
2369
|
+
if (updatingBlockNames.length === 0) {
|
|
2370
|
+
const promptResult = await multiselect2({
|
|
2371
|
+
message: "Which blocks would you like to update?",
|
|
2372
|
+
options: installedBlocks.map((block) => {
|
|
2373
|
+
return {
|
|
2374
|
+
label: `${color13.cyan(block.block.category)}/${block.block.name}`,
|
|
2375
|
+
value: block.specifier
|
|
2376
|
+
};
|
|
2377
|
+
}),
|
|
2378
|
+
required: true
|
|
2379
|
+
});
|
|
2380
|
+
if (isCancel5(promptResult)) {
|
|
2381
|
+
cancel5("Canceled!");
|
|
2382
|
+
process.exit(0);
|
|
2383
|
+
}
|
|
2384
|
+
updatingBlockNames = promptResult;
|
|
2385
|
+
}
|
|
2386
|
+
verbose(`Preparing to update ${color13.cyan(updatingBlockNames.join(", "))}`);
|
|
2387
|
+
const updatingBlocks = (await resolveTree(updatingBlockNames, blocksMap, repoPaths)).match(
|
|
2388
|
+
(val) => val,
|
|
2389
|
+
program5.error
|
|
2390
|
+
);
|
|
2391
|
+
const pm = (await detect3({ cwd: process.cwd() }))?.agent ?? "npm";
|
|
2392
|
+
const tasks = [];
|
|
2393
|
+
const devDeps = /* @__PURE__ */ new Set();
|
|
2394
|
+
const deps = /* @__PURE__ */ new Set();
|
|
2395
|
+
for (const { block } of updatingBlocks) {
|
|
2396
|
+
const fullSpecifier = `${block.sourceRepo.url}/${block.category}/${block.name}`;
|
|
2397
|
+
const watermark = getWatermark(context.package.version, block.sourceRepo.url);
|
|
2398
|
+
const providerInfo = block.sourceRepo;
|
|
2399
|
+
verbose(`Attempting to add ${fullSpecifier}`);
|
|
2400
|
+
const directory = path11.join(options.cwd, config.path, block.category);
|
|
2401
|
+
const files = [];
|
|
2402
|
+
const getSourceFile = async (filePath) => {
|
|
2403
|
+
const rawUrl = await providerInfo.provider.resolveRaw(providerInfo, filePath);
|
|
2404
|
+
const response = await fetch(rawUrl);
|
|
2405
|
+
if (!response.ok) {
|
|
2406
|
+
loading.stop(color13.red(`Error fetching ${color13.bold(rawUrl.href)}`));
|
|
2407
|
+
program5.error(color13.red(`There was an error trying to get ${fullSpecifier}`));
|
|
2408
|
+
}
|
|
2409
|
+
return await response.text();
|
|
2410
|
+
};
|
|
2411
|
+
for (const sourceFile of block.files) {
|
|
2412
|
+
if (!config.includeTests && isTestFile(sourceFile)) continue;
|
|
2413
|
+
const sourcePath = path11.join(block.directory, sourceFile);
|
|
2414
|
+
let destPath;
|
|
2415
|
+
if (block.subdirectory) {
|
|
2416
|
+
destPath = path11.join(directory, block.name, sourceFile);
|
|
2417
|
+
} else {
|
|
2418
|
+
destPath = path11.join(directory, sourceFile);
|
|
2419
|
+
}
|
|
2420
|
+
const content = await getSourceFile(sourcePath);
|
|
2421
|
+
fs11.mkdirSync(destPath.slice(0, destPath.length - sourceFile.length), {
|
|
2422
|
+
recursive: true
|
|
2423
|
+
});
|
|
2424
|
+
files.push({ content, destPath, fileName: sourceFile });
|
|
2425
|
+
}
|
|
2426
|
+
process.stdout.write(`${VERTICAL_LINE}
|
|
2427
|
+
`);
|
|
2428
|
+
process.stdout.write(`${VERTICAL_LINE} ${fullSpecifier}
|
|
2429
|
+
`);
|
|
2430
|
+
for (const file of files) {
|
|
2431
|
+
let remoteContent = file.content;
|
|
2432
|
+
if (config.watermark) {
|
|
2433
|
+
const lang = languages.find((lang2) => lang2.matches(file.destPath));
|
|
2434
|
+
if (lang) {
|
|
2435
|
+
const comment = lang.comment(watermark);
|
|
2436
|
+
remoteContent = `${comment}
|
|
2437
|
+
|
|
2438
|
+
${remoteContent}`;
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2441
|
+
let acceptedChanges = options.yes;
|
|
2442
|
+
if (!options.yes) {
|
|
2443
|
+
process.stdout.write(`${VERTICAL_LINE}
|
|
2444
|
+
`);
|
|
2445
|
+
let localContent = "";
|
|
2446
|
+
if (fs11.existsSync(file.destPath)) {
|
|
2447
|
+
localContent = fs11.readFileSync(file.destPath).toString();
|
|
2448
|
+
}
|
|
2449
|
+
const changes = diffLines2(localContent, remoteContent);
|
|
2450
|
+
const from = path11.join(
|
|
2451
|
+
`${providerInfo.name}/${providerInfo.owner}/${providerInfo.repoName}`,
|
|
2452
|
+
file.fileName
|
|
2453
|
+
).replaceAll("\\", "/");
|
|
2454
|
+
const to = path11.relative(options.cwd, file.destPath).replaceAll("\\", "/");
|
|
2455
|
+
const formattedDiff = formatDiff({
|
|
2456
|
+
from,
|
|
2457
|
+
to,
|
|
2458
|
+
changes,
|
|
2459
|
+
expand: options.expand,
|
|
2460
|
+
maxUnchanged: options.maxUnchanged,
|
|
2461
|
+
colorAdded: color13.greenBright,
|
|
2462
|
+
colorRemoved: color13.redBright,
|
|
2463
|
+
colorCharsAdded: color13.bgGreenBright,
|
|
2464
|
+
colorCharsRemoved: color13.bgRedBright,
|
|
2465
|
+
prefix: () => `${VERTICAL_LINE} `,
|
|
2466
|
+
onUnchanged: ({ from: from2, to: to2, prefix }) => `${prefix?.() ?? ""}${color13.cyan(from2)} \u2192 ${color13.gray(to2)} ${color13.gray("(unchanged)")}
|
|
2467
|
+
`,
|
|
2468
|
+
intro: ({ from: from2, to: to2, changes: changes2, prefix }) => {
|
|
2469
|
+
const totalChanges = changes2.filter((a) => a.added).length;
|
|
2470
|
+
return `${prefix?.() ?? ""}${color13.cyan(from2)} \u2192 ${color13.gray(to2)} (${totalChanges} change${totalChanges === 1 ? "" : "s"})
|
|
2471
|
+
${prefix?.() ?? ""}
|
|
2472
|
+
`;
|
|
2473
|
+
}
|
|
2474
|
+
});
|
|
2475
|
+
process.stdout.write(formattedDiff);
|
|
2476
|
+
if (changes.length > 1) {
|
|
2477
|
+
const confirmResult = await confirm5({
|
|
2478
|
+
message: "Accept changes?",
|
|
2479
|
+
initialValue: true
|
|
2480
|
+
});
|
|
2481
|
+
if (isCancel5(confirmResult)) {
|
|
2482
|
+
cancel5("Canceled!");
|
|
2483
|
+
process.exit(0);
|
|
2484
|
+
}
|
|
2485
|
+
acceptedChanges = confirmResult;
|
|
2486
|
+
}
|
|
2487
|
+
}
|
|
2488
|
+
if (acceptedChanges) {
|
|
2489
|
+
await runTasks(
|
|
2490
|
+
[
|
|
2491
|
+
{
|
|
2492
|
+
loadingMessage: `Writing changes to ${color13.cyan(file.destPath)}`,
|
|
2493
|
+
completedMessage: `Wrote changes to ${color13.cyan(file.destPath)}.`,
|
|
2494
|
+
run: async () => fs11.writeFileSync(file.destPath, remoteContent)
|
|
2495
|
+
}
|
|
2496
|
+
],
|
|
2497
|
+
{
|
|
2498
|
+
verbose: options.verbose ? verbose : void 0
|
|
2499
|
+
}
|
|
2500
|
+
);
|
|
2501
|
+
}
|
|
2502
|
+
}
|
|
2503
|
+
if (config.includeTests) {
|
|
2504
|
+
verbose("Trying to include tests");
|
|
2505
|
+
const { devDependencies } = JSON.parse(
|
|
2506
|
+
fs11.readFileSync(path11.join(options.cwd, "package.json")).toString()
|
|
2507
|
+
);
|
|
2508
|
+
if (devDependencies.vitest === void 0) {
|
|
2509
|
+
devDeps.add("vitest");
|
|
2510
|
+
}
|
|
2511
|
+
}
|
|
2512
|
+
for (const dep of block.devDependencies) {
|
|
2513
|
+
devDeps.add(dep);
|
|
2514
|
+
}
|
|
2515
|
+
for (const dep of block.dependencies) {
|
|
2516
|
+
deps.add(dep);
|
|
2517
|
+
}
|
|
2518
|
+
}
|
|
2519
|
+
await runTasks(tasks, { verbose: options.verbose ? verbose : void 0 });
|
|
2520
|
+
const hasDependencies = deps.size > 0 || devDeps.size > 0;
|
|
2521
|
+
if (hasDependencies) {
|
|
2522
|
+
let install = options.yes;
|
|
2523
|
+
if (!options.yes) {
|
|
2524
|
+
const result = await confirm5({
|
|
2525
|
+
message: "Would you like to install dependencies?",
|
|
2526
|
+
initialValue: true
|
|
2527
|
+
});
|
|
2528
|
+
if (isCancel5(result)) {
|
|
2529
|
+
cancel5("Canceled!");
|
|
2530
|
+
process.exit(0);
|
|
2531
|
+
}
|
|
2532
|
+
install = result;
|
|
2533
|
+
}
|
|
2534
|
+
if (install) {
|
|
2535
|
+
if (deps.size > 0) {
|
|
2536
|
+
if (!options.verbose)
|
|
2537
|
+
loading.start(`Installing dependencies with ${color13.cyan(pm)}`);
|
|
2538
|
+
(await installDependencies({
|
|
2539
|
+
pm,
|
|
2540
|
+
deps: Array.from(deps),
|
|
2541
|
+
dev: false,
|
|
2542
|
+
cwd: options.cwd
|
|
2543
|
+
})).match(
|
|
2544
|
+
(installed) => {
|
|
2545
|
+
if (!options.verbose)
|
|
2546
|
+
loading.stop(`Installed ${color13.cyan(installed.join(", "))}`);
|
|
2547
|
+
},
|
|
2548
|
+
(err) => {
|
|
2549
|
+
if (!options.verbose) loading.stop("Failed to install dependencies");
|
|
2550
|
+
program5.error(err);
|
|
2551
|
+
}
|
|
2552
|
+
);
|
|
2553
|
+
}
|
|
2554
|
+
if (devDeps.size > 0) {
|
|
2555
|
+
if (!options.verbose)
|
|
2556
|
+
loading.start(`Installing dependencies with ${color13.cyan(pm)}`);
|
|
2557
|
+
(await installDependencies({
|
|
2558
|
+
pm,
|
|
2559
|
+
deps: Array.from(devDeps),
|
|
2560
|
+
dev: true,
|
|
2561
|
+
cwd: options.cwd
|
|
2562
|
+
})).match(
|
|
2563
|
+
(installed) => {
|
|
2564
|
+
if (!options.verbose)
|
|
2565
|
+
loading.stop(`Installed ${color13.cyan(installed.join(", "))}`);
|
|
2566
|
+
},
|
|
2567
|
+
(err) => {
|
|
2568
|
+
if (!options.verbose) loading.stop("Failed to install dev dependencies");
|
|
2569
|
+
program5.error(err);
|
|
2570
|
+
}
|
|
2571
|
+
);
|
|
2572
|
+
}
|
|
2573
|
+
}
|
|
2574
|
+
let steps = [];
|
|
2575
|
+
if (!install) {
|
|
2576
|
+
if (deps.size > 0) {
|
|
2577
|
+
const cmd = resolveCommand4(pm, "install", [...deps]);
|
|
2578
|
+
steps.push(
|
|
2579
|
+
`Install dependencies \`${color13.cyan(`${cmd?.command} ${cmd?.args.join(" ")}`)}\``
|
|
2580
|
+
);
|
|
2581
|
+
}
|
|
2582
|
+
if (devDeps.size > 0) {
|
|
2583
|
+
const cmd = resolveCommand4(pm, "install", [...devDeps, "-D"]);
|
|
2584
|
+
steps.push(
|
|
2585
|
+
`Install dev dependencies \`${color13.cyan(`${cmd?.command} ${cmd?.args.join(" ")}`)}\``
|
|
2586
|
+
);
|
|
2587
|
+
}
|
|
2588
|
+
}
|
|
2589
|
+
steps = steps.map((step, i) => `${i + 1}. ${step}`);
|
|
2590
|
+
if (!install) {
|
|
2591
|
+
steps.push("");
|
|
2592
|
+
}
|
|
2593
|
+
steps.push(`Import the blocks from \`${color13.cyan(config.path)}\``);
|
|
2594
|
+
const next = nextSteps(steps);
|
|
2595
|
+
process.stdout.write(next);
|
|
2231
2596
|
}
|
|
2232
2597
|
};
|
|
2233
2598
|
|
|
2234
2599
|
// src/index.ts
|
|
2235
2600
|
var resolveRelativeToRoot = (p) => {
|
|
2236
2601
|
const dirname = fileURLToPath(import.meta.url);
|
|
2237
|
-
return
|
|
2602
|
+
return path12.join(dirname, "../..", p);
|
|
2238
2603
|
};
|
|
2239
2604
|
var { version, name, description, repository } = JSON.parse(
|
|
2240
|
-
|
|
2605
|
+
fs12.readFileSync(resolveRelativeToRoot("package.json"), "utf-8")
|
|
2241
2606
|
);
|
|
2242
2607
|
var context = {
|
|
2243
2608
|
package: {
|
|
@@ -2248,8 +2613,8 @@ var context = {
|
|
|
2248
2613
|
},
|
|
2249
2614
|
resolveRelativeToRoot
|
|
2250
2615
|
};
|
|
2251
|
-
|
|
2252
|
-
|
|
2616
|
+
program6.name(name).description(description).version(version).addCommand(add).addCommand(init).addCommand(test).addCommand(build).addCommand(update).addCommand(diff);
|
|
2617
|
+
program6.parse();
|
|
2253
2618
|
export {
|
|
2254
2619
|
context
|
|
2255
2620
|
};
|