@qzsy/vinext 0.1.85 → 0.1.87

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.
@@ -152,7 +152,11 @@ type NextConfig = {
152
152
  * @see https://nextjs.org/docs/app/api-reference/config/next-config-js/reactMaxHeadersLength
153
153
  */
154
154
  reactMaxHeadersLength?: number; /** User agents that require blocking metadata in the initial head. */
155
- htmlLimitedBots?: RegExp | string;
155
+ htmlLimitedBots?: RegExp | string; /** Development logging controls. Mirrors Next.js `logging` config. */
156
+ logging?: {
157
+ /** Log Server Function invocations in development. Defaults to true. */serverFunctions?: boolean;
158
+ [key: string]: unknown;
159
+ };
156
160
  /**
157
161
  * Enable Cache Components (Next.js 16).
158
162
  * When true, enables the "use cache" directive for pages, components, and functions.
@@ -291,7 +295,8 @@ type ResolvedNextConfig = {
291
295
  * during App Router SSR. `0` disables emission. Defaults to 6000.
292
296
  */
293
297
  reactMaxHeadersLength: number; /** Serialized htmlLimitedBots regexp source from next.config. */
294
- htmlLimitedBots: string | undefined;
298
+ htmlLimitedBots: string | undefined; /** Whether Server Function invocations are logged during development. */
299
+ serverFunctionsLogging: boolean;
295
300
  /**
296
301
  * Packages that should be treated as server-external (not bundled by Vite).
297
302
  * Sourced from `serverExternalPackages` or the legacy
@@ -620,6 +620,7 @@ async function resolveNextConfig(config, root = process.cwd(), options = {}) {
620
620
  expireTime: DEFAULT_EXPIRE_TIME,
621
621
  reactMaxHeadersLength: DEFAULT_REACT_MAX_HEADERS_LENGTH,
622
622
  htmlLimitedBots: void 0,
623
+ serverFunctionsLogging: true,
623
624
  serverExternalPackages: [],
624
625
  cacheHandler: void 0,
625
626
  cacheMaxMemorySize: void 0,
@@ -695,6 +696,7 @@ async function resolveNextConfig(config, root = process.cwd(), options = {}) {
695
696
  const serverActionsBodySizeLimitLabel = serverActionsBodySizeLimitConfig === void 0 ? "1 MB" : String(serverActionsBodySizeLimitConfig);
696
697
  const hashSalt = (readOptionalString(experimental?.outputHashSalt) ?? "") + (process.env.NEXT_HASH_SALT ?? "");
697
698
  const htmlLimitedBots = resolveHtmlLimitedBots(config.htmlLimitedBots);
699
+ const serverFunctionsLogging = readOptionalRecord(config.logging)?.serverFunctions !== false;
698
700
  const rawOptimize = experimental?.optimizePackageImports;
699
701
  const optimizePackageImports = Array.isArray(rawOptimize) ? rawOptimize.filter((x) => typeof x === "string") : [];
700
702
  const inlineCss = experimental?.inlineCss === true;
@@ -796,6 +798,7 @@ async function resolveNextConfig(config, root = process.cwd(), options = {}) {
796
798
  expireTime: typeof config.expireTime === "number" ? config.expireTime : DEFAULT_EXPIRE_TIME,
797
799
  reactMaxHeadersLength: typeof config.reactMaxHeadersLength === "number" ? config.reactMaxHeadersLength : DEFAULT_REACT_MAX_HEADERS_LENGTH,
798
800
  htmlLimitedBots,
801
+ serverFunctionsLogging,
799
802
  serverExternalPackages,
800
803
  cacheHandler,
801
804
  cacheMaxMemorySize,
package/dist/index.js CHANGED
@@ -784,6 +784,7 @@ function vinext(options = {}) {
784
784
  defines["process.env.__VINEXT_IMAGE_UNOPTIMIZED"] = JSON.stringify(String(nextConfig.images?.unoptimized === true));
785
785
  defines["process.env.__VINEXT_BUILD_ID"] = JSON.stringify(nextConfig.buildId);
786
786
  defines["process.env.__VINEXT_RSC_COMPATIBILITY_ID"] = JSON.stringify(rscCompatibilityId);
787
+ defines["process.env.__VINEXT_SERVER_FUNCTIONS_LOGGING"] = JSON.stringify(String(nextConfig.serverFunctionsLogging));
787
788
  defines["process.env.__VINEXT_DEPLOYMENT_ID"] = JSON.stringify(nextConfig.deploymentId ?? "");
788
789
  defines["process.env.NEXT_DEPLOYMENT_ID"] = nextConfig.deploymentId ? JSON.stringify(nextConfig.deploymentId) : "false";
789
790
  defines["process.env.NEXT_RUNTIME"] = "\"\"";
@@ -613,11 +613,15 @@ async function handleServerActionRscRequest(options) {
613
613
  }
614
614
  }
615
615
  } finally {
616
- if (shouldLogAction) actionLogInfo = createServerActionLogInfo({
617
- actionId: options.actionId,
618
- args,
619
- durationMs: Math.round(performance.now() - actionLogStart)
620
- });
616
+ if (shouldLogAction) try {
617
+ actionLogInfo = createServerActionLogInfo({
618
+ actionId: options.actionId,
619
+ args,
620
+ durationMs: Math.round(performance.now() - actionLogStart)
621
+ });
622
+ } catch {
623
+ actionLogInfo = null;
624
+ }
621
625
  options.setHeadersAccessPhase(previousHeadersPhase);
622
626
  if (actionThrew && !actionWasForwarded) rootParamsUsage.transitionToRender();
623
627
  }
@@ -28,6 +28,16 @@ const DEFAULT_ARG_SANITIZE_LIMITS = {
28
28
  maxObjectKeys: 3,
29
29
  maxDepth: 2
30
30
  };
31
+ function isPlainObject(value) {
32
+ const proto = Object.getPrototypeOf(value);
33
+ return proto === Object.prototype || proto === null;
34
+ }
35
+ function describeOpaqueArg(arg) {
36
+ if (Array.isArray(arg)) return `[Array(${arg.length})]`;
37
+ if (typeof FormData !== "undefined" && arg instanceof FormData) return "[FormData]";
38
+ if (typeof Blob !== "undefined" && arg instanceof Blob) return `[${arg.constructor.name}]`;
39
+ return `[${arg.constructor.name}]`;
40
+ }
31
41
  function sanitizeArgForLog(arg, depth = 0, limits = DEFAULT_ARG_SANITIZE_LIMITS) {
32
42
  if (arg === null || arg === void 0) return arg;
33
43
  if (typeof arg === "string") return truncateString(arg, limits.maxStringLength);
@@ -40,14 +50,17 @@ function sanitizeArgForLog(arg, depth = 0, limits = DEFAULT_ARG_SANITIZE_LIMITS)
40
50
  if (arg.length > limits.maxArrayItems) items.push("...");
41
51
  return items;
42
52
  }
43
- if (typeof arg === "object") try {
44
- const entries = Object.entries(arg).slice(0, limits.maxObjectKeys);
45
- const sanitized = {};
46
- for (const [key, value] of entries) sanitized[key] = sanitizeArgForLog(value, depth + 1, limits);
47
- if (Object.keys(arg).length > limits.maxObjectKeys) sanitized["..."] = "...";
48
- return sanitized;
49
- } catch {
50
- return "[Object]";
53
+ if (typeof arg === "object") {
54
+ if (!isPlainObject(arg)) return describeOpaqueArg(arg);
55
+ try {
56
+ const entries = Object.entries(arg).slice(0, limits.maxObjectKeys);
57
+ const sanitized = {};
58
+ for (const [key, value] of entries) sanitized[key] = sanitizeArgForLog(value, depth + 1, limits);
59
+ if (Object.keys(arg).length > limits.maxObjectKeys) sanitized["..."] = "...";
60
+ return sanitized;
61
+ } catch {
62
+ return "[Object]";
63
+ }
51
64
  }
52
65
  try {
53
66
  return truncateString(JSON.stringify(arg), limits.maxStringLength);
@@ -55,6 +68,22 @@ function sanitizeArgForLog(arg, depth = 0, limits = DEFAULT_ARG_SANITIZE_LIMITS)
55
68
  return "[unserializable]";
56
69
  }
57
70
  }
71
+ /** Snapshot args without spreading lazy Flight arrays or throwing on bad payloads. */
72
+ function safeArgsSnapshotForLog(args) {
73
+ let length;
74
+ try {
75
+ length = args.length;
76
+ } catch {
77
+ return ["(args unavailable)"];
78
+ }
79
+ const snapshot = [];
80
+ for (let index = 0; index < length; index++) try {
81
+ snapshot.push(sanitizeArgForLog(args[index]));
82
+ } catch {
83
+ snapshot.push("(arg unavailable)");
84
+ }
85
+ return snapshot;
86
+ }
58
87
  function sanitizeArgsForLog(args, limits = DEFAULT_ARG_SANITIZE_LIMITS) {
59
88
  return args.map((arg) => sanitizeArgForLog(arg, 0, limits));
60
89
  }
@@ -110,7 +139,7 @@ function fitLogInfoForHeader(info) {
110
139
  }
111
140
  }
