@valbuild/server 0.134.0 → 0.135.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.
- package/CHANGELOG.md +68 -0
- package/dist/declarations/src/createPrettierFormatter.d.ts +87 -0
- package/dist/declarations/src/index.d.ts +2 -0
- package/dist/valbuild-server.cjs.dev.js +174 -6
- package/dist/valbuild-server.cjs.prod.js +174 -6
- package/dist/valbuild-server.esm.js +174 -7
- package/package.json +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,73 @@
|
|
|
1
1
|
# @valbuild/server
|
|
2
2
|
|
|
3
|
+
## 0.135.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#707](https://github.com/valbuild/val/pull/707) [`c9affec`](https://github.com/valbuild/val/commit/c9affece6ae6ba62bd6c1113ed1fdab6317fa112) Thanks [@freekh](https://github.com/freekh)! - `val validate --fix` now formats with your prettier config instead of prettier's defaults
|
|
8
|
+
|
|
9
|
+
`--fix` formatted the files it repaired by calling `prettier.format(code, { filepath })`, which never reads `.prettierrc`: `filepath` picks the parser and nothing else — only `resolveConfig`, `getFileInfo` and prettier's own CLI consult the config. On a project whose style is not prettier's default, a two-line content fix therefore arrived as a whole-file rewrite, and in a repo with a format check in CI it turned a content fix into a red build.
|
|
10
|
+
|
|
11
|
+
There is now one implementation of "format a written file the way this project does", `createPrettierFormatter`, exported from `@valbuild/server` and re-exported by `@valbuild/next/server` and `@valbuild/tanstack/server`. It resolves `.prettierrc` for each file (including any `overrides` that match it), leaves anything in `.prettierignore` untouched, and falls back to prettier's defaults when the project has no config. `val validate --fix` uses it, so the CLI and the Studio can no longer disagree about formatting.
|
|
12
|
+
|
|
13
|
+
Use it for your app's `formatter` too — this is the recommended setup, and it replaces reading `.prettierrc.json` by hand:
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import prettier from "prettier";
|
|
17
|
+
import {
|
|
18
|
+
initValServer,
|
|
19
|
+
createPrettierFormatter,
|
|
20
|
+
} from "@valbuild/next/server";
|
|
21
|
+
|
|
22
|
+
const { valNextAppRouter } = initValServer(
|
|
23
|
+
valModules,
|
|
24
|
+
{ ...config },
|
|
25
|
+
{
|
|
26
|
+
draftMode,
|
|
27
|
+
formatter: createPrettierFormatter(prettier, {
|
|
28
|
+
projectRoot: process.cwd(),
|
|
29
|
+
}),
|
|
30
|
+
},
|
|
31
|
+
);
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Existing `formatter` callbacks keep working unchanged.
|
|
35
|
+
|
|
36
|
+
- [#706](https://github.com/valbuild/val/pull/706) [`72a7ca7`](https://github.com/valbuild/val/commit/72a7ca78354fff00e37a51359b17fba9334dc5e6) Thanks [@freekh](https://github.com/freekh)! - An endpoint that throws now answers Val's own 500 instead of the framework's.
|
|
37
|
+
|
|
38
|
+
Nothing caught a throw from an endpoint implementation, so it left the Val
|
|
39
|
+
router entirely and became whatever the host does with an unhandled error. On
|
|
40
|
+
TanStack Start that is h3, which replaces the message with the literal string
|
|
41
|
+
`"HTTPError"` and drops the stack — the same five words for a missing project,
|
|
42
|
+
a bad cookie and a module that failed to link — and keeps the real cause on the
|
|
43
|
+
server console. Where that console cannot be read (a Cloudflare Worker, for
|
|
44
|
+
one), a Val server had no way to say what broke inside it.
|
|
45
|
+
|
|
46
|
+
Such a request now answers Val's usual error envelope, naming the route, the
|
|
47
|
+
method and the cause:
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"message": "Val: GET /authorize failed: Project is not set",
|
|
52
|
+
"details": {
|
|
53
|
+
"route": "/authorize",
|
|
54
|
+
"method": "GET",
|
|
55
|
+
"error": "Project is not set"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The stack is logged rather than returned: `/authorize` and `/enable` are
|
|
61
|
+
reachable without a session, and the message is the part a caller can act on.
|
|
62
|
+
|
|
63
|
+
## 0.134.1
|
|
64
|
+
|
|
65
|
+
### Patch Changes
|
|
66
|
+
|
|
67
|
+
- Updated dependencies [[`821e789`](https://github.com/valbuild/val/commit/821e789c1af47510af5d23eb96384ff78ddd7646)]:
|
|
68
|
+
- @valbuild/shared@0.134.1
|
|
69
|
+
- @valbuild/ui@0.134.0
|
|
70
|
+
|
|
3
71
|
## 0.134.0
|
|
4
72
|
|
|
5
73
|
### Patch Changes
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What Val calls to format a file it has just written.
|
|
3
|
+
*
|
|
4
|
+
* The same shape `initValServer`, `initValMcp` and `ValOps` take as their
|
|
5
|
+
* `formatter` option. The path is the file's path INSIDE the project — a
|
|
6
|
+
* `ModuleFilePath` such as `/content/page.val.ts`, or a `*.val.json` entry
|
|
7
|
+
* beside it — never an absolute path on disk, because the writers that call it
|
|
8
|
+
* (`ValOps.prepare`, the CLI's `--fix`) only ever know a module by that path.
|
|
9
|
+
*/
|
|
10
|
+
export type ValFormatter = (code: string, filePath: string) => Promise<string> | string;
|
|
11
|
+
/**
|
|
12
|
+
* Prettier's options, as far as this file is concerned.
|
|
13
|
+
*
|
|
14
|
+
* Deliberately opaque: this file never reads an option, it only carries the
|
|
15
|
+
* bag from `resolveConfig` to `format`. Naming the real `Options` here would
|
|
16
|
+
* make it a compile error to build `@valbuild/server` in a project that has no
|
|
17
|
+
* prettier installed, which is most of them — prettier is a dependency the app
|
|
18
|
+
* opts into, so it is passed IN rather than imported.
|
|
19
|
+
*/
|
|
20
|
+
export type PrettierLikeConfig = object;
|
|
21
|
+
/**
|
|
22
|
+
* `prettier`, as this file wants it.
|
|
23
|
+
*
|
|
24
|
+
* Structural for the same reason `SharpLike` in `@valbuild/mcp` is: a type-only
|
|
25
|
+
* import of a package that is not installed is still a compile error, and this
|
|
26
|
+
* package has to typecheck without prettier. `createPrettierFormatter.test.ts`
|
|
27
|
+
* asserts the real library against this type so the structural description
|
|
28
|
+
* cannot drift away from it unnoticed.
|
|
29
|
+
*
|
|
30
|
+
* Every result is `T | Promise<T>` so that `@prettier/sync` — the same API with
|
|
31
|
+
* the awaits taken out — satisfies it too. Everything here is awaited either
|
|
32
|
+
* way, and a formatter is allowed to be synchronous: `ValFormatter` says so.
|
|
33
|
+
*/
|
|
34
|
+
export type PrettierLike = {
|
|
35
|
+
format(source: string, options: PrettierLikeConfig & {
|
|
36
|
+
filepath: string;
|
|
37
|
+
}): Promise<string> | string;
|
|
38
|
+
resolveConfig(filePath: string): Promise<PrettierLikeConfig | null> | PrettierLikeConfig | null;
|
|
39
|
+
getFileInfo(filePath: string, options: {
|
|
40
|
+
ignorePath: string[];
|
|
41
|
+
}): Promise<{
|
|
42
|
+
ignored: boolean;
|
|
43
|
+
}> | {
|
|
44
|
+
ignored: boolean;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* A {@link ValFormatter} that formats the way the project itself does.
|
|
49
|
+
*
|
|
50
|
+
* ONE implementation, for every writer of source files Val has: the Studio and
|
|
51
|
+
* the dev server (`initValServer`), an agent (`initValMcp`) and
|
|
52
|
+
* `val validate --fix`. They used to disagree — the CLI called
|
|
53
|
+
* `prettier.format(code, { filepath })` on its own behalf, and `format` does
|
|
54
|
+
* not read `.prettierrc`; only `resolveConfig`, `getFileInfo` and the prettier
|
|
55
|
+
* CLI do. `filepath` there selects the PARSER and nothing else, so the output
|
|
56
|
+
* was valid TypeScript in prettier's default style rather than the project's:
|
|
57
|
+
* a two-line content fix arriving as a whole-file rewrite, and a red `format`
|
|
58
|
+
* job in any repo that checks formatting in CI.
|
|
59
|
+
*
|
|
60
|
+
* ```ts
|
|
61
|
+
* import prettier from "prettier";
|
|
62
|
+
* import { createPrettierFormatter } from "@valbuild/next/server";
|
|
63
|
+
*
|
|
64
|
+
* initValServer(valModules, config, {
|
|
65
|
+
* draftMode,
|
|
66
|
+
* formatter: createPrettierFormatter(prettier, { projectRoot: process.cwd() }),
|
|
67
|
+
* });
|
|
68
|
+
* ```
|
|
69
|
+
*
|
|
70
|
+
* `projectRoot` is what a project-relative path is resolved against, and is
|
|
71
|
+
* therefore also where `.prettierignore` is looked for. Prettier's own config
|
|
72
|
+
* search walks UP from the resolved file, so a monorepo package with its own
|
|
73
|
+
* `.prettierrc` is found without being named here.
|
|
74
|
+
*
|
|
75
|
+
* Two decisions worth knowing:
|
|
76
|
+
*
|
|
77
|
+
* - **`.prettierignore` is honoured; `.gitignore` is not.** The prettier CLI
|
|
78
|
+
* consults both, but only one of them is a statement about formatting — a
|
|
79
|
+
* file is gitignored for reasons that have nothing to do with style, and the
|
|
80
|
+
* only files reaching this function are ones Val itself just wrote.
|
|
81
|
+
* - **No config found is not an error.** `resolveConfig` returns `null` and
|
|
82
|
+
* the file is formatted with prettier's defaults, which is what a project
|
|
83
|
+
* without a config has asked for.
|
|
84
|
+
*/
|
|
85
|
+
export declare function createPrettierFormatter(prettier: PrettierLike, options: {
|
|
86
|
+
projectRoot: string;
|
|
87
|
+
}): ValFormatter;
|
|
@@ -29,6 +29,8 @@ export { getValidationErrorFileRef } from "./getValidationErrorFileRef.js";
|
|
|
29
29
|
export { checkRemoteRef, downloadFileFromRemote, getCachedRemoteFileDir, getCachedRemoteFilePath, } from "./checkRemoteRef.js";
|
|
30
30
|
export { hasRemoteFileSchema } from "@valbuild/core";
|
|
31
31
|
export { getFileExt } from "./getFileExt.js";
|
|
32
|
+
export { createPrettierFormatter } from "./createPrettierFormatter.js";
|
|
33
|
+
export type { PrettierLike, PrettierLikeConfig, ValFormatter, } from "./createPrettierFormatter.js";
|
|
32
34
|
export { evalValConfigFile, findAndEvalValConfigFile, } from "./evalValConfigFile.js";
|
|
33
35
|
export { startValLogin, awaitValLoginConfirmation, persistPersonalAccessToken, ValLoginError, DEFAULT_LOGIN_HOST, DEFAULT_LOGIN_EXPIRES_IN_SECONDS, DEFAULT_LOGIN_POLL_INTERVAL_SECONDS, } from "./login.js";
|
|
34
36
|
export type { ValLoginErrorCode, ValLoginResult, ValDeviceAuthorization, } from "./login.js";
|
|
@@ -15311,12 +15311,62 @@ function createValApiRouter(route, valServerPromise, convert) {
|
|
|
15311
15311
|
}
|
|
15312
15312
|
query = queryRes.data;
|
|
15313
15313
|
}
|
|
15314
|
-
|
|
15315
|
-
|
|
15316
|
-
|
|
15317
|
-
|
|
15318
|
-
|
|
15319
|
-
|
|
15314
|
+
|
|
15315
|
+
/*
|
|
15316
|
+
* A throw from an endpoint is Val's to report, not the framework's.
|
|
15317
|
+
*
|
|
15318
|
+
* Nothing here used to catch, so an endpoint that threw left the router
|
|
15319
|
+
* entirely and became whatever the host does with an unhandled error --
|
|
15320
|
+
* and on TanStack Start that is h3, which replaces the message with the
|
|
15321
|
+
* literal string "HTTPError" and drops the stack. Its `debug` and
|
|
15322
|
+
* `silent` options are not reachable from out here: `requestHandler`
|
|
15323
|
+
* calls `toResponse(value, event)` with no config, and the default is
|
|
15324
|
+
* `{}`. So the body a caller got was
|
|
15325
|
+
* `{"status":500,"unhandled":true,"message":"HTTPError"}` -- the same
|
|
15326
|
+
* five words for a missing project, a bad cookie secret and a module
|
|
15327
|
+
* that failed to link -- with the real cause only on the server's
|
|
15328
|
+
* console.
|
|
15329
|
+
*
|
|
15330
|
+
* That is survivable where the console is readable. It is not in a
|
|
15331
|
+
* Cloudflare Dynamic Worker, whose `console` reaches no tail stream: a
|
|
15332
|
+
* link error in a lazily imported chunk (`does not provide an export
|
|
15333
|
+
* named 'getSerovalPlugins'`) showed up as an unreadable 500 on
|
|
15334
|
+
* `/authorize` and nowhere else at all.
|
|
15335
|
+
*
|
|
15336
|
+
* So every endpoint's throw becomes Val's own 500 envelope, which the
|
|
15337
|
+
* Studio already renders and `curl` already prints. The route and method
|
|
15338
|
+
* are named because a message rarely says which endpoint it came from.
|
|
15339
|
+
*
|
|
15340
|
+
* The MESSAGE travels and the STACK does not. The message is the whole
|
|
15341
|
+
* diagnostic value -- the line above names the package, the chunk and
|
|
15342
|
+
* the export -- while a stack is a walk through somebody's bundle, and
|
|
15343
|
+
* `/authorize` and `/enable` are reachable without a session. So the
|
|
15344
|
+
* stack goes to the console, where a host that can read one will find
|
|
15345
|
+
* it, and the body carries what a caller can act on.
|
|
15346
|
+
*/
|
|
15347
|
+
let res;
|
|
15348
|
+
try {
|
|
15349
|
+
res = await endpointImpl({
|
|
15350
|
+
body: bodyRes.data,
|
|
15351
|
+
cookies: cookiesRes.data,
|
|
15352
|
+
query,
|
|
15353
|
+
path
|
|
15354
|
+
});
|
|
15355
|
+
} catch (err) {
|
|
15356
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
15357
|
+
console.error(`Val: ${method} ${route} threw: ${error.message}`, error.stack);
|
|
15358
|
+
return {
|
|
15359
|
+
status: 500,
|
|
15360
|
+
json: {
|
|
15361
|
+
message: `Val: ${method} ${route} failed: ${error.message}`,
|
|
15362
|
+
details: {
|
|
15363
|
+
route,
|
|
15364
|
+
method,
|
|
15365
|
+
error: error.message
|
|
15366
|
+
}
|
|
15367
|
+
}
|
|
15368
|
+
};
|
|
15369
|
+
}
|
|
15320
15370
|
if (res.status === 500) {
|
|
15321
15371
|
var _res$json;
|
|
15322
15372
|
return {
|
|
@@ -17246,6 +17296,123 @@ function validateMetadata(actualMetadata, expectedMetadata) {
|
|
|
17246
17296
|
};
|
|
17247
17297
|
}
|
|
17248
17298
|
|
|
17299
|
+
/**
|
|
17300
|
+
* What Val calls to format a file it has just written.
|
|
17301
|
+
*
|
|
17302
|
+
* The same shape `initValServer`, `initValMcp` and `ValOps` take as their
|
|
17303
|
+
* `formatter` option. The path is the file's path INSIDE the project — a
|
|
17304
|
+
* `ModuleFilePath` such as `/content/page.val.ts`, or a `*.val.json` entry
|
|
17305
|
+
* beside it — never an absolute path on disk, because the writers that call it
|
|
17306
|
+
* (`ValOps.prepare`, the CLI's `--fix`) only ever know a module by that path.
|
|
17307
|
+
*/
|
|
17308
|
+
|
|
17309
|
+
/**
|
|
17310
|
+
* Prettier's options, as far as this file is concerned.
|
|
17311
|
+
*
|
|
17312
|
+
* Deliberately opaque: this file never reads an option, it only carries the
|
|
17313
|
+
* bag from `resolveConfig` to `format`. Naming the real `Options` here would
|
|
17314
|
+
* make it a compile error to build `@valbuild/server` in a project that has no
|
|
17315
|
+
* prettier installed, which is most of them — prettier is a dependency the app
|
|
17316
|
+
* opts into, so it is passed IN rather than imported.
|
|
17317
|
+
*/
|
|
17318
|
+
|
|
17319
|
+
/**
|
|
17320
|
+
* `prettier`, as this file wants it.
|
|
17321
|
+
*
|
|
17322
|
+
* Structural for the same reason `SharpLike` in `@valbuild/mcp` is: a type-only
|
|
17323
|
+
* import of a package that is not installed is still a compile error, and this
|
|
17324
|
+
* package has to typecheck without prettier. `createPrettierFormatter.test.ts`
|
|
17325
|
+
* asserts the real library against this type so the structural description
|
|
17326
|
+
* cannot drift away from it unnoticed.
|
|
17327
|
+
*
|
|
17328
|
+
* Every result is `T | Promise<T>` so that `@prettier/sync` — the same API with
|
|
17329
|
+
* the awaits taken out — satisfies it too. Everything here is awaited either
|
|
17330
|
+
* way, and a formatter is allowed to be synchronous: `ValFormatter` says so.
|
|
17331
|
+
*/
|
|
17332
|
+
|
|
17333
|
+
/**
|
|
17334
|
+
* Resolve a path Val handed us against the project.
|
|
17335
|
+
*
|
|
17336
|
+
* Val's writers pass a project-relative path (`/content/page.val.ts`), and
|
|
17337
|
+
* prettier needs a real one — both to find the `.prettierrc` that governs the
|
|
17338
|
+
* file and to match it against `.prettierignore`. An absolute path that is
|
|
17339
|
+
* already inside the project is taken as it comes, so a caller that happens to
|
|
17340
|
+
* hold a real path is not mangled into `<root>/<root>/...`.
|
|
17341
|
+
*/
|
|
17342
|
+
function resolveAgainstProject(projectRoot, filePath) {
|
|
17343
|
+
if (path__namespace["default"].isAbsolute(filePath)) {
|
|
17344
|
+
const relative = path__namespace["default"].relative(projectRoot, filePath);
|
|
17345
|
+
if (relative && !relative.startsWith("..") && !path__namespace["default"].isAbsolute(relative)) {
|
|
17346
|
+
return filePath;
|
|
17347
|
+
}
|
|
17348
|
+
}
|
|
17349
|
+
return path__namespace["default"].join(projectRoot, filePath);
|
|
17350
|
+
}
|
|
17351
|
+
|
|
17352
|
+
/**
|
|
17353
|
+
* A {@link ValFormatter} that formats the way the project itself does.
|
|
17354
|
+
*
|
|
17355
|
+
* ONE implementation, for every writer of source files Val has: the Studio and
|
|
17356
|
+
* the dev server (`initValServer`), an agent (`initValMcp`) and
|
|
17357
|
+
* `val validate --fix`. They used to disagree — the CLI called
|
|
17358
|
+
* `prettier.format(code, { filepath })` on its own behalf, and `format` does
|
|
17359
|
+
* not read `.prettierrc`; only `resolveConfig`, `getFileInfo` and the prettier
|
|
17360
|
+
* CLI do. `filepath` there selects the PARSER and nothing else, so the output
|
|
17361
|
+
* was valid TypeScript in prettier's default style rather than the project's:
|
|
17362
|
+
* a two-line content fix arriving as a whole-file rewrite, and a red `format`
|
|
17363
|
+
* job in any repo that checks formatting in CI.
|
|
17364
|
+
*
|
|
17365
|
+
* ```ts
|
|
17366
|
+
* import prettier from "prettier";
|
|
17367
|
+
* import { createPrettierFormatter } from "@valbuild/next/server";
|
|
17368
|
+
*
|
|
17369
|
+
* initValServer(valModules, config, {
|
|
17370
|
+
* draftMode,
|
|
17371
|
+
* formatter: createPrettierFormatter(prettier, { projectRoot: process.cwd() }),
|
|
17372
|
+
* });
|
|
17373
|
+
* ```
|
|
17374
|
+
*
|
|
17375
|
+
* `projectRoot` is what a project-relative path is resolved against, and is
|
|
17376
|
+
* therefore also where `.prettierignore` is looked for. Prettier's own config
|
|
17377
|
+
* search walks UP from the resolved file, so a monorepo package with its own
|
|
17378
|
+
* `.prettierrc` is found without being named here.
|
|
17379
|
+
*
|
|
17380
|
+
* Two decisions worth knowing:
|
|
17381
|
+
*
|
|
17382
|
+
* - **`.prettierignore` is honoured; `.gitignore` is not.** The prettier CLI
|
|
17383
|
+
* consults both, but only one of them is a statement about formatting — a
|
|
17384
|
+
* file is gitignored for reasons that have nothing to do with style, and the
|
|
17385
|
+
* only files reaching this function are ones Val itself just wrote.
|
|
17386
|
+
* - **No config found is not an error.** `resolveConfig` returns `null` and
|
|
17387
|
+
* the file is formatted with prettier's defaults, which is what a project
|
|
17388
|
+
* without a config has asked for.
|
|
17389
|
+
*/
|
|
17390
|
+
function createPrettierFormatter(prettier, options) {
|
|
17391
|
+
const projectRoot = path__namespace["default"].resolve(options.projectRoot);
|
|
17392
|
+
// One array, built once: prettier reads and caches the ignore file itself, so
|
|
17393
|
+
// this is only here to avoid rebuilding the path per file.
|
|
17394
|
+
const ignorePath = [path__namespace["default"].join(projectRoot, ".prettierignore")];
|
|
17395
|
+
return async (code, filePath) => {
|
|
17396
|
+
const absoluteFilePath = resolveAgainstProject(projectRoot, filePath);
|
|
17397
|
+
const {
|
|
17398
|
+
ignored
|
|
17399
|
+
} = await prettier.getFileInfo(absoluteFilePath, {
|
|
17400
|
+
ignorePath
|
|
17401
|
+
});
|
|
17402
|
+
if (ignored) {
|
|
17403
|
+
return code;
|
|
17404
|
+
}
|
|
17405
|
+
// `resolveConfig` applies the `overrides` that match this file and caches
|
|
17406
|
+
// per directory, so calling it per file is cheap even on a project-wide
|
|
17407
|
+
// `--fix`. `filepath` is still required: it is what picks the parser.
|
|
17408
|
+
const config = await prettier.resolveConfig(absoluteFilePath);
|
|
17409
|
+
return prettier.format(code, {
|
|
17410
|
+
...config,
|
|
17411
|
+
filepath: absoluteFilePath
|
|
17412
|
+
});
|
|
17413
|
+
};
|
|
17414
|
+
}
|
|
17415
|
+
|
|
17249
17416
|
/**
|
|
17250
17417
|
* NOTE: this is intentionally NOT `SharedValConfig` from `@valbuild/shared`.
|
|
17251
17418
|
* That schema requires `files.directory` to be exactly `/public/val`, whereas
|
|
@@ -17854,6 +18021,7 @@ exports.createDefaultValFSHost = createDefaultValFSHost;
|
|
|
17854
18021
|
exports.createFixPatch = createFixPatch;
|
|
17855
18022
|
exports.createJsonEntryPathMap = createJsonEntryPathMap;
|
|
17856
18023
|
exports.createModulePathMap = createModulePathMap;
|
|
18024
|
+
exports.createPrettierFormatter = createPrettierFormatter;
|
|
17857
18025
|
exports.createService = createService;
|
|
17858
18026
|
exports.createValApiRouter = createValApiRouter;
|
|
17859
18027
|
exports.createValModuleFileInspector = createValModuleFileInspector;
|
|
@@ -15311,12 +15311,62 @@ function createValApiRouter(route, valServerPromise, convert) {
|
|
|
15311
15311
|
}
|
|
15312
15312
|
query = queryRes.data;
|
|
15313
15313
|
}
|
|
15314
|
-
|
|
15315
|
-
|
|
15316
|
-
|
|
15317
|
-
|
|
15318
|
-
|
|
15319
|
-
|
|
15314
|
+
|
|
15315
|
+
/*
|
|
15316
|
+
* A throw from an endpoint is Val's to report, not the framework's.
|
|
15317
|
+
*
|
|
15318
|
+
* Nothing here used to catch, so an endpoint that threw left the router
|
|
15319
|
+
* entirely and became whatever the host does with an unhandled error --
|
|
15320
|
+
* and on TanStack Start that is h3, which replaces the message with the
|
|
15321
|
+
* literal string "HTTPError" and drops the stack. Its `debug` and
|
|
15322
|
+
* `silent` options are not reachable from out here: `requestHandler`
|
|
15323
|
+
* calls `toResponse(value, event)` with no config, and the default is
|
|
15324
|
+
* `{}`. So the body a caller got was
|
|
15325
|
+
* `{"status":500,"unhandled":true,"message":"HTTPError"}` -- the same
|
|
15326
|
+
* five words for a missing project, a bad cookie secret and a module
|
|
15327
|
+
* that failed to link -- with the real cause only on the server's
|
|
15328
|
+
* console.
|
|
15329
|
+
*
|
|
15330
|
+
* That is survivable where the console is readable. It is not in a
|
|
15331
|
+
* Cloudflare Dynamic Worker, whose `console` reaches no tail stream: a
|
|
15332
|
+
* link error in a lazily imported chunk (`does not provide an export
|
|
15333
|
+
* named 'getSerovalPlugins'`) showed up as an unreadable 500 on
|
|
15334
|
+
* `/authorize` and nowhere else at all.
|
|
15335
|
+
*
|
|
15336
|
+
* So every endpoint's throw becomes Val's own 500 envelope, which the
|
|
15337
|
+
* Studio already renders and `curl` already prints. The route and method
|
|
15338
|
+
* are named because a message rarely says which endpoint it came from.
|
|
15339
|
+
*
|
|
15340
|
+
* The MESSAGE travels and the STACK does not. The message is the whole
|
|
15341
|
+
* diagnostic value -- the line above names the package, the chunk and
|
|
15342
|
+
* the export -- while a stack is a walk through somebody's bundle, and
|
|
15343
|
+
* `/authorize` and `/enable` are reachable without a session. So the
|
|
15344
|
+
* stack goes to the console, where a host that can read one will find
|
|
15345
|
+
* it, and the body carries what a caller can act on.
|
|
15346
|
+
*/
|
|
15347
|
+
let res;
|
|
15348
|
+
try {
|
|
15349
|
+
res = await endpointImpl({
|
|
15350
|
+
body: bodyRes.data,
|
|
15351
|
+
cookies: cookiesRes.data,
|
|
15352
|
+
query,
|
|
15353
|
+
path
|
|
15354
|
+
});
|
|
15355
|
+
} catch (err) {
|
|
15356
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
15357
|
+
console.error(`Val: ${method} ${route} threw: ${error.message}`, error.stack);
|
|
15358
|
+
return {
|
|
15359
|
+
status: 500,
|
|
15360
|
+
json: {
|
|
15361
|
+
message: `Val: ${method} ${route} failed: ${error.message}`,
|
|
15362
|
+
details: {
|
|
15363
|
+
route,
|
|
15364
|
+
method,
|
|
15365
|
+
error: error.message
|
|
15366
|
+
}
|
|
15367
|
+
}
|
|
15368
|
+
};
|
|
15369
|
+
}
|
|
15320
15370
|
if (res.status === 500) {
|
|
15321
15371
|
var _res$json;
|
|
15322
15372
|
return {
|
|
@@ -17246,6 +17296,123 @@ function validateMetadata(actualMetadata, expectedMetadata) {
|
|
|
17246
17296
|
};
|
|
17247
17297
|
}
|
|
17248
17298
|
|
|
17299
|
+
/**
|
|
17300
|
+
* What Val calls to format a file it has just written.
|
|
17301
|
+
*
|
|
17302
|
+
* The same shape `initValServer`, `initValMcp` and `ValOps` take as their
|
|
17303
|
+
* `formatter` option. The path is the file's path INSIDE the project — a
|
|
17304
|
+
* `ModuleFilePath` such as `/content/page.val.ts`, or a `*.val.json` entry
|
|
17305
|
+
* beside it — never an absolute path on disk, because the writers that call it
|
|
17306
|
+
* (`ValOps.prepare`, the CLI's `--fix`) only ever know a module by that path.
|
|
17307
|
+
*/
|
|
17308
|
+
|
|
17309
|
+
/**
|
|
17310
|
+
* Prettier's options, as far as this file is concerned.
|
|
17311
|
+
*
|
|
17312
|
+
* Deliberately opaque: this file never reads an option, it only carries the
|
|
17313
|
+
* bag from `resolveConfig` to `format`. Naming the real `Options` here would
|
|
17314
|
+
* make it a compile error to build `@valbuild/server` in a project that has no
|
|
17315
|
+
* prettier installed, which is most of them — prettier is a dependency the app
|
|
17316
|
+
* opts into, so it is passed IN rather than imported.
|
|
17317
|
+
*/
|
|
17318
|
+
|
|
17319
|
+
/**
|
|
17320
|
+
* `prettier`, as this file wants it.
|
|
17321
|
+
*
|
|
17322
|
+
* Structural for the same reason `SharpLike` in `@valbuild/mcp` is: a type-only
|
|
17323
|
+
* import of a package that is not installed is still a compile error, and this
|
|
17324
|
+
* package has to typecheck without prettier. `createPrettierFormatter.test.ts`
|
|
17325
|
+
* asserts the real library against this type so the structural description
|
|
17326
|
+
* cannot drift away from it unnoticed.
|
|
17327
|
+
*
|
|
17328
|
+
* Every result is `T | Promise<T>` so that `@prettier/sync` — the same API with
|
|
17329
|
+
* the awaits taken out — satisfies it too. Everything here is awaited either
|
|
17330
|
+
* way, and a formatter is allowed to be synchronous: `ValFormatter` says so.
|
|
17331
|
+
*/
|
|
17332
|
+
|
|
17333
|
+
/**
|
|
17334
|
+
* Resolve a path Val handed us against the project.
|
|
17335
|
+
*
|
|
17336
|
+
* Val's writers pass a project-relative path (`/content/page.val.ts`), and
|
|
17337
|
+
* prettier needs a real one — both to find the `.prettierrc` that governs the
|
|
17338
|
+
* file and to match it against `.prettierignore`. An absolute path that is
|
|
17339
|
+
* already inside the project is taken as it comes, so a caller that happens to
|
|
17340
|
+
* hold a real path is not mangled into `<root>/<root>/...`.
|
|
17341
|
+
*/
|
|
17342
|
+
function resolveAgainstProject(projectRoot, filePath) {
|
|
17343
|
+
if (path__namespace["default"].isAbsolute(filePath)) {
|
|
17344
|
+
const relative = path__namespace["default"].relative(projectRoot, filePath);
|
|
17345
|
+
if (relative && !relative.startsWith("..") && !path__namespace["default"].isAbsolute(relative)) {
|
|
17346
|
+
return filePath;
|
|
17347
|
+
}
|
|
17348
|
+
}
|
|
17349
|
+
return path__namespace["default"].join(projectRoot, filePath);
|
|
17350
|
+
}
|
|
17351
|
+
|
|
17352
|
+
/**
|
|
17353
|
+
* A {@link ValFormatter} that formats the way the project itself does.
|
|
17354
|
+
*
|
|
17355
|
+
* ONE implementation, for every writer of source files Val has: the Studio and
|
|
17356
|
+
* the dev server (`initValServer`), an agent (`initValMcp`) and
|
|
17357
|
+
* `val validate --fix`. They used to disagree — the CLI called
|
|
17358
|
+
* `prettier.format(code, { filepath })` on its own behalf, and `format` does
|
|
17359
|
+
* not read `.prettierrc`; only `resolveConfig`, `getFileInfo` and the prettier
|
|
17360
|
+
* CLI do. `filepath` there selects the PARSER and nothing else, so the output
|
|
17361
|
+
* was valid TypeScript in prettier's default style rather than the project's:
|
|
17362
|
+
* a two-line content fix arriving as a whole-file rewrite, and a red `format`
|
|
17363
|
+
* job in any repo that checks formatting in CI.
|
|
17364
|
+
*
|
|
17365
|
+
* ```ts
|
|
17366
|
+
* import prettier from "prettier";
|
|
17367
|
+
* import { createPrettierFormatter } from "@valbuild/next/server";
|
|
17368
|
+
*
|
|
17369
|
+
* initValServer(valModules, config, {
|
|
17370
|
+
* draftMode,
|
|
17371
|
+
* formatter: createPrettierFormatter(prettier, { projectRoot: process.cwd() }),
|
|
17372
|
+
* });
|
|
17373
|
+
* ```
|
|
17374
|
+
*
|
|
17375
|
+
* `projectRoot` is what a project-relative path is resolved against, and is
|
|
17376
|
+
* therefore also where `.prettierignore` is looked for. Prettier's own config
|
|
17377
|
+
* search walks UP from the resolved file, so a monorepo package with its own
|
|
17378
|
+
* `.prettierrc` is found without being named here.
|
|
17379
|
+
*
|
|
17380
|
+
* Two decisions worth knowing:
|
|
17381
|
+
*
|
|
17382
|
+
* - **`.prettierignore` is honoured; `.gitignore` is not.** The prettier CLI
|
|
17383
|
+
* consults both, but only one of them is a statement about formatting — a
|
|
17384
|
+
* file is gitignored for reasons that have nothing to do with style, and the
|
|
17385
|
+
* only files reaching this function are ones Val itself just wrote.
|
|
17386
|
+
* - **No config found is not an error.** `resolveConfig` returns `null` and
|
|
17387
|
+
* the file is formatted with prettier's defaults, which is what a project
|
|
17388
|
+
* without a config has asked for.
|
|
17389
|
+
*/
|
|
17390
|
+
function createPrettierFormatter(prettier, options) {
|
|
17391
|
+
const projectRoot = path__namespace["default"].resolve(options.projectRoot);
|
|
17392
|
+
// One array, built once: prettier reads and caches the ignore file itself, so
|
|
17393
|
+
// this is only here to avoid rebuilding the path per file.
|
|
17394
|
+
const ignorePath = [path__namespace["default"].join(projectRoot, ".prettierignore")];
|
|
17395
|
+
return async (code, filePath) => {
|
|
17396
|
+
const absoluteFilePath = resolveAgainstProject(projectRoot, filePath);
|
|
17397
|
+
const {
|
|
17398
|
+
ignored
|
|
17399
|
+
} = await prettier.getFileInfo(absoluteFilePath, {
|
|
17400
|
+
ignorePath
|
|
17401
|
+
});
|
|
17402
|
+
if (ignored) {
|
|
17403
|
+
return code;
|
|
17404
|
+
}
|
|
17405
|
+
// `resolveConfig` applies the `overrides` that match this file and caches
|
|
17406
|
+
// per directory, so calling it per file is cheap even on a project-wide
|
|
17407
|
+
// `--fix`. `filepath` is still required: it is what picks the parser.
|
|
17408
|
+
const config = await prettier.resolveConfig(absoluteFilePath);
|
|
17409
|
+
return prettier.format(code, {
|
|
17410
|
+
...config,
|
|
17411
|
+
filepath: absoluteFilePath
|
|
17412
|
+
});
|
|
17413
|
+
};
|
|
17414
|
+
}
|
|
17415
|
+
|
|
17249
17416
|
/**
|
|
17250
17417
|
* NOTE: this is intentionally NOT `SharedValConfig` from `@valbuild/shared`.
|
|
17251
17418
|
* That schema requires `files.directory` to be exactly `/public/val`, whereas
|
|
@@ -17854,6 +18021,7 @@ exports.createDefaultValFSHost = createDefaultValFSHost;
|
|
|
17854
18021
|
exports.createFixPatch = createFixPatch;
|
|
17855
18022
|
exports.createJsonEntryPathMap = createJsonEntryPathMap;
|
|
17856
18023
|
exports.createModulePathMap = createModulePathMap;
|
|
18024
|
+
exports.createPrettierFormatter = createPrettierFormatter;
|
|
17857
18025
|
exports.createService = createService;
|
|
17858
18026
|
exports.createValApiRouter = createValApiRouter;
|
|
17859
18027
|
exports.createValModuleFileInspector = createValModuleFileInspector;
|
|
@@ -15277,12 +15277,62 @@ function createValApiRouter(route, valServerPromise, convert) {
|
|
|
15277
15277
|
}
|
|
15278
15278
|
query = queryRes.data;
|
|
15279
15279
|
}
|
|
15280
|
-
|
|
15281
|
-
|
|
15282
|
-
|
|
15283
|
-
|
|
15284
|
-
|
|
15285
|
-
|
|
15280
|
+
|
|
15281
|
+
/*
|
|
15282
|
+
* A throw from an endpoint is Val's to report, not the framework's.
|
|
15283
|
+
*
|
|
15284
|
+
* Nothing here used to catch, so an endpoint that threw left the router
|
|
15285
|
+
* entirely and became whatever the host does with an unhandled error --
|
|
15286
|
+
* and on TanStack Start that is h3, which replaces the message with the
|
|
15287
|
+
* literal string "HTTPError" and drops the stack. Its `debug` and
|
|
15288
|
+
* `silent` options are not reachable from out here: `requestHandler`
|
|
15289
|
+
* calls `toResponse(value, event)` with no config, and the default is
|
|
15290
|
+
* `{}`. So the body a caller got was
|
|
15291
|
+
* `{"status":500,"unhandled":true,"message":"HTTPError"}` -- the same
|
|
15292
|
+
* five words for a missing project, a bad cookie secret and a module
|
|
15293
|
+
* that failed to link -- with the real cause only on the server's
|
|
15294
|
+
* console.
|
|
15295
|
+
*
|
|
15296
|
+
* That is survivable where the console is readable. It is not in a
|
|
15297
|
+
* Cloudflare Dynamic Worker, whose `console` reaches no tail stream: a
|
|
15298
|
+
* link error in a lazily imported chunk (`does not provide an export
|
|
15299
|
+
* named 'getSerovalPlugins'`) showed up as an unreadable 500 on
|
|
15300
|
+
* `/authorize` and nowhere else at all.
|
|
15301
|
+
*
|
|
15302
|
+
* So every endpoint's throw becomes Val's own 500 envelope, which the
|
|
15303
|
+
* Studio already renders and `curl` already prints. The route and method
|
|
15304
|
+
* are named because a message rarely says which endpoint it came from.
|
|
15305
|
+
*
|
|
15306
|
+
* The MESSAGE travels and the STACK does not. The message is the whole
|
|
15307
|
+
* diagnostic value -- the line above names the package, the chunk and
|
|
15308
|
+
* the export -- while a stack is a walk through somebody's bundle, and
|
|
15309
|
+
* `/authorize` and `/enable` are reachable without a session. So the
|
|
15310
|
+
* stack goes to the console, where a host that can read one will find
|
|
15311
|
+
* it, and the body carries what a caller can act on.
|
|
15312
|
+
*/
|
|
15313
|
+
let res;
|
|
15314
|
+
try {
|
|
15315
|
+
res = await endpointImpl({
|
|
15316
|
+
body: bodyRes.data,
|
|
15317
|
+
cookies: cookiesRes.data,
|
|
15318
|
+
query,
|
|
15319
|
+
path
|
|
15320
|
+
});
|
|
15321
|
+
} catch (err) {
|
|
15322
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
15323
|
+
console.error(`Val: ${method} ${route} threw: ${error.message}`, error.stack);
|
|
15324
|
+
return {
|
|
15325
|
+
status: 500,
|
|
15326
|
+
json: {
|
|
15327
|
+
message: `Val: ${method} ${route} failed: ${error.message}`,
|
|
15328
|
+
details: {
|
|
15329
|
+
route,
|
|
15330
|
+
method,
|
|
15331
|
+
error: error.message
|
|
15332
|
+
}
|
|
15333
|
+
}
|
|
15334
|
+
};
|
|
15335
|
+
}
|
|
15286
15336
|
if (res.status === 500) {
|
|
15287
15337
|
var _res$json;
|
|
15288
15338
|
return {
|
|
@@ -17212,6 +17262,123 @@ function validateMetadata(actualMetadata, expectedMetadata) {
|
|
|
17212
17262
|
};
|
|
17213
17263
|
}
|
|
17214
17264
|
|
|
17265
|
+
/**
|
|
17266
|
+
* What Val calls to format a file it has just written.
|
|
17267
|
+
*
|
|
17268
|
+
* The same shape `initValServer`, `initValMcp` and `ValOps` take as their
|
|
17269
|
+
* `formatter` option. The path is the file's path INSIDE the project — a
|
|
17270
|
+
* `ModuleFilePath` such as `/content/page.val.ts`, or a `*.val.json` entry
|
|
17271
|
+
* beside it — never an absolute path on disk, because the writers that call it
|
|
17272
|
+
* (`ValOps.prepare`, the CLI's `--fix`) only ever know a module by that path.
|
|
17273
|
+
*/
|
|
17274
|
+
|
|
17275
|
+
/**
|
|
17276
|
+
* Prettier's options, as far as this file is concerned.
|
|
17277
|
+
*
|
|
17278
|
+
* Deliberately opaque: this file never reads an option, it only carries the
|
|
17279
|
+
* bag from `resolveConfig` to `format`. Naming the real `Options` here would
|
|
17280
|
+
* make it a compile error to build `@valbuild/server` in a project that has no
|
|
17281
|
+
* prettier installed, which is most of them — prettier is a dependency the app
|
|
17282
|
+
* opts into, so it is passed IN rather than imported.
|
|
17283
|
+
*/
|
|
17284
|
+
|
|
17285
|
+
/**
|
|
17286
|
+
* `prettier`, as this file wants it.
|
|
17287
|
+
*
|
|
17288
|
+
* Structural for the same reason `SharpLike` in `@valbuild/mcp` is: a type-only
|
|
17289
|
+
* import of a package that is not installed is still a compile error, and this
|
|
17290
|
+
* package has to typecheck without prettier. `createPrettierFormatter.test.ts`
|
|
17291
|
+
* asserts the real library against this type so the structural description
|
|
17292
|
+
* cannot drift away from it unnoticed.
|
|
17293
|
+
*
|
|
17294
|
+
* Every result is `T | Promise<T>` so that `@prettier/sync` — the same API with
|
|
17295
|
+
* the awaits taken out — satisfies it too. Everything here is awaited either
|
|
17296
|
+
* way, and a formatter is allowed to be synchronous: `ValFormatter` says so.
|
|
17297
|
+
*/
|
|
17298
|
+
|
|
17299
|
+
/**
|
|
17300
|
+
* Resolve a path Val handed us against the project.
|
|
17301
|
+
*
|
|
17302
|
+
* Val's writers pass a project-relative path (`/content/page.val.ts`), and
|
|
17303
|
+
* prettier needs a real one — both to find the `.prettierrc` that governs the
|
|
17304
|
+
* file and to match it against `.prettierignore`. An absolute path that is
|
|
17305
|
+
* already inside the project is taken as it comes, so a caller that happens to
|
|
17306
|
+
* hold a real path is not mangled into `<root>/<root>/...`.
|
|
17307
|
+
*/
|
|
17308
|
+
function resolveAgainstProject(projectRoot, filePath) {
|
|
17309
|
+
if (path__default.isAbsolute(filePath)) {
|
|
17310
|
+
const relative = path__default.relative(projectRoot, filePath);
|
|
17311
|
+
if (relative && !relative.startsWith("..") && !path__default.isAbsolute(relative)) {
|
|
17312
|
+
return filePath;
|
|
17313
|
+
}
|
|
17314
|
+
}
|
|
17315
|
+
return path__default.join(projectRoot, filePath);
|
|
17316
|
+
}
|
|
17317
|
+
|
|
17318
|
+
/**
|
|
17319
|
+
* A {@link ValFormatter} that formats the way the project itself does.
|
|
17320
|
+
*
|
|
17321
|
+
* ONE implementation, for every writer of source files Val has: the Studio and
|
|
17322
|
+
* the dev server (`initValServer`), an agent (`initValMcp`) and
|
|
17323
|
+
* `val validate --fix`. They used to disagree — the CLI called
|
|
17324
|
+
* `prettier.format(code, { filepath })` on its own behalf, and `format` does
|
|
17325
|
+
* not read `.prettierrc`; only `resolveConfig`, `getFileInfo` and the prettier
|
|
17326
|
+
* CLI do. `filepath` there selects the PARSER and nothing else, so the output
|
|
17327
|
+
* was valid TypeScript in prettier's default style rather than the project's:
|
|
17328
|
+
* a two-line content fix arriving as a whole-file rewrite, and a red `format`
|
|
17329
|
+
* job in any repo that checks formatting in CI.
|
|
17330
|
+
*
|
|
17331
|
+
* ```ts
|
|
17332
|
+
* import prettier from "prettier";
|
|
17333
|
+
* import { createPrettierFormatter } from "@valbuild/next/server";
|
|
17334
|
+
*
|
|
17335
|
+
* initValServer(valModules, config, {
|
|
17336
|
+
* draftMode,
|
|
17337
|
+
* formatter: createPrettierFormatter(prettier, { projectRoot: process.cwd() }),
|
|
17338
|
+
* });
|
|
17339
|
+
* ```
|
|
17340
|
+
*
|
|
17341
|
+
* `projectRoot` is what a project-relative path is resolved against, and is
|
|
17342
|
+
* therefore also where `.prettierignore` is looked for. Prettier's own config
|
|
17343
|
+
* search walks UP from the resolved file, so a monorepo package with its own
|
|
17344
|
+
* `.prettierrc` is found without being named here.
|
|
17345
|
+
*
|
|
17346
|
+
* Two decisions worth knowing:
|
|
17347
|
+
*
|
|
17348
|
+
* - **`.prettierignore` is honoured; `.gitignore` is not.** The prettier CLI
|
|
17349
|
+
* consults both, but only one of them is a statement about formatting — a
|
|
17350
|
+
* file is gitignored for reasons that have nothing to do with style, and the
|
|
17351
|
+
* only files reaching this function are ones Val itself just wrote.
|
|
17352
|
+
* - **No config found is not an error.** `resolveConfig` returns `null` and
|
|
17353
|
+
* the file is formatted with prettier's defaults, which is what a project
|
|
17354
|
+
* without a config has asked for.
|
|
17355
|
+
*/
|
|
17356
|
+
function createPrettierFormatter(prettier, options) {
|
|
17357
|
+
const projectRoot = path__default.resolve(options.projectRoot);
|
|
17358
|
+
// One array, built once: prettier reads and caches the ignore file itself, so
|
|
17359
|
+
// this is only here to avoid rebuilding the path per file.
|
|
17360
|
+
const ignorePath = [path__default.join(projectRoot, ".prettierignore")];
|
|
17361
|
+
return async (code, filePath) => {
|
|
17362
|
+
const absoluteFilePath = resolveAgainstProject(projectRoot, filePath);
|
|
17363
|
+
const {
|
|
17364
|
+
ignored
|
|
17365
|
+
} = await prettier.getFileInfo(absoluteFilePath, {
|
|
17366
|
+
ignorePath
|
|
17367
|
+
});
|
|
17368
|
+
if (ignored) {
|
|
17369
|
+
return code;
|
|
17370
|
+
}
|
|
17371
|
+
// `resolveConfig` applies the `overrides` that match this file and caches
|
|
17372
|
+
// per directory, so calling it per file is cheap even on a project-wide
|
|
17373
|
+
// `--fix`. `filepath` is still required: it is what picks the parser.
|
|
17374
|
+
const config = await prettier.resolveConfig(absoluteFilePath);
|
|
17375
|
+
return prettier.format(code, {
|
|
17376
|
+
...config,
|
|
17377
|
+
filepath: absoluteFilePath
|
|
17378
|
+
});
|
|
17379
|
+
};
|
|
17380
|
+
}
|
|
17381
|
+
|
|
17215
17382
|
/**
|
|
17216
17383
|
* NOTE: this is intentionally NOT `SharedValConfig` from `@valbuild/shared`.
|
|
17217
17384
|
* That schema requires `files.directory` to be exactly `/public/val`, whereas
|
|
@@ -17794,4 +17961,4 @@ function readCapturedReport(snapshotDir) {
|
|
|
17794
17961
|
return JSON.parse(fs.readFileSync(reportPath, "utf-8"));
|
|
17795
17962
|
}
|
|
17796
17963
|
|
|
17797
|
-
export { DEFAULT_LOGIN_EXPIRES_IN_SECONDS, DEFAULT_LOGIN_HOST, DEFAULT_LOGIN_POLL_INTERVAL_SECONDS, EXTERNAL_RESULT, InMemoryPatchStore, Service, ValFSHost, ValLoginError, ValModuleLoader, ValOpsFS, ValOpsHttp, ValOpsMemory, ValSourceFileHandler, analyzeValModule, awaitValLoginConfirmation, checkRemoteRef, classifyJsonValuesOp, compareWithCapturedReport, createDefaultValFSHost, createFixPatch, createJsonEntryPathMap, createModulePathMap, createService, createValApiRouter, createValModuleFileInspector, createValOps, createValServer, currentFixHandlers, decodeJwtWithoutVerifying, defineExternal, describePatchStoreProblems, downloadFileFromRemote, encodeJwt, err, evalValConfigFile, extractFileMetadata, extractImageMetadata, extractJsonValuesEntry, findAndEvalValConfigFile, findJsonEntryFilePath, fixHandlers, formatPatchSourceError, formatSyntaxErrorTree, getCachedRemoteFileDir, getCachedRemoteFilePath, getCompilerOptions, getExpire, getFileExt, getModulePathRange, getPersonalAccessTokenPath, getSettings, getValidationErrorFileRef, handleCheckAllFiles, handleExternalUpload, handleFileMetadata, handleJsonValuesExtractEntry, handleRemoteFileCheck, handleRemoteFileDownload, handleRemoteFileUpload, handleRemoteGalleryFileUpload, handleUniqueFolderCheck, initHandlerOptions, isExternalResult, loadValModules, ok, parsePersonalAccessTokenFile, patchSourceFile, persistPersonalAccessToken, planJsonValuesEntryExtraction, readCapturedReport, readPatchStore, rebaseContentOp, replaySnapshot, resolveRemoteFileAuth, safeReadGit, startValLogin, uploadRemoteFile, validateMetadata, verifyJwt };
|
|
17964
|
+
export { DEFAULT_LOGIN_EXPIRES_IN_SECONDS, DEFAULT_LOGIN_HOST, DEFAULT_LOGIN_POLL_INTERVAL_SECONDS, EXTERNAL_RESULT, InMemoryPatchStore, Service, ValFSHost, ValLoginError, ValModuleLoader, ValOpsFS, ValOpsHttp, ValOpsMemory, ValSourceFileHandler, analyzeValModule, awaitValLoginConfirmation, checkRemoteRef, classifyJsonValuesOp, compareWithCapturedReport, createDefaultValFSHost, createFixPatch, createJsonEntryPathMap, createModulePathMap, createPrettierFormatter, createService, createValApiRouter, createValModuleFileInspector, createValOps, createValServer, currentFixHandlers, decodeJwtWithoutVerifying, defineExternal, describePatchStoreProblems, downloadFileFromRemote, encodeJwt, err, evalValConfigFile, extractFileMetadata, extractImageMetadata, extractJsonValuesEntry, findAndEvalValConfigFile, findJsonEntryFilePath, fixHandlers, formatPatchSourceError, formatSyntaxErrorTree, getCachedRemoteFileDir, getCachedRemoteFilePath, getCompilerOptions, getExpire, getFileExt, getModulePathRange, getPersonalAccessTokenPath, getSettings, getValidationErrorFileRef, handleCheckAllFiles, handleExternalUpload, handleFileMetadata, handleJsonValuesExtractEntry, handleRemoteFileCheck, handleRemoteFileDownload, handleRemoteFileUpload, handleRemoteGalleryFileUpload, handleUniqueFolderCheck, initHandlerOptions, isExternalResult, loadValModules, ok, parsePersonalAccessTokenFile, patchSourceFile, persistPersonalAccessToken, planJsonValuesEntryExtraction, readCapturedReport, readPatchStore, rebaseContentOp, replaySnapshot, resolveRemoteFileAuth, safeReadGit, startValLogin, uploadRemoteFile, validateMetadata, verifyJwt };
|
package/package.json
CHANGED
|
@@ -16,10 +16,11 @@
|
|
|
16
16
|
"./package.json": "./package.json"
|
|
17
17
|
},
|
|
18
18
|
"types": "dist/valbuild-server.cjs.d.ts",
|
|
19
|
-
"version": "0.
|
|
19
|
+
"version": "0.135.0",
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@prettier/sync": "^0.6.1",
|
|
22
|
-
"@types/jest": "^30.0.0"
|
|
22
|
+
"@types/jest": "^30.0.0",
|
|
23
|
+
"prettier": "~3.8.5"
|
|
23
24
|
},
|
|
24
25
|
"dependencies": {
|
|
25
26
|
"chokidar": "^5.0.0",
|
|
@@ -30,7 +31,7 @@
|
|
|
30
31
|
"zod": "^4.4.3",
|
|
31
32
|
"zod-validation-error": "^5.0.0",
|
|
32
33
|
"@valbuild/core": "0.134.0",
|
|
33
|
-
"@valbuild/shared": "0.134.
|
|
34
|
+
"@valbuild/shared": "0.134.1",
|
|
34
35
|
"@valbuild/ui": "0.134.0"
|
|
35
36
|
},
|
|
36
37
|
"engines": {
|