@freecodecamp/universe-cli 0.12.0 → 0.13.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.cjs +162 -59
- package/package.json +30 -27
package/dist/index.cjs
CHANGED
|
@@ -9609,7 +9609,7 @@ var require_public_api = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
9609
9609
|
exports.stringify = stringify;
|
|
9610
9610
|
}));
|
|
9611
9611
|
//#endregion
|
|
9612
|
-
//#region src/commands/create/layer-composition/build-compose-
|
|
9612
|
+
//#region src/commands/create/layer-composition/build-compose-yaml.ts
|
|
9613
9613
|
var import_dist = (/* @__PURE__ */ __commonJSMin(((exports) => {
|
|
9614
9614
|
var composer = require_composer();
|
|
9615
9615
|
var Document = require_Document();
|
|
@@ -9656,7 +9656,7 @@ var import_dist = (/* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
9656
9656
|
exports.visit = visit.visit;
|
|
9657
9657
|
exports.visitAsync = visit.visitAsync;
|
|
9658
9658
|
})))();
|
|
9659
|
-
const
|
|
9659
|
+
const buildComposeYaml = (framework, packageManager) => {
|
|
9660
9660
|
const { port } = framework;
|
|
9661
9661
|
const portMapping = `${port}:${port}`;
|
|
9662
9662
|
const syncEntries = framework.watchSync.map((entry) => ({
|
|
@@ -9677,6 +9677,28 @@ const buildComposeDevYaml = (framework, packageManager) => {
|
|
|
9677
9677
|
ports: [portMapping]
|
|
9678
9678
|
} } });
|
|
9679
9679
|
};
|
|
9680
|
+
const buildDevcontainerComposeYaml = () => `services:
|
|
9681
|
+
devcontainer:
|
|
9682
|
+
build:
|
|
9683
|
+
context: ..
|
|
9684
|
+
target: dev
|
|
9685
|
+
command: ["sleep", "infinity"]
|
|
9686
|
+
volumes:
|
|
9687
|
+
# First mount the source
|
|
9688
|
+
- type: bind
|
|
9689
|
+
source: ..
|
|
9690
|
+
target: /app
|
|
9691
|
+
consistency: cached
|
|
9692
|
+
# Then mount an anonymous volume to hold node_modules. Otherwise the bind mount causes the host node_modules to be used.
|
|
9693
|
+
- type: volume
|
|
9694
|
+
target: /app/node_modules
|
|
9695
|
+
`;
|
|
9696
|
+
const buildDevcontainerJson = () => `{
|
|
9697
|
+
"$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.schema.json",
|
|
9698
|
+
"dockerComposeFile": ["./docker-compose.yml"],
|
|
9699
|
+
"service": "devcontainer",
|
|
9700
|
+
"workspaceFolder": "/app"
|
|
9701
|
+
}`;
|
|
9680
9702
|
//#endregion
|
|
9681
9703
|
//#region src/output/exit-codes.ts
|
|
9682
9704
|
/**
|
|
@@ -9804,7 +9826,7 @@ const composeLayerFiles = (layers, pmPreinstall) => {
|
|
|
9804
9826
|
//#region src/commands/create/layer-composition/layer-template-renderer.ts
|
|
9805
9827
|
var LayerTemplateRenderer = class {
|
|
9806
9828
|
render(template, context) {
|
|
9807
|
-
return template.replaceAll("{{name}}", context.name).replaceAll("{{port}}", String(context.port)).replaceAll("{{runtime}}", context.runtime).replaceAll("{{framework}}", context.framework);
|
|
9829
|
+
return template.replaceAll("{{name}}", context.name).replaceAll("{{port}}", String(context.port)).replaceAll("{{runtime}}", context.runtime).replaceAll("{{framework}}", context.framework).replaceAll("{{pmVersion}}", context.pmVersion);
|
|
9808
9830
|
}
|
|
9809
9831
|
};
|
|
9810
9832
|
//#endregion
|
|
@@ -9864,23 +9886,24 @@ const buildDockerfileData = (runtime, framework, packageManager) => {
|
|
|
9864
9886
|
const renderDockerfile = (data) => `FROM ${data.baseImage} AS base\nWORKDIR /app\n\nFROM base AS package-manager\n${data.pmInstall} \n\nFROM package-manager AS dev\n${data.devInstall}\n${data.devCopySource}\nCMD ${JSON.stringify(data.devCmd)}\n`;
|
|
9865
9887
|
const resolveWithLayers = (input, layers, labels) => {
|
|
9866
9888
|
const resolvedLayers = resolveOrderedLayers(input, layers);
|
|
9867
|
-
const
|
|
9889
|
+
const pmData = input.packageManager !== void 0 ? layers["package-managers"][input.packageManager] : void 0;
|
|
9890
|
+
const composedFiles = composeLayerFiles(resolvedLayers, pmData?.preinstall);
|
|
9868
9891
|
const renderer = new LayerTemplateRenderer();
|
|
9869
9892
|
const frameworkData = layers.frameworks?.[input.framework];
|
|
9870
9893
|
const context = {
|
|
9871
9894
|
framework: getLabel(labels, "framework", input.framework),
|
|
9872
9895
|
name: input.name,
|
|
9896
|
+
pmVersion: pmData?.pmVersion ?? "",
|
|
9873
9897
|
port: frameworkData?.port ?? 0,
|
|
9874
9898
|
runtime: getLabel(labels, "runtime", input.runtime)
|
|
9875
9899
|
};
|
|
9876
9900
|
const renderedFiles = Object.fromEntries(Object.entries(composedFiles).map(([filePath, content]) => [filePath, renderer.render(content, context)]));
|
|
9877
9901
|
const runtimeData = layers.runtime?.[input.runtime];
|
|
9878
|
-
if (runtimeData !== void 0 && frameworkData !== void 0 &&
|
|
9879
|
-
|
|
9880
|
-
|
|
9881
|
-
|
|
9882
|
-
|
|
9883
|
-
}
|
|
9902
|
+
if (runtimeData !== void 0 && frameworkData !== void 0 && pmData !== void 0) {
|
|
9903
|
+
renderedFiles["Dockerfile"] = renderer.render(renderDockerfile(buildDockerfileData(runtimeData, frameworkData, pmData)), context);
|
|
9904
|
+
renderedFiles["compose.yaml"] = renderer.render(buildComposeYaml(frameworkData, pmData), context);
|
|
9905
|
+
renderedFiles[".devcontainer/docker-compose.yml"] = buildDevcontainerComposeYaml();
|
|
9906
|
+
renderedFiles[".devcontainer/devcontainer.json"] = buildDevcontainerJson();
|
|
9884
9907
|
}
|
|
9885
9908
|
return {
|
|
9886
9909
|
files: renderedFiles,
|
|
@@ -9905,10 +9928,10 @@ var PackageManagerService = class {
|
|
|
9905
9928
|
this.adapters = adapters;
|
|
9906
9929
|
}
|
|
9907
9930
|
async specifyDeps(options) {
|
|
9908
|
-
const { manager, projectDirectory } = options;
|
|
9931
|
+
const { manager, pmVersion, projectDirectory } = options;
|
|
9909
9932
|
const adapter = this.adapters[manager];
|
|
9910
9933
|
if (!adapter) throw new Error(`Unknown package manager: ${manager}`);
|
|
9911
|
-
await adapter.specifyDeps(projectDirectory);
|
|
9934
|
+
await adapter.specifyDeps(projectDirectory, pmVersion);
|
|
9912
9935
|
}
|
|
9913
9936
|
};
|
|
9914
9937
|
//#endregion
|
|
@@ -9933,7 +9956,7 @@ Please check that the output format of list() has not changed, and that extractV
|
|
|
9933
9956
|
if (devDependencies !== void 0) pinned.devDependencies = pin(devDependencies);
|
|
9934
9957
|
return pinned;
|
|
9935
9958
|
};
|
|
9936
|
-
const createPackageSpecifier = (config) => ({ async
|
|
9959
|
+
const createPackageSpecifier = (config) => ({ async run(projectDirectory) {
|
|
9937
9960
|
const { lockfileName, runner, deleteBeforeFirstInstall } = config;
|
|
9938
9961
|
const lockfilePath = (0, node_path.join)(projectDirectory, lockfileName);
|
|
9939
9962
|
if (deleteBeforeFirstInstall) try {
|
|
@@ -9965,11 +9988,11 @@ const createPackageSpecifier = (config) => ({ async specifyDeps(projectDirectory
|
|
|
9965
9988
|
} });
|
|
9966
9989
|
//#endregion
|
|
9967
9990
|
//#region src/commands/create/package-manager/docker-runner.ts
|
|
9968
|
-
const execFileAsync$
|
|
9991
|
+
const execFileAsync$3 = (0, node_util.promisify)(node_child_process.execFile);
|
|
9969
9992
|
const IMAGE_TAG = "universe-runner:pm";
|
|
9970
9993
|
const ensureImageBuilt = async (cwd) => {
|
|
9971
9994
|
const dockerfile = (0, node_path.resolve)(cwd, "Dockerfile");
|
|
9972
|
-
await execFileAsync$
|
|
9995
|
+
await execFileAsync$3("docker", [
|
|
9973
9996
|
"build",
|
|
9974
9997
|
"--file",
|
|
9975
9998
|
dockerfile,
|
|
@@ -9982,7 +10005,7 @@ const ensureImageBuilt = async (cwd) => {
|
|
|
9982
10005
|
};
|
|
9983
10006
|
const runCmdForFiles = async (cwd, cmd, inputs, outputs) => {
|
|
9984
10007
|
await ensureImageBuilt(cwd);
|
|
9985
|
-
const { stdout: idRaw } = await execFileAsync$
|
|
10008
|
+
const { stdout: idRaw } = await execFileAsync$3("docker", [
|
|
9986
10009
|
"create",
|
|
9987
10010
|
"-w",
|
|
9988
10011
|
"/app",
|
|
@@ -9991,28 +10014,28 @@ const runCmdForFiles = async (cwd, cmd, inputs, outputs) => {
|
|
|
9991
10014
|
], { encoding: "utf8" });
|
|
9992
10015
|
const id = idRaw.trim();
|
|
9993
10016
|
try {
|
|
9994
|
-
await Promise.all(inputs.map((file) => execFileAsync$
|
|
10017
|
+
await Promise.all(inputs.map((file) => execFileAsync$3("docker", [
|
|
9995
10018
|
"cp",
|
|
9996
10019
|
`${cwd}/${file}`,
|
|
9997
10020
|
`${id}:/app/${file}`
|
|
9998
10021
|
], { encoding: "utf8" })));
|
|
9999
|
-
await execFileAsync$
|
|
10022
|
+
await execFileAsync$3("docker", [
|
|
10000
10023
|
"start",
|
|
10001
10024
|
"-a",
|
|
10002
10025
|
id
|
|
10003
10026
|
], { encoding: "utf8" });
|
|
10004
|
-
await Promise.all(outputs.map((file) => execFileAsync$
|
|
10027
|
+
await Promise.all(outputs.map((file) => execFileAsync$3("docker", [
|
|
10005
10028
|
"cp",
|
|
10006
10029
|
`${id}:/app/${file}`,
|
|
10007
10030
|
`${cwd}/${file}`
|
|
10008
10031
|
], { encoding: "utf8" })));
|
|
10009
10032
|
} finally {
|
|
10010
|
-
await execFileAsync$
|
|
10033
|
+
await execFileAsync$3("docker", ["rm", id], { encoding: "utf8" });
|
|
10011
10034
|
}
|
|
10012
10035
|
};
|
|
10013
10036
|
const runCmdForStdout = async (cwd, cmd, inputs) => {
|
|
10014
10037
|
await ensureImageBuilt(cwd);
|
|
10015
|
-
const { stdout: idRaw } = await execFileAsync$
|
|
10038
|
+
const { stdout: idRaw } = await execFileAsync$3("docker", [
|
|
10016
10039
|
"create",
|
|
10017
10040
|
"-w",
|
|
10018
10041
|
"/app",
|
|
@@ -10021,19 +10044,19 @@ const runCmdForStdout = async (cwd, cmd, inputs) => {
|
|
|
10021
10044
|
], { encoding: "utf8" });
|
|
10022
10045
|
const id = idRaw.trim();
|
|
10023
10046
|
try {
|
|
10024
|
-
await Promise.all(inputs.map((file) => execFileAsync$
|
|
10047
|
+
await Promise.all(inputs.map((file) => execFileAsync$3("docker", [
|
|
10025
10048
|
"cp",
|
|
10026
10049
|
`${cwd}/${file}`,
|
|
10027
10050
|
`${id}:/app/${file}`
|
|
10028
10051
|
], { encoding: "utf8" })));
|
|
10029
|
-
const { stdout } = await execFileAsync$
|
|
10052
|
+
const { stdout } = await execFileAsync$3("docker", [
|
|
10030
10053
|
"start",
|
|
10031
10054
|
"-a",
|
|
10032
10055
|
id
|
|
10033
10056
|
], { encoding: "utf8" });
|
|
10034
10057
|
return stdout;
|
|
10035
10058
|
} finally {
|
|
10036
|
-
await execFileAsync$
|
|
10059
|
+
await execFileAsync$3("docker", ["rm", id], { encoding: "utf8" });
|
|
10037
10060
|
}
|
|
10038
10061
|
};
|
|
10039
10062
|
//#endregion
|
|
@@ -10067,17 +10090,17 @@ const extractVersions$1 = (listOutput) => {
|
|
|
10067
10090
|
return versions;
|
|
10068
10091
|
};
|
|
10069
10092
|
var BunPackageManager = class {
|
|
10070
|
-
|
|
10093
|
+
runner;
|
|
10071
10094
|
constructor(runner = bunRunner) {
|
|
10072
|
-
this.
|
|
10095
|
+
this.runner = runner;
|
|
10096
|
+
}
|
|
10097
|
+
specifyDeps(projectDirectory, _pmVersion) {
|
|
10098
|
+
return createPackageSpecifier({
|
|
10073
10099
|
deleteBeforeFirstInstall: true,
|
|
10074
10100
|
extractVersions: extractVersions$1,
|
|
10075
10101
|
lockfileName: LOCKFILE$1,
|
|
10076
|
-
runner
|
|
10077
|
-
});
|
|
10078
|
-
}
|
|
10079
|
-
specifyDeps(projectDirectory) {
|
|
10080
|
-
return this.impl.specifyDeps(projectDirectory);
|
|
10102
|
+
runner: this.runner
|
|
10103
|
+
}).run(projectDirectory);
|
|
10081
10104
|
}
|
|
10082
10105
|
};
|
|
10083
10106
|
//#endregion
|
|
@@ -10088,13 +10111,13 @@ var BunPackageManager = class {
|
|
|
10088
10111
|
*/
|
|
10089
10112
|
const LOCKFILE = "pnpm-lock.yaml";
|
|
10090
10113
|
const MANIFESTS = ["package.json", "pnpm-workspace.yaml"];
|
|
10091
|
-
const
|
|
10114
|
+
const defaultRunnerFactory = (pmVersion) => ({
|
|
10092
10115
|
async installLockfileOnly(cwd) {
|
|
10093
10116
|
await runCmdForFiles(cwd, [
|
|
10094
|
-
"
|
|
10095
|
-
"
|
|
10096
|
-
|
|
10097
|
-
], MANIFESTS, [LOCKFILE]);
|
|
10117
|
+
"sh",
|
|
10118
|
+
"-c",
|
|
10119
|
+
`corepack use pnpm@${pmVersion} && pnpm install --lockfile-only`
|
|
10120
|
+
], MANIFESTS, [LOCKFILE, "package.json"]);
|
|
10098
10121
|
},
|
|
10099
10122
|
list(cwd) {
|
|
10100
10123
|
return runCmdForStdout(cwd, [
|
|
@@ -10105,7 +10128,7 @@ const defaultPnpmRunner = {
|
|
|
10105
10128
|
"--lockfile-only"
|
|
10106
10129
|
], [...MANIFESTS, LOCKFILE]);
|
|
10107
10130
|
}
|
|
10108
|
-
};
|
|
10131
|
+
});
|
|
10109
10132
|
const extractVersions = (listOutput) => {
|
|
10110
10133
|
const root = JSON.parse(listOutput)[0] ?? {};
|
|
10111
10134
|
const versions = {};
|
|
@@ -10114,17 +10137,17 @@ const extractVersions = (listOutput) => {
|
|
|
10114
10137
|
return versions;
|
|
10115
10138
|
};
|
|
10116
10139
|
var PnpmPackageManager = class {
|
|
10117
|
-
|
|
10118
|
-
constructor(
|
|
10119
|
-
this.
|
|
10140
|
+
createRunner;
|
|
10141
|
+
constructor(createRunner = defaultRunnerFactory) {
|
|
10142
|
+
this.createRunner = createRunner;
|
|
10143
|
+
}
|
|
10144
|
+
async specifyDeps(projectDirectory, pmVersion) {
|
|
10145
|
+
await createPackageSpecifier({
|
|
10120
10146
|
deleteBeforeFirstInstall: false,
|
|
10121
10147
|
extractVersions,
|
|
10122
10148
|
lockfileName: LOCKFILE,
|
|
10123
|
-
runner
|
|
10124
|
-
});
|
|
10125
|
-
}
|
|
10126
|
-
specifyDeps(projectDirectory) {
|
|
10127
|
-
return this.impl.specifyDeps(projectDirectory);
|
|
10149
|
+
runner: this.createRunner(pmVersion)
|
|
10150
|
+
}).run(projectDirectory);
|
|
10128
10151
|
}
|
|
10129
10152
|
};
|
|
10130
10153
|
//#endregion
|
|
@@ -11372,13 +11395,13 @@ var ClackPrompt = class {
|
|
|
11372
11395
|
};
|
|
11373
11396
|
//#endregion
|
|
11374
11397
|
//#region src/commands/create/io/git-repo-initialiser.ts
|
|
11375
|
-
const execFileAsync$
|
|
11376
|
-
const defaultRun = async (command, args, cwd) => {
|
|
11377
|
-
await execFileAsync$
|
|
11398
|
+
const execFileAsync$2 = (0, node_util.promisify)(node_child_process.execFile);
|
|
11399
|
+
const defaultRun$1 = async (command, args, cwd) => {
|
|
11400
|
+
await execFileAsync$2(command, args, { cwd });
|
|
11378
11401
|
};
|
|
11379
11402
|
var GitRepoInitialiser = class {
|
|
11380
11403
|
run;
|
|
11381
|
-
constructor(run = defaultRun) {
|
|
11404
|
+
constructor(run = defaultRun$1) {
|
|
11382
11405
|
this.run = run;
|
|
11383
11406
|
}
|
|
11384
11407
|
async initialise(projectDirectory) {
|
|
@@ -11396,6 +11419,41 @@ var GitRepoInitialiser = class {
|
|
|
11396
11419
|
}
|
|
11397
11420
|
};
|
|
11398
11421
|
//#endregion
|
|
11422
|
+
//#region src/commands/create/io/npx-skill-installer.ts
|
|
11423
|
+
const execFileAsync$1 = (0, node_util.promisify)(node_child_process.execFile);
|
|
11424
|
+
const defaultRun = async (command, args, cwd) => {
|
|
11425
|
+
await execFileAsync$1(command, args, { cwd });
|
|
11426
|
+
};
|
|
11427
|
+
var NpxSkillInstaller = class {
|
|
11428
|
+
run;
|
|
11429
|
+
constructor(run = defaultRun) {
|
|
11430
|
+
this.run = run;
|
|
11431
|
+
}
|
|
11432
|
+
async installSkills(skills, projectDirectory) {
|
|
11433
|
+
const skillsByRepo = /* @__PURE__ */ new Map();
|
|
11434
|
+
for (const { repo, skill } of skills) {
|
|
11435
|
+
const existing = skillsByRepo.get(repo);
|
|
11436
|
+
if (existing === void 0) skillsByRepo.set(repo, [skill]);
|
|
11437
|
+
else existing.push(skill);
|
|
11438
|
+
}
|
|
11439
|
+
try {
|
|
11440
|
+
for (const [repo, repoSkills] of skillsByRepo) {
|
|
11441
|
+
const args = [
|
|
11442
|
+
"--yes",
|
|
11443
|
+
"skills",
|
|
11444
|
+
"add",
|
|
11445
|
+
"--yes",
|
|
11446
|
+
repo,
|
|
11447
|
+
...repoSkills.flatMap((skill) => ["--skill", skill])
|
|
11448
|
+
];
|
|
11449
|
+
await this.run("npx", args, projectDirectory);
|
|
11450
|
+
}
|
|
11451
|
+
} catch (error) {
|
|
11452
|
+
throw new ConfigError(error.message);
|
|
11453
|
+
}
|
|
11454
|
+
}
|
|
11455
|
+
};
|
|
11456
|
+
//#endregion
|
|
11399
11457
|
//#region node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/core.js
|
|
11400
11458
|
var _a$1;
|
|
11401
11459
|
function $constructor(name, initializer, params) {
|
|
@@ -15712,6 +15770,15 @@ const silentLogger = {
|
|
|
15712
15770
|
warn: () => {}
|
|
15713
15771
|
};
|
|
15714
15772
|
//#endregion
|
|
15773
|
+
//#region src/output/spinner.ts
|
|
15774
|
+
const clackSpinner = () => vt();
|
|
15775
|
+
const silentSpinner = () => ({
|
|
15776
|
+
error: () => {},
|
|
15777
|
+
start: () => {},
|
|
15778
|
+
message: () => {},
|
|
15779
|
+
stop: () => {}
|
|
15780
|
+
});
|
|
15781
|
+
//#endregion
|
|
15715
15782
|
//#region src/output/envelope.ts
|
|
15716
15783
|
function buildEnvelope(command, success, data) {
|
|
15717
15784
|
return {
|
|
@@ -15866,6 +15933,7 @@ const PackageManagerSchema = record(literal(["bun", "pnpm"]), strictObject({
|
|
|
15866
15933
|
lockfile: string(),
|
|
15867
15934
|
manifests: array(string()),
|
|
15868
15935
|
pmInstall: string(),
|
|
15936
|
+
pmVersion: string().regex(/^\d+\.\d+\.\d+$/, "pmVersion must be a semver version (major.minor.patch), e.g. 1.2.3"),
|
|
15869
15937
|
preinstall: string().optional()
|
|
15870
15938
|
}));
|
|
15871
15939
|
const ServiceSchema = record(literal([
|
|
@@ -15877,6 +15945,10 @@ const FrameworkSchema = record(string(), strictObject({
|
|
|
15877
15945
|
devCopySource: string(),
|
|
15878
15946
|
files: record(string(), string()),
|
|
15879
15947
|
port: number(),
|
|
15948
|
+
skills: array(strictObject({
|
|
15949
|
+
repo: string(),
|
|
15950
|
+
skill: string()
|
|
15951
|
+
})).optional(),
|
|
15880
15952
|
watchSync: array(strictObject({
|
|
15881
15953
|
path: string(),
|
|
15882
15954
|
target: string()
|
|
@@ -15893,7 +15965,7 @@ const LabelsSchema = record(union([
|
|
|
15893
15965
|
]), record(string(), string()));
|
|
15894
15966
|
//#endregion
|
|
15895
15967
|
//#region src/commands/create/layer-composition/assets.json
|
|
15896
|
-
var templateVersion = "0.
|
|
15968
|
+
var templateVersion = "0.4.1";
|
|
15897
15969
|
var templateUrl = "https://github.com/freeCodeCamp-Universe/templates/releases/download/app-templates-v{{version}}/app-templates-{{version}}.tar.gz";
|
|
15898
15970
|
//#endregion
|
|
15899
15971
|
//#region src/commands/create/layer-composition/assets.ts
|
|
@@ -16225,6 +16297,9 @@ const create$1 = async (options, deps = {}) => {
|
|
|
16225
16297
|
});
|
|
16226
16298
|
const platformManifestGenerator = deps.platformManifestGenerator ?? new PlatformManifestService();
|
|
16227
16299
|
const repoInitialiser = deps.repoInitialiser ?? new GitRepoInitialiser();
|
|
16300
|
+
const skillInstaller = deps.skillInstaller ?? new NpxSkillInstaller();
|
|
16301
|
+
const isTTY = process.stdin.isTTY;
|
|
16302
|
+
const spinner = deps.spinner ?? (options.json || !isTTY ? silentSpinner() : clackSpinner());
|
|
16228
16303
|
try {
|
|
16229
16304
|
const templatesDir = process.env["UNIVERSE_TEMPLATES_DIR"];
|
|
16230
16305
|
if (!(templatesDir && templatesDir.length > 0)) {
|
|
@@ -16267,20 +16342,38 @@ const create$1 = async (options, deps = {}) => {
|
|
|
16267
16342
|
...pm !== void 0 ? { packageManager: pm } : {}
|
|
16268
16343
|
};
|
|
16269
16344
|
}
|
|
16345
|
+
spinner.start("Preparing your project");
|
|
16270
16346
|
const validatedInput = validator.validateCreateInput(selections);
|
|
16347
|
+
spinner.message("Composing project layers");
|
|
16271
16348
|
const resolvedLayers = await layerResolver.resolveLayers(validatedInput);
|
|
16272
16349
|
const targetDirectory = `${cwd}/${validatedInput.name}`;
|
|
16273
16350
|
const projectFiles = {
|
|
16274
16351
|
...resolvedLayers.files,
|
|
16275
16352
|
"platform.yaml": platformManifestGenerator.generatePlatformManifest(validatedInput)
|
|
16276
16353
|
};
|
|
16354
|
+
spinner.message("Writing project files");
|
|
16277
16355
|
await filesystemWriter.writeProject(targetDirectory, projectFiles);
|
|
16278
16356
|
const manager = validatedInput.packageManager;
|
|
16279
|
-
if (manager !== void 0)
|
|
16280
|
-
manager
|
|
16281
|
-
|
|
16282
|
-
|
|
16357
|
+
if (manager !== void 0) {
|
|
16358
|
+
spinner.message(`Pinning dependencies with ${manager}`);
|
|
16359
|
+
await packageManager.specifyDeps({
|
|
16360
|
+
manager,
|
|
16361
|
+
pmVersion: registry["package-managers"][manager]?.pmVersion ?? "",
|
|
16362
|
+
projectDirectory: targetDirectory
|
|
16363
|
+
});
|
|
16364
|
+
}
|
|
16365
|
+
const skills = registry.frameworks[validatedInput.framework]?.skills;
|
|
16366
|
+
if (skills && skills.length > 0) {
|
|
16367
|
+
spinner.message("Installing skills");
|
|
16368
|
+
try {
|
|
16369
|
+
await skillInstaller.installSkills(skills, targetDirectory);
|
|
16370
|
+
} catch (err) {
|
|
16371
|
+
logger.error(err instanceof Error ? err.message : String(err));
|
|
16372
|
+
}
|
|
16373
|
+
}
|
|
16374
|
+
spinner.message("Initialising git repository");
|
|
16283
16375
|
await repoInitialiser.initialise(targetDirectory);
|
|
16376
|
+
spinner.stop("Project scaffolded");
|
|
16284
16377
|
if (options.json) {
|
|
16285
16378
|
emitJson(buildEnvelope("create", true, {
|
|
16286
16379
|
path: targetDirectory,
|
|
@@ -16293,9 +16386,11 @@ const create$1 = async (options, deps = {}) => {
|
|
|
16293
16386
|
}));
|
|
16294
16387
|
return;
|
|
16295
16388
|
}
|
|
16296
|
-
|
|
16297
|
-
|
|
16389
|
+
const startInstruction = `Project scaffolded. cd into ${validatedInput.name} and run \`docker compose up --watch\` to start the project`;
|
|
16390
|
+
if (interactive) logger.success(startInstruction);
|
|
16391
|
+
else logger.info(startInstruction);
|
|
16298
16392
|
} catch (err) {
|
|
16393
|
+
spinner.error("Create failed");
|
|
16299
16394
|
const code = err instanceof CliError ? err.exitCode : 10;
|
|
16300
16395
|
const message = err instanceof Error ? err.message : String(err);
|
|
16301
16396
|
outputError({
|
|
@@ -16735,6 +16830,10 @@ const auditRowArraySchema = array(object({
|
|
|
16735
16830
|
requestId: string().optional(),
|
|
16736
16831
|
detail: record(string(), unknown()).optional()
|
|
16737
16832
|
}));
|
|
16833
|
+
const deploySummaryArraySchema = array(object({
|
|
16834
|
+
deployId: string(),
|
|
16835
|
+
actor: string().optional()
|
|
16836
|
+
}));
|
|
16738
16837
|
const repoName = string().regex(/^[a-zA-Z0-9][a-zA-Z0-9._-]{0,99}$/, "must start with a letter or digit, then letters, digits, '.', '_' or '-' (max 100 chars)");
|
|
16739
16838
|
const visibilitySchema = _enum(["public", "private"]);
|
|
16740
16839
|
const repoStatusSchema = _enum([
|
|
@@ -17013,7 +17112,7 @@ function createProxyClient(cfg) {
|
|
|
17013
17112
|
Authorization: await userBearer(),
|
|
17014
17113
|
Accept: "application/json"
|
|
17015
17114
|
}
|
|
17016
|
-
});
|
|
17115
|
+
}, (raw) => deploySummaryArraySchema.parse(raw));
|
|
17017
17116
|
},
|
|
17018
17117
|
async getAlias(req) {
|
|
17019
17118
|
const url = `${base}/api/site/${encodeURIComponent(req.site)}/alias/${encodeURIComponent(req.mode)}`;
|
|
@@ -19133,7 +19232,7 @@ function formatTable(rows) {
|
|
|
19133
19232
|
r.occurredAt,
|
|
19134
19233
|
r.actor,
|
|
19135
19234
|
r.action,
|
|
19136
|
-
|
|
19235
|
+
targetOf(r),
|
|
19137
19236
|
r.outcome
|
|
19138
19237
|
]);
|
|
19139
19238
|
const widths = headers.map((h, i) => Math.max(h.length, ...cells.map((row) => row[i]?.length ?? 0)));
|
|
@@ -19144,6 +19243,10 @@ function targetFromDetail(r) {
|
|
|
19144
19243
|
const name = r.detail?.["name"];
|
|
19145
19244
|
return typeof name === "string" ? name : "";
|
|
19146
19245
|
}
|
|
19246
|
+
function targetOf(r) {
|
|
19247
|
+
if (r.site && r.deployId) return `${r.site}/${r.deployId}`;
|
|
19248
|
+
return r.site || r.deployId || targetFromDetail(r);
|
|
19249
|
+
}
|
|
19147
19250
|
async function ls(options, deps = {}) {
|
|
19148
19251
|
const command = "audit ls";
|
|
19149
19252
|
const message = deps.logMessage ?? ((s) => R.message(s));
|
|
@@ -19316,7 +19419,7 @@ function installExitNotice(current) {
|
|
|
19316
19419
|
}
|
|
19317
19420
|
//#endregion
|
|
19318
19421
|
//#region src/cli.ts
|
|
19319
|
-
const version = "0.
|
|
19422
|
+
const version = "0.13.0";
|
|
19320
19423
|
function handleActionError(command, json, err) {
|
|
19321
19424
|
const ctx = {
|
|
19322
19425
|
json,
|
package/package.json
CHANGED
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@freecodecamp/universe-cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
3
|
+
"version": "0.13.0",
|
|
4
|
+
"description": "Static site deployment CLI for the freeCodeCamp Universe platform",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"cli",
|
|
7
|
+
"deployment",
|
|
8
|
+
"freecodecamp",
|
|
9
|
+
"static-site"
|
|
10
|
+
],
|
|
11
|
+
"homepage": "https://github.com/freeCodeCamp-Universe/universe-cli#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/freeCodeCamp-Universe/universe-cli/issues"
|
|
13
14
|
},
|
|
14
|
-
"author": "Mrugesh Mohapatra <noreply@mrugesh.dev> (https://mrugesh.dev/)",
|
|
15
15
|
"license": "BSD-3-Clause",
|
|
16
|
+
"author": "Mrugesh Mohapatra <noreply@mrugesh.dev> (https://mrugesh.dev/)",
|
|
16
17
|
"repository": {
|
|
17
18
|
"type": "git",
|
|
18
19
|
"url": "git+https://github.com/freeCodeCamp-Universe/universe-cli.git"
|
|
19
20
|
},
|
|
20
|
-
"
|
|
21
|
-
"
|
|
21
|
+
"bin": {
|
|
22
|
+
"universe": "dist/index.cjs"
|
|
22
23
|
},
|
|
23
24
|
"files": [
|
|
24
25
|
"dist/",
|
|
@@ -26,8 +27,20 @@
|
|
|
26
27
|
"LICENSE"
|
|
27
28
|
],
|
|
28
29
|
"type": "module",
|
|
29
|
-
"
|
|
30
|
-
|
|
30
|
+
"main": "dist/index.cjs",
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"test": "vitest run",
|
|
36
|
+
"test:smoke": "UNIVERSE_E2E_REAL=1 vitest run tests/e2e/smoke-real-artemis.test.ts",
|
|
37
|
+
"build": "tsdown",
|
|
38
|
+
"lint": "oxlint src tests",
|
|
39
|
+
"typecheck": "tsc --noEmit",
|
|
40
|
+
"prepare": "husky",
|
|
41
|
+
"dev": "tsx src/index.ts",
|
|
42
|
+
"fmt": "oxfmt",
|
|
43
|
+
"fmt:check": "oxfmt --check"
|
|
31
44
|
},
|
|
32
45
|
"dependencies": {
|
|
33
46
|
"@clack/prompts": "^1.5.0",
|
|
@@ -38,6 +51,7 @@
|
|
|
38
51
|
"devDependencies": {
|
|
39
52
|
"@types/node": "^24.12.2",
|
|
40
53
|
"husky": "^9.1.7",
|
|
54
|
+
"oxfmt": "^0.59.0",
|
|
41
55
|
"oxlint": "^1.68.0",
|
|
42
56
|
"postject": "1.0.0-alpha.6",
|
|
43
57
|
"tsdown": "0.22.1",
|
|
@@ -45,19 +59,8 @@
|
|
|
45
59
|
"typescript": "^5.9.3",
|
|
46
60
|
"vitest": "^3.2.4"
|
|
47
61
|
},
|
|
48
|
-
"packageManager": "pnpm@10.33.0",
|
|
49
62
|
"engines": {
|
|
50
63
|
"node": ">=24.0.0"
|
|
51
64
|
},
|
|
52
|
-
"
|
|
53
|
-
"homepage": "https://github.com/freeCodeCamp-Universe/universe-cli#readme",
|
|
54
|
-
"bugs": {
|
|
55
|
-
"url": "https://github.com/freeCodeCamp-Universe/universe-cli/issues"
|
|
56
|
-
},
|
|
57
|
-
"keywords": [
|
|
58
|
-
"cli",
|
|
59
|
-
"static-site",
|
|
60
|
-
"deployment",
|
|
61
|
-
"freecodecamp"
|
|
62
|
-
]
|
|
65
|
+
"packageManager": "pnpm@10.33.0"
|
|
63
66
|
}
|