112
141
  function isDevServerActionLoggingEnabled() {
113
- return process.env.NODE_ENV !== "production";
142
+ return process.env.NODE_ENV !== "production" && process.env.__VINEXT_SERVER_FUNCTIONS_LOGGING !== "false";
114
143
  }
115
144
  function isInlineActionExport(exportedName) {
116
145
  return INLINE_ACTION_PREFIXES.some((prefix) => exportedName.startsWith(prefix));
@@ -203,12 +232,20 @@ function createServerActionLogInfo(options) {
203
232
  if (!isDevServerActionLoggingEnabled()) return null;
204
233
  const meta = resolveServerActionLogMeta(options.actionId);
205
234
  if (!meta) return null;
206
- const args = Array.isArray(options.args) ? options.args : [options.args];
207
- return {
208
- ...meta,
209
- args: sanitizeArgsForLog([...args]),
210
- duration: options.durationMs
211
- };
235
+ try {
236
+ const args = Array.isArray(options.args) ? options.args : [options.args];
237
+ return {
238
+ ...meta,
239
+ args: safeArgsSnapshotForLog(args),
240
+ duration: options.durationMs
241
+ };
242
+ } catch {
243
+ return {
244
+ ...meta,
245
+ args: ["(args unavailable)"],
246
+ duration: options.durationMs
247
+ };
248
+ }
212
249
  }
213
250
  //#endregion
214
251
  export { applyServerActionLogHeader, createServerActionLogInfo, formatActionArgs, isDevServerActionLoggingEnabled, parseServerActionLogHeader, resolveServerActionLogMeta, serializeServerActionLogHeader };
@@ -50,7 +50,7 @@ declare class RedirectErrorBoundary extends React.Component<{
50
50
  children?: React.ReactNode;
51
51
  });
