@valbuild/server 0.105.1 → 0.106.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.
@@ -120,7 +120,14 @@ export type ValidationEvent = {
120
120
  sourcePath: string;
121
121
  fixes: string[];
122
122
  keyError?: boolean;
123
- } | {
123
+ }
124
+ /**
125
+ * A file that default exports a Val module, but that val.modules does not
126
+ * register — so Val will never serve it. Files that do NOT default export a
127
+ * module are not reported at all, and one whose default export is not a
128
+ * module is a `fatal-error`; see `reportUnregistered` in the CLI.
129
+ */
130
+ | {
124
131
  type: "unregistered-module";
125
132
  file: string;
126
133
  } | {
@@ -33,7 +33,8 @@ export { extractJsonValuesEntry } from "./extractJsonValuesEntry.js";
33
33
  export type { ModulePathMap } from "./modulePathMap.js";
34
34
  export { ValOpsFS } from "./ValOpsFS.js";
35
35
  export { ValOpsHttp } from "./ValOpsHttp.js";
36
- export { loadValModules } from "./loadValModules.js";
36
+ export { loadValModules, createValModuleFileInspector } from "./loadValModules.js";
37
+ export type { ValModuleFileInspection } from "./loadValModules.js";
37
38
  export { formatPatchSourceError } from "./ValOps.js";
38
39
  export { compareWithCapturedReport, readCapturedReport, replaySnapshot, } from "./debug/replaySnapshot.js";
39
40
  export type { ReplayComparison, ReplayResult } from "./debug/replaySnapshot.js";
@@ -1,5 +1,5 @@
1
1
  import ts from "typescript";
2
- import type { ValModules } from "@valbuild/core";
2
+ import { type ValModules } from "@valbuild/core";
3
3
  /**
4
4
  * The filesystem seam `loadValModules` reads through.
5
5
  *
@@ -31,3 +31,43 @@ export type ValModulesHost = ts.ParseConfigHost & ts.ModuleResolutionHost;
31
31
  * evaluate untrusted or third-party modules.
32
32
  */
33
33
  export declare function loadValModules(projectRoot: string, host?: ValModulesHost): ValModules;
34
+ /**
35
+ * What a `*.val.ts` file that is NOT registered in `val.modules` turns out to
36
+ * be.
37
+ *
38
+ * A file matching `*.val.ts` is not necessarily a Val module: the same
39
+ * convention is used for shared schemas and other content-adjacent helpers, and
40
+ * those are not meant to be registered. Only a file that actually default
41
+ * exports a module is worth warning about; one that default exports something
42
+ * else is a mistake, because nothing will ever load it.
43
+ *
44
+ * See {@link createValModuleFileInspector}.
45
+ */
46
+ export type ValModuleFileInspection =
47
+ /** No default export at all: not a Val module, and not trying to be one. */
48
+ {
49
+ status: "no-default-export";
50
+ }
51
+ /** A real Val module — `export default c.define(...)`. */
52
+ | {
53
+ status: "val-module";
54
+ }
55
+ /** A default export that is not a Val module, or that would not evaluate. */
56
+ | {
57
+ status: "invalid";
58
+ message: string;
59
+ };
60
+ /**
61
+ * Inspects individual `*.val.{ts,js}` files, sharing one module cache and one
62
+ * parsed tsconfig across every call.
63
+ *
64
+ * The default export is checked SYNTACTICALLY first and only evaluated if it is
65
+ * there. That ordering is the point: a `.val.ts` with no default export is a
66
+ * helper file, and evaluating it to learn that would be both wasted work and a
67
+ * way to turn an unrelated top-level throw into a reported error.
68
+ *
69
+ * SECURITY: evaluation goes through the same `vm` loader as
70
+ * {@link loadValModules} — see the warning there. Only ever point this at the
71
+ * project's own first-party files.
72
+ */
73
+ export declare function createValModuleFileInspector(projectRoot: string, host?: ValModulesHost): (absPath: string) => ValModuleFileInspection;
@@ -896,6 +896,150 @@ function resolveRelative(dirName, spec, host) {
896
896
  return null;
897
897
  }
898
898
 
899
+ /**
900
+ * What a `*.val.ts` file that is NOT registered in `val.modules` turns out to
901
+ * be.
902
+ *
903
+ * A file matching `*.val.ts` is not necessarily a Val module: the same
904
+ * convention is used for shared schemas and other content-adjacent helpers, and
905
+ * those are not meant to be registered. Only a file that actually default
906
+ * exports a module is worth warning about; one that default exports something
907
+ * else is a mistake, because nothing will ever load it.
908
+ *
909
+ * See {@link createValModuleFileInspector}.
910
+ */
911
+
912
+ /**
913
+ * Inspects individual `*.val.{ts,js}` files, sharing one module cache and one
914
+ * parsed tsconfig across every call.
915
+ *
916
+ * The default export is checked SYNTACTICALLY first and only evaluated if it is
917
+ * there. That ordering is the point: a `.val.ts` with no default export is a
918
+ * helper file, and evaluating it to learn that would be both wasted work and a
919
+ * way to turn an unrelated top-level throw into a reported error.
920
+ *
921
+ * SECURITY: evaluation goes through the same `vm` loader as
922
+ * {@link loadValModules} — see the warning there. Only ever point this at the
923
+ * project's own first-party files.
924
+ */
925
+ function createValModuleFileInspector(projectRoot, host = ts__default["default"].sys) {
926
+ const compilerOptions = getCompilerOptions(projectRoot, host);
927
+ const cache = {};
928
+ return absPath => {
929
+ const code = host.readFile(absPath);
930
+ if (code === undefined) {
931
+ return {
932
+ status: "invalid",
933
+ message: `Could not read file: '${absPath}'`
934
+ };
935
+ }
936
+ const sourceFile = ts__default["default"].createSourceFile(absPath, code, ts__default["default"].ScriptTarget.ES2020, true);
937
+ if (!hasDefaultExport(sourceFile)) {
938
+ return {
939
+ status: "no-default-export"
940
+ };
941
+ }
942
+ let exports;
943
+ // `loadModule` inserts a module into the cache BEFORE evaluating it, so
944
+ // that a cycle resolves. One that throws therefore leaves a half-built
945
+ // entry behind - and unlike `loadValModules`, which builds a cache per
946
+ // call and lets the throw escape, this cache outlives the failure. A later
947
+ // inspection of the same file (or of the helper that actually threw) would
948
+ // hit that entry, see empty exports, and report "default export is
949
+ // undefined" instead of the real error - or, worse, quietly downgrade it to
950
+ // a warning. So roll the cache back to what it was before this attempt.
951
+ const before = new Set(Object.keys(cache));
952
+ try {
953
+ exports = loadModule(absPath, cache, compilerOptions, host).exports;
954
+ } catch (e) {
955
+ for (const key of Object.keys(cache)) {
956
+ if (!before.has(key)) {
957
+ delete cache[key];
958
+ }
959
+ }
960
+ return {
961
+ status: "invalid",
962
+ message: `Could not be loaded. Error: ${errorMessage(e)}`
963
+ };
964
+ }
965
+ if (core.Internal.isValModule(exports.default)) {
966
+ return {
967
+ status: "val-module"
968
+ };
969
+ }
970
+ // NOTE: do NOT suggest wrapping this in `c.define`. A shared schema turned
971
+ // into a module is an UNREGISTERED module, i.e. straight back to a warning.
972
+ // The fix is to move it out of the default export slot, which is the one
973
+ // thing about a `.val.ts` that Val reserves for itself.
974
+ return {
975
+ status: "invalid",
976
+ message: `Default export is ${describeDefaultExport(exports.default)}, not a Val module. Only 'c.define(...)' may be the default export of a '*.val.ts' file: use a named export for a shared schema or helper`
977
+ };
978
+ };
979
+ }
980
+
981
+ /**
982
+ * Whether the file exports a RUNTIME value as `default`, without evaluating it.
983
+ *
984
+ * Two things deliberately do not count, because neither exists once the file is
985
+ * transpiled — and treating either as a default export would send a pure helper
986
+ * off to be evaluated and reported:
987
+ *
988
+ * - `export * from "./x"`, since a star re-export never carries the default;
989
+ * - a type-only export, in either of its spellings
990
+ * (`export type { T as default }` and `export { type T as default }`).
991
+ */
992
+ function hasDefaultExport(sourceFile) {
993
+ return sourceFile.statements.some(statement => {
994
+ // `export default <expr>` — but not `export = x`, which shares this node.
995
+ if (ts__default["default"].isExportAssignment(statement)) {
996
+ return !statement.isExportEquals;
997
+ }
998
+ // `export { x as default }` / `export { default } from "./x"`
999
+ if (ts__default["default"].isExportDeclaration(statement) && !statement.isTypeOnly && statement.exportClause && ts__default["default"].isNamedExports(statement.exportClause)) {
1000
+ return statement.exportClause.elements.some(element => !element.isTypeOnly && element.name.text === "default");
1001
+ }
1002
+ // `export default function f() {}` / `export default class C {}`, which are
1003
+ // declarations carrying a `default` modifier rather than export assignments.
1004
+ return ts__default["default"].canHaveModifiers(statement) && (ts__default["default"].getModifiers(statement) ?? []).some(modifier => modifier.kind === ts__default["default"].SyntaxKind.DefaultKeyword);
1005
+ });
1006
+ }
1007
+
1008
+ /** A short, human-readable "what you exported instead" for the error message. */
1009
+ function describeDefaultExport(value) {
1010
+ if (value === null) {
1011
+ return "null";
1012
+ }
1013
+ if (Array.isArray(value)) {
1014
+ return "an array";
1015
+ }
1016
+ if (typeof value === "object") {
1017
+ // Duck-typed rather than `instanceof Schema`, for the same cross-realm
1018
+ // reason `isValModule` avoids a constructor check.
1019
+ if ("executeSerialize" in value && typeof value["executeSerialize"] === "function") {
1020
+ return "a schema";
1021
+ }
1022
+ return "an object";
1023
+ }
1024
+ if (typeof value === "undefined") {
1025
+ return "undefined";
1026
+ }
1027
+ return `a ${typeof value}`;
1028
+ }
1029
+ function errorMessage(e) {
1030
+ // NOT `e instanceof Error`: an error thrown from inside the `vm` context is
1031
+ // built from that realm's Error constructor. Duck-type the message instead.
1032
+ if (typeof e === "object" && e !== null && "message" in e) {
1033
+ const {
1034
+ message
1035
+ } = e;
1036
+ if (typeof message === "string") {
1037
+ return message;
1038
+ }
1039
+ }
1040
+ return String(e);
1041
+ }
1042
+
899
1043
  const jsonOps$1 = new patch.JSONOps();
900
1044
 
901
1045
  /**
@@ -12531,6 +12675,7 @@ exports.createJsonEntryPathMap = createJsonEntryPathMap;
12531
12675
  exports.createModulePathMap = createModulePathMap;
12532
12676
  exports.createService = createService;
12533
12677
  exports.createValApiRouter = createValApiRouter;
12678
+ exports.createValModuleFileInspector = createValModuleFileInspector;
12534
12679
  exports.createValServer = createValServer;
12535
12680
  exports.currentFixHandlers = currentFixHandlers;
12536
12681
  exports.decodeJwt = decodeJwt;
@@ -896,6 +896,150 @@ function resolveRelative(dirName, spec, host) {
896
896
  return null;
897
897
  }
898
898
 
899
+ /**
900
+ * What a `*.val.ts` file that is NOT registered in `val.modules` turns out to
901
+ * be.
902
+ *
903
+ * A file matching `*.val.ts` is not necessarily a Val module: the same
904
+ * convention is used for shared schemas and other content-adjacent helpers, and
905
+ * those are not meant to be registered. Only a file that actually default
906
+ * exports a module is worth warning about; one that default exports something
907
+ * else is a mistake, because nothing will ever load it.
908
+ *
909
+ * See {@link createValModuleFileInspector}.
910
+ */
911
+
912
+ /**
913
+ * Inspects individual `*.val.{ts,js}` files, sharing one module cache and one
914
+ * parsed tsconfig across every call.
915
+ *
916
+ * The default export is checked SYNTACTICALLY first and only evaluated if it is
917
+ * there. That ordering is the point: a `.val.ts` with no default export is a
918
+ * helper file, and evaluating it to learn that would be both wasted work and a
919
+ * way to turn an unrelated top-level throw into a reported error.
920
+ *
921
+ * SECURITY: evaluation goes through the same `vm` loader as
922
+ * {@link loadValModules} — see the warning there. Only ever point this at the
923
+ * project's own first-party files.
924
+ */
925
+ function createValModuleFileInspector(projectRoot, host = ts__default["default"].sys) {
926
+ const compilerOptions = getCompilerOptions(projectRoot, host);
927
+ const cache = {};
928
+ return absPath => {
929
+ const code = host.readFile(absPath);
930
+ if (code === undefined) {
931
+ return {
932
+ status: "invalid",
933
+ message: `Could not read file: '${absPath}'`
934
+ };
935
+ }
936
+ const sourceFile = ts__default["default"].createSourceFile(absPath, code, ts__default["default"].ScriptTarget.ES2020, true);
937
+ if (!hasDefaultExport(sourceFile)) {
938
+ return {
939
+ status: "no-default-export"
940
+ };
941
+ }
942
+ let exports;
943
+ // `loadModule` inserts a module into the cache BEFORE evaluating it, so
944
+ // that a cycle resolves. One that throws therefore leaves a half-built
945
+ // entry behind - and unlike `loadValModules`, which builds a cache per
946
+ // call and lets the throw escape, this cache outlives the failure. A later
947
+ // inspection of the same file (or of the helper that actually threw) would
948
+ // hit that entry, see empty exports, and report "default export is
949
+ // undefined" instead of the real error - or, worse, quietly downgrade it to
950
+ // a warning. So roll the cache back to what it was before this attempt.
951
+ const before = new Set(Object.keys(cache));
952
+ try {
953
+ exports = loadModule(absPath, cache, compilerOptions, host).exports;
954
+ } catch (e) {
955
+ for (const key of Object.keys(cache)) {
956
+ if (!before.has(key)) {
957
+ delete cache[key];
958
+ }
959
+ }
960
+ return {
961
+ status: "invalid",
962
+ message: `Could not be loaded. Error: ${errorMessage(e)}`
963
+ };
964
+ }
965
+ if (core.Internal.isValModule(exports.default)) {
966
+ return {
967
+ status: "val-module"
968
+ };
969
+ }
970
+ // NOTE: do NOT suggest wrapping this in `c.define`. A shared schema turned
971
+ // into a module is an UNREGISTERED module, i.e. straight back to a warning.
972
+ // The fix is to move it out of the default export slot, which is the one
973
+ // thing about a `.val.ts` that Val reserves for itself.
974
+ return {
975
+ status: "invalid",
976
+ message: `Default export is ${describeDefaultExport(exports.default)}, not a Val module. Only 'c.define(...)' may be the default export of a '*.val.ts' file: use a named export for a shared schema or helper`
977
+ };
978
+ };
979
+ }
980
+
981
+ /**
982
+ * Whether the file exports a RUNTIME value as `default`, without evaluating it.
983
+ *
984
+ * Two things deliberately do not count, because neither exists once the file is
985
+ * transpiled — and treating either as a default export would send a pure helper
986
+ * off to be evaluated and reported:
987
+ *
988
+ * - `export * from "./x"`, since a star re-export never carries the default;
989
+ * - a type-only export, in either of its spellings
990
+ * (`export type { T as default }` and `export { type T as default }`).
991
+ */
992
+ function hasDefaultExport(sourceFile) {
993
+ return sourceFile.statements.some(statement => {
994
+ // `export default <expr>` — but not `export = x`, which shares this node.
995
+ if (ts__default["default"].isExportAssignment(statement)) {
996
+ return !statement.isExportEquals;
997
+ }
998
+ // `export { x as default }` / `export { default } from "./x"`
999
+ if (ts__default["default"].isExportDeclaration(statement) && !statement.isTypeOnly && statement.exportClause && ts__default["default"].isNamedExports(statement.exportClause)) {
1000
+ return statement.exportClause.elements.some(element => !element.isTypeOnly && element.name.text === "default");
1001
+ }
1002
+ // `export default function f() {}` / `export default class C {}`, which are
1003
+ // declarations carrying a `default` modifier rather than export assignments.
1004
+ return ts__default["default"].canHaveModifiers(statement) && (ts__default["default"].getModifiers(statement) ?? []).some(modifier => modifier.kind === ts__default["default"].SyntaxKind.DefaultKeyword);
1005
+ });
1006
+ }
1007
+
1008
+ /** A short, human-readable "what you exported instead" for the error message. */
1009
+ function describeDefaultExport(value) {
1010
+ if (value === null) {
1011
+ return "null";
1012
+ }
1013
+ if (Array.isArray(value)) {
1014
+ return "an array";
1015
+ }
1016
+ if (typeof value === "object") {
1017
+ // Duck-typed rather than `instanceof Schema`, for the same cross-realm
1018
+ // reason `isValModule` avoids a constructor check.
1019
+ if ("executeSerialize" in value && typeof value["executeSerialize"] === "function") {
1020
+ return "a schema";
1021
+ }
1022
+ return "an object";
1023
+ }
1024
+ if (typeof value === "undefined") {
1025
+ return "undefined";
1026
+ }
1027
+ return `a ${typeof value}`;
1028
+ }
1029
+ function errorMessage(e) {
1030
+ // NOT `e instanceof Error`: an error thrown from inside the `vm` context is
1031
+ // built from that realm's Error constructor. Duck-type the message instead.
1032
+ if (typeof e === "object" && e !== null && "message" in e) {
1033
+ const {
1034
+ message
1035
+ } = e;
1036
+ if (typeof message === "string") {
1037
+ return message;
1038
+ }
1039
+ }
1040
+ return String(e);
1041
+ }
1042
+
899
1043
  const jsonOps$1 = new patch.JSONOps();
900
1044
 
901
1045
  /**
@@ -12531,6 +12675,7 @@ exports.createJsonEntryPathMap = createJsonEntryPathMap;
12531
12675
  exports.createModulePathMap = createModulePathMap;
12532
12676
  exports.createService = createService;
12533
12677
  exports.createValApiRouter = createValApiRouter;
12678
+ exports.createValModuleFileInspector = createValModuleFileInspector;
12534
12679
  exports.createValServer = createValServer;
12535
12680
  exports.currentFixHandlers = currentFixHandlers;
12536
12681
  exports.decodeJwt = decodeJwt;
@@ -1,7 +1,7 @@
1
1
  import ts from 'typescript';
2
2
  import { pipe, result, array } from '@valbuild/core/fp';
3
3
  import { PatchError, deepEqual, parseAndValidateArrayIndex, isNotRoot, applyPatch, JSONOps, deepClone, sourceToPatchPath } from '@valbuild/core/patch';
4
- import { derefPatch, RecordSchema, Internal, extractValModules, computeValModuleShas, VAL_EXTENSION, ImageSchema, DEFAULT_CONTENT_HOST, hasRemoteFileSchema } from '@valbuild/core';
4
+ import { derefPatch, Internal, RecordSchema, extractValModules, computeValModuleShas, VAL_EXTENSION, ImageSchema, DEFAULT_CONTENT_HOST, hasRemoteFileSchema } from '@valbuild/core';
5
5
  export { hasRemoteFileSchema } from '@valbuild/core';
6
6
  import * as path from 'path';
7
7
  import path__default from 'path';
@@ -862,6 +862,150 @@ function resolveRelative(dirName, spec, host) {
862
862
  return null;
863
863
  }
864
864
 
865
+ /**
866
+ * What a `*.val.ts` file that is NOT registered in `val.modules` turns out to
867
+ * be.
868
+ *
869
+ * A file matching `*.val.ts` is not necessarily a Val module: the same
870
+ * convention is used for shared schemas and other content-adjacent helpers, and
871
+ * those are not meant to be registered. Only a file that actually default
872
+ * exports a module is worth warning about; one that default exports something
873
+ * else is a mistake, because nothing will ever load it.
874
+ *
875
+ * See {@link createValModuleFileInspector}.
876
+ */
877
+
878
+ /**
879
+ * Inspects individual `*.val.{ts,js}` files, sharing one module cache and one
880
+ * parsed tsconfig across every call.
881
+ *
882
+ * The default export is checked SYNTACTICALLY first and only evaluated if it is
883
+ * there. That ordering is the point: a `.val.ts` with no default export is a
884
+ * helper file, and evaluating it to learn that would be both wasted work and a
885
+ * way to turn an unrelated top-level throw into a reported error.
886
+ *
887
+ * SECURITY: evaluation goes through the same `vm` loader as
888
+ * {@link loadValModules} — see the warning there. Only ever point this at the
889
+ * project's own first-party files.
890
+ */
891
+ function createValModuleFileInspector(projectRoot, host = ts.sys) {
892
+ const compilerOptions = getCompilerOptions(projectRoot, host);
893
+ const cache = {};
894
+ return absPath => {
895
+ const code = host.readFile(absPath);
896
+ if (code === undefined) {
897
+ return {
898
+ status: "invalid",
899
+ message: `Could not read file: '${absPath}'`
900
+ };
901
+ }
902
+ const sourceFile = ts.createSourceFile(absPath, code, ts.ScriptTarget.ES2020, true);
903
+ if (!hasDefaultExport(sourceFile)) {
904
+ return {
905
+ status: "no-default-export"
906
+ };
907
+ }
908
+ let exports;
909
+ // `loadModule` inserts a module into the cache BEFORE evaluating it, so
910
+ // that a cycle resolves. One that throws therefore leaves a half-built
911
+ // entry behind - and unlike `loadValModules`, which builds a cache per
912
+ // call and lets the throw escape, this cache outlives the failure. A later
913
+ // inspection of the same file (or of the helper that actually threw) would
914
+ // hit that entry, see empty exports, and report "default export is
915
+ // undefined" instead of the real error - or, worse, quietly downgrade it to
916
+ // a warning. So roll the cache back to what it was before this attempt.
917
+ const before = new Set(Object.keys(cache));
918
+ try {
919
+ exports = loadModule(absPath, cache, compilerOptions, host).exports;
920
+ } catch (e) {
921
+ for (const key of Object.keys(cache)) {
922
+ if (!before.has(key)) {
923
+ delete cache[key];
924
+ }
925
+ }
926
+ return {
927
+ status: "invalid",
928
+ message: `Could not be loaded. Error: ${errorMessage(e)}`
929
+ };
930
+ }
931
+ if (Internal.isValModule(exports.default)) {
932
+ return {
933
+ status: "val-module"
934
+ };
935
+ }
936
+ // NOTE: do NOT suggest wrapping this in `c.define`. A shared schema turned
937
+ // into a module is an UNREGISTERED module, i.e. straight back to a warning.
938
+ // The fix is to move it out of the default export slot, which is the one
939
+ // thing about a `.val.ts` that Val reserves for itself.
940
+ return {
941
+ status: "invalid",
942
+ message: `Default export is ${describeDefaultExport(exports.default)}, not a Val module. Only 'c.define(...)' may be the default export of a '*.val.ts' file: use a named export for a shared schema or helper`
943
+ };
944
+ };
945
+ }
946
+
947
+ /**
948
+ * Whether the file exports a RUNTIME value as `default`, without evaluating it.
949
+ *
950
+ * Two things deliberately do not count, because neither exists once the file is
951
+ * transpiled — and treating either as a default export would send a pure helper
952
+ * off to be evaluated and reported:
953
+ *
954
+ * - `export * from "./x"`, since a star re-export never carries the default;
955
+ * - a type-only export, in either of its spellings
956
+ * (`export type { T as default }` and `export { type T as default }`).
957
+ */
958
+ function hasDefaultExport(sourceFile) {
959
+ return sourceFile.statements.some(statement => {
960
+ // `export default <expr>` — but not `export = x`, which shares this node.
961
+ if (ts.isExportAssignment(statement)) {
962
+ return !statement.isExportEquals;
963
+ }
964
+ // `export { x as default }` / `export { default } from "./x"`
965
+ if (ts.isExportDeclaration(statement) && !statement.isTypeOnly && statement.exportClause && ts.isNamedExports(statement.exportClause)) {
966
+ return statement.exportClause.elements.some(element => !element.isTypeOnly && element.name.text === "default");
967
+ }
968
+ // `export default function f() {}` / `export default class C {}`, which are
969
+ // declarations carrying a `default` modifier rather than export assignments.
970
+ return ts.canHaveModifiers(statement) && (ts.getModifiers(statement) ?? []).some(modifier => modifier.kind === ts.SyntaxKind.DefaultKeyword);
971
+ });
972
+ }
973
+
974
+ /** A short, human-readable "what you exported instead" for the error message. */
975
+ function describeDefaultExport(value) {
976
+ if (value === null) {
977
+ return "null";
978
+ }
979
+ if (Array.isArray(value)) {
980
+ return "an array";
981
+ }
982
+ if (typeof value === "object") {
983
+ // Duck-typed rather than `instanceof Schema`, for the same cross-realm
984
+ // reason `isValModule` avoids a constructor check.
985
+ if ("executeSerialize" in value && typeof value["executeSerialize"] === "function") {
986
+ return "a schema";
987
+ }
988
+ return "an object";
989
+ }
990
+ if (typeof value === "undefined") {
991
+ return "undefined";
992
+ }
993
+ return `a ${typeof value}`;
994
+ }
995
+ function errorMessage(e) {
996
+ // NOT `e instanceof Error`: an error thrown from inside the `vm` context is
997
+ // built from that realm's Error constructor. Duck-type the message instead.
998
+ if (typeof e === "object" && e !== null && "message" in e) {
999
+ const {
1000
+ message
1001
+ } = e;
1002
+ if (typeof message === "string") {
1003
+ return message;
1004
+ }
1005
+ }
1006
+ return String(e);
1007
+ }
1008
+
865
1009
  const jsonOps$1 = new JSONOps();
866
1010
 
867
1011
  /**
@@ -12473,4 +12617,4 @@ function readCapturedReport(snapshotDir) {
12473
12617
  return JSON.parse(fs.readFileSync(reportPath, "utf-8"));
12474
12618
  }
12475
12619
 
12476
- export { DEFAULT_LOGIN_HOST, DEFAULT_LOGIN_MAX_DURATION, DEFAULT_LOGIN_POLL_INTERVAL, Service, ValFSHost, ValLoginError, ValModuleLoader, ValOpsFS, ValOpsHttp, ValSourceFileHandler, analyzeValModule, awaitValLoginConfirmation, checkRemoteRef, compareWithCapturedReport, createDefaultValFSHost, createFixPatch, createJsonEntryPathMap, createModulePathMap, createService, createValApiRouter, createValServer, currentFixHandlers, decodeJwt, describePatchStoreProblems, downloadFileFromRemote, encodeJwt, evalValConfigFile, extractFileMetadata, extractImageMetadata, extractJsonValuesEntry, findAndEvalValConfigFile, findJsonEntryFilePath, fixHandlers, formatPatchSourceError, formatSyntaxErrorTree, getCachedRemoteFileDir, getCachedRemoteFilePath, getCompilerOptions, getExpire, getFileExt, getModulePathRange, getPersonalAccessTokenPath, getSettings, getValidationErrorFileRef, handleCheckAllFiles, handleFileMetadata, handleJsonValuesExtractEntry, handleRemoteFileCheck, handleRemoteFileDownload, handleRemoteFileUpload, handleRemoteGalleryFileUpload, handleUniqueFolderCheck, loadValModules, parsePersonalAccessTokenFile, patchSourceFile, persistPersonalAccessToken, readCapturedReport, readPatchStore, replaySnapshot, safeReadGit, startValLogin, uploadRemoteFile, validateMetadata };
12620
+ export { DEFAULT_LOGIN_HOST, DEFAULT_LOGIN_MAX_DURATION, DEFAULT_LOGIN_POLL_INTERVAL, Service, ValFSHost, ValLoginError, ValModuleLoader, ValOpsFS, ValOpsHttp, ValSourceFileHandler, analyzeValModule, awaitValLoginConfirmation, checkRemoteRef, compareWithCapturedReport, createDefaultValFSHost, createFixPatch, createJsonEntryPathMap, createModulePathMap, createService, createValApiRouter, createValModuleFileInspector, createValServer, currentFixHandlers, decodeJwt, describePatchStoreProblems, downloadFileFromRemote, encodeJwt, evalValConfigFile, extractFileMetadata, extractImageMetadata, extractJsonValuesEntry, findAndEvalValConfigFile, findJsonEntryFilePath, fixHandlers, formatPatchSourceError, formatSyntaxErrorTree, getCachedRemoteFileDir, getCachedRemoteFilePath, getCompilerOptions, getExpire, getFileExt, getModulePathRange, getPersonalAccessTokenPath, getSettings, getValidationErrorFileRef, handleCheckAllFiles, handleFileMetadata, handleJsonValuesExtractEntry, handleRemoteFileCheck, handleRemoteFileDownload, handleRemoteFileUpload, handleRemoteGalleryFileUpload, handleUniqueFolderCheck, loadValModules, parsePersonalAccessTokenFile, patchSourceFile, persistPersonalAccessToken, readCapturedReport, readPatchStore, replaySnapshot, safeReadGit, startValLogin, uploadRemoteFile, validateMetadata };
package/package.json CHANGED
@@ -16,7 +16,7 @@
16
16
  "./package.json": "./package.json"
17
17
  },
18
18
  "types": "dist/valbuild-server.cjs.d.ts",
19
- "version": "0.105.1",
19
+ "version": "0.106.0",
20
20
  "devDependencies": {
21
21
  "@prettier/sync": "^0.6.1",
22
22
  "@types/jest": "^30.0.0"
@@ -24,13 +24,13 @@
24
24
  "dependencies": {
25
25
  "chokidar": "^5.0.0",
26
26
  "image-size": "^2.0.2",
27
- "minimatch": "^10.1.1",
27
+ "minimatch": "^10.2.3",
28
28
  "sucrase": "^3.35.1",
29
29
  "typescript": "^5.9.3",
30
30
  "zod": "^4.3.5",
31
31
  "zod-validation-error": "^5.0.0",
32
- "@valbuild/core": "0.105.1",
33
- "@valbuild/shared": "0.105.1",
32
+ "@valbuild/core": "0.106.0",
33
+ "@valbuild/shared": "0.106.0",
34
34
  "@valbuild/ui": "0.105.1"
35
35
  },
36
36
  "engines": {