lecodes-cli 0.1.5 → 0.1.6
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 +142 -143
- package/package.json +3 -2
- package/runtime/inject.js +4629 -0
- package/runtime/gl-matrix/common.js +0 -54
- package/runtime/gl-matrix/header.js +0 -12
- package/runtime/gl-matrix/index.js +0 -11
- package/runtime/gl-matrix/mat2.js +0 -425
- package/runtime/gl-matrix/mat2d.js +0 -476
- package/runtime/gl-matrix/mat3.js +0 -765
- package/runtime/gl-matrix/mat4.js +0 -1947
- package/runtime/gl-matrix/quat.js +0 -737
- package/runtime/gl-matrix/quat2.js +0 -822
- package/runtime/gl-matrix/vec2.js +0 -620
- package/runtime/gl-matrix/vec3.js +0 -791
- package/runtime/gl-matrix/vec4.js +0 -652
- package/runtime/worker/animate.js +0 -304
- package/runtime/worker/chunk-4ZN32GYS.js +0 -34
- package/runtime/worker/chunk-G5ZA3LKB.js +0 -52
- package/runtime/worker/chunk-MI3UXE5H.js +0 -1395
- package/runtime/worker/creator.js +0 -930
- package/runtime/worker/globals.js +0 -208
- package/runtime/worker/ui.js +0 -763
- package/runtime/worker/utils.js +0 -16
package/dist/index.js
CHANGED
|
@@ -4,8 +4,8 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
|
4
4
|
|
|
5
5
|
// src/index.ts
|
|
6
6
|
import { readFileSync as readFileSync8 } from "node:fs";
|
|
7
|
-
import { dirname as
|
|
8
|
-
import { fileURLToPath as
|
|
7
|
+
import { dirname as dirname7, join as join11 } from "node:path";
|
|
8
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
9
9
|
|
|
10
10
|
// src/commands/clone.ts
|
|
11
11
|
import { existsSync as existsSync3, mkdirSync as mkdirSync5, readdirSync } from "node:fs";
|
|
@@ -160,6 +160,7 @@ var apiRequest = async (apiUrl, path, opts = {}) => {
|
|
|
160
160
|
};
|
|
161
161
|
var getAccount = (apiUrl, token) => apiRequest(apiUrl, "/account", { token });
|
|
162
162
|
var getProject = (apiUrl, token, uuid) => apiRequest(apiUrl, `/projects/${uuid}`, { token });
|
|
163
|
+
var createProject = (apiUrl, token, name, teamUuid) => apiRequest(apiUrl, "/projects", { token, body: { name, teamUuid } });
|
|
163
164
|
var getCommits = (apiUrl, token, uuid) => apiRequest(apiUrl, `/projects/${uuid}/commits`, { token });
|
|
164
165
|
var getTypes = (apiUrl) => apiRequest(apiUrl, "/types");
|
|
165
166
|
var uploadBlob = (apiUrl, token, uuid, name, bytes) => {
|
|
@@ -282,38 +283,8 @@ var materializeAssets = async (root, project, apiUrl, token, onProgress) => {
|
|
|
282
283
|
};
|
|
283
284
|
|
|
284
285
|
// src/types.ts
|
|
285
|
-
import { join as join4 } from "node:path";
|
|
286
|
+
import { dirname as dirname3, join as join4 } from "node:path";
|
|
286
287
|
import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "node:fs";
|
|
287
|
-
var wrapGlobal = (text) => {
|
|
288
|
-
const marker = text.indexOf("declare global");
|
|
289
|
-
if (marker < 0)
|
|
290
|
-
return text;
|
|
291
|
-
const importLines = [];
|
|
292
|
-
const bodyLines = [];
|
|
293
|
-
for (const line of text.split(`
|
|
294
|
-
`)) {
|
|
295
|
-
if (/^\s*import\s.*\sfrom\s/.test(line))
|
|
296
|
-
importLines.push(line);
|
|
297
|
-
else
|
|
298
|
-
bodyLines.push(line);
|
|
299
|
-
}
|
|
300
|
-
const rest = bodyLines.join(`
|
|
301
|
-
`);
|
|
302
|
-
const open = rest.indexOf("{", rest.indexOf("declare global"));
|
|
303
|
-
const close = rest.lastIndexOf("}");
|
|
304
|
-
const preamble = rest.slice(0, rest.indexOf("declare global"));
|
|
305
|
-
const inner = rest.slice(open + 1, close);
|
|
306
|
-
const stripDeclare = (s) => s.replace(/(^|\n)([ \t]*)declare\s+/g, "$1$2");
|
|
307
|
-
const merged = stripDeclare(preamble) + `
|
|
308
|
-
` + stripDeclare(inner);
|
|
309
|
-
return `${importLines.join(`
|
|
310
|
-
`)}
|
|
311
|
-
|
|
312
|
-
declare global {
|
|
313
|
-
${merged}
|
|
314
|
-
}
|
|
315
|
-
`;
|
|
316
|
-
};
|
|
317
288
|
var TSCONFIG = {
|
|
318
289
|
compilerOptions: {
|
|
319
290
|
target: "ES2020",
|
|
@@ -333,10 +304,10 @@ var TSCONFIG = {
|
|
|
333
304
|
var materializeTypes = async (root, apiUrl) => {
|
|
334
305
|
const bundle = await getTypes(apiUrl);
|
|
335
306
|
const typesDir = join4(root, LECODES_DIR, "types");
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
writeFileSync4(
|
|
307
|
+
for (const [path, text] of Object.entries(bundle)) {
|
|
308
|
+
const dest = join4(typesDir, path);
|
|
309
|
+
mkdirSync4(dirname3(dest), { recursive: true });
|
|
310
|
+
writeFileSync4(dest, text);
|
|
340
311
|
}
|
|
341
312
|
};
|
|
342
313
|
var writeTsconfig = (root) => {
|
|
@@ -471,9 +442,47 @@ var clone = async (args) => {
|
|
|
471
442
|
info(c.dim(` cd ${dir} — edit, then \`lecodes push -m "your message"\``));
|
|
472
443
|
};
|
|
473
444
|
|
|
445
|
+
// src/commands/create.ts
|
|
446
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync6, readdirSync as readdirSync2, writeFileSync as writeFileSync6 } from "node:fs";
|
|
447
|
+
import { join as join6, resolve as resolve2 } from "node:path";
|
|
448
|
+
var slug2 = (name) => name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "project";
|
|
449
|
+
var STARTER = `// Welcome to le.codes — no imports needed, the whole SDK is available as globals.
|
|
450
|
+
const scene = new Scene2D({ background: '#10131a' })
|
|
451
|
+
scene.open()
|
|
452
|
+
|
|
453
|
+
setLoop((dt) => {
|
|
454
|
+
// your per-frame logic — dt is seconds since the previous frame
|
|
455
|
+
})
|
|
456
|
+
`;
|
|
457
|
+
var create = async (args) => {
|
|
458
|
+
const config = loadConfig();
|
|
459
|
+
const apiUrl = requireApiUrl(config);
|
|
460
|
+
const token = requireToken(config);
|
|
461
|
+
const name = args._[0];
|
|
462
|
+
if (!name)
|
|
463
|
+
throw new CliError("Usage: lecodes create <name> [directory]");
|
|
464
|
+
const dir = args._[1] ?? slug2(name);
|
|
465
|
+
const root = resolve2(dir);
|
|
466
|
+
if (existsSync4(root) && readdirSync2(root).length > 0) {
|
|
467
|
+
throw new CliError(`Directory "${dir}" already exists and is not empty.`);
|
|
468
|
+
}
|
|
469
|
+
mkdirSync6(root, { recursive: true });
|
|
470
|
+
info(c.dim(`Creating project ${c.bold(name)}…`));
|
|
471
|
+
const { uuid } = await createProject(apiUrl, token, name, flagStr(args, "team"));
|
|
472
|
+
info(c.dim("Fetching type definitions…"));
|
|
473
|
+
await materializeTypes(root, apiUrl);
|
|
474
|
+
writeTsconfig(root);
|
|
475
|
+
writeDefaultIgnore(root);
|
|
476
|
+
writeFileSync6(join6(root, "main.ts"), STARTER);
|
|
477
|
+
const commits = await getCommits(apiUrl, token, uuid);
|
|
478
|
+
writeManifest(root, { uuid, apiUrl, name, baseHeadId: commits.headId, files: {} });
|
|
479
|
+
success(`Created ${c.bold(name)} in ${c.bold(dir)}/`);
|
|
480
|
+
info(c.dim(` cd ${dir} — edit main.ts, then \`lecodes push -m "first commit"\` to save it`));
|
|
481
|
+
};
|
|
482
|
+
|
|
474
483
|
// src/localFiles.ts
|
|
475
|
-
import { readdirSync as
|
|
476
|
-
import { join as
|
|
484
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync4 } from "node:fs";
|
|
485
|
+
import { join as join7, relative } from "node:path";
|
|
477
486
|
var SKIP_DIRS = new Set([".lecodes", ".git", "node_modules"]);
|
|
478
487
|
var SKIP_FILES = new Set(["tsconfig.json", "jsconfig.json", ".gitignore", ".lecodesignore", ".DS_Store"]);
|
|
479
488
|
var TEXT_EXTS = new Set([
|
|
@@ -526,8 +535,8 @@ var scanLocal = (root, opts = {}) => {
|
|
|
526
535
|
return false;
|
|
527
536
|
};
|
|
528
537
|
const walk = (dir, parentIgnored) => {
|
|
529
|
-
for (const entry of
|
|
530
|
-
const abs =
|
|
538
|
+
for (const entry of readdirSync3(dir, { withFileTypes: true })) {
|
|
539
|
+
const abs = join7(dir, entry.name);
|
|
531
540
|
const key = toKey(relative(root, abs));
|
|
532
541
|
if (entry.isDirectory()) {
|
|
533
542
|
if (SKIP_DIRS.has(entry.name))
|
|
@@ -804,10 +813,10 @@ var openBrowser = (url) => {
|
|
|
804
813
|
};
|
|
805
814
|
var browserLogin = async (webBase, timeoutMs = 5 * 60 * 1000, open = openBrowser) => {
|
|
806
815
|
const state = randomBytes(16).toString("hex");
|
|
807
|
-
let
|
|
816
|
+
let resolve3;
|
|
808
817
|
let reject;
|
|
809
818
|
const tokenPromise = new Promise((res, rej) => {
|
|
810
|
-
|
|
819
|
+
resolve3 = res;
|
|
811
820
|
reject = rej;
|
|
812
821
|
});
|
|
813
822
|
const server = createServer((req, res) => {
|
|
@@ -825,7 +834,7 @@ var browserLogin = async (webBase, timeoutMs = 5 * 60 * 1000, open = openBrowser
|
|
|
825
834
|
}
|
|
826
835
|
res.writeHead(200, { "content-type": "text/html" });
|
|
827
836
|
res.end(SUCCESS_HTML);
|
|
828
|
-
|
|
837
|
+
resolve3(token);
|
|
829
838
|
});
|
|
830
839
|
await new Promise((res, rej) => {
|
|
831
840
|
server.once("error", rej);
|
|
@@ -858,8 +867,8 @@ var login = async (args) => {
|
|
|
858
867
|
};
|
|
859
868
|
|
|
860
869
|
// src/commands/preview.ts
|
|
861
|
-
import { writeFileSync as
|
|
862
|
-
import { resolve as
|
|
870
|
+
import { writeFileSync as writeFileSync7 } from "node:fs";
|
|
871
|
+
import { resolve as resolve3 } from "node:path";
|
|
863
872
|
|
|
864
873
|
// src/compile/collect.ts
|
|
865
874
|
import { readFileSync as readFileSync6 } from "node:fs";
|
|
@@ -893,13 +902,17 @@ var collectEntries = (root, manifest, project) => {
|
|
|
893
902
|
return { entries, warnings };
|
|
894
903
|
};
|
|
895
904
|
|
|
896
|
-
// src/compile/
|
|
905
|
+
// src/compile/projectCompile.ts
|
|
906
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
907
|
+
import { dirname as dirname5, join as join9 } from "node:path";
|
|
908
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
909
|
+
// ../sdk/src/compile/bundler.ts
|
|
897
910
|
import * as esbuild from "esbuild";
|
|
898
|
-
import { existsSync as
|
|
899
|
-
import { dirname as
|
|
911
|
+
import { existsSync as existsSync5 } from "node:fs";
|
|
912
|
+
import { dirname as dirname4, join as join8 } from "node:path";
|
|
900
913
|
import { fileURLToPath } from "node:url";
|
|
901
914
|
|
|
902
|
-
// src/compile/assetMacro.ts
|
|
915
|
+
// ../sdk/src/compile/assetMacro.ts
|
|
903
916
|
var ASSET_RE = /\basset\(\s*(["'])((?:[^"'\\]|\\.)*)\1\s*\)/g;
|
|
904
917
|
var hasAssetMacro = (src) => src.includes("asset(");
|
|
905
918
|
var desugarAssetMacros = (src, filePath) => {
|
|
@@ -924,52 +937,21 @@ var desugarAssetMacros = (src, filePath) => {
|
|
|
924
937
|
` + out;
|
|
925
938
|
};
|
|
926
939
|
|
|
927
|
-
// src/compile/bundler.ts
|
|
928
|
-
var
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
const vendored = join7(here, "..", "runtime");
|
|
943
|
-
if (existsSync4(join7(vendored, "worker", "creator.js"))) {
|
|
944
|
-
const w = join7(vendored, "worker");
|
|
945
|
-
return {
|
|
946
|
-
alias: {
|
|
947
|
-
creator: join7(w, "creator.js"),
|
|
948
|
-
ui: join7(w, "ui.js"),
|
|
949
|
-
animate: join7(w, "animate.js"),
|
|
950
|
-
utils: join7(w, "utils.js"),
|
|
951
|
-
"gl-matrix": join7(vendored, "gl-matrix")
|
|
952
|
-
},
|
|
953
|
-
inject: [join7(w, "globals.js")]
|
|
954
|
-
};
|
|
955
|
-
}
|
|
956
|
-
const repoRoot = join7(here, "..", "..", "..", "..");
|
|
957
|
-
const ws = join7(repoRoot, "packages", "worker", "src");
|
|
958
|
-
if (existsSync4(join7(ws, "index.ts"))) {
|
|
959
|
-
return {
|
|
960
|
-
alias: {
|
|
961
|
-
creator: join7(ws, "index.ts"),
|
|
962
|
-
ui: join7(ws, "ui.ts"),
|
|
963
|
-
animate: join7(ws, "animate.ts"),
|
|
964
|
-
utils: join7(ws, "utils.ts"),
|
|
965
|
-
"gl-matrix": join7(repoRoot, "packages", "backend", "src", "assets", "dependencies", "gl-matrix")
|
|
966
|
-
},
|
|
967
|
-
inject: [join7(ws, "globals.ts")]
|
|
968
|
-
};
|
|
969
|
-
}
|
|
970
|
-
throw new CliError("Could not locate the compile runtime — try reinstalling lecodes-cli.");
|
|
971
|
-
};
|
|
972
|
-
function normalize(path) {
|
|
940
|
+
// ../sdk/src/compile/bundler.ts
|
|
941
|
+
var resolveInject = () => {
|
|
942
|
+
const override = process.env.LECODES_SDK_INJECT;
|
|
943
|
+
if (override && existsSync5(override))
|
|
944
|
+
return override;
|
|
945
|
+
const here = dirname4(fileURLToPath(import.meta.url));
|
|
946
|
+
const src = join8(here, "..", "inject.ts");
|
|
947
|
+
if (existsSync5(src))
|
|
948
|
+
return src;
|
|
949
|
+
const dist = join8(here, "..", "..", "dist", "inject.js");
|
|
950
|
+
if (existsSync5(dist))
|
|
951
|
+
return dist;
|
|
952
|
+
throw new Error("sdk: could not locate the inject entry (LECODES_SDK_INJECT / src/inject.ts / dist/inject.js)");
|
|
953
|
+
};
|
|
954
|
+
var normalize = (path) => {
|
|
973
955
|
const parts = [];
|
|
974
956
|
for (const part of path.split("/")) {
|
|
975
957
|
if (!part || part === ".")
|
|
@@ -980,20 +962,20 @@ function normalize(path) {
|
|
|
980
962
|
parts.push(part);
|
|
981
963
|
}
|
|
982
964
|
return "/" + parts.join("/");
|
|
983
|
-
}
|
|
984
|
-
|
|
965
|
+
};
|
|
966
|
+
var dirOf = (path) => {
|
|
985
967
|
const i = path.lastIndexOf("/");
|
|
986
968
|
return i <= 0 ? "/" : path.slice(0, i);
|
|
987
|
-
}
|
|
969
|
+
};
|
|
988
970
|
var hasExtension = (path) => /\.[a-zA-Z0-9]+$/.test(path);
|
|
989
|
-
|
|
971
|
+
var resolveBase = (importer, specifier) => {
|
|
990
972
|
if (specifier.startsWith("/"))
|
|
991
973
|
return normalize(specifier);
|
|
992
974
|
if (specifier.startsWith("./") || specifier.startsWith("../"))
|
|
993
975
|
return normalize(dirOf(importer) + "/" + specifier);
|
|
994
|
-
throw new Error(`Bare
|
|
995
|
-
}
|
|
996
|
-
|
|
976
|
+
throw new Error(`Bare imports are not allowed — the whole SDK is available as globals (no imports): ${specifier}`);
|
|
977
|
+
};
|
|
978
|
+
var resolveWithExtensions = (files, importer, specifier) => {
|
|
997
979
|
const base = resolveBase(importer, specifier);
|
|
998
980
|
if (hasExtension(base)) {
|
|
999
981
|
if (files.has(base))
|
|
@@ -1005,31 +987,26 @@ function resolveWithExtensions(files, importer, specifier) {
|
|
|
1005
987
|
return candidate;
|
|
1006
988
|
}
|
|
1007
989
|
throw new Error(`Module not found: ${specifier} from ${importer}`);
|
|
1008
|
-
}
|
|
990
|
+
};
|
|
1009
991
|
var getLoader = (path) => path.endsWith(".ts") ? "ts" : "js";
|
|
1010
|
-
async
|
|
1011
|
-
const
|
|
1012
|
-
const files = new Map(Object.entries(inputFiles).map(([k, v]) => [normalize(k), v]));
|
|
992
|
+
var bundleProject = async (entrypoint, files, format = "esm") => {
|
|
993
|
+
const fileMap = new Map(Object.entries(files).map(([k, v]) => [normalize(k), v]));
|
|
1013
994
|
const entry = normalize(entrypoint);
|
|
1014
|
-
if (!
|
|
1015
|
-
throw new
|
|
995
|
+
if (!fileMap.has(entry))
|
|
996
|
+
throw new Error(`Entrypoint not found: ${entry}`);
|
|
1016
997
|
const plugin = {
|
|
1017
998
|
name: "memfs",
|
|
1018
999
|
setup(build2) {
|
|
1019
1000
|
build2.onResolve({ filter: /^entry$/ }, () => ({ path: entry, namespace: "mem" }));
|
|
1020
1001
|
build2.onResolve({ filter: /.*/, namespace: "mem" }, (args) => {
|
|
1021
|
-
const isRelative = args.path.startsWith("./") || args.path.startsWith("../");
|
|
1022
|
-
const isAbsolute = args.path.startsWith("/");
|
|
1023
|
-
if (!isRelative && !isAbsolute)
|
|
1024
|
-
return null;
|
|
1025
1002
|
try {
|
|
1026
|
-
return { path: resolveWithExtensions(
|
|
1003
|
+
return { path: resolveWithExtensions(fileMap, args.importer || entry, args.path), namespace: "mem" };
|
|
1027
1004
|
} catch (error) {
|
|
1028
1005
|
return { errors: [{ text: error instanceof Error ? error.message : String(error) }] };
|
|
1029
1006
|
}
|
|
1030
1007
|
});
|
|
1031
1008
|
build2.onLoad({ filter: /.*/, namespace: "mem" }, (args) => {
|
|
1032
|
-
const contents =
|
|
1009
|
+
const contents = fileMap.get(args.path);
|
|
1033
1010
|
if (contents == null)
|
|
1034
1011
|
return { errors: [{ text: `Module not found: ${args.path}` }] };
|
|
1035
1012
|
const finalContents = /\.[tj]sx?$/.test(args.path) && hasAssetMacro(contents) ? desugarAssetMacros(contents, args.path) : contents;
|
|
@@ -1039,9 +1016,8 @@ async function buildInMemory(entrypoint, inputFiles, format = "esm") {
|
|
|
1039
1016
|
};
|
|
1040
1017
|
const result = await esbuild.build({
|
|
1041
1018
|
stdin: { contents: `import "entry";`, loader: "js", sourcefile: "bootstrap.js" },
|
|
1042
|
-
|
|
1019
|
+
inject: [resolveInject()],
|
|
1043
1020
|
define: { RAD2DEG: "57.29577951308232", DEG2RAD: "0.017453292519943295" },
|
|
1044
|
-
inject: runtime.inject,
|
|
1045
1021
|
bundle: true,
|
|
1046
1022
|
write: false,
|
|
1047
1023
|
format,
|
|
@@ -1051,13 +1027,16 @@ async function buildInMemory(entrypoint, inputFiles, format = "esm") {
|
|
|
1051
1027
|
});
|
|
1052
1028
|
const output = result.outputFiles?.[0];
|
|
1053
1029
|
if (!output)
|
|
1054
|
-
throw new
|
|
1030
|
+
throw new Error("Compilation produced no output");
|
|
1055
1031
|
return output.text;
|
|
1056
|
-
}
|
|
1032
|
+
};
|
|
1057
1033
|
|
|
1058
|
-
// src/compile/
|
|
1059
|
-
var buildHeader = (name, code) => {
|
|
1034
|
+
// ../sdk/src/compile/header.ts
|
|
1035
|
+
var buildHeader = (name, code, opts = {}) => {
|
|
1060
1036
|
let header = `// name: ${name.slice(0, 20)}
|
|
1037
|
+
`;
|
|
1038
|
+
if (opts.icon)
|
|
1039
|
+
header += `// icon: ${opts.icon}
|
|
1061
1040
|
`;
|
|
1062
1041
|
header += `// last-updated: ${new Date().toISOString()}
|
|
1063
1042
|
`;
|
|
@@ -1077,6 +1056,9 @@ var buildHeader = (name, code) => {
|
|
|
1077
1056
|
`;
|
|
1078
1057
|
else if (code.includes("_creator.createEngine"))
|
|
1079
1058
|
header += `// gl: defer
|
|
1059
|
+
`;
|
|
1060
|
+
if (code.includes("_creator2d."))
|
|
1061
|
+
header += `// 2d: enable
|
|
1080
1062
|
`;
|
|
1081
1063
|
if (code.includes("_creator.createARController"))
|
|
1082
1064
|
header += "// ar: enable";
|
|
@@ -1084,6 +1066,8 @@ var buildHeader = (name, code) => {
|
|
|
1084
1066
|
`;
|
|
1085
1067
|
return header;
|
|
1086
1068
|
};
|
|
1069
|
+
|
|
1070
|
+
// ../sdk/src/compile/compileProject.ts
|
|
1087
1071
|
var detectEntry = (entries) => {
|
|
1088
1072
|
let entry = "";
|
|
1089
1073
|
let max = -1;
|
|
@@ -1101,7 +1085,7 @@ var detectEntry = (entries) => {
|
|
|
1101
1085
|
var compileProject = async (opts) => {
|
|
1102
1086
|
const entry = opts.entryOverride ?? detectEntry(opts.entries);
|
|
1103
1087
|
if (!entry) {
|
|
1104
|
-
throw new
|
|
1088
|
+
throw new Error("Couldn't find an entrypoint (a top-level .ts/.js file with no `export`). Pass entryOverride.");
|
|
1105
1089
|
}
|
|
1106
1090
|
const files = {};
|
|
1107
1091
|
for (const e of opts.entries) {
|
|
@@ -1119,12 +1103,24 @@ var compileProject = async (opts) => {
|
|
|
1119
1103
|
} else if (e.path.toLowerCase().endsWith(".svg")) {
|
|
1120
1104
|
files[e.path] = `export default SvgSource(\`${e.text ?? ""}\`)`;
|
|
1121
1105
|
} else {
|
|
1122
|
-
files[e.path] =
|
|
1106
|
+
files[e.path] = e.text ?? "";
|
|
1123
1107
|
}
|
|
1124
1108
|
}
|
|
1125
|
-
const code = await
|
|
1126
|
-
return opts.header === false ? code : buildHeader(opts.name, code) + code;
|
|
1109
|
+
const code = await bundleProject(entry, files, opts.format ?? "esm");
|
|
1110
|
+
return opts.header === false ? code : buildHeader(opts.name, code, { icon: opts.icon }) + code;
|
|
1127
1111
|
};
|
|
1112
|
+
// src/compile/projectCompile.ts
|
|
1113
|
+
var vendoredInject = join9(dirname5(fileURLToPath2(import.meta.url)), "..", "runtime", "inject.js");
|
|
1114
|
+
if (existsSync6(vendoredInject))
|
|
1115
|
+
process.env.LECODES_SDK_INJECT = vendoredInject;
|
|
1116
|
+
var compileProject2 = (opts) => compileProject({
|
|
1117
|
+
entries: opts.entries.map((e) => ({ path: e.path, type: e.type, text: e.text, fileSrc: e.fileSrc, shaders: e.shaders })),
|
|
1118
|
+
name: opts.name,
|
|
1119
|
+
publicUrl: opts.publicUrl,
|
|
1120
|
+
entryOverride: opts.entryOverride,
|
|
1121
|
+
header: opts.header,
|
|
1122
|
+
format: opts.format
|
|
1123
|
+
});
|
|
1128
1124
|
|
|
1129
1125
|
// src/commands/preview.ts
|
|
1130
1126
|
var preview = async (args) => {
|
|
@@ -1137,7 +1133,7 @@ var preview = async (args) => {
|
|
|
1137
1133
|
const project = await getProject(apiUrl, token, manifest.uuid);
|
|
1138
1134
|
const { entries, warnings } = collectEntries(root, manifest, project);
|
|
1139
1135
|
note("Compiling…");
|
|
1140
|
-
const js = await
|
|
1136
|
+
const js = await compileProject2({
|
|
1141
1137
|
entries,
|
|
1142
1138
|
name: manifest.name,
|
|
1143
1139
|
publicUrl: flagStr(args, "public-url") ?? apiUrl,
|
|
@@ -1150,7 +1146,7 @@ var preview = async (args) => {
|
|
|
1150
1146
|
if (out && isNullSink(out)) {
|
|
1151
1147
|
note(`Discarded output (${out})`);
|
|
1152
1148
|
} else if (out) {
|
|
1153
|
-
|
|
1149
|
+
writeFileSync7(resolve3(out), js);
|
|
1154
1150
|
note(`Wrote ${out} (${js.length} bytes)`);
|
|
1155
1151
|
} else {
|
|
1156
1152
|
process.stdout.write(js);
|
|
@@ -1162,8 +1158,8 @@ var preview = async (args) => {
|
|
|
1162
1158
|
};
|
|
1163
1159
|
|
|
1164
1160
|
// src/commands/render.ts
|
|
1165
|
-
import { writeFileSync as
|
|
1166
|
-
import { resolve as
|
|
1161
|
+
import { writeFileSync as writeFileSync8 } from "node:fs";
|
|
1162
|
+
import { resolve as resolve4 } from "node:path";
|
|
1167
1163
|
var DEVICE_SAFE_AREA = {
|
|
1168
1164
|
none: [0, 0, 0, 0],
|
|
1169
1165
|
iphone: [47, 0, 34, 0],
|
|
@@ -1202,7 +1198,7 @@ var render = async (args) => {
|
|
|
1202
1198
|
const project = await getProject(apiUrl, token, manifest.uuid);
|
|
1203
1199
|
const { entries, warnings } = collectEntries(root, manifest, project);
|
|
1204
1200
|
note("Compiling…");
|
|
1205
|
-
const js = await
|
|
1201
|
+
const js = await compileProject2({
|
|
1206
1202
|
entries,
|
|
1207
1203
|
name: manifest.name,
|
|
1208
1204
|
publicUrl: flagStr(args, "public-url") ?? apiUrl,
|
|
@@ -1250,7 +1246,7 @@ var render = async (args) => {
|
|
|
1250
1246
|
if (isNullSink(pngFlag)) {
|
|
1251
1247
|
note(`Discarded PNG (${pngFlag})`);
|
|
1252
1248
|
} else {
|
|
1253
|
-
|
|
1249
|
+
writeFileSync8(resolve4(pngFlag), png);
|
|
1254
1250
|
note(`Wrote ${pngFlag} (${png.length} bytes, ${width}x${height})`);
|
|
1255
1251
|
}
|
|
1256
1252
|
return done((cb) => cb());
|
|
@@ -1265,7 +1261,7 @@ var render = async (args) => {
|
|
|
1265
1261
|
return done((cb) => cb());
|
|
1266
1262
|
}
|
|
1267
1263
|
if (out) {
|
|
1268
|
-
|
|
1264
|
+
writeFileSync8(resolve4(out), result.text);
|
|
1269
1265
|
note(`Wrote ${out} (${result.text.length} bytes)`);
|
|
1270
1266
|
return done((cb) => cb());
|
|
1271
1267
|
}
|
|
@@ -1276,8 +1272,8 @@ var render = async (args) => {
|
|
|
1276
1272
|
};
|
|
1277
1273
|
|
|
1278
1274
|
// src/commands/pull.ts
|
|
1279
|
-
import { existsSync as
|
|
1280
|
-
import { dirname as
|
|
1275
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync7, rmSync, writeFileSync as writeFileSync9 } from "node:fs";
|
|
1276
|
+
import { dirname as dirname6, join as join10 } from "node:path";
|
|
1281
1277
|
var pull = async (args) => {
|
|
1282
1278
|
const root = findProjectRoot(process.cwd());
|
|
1283
1279
|
const manifest = readManifest(root);
|
|
@@ -1297,8 +1293,8 @@ var pull = async (args) => {
|
|
|
1297
1293
|
const remotePaths = new Set([...buildPaths(project.assets).entries()].filter(([id]) => project.assets.find((a) => a.id === id)?.type !== "folder").map(([, path]) => path));
|
|
1298
1294
|
for (const path of Object.keys(manifest.files)) {
|
|
1299
1295
|
if (!remotePaths.has(path)) {
|
|
1300
|
-
const abs =
|
|
1301
|
-
if (
|
|
1296
|
+
const abs = join10(root, ...path.replace(/^\//, "").split("/"));
|
|
1297
|
+
if (existsSync7(abs))
|
|
1302
1298
|
rmSync(abs);
|
|
1303
1299
|
}
|
|
1304
1300
|
}
|
|
@@ -1336,18 +1332,18 @@ var pullPaths = async (root, manifest, project, paths, apiUrl, token) => {
|
|
|
1336
1332
|
const files = { ...manifest.files };
|
|
1337
1333
|
for (const asset of targets) {
|
|
1338
1334
|
const key = pathById.get(asset.id);
|
|
1339
|
-
const abs =
|
|
1340
|
-
|
|
1335
|
+
const abs = join10(root, ...key.replace(/^\//, "").split("/"));
|
|
1336
|
+
mkdirSync7(dirname6(abs), { recursive: true });
|
|
1341
1337
|
let sha;
|
|
1342
1338
|
if (asset.type === "file") {
|
|
1343
1339
|
if (!asset.file?.src)
|
|
1344
1340
|
continue;
|
|
1345
1341
|
const bytes = await downloadBlob(apiUrl, asset.file.src);
|
|
1346
|
-
|
|
1342
|
+
writeFileSync9(abs, bytes);
|
|
1347
1343
|
sha = sha256(bytes);
|
|
1348
1344
|
} else {
|
|
1349
1345
|
const text = asset.text ?? "";
|
|
1350
|
-
|
|
1346
|
+
writeFileSync9(abs, text);
|
|
1351
1347
|
sha = sha256(text);
|
|
1352
1348
|
}
|
|
1353
1349
|
files[key] = { id: asset.id, type: kindOf2(asset.type), sha };
|
|
@@ -1493,6 +1489,9 @@ ${c.bold("Commands:")}
|
|
|
1493
1489
|
--token <pat> store a token from the web UI instead
|
|
1494
1490
|
--api <url> API origin (default https://le.codes)
|
|
1495
1491
|
--web <url> app origin for the browser flow
|
|
1492
|
+
create <name> [dir] Create a new project on the server and scaffold it locally
|
|
1493
|
+
(types from the server + tsconfig + a starter main.ts)
|
|
1494
|
+
--team <uuid> create it inside a team
|
|
1496
1495
|
clone <uuid|url> [dir] Download a project's files + types into a new folder
|
|
1497
1496
|
--no-types skip the .d.ts / tsconfig generation
|
|
1498
1497
|
status Show local changes vs the last sync
|
|
@@ -1525,11 +1524,11 @@ ${c.bold("Commands:")}
|
|
|
1525
1524
|
--logs forward the app's console output (to stderr)
|
|
1526
1525
|
|
|
1527
1526
|
Config lives in ~/.lecodes/config.json (override with LECODES_API / LECODES_TOKEN).`;
|
|
1528
|
-
var commands = { login, clone, status, diff, pull, push, preview, render };
|
|
1527
|
+
var commands = { login, create, clone, status, diff, pull, push, preview, render };
|
|
1529
1528
|
var readVersion = () => {
|
|
1530
1529
|
try {
|
|
1531
|
-
const here =
|
|
1532
|
-
return JSON.parse(readFileSync8(
|
|
1530
|
+
const here = dirname7(fileURLToPath3(import.meta.url));
|
|
1531
|
+
return JSON.parse(readFileSync8(join11(here, "..", "package.json"), "utf8")).version ?? "unknown";
|
|
1533
1532
|
} catch {
|
|
1534
1533
|
return "unknown";
|
|
1535
1534
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lecodes-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Clone, edit and push LeCodes projects from your machine.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
}
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"lecodes-renderer": "
|
|
41
|
+
"lecodes-renderer": "workspace:*",
|
|
42
|
+
"sdk": "workspace:*"
|
|
42
43
|
}
|
|
43
44
|
}
|