@scaffscript/core 0.2.3 → 0.2.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.cjs +632 -472
- package/package.json +41 -41
package/dist/index.cjs
CHANGED
|
@@ -314,7 +314,7 @@ async function getScaffConfig() {
|
|
|
314
314
|
};
|
|
315
315
|
}
|
|
316
316
|
// src/parser/regex.ts
|
|
317
|
-
var commentRegex =
|
|
317
|
+
var commentRegex = /(?<!\/)\/\/(?!\/)[^\n]*|\/\*(?!\*)[\s\S]*?\*\//g;
|
|
318
318
|
var implRegex = /impl\s+(?<name>[\w+]+)\s+\{\s+(?<body>[.\s\S]+?)\}/g;
|
|
319
319
|
var implHeaderRegex = /impl\s+(?<name>\w+)\s*\{/g;
|
|
320
320
|
var fnParamsRegex = /\((?<params>[^)]*)\)/g;
|
|
@@ -344,14 +344,14 @@ function getTabLevels(str, tabType) {
|
|
|
344
344
|
// package.json
|
|
345
345
|
var package_default = {
|
|
346
346
|
name: "@scaffscript/core",
|
|
347
|
-
version: "0.2.
|
|
347
|
+
version: "0.2.6",
|
|
348
348
|
repository: {
|
|
349
349
|
type: "git",
|
|
350
350
|
url: "https://github.com/undervolta/scaffscript"
|
|
351
351
|
},
|
|
352
352
|
main: "dist/index.cjs",
|
|
353
353
|
devDependencies: {
|
|
354
|
-
"@types/bun": "
|
|
354
|
+
"@types/bun": "^1.3.11"
|
|
355
355
|
},
|
|
356
356
|
peerDependencies: {
|
|
357
357
|
typescript: "^5"
|
|
@@ -516,6 +516,362 @@ async function readAndSplitFiles(files, config) {
|
|
|
516
516
|
}
|
|
517
517
|
return res;
|
|
518
518
|
}
|
|
519
|
+
// src/parser/import-module.ts
|
|
520
|
+
function countTabsBeforeSubstring(str, sub, tabChar) {
|
|
521
|
+
const idx = str.indexOf(sub);
|
|
522
|
+
if (idx === -1)
|
|
523
|
+
return -1;
|
|
524
|
+
const lineStart = str.lastIndexOf(`
|
|
525
|
+
`, idx - 1) + 1;
|
|
526
|
+
const segment = str.slice(lineStart, idx);
|
|
527
|
+
let count = 0;
|
|
528
|
+
for (const ch of segment) {
|
|
529
|
+
if (ch === tabChar)
|
|
530
|
+
count++;
|
|
531
|
+
else
|
|
532
|
+
break;
|
|
533
|
+
}
|
|
534
|
+
return count;
|
|
535
|
+
}
|
|
536
|
+
function resolveImportPath(filePath, importPath, config) {
|
|
537
|
+
if (!config.path)
|
|
538
|
+
return resolvePath(`${filePath}/${importPath}`);
|
|
539
|
+
const useWildcard = Object.keys(config.path).filter((k) => k.endsWith("*")).find((k) => importPath.startsWith(k.slice(0, -1)));
|
|
540
|
+
if (useWildcard) {
|
|
541
|
+
const pathAlias = config.path[useWildcard]?.replace("*", "");
|
|
542
|
+
const dynPath = importPath.replace(useWildcard.slice(0, -2), "");
|
|
543
|
+
if (!pathAlias) {
|
|
544
|
+
log.error(`Path \x1B[33m${importPath}\x1B[0m not found in path aliases. Aborting...`);
|
|
545
|
+
return "";
|
|
546
|
+
}
|
|
547
|
+
if (pathAlias.startsWith("~")) {
|
|
548
|
+
return resolvePath(`${config.source}/${pathAlias.replace("~/", "").replace("~", "")}${dynPath}`);
|
|
549
|
+
}
|
|
550
|
+
return resolvePath(`${filePath}/${pathAlias}${dynPath}`);
|
|
551
|
+
} else if (config.path[importPath]) {
|
|
552
|
+
const pathAlias = config.path[importPath];
|
|
553
|
+
if (pathAlias.startsWith("~")) {
|
|
554
|
+
return resolvePath(`${config.source}/${pathAlias.replace("~/", "").replace("~", "")}`);
|
|
555
|
+
}
|
|
556
|
+
return resolvePath(`${filePath}/${pathAlias}`);
|
|
557
|
+
}
|
|
558
|
+
return resolvePath(`${filePath}/${importPath}`);
|
|
559
|
+
}
|
|
560
|
+
async function getModuleUsage(module2, fileGroup, file, config) {
|
|
561
|
+
const matches = [...file.content.matchAll(modControlRegex)].filter((match) => match.groups.cmd !== "export");
|
|
562
|
+
const limit = 10;
|
|
563
|
+
const results = [];
|
|
564
|
+
let isInvalid = false;
|
|
565
|
+
for (let i = 0;i < matches.length; i += limit) {
|
|
566
|
+
const batch = matches.slice(i, i + limit);
|
|
567
|
+
const res = await Promise.all(batch.map(async (match) => {
|
|
568
|
+
const { cmd, mod, path: path3 } = match.groups;
|
|
569
|
+
const res2 = {
|
|
570
|
+
cmd: null,
|
|
571
|
+
files: null,
|
|
572
|
+
modList: null,
|
|
573
|
+
targetPath: null,
|
|
574
|
+
targetStr: ""
|
|
575
|
+
};
|
|
576
|
+
if (!(cmd && mod && path3)) {
|
|
577
|
+
log.error(`Invalid module control statement: \x1B[34m${cmd} ${mod} from ${path3}\x1B[0m in \x1B[33m${file.name}\x1B[0m from \x1B[32m${file.path}\x1B[0m. Aborting...`);
|
|
578
|
+
isInvalid = true;
|
|
579
|
+
return null;
|
|
580
|
+
}
|
|
581
|
+
const fromPath = normalizePath(resolveImportPath(file.path, path3.slice(1, -1), config));
|
|
582
|
+
const modList = {};
|
|
583
|
+
const alias = {};
|
|
584
|
+
if (!module2[fromPath]) {
|
|
585
|
+
if (cmd === "include" && mod.startsWith("{") && (mod.includes('"') || mod.includes("'"))) {
|
|
586
|
+
const files = mod.slice(1, -1).split(",").map((m) => m.trim());
|
|
587
|
+
const filePaths = [];
|
|
588
|
+
for (const f of files) {
|
|
589
|
+
const filePath = normalizePath(resolvePath(`${file.path}/${f.slice(1, -1)}`));
|
|
590
|
+
const targetFile = fileGroup.normal.find((fl) => {
|
|
591
|
+
let targetFile2 = `${fl.path}/${fl.name}`;
|
|
592
|
+
let currFile = filePath;
|
|
593
|
+
if (!targetFile2.endsWith(".gml"))
|
|
594
|
+
targetFile2 += ".gml";
|
|
595
|
+
if (!currFile.endsWith(".gml"))
|
|
596
|
+
currFile += ".gml";
|
|
597
|
+
return targetFile2 === currFile;
|
|
598
|
+
});
|
|
599
|
+
if (targetFile)
|
|
600
|
+
filePaths.push(targetFile);
|
|
601
|
+
else if (await fileExists(filePath))
|
|
602
|
+
filePaths.push(filePath);
|
|
603
|
+
else {
|
|
604
|
+
if (config.onNotFound === "error") {
|
|
605
|
+
log.error(`File \x1B[33m${f.slice(1, -1)}\x1B[0m from \x1B[32m${file.path}\x1B[0m not found. Aborting...`);
|
|
606
|
+
isInvalid = true;
|
|
607
|
+
return null;
|
|
608
|
+
} else
|
|
609
|
+
log.warn(`File \x1B[33m${f.slice(1, -1)}\x1B[0m from \x1B[32m${file.path}\x1B[0m not found. Skipping this file...`);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
return {
|
|
613
|
+
cmd,
|
|
614
|
+
files: filePaths,
|
|
615
|
+
modList,
|
|
616
|
+
targetPath: fromPath,
|
|
617
|
+
targetStr: match[0]
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
log.error(`Path \x1B[33m${fromPath}\x1B[0m doesn't have any exported modules. Aborting...`);
|
|
621
|
+
isInvalid = true;
|
|
622
|
+
return null;
|
|
623
|
+
}
|
|
624
|
+
if (mod === "*" || mod.startsWith("{") && mod.endsWith("}")) {
|
|
625
|
+
const targetMods = mod === "*" ? null : mod.slice(1, -1).split(",").map((m) => {
|
|
626
|
+
const split = m.split(":");
|
|
627
|
+
const key = split[0].trim();
|
|
628
|
+
if (split.length === 1)
|
|
629
|
+
alias[key] = key;
|
|
630
|
+
else
|
|
631
|
+
alias[key] = split[1].trim();
|
|
632
|
+
if (!module2[fromPath]) {
|
|
633
|
+
if (config.onNotFound === "error") {
|
|
634
|
+
log.error(`Path \x1B[33m${fromPath}\x1B[0m doesn't have any exported modules. Aborting...`);
|
|
635
|
+
isInvalid = true;
|
|
636
|
+
} else
|
|
637
|
+
log.warn(`Path \x1B[33m${fromPath}\x1B[0m doesn't have any exported modules. Skipping this module...`);
|
|
638
|
+
return null;
|
|
639
|
+
}
|
|
640
|
+
if (!module2[fromPath][key]) {
|
|
641
|
+
if (config.onNotFound === "error") {
|
|
642
|
+
log.error(`Module \x1B[33m${key}\x1B[0m from \x1B[32m${fromPath}\x1B[0m not found. Aborting...`);
|
|
643
|
+
isInvalid = true;
|
|
644
|
+
} else
|
|
645
|
+
log.warn(`Module \x1B[33m${key}\x1B[0m from \x1B[32m${fromPath}\x1B[0m not found. Skipping this module...`);
|
|
646
|
+
return null;
|
|
647
|
+
}
|
|
648
|
+
return key;
|
|
649
|
+
}).filter(Boolean);
|
|
650
|
+
Object.entries(module2[fromPath]).forEach(([key, value]) => {
|
|
651
|
+
if (mod === "*")
|
|
652
|
+
modList[key] = { name: key, as: key, value, usingAlias: false };
|
|
653
|
+
else if (targetMods.includes(key)) {
|
|
654
|
+
const usingAlias = key in alias && alias[key] !== key;
|
|
655
|
+
modList[alias[key] ?? key] = {
|
|
656
|
+
name: key,
|
|
657
|
+
as: alias[key] ?? key,
|
|
658
|
+
value,
|
|
659
|
+
usingAlias
|
|
660
|
+
};
|
|
661
|
+
if (usingAlias) {
|
|
662
|
+
if (!module2[fromPath])
|
|
663
|
+
module2[fromPath] = {};
|
|
664
|
+
module2[fromPath][`@${alias[key]}`] = value;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
});
|
|
668
|
+
} else {
|
|
669
|
+
if (!module2[fromPath][mod]) {
|
|
670
|
+
if (config.onNotFound === "error") {
|
|
671
|
+
log.error(`Module \x1B[33m${mod}\x1B[0m from \x1B[32m${fromPath}\x1B[0m not found. Aborting...`);
|
|
672
|
+
isInvalid = true;
|
|
673
|
+
} else
|
|
674
|
+
log.warn(`Module \x1B[33m${mod}\x1B[0m from \x1B[32m${fromPath}\x1B[0m not found. Skipping this module...`);
|
|
675
|
+
return res2;
|
|
676
|
+
}
|
|
677
|
+
modList[mod] = {
|
|
678
|
+
name: mod,
|
|
679
|
+
as: mod,
|
|
680
|
+
value: module2[fromPath][mod],
|
|
681
|
+
usingAlias: false
|
|
682
|
+
};
|
|
683
|
+
}
|
|
684
|
+
return {
|
|
685
|
+
cmd,
|
|
686
|
+
files: null,
|
|
687
|
+
modList,
|
|
688
|
+
targetPath: fromPath,
|
|
689
|
+
targetStr: match[0]
|
|
690
|
+
};
|
|
691
|
+
}));
|
|
692
|
+
if (isInvalid)
|
|
693
|
+
break;
|
|
694
|
+
results.push(...res);
|
|
695
|
+
}
|
|
696
|
+
return !isInvalid && results.every((r) => r) ? results : null;
|
|
697
|
+
}
|
|
698
|
+
async function implementModules(module2, fileGroup, file, config, mods) {
|
|
699
|
+
if (!mods)
|
|
700
|
+
mods = await getModuleUsage(module2, fileGroup, file, config);
|
|
701
|
+
if (!mods)
|
|
702
|
+
return null;
|
|
703
|
+
const toRemove = [...file.content.matchAll(modControlRegex)];
|
|
704
|
+
for (const rm of toRemove) {
|
|
705
|
+
if (rm.groups?.cmd !== "include")
|
|
706
|
+
file.content = file.content.replace(rm[0], "");
|
|
707
|
+
}
|
|
708
|
+
for (const mod of mods) {
|
|
709
|
+
if (!mod)
|
|
710
|
+
return null;
|
|
711
|
+
if (!mod.cmd)
|
|
712
|
+
return null;
|
|
713
|
+
switch (mod.cmd) {
|
|
714
|
+
case "include":
|
|
715
|
+
let toReplace = "";
|
|
716
|
+
if (!mod.files) {
|
|
717
|
+
if (!mod.modList)
|
|
718
|
+
return null;
|
|
719
|
+
const modEntries = Object.entries(mod.modList);
|
|
720
|
+
const modLen = modEntries.length;
|
|
721
|
+
const modIterator = modEntries.entries();
|
|
722
|
+
for (const [idx, [_, include]] of modIterator) {
|
|
723
|
+
if (idx > 0)
|
|
724
|
+
switch (include.value.type) {
|
|
725
|
+
case "function":
|
|
726
|
+
case "class":
|
|
727
|
+
case "type":
|
|
728
|
+
case "interface":
|
|
729
|
+
case "enum":
|
|
730
|
+
toReplace += `
|
|
731
|
+
`;
|
|
732
|
+
break;
|
|
733
|
+
}
|
|
734
|
+
if (include.value.type === "class")
|
|
735
|
+
toReplace += `${include.value.declaration} {
|
|
736
|
+
${include.value.body}
|
|
737
|
+
}`;
|
|
738
|
+
else
|
|
739
|
+
toReplace += include.value.parsedStr + `
|
|
740
|
+
`;
|
|
741
|
+
if (idx === modLen - 1)
|
|
742
|
+
toReplace += `
|
|
743
|
+
`;
|
|
744
|
+
}
|
|
745
|
+
file.content = file.content.replace(mod.targetStr, toReplace);
|
|
746
|
+
} else {
|
|
747
|
+
for (const fileOrPath of mod.files) {
|
|
748
|
+
if (typeof fileOrPath === "string") {
|
|
749
|
+
const content = await fsRuntime.readText(fileOrPath);
|
|
750
|
+
toReplace += content + `
|
|
751
|
+
|
|
752
|
+
`;
|
|
753
|
+
} else
|
|
754
|
+
toReplace += fileOrPath.content + `
|
|
755
|
+
|
|
756
|
+
`;
|
|
757
|
+
}
|
|
758
|
+
file.content = file.content.replace(mod.targetStr, toReplace);
|
|
759
|
+
}
|
|
760
|
+
break;
|
|
761
|
+
case "import":
|
|
762
|
+
const cmdMatches = [...file.content.matchAll(contentModRegex)];
|
|
763
|
+
const shortCmdMatches = [
|
|
764
|
+
...file.content.matchAll(contentModShortRegex)
|
|
765
|
+
];
|
|
766
|
+
const useMatches = [...file.content.matchAll(useModRegex)];
|
|
767
|
+
for (const match of cmdMatches) {
|
|
768
|
+
const { cmd: contentCmd, mod: contentMod } = match.groups;
|
|
769
|
+
if (!contentCmd || !contentMod) {
|
|
770
|
+
log.error(`Invalid content module statement: \x1B[34m${contentCmd} ${contentMod}\x1B[0m in \x1B[33m${file.name}\x1B[0m from \x1B[32m${file.path}\x1B[0m. Aborting...`);
|
|
771
|
+
return null;
|
|
772
|
+
}
|
|
773
|
+
if (!(`@${contentMod}` in mod.modList) && !(contentMod in mod.modList))
|
|
774
|
+
continue;
|
|
775
|
+
if (config.debugLevel >= 1)
|
|
776
|
+
log.debug(`Content module statement found: \x1B[34m${contentCmd} ${contentMod}\x1B[0m in \x1B[33m${file.name === "" ? "index" : file.name}\x1B[0m from \x1B[32m${file.path}\x1B[0m.`);
|
|
777
|
+
let parsedStr = "";
|
|
778
|
+
switch (contentCmd) {
|
|
779
|
+
case "content":
|
|
780
|
+
const tabChar = config.tabType === "1t" ? "\t" : config.tabType === "2s" ? " " : " ";
|
|
781
|
+
const tabCnt = countTabsBeforeSubstring(file.content, match[0], tabChar);
|
|
782
|
+
const usedMod = module2[mod.targetPath][`@${contentMod}` in module2[mod.targetPath] ? `@${contentMod}` : contentMod];
|
|
783
|
+
parsedStr = usedMod?.type !== "class" ? usedMod?.parsedStr ?? "" : `${usedMod?.declaration} {
|
|
784
|
+
${usedMod?.body}
|
|
785
|
+
}`;
|
|
786
|
+
if (tabCnt > 0) {
|
|
787
|
+
const tabLevels = getTabLevels(parsedStr, config.tabType).map((l) => l + tabCnt);
|
|
788
|
+
file.content = file.content.replace(match[0], parsedStr.split(`
|
|
789
|
+
`).map((l, i) => tabLevels[i] ? insertTabs(tabLevels[i], config.tabType) + l : l).join(`
|
|
790
|
+
`));
|
|
791
|
+
} else
|
|
792
|
+
file.content = file.content.replace(match[0], parsedStr);
|
|
793
|
+
break;
|
|
794
|
+
case "nameof":
|
|
795
|
+
parsedStr = module2[mod.targetPath][`@${contentMod}` in module2[mod.targetPath] ? `@${contentMod}` : contentMod].name;
|
|
796
|
+
file.content = file.content.replace(`@nameof ${contentMod}`, parsedStr);
|
|
797
|
+
break;
|
|
798
|
+
case "typeof":
|
|
799
|
+
parsedStr = module2[mod.targetPath][`@${contentMod}` in module2[mod.targetPath] ? `@${contentMod}` : contentMod].type;
|
|
800
|
+
file.content = file.content.replace(`@typeof ${contentMod}`, `"${parsedStr}"`);
|
|
801
|
+
break;
|
|
802
|
+
case "valueof":
|
|
803
|
+
parsedStr = module2[mod.targetPath][`@${contentMod}` in module2[mod.targetPath] ? `@${contentMod}` : contentMod].value;
|
|
804
|
+
file.content = file.content.replace(`@valueof ${contentMod}`, parsedStr);
|
|
805
|
+
break;
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
for (const match of shortCmdMatches) {
|
|
809
|
+
const { mod: contentMod } = match.groups;
|
|
810
|
+
if (!contentMod) {
|
|
811
|
+
log.error(`Invalid content module statement: \x1B[34m@:${contentMod}\x1B[0m in \x1B[33m${file.name}\x1B[0m from \x1B[32m${file.path}\x1B[0m. Aborting...`);
|
|
812
|
+
return null;
|
|
813
|
+
}
|
|
814
|
+
if (config.debugLevel >= 1)
|
|
815
|
+
log.debug(`Valueof module statement found: \x1B[34m${contentMod}\x1B[0m in \x1B[33m${file.name}\x1B[0m from \x1B[32m${file.path}\x1B[0m.`);
|
|
816
|
+
if (!(`@${contentMod}` in mod.modList) && !(contentMod in mod.modList))
|
|
817
|
+
continue;
|
|
818
|
+
const parsedStr = module2[mod.targetPath][`@${contentMod}` in module2[mod.targetPath] ? `@${contentMod}` : contentMod].value;
|
|
819
|
+
file.content = file.content.replace(`@:${contentMod}`, parsedStr);
|
|
820
|
+
}
|
|
821
|
+
for (const match of useMatches) {
|
|
822
|
+
const { mod: contentMod, body } = match.groups;
|
|
823
|
+
if (!contentMod || !body) {
|
|
824
|
+
log.error(`Invalid content module statement: \x1B[34m@use ${contentMod} ${body}\x1B[0m in \x1B[33m${file.name}\x1B[0m from \x1B[32m${file.path}\x1B[0m. Aborting...`);
|
|
825
|
+
return null;
|
|
826
|
+
}
|
|
827
|
+
if (!(`@${contentMod}` in mod.modList) && !(contentMod in mod.modList))
|
|
828
|
+
continue;
|
|
829
|
+
if (config.debugLevel >= 1)
|
|
830
|
+
log.debug(`Use module statement found: \x1B[34m@use ${contentMod} ${body}\x1B[0m in \x1B[33m${file.name}\x1B[0m from \x1B[32m${file.path}\x1B[0m.`);
|
|
831
|
+
const lines = body.slice(1, -1).split(`
|
|
832
|
+
`).filter(Boolean);
|
|
833
|
+
const pairs = lines.map((l) => l.split(":").map((p) => {
|
|
834
|
+
const delimIdx = p.lastIndexOf(",");
|
|
835
|
+
return p.slice(0, delimIdx === -1 ? undefined : delimIdx).trim();
|
|
836
|
+
}));
|
|
837
|
+
const tabChar = config.tabType === "1t" ? "\t" : config.tabType === "2s" ? " " : " ";
|
|
838
|
+
const tabCnt = countTabsBeforeSubstring(file.content.slice(file.content.lastIndexOf(`
|
|
839
|
+
`, match.index), match.index + match[0].length), "@", tabChar);
|
|
840
|
+
const tabLevels = getTabLevels(body, config.tabType).map((l) => l + tabCnt);
|
|
841
|
+
const currMod = module2[mod.targetPath][`@${contentMod}` in module2[mod.targetPath] ? `@${contentMod}` : contentMod];
|
|
842
|
+
const modMember = Object.entries(currMod.member);
|
|
843
|
+
const tabLevel = tabCnt + tabLevels[Math.min(1, tabLevels.length - 1)];
|
|
844
|
+
let res = `{
|
|
845
|
+
`;
|
|
846
|
+
for (const [idx, [mName, mVal]] of modMember.entries()) {
|
|
847
|
+
const pairIdx = pairs.findIndex((p) => p[0] === mName);
|
|
848
|
+
const pair = pairIdx > -1 ? pairs[pairIdx] : null;
|
|
849
|
+
const value = pair ? pair.length === 2 ? pair[1] : mVal.value : mVal.value;
|
|
850
|
+
if (value) {
|
|
851
|
+
res += `${insertTabs(tabLevel, config.tabType)}${mName}: ${value}${idx < modMember.length - 2 ? "," : ""}
|
|
852
|
+
`;
|
|
853
|
+
}
|
|
854
|
+
if (pairIdx > -1)
|
|
855
|
+
swapAndPop(pairs, pairIdx);
|
|
856
|
+
}
|
|
857
|
+
for (const [idx, pair] of pairs.entries()) {
|
|
858
|
+
if (idx === 0)
|
|
859
|
+
res = res.slice(0, -1) + `,
|
|
860
|
+
`;
|
|
861
|
+
res += `${insertTabs(tabLevel, config.tabType)}${pair[0]}: ${pair[1]}${idx < pairs.length - 1 ? "," : ""}
|
|
862
|
+
`;
|
|
863
|
+
}
|
|
864
|
+
res += insertTabs(tabCnt, config.tabType) + "}";
|
|
865
|
+
file.content = file.content.replace(match[0], res);
|
|
866
|
+
}
|
|
867
|
+
break;
|
|
868
|
+
}
|
|
869
|
+
file.content = file.content.trim() + `
|
|
870
|
+
`;
|
|
871
|
+
}
|
|
872
|
+
return mods;
|
|
873
|
+
}
|
|
874
|
+
|
|
519
875
|
// src/parser/export-module.ts
|
|
520
876
|
function inferType(value) {
|
|
521
877
|
value = value.trim();
|
|
@@ -637,6 +993,7 @@ function countBraces(line) {
|
|
|
637
993
|
return count;
|
|
638
994
|
}
|
|
639
995
|
function parseFnParams(str) {
|
|
996
|
+
fnParamsRegex.lastIndex = 0;
|
|
640
997
|
const match = str.match(fnParamsRegex);
|
|
641
998
|
let names = [];
|
|
642
999
|
let defaults = [];
|
|
@@ -657,9 +1014,10 @@ function parseFnParams(str) {
|
|
|
657
1014
|
return { names, defaults, combined };
|
|
658
1015
|
}
|
|
659
1016
|
function convertClassMethods(classBody) {
|
|
1017
|
+
const reservedMethodNames = new Set(["if", "for", "while", "switch", "catch", "do", "else", "try", "finally"]);
|
|
660
1018
|
const methodRegex = /(\w+)\s*\(([^)]*)\)\s*{([\s\S]*?)}/g;
|
|
661
1019
|
return classBody.replace(methodRegex, (match, methodName, params, body) => {
|
|
662
|
-
if (methodName === "function")
|
|
1020
|
+
if (methodName === "function" || reservedMethodNames.has(methodName))
|
|
663
1021
|
return match;
|
|
664
1022
|
return `${methodName} = function(${params.replaceAll("?", " = undefined")}) {${body}}`;
|
|
665
1023
|
});
|
|
@@ -718,7 +1076,14 @@ function getExportedModules(files, config) {
|
|
|
718
1076
|
const body = funcCode.slice(funcCode.indexOf("{")).trim();
|
|
719
1077
|
const params = parseFnParams(funcCode);
|
|
720
1078
|
const parsedStr = `function ${name}(${params.combined.join(", ")}) ${body}`;
|
|
721
|
-
module2[filePath][name] = {
|
|
1079
|
+
module2[filePath][name] = {
|
|
1080
|
+
name,
|
|
1081
|
+
value: body.slice(1, -1),
|
|
1082
|
+
type: "function",
|
|
1083
|
+
parsedStr,
|
|
1084
|
+
header: funcCode.slice(0, funcCode.indexOf("{")).trim(),
|
|
1085
|
+
blockValue: insertTabs(1, config.tabType) + body.slice(1, -1)
|
|
1086
|
+
};
|
|
722
1087
|
}
|
|
723
1088
|
} else if (line.startsWith("export class ")) {
|
|
724
1089
|
const classLines = [];
|
|
@@ -754,7 +1119,14 @@ function getExportedModules(files, config) {
|
|
|
754
1119
|
const parsedStr = `function ${name}(${constructor.replaceAll("?", " = undefined")}) constructor {
|
|
755
1120
|
${insertTabs(1, config.tabType)}${classBody}
|
|
756
1121
|
}`;
|
|
757
|
-
module2[filePath][name] = {
|
|
1122
|
+
module2[filePath][name] = {
|
|
1123
|
+
name,
|
|
1124
|
+
value: classCode.replace("export ", ""),
|
|
1125
|
+
type: "class",
|
|
1126
|
+
parsedStr,
|
|
1127
|
+
declaration: `function ${name}(${constructor.replaceAll("?", " = undefined")}) constructor`,
|
|
1128
|
+
body: `${insertTabs(1, config.tabType)}${classBody}`
|
|
1129
|
+
};
|
|
758
1130
|
}
|
|
759
1131
|
} else if (line.startsWith("export interface ")) {
|
|
760
1132
|
const interfaceLines = [];
|
|
@@ -857,14 +1229,28 @@ ${insertTabs(1, config.tabType)}${classBody}
|
|
|
857
1229
|
const parsedStr = `${name} = function(${params.combined.join(", ")}) ${arrowBlock}`;
|
|
858
1230
|
if (!module2[filePath])
|
|
859
1231
|
module2[filePath] = {};
|
|
860
|
-
module2[filePath][name] = {
|
|
1232
|
+
module2[filePath][name] = {
|
|
1233
|
+
name,
|
|
1234
|
+
value: arrowBlock.slice(1, -1),
|
|
1235
|
+
type: "function",
|
|
1236
|
+
header: `${name} = function(${params.combined.join(", ")})`,
|
|
1237
|
+
blockValue: arrowBlock,
|
|
1238
|
+
parsedStr
|
|
1239
|
+
};
|
|
861
1240
|
} else {
|
|
862
1241
|
const params = parseFnParams(valuePart);
|
|
863
1242
|
const body = valuePart.split("=>")[1].trim();
|
|
864
1243
|
const parsedStr = `${name} = function(${params.combined.join(", ")}) { return ${body}; }`;
|
|
865
1244
|
if (!module2[filePath])
|
|
866
1245
|
module2[filePath] = {};
|
|
867
|
-
module2[filePath][name] = {
|
|
1246
|
+
module2[filePath][name] = {
|
|
1247
|
+
name,
|
|
1248
|
+
value: body,
|
|
1249
|
+
type: "function",
|
|
1250
|
+
header: `${name} = function(${params.combined.join(", ")})`,
|
|
1251
|
+
blockValue: body,
|
|
1252
|
+
parsedStr
|
|
1253
|
+
};
|
|
868
1254
|
}
|
|
869
1255
|
} else if (valuePart.startsWith("function")) {
|
|
870
1256
|
if (valuePart.trim().endsWith("{")) {
|
|
@@ -886,12 +1272,27 @@ ${insertTabs(1, config.tabType)}${classBody}
|
|
|
886
1272
|
const parsedStr = `${name} = function(${params.combined.join(", ")}) ${funcBlock}`;
|
|
887
1273
|
if (!module2[filePath])
|
|
888
1274
|
module2[filePath] = {};
|
|
889
|
-
module2[filePath][name] = {
|
|
1275
|
+
module2[filePath][name] = {
|
|
1276
|
+
name,
|
|
1277
|
+
value: funcBlock.slice(1, -1),
|
|
1278
|
+
type: "function",
|
|
1279
|
+
header: `${name} = function(${params.combined.join(", ")})`,
|
|
1280
|
+
blockValue: funcBlock,
|
|
1281
|
+
parsedStr
|
|
1282
|
+
};
|
|
890
1283
|
} else {
|
|
1284
|
+
const params = parseFnParams(valuePart);
|
|
891
1285
|
const parsedStr = `${name} = ${valuePart}`;
|
|
892
1286
|
if (!module2[filePath])
|
|
893
1287
|
module2[filePath] = {};
|
|
894
|
-
module2[filePath][name] = {
|
|
1288
|
+
module2[filePath][name] = {
|
|
1289
|
+
name,
|
|
1290
|
+
value: line.replace("export ", ""),
|
|
1291
|
+
type: "function",
|
|
1292
|
+
header: `${name} = function(${params.combined.join(", ")})`,
|
|
1293
|
+
blockValue: valuePart,
|
|
1294
|
+
parsedStr
|
|
1295
|
+
};
|
|
895
1296
|
}
|
|
896
1297
|
} else {
|
|
897
1298
|
let varType = "var";
|
|
@@ -901,7 +1302,6 @@ ${insertTabs(1, config.tabType)}${classBody}
|
|
|
901
1302
|
varType = "let";
|
|
902
1303
|
else if (decl?.includes("var"))
|
|
903
1304
|
varType = "var";
|
|
904
|
-
const noVarKeyword = varType === "var" && !parts[0].includes("var");
|
|
905
1305
|
if (!module2[filePath])
|
|
906
1306
|
module2[filePath] = {};
|
|
907
1307
|
const parsedStr = varType !== "const" ? `${varType === "let" ? "" : "var "}${name} = ${valuePart};` : `#macro ${name} ${valuePart}`;
|
|
@@ -913,503 +1313,260 @@ ${insertTabs(1, config.tabType)}${classBody}
|
|
|
913
1313
|
}
|
|
914
1314
|
}
|
|
915
1315
|
retryLen = retryList.length;
|
|
916
|
-
while (retryCount < 10 && retryLastLen !== retryLen) {
|
|
917
|
-
for (const retry of retryList) {
|
|
918
|
-
if (!module2[retry.filePath])
|
|
919
|
-
continue;
|
|
920
|
-
if (!module2[retry.filePath][retry.targetName])
|
|
921
|
-
continue;
|
|
922
|
-
switch (module2[retry.filePath][retry.name].type) {
|
|
923
|
-
case "interface":
|
|
924
|
-
const currInterface = module2[retry.filePath][retry.name];
|
|
925
|
-
const extendsInterface = module2[retry.filePath][retry.targetName];
|
|
926
|
-
for (const [mName, m] of Object.entries(extendsInterface.member)) {
|
|
927
|
-
currInterface.member[mName] = { type: m.type, value: m.value };
|
|
928
|
-
}
|
|
929
|
-
break;
|
|
930
|
-
case "type":
|
|
931
|
-
const currType = module2[retry.filePath][retry.name];
|
|
932
|
-
const extendsType = module2[retry.filePath][retry.targetName];
|
|
933
|
-
for (const [mName, m] of Object.entries(extendsType.member)) {
|
|
934
|
-
currType.member[mName] = { type: m.type, value: m.value };
|
|
935
|
-
}
|
|
936
|
-
break;
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
retryLastLen = retryLen;
|
|
940
|
-
retryLen = retryList.length;
|
|
941
|
-
retryCount++;
|
|
942
|
-
}
|
|
943
|
-
return module2;
|
|
944
|
-
}
|
|
945
|
-
// src/parser/class-implement.ts
|
|
946
|
-
function convertArrowFn(str) {
|
|
947
|
-
return str.replace(arrowFnHeaderRegex, (match, _p1, _p2, _offset, _input, groups) => {
|
|
948
|
-
if (!groups?.name)
|
|
949
|
-
return match;
|
|
950
|
-
const rawParams = groups.params?.trim() ?? "";
|
|
951
|
-
const paramsSource = rawParams.startsWith("(") ? rawParams : `(${rawParams})`;
|
|
952
|
-
const params = parseFnParams(paramsSource);
|
|
953
|
-
return `${groups.name} = function(${params.combined.join(", ")})`;
|
|
954
|
-
});
|
|
955
|
-
}
|
|
956
|
-
function parseHeader(str, regex = implHeaderRegex) {
|
|
957
|
-
const results = [];
|
|
958
|
-
let match;
|
|
959
|
-
while ((match = regex.exec(str)) !== null) {
|
|
960
|
-
const name = match.groups.name;
|
|
961
|
-
const start = regex.lastIndex;
|
|
962
|
-
let braceCount = 1;
|
|
963
|
-
let inString = false;
|
|
964
|
-
let stringChar = "";
|
|
965
|
-
let i = start;
|
|
966
|
-
for (;i < str.length; i++) {
|
|
967
|
-
const char = str[i];
|
|
968
|
-
if (inString) {
|
|
969
|
-
if (char === stringChar && (i === 0 || str[i - 1] !== "\\")) {
|
|
970
|
-
inString = false;
|
|
971
|
-
}
|
|
972
|
-
} else {
|
|
973
|
-
if (char === '"' || char === "'") {
|
|
974
|
-
inString = true;
|
|
975
|
-
stringChar = char;
|
|
976
|
-
} else if (char === "{") {
|
|
977
|
-
braceCount++;
|
|
978
|
-
} else if (char === "}") {
|
|
979
|
-
braceCount--;
|
|
980
|
-
if (braceCount === 0)
|
|
981
|
-
break;
|
|
982
|
-
}
|
|
1316
|
+
while (retryCount < 10 && retryLastLen !== retryLen) {
|
|
1317
|
+
for (const retry of retryList) {
|
|
1318
|
+
if (!module2[retry.filePath])
|
|
1319
|
+
continue;
|
|
1320
|
+
if (!module2[retry.filePath][retry.targetName])
|
|
1321
|
+
continue;
|
|
1322
|
+
switch (module2[retry.filePath][retry.name].type) {
|
|
1323
|
+
case "interface":
|
|
1324
|
+
const currInterface = module2[retry.filePath][retry.name];
|
|
1325
|
+
const extendsInterface = module2[retry.filePath][retry.targetName];
|
|
1326
|
+
for (const [mName, m] of Object.entries(extendsInterface.member)) {
|
|
1327
|
+
currInterface.member[mName] = { type: m.type, value: m.value };
|
|
1328
|
+
}
|
|
1329
|
+
break;
|
|
1330
|
+
case "type":
|
|
1331
|
+
const currType = module2[retry.filePath][retry.name];
|
|
1332
|
+
const extendsType = module2[retry.filePath][retry.targetName];
|
|
1333
|
+
for (const [mName, m] of Object.entries(extendsType.member)) {
|
|
1334
|
+
currType.member[mName] = { type: m.type, value: m.value };
|
|
1335
|
+
}
|
|
1336
|
+
break;
|
|
983
1337
|
}
|
|
984
1338
|
}
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
1339
|
+
retryLastLen = retryLen;
|
|
1340
|
+
retryLen = retryList.length;
|
|
1341
|
+
retryCount++;
|
|
988
1342
|
}
|
|
989
|
-
return
|
|
1343
|
+
return module2;
|
|
990
1344
|
}
|
|
991
|
-
function
|
|
992
|
-
|
|
993
|
-
|
|
1345
|
+
function reexportModule(module2, file, config) {
|
|
1346
|
+
const reexportMatches = [...file.content.matchAll(modControlRegex)].filter((match) => match.groups?.cmd === "export");
|
|
1347
|
+
if (!reexportMatches.length)
|
|
994
1348
|
return false;
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
for (const file of fileGroup.scaff) {
|
|
1020
|
-
if (file.content.includes(`class ${className} {`)) {
|
|
1021
|
-
newFilePath = file.isIndex ? file.path : `${file.path}/${file.name}`;
|
|
1022
|
-
break;
|
|
1023
|
-
}
|
|
1024
|
-
}
|
|
1025
|
-
if (!newFilePath) {
|
|
1026
|
-
for (const file of fileGroup.generate) {
|
|
1027
|
-
if (file.content.includes(`class ${className} {`)) {
|
|
1028
|
-
newFilePath = file.isIndex ? file.path : `${file.path}/${file.name}`;
|
|
1029
|
-
break;
|
|
1030
|
-
}
|
|
1031
|
-
}
|
|
1349
|
+
for (const match of reexportMatches) {
|
|
1350
|
+
const { cmd, mod, path: path3 } = match.groups;
|
|
1351
|
+
if (!(cmd && mod && path3)) {
|
|
1352
|
+
log.error(`Invalid module control statement: \x1B[34m${cmd} ${mod} from ${path3}\x1B[0m in \x1B[33m${file.name}\x1B[0m from \x1B[32m${file.path}\x1B[0m. Aborting...`);
|
|
1353
|
+
return false;
|
|
1354
|
+
}
|
|
1355
|
+
const fromPath = normalizePath(resolveImportPath(file.path, path3.slice(1, -1), config));
|
|
1356
|
+
const thisPath = file.isIndex ? file.path : `${file.path}/${file.name}`;
|
|
1357
|
+
const alias = {};
|
|
1358
|
+
if (mod === "*" || mod.startsWith("{") && mod.endsWith("}")) {
|
|
1359
|
+
const targetMods = mod === "*" ? null : mod.slice(1, -1).split(",").map((m) => {
|
|
1360
|
+
const split = m.split(":");
|
|
1361
|
+
const key = split[0].trim();
|
|
1362
|
+
if (split.length === 1)
|
|
1363
|
+
alias[key] = key;
|
|
1364
|
+
else
|
|
1365
|
+
alias[key] = split[1].trim();
|
|
1366
|
+
if (!module2[fromPath]) {
|
|
1367
|
+
if (config.onNotFound === "error") {
|
|
1368
|
+
log.error(`Path \x1B[33m${fromPath}\x1B[0m doesn't have any exported modules. Aborting...`);
|
|
1369
|
+
return false;
|
|
1370
|
+
} else
|
|
1371
|
+
log.warn(`Path \x1B[33m${fromPath}\x1B[0m doesn't have any exported modules. Skipping this module...`);
|
|
1372
|
+
return false;
|
|
1032
1373
|
}
|
|
1033
|
-
if (!
|
|
1374
|
+
if (!module2[fromPath][key]) {
|
|
1034
1375
|
if (config.onNotFound === "error") {
|
|
1035
|
-
log.error(`
|
|
1376
|
+
log.error(`Module \x1B[33m${key}\x1B[0m from \x1B[32m${fromPath}\x1B[0m not found. Aborting...`);
|
|
1036
1377
|
return false;
|
|
1037
|
-
} else
|
|
1038
|
-
log.warn(`
|
|
1039
|
-
|
|
1040
|
-
}
|
|
1378
|
+
} else
|
|
1379
|
+
log.warn(`Module \x1B[33m${key}\x1B[0m from \x1B[32m${fromPath}\x1B[0m not found. Skipping this module...`);
|
|
1380
|
+
return false;
|
|
1041
1381
|
}
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
`
|
|
1047
|
-
|
|
1048
|
-
`);
|
|
1049
|
-
if (mIdx === match.length - 1) {
|
|
1050
|
-
for (const name of classNames) {
|
|
1051
|
-
if (!module2[filePath] || !module2[filePath][name])
|
|
1052
|
-
continue;
|
|
1053
|
-
module2[filePath][name].parsedStr += `}
|
|
1054
|
-
`;
|
|
1055
|
-
}
|
|
1382
|
+
return key;
|
|
1383
|
+
}).filter(Boolean);
|
|
1384
|
+
if (!module2[fromPath]) {
|
|
1385
|
+
if (config.onNotFound === "error") {
|
|
1386
|
+
log.error(`Path \x1B[33m${fromPath}\x1B[0m doesn't have any exported modules. Aborting...`);
|
|
1387
|
+
return false;
|
|
1056
1388
|
} else
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
}
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1389
|
+
log.warn(`Path \x1B[33m${fromPath}\x1B[0m doesn't have any exported modules. Skipping this module...`);
|
|
1390
|
+
return false;
|
|
1391
|
+
}
|
|
1392
|
+
Object.entries(module2[fromPath]).forEach(([key, value]) => {
|
|
1393
|
+
if (!module2[thisPath])
|
|
1394
|
+
module2[thisPath] = {};
|
|
1395
|
+
if (mod === "*")
|
|
1396
|
+
module2[thisPath][key] = value;
|
|
1397
|
+
else if (targetMods.includes(key)) {
|
|
1398
|
+
const usingAlias = key in alias && alias[key] !== key;
|
|
1399
|
+
if (usingAlias)
|
|
1400
|
+
module2[thisPath][`@${alias[key]}`] = value;
|
|
1401
|
+
else
|
|
1402
|
+
module2[thisPath][key] = value;
|
|
1403
|
+
}
|
|
1404
|
+
});
|
|
1405
|
+
} else {
|
|
1406
|
+
if (!module2[fromPath]) {
|
|
1407
|
+
if (config.onNotFound === "error") {
|
|
1408
|
+
log.error(`Path \x1B[33m${fromPath}\x1B[0m doesn't have any exported modules. Aborting...`);
|
|
1409
|
+
return false;
|
|
1410
|
+
} else
|
|
1411
|
+
log.warn(`Path \x1B[33m${fromPath}\x1B[0m doesn't have any exported modules. Skipping this module...`);
|
|
1412
|
+
return false;
|
|
1413
|
+
}
|
|
1414
|
+
if (!module2[fromPath][mod]) {
|
|
1415
|
+
if (config.onNotFound === "error") {
|
|
1416
|
+
log.error(`Module \x1B[33m${mod}\x1B[0m from \x1B[32m${fromPath}\x1B[0m not found. Aborting...`);
|
|
1417
|
+
return false;
|
|
1418
|
+
} else
|
|
1419
|
+
log.warn(`Module \x1B[33m${mod}\x1B[0m from \x1B[32m${fromPath}\x1B[0m not found. Skipping this module...`);
|
|
1420
|
+
return false;
|
|
1067
1421
|
}
|
|
1422
|
+
if (!module2[thisPath])
|
|
1423
|
+
module2[thisPath] = {};
|
|
1424
|
+
module2[thisPath][mod] = module2[fromPath][mod];
|
|
1068
1425
|
}
|
|
1069
1426
|
}
|
|
1070
1427
|
return true;
|
|
1071
1428
|
}
|
|
1072
|
-
// src/parser/
|
|
1073
|
-
function
|
|
1074
|
-
const
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
const segment = str.slice(lineStart, idx);
|
|
1080
|
-
let count = 0;
|
|
1081
|
-
for (const ch of segment) {
|
|
1082
|
-
if (ch === tabChar)
|
|
1083
|
-
count++;
|
|
1084
|
-
else
|
|
1085
|
-
break;
|
|
1086
|
-
}
|
|
1087
|
-
return count;
|
|
1429
|
+
// src/parser/class-implement.ts
|
|
1430
|
+
function resolveOptionalParams(str) {
|
|
1431
|
+
const funcExprRegex = /(\w+)\s*=\s*function\s*\(([^)]*)\)/g;
|
|
1432
|
+
return str.replace(funcExprRegex, (match, name, params) => {
|
|
1433
|
+
const resolvedParams = params.replace(/\?/g, " = undefined");
|
|
1434
|
+
return `${name} = function(${resolvedParams})`;
|
|
1435
|
+
});
|
|
1088
1436
|
}
|
|
1089
|
-
function
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
const
|
|
1095
|
-
const
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
}
|
|
1100
|
-
if (pathAlias.startsWith("~")) {
|
|
1101
|
-
return resolvePath(`${config.source}/${pathAlias.replace("~/", "").replace("~", "")}${dynPath}`);
|
|
1102
|
-
}
|
|
1103
|
-
return resolvePath(`${filePath}/${pathAlias}${dynPath}`);
|
|
1104
|
-
} else if (config.path[importPath]) {
|
|
1105
|
-
const pathAlias = config.path[importPath];
|
|
1106
|
-
if (pathAlias.startsWith("~")) {
|
|
1107
|
-
return resolvePath(`${config.source}/${pathAlias.replace("~/", "").replace("~", "")}`);
|
|
1108
|
-
}
|
|
1109
|
-
return resolvePath(`${filePath}/${pathAlias}`);
|
|
1110
|
-
}
|
|
1111
|
-
return resolvePath(`${filePath}/${importPath}`);
|
|
1437
|
+
function convertArrowFn(str) {
|
|
1438
|
+
arrowFnHeaderRegex.lastIndex = 0;
|
|
1439
|
+
return str.replace(arrowFnHeaderRegex, (match, _p1, _p2, _offset, _input, groups) => {
|
|
1440
|
+
if (!groups?.name)
|
|
1441
|
+
return match;
|
|
1442
|
+
const rawParams = groups.params?.trim() ?? "";
|
|
1443
|
+
const paramsSource = rawParams.startsWith("(") ? rawParams : `(${rawParams})`;
|
|
1444
|
+
const params = parseFnParams(paramsSource);
|
|
1445
|
+
return `${groups.name} = function(${params.combined.join(", ")})`;
|
|
1446
|
+
});
|
|
1112
1447
|
}
|
|
1113
|
-
|
|
1114
|
-
const matches = [...file.content.matchAll(modControlRegex)];
|
|
1115
|
-
const limit = 10;
|
|
1448
|
+
function parseHeader(str, regex = implHeaderRegex) {
|
|
1116
1449
|
const results = [];
|
|
1117
|
-
let
|
|
1118
|
-
|
|
1119
|
-
const
|
|
1120
|
-
const
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
if (!module2[fromPath]) {
|
|
1138
|
-
if (cmd === "include" && (mod.startsWith("{") && (mod.includes('"') || mod.includes("'")))) {
|
|
1139
|
-
const files = mod.slice(1, -1).split(",").map((m) => m.trim());
|
|
1140
|
-
const filePaths = [];
|
|
1141
|
-
for (const f of files) {
|
|
1142
|
-
const filePath = normalizePath(resolvePath(`${file.path}/${f.slice(1, -1)}`));
|
|
1143
|
-
const targetFile = fileGroup.normal.find((fl) => {
|
|
1144
|
-
let targetFile2 = `${fl.path}/${fl.name}`;
|
|
1145
|
-
let currFile = filePath;
|
|
1146
|
-
if (!targetFile2.endsWith(".gml"))
|
|
1147
|
-
targetFile2 += ".gml";
|
|
1148
|
-
if (!currFile.endsWith(".gml"))
|
|
1149
|
-
currFile += ".gml";
|
|
1150
|
-
return targetFile2 === currFile;
|
|
1151
|
-
});
|
|
1152
|
-
if (targetFile)
|
|
1153
|
-
filePaths.push(targetFile);
|
|
1154
|
-
else if (await fileExists(filePath))
|
|
1155
|
-
filePaths.push(filePath);
|
|
1156
|
-
else {
|
|
1157
|
-
if (config.onNotFound === "error") {
|
|
1158
|
-
log.error(`File \x1B[33m${f.slice(1, -1)}\x1B[0m from \x1B[32m${file.path}\x1B[0m not found. Aborting...`);
|
|
1159
|
-
isInvalid = true;
|
|
1160
|
-
return null;
|
|
1161
|
-
} else
|
|
1162
|
-
log.warn(`File \x1B[33m${f.slice(1, -1)}\x1B[0m from \x1B[32m${file.path}\x1B[0m not found. Skipping this file...`);
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
return {
|
|
1166
|
-
cmd,
|
|
1167
|
-
files: filePaths,
|
|
1168
|
-
modList,
|
|
1169
|
-
targetPath: fromPath,
|
|
1170
|
-
targetStr: match[0]
|
|
1171
|
-
};
|
|
1172
|
-
}
|
|
1173
|
-
log.error(`Path \x1B[33m${fromPath}\x1B[0m doesn't have any exported modules. Aborting...`);
|
|
1174
|
-
isInvalid = true;
|
|
1175
|
-
return null;
|
|
1176
|
-
}
|
|
1177
|
-
if (mod === "*" || mod.startsWith("{") && mod.endsWith("}")) {
|
|
1178
|
-
const targetMods = mod === "*" ? null : mod.slice(1, -1).split(",").map((m) => {
|
|
1179
|
-
const split = m.split(":");
|
|
1180
|
-
const key = split[0].trim();
|
|
1181
|
-
if (split.length === 1)
|
|
1182
|
-
alias[key] = key;
|
|
1183
|
-
else
|
|
1184
|
-
alias[key] = split[1].trim();
|
|
1185
|
-
if (!module2[fromPath]) {
|
|
1186
|
-
if (config.onNotFound === "error") {
|
|
1187
|
-
log.error(`Path \x1B[33m${fromPath}\x1B[0m doesn't have any exported modules. Aborting...`);
|
|
1188
|
-
isInvalid = true;
|
|
1189
|
-
} else
|
|
1190
|
-
log.warn(`Path \x1B[33m${fromPath}\x1B[0m doesn't have any exported modules. Skipping this module...`);
|
|
1191
|
-
return null;
|
|
1192
|
-
}
|
|
1193
|
-
if (!module2[fromPath][key]) {
|
|
1194
|
-
if (config.onNotFound === "error") {
|
|
1195
|
-
log.error(`Module \x1B[33m${key}\x1B[0m from \x1B[32m${fromPath}\x1B[0m not found. Aborting...`);
|
|
1196
|
-
isInvalid = true;
|
|
1197
|
-
} else
|
|
1198
|
-
log.warn(`Module \x1B[33m${key}\x1B[0m from \x1B[32m${fromPath}\x1B[0m not found. Skipping this module...`);
|
|
1199
|
-
return null;
|
|
1200
|
-
}
|
|
1201
|
-
return key;
|
|
1202
|
-
}).filter(Boolean);
|
|
1203
|
-
Object.entries(module2[fromPath]).forEach(([key, value]) => {
|
|
1204
|
-
if (mod === "*")
|
|
1205
|
-
modList[key] = { name: key, as: key, value, usingAlias: false };
|
|
1206
|
-
else if (targetMods.includes(key)) {
|
|
1207
|
-
const usingAlias = key in alias && alias[key] !== key;
|
|
1208
|
-
modList[alias[key] ?? key] = { name: key, as: alias[key] ?? key, value, usingAlias };
|
|
1209
|
-
if (usingAlias) {
|
|
1210
|
-
if (!module2[fromPath])
|
|
1211
|
-
module2[fromPath] = {};
|
|
1212
|
-
module2[fromPath][`@${alias[key]}`] = value;
|
|
1213
|
-
}
|
|
1214
|
-
}
|
|
1215
|
-
});
|
|
1450
|
+
let match;
|
|
1451
|
+
while ((match = regex.exec(str)) !== null) {
|
|
1452
|
+
const name = match.groups.name;
|
|
1453
|
+
const start = regex.lastIndex;
|
|
1454
|
+
let braceCount = 1;
|
|
1455
|
+
let inString = false;
|
|
1456
|
+
let stringChar = "";
|
|
1457
|
+
let i = start;
|
|
1458
|
+
for (;i < str.length; i++) {
|
|
1459
|
+
const char = str[i];
|
|
1460
|
+
if (!inString && char === "/" && str[i + 1] === "/") {
|
|
1461
|
+
while (i < str.length && str[i] !== `
|
|
1462
|
+
`)
|
|
1463
|
+
i++;
|
|
1464
|
+
continue;
|
|
1465
|
+
}
|
|
1466
|
+
if (inString) {
|
|
1467
|
+
if (char === stringChar && (i === 0 || str[i - 1] !== "\\")) {
|
|
1468
|
+
inString = false;
|
|
1469
|
+
}
|
|
1216
1470
|
} else {
|
|
1217
|
-
if (
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1471
|
+
if (char === '"' || char === "'") {
|
|
1472
|
+
inString = true;
|
|
1473
|
+
stringChar = char;
|
|
1474
|
+
} else if (char === "{") {
|
|
1475
|
+
braceCount++;
|
|
1476
|
+
} else if (char === "}") {
|
|
1477
|
+
braceCount--;
|
|
1478
|
+
if (braceCount === 0)
|
|
1479
|
+
break;
|
|
1224
1480
|
}
|
|
1225
|
-
modList[mod] = { name: mod, as: mod, value: module2[fromPath][mod], usingAlias: false };
|
|
1226
1481
|
}
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
targetPath: fromPath,
|
|
1232
|
-
targetStr: match[0]
|
|
1233
|
-
};
|
|
1234
|
-
}));
|
|
1235
|
-
if (isInvalid)
|
|
1236
|
-
break;
|
|
1237
|
-
results.push(...res);
|
|
1482
|
+
}
|
|
1483
|
+
const body = str.slice(start, i);
|
|
1484
|
+
results.push({ name, body });
|
|
1485
|
+
regex.lastIndex = i + 1;
|
|
1238
1486
|
}
|
|
1239
|
-
return
|
|
1487
|
+
return results;
|
|
1240
1488
|
}
|
|
1241
|
-
|
|
1242
|
-
if (
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
return null;
|
|
1246
|
-
const toRemove = [...file.content.matchAll(modControlRegex)];
|
|
1247
|
-
for (const rm of toRemove) {
|
|
1248
|
-
if (rm.groups?.cmd !== "include")
|
|
1249
|
-
file.content = file.content.replace(rm[0], "");
|
|
1489
|
+
function implementClass(module2, fileGroup, config) {
|
|
1490
|
+
if (fileGroup.generate.length == 0 && fileGroup.scaff.length == 0) {
|
|
1491
|
+
log.warn("No files to implement classes from.");
|
|
1492
|
+
return false;
|
|
1250
1493
|
}
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
case "enum":
|
|
1280
|
-
toReplace += `
|
|
1281
|
-
`;
|
|
1282
|
-
break;
|
|
1283
|
-
}
|
|
1284
|
-
toReplace += include.value.parsedStr + `
|
|
1285
|
-
`;
|
|
1286
|
-
if (idx === modLen - 1)
|
|
1287
|
-
toReplace += `
|
|
1288
|
-
`;
|
|
1289
|
-
}
|
|
1290
|
-
file.content = file.content.replace(mod.targetStr, toReplace);
|
|
1291
|
-
} else {
|
|
1292
|
-
for (const fileOrPath of mod.files) {
|
|
1293
|
-
if (typeof fileOrPath === "string") {
|
|
1294
|
-
const content = await fsRuntime.readText(fileOrPath);
|
|
1295
|
-
toReplace += content + `
|
|
1296
|
-
|
|
1297
|
-
`;
|
|
1298
|
-
} else
|
|
1299
|
-
toReplace += fileOrPath.content + `
|
|
1300
|
-
|
|
1301
|
-
`;
|
|
1494
|
+
const toImpl = [];
|
|
1495
|
+
for (const file of fileGroup.scaff) {
|
|
1496
|
+
if (file.childs.length > 0)
|
|
1497
|
+
file.childs.forEach((child) => toImpl.push({ parent: file, file: child }));
|
|
1498
|
+
}
|
|
1499
|
+
for (const file of fileGroup.generate) {
|
|
1500
|
+
if (file.childs.length > 0)
|
|
1501
|
+
file.childs.forEach((child) => toImpl.push({ parent: file, file: child }));
|
|
1502
|
+
}
|
|
1503
|
+
for (const fileImpl of toImpl) {
|
|
1504
|
+
const filePath = fileImpl.parent.isIndex ? fileImpl.parent.path : `${fileImpl.parent.path}/${fileImpl.parent.name}`;
|
|
1505
|
+
const match = parseHeader(fileImpl.file.content);
|
|
1506
|
+
const classNames = [];
|
|
1507
|
+
for (const [_, m] of match.entries()) {
|
|
1508
|
+
const { name: className } = m;
|
|
1509
|
+
let { body } = m;
|
|
1510
|
+
body = resolveOptionalParams(body);
|
|
1511
|
+
body = convertClassMethods(body);
|
|
1512
|
+
body = convertArrowFn(body);
|
|
1513
|
+
if (!className || !body)
|
|
1514
|
+
continue;
|
|
1515
|
+
classNames.push(className);
|
|
1516
|
+
if (!module2[filePath] || !module2[filePath][className]) {
|
|
1517
|
+
let newFilePath = null;
|
|
1518
|
+
for (const file of fileGroup.scaff) {
|
|
1519
|
+
if (file.content.includes(`class ${className} {`)) {
|
|
1520
|
+
newFilePath = file.isIndex ? file.path : `${file.path}/${file.name}`;
|
|
1521
|
+
break;
|
|
1302
1522
|
}
|
|
1303
|
-
file.content = file.content.replace(mod.targetStr, toReplace);
|
|
1304
1523
|
}
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
const useMatches = [...file.content.matchAll(useModRegex)];
|
|
1310
|
-
for (const match of cmdMatches) {
|
|
1311
|
-
const { cmd: contentCmd, mod: contentMod } = match.groups;
|
|
1312
|
-
if (!contentCmd || !contentMod) {
|
|
1313
|
-
log.error(`Invalid content module statement: \x1B[34m${contentCmd} ${contentMod}\x1B[0m in \x1B[33m${file.name}\x1B[0m from \x1B[32m${file.path}\x1B[0m. Aborting...`);
|
|
1314
|
-
return null;
|
|
1315
|
-
}
|
|
1316
|
-
if (!(`@${contentMod}` in mod.modList) && !(contentMod in mod.modList))
|
|
1317
|
-
continue;
|
|
1318
|
-
if (config.debugLevel >= 1)
|
|
1319
|
-
log.debug(`Content module statement found: \x1B[34m${contentCmd} ${contentMod}\x1B[0m in \x1B[33m${file.name === "" ? "index" : file.name}\x1B[0m from \x1B[32m${file.path}\x1B[0m.`);
|
|
1320
|
-
let parsedStr = "";
|
|
1321
|
-
switch (contentCmd) {
|
|
1322
|
-
case "content":
|
|
1323
|
-
const tabChar = config.tabType === "1t" ? "\t" : config.tabType === "2s" ? " " : " ";
|
|
1324
|
-
const tabCnt = countTabsBeforeSubstring(file.content, match[0], tabChar);
|
|
1325
|
-
parsedStr = module2[mod.targetPath][`@${contentMod}` in module2[mod.targetPath] ? `@${contentMod}` : contentMod].parsedStr;
|
|
1326
|
-
if (tabCnt > 0) {
|
|
1327
|
-
const tabLevels = getTabLevels(parsedStr, config.tabType).map((l) => l + tabCnt);
|
|
1328
|
-
file.content = file.content.replace(match[0], parsedStr.split(`
|
|
1329
|
-
`).map((l, i) => tabLevels[i] ? insertTabs(tabLevels[i], config.tabType) + l : l).join(`
|
|
1330
|
-
`));
|
|
1331
|
-
} else
|
|
1332
|
-
file.content = file.content.replace(match[0], parsedStr);
|
|
1333
|
-
break;
|
|
1334
|
-
case "nameof":
|
|
1335
|
-
parsedStr = module2[mod.targetPath][`@${contentMod}` in module2[mod.targetPath] ? `@${contentMod}` : contentMod].name;
|
|
1336
|
-
file.content = file.content.replace(`@nameof ${contentMod}`, parsedStr);
|
|
1337
|
-
break;
|
|
1338
|
-
case "typeof":
|
|
1339
|
-
parsedStr = module2[mod.targetPath][`@${contentMod}` in module2[mod.targetPath] ? `@${contentMod}` : contentMod].type;
|
|
1340
|
-
file.content = file.content.replace(`@typeof ${contentMod}`, `"${parsedStr}"`);
|
|
1341
|
-
break;
|
|
1342
|
-
case "valueof":
|
|
1343
|
-
parsedStr = module2[mod.targetPath][`@${contentMod}` in module2[mod.targetPath] ? `@${contentMod}` : contentMod].value;
|
|
1344
|
-
file.content = file.content.replace(`@valueof ${contentMod}`, parsedStr);
|
|
1524
|
+
if (!newFilePath) {
|
|
1525
|
+
for (const file of fileGroup.generate) {
|
|
1526
|
+
if (file.content.includes(`class ${className} {`)) {
|
|
1527
|
+
newFilePath = file.isIndex ? file.path : `${file.path}/${file.name}`;
|
|
1345
1528
|
break;
|
|
1529
|
+
}
|
|
1346
1530
|
}
|
|
1347
1531
|
}
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
if (config.debugLevel >= 1)
|
|
1355
|
-
log.debug(`Valueof module statement found: \x1B[34m${contentMod}\x1B[0m in \x1B[33m${file.name}\x1B[0m from \x1B[32m${file.path}\x1B[0m.`);
|
|
1356
|
-
if (!(`@${contentMod}` in mod.modList) && !(contentMod in mod.modList))
|
|
1532
|
+
if (!newFilePath) {
|
|
1533
|
+
if (config.onNotFound === "error") {
|
|
1534
|
+
log.error(`Class \x1B[33m${className}\x1B[0m not found for file \x1B[34m${fileImpl.file.name}\x1B[0m. Aborting...`);
|
|
1535
|
+
return false;
|
|
1536
|
+
} else {
|
|
1537
|
+
log.warn(`Class \x1B[33m${className}\x1B[0m not found for file \x1B[34m${fileImpl.file.name}\x1B[0m. Skipping this class...`);
|
|
1357
1538
|
continue;
|
|
1358
|
-
const parsedStr = module2[mod.targetPath][`@${contentMod}` in module2[mod.targetPath] ? `@${contentMod}` : contentMod].value;
|
|
1359
|
-
file.content = file.content.replace(`@:${contentMod}`, parsedStr);
|
|
1360
|
-
}
|
|
1361
|
-
for (const match of useMatches) {
|
|
1362
|
-
const { mod: contentMod, body } = match.groups;
|
|
1363
|
-
if (!contentMod || !body) {
|
|
1364
|
-
log.error(`Invalid content module statement: \x1B[34m@use ${contentMod} ${body}\x1B[0m in \x1B[33m${file.name}\x1B[0m from \x1B[32m${file.path}\x1B[0m. Aborting...`);
|
|
1365
|
-
return null;
|
|
1366
1539
|
}
|
|
1367
|
-
|
|
1540
|
+
}
|
|
1541
|
+
if (module2[newFilePath][className].type === "class") {
|
|
1542
|
+
const newMod = module2[newFilePath][className];
|
|
1543
|
+
newMod.body += `
|
|
1544
|
+
${body}`;
|
|
1545
|
+
} else {
|
|
1546
|
+
if (config.onNotFound === "error") {
|
|
1547
|
+
log.error(`Class \x1B[33m${className}\x1B[0m not found for file \x1B[34m${fileImpl.file.name}\x1B[0m. Aborting...`);
|
|
1548
|
+
return false;
|
|
1549
|
+
} else {
|
|
1550
|
+
log.warn(`Class \x1B[33m${className}\x1B[0m not found for file \x1B[34m${fileImpl.file.name}\x1B[0m. Skipping this class...`);
|
|
1368
1551
|
continue;
|
|
1369
|
-
if (config.debugLevel >= 1)
|
|
1370
|
-
log.debug(`Use module statement found: \x1B[34m@use ${contentMod} ${body}\x1B[0m in \x1B[33m${file.name}\x1B[0m from \x1B[32m${file.path}\x1B[0m.`);
|
|
1371
|
-
const lines = body.slice(1, -1).split(`
|
|
1372
|
-
`).filter(Boolean);
|
|
1373
|
-
const pairs = lines.map((l) => l.split(":").map((p) => {
|
|
1374
|
-
const delimIdx = p.lastIndexOf(",");
|
|
1375
|
-
return p.slice(0, delimIdx === -1 ? undefined : delimIdx).trim();
|
|
1376
|
-
}));
|
|
1377
|
-
const tabChar = config.tabType === "1t" ? "\t" : config.tabType === "2s" ? " " : " ";
|
|
1378
|
-
const tabCnt = countTabsBeforeSubstring(file.content.slice(file.content.lastIndexOf(`
|
|
1379
|
-
`, match.index), match.index + match[0].length), "@", tabChar);
|
|
1380
|
-
const tabLevels = getTabLevels(body, config.tabType).map((l) => l + tabCnt);
|
|
1381
|
-
const currMod = module2[mod.targetPath][`@${contentMod}` in module2[mod.targetPath] ? `@${contentMod}` : contentMod];
|
|
1382
|
-
const modMember = Object.entries(currMod.member);
|
|
1383
|
-
const tabLevel = tabCnt + tabLevels[Math.min(1, tabLevels.length - 1)];
|
|
1384
|
-
let res = `{
|
|
1385
|
-
`;
|
|
1386
|
-
for (const [idx, [mName, mVal]] of modMember.entries()) {
|
|
1387
|
-
const pairIdx = pairs.findIndex((p) => p[0] === mName);
|
|
1388
|
-
const pair = pairIdx > -1 ? pairs[pairIdx] : null;
|
|
1389
|
-
const value = pair ? pair.length === 2 ? pair[1] : mVal.value : mVal.value;
|
|
1390
|
-
if (value) {
|
|
1391
|
-
res += `${insertTabs(tabLevel, config.tabType)}${mName}: ${value}${idx < modMember.length - 2 ? "," : ""}
|
|
1392
|
-
`;
|
|
1393
|
-
}
|
|
1394
|
-
if (pairIdx > -1)
|
|
1395
|
-
swapAndPop(pairs, pairIdx);
|
|
1396
|
-
}
|
|
1397
|
-
for (const [idx, pair] of pairs.entries()) {
|
|
1398
|
-
if (idx === 0)
|
|
1399
|
-
res = res.slice(0, -1) + `,
|
|
1400
|
-
`;
|
|
1401
|
-
res += `${insertTabs(tabLevel, config.tabType)}${pair[0]}: ${pair[1]}${idx < pairs.length - 1 ? "," : ""}
|
|
1402
|
-
`;
|
|
1403
1552
|
}
|
|
1404
|
-
res += insertTabs(tabCnt, config.tabType) + "}";
|
|
1405
|
-
file.content = file.content.replace(match[0], res);
|
|
1406
1553
|
}
|
|
1407
|
-
|
|
1554
|
+
continue;
|
|
1555
|
+
} else if (module2[filePath][className].type === "class") {
|
|
1556
|
+
module2[filePath][className].body += `
|
|
1557
|
+
${body}`;
|
|
1558
|
+
} else {
|
|
1559
|
+
if (config.onNotFound === "error") {
|
|
1560
|
+
log.error(`Class \x1B[33m${className}\x1B[0m not found for file \x1B[34m${fileImpl.file.name}\x1B[0m. Aborting...`);
|
|
1561
|
+
return false;
|
|
1562
|
+
} else {
|
|
1563
|
+
log.warn(`Class \x1B[33m${className}\x1B[0m not found for file \x1B[34m${fileImpl.file.name}\x1B[0m. Skipping this class...`);
|
|
1564
|
+
continue;
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1408
1567
|
}
|
|
1409
|
-
file.content = file.content.trim() + `
|
|
1410
|
-
`;
|
|
1411
1568
|
}
|
|
1412
|
-
return
|
|
1569
|
+
return true;
|
|
1413
1570
|
}
|
|
1414
1571
|
// types/gm-event.ts
|
|
1415
1572
|
var EVENT = {
|
|
@@ -2370,6 +2527,9 @@ async function main() {
|
|
|
2370
2527
|
return;
|
|
2371
2528
|
log.debug("Classes implemented successfully.");
|
|
2372
2529
|
log.debug("Implementing modules...");
|
|
2530
|
+
for (const file of files) {
|
|
2531
|
+
reexportModule(module2, file, config);
|
|
2532
|
+
}
|
|
2373
2533
|
const implMods = [];
|
|
2374
2534
|
for (const file of files) {
|
|
2375
2535
|
const mod = await implementModules(module2, fileGroup, file, config);
|
package/package.json
CHANGED
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@scaffscript/core",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"repository": {
|
|
5
|
-
"type": "git",
|
|
6
|
-
"url": "https://github.com/undervolta/scaffscript"
|
|
7
|
-
},
|
|
8
|
-
"main": "dist/index.cjs",
|
|
9
|
-
"devDependencies": {
|
|
10
|
-
"@types/bun": "
|
|
11
|
-
},
|
|
12
|
-
"peerDependencies": {
|
|
13
|
-
"typescript": "^5"
|
|
14
|
-
},
|
|
15
|
-
"bin": {
|
|
16
|
-
"scaff": "./dist/index.cjs"
|
|
17
|
-
},
|
|
18
|
-
"description": "A minimal superset language of GML with TypeScript-like module system",
|
|
19
|
-
"files": [
|
|
20
|
-
"dist"
|
|
21
|
-
],
|
|
22
|
-
"keywords": [
|
|
23
|
-
"gamemaker",
|
|
24
|
-
"gml",
|
|
25
|
-
"scaff",
|
|
26
|
-
"script",
|
|
27
|
-
"superset",
|
|
28
|
-
"module",
|
|
29
|
-
"cli"
|
|
30
|
-
],
|
|
31
|
-
"license": "MIT",
|
|
32
|
-
"scripts": {
|
|
33
|
-
"build": "bun run build:all",
|
|
34
|
-
"build:node": "bun build src/index-node.ts --outfile dist/index.cjs --target node --format cjs",
|
|
35
|
-
"build:bun": "bun build src/index-bun.ts --outfile build/index.mjs --target bun --format esm",
|
|
36
|
-
"build:all": "bun run build:node && bun run build:bun",
|
|
37
|
-
"dev": "bun run src/index-node.ts",
|
|
38
|
-
"prelink": "bun run build"
|
|
39
|
-
},
|
|
40
|
-
"type": "module"
|
|
41
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@scaffscript/core",
|
|
3
|
+
"version": "0.2.6",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "https://github.com/undervolta/scaffscript"
|
|
7
|
+
},
|
|
8
|
+
"main": "dist/index.cjs",
|
|
9
|
+
"devDependencies": {
|
|
10
|
+
"@types/bun": "^1.3.11"
|
|
11
|
+
},
|
|
12
|
+
"peerDependencies": {
|
|
13
|
+
"typescript": "^5"
|
|
14
|
+
},
|
|
15
|
+
"bin": {
|
|
16
|
+
"scaff": "./dist/index.cjs"
|
|
17
|
+
},
|
|
18
|
+
"description": "A minimal superset language of GML with TypeScript-like module system",
|
|
19
|
+
"files": [
|
|
20
|
+
"dist"
|
|
21
|
+
],
|
|
22
|
+
"keywords": [
|
|
23
|
+
"gamemaker",
|
|
24
|
+
"gml",
|
|
25
|
+
"scaff",
|
|
26
|
+
"script",
|
|
27
|
+
"superset",
|
|
28
|
+
"module",
|
|
29
|
+
"cli"
|
|
30
|
+
],
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "bun run build:all",
|
|
34
|
+
"build:node": "bun build src/index-node.ts --outfile dist/index.cjs --target node --format cjs",
|
|
35
|
+
"build:bun": "bun build src/index-bun.ts --outfile build/index.mjs --target bun --format esm",
|
|
36
|
+
"build:all": "bun run build:node && bun run build:bun",
|
|
37
|
+
"dev": "bun run src/index-node.ts",
|
|
38
|
+
"prelink": "bun run build"
|
|
39
|
+
},
|
|
40
|
+
"type": "module"
|
|
41
|
+
}
|