@moonsjs/vite 0.1.13 → 0.1.14

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.
@@ -645,9 +645,118 @@ function nonContractServerFileError2(file, projectRoot) {
645
645
  ]
646
646
  });
647
647
  }
648
+ async function traceValueToServer(input) {
649
+ const key = `${input.file}#${input.name}`;
650
+ if (input.seen.has(key) || input.seen.size > 64) {
651
+ return null;
652
+ }
653
+ input.seen.add(key);
654
+ const record = loadTraceFile(input.file, input.cache);
655
+ if (record === null || record.ast === null || !record.mentionsServer) {
656
+ return null;
657
+ }
658
+ const ast = record.ast;
659
+ if (localTopLevelNames(ast).has(input.name)) {
660
+ return null;
661
+ }
662
+ const importBindings = new Map;
663
+ const edges = [];
664
+ for (const statement of topLevelStatements(ast)) {
665
+ if (statement.type === "ImportDeclaration") {
666
+ const source = statement["source"]?.["value"];
667
+ if (typeof source !== "string") {
668
+ continue;
669
+ }
670
+ for (const item of statement["specifiers"] ?? []) {
671
+ if (item.type !== "ImportSpecifier") {
672
+ continue;
673
+ }
674
+ const local = item["local"]?.["name"];
675
+ const imported = item["imported"]?.["name"] ?? local;
676
+ if (local !== undefined && imported !== undefined) {
677
+ importBindings.set(local, { specifier: source, imported });
678
+ }
679
+ }
680
+ continue;
681
+ }
682
+ if (statement.type === "ExportNamedDeclaration") {
683
+ const source = statement["source"]?.["value"];
684
+ for (const item of statement["specifiers"] ?? []) {
685
+ if (item.type !== "ExportSpecifier") {
686
+ continue;
687
+ }
688
+ const local = item["local"]?.["name"];
689
+ const exported = item["exported"]?.["name"] ?? local;
690
+ if (local === undefined || exported !== input.name) {
691
+ continue;
692
+ }
693
+ if (typeof source === "string") {
694
+ edges.push({ specifier: source, local });
695
+ } else {
696
+ const binding = importBindings.get(local);
697
+ if (binding !== undefined) {
698
+ edges.push({ specifier: binding.specifier, local: binding.imported });
699
+ }
700
+ }
701
+ }
702
+ continue;
703
+ }
704
+ const exportedAll = statement["exported"];
705
+ if (statement.type === "ExportAllDeclaration" && (exportedAll === null || exportedAll === undefined)) {
706
+ const source = statement["source"]?.["value"];
707
+ if (typeof source === "string") {
708
+ edges.push({ specifier: source, local: input.name });
709
+ }
710
+ }
711
+ }
712
+ for (const edge of edges) {
713
+ const next = await input.resolveSafe(edge.specifier, input.file);
714
+ if (next === null) {
715
+ continue;
716
+ }
717
+ if (isServerFilePath2(next)) {
718
+ const analysis = input.analyze(next);
719
+ const isServerFn = analysis !== null && analysis.serverFns.some((fn) => fn.name === edge.local);
720
+ if (!isServerFn) {
721
+ return next;
722
+ }
723
+ continue;
724
+ }
725
+ const deeper = await traceValueToServer({
726
+ ...input,
727
+ file: next,
728
+ name: edge.local
729
+ });
730
+ if (deeper !== null) {
731
+ return deeper;
732
+ }
733
+ }
734
+ return null;
735
+ }
736
+ function loadTraceFile(file, cache) {
737
+ const cached = cache.get(file);
738
+ if (cached !== undefined) {
739
+ return cached;
740
+ }
741
+ let record = null;
742
+ try {
743
+ const source = readFileSync2(file, "utf8");
744
+ const isBarrel = /(^|\n)\s*export\s+(\*|\{[^}]*\})\s+from\s/.test(source);
745
+ const mentionsServer = source.includes(".server") || isBarrel;
746
+ record = {
747
+ ast: mentionsServer ? parseModule(source, file) : null,
748
+ mentionsServer
749
+ };
750
+ } catch {
751
+ record = null;
752
+ }
753
+ cache.set(file, record ?? { ast: null, mentionsServer: false });
754
+ return record;
755
+ }
648
756
  async function checkClientModuleImports2(context) {
649
757
  const { file, code, projectRoot, resolve, analyze } = context;
650
758
  const ast = parseModule(code, file);
759
+ const traceCache = new Map;
651
760
  const relativeFile = toRelative(projectRoot, file);
652
761
  const serverOnly = createServerOnlyClassifier({
653
762
  configured: context.serverOnlyPackages ?? [],
@@ -819,6 +928,58 @@ async function checkClientModuleImports2(context) {
819
928
  const serverBySpecifier = isServerSpecifier2(specifier);
820
929
  const serverByResolve = resolvedTarget !== null && isServerFilePath2(resolvedTarget);
821
930
  if (!serverBySpecifier && !serverByResolve) {
931
+ if (!typeOnly && resolvedTarget !== null && /[.](ts|tsx)$/.test(resolvedTarget)) {
932
+ const requestedNames = [];
933
+ if (statement.type === "ImportDeclaration") {
934
+ for (const item of statement["specifiers"] ?? []) {
935
+ if (item.type !== "ImportSpecifier") {
936
+ continue;
937
+ }
938
+ const kind = item["importKind"] ?? statement["importKind"];
939
+ if (kind === "type") {
940
+ continue;
941
+ }
942
+ const imported = item["imported"]?.["name"];
943
+ if (imported !== undefined) {
944
+ requestedNames.push(imported);
945
+ }
946
+ }
947
+ } else if (statement.type === "ExportNamedDeclaration") {
948
+ for (const item of statement["specifiers"] ?? []) {
949
+ const kind = item["importKind"] ?? statement["importKind"] ?? item["exportKind"] ?? statement["exportKind"];
950
+ if (kind === "type") {
951
+ continue;
952
+ }
953
+ const local = item["local"]?.["name"];
954
+ if (local !== undefined) {
955
+ requestedNames.push(local);
956
+ }
957
+ }
958
+ }
959
+ for (const name of requestedNames) {
960
+ const serverFile = await traceValueToServer({
961
+ file: resolvedTarget,
962
+ name,
963
+ resolveSafe,
964
+ analyze,
965
+ cache: traceCache,
966
+ seen: new Set
967
+ });
968
+ if (serverFile !== null) {
969
+ throw new MoonsError2({
970
+ code: "E_SERVER_IMPORT_IN_CLIENT",
971
+ file: relativeFile,
972
+ line,
973
+ message: `mengimpor \`${name}\` — berasal dari \`${toRelative(projectRoot, serverFile)}\` (via rantai re-export)`,
974
+ details: `\`${toRelative(projectRoot, resolvedTarget)}\` me-re-export nilai dari file server; ` + "stub client tidak mengekspornya (dulu gagal dengan error mentah bundler `MISSING_EXPORT`).",
975
+ suggestions: [
976
+ "Buat server function yang mengembalikan data yang dibutuhkan, atau",
977
+ "Definisikan ulang konstanta publik itu di modul client-safe (jangan pindahkan nilai rahasia)"
978
+ ]
979
+ });
980
+ }
981
+ }
982
+ }
822
983
  continue;
823
984
  }
824
985
  const targetRelative = resolvedTarget === null ? rawSpecifier : toRelative(projectRoot, resolvedTarget);
@@ -1171,4 +1332,4 @@ function buildFnRegistry2(projectRoot, files) {
1171
1332
 
1172
1333
  export { isServerFilePath2, isNonContractServerFile2, isServerSpecifier2, resolveServerSpecifierSync2, stripQuery2, analyzeServerFile2, serverFnExportNames2, renderServerFnStub2, injectServerFnMeta2, nonContractServerFileError2, checkClientModuleImports2, checkRouteModuleExports2, scanServerFiles2, buildFnRegistry2 };
1173
1334
 
1174
- //# debugId=A3B53E6E2FB6EA4564756E2164756E21
1335
+ //# debugId=0D0964765353A35764756E2164756E21