jsrepo 1.4.1 → 1.5.0
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 +210 -41
- package/package.json +4 -4
- package/src/commands/add.ts +1 -1
- package/src/commands/init.ts +226 -6
- package/src/commands/update.ts +1 -1
- package/src/utils/ascii.ts +2 -0
- package/src/utils/build.ts +9 -2
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import fs12 from "node:fs";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
-
import { program as
|
|
4
|
+
import { program as program7 } from "commander";
|
|
5
5
|
import path12 from "pathe";
|
|
6
6
|
|
|
7
7
|
// src/commands/add.ts
|
|
@@ -25,6 +25,7 @@ var TOP_LEFT_CORNER = color.gray("\u250C");
|
|
|
25
25
|
var BOTTOM_LEFT_CORNER = color.gray("\u2514");
|
|
26
26
|
var WARN = color.bgRgb(245, 149, 66).white("WARN");
|
|
27
27
|
var INFO = color.bgBlueBright.white("INFO");
|
|
28
|
+
var JSREPO = color.hex("#f7df1e")("jsrepo");
|
|
28
29
|
|
|
29
30
|
// src/utils/blocks.ts
|
|
30
31
|
import fs4 from "node:fs";
|
|
@@ -981,11 +982,17 @@ var buildBlocksDirectory = (blocksPath, { cwd, excludeDeps }) => {
|
|
|
981
982
|
const devDepsSet = /* @__PURE__ */ new Set();
|
|
982
983
|
for (const f of blockFiles) {
|
|
983
984
|
if (isTestFile(f)) continue;
|
|
985
|
+
if (fs3.statSync(path3.join(blockDir, f)).isDirectory()) {
|
|
986
|
+
console.warn(
|
|
987
|
+
`${VERTICAL_LINE} ${WARN} Skipped \`${color3.bold(path3.join(blockDir, f))}\` subdirectories are not currently supported!`
|
|
988
|
+
);
|
|
989
|
+
continue;
|
|
990
|
+
}
|
|
984
991
|
const lang = languages.find((resolver) => resolver.matches(f));
|
|
985
992
|
if (!lang) {
|
|
986
993
|
console.warn(
|
|
987
|
-
`${WARN} Skipped \`${color3.bold(path3.join(blockDir, f))}\`
|
|
988
|
-
path3.parse(
|
|
994
|
+
`${VERTICAL_LINE} ${WARN} Skipped \`${color3.bold(path3.join(blockDir, f))}\` \`*${color3.bold(
|
|
995
|
+
path3.parse(f).ext
|
|
989
996
|
)}\` files are not currently supported!`
|
|
990
997
|
);
|
|
991
998
|
continue;
|
|
@@ -1455,7 +1462,7 @@ var _add = async (blockNames, options) => {
|
|
|
1455
1462
|
(val) => val,
|
|
1456
1463
|
program2.error
|
|
1457
1464
|
);
|
|
1458
|
-
const pm = (await detect({ cwd:
|
|
1465
|
+
const pm = (await detect({ cwd: options.cwd }))?.agent ?? "npm";
|
|
1459
1466
|
const tasks = [];
|
|
1460
1467
|
const devDeps = /* @__PURE__ */ new Set();
|
|
1461
1468
|
const deps = /* @__PURE__ */ new Set();
|
|
@@ -2001,9 +2008,10 @@ ${prefix?.() ?? ""}
|
|
|
2001
2008
|
|
|
2002
2009
|
// src/commands/init.ts
|
|
2003
2010
|
import fs9 from "node:fs";
|
|
2004
|
-
import { cancel as cancel3, confirm as confirm3, isCancel as isCancel3, outro as outro4, spinner as spinner5, text } from "@clack/prompts";
|
|
2011
|
+
import { cancel as cancel3, confirm as confirm3, isCancel as isCancel3, outro as outro4, select, spinner as spinner5, text } from "@clack/prompts";
|
|
2005
2012
|
import color11 from "chalk";
|
|
2006
|
-
import { Command as Command4 } from "commander";
|
|
2013
|
+
import { Command as Command4, program as program4 } from "commander";
|
|
2014
|
+
import { detect as detect2, resolveCommand as resolveCommand3 } from "package-manager-detector";
|
|
2007
2015
|
import path9 from "pathe";
|
|
2008
2016
|
import * as v8 from "valibot";
|
|
2009
2017
|
var schema5 = v8.object({
|
|
@@ -2011,18 +2019,48 @@ var schema5 = v8.object({
|
|
|
2011
2019
|
repos: v8.optional(v8.array(v8.string())),
|
|
2012
2020
|
watermark: v8.boolean(),
|
|
2013
2021
|
tests: v8.optional(v8.boolean()),
|
|
2022
|
+
project: v8.optional(v8.boolean()),
|
|
2023
|
+
registry: v8.optional(v8.boolean()),
|
|
2024
|
+
script: v8.string(),
|
|
2025
|
+
yes: v8.boolean(),
|
|
2014
2026
|
cwd: v8.string()
|
|
2015
2027
|
});
|
|
2016
|
-
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(
|
|
2028
|
+
var init = new Command4("init").description("Initializes your project with a configuration file.").option("--path <path>", "Path to install the blocks / Path to build the blocks from.").option("--repos [repos...]", "Repository to install the blocks from.").option(
|
|
2017
2029
|
"--no-watermark",
|
|
2018
2030
|
"Will not add a watermark to each file upon adding it to your project."
|
|
2019
|
-
).option("--tests", "Will include tests with the blocks.").option("--cwd <path>", "The current working directory.", process.cwd()).action(async (opts) => {
|
|
2031
|
+
).option("--tests", "Will include tests with the blocks.").option("-P, --project", "Takes you through the steps to initialize a project.").option("-R, --registry", "Takes you through the steps to initialize a registry.").option("--script <name>", "The name of the build script. (For Registry setup)", "build").option("-y, --yes", "Skip confirmation prompt.", false).option("--cwd <path>", "The current working directory.", process.cwd()).action(async (opts) => {
|
|
2020
2032
|
const options = v8.parse(schema5, opts);
|
|
2021
2033
|
_intro(context.package.version);
|
|
2022
|
-
|
|
2034
|
+
if (options.registry !== void 0 && options.project !== void 0) {
|
|
2035
|
+
program4.error(
|
|
2036
|
+
color11.red(
|
|
2037
|
+
`You cannot provide both ${color11.bold("--project")} and ${color11.bold("--registry")} at the same time.`
|
|
2038
|
+
)
|
|
2039
|
+
);
|
|
2040
|
+
}
|
|
2041
|
+
if (options.registry === void 0 && options.project === void 0) {
|
|
2042
|
+
const response = await select({
|
|
2043
|
+
message: "Initialize a project or registry?",
|
|
2044
|
+
options: [
|
|
2045
|
+
{ value: "project", label: "project" },
|
|
2046
|
+
{ value: "registry", label: "registry" }
|
|
2047
|
+
],
|
|
2048
|
+
initialValue: "project"
|
|
2049
|
+
});
|
|
2050
|
+
if (isCancel3(response)) {
|
|
2051
|
+
cancel3("Canceled!");
|
|
2052
|
+
process.exit(0);
|
|
2053
|
+
}
|
|
2054
|
+
options.registry = response === "registry";
|
|
2055
|
+
}
|
|
2056
|
+
if (options.registry) {
|
|
2057
|
+
await _initRegistry(options);
|
|
2058
|
+
} else {
|
|
2059
|
+
await _initProject(options);
|
|
2060
|
+
}
|
|
2023
2061
|
outro4(color11.green("All done!"));
|
|
2024
2062
|
});
|
|
2025
|
-
var
|
|
2063
|
+
var _initProject = async (options) => {
|
|
2026
2064
|
const initialConfig = getConfig(options.cwd);
|
|
2027
2065
|
const loading = spinner5();
|
|
2028
2066
|
if (!options.path) {
|
|
@@ -2084,15 +2122,146 @@ var _init = async (options) => {
|
|
|
2084
2122
|
fs9.mkdirSync(path9.join(options.cwd, config.path), { recursive: true });
|
|
2085
2123
|
loading.stop(`Wrote config to \`${CONFIG_NAME}\`.`);
|
|
2086
2124
|
};
|
|
2125
|
+
var _initRegistry = async (options) => {
|
|
2126
|
+
const loading = spinner5();
|
|
2127
|
+
if (!options.path) {
|
|
2128
|
+
const response = await text({
|
|
2129
|
+
message: "Where are your blocks located?",
|
|
2130
|
+
defaultValue: "./blocks",
|
|
2131
|
+
initialValue: "./blocks",
|
|
2132
|
+
placeholder: "./blocks"
|
|
2133
|
+
});
|
|
2134
|
+
if (isCancel3(response)) {
|
|
2135
|
+
cancel3("Canceled!");
|
|
2136
|
+
process.exit(0);
|
|
2137
|
+
}
|
|
2138
|
+
options.path = response;
|
|
2139
|
+
}
|
|
2140
|
+
const packagePath = path9.join(options.cwd, "package.json");
|
|
2141
|
+
if (!fs9.existsSync(packagePath)) {
|
|
2142
|
+
program4.error(color11.red(`Couldn't find your ${color11.bold("package.json")}!`));
|
|
2143
|
+
}
|
|
2144
|
+
const pkg = JSON.parse(fs9.readFileSync(packagePath).toString());
|
|
2145
|
+
const scriptAlreadyExists = pkg.scripts !== void 0 && pkg.scripts[options.script] !== void 0;
|
|
2146
|
+
if (!options.yes && scriptAlreadyExists) {
|
|
2147
|
+
const response = await confirm3({
|
|
2148
|
+
message: `The \`${color11.cyan(options.script)}\` already exists overwrite?`,
|
|
2149
|
+
initialValue: false
|
|
2150
|
+
});
|
|
2151
|
+
if (isCancel3(response)) {
|
|
2152
|
+
cancel3("Canceled!");
|
|
2153
|
+
process.exit(0);
|
|
2154
|
+
}
|
|
2155
|
+
if (!response) {
|
|
2156
|
+
const response2 = await text({
|
|
2157
|
+
message: "What would you like to call the script?",
|
|
2158
|
+
defaultValue: "build:registry",
|
|
2159
|
+
placeholder: "build:registry",
|
|
2160
|
+
initialValue: "build:registry",
|
|
2161
|
+
validate: (val) => {
|
|
2162
|
+
if (val.trim().length === 0) return "Please provide a value!";
|
|
2163
|
+
}
|
|
2164
|
+
});
|
|
2165
|
+
if (isCancel3(response2)) {
|
|
2166
|
+
cancel3("Canceled!");
|
|
2167
|
+
process.exit(0);
|
|
2168
|
+
}
|
|
2169
|
+
options.script = response2;
|
|
2170
|
+
}
|
|
2171
|
+
}
|
|
2172
|
+
const alreadyInstalled = pkg.devDependencies && pkg.devDependencies.jsrepo !== void 0;
|
|
2173
|
+
let installAsDevDependency = options.yes || alreadyInstalled;
|
|
2174
|
+
if (!options.yes && !alreadyInstalled) {
|
|
2175
|
+
const response = await confirm3({
|
|
2176
|
+
message: `Add ${JSREPO} as a dev dependency?`,
|
|
2177
|
+
initialValue: true
|
|
2178
|
+
});
|
|
2179
|
+
if (isCancel3(response)) {
|
|
2180
|
+
cancel3("Canceled!");
|
|
2181
|
+
process.exit(0);
|
|
2182
|
+
}
|
|
2183
|
+
installAsDevDependency = response;
|
|
2184
|
+
}
|
|
2185
|
+
const pm = (await detect2({ cwd: "cwd" }))?.agent ?? "npm";
|
|
2186
|
+
let buildScript = "";
|
|
2187
|
+
if (installAsDevDependency) {
|
|
2188
|
+
buildScript += "jsrepo build ";
|
|
2189
|
+
} else {
|
|
2190
|
+
const command = resolveCommand3(pm, "execute", ["jsrepo", "build"]);
|
|
2191
|
+
if (!command) program4.error(color11.red(`Error resolving execute command for ${pm}`));
|
|
2192
|
+
buildScript += `${command.command} ${command.args.join(" ")} `;
|
|
2193
|
+
}
|
|
2194
|
+
if (options.path !== "./build") {
|
|
2195
|
+
buildScript += `--dirs ${options.path}`;
|
|
2196
|
+
}
|
|
2197
|
+
if (pkg.scripts === void 0) {
|
|
2198
|
+
pkg.scripts = {};
|
|
2199
|
+
}
|
|
2200
|
+
pkg.scripts[options.script] = buildScript;
|
|
2201
|
+
loading.start(`Adding \`${color11.cyan(options.script)}\` to scripts in package.json`);
|
|
2202
|
+
try {
|
|
2203
|
+
fs9.writeFileSync(packagePath, JSON.stringify(pkg, null, " "));
|
|
2204
|
+
} catch (err) {
|
|
2205
|
+
program4.error(color11.red(`Error writing to \`${color11.bold(packagePath)}\`. Error: ${err}`));
|
|
2206
|
+
}
|
|
2207
|
+
loading.stop(`Added \`${color11.cyan(options.script)}\` to scripts in package.json`);
|
|
2208
|
+
let installed = alreadyInstalled;
|
|
2209
|
+
if (installAsDevDependency && !alreadyInstalled) {
|
|
2210
|
+
let shouldInstall = options.yes;
|
|
2211
|
+
if (!options.yes) {
|
|
2212
|
+
const response = await confirm3({
|
|
2213
|
+
message: "Install dependencies?",
|
|
2214
|
+
initialValue: true
|
|
2215
|
+
});
|
|
2216
|
+
if (isCancel3(response)) {
|
|
2217
|
+
cancel3("Canceled!");
|
|
2218
|
+
process.exit(0);
|
|
2219
|
+
}
|
|
2220
|
+
shouldInstall = response;
|
|
2221
|
+
}
|
|
2222
|
+
if (shouldInstall) {
|
|
2223
|
+
loading.start(`Installing ${JSREPO}`);
|
|
2224
|
+
const installedResult = await installDependencies({
|
|
2225
|
+
pm,
|
|
2226
|
+
deps: ["jsrepo"],
|
|
2227
|
+
dev: true,
|
|
2228
|
+
cwd: options.cwd
|
|
2229
|
+
});
|
|
2230
|
+
installedResult.match(
|
|
2231
|
+
() => loading.stop(`Installed ${JSREPO}.`),
|
|
2232
|
+
(err) => {
|
|
2233
|
+
loading.stop(`Failed to install ${JSREPO}.`);
|
|
2234
|
+
program4.error(err);
|
|
2235
|
+
}
|
|
2236
|
+
);
|
|
2237
|
+
installed = true;
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2240
|
+
let steps = [];
|
|
2241
|
+
if (!installed && installAsDevDependency) {
|
|
2242
|
+
const cmd = resolveCommand3(pm, "install", ["jsrepo", "-D"]);
|
|
2243
|
+
steps.push(
|
|
2244
|
+
`Install ${JSREPO} as a dev dependency \`${color11.cyan(`${cmd?.command} ${cmd?.args.join(" ")}`)}\``
|
|
2245
|
+
);
|
|
2246
|
+
}
|
|
2247
|
+
steps.push(`Add blocks to \`${color11.cyan(options.path)}\`.`);
|
|
2248
|
+
const runScript = resolveCommand3(pm, "run", [options.script]);
|
|
2249
|
+
steps.push(
|
|
2250
|
+
`Run \`${color11.cyan(`${runScript?.command} ${runScript?.args.join(" ")}`)}\` to build the registry.`
|
|
2251
|
+
);
|
|
2252
|
+
steps = steps.map((step, i) => `${i + 1}. ${step}`);
|
|
2253
|
+
const next = nextSteps(steps);
|
|
2254
|
+
process.stdout.write(next);
|
|
2255
|
+
};
|
|
2087
2256
|
|
|
2088
2257
|
// src/commands/test.ts
|
|
2089
2258
|
import fs10 from "node:fs";
|
|
2090
2259
|
import { cancel as cancel4, confirm as confirm4, isCancel as isCancel4, outro as outro5, spinner as spinner6 } from "@clack/prompts";
|
|
2091
2260
|
import color12 from "chalk";
|
|
2092
|
-
import { Argument, Command as Command5, program as
|
|
2261
|
+
import { Argument, Command as Command5, program as program5 } from "commander";
|
|
2093
2262
|
import { execa as execa2 } from "execa";
|
|
2094
|
-
import { resolveCommand as
|
|
2095
|
-
import { detect as
|
|
2263
|
+
import { resolveCommand as resolveCommand4 } from "package-manager-detector/commands";
|
|
2264
|
+
import { detect as detect3 } from "package-manager-detector/detect";
|
|
2096
2265
|
import path10 from "pathe";
|
|
2097
2266
|
import { Project as Project2 } from "ts-morph";
|
|
2098
2267
|
import * as v9 from "valibot";
|
|
@@ -2118,7 +2287,7 @@ var _test = async (blockNames, options) => {
|
|
|
2118
2287
|
verbose(`Attempting to test ${JSON.stringify(blockNames)}`);
|
|
2119
2288
|
const config = getConfig(options.cwd).match(
|
|
2120
2289
|
(val) => val,
|
|
2121
|
-
(err) =>
|
|
2290
|
+
(err) => program5.error(color12.red(err))
|
|
2122
2291
|
);
|
|
2123
2292
|
const loading = spinner6();
|
|
2124
2293
|
const blocksMap = /* @__PURE__ */ new Map();
|
|
@@ -2139,14 +2308,14 @@ var _test = async (blockNames, options) => {
|
|
|
2139
2308
|
for (const repo of repoPaths) {
|
|
2140
2309
|
const providerInfo = (await getProviderInfo(repo)).match(
|
|
2141
2310
|
(info) => info,
|
|
2142
|
-
(err) =>
|
|
2311
|
+
(err) => program5.error(color12.red(err))
|
|
2143
2312
|
);
|
|
2144
2313
|
const manifestUrl = await providerInfo.provider.resolveRaw(providerInfo, OUTPUT_FILE);
|
|
2145
2314
|
verbose(`Got info for provider ${color12.cyan(providerInfo.name)}`);
|
|
2146
2315
|
const response = await fetch(manifestUrl);
|
|
2147
2316
|
if (!response.ok) {
|
|
2148
2317
|
if (!options.verbose) loading.stop(`Error fetching ${color12.cyan(manifestUrl.href)}`);
|
|
2149
|
-
|
|
2318
|
+
program5.error(
|
|
2150
2319
|
color12.red(
|
|
2151
2320
|
`There was an error fetching the \`${OUTPUT_FILE}\` from the repository ${color12.cyan(
|
|
2152
2321
|
repo
|
|
@@ -2186,7 +2355,7 @@ var _test = async (blockNames, options) => {
|
|
|
2186
2355
|
}
|
|
2187
2356
|
if (testingBlocks.length === 0) {
|
|
2188
2357
|
cleanUp();
|
|
2189
|
-
|
|
2358
|
+
program5.error(color12.red("There were no blocks found in your project!"));
|
|
2190
2359
|
}
|
|
2191
2360
|
const testingBlocksMapped = [];
|
|
2192
2361
|
for (const blockSpecifier of testingBlocks) {
|
|
@@ -2212,7 +2381,7 @@ var _test = async (blockNames, options) => {
|
|
|
2212
2381
|
}
|
|
2213
2382
|
const providerInfo = (await getProviderInfo(repo)).match(
|
|
2214
2383
|
(val) => val,
|
|
2215
|
-
(err) =>
|
|
2384
|
+
(err) => program5.error(color12.red(err))
|
|
2216
2385
|
);
|
|
2217
2386
|
const manifestUrl = await providerInfo.provider.resolveRaw(
|
|
2218
2387
|
providerInfo,
|
|
@@ -2220,7 +2389,7 @@ var _test = async (blockNames, options) => {
|
|
|
2220
2389
|
);
|
|
2221
2390
|
const categories = (await getManifest(manifestUrl)).match(
|
|
2222
2391
|
(val) => val,
|
|
2223
|
-
(err) =>
|
|
2392
|
+
(err) => program5.error(color12.red(err))
|
|
2224
2393
|
);
|
|
2225
2394
|
for (const category of categories) {
|
|
2226
2395
|
for (const block2 of category.blocks) {
|
|
@@ -2237,7 +2406,7 @@ var _test = async (blockNames, options) => {
|
|
|
2237
2406
|
block = blocksMap.get(blockSpecifier);
|
|
2238
2407
|
}
|
|
2239
2408
|
if (!block) {
|
|
2240
|
-
|
|
2409
|
+
program5.error(
|
|
2241
2410
|
color12.red(`Invalid block! ${color12.bold(blockSpecifier)} does not exist!`)
|
|
2242
2411
|
);
|
|
2243
2412
|
}
|
|
@@ -2257,7 +2426,7 @@ var _test = async (blockNames, options) => {
|
|
|
2257
2426
|
const response = await fetch(rawUrl);
|
|
2258
2427
|
if (!response.ok) {
|
|
2259
2428
|
loading.stop(color12.red(`Error fetching ${color12.bold(rawUrl.href)}`));
|
|
2260
|
-
|
|
2429
|
+
program5.error(color12.red(`There was an error trying to get ${specifier}`));
|
|
2261
2430
|
}
|
|
2262
2431
|
return await response.text();
|
|
2263
2432
|
};
|
|
@@ -2306,13 +2475,13 @@ var _test = async (blockNames, options) => {
|
|
|
2306
2475
|
}
|
|
2307
2476
|
}
|
|
2308
2477
|
verbose("Beginning testing");
|
|
2309
|
-
const pm = await
|
|
2478
|
+
const pm = await detect3({ cwd: options.cwd });
|
|
2310
2479
|
if (pm == null) {
|
|
2311
|
-
|
|
2480
|
+
program5.error(color12.red("Could not detect package manager"));
|
|
2312
2481
|
}
|
|
2313
|
-
const resolved =
|
|
2482
|
+
const resolved = resolveCommand4(pm.agent, "execute", ["vitest", "run", tempTestDirectory]);
|
|
2314
2483
|
if (resolved == null) {
|
|
2315
|
-
|
|
2484
|
+
program5.error(color12.red(`Could not resolve add command for '${pm.agent}'.`));
|
|
2316
2485
|
}
|
|
2317
2486
|
const { command, args } = resolved;
|
|
2318
2487
|
const testCommand = `${command} ${args.join(" ")}`;
|
|
@@ -2337,7 +2506,7 @@ var _test = async (blockNames, options) => {
|
|
|
2337
2506
|
} else {
|
|
2338
2507
|
cleanUp();
|
|
2339
2508
|
}
|
|
2340
|
-
|
|
2509
|
+
program5.error(color12.red(`Tests failed! Error ${err}`));
|
|
2341
2510
|
}
|
|
2342
2511
|
};
|
|
2343
2512
|
|
|
@@ -2345,10 +2514,10 @@ var _test = async (blockNames, options) => {
|
|
|
2345
2514
|
import fs11 from "node:fs";
|
|
2346
2515
|
import { cancel as cancel5, confirm as confirm5, isCancel as isCancel5, multiselect as multiselect2, outro as outro6, spinner as spinner7 } from "@clack/prompts";
|
|
2347
2516
|
import color13 from "chalk";
|
|
2348
|
-
import { Command as Command6, program as
|
|
2517
|
+
import { Command as Command6, program as program6 } from "commander";
|
|
2349
2518
|
import { diffLines as diffLines2 } from "diff";
|
|
2350
|
-
import { resolveCommand as
|
|
2351
|
-
import { detect as
|
|
2519
|
+
import { resolveCommand as resolveCommand5 } from "package-manager-detector/commands";
|
|
2520
|
+
import { detect as detect4 } from "package-manager-detector/detect";
|
|
2352
2521
|
import path11 from "pathe";
|
|
2353
2522
|
import * as v10 from "valibot";
|
|
2354
2523
|
var schema7 = v10.object({
|
|
@@ -2383,13 +2552,13 @@ var _update = async (blockNames, options) => {
|
|
|
2383
2552
|
const loading = spinner7();
|
|
2384
2553
|
const config = getConfig(options.cwd).match(
|
|
2385
2554
|
(val) => val,
|
|
2386
|
-
(err) =>
|
|
2555
|
+
(err) => program6.error(color13.red(err))
|
|
2387
2556
|
);
|
|
2388
2557
|
let repoPaths = config.repos;
|
|
2389
2558
|
if (options.repo) repoPaths = [options.repo];
|
|
2390
2559
|
for (const blockSpecifier of blockNames) {
|
|
2391
2560
|
if (blockSpecifier.startsWith("github")) {
|
|
2392
|
-
|
|
2561
|
+
program6.error(
|
|
2393
2562
|
color13.red(
|
|
2394
2563
|
`Invalid value provided for block names \`${color13.bold(blockSpecifier)}\`. Block names are expected to be provided in the format of \`${color13.bold("<category>/<name>")}\``
|
|
2395
2564
|
)
|
|
@@ -2412,7 +2581,7 @@ var _update = async (blockNames, options) => {
|
|
|
2412
2581
|
(val) => val,
|
|
2413
2582
|
({ repo, message }) => {
|
|
2414
2583
|
loading.stop(`Failed fetching blocks from ${color13.cyan(repo)}`);
|
|
2415
|
-
|
|
2584
|
+
program6.error(color13.red(message));
|
|
2416
2585
|
}
|
|
2417
2586
|
);
|
|
2418
2587
|
if (!options.verbose) loading.stop(`Retrieved blocks from ${color13.cyan(repoPaths.join(", "))}`);
|
|
@@ -2442,9 +2611,9 @@ var _update = async (blockNames, options) => {
|
|
|
2442
2611
|
verbose(`Preparing to update ${color13.cyan(updatingBlockNames.join(", "))}`);
|
|
2443
2612
|
const updatingBlocks = (await resolveTree(updatingBlockNames, blocksMap, repoPaths)).match(
|
|
2444
2613
|
(val) => val,
|
|
2445
|
-
|
|
2614
|
+
program6.error
|
|
2446
2615
|
);
|
|
2447
|
-
const pm = (await
|
|
2616
|
+
const pm = (await detect4({ cwd: options.cwd }))?.agent ?? "npm";
|
|
2448
2617
|
const tasks = [];
|
|
2449
2618
|
const devDeps = /* @__PURE__ */ new Set();
|
|
2450
2619
|
const deps = /* @__PURE__ */ new Set();
|
|
@@ -2460,7 +2629,7 @@ var _update = async (blockNames, options) => {
|
|
|
2460
2629
|
const response = await fetch(rawUrl);
|
|
2461
2630
|
if (!response.ok) {
|
|
2462
2631
|
loading.stop(color13.red(`Error fetching ${color13.bold(rawUrl.href)}`));
|
|
2463
|
-
|
|
2632
|
+
program6.error(color13.red(`There was an error trying to get ${fullSpecifier}`));
|
|
2464
2633
|
}
|
|
2465
2634
|
return await response.text();
|
|
2466
2635
|
};
|
|
@@ -2603,7 +2772,7 @@ ${prefix?.() ?? ""}
|
|
|
2603
2772
|
},
|
|
2604
2773
|
(err) => {
|
|
2605
2774
|
if (!options.verbose) loading.stop("Failed to install dependencies");
|
|
2606
|
-
|
|
2775
|
+
program6.error(err);
|
|
2607
2776
|
}
|
|
2608
2777
|
);
|
|
2609
2778
|
}
|
|
@@ -2622,7 +2791,7 @@ ${prefix?.() ?? ""}
|
|
|
2622
2791
|
},
|
|
2623
2792
|
(err) => {
|
|
2624
2793
|
if (!options.verbose) loading.stop("Failed to install dev dependencies");
|
|
2625
|
-
|
|
2794
|
+
program6.error(err);
|
|
2626
2795
|
}
|
|
2627
2796
|
);
|
|
2628
2797
|
}
|
|
@@ -2630,13 +2799,13 @@ ${prefix?.() ?? ""}
|
|
|
2630
2799
|
let steps = [];
|
|
2631
2800
|
if (!install) {
|
|
2632
2801
|
if (deps.size > 0) {
|
|
2633
|
-
const cmd =
|
|
2802
|
+
const cmd = resolveCommand5(pm, "install", [...deps]);
|
|
2634
2803
|
steps.push(
|
|
2635
2804
|
`Install dependencies \`${color13.cyan(`${cmd?.command} ${cmd?.args.join(" ")}`)}\``
|
|
2636
2805
|
);
|
|
2637
2806
|
}
|
|
2638
2807
|
if (devDeps.size > 0) {
|
|
2639
|
-
const cmd =
|
|
2808
|
+
const cmd = resolveCommand5(pm, "install", [...devDeps, "-D"]);
|
|
2640
2809
|
steps.push(
|
|
2641
2810
|
`Install dev dependencies \`${color13.cyan(`${cmd?.command} ${cmd?.args.join(" ")}`)}\``
|
|
2642
2811
|
);
|
|
@@ -2669,8 +2838,8 @@ var context = {
|
|
|
2669
2838
|
},
|
|
2670
2839
|
resolveRelativeToRoot
|
|
2671
2840
|
};
|
|
2672
|
-
|
|
2673
|
-
|
|
2841
|
+
program7.name(name).description(description).version(version).addCommand(add).addCommand(init).addCommand(test).addCommand(build).addCommand(update).addCommand(diff);
|
|
2842
|
+
program7.parse();
|
|
2674
2843
|
export {
|
|
2675
2844
|
context
|
|
2676
2845
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jsrepo",
|
|
3
3
|
"description": "A CLI to add shared code from remote repositories.",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.5.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/ieedan/jsrepo"
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
"@types/node": "^22.9.0",
|
|
35
35
|
"@types/validate-npm-package-name": "^4.0.2",
|
|
36
36
|
"tsup": "^8.3.5",
|
|
37
|
-
"typescript": "^5.
|
|
37
|
+
"typescript": "^5.7.2",
|
|
38
38
|
"vitest": "^2.1.5"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@clack/prompts": "^0.8.
|
|
41
|
+
"@clack/prompts": "^0.8.2",
|
|
42
42
|
"@vue/compiler-sfc": "^3.5.13",
|
|
43
43
|
"ansi-regex": "^6.1.0",
|
|
44
44
|
"chalk": "^5.3.0",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"octokit": "^4.0.2",
|
|
50
50
|
"package-manager-detector": "^0.2.4",
|
|
51
51
|
"pathe": "^1.1.2",
|
|
52
|
-
"svelte": "^5.2.
|
|
52
|
+
"svelte": "^5.2.7",
|
|
53
53
|
"ts-morph": "^24.0.0",
|
|
54
54
|
"valibot": "^0.42.1",
|
|
55
55
|
"validate-npm-package-name": "^6.0.0"
|
package/src/commands/add.ts
CHANGED
|
@@ -194,7 +194,7 @@ const _add = async (blockNames: string[], options: Options) => {
|
|
|
194
194
|
program.error
|
|
195
195
|
);
|
|
196
196
|
|
|
197
|
-
const pm = (await detect({ cwd:
|
|
197
|
+
const pm = (await detect({ cwd: options.cwd }))?.agent ?? 'npm';
|
|
198
198
|
|
|
199
199
|
const tasks: Task[] = [];
|
|
200
200
|
|
package/src/commands/init.ts
CHANGED
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
|
-
import { cancel, confirm, isCancel, outro, spinner, text } from '@clack/prompts';
|
|
2
|
+
import { cancel, confirm, isCancel, outro, select, spinner, text } from '@clack/prompts';
|
|
3
3
|
import color from 'chalk';
|
|
4
|
-
import { Command } from 'commander';
|
|
4
|
+
import { Command, program } from 'commander';
|
|
5
|
+
import { detect, resolveCommand } from 'package-manager-detector';
|
|
5
6
|
import path from 'pathe';
|
|
6
7
|
import * as v from 'valibot';
|
|
7
8
|
import { context } from '..';
|
|
9
|
+
import * as ascii from '../utils/ascii';
|
|
8
10
|
import { CONFIG_NAME, type Config, getConfig } from '../utils/config';
|
|
9
|
-
import {
|
|
11
|
+
import { installDependencies } from '../utils/dependencies';
|
|
12
|
+
import { intro, nextSteps } from '../utils/prompts';
|
|
10
13
|
|
|
11
14
|
const schema = v.object({
|
|
12
15
|
path: v.optional(v.string()),
|
|
13
16
|
repos: v.optional(v.array(v.string())),
|
|
14
17
|
watermark: v.boolean(),
|
|
15
18
|
tests: v.optional(v.boolean()),
|
|
19
|
+
project: v.optional(v.boolean()),
|
|
20
|
+
registry: v.optional(v.boolean()),
|
|
21
|
+
script: v.string(),
|
|
22
|
+
yes: v.boolean(),
|
|
16
23
|
cwd: v.string(),
|
|
17
24
|
});
|
|
18
25
|
|
|
@@ -20,25 +27,59 @@ type Options = v.InferInput<typeof schema>;
|
|
|
20
27
|
|
|
21
28
|
const init = new Command('init')
|
|
22
29
|
.description('Initializes your project with a configuration file.')
|
|
23
|
-
.option('--path <path>', 'Path to install the blocks.')
|
|
30
|
+
.option('--path <path>', 'Path to install the blocks / Path to build the blocks from.')
|
|
24
31
|
.option('--repos [repos...]', 'Repository to install the blocks from.')
|
|
25
32
|
.option(
|
|
26
33
|
'--no-watermark',
|
|
27
34
|
'Will not add a watermark to each file upon adding it to your project.'
|
|
28
35
|
)
|
|
29
36
|
.option('--tests', 'Will include tests with the blocks.')
|
|
37
|
+
.option('-P, --project', 'Takes you through the steps to initialize a project.')
|
|
38
|
+
.option('-R, --registry', 'Takes you through the steps to initialize a registry.')
|
|
39
|
+
.option('--script <name>', 'The name of the build script. (For Registry setup)', 'build')
|
|
40
|
+
.option('-y, --yes', 'Skip confirmation prompt.', false)
|
|
30
41
|
.option('--cwd <path>', 'The current working directory.', process.cwd())
|
|
31
42
|
.action(async (opts) => {
|
|
32
43
|
const options = v.parse(schema, opts);
|
|
33
44
|
|
|
34
45
|
intro(context.package.version);
|
|
35
46
|
|
|
36
|
-
|
|
47
|
+
if (options.registry !== undefined && options.project !== undefined) {
|
|
48
|
+
program.error(
|
|
49
|
+
color.red(
|
|
50
|
+
`You cannot provide both ${color.bold('--project')} and ${color.bold('--registry')} at the same time.`
|
|
51
|
+
)
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (options.registry === undefined && options.project === undefined) {
|
|
56
|
+
const response = await select({
|
|
57
|
+
message: 'Initialize a project or registry?',
|
|
58
|
+
options: [
|
|
59
|
+
{ value: 'project', label: 'project' },
|
|
60
|
+
{ value: 'registry', label: 'registry' },
|
|
61
|
+
],
|
|
62
|
+
initialValue: 'project',
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
if (isCancel(response)) {
|
|
66
|
+
cancel('Canceled!');
|
|
67
|
+
process.exit(0);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
options.registry = response === 'registry';
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (options.registry) {
|
|
74
|
+
await _initRegistry(options);
|
|
75
|
+
} else {
|
|
76
|
+
await _initProject(options);
|
|
77
|
+
}
|
|
37
78
|
|
|
38
79
|
outro(color.green('All done!'));
|
|
39
80
|
});
|
|
40
81
|
|
|
41
|
-
const
|
|
82
|
+
const _initProject = async (options: Options) => {
|
|
42
83
|
const initialConfig = getConfig(options.cwd);
|
|
43
84
|
|
|
44
85
|
const loading = spinner();
|
|
@@ -118,4 +159,183 @@ const _init = async (options: Options) => {
|
|
|
118
159
|
loading.stop(`Wrote config to \`${CONFIG_NAME}\`.`);
|
|
119
160
|
};
|
|
120
161
|
|
|
162
|
+
const _initRegistry = async (options: Options) => {
|
|
163
|
+
const loading = spinner();
|
|
164
|
+
|
|
165
|
+
if (!options.path) {
|
|
166
|
+
const response = await text({
|
|
167
|
+
message: 'Where are your blocks located?',
|
|
168
|
+
defaultValue: './blocks',
|
|
169
|
+
initialValue: './blocks',
|
|
170
|
+
placeholder: './blocks',
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
if (isCancel(response)) {
|
|
174
|
+
cancel('Canceled!');
|
|
175
|
+
process.exit(0);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
options.path = response;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const packagePath = path.join(options.cwd, 'package.json');
|
|
182
|
+
|
|
183
|
+
if (!fs.existsSync(packagePath)) {
|
|
184
|
+
program.error(color.red(`Couldn't find your ${color.bold('package.json')}!`));
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const pkg = JSON.parse(fs.readFileSync(packagePath).toString());
|
|
188
|
+
|
|
189
|
+
const scriptAlreadyExists =
|
|
190
|
+
pkg.scripts !== undefined && pkg.scripts[options.script] !== undefined;
|
|
191
|
+
|
|
192
|
+
if (!options.yes && scriptAlreadyExists) {
|
|
193
|
+
const response = await confirm({
|
|
194
|
+
message: `The \`${color.cyan(options.script)}\` already exists overwrite?`,
|
|
195
|
+
initialValue: false,
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
if (isCancel(response)) {
|
|
199
|
+
cancel('Canceled!');
|
|
200
|
+
process.exit(0);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (!response) {
|
|
204
|
+
const response = await text({
|
|
205
|
+
message: 'What would you like to call the script?',
|
|
206
|
+
defaultValue: 'build:registry',
|
|
207
|
+
placeholder: 'build:registry',
|
|
208
|
+
initialValue: 'build:registry',
|
|
209
|
+
validate: (val) => {
|
|
210
|
+
if (val.trim().length === 0) return 'Please provide a value!';
|
|
211
|
+
},
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
if (isCancel(response)) {
|
|
215
|
+
cancel('Canceled!');
|
|
216
|
+
process.exit(0);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
options.script = response;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const alreadyInstalled = pkg.devDependencies && pkg.devDependencies.jsrepo !== undefined;
|
|
224
|
+
|
|
225
|
+
let installAsDevDependency = options.yes || alreadyInstalled;
|
|
226
|
+
|
|
227
|
+
if (!options.yes && !alreadyInstalled) {
|
|
228
|
+
const response = await confirm({
|
|
229
|
+
message: `Add ${ascii.JSREPO} as a dev dependency?`,
|
|
230
|
+
initialValue: true,
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
if (isCancel(response)) {
|
|
234
|
+
cancel('Canceled!');
|
|
235
|
+
process.exit(0);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
installAsDevDependency = response;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const pm = (await detect({ cwd: 'cwd' }))?.agent ?? 'npm';
|
|
242
|
+
|
|
243
|
+
let buildScript = '';
|
|
244
|
+
|
|
245
|
+
if (installAsDevDependency) {
|
|
246
|
+
buildScript += 'jsrepo build ';
|
|
247
|
+
} else {
|
|
248
|
+
const command = resolveCommand(pm, 'execute', ['jsrepo', 'build']);
|
|
249
|
+
|
|
250
|
+
if (!command) program.error(color.red(`Error resolving execute command for ${pm}`));
|
|
251
|
+
|
|
252
|
+
buildScript += `${command.command} ${command.args.join(' ')} `;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (options.path !== './build') {
|
|
256
|
+
buildScript += `--dirs ${options.path}`;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (pkg.scripts === undefined) {
|
|
260
|
+
pkg.scripts = {};
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
pkg.scripts[options.script] = buildScript;
|
|
264
|
+
|
|
265
|
+
loading.start(`Adding \`${color.cyan(options.script)}\` to scripts in package.json`);
|
|
266
|
+
|
|
267
|
+
try {
|
|
268
|
+
fs.writeFileSync(packagePath, JSON.stringify(pkg, null, '\t'));
|
|
269
|
+
} catch (err) {
|
|
270
|
+
program.error(color.red(`Error writing to \`${color.bold(packagePath)}\`. Error: ${err}`));
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
loading.stop(`Added \`${color.cyan(options.script)}\` to scripts in package.json`);
|
|
274
|
+
|
|
275
|
+
let installed = alreadyInstalled;
|
|
276
|
+
|
|
277
|
+
if (installAsDevDependency && !alreadyInstalled) {
|
|
278
|
+
let shouldInstall = options.yes;
|
|
279
|
+
if (!options.yes) {
|
|
280
|
+
const response = await confirm({
|
|
281
|
+
message: 'Install dependencies?',
|
|
282
|
+
initialValue: true,
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
if (isCancel(response)) {
|
|
286
|
+
cancel('Canceled!');
|
|
287
|
+
process.exit(0);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
shouldInstall = response;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (shouldInstall) {
|
|
294
|
+
loading.start(`Installing ${ascii.JSREPO}`);
|
|
295
|
+
|
|
296
|
+
const installedResult = await installDependencies({
|
|
297
|
+
pm,
|
|
298
|
+
deps: ['jsrepo'],
|
|
299
|
+
dev: true,
|
|
300
|
+
cwd: options.cwd,
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
installedResult.match(
|
|
304
|
+
() => loading.stop(`Installed ${ascii.JSREPO}.`),
|
|
305
|
+
(err) => {
|
|
306
|
+
loading.stop(`Failed to install ${ascii.JSREPO}.`);
|
|
307
|
+
program.error(err);
|
|
308
|
+
}
|
|
309
|
+
);
|
|
310
|
+
|
|
311
|
+
installed = true;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
let steps: string[] = [];
|
|
316
|
+
|
|
317
|
+
if (!installed && installAsDevDependency) {
|
|
318
|
+
const cmd = resolveCommand(pm, 'install', ['jsrepo', '-D']);
|
|
319
|
+
|
|
320
|
+
steps.push(
|
|
321
|
+
`Install ${ascii.JSREPO} as a dev dependency \`${color.cyan(`${cmd?.command} ${cmd?.args.join(' ')}`)}\``
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
steps.push(`Add blocks to \`${color.cyan(options.path)}\`.`);
|
|
326
|
+
|
|
327
|
+
const runScript = resolveCommand(pm, 'run', [options.script]);
|
|
328
|
+
|
|
329
|
+
steps.push(
|
|
330
|
+
`Run \`${color.cyan(`${runScript?.command} ${runScript?.args.join(' ')}`)}\` to build the registry.`
|
|
331
|
+
);
|
|
332
|
+
|
|
333
|
+
// put steps with numbers above here
|
|
334
|
+
steps = steps.map((step, i) => `${i + 1}. ${step}`);
|
|
335
|
+
|
|
336
|
+
const next = nextSteps(steps);
|
|
337
|
+
|
|
338
|
+
process.stdout.write(next);
|
|
339
|
+
};
|
|
340
|
+
|
|
121
341
|
export { init };
|
package/src/commands/update.ts
CHANGED
|
@@ -156,7 +156,7 @@ const _update = async (blockNames: string[], options: Options) => {
|
|
|
156
156
|
program.error
|
|
157
157
|
);
|
|
158
158
|
|
|
159
|
-
const pm = (await detect({ cwd:
|
|
159
|
+
const pm = (await detect({ cwd: options.cwd }))?.agent ?? 'npm';
|
|
160
160
|
|
|
161
161
|
const tasks: Task[] = [];
|
|
162
162
|
|
package/src/utils/ascii.ts
CHANGED
package/src/utils/build.ts
CHANGED
|
@@ -138,12 +138,19 @@ const buildBlocksDirectory = (blocksPath: string, { cwd, excludeDeps }: Options)
|
|
|
138
138
|
for (const f of blockFiles) {
|
|
139
139
|
if (isTestFile(f)) continue;
|
|
140
140
|
|
|
141
|
+
if (fs.statSync(path.join(blockDir, f)).isDirectory()) {
|
|
142
|
+
console.warn(
|
|
143
|
+
`${ascii.VERTICAL_LINE} ${ascii.WARN} Skipped \`${color.bold(path.join(blockDir, f))}\` subdirectories are not currently supported!`
|
|
144
|
+
);
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
|
|
141
148
|
const lang = languages.find((resolver) => resolver.matches(f));
|
|
142
149
|
|
|
143
150
|
if (!lang) {
|
|
144
151
|
console.warn(
|
|
145
|
-
`${ascii.WARN} Skipped \`${color.bold(path.join(blockDir, f))}\`
|
|
146
|
-
path.parse(
|
|
152
|
+
`${ascii.VERTICAL_LINE} ${ascii.WARN} Skipped \`${color.bold(path.join(blockDir, f))}\` \`*${color.bold(
|
|
153
|
+
path.parse(f).ext
|
|
147
154
|
)}\` files are not currently supported!`
|
|
148
155
|
);
|
|
149
156
|
continue;
|