52
52
  static getDerivedStateFromError(error: unknown): RedirectBoundaryState;
53
- render(): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | React.JSX.Element | null | undefined;
53
+ render(): string | number | bigint | boolean | React.JSX.Element | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null | undefined;
54
54
  }
55
55
  declare function RedirectBoundary({
56
56
  children
@@ -70,7 +70,7 @@ declare class ErrorBoundaryInner extends React.Component<ErrorBoundaryInnerProps
70
70
  componentDidMount(): void;
71
71
  componentWillUnmount(): void;
72
72
  reset: () => void;
73
- render(): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | React.JSX.Element | null | undefined;
73
+ render(): string | number | bigint | boolean | React.JSX.Element | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null | undefined;
74
74
  }
75
75
  declare function ErrorBoundary({
76
76
  fallback,
@@ -118,7 +118,7 @@ declare class ForbiddenBoundaryInner extends React.Component<ForbiddenBoundaryIn
118
118
  constructor(props: ForbiddenBoundaryInnerProps);
119
119
  static getDerivedStateFromProps(props: ForbiddenBoundaryInnerProps, state: ForbiddenBoundaryState): ForbiddenBoundaryState | null;
120
120
  static getDerivedStateFromError(error: unknown): Partial<ForbiddenBoundaryState>;
121
- render(): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | React.JSX.Element | null | undefined;
121
+ render(): string | number | bigint | boolean | React.JSX.Element | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null | undefined;
122
122
  }
123
123
  declare function ForbiddenBoundary({
124
124
  fallback,
@@ -142,7 +142,7 @@ declare class UnauthorizedBoundaryInner extends React.Component<UnauthorizedBoun
142
142
  constructor(props: UnauthorizedBoundaryInnerProps);
143
143
  static getDerivedStateFromProps(props: UnauthorizedBoundaryInnerProps, state: UnauthorizedBoundaryState): UnauthorizedBoundaryState | null;
144
144
  static getDerivedStateFromError(error: unknown): Partial<UnauthorizedBoundaryState>;
145
- render(): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | React.JSX.Element | null | undefined;
145
+ render(): string | number | bigint | boolean | React.JSX.Element | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null | undefined;
146
146
  }
147
147
  declare function UnauthorizedBoundary({
148
148
  fallback,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qzsy/vinext",
3
- "version": "0.1.85",
3
+ "version": "0.1.87",
4
4
  "description": "Run Next.js apps on Vite. Drop-in replacement for the next CLI.",
5
5
  "license": "MIT",
6
6
  "repository": {