@valbuild/cli 0.124.0 → 0.126.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 +177 -0
- package/cli/dist/valbuild-cli-cli.cjs.dev.js +46 -26
- package/cli/dist/valbuild-cli-cli.cjs.prod.js +46 -26
- package/cli/dist/valbuild-cli-cli.esm.js +46 -26
- package/package.json +6 -6
- package/src/cli.ts +17 -1
- package/src/debug/moduleClosure.ts +1 -4
- package/src/debug/snapshot.ts +19 -2
- package/src/getVersions.ts +22 -16
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,182 @@
|
|
|
1
1
|
# @valbuild/cli
|
|
2
2
|
|
|
3
|
+
## 0.126.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#652](https://github.com/valbuild/val/pull/652) [`f2fe70d`](https://github.com/valbuild/val/commit/f2fe70dab2b65000dfaf289f09c70b4a8291467a) Thanks [@freekh](https://github.com/freekh)! - `s.union` is now `s.discriminatedUnion` and `s.enum`.
|
|
8
|
+
|
|
9
|
+
`s.union` did two unrelated jobs and worked out which one you meant from its
|
|
10
|
+
first argument: a string key meant a tagged union of objects, literal schemas
|
|
11
|
+
meant a set of allowed strings. Those are now two schemas with two names.
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
// A fixed set of strings — presents as a dropdown
|
|
15
|
+
s.enum("primary", "secondary", "ghost"); // Schema<"primary" | "secondary" | "ghost">
|
|
16
|
+
|
|
17
|
+
// One of several object shapes, told apart by a tag field
|
|
18
|
+
s.discriminatedUnion(
|
|
19
|
+
"type",
|
|
20
|
+
s.object({ type: s.literal("hero"), heading: s.string() }),
|
|
21
|
+
s.object({ type: s.literal("quote"), text: s.string() }),
|
|
22
|
+
);
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`s.enum` takes the strings directly, so the `s.literal(...)` wrapper is gone.
|
|
26
|
+
|
|
27
|
+
**`s.union` still works** — it is deprecated, and it builds exactly the schema
|
|
28
|
+
above, so nothing has to change today:
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
s.union(s.literal("one"), s.literal("two")); // → s.enum("one", "two")
|
|
32
|
+
s.union("type", pageA, pageB); // → s.discriminatedUnion("type", pageA, pageB)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The two are different kinds of node, and that is the reason for the split. A
|
|
36
|
+
discriminated union is a container: the selected variant's fields are the fields
|
|
37
|
+
being edited, and everything that walks a schema descends through it. An enum is
|
|
38
|
+
a leaf — a string with a closed domain — so nothing recurses into it. Told apart
|
|
39
|
+
only by the shape of `key`, every consumer had to re-derive which one it was
|
|
40
|
+
holding; each now has its own serialized type (`"discriminated-union"` and
|
|
41
|
+
`"enum"`) and Val Studio has a field per kind rather than one field that
|
|
42
|
+
branches.
|
|
43
|
+
|
|
44
|
+
Two behaviour changes fall out of the split, both of them fixes:
|
|
45
|
+
|
|
46
|
+
- A value that is not a string at all now fails an enum's validation with a
|
|
47
|
+
type error. `s.union` of literals only ever checked the value against its
|
|
48
|
+
literals when the value WAS a string, so a number or an object where an enum
|
|
49
|
+
was declared validated clean.
|
|
50
|
+
- An enum field now shows its validation errors in Val Studio where the field
|
|
51
|
+
is opened on its own — the module editor and the canvas's fields column — and
|
|
52
|
+
gets the compact error layout inside an inline list row. It is a leaf now, so
|
|
53
|
+
it goes through the same error rendering as every other leaf field; the string
|
|
54
|
+
union bypassed it and showed nothing in those places.
|
|
55
|
+
|
|
56
|
+
Several latent crashes in the old `s.union` are fixed on the way past, all of
|
|
57
|
+
them cases where it threw a `TypeError` instead of reporting:
|
|
58
|
+
|
|
59
|
+
- A required discriminated union holding `null` now reports a type error rather
|
|
60
|
+
than throwing, and resolving a path underneath a nullable one that is `null`
|
|
61
|
+
gives the error the API promises instead of a crash.
|
|
62
|
+
- `s.literal("")` is a legal discriminator tag, and `s.enum("")` a legal value.
|
|
63
|
+
Both used to be treated as absent by a truthiness check — in path resolution,
|
|
64
|
+
in stega encoding, and in the message that lists a union's valid tags. The
|
|
65
|
+
editor's dropdowns handle them too: an empty value is reserved by the select
|
|
66
|
+
component and had to be mapped around.
|
|
67
|
+
- A variant that omits the discriminator entirely is now reported as the schema
|
|
68
|
+
error it is, instead of throwing while the check looked for it.
|
|
69
|
+
- An enum's value is now indexed for search, like every other string leaf. The
|
|
70
|
+
old string union was never indexed at all, so searching for one of its values
|
|
71
|
+
could not find the field.
|
|
72
|
+
- A nullable discriminated union set to `null` no longer renders a spinner that
|
|
73
|
+
never resolves.
|
|
74
|
+
|
|
75
|
+
`s.discriminatedUnion` also requires at least one variant, as `s.enum` requires
|
|
76
|
+
at least one value: a union with nothing to select is not a thing to write, and
|
|
77
|
+
everything downstream reads the first variant where it needs any.
|
|
78
|
+
|
|
79
|
+
If you read serialized schemas yourself, that is the breaking part: `type` is no
|
|
80
|
+
longer `"union"`, an enum carries `values: string[]` instead of a `key` plus
|
|
81
|
+
`items` of literal schemas, and `UnionSchema` is no longer a class.
|
|
82
|
+
`SerializedUnionSchema`, `SerializedStringUnionSchema`,
|
|
83
|
+
`SerializedObjectUnionSchema` and `UnionSchema` remain as deprecated type
|
|
84
|
+
aliases.
|
|
85
|
+
|
|
86
|
+
- Updated dependencies [[`5bfd630`](https://github.com/valbuild/val/commit/5bfd630b63dee2189e238f20fe72ecc5537160f7), [`ccbcda6`](https://github.com/valbuild/val/commit/ccbcda60b3e3c465071229ae1ba28ac735483e63), [`f2fe70d`](https://github.com/valbuild/val/commit/f2fe70dab2b65000dfaf289f09c70b4a8291467a), [`5c18c99`](https://github.com/valbuild/val/commit/5c18c99ecc84651f82123481fc042063db953833), [`171208a`](https://github.com/valbuild/val/commit/171208a20177e68ed5a8b1a6fdaabfe893a6aa5f)]:
|
|
87
|
+
- @valbuild/shared@0.126.0
|
|
88
|
+
- @valbuild/server@0.126.0
|
|
89
|
+
- @valbuild/core@0.126.0
|
|
90
|
+
- @valbuild/language-server@0.126.0
|
|
91
|
+
|
|
92
|
+
## 0.125.0
|
|
93
|
+
|
|
94
|
+
### Patch Changes
|
|
95
|
+
|
|
96
|
+
- [#638](https://github.com/valbuild/val/pull/638) [`c390397`](https://github.com/valbuild/val/commit/c390397cb5e203eb1bedae3a6fab15726e850b90) Thanks [@freekh](https://github.com/freekh)! - Val now runs on TanStack Start.
|
|
97
|
+
|
|
98
|
+
`@valbuild/tanstack` is a new package with everything `@valbuild/next` has: Val
|
|
99
|
+
Studio at `/val`, the on-page overlay and canvas, draft mode, the client hooks,
|
|
100
|
+
server-side content reads, images, and the MCP tools.
|
|
101
|
+
|
|
102
|
+
```sh
|
|
103
|
+
npm install @valbuild/tanstack
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
// val.config.ts
|
|
108
|
+
import { initVal } from "@valbuild/tanstack";
|
|
109
|
+
const { s, c, config, tanstackRouter } = initVal({ project: "org/project" });
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**Routes are first class.** A Val module for a route is named after the route
|
|
113
|
+
file it sits beside — `src/routes/posts.$postId.tsx` is served content by
|
|
114
|
+
`src/routes/posts.$postId.val.ts` — and its keys are the URLs that route serves:
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
export default c.define(
|
|
118
|
+
"/src/routes/posts.$postId.val.ts",
|
|
119
|
+
s.router(tanstackRouter, s.object({ title: s.string() })),
|
|
120
|
+
{ "/posts/hello-world": { title: "Hello world" } },
|
|
121
|
+
);
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`.` and `/` both separate segments, `$param` is a parameter, `$` is a splat, and
|
|
125
|
+
`index`, `route`, `(groups)` and `_pathless` layouts add no URL segment — the
|
|
126
|
+
same rules TanStack Router uses for the route file itself. Val validates every
|
|
127
|
+
key against that pattern, and Val Studio shows these modules as a sitemap under
|
|
128
|
+
**Pages**, where an editor can add a page.
|
|
129
|
+
|
|
130
|
+
Point the route generator away from your content files, in `vite.config.ts` and
|
|
131
|
+
`tsr.config.json`:
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
tanstackStart({ router: { routeFileIgnorePattern: "\\.val\\.[tj]sx?$" } });
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
See the [README](https://github.com/valbuild/val/blob/main/packages/tanstack/README.md)
|
|
138
|
+
for the full wiring, and `examples/tanstack` for a working app.
|
|
139
|
+
|
|
140
|
+
**Also fixed, for everyone:** `Internal.VERSION.core` was `null` in any ESM
|
|
141
|
+
bundle — it was read with `require("../package.json")` inside a `try`, so the
|
|
142
|
+
failure was silent. That version goes into every remote file ref and proxy mode
|
|
143
|
+
refuses to start without it. Every package now reads its version through a
|
|
144
|
+
static JSON import, which is inlined at build time.
|
|
145
|
+
|
|
146
|
+
Two smaller fixes that came out of running the whole toolchain against a
|
|
147
|
+
TanStack project:
|
|
148
|
+
|
|
149
|
+
- `val versions` reports `@valbuild/tanstack`, and `val debug` writes a snapshot
|
|
150
|
+
that names whichever framework package the captured project actually has.
|
|
151
|
+
- `@valbuild/eslint-plugin` reads a `tsconfig.json` that has comments in it. A
|
|
152
|
+
tsconfig is JSONC, and `JSON.parse` is not — so on any project whose tsconfig
|
|
153
|
+
carries a comment (the TanStack starter's does) the
|
|
154
|
+
`module-in-val-modules` rule threw `Expected double-quoted property name in
|
|
155
|
+
JSON` on the first file and took the whole lint run with it.
|
|
156
|
+
|
|
157
|
+
Three fixes found by driving the Studio against a real TanStack app:
|
|
158
|
+
|
|
159
|
+
- **A draft image now loads on the page.** The source the Studio pushes to the
|
|
160
|
+
host page carries `patch_id` for any file whose bytes are still in a patch, so
|
|
161
|
+
the page asks `/api/val/files/...?patch_id=` rather than a `/public` path that
|
|
162
|
+
nothing has written yet. This was silent — the image just did not appear — and
|
|
163
|
+
it affects any page that reads media through the hooks rather than on the
|
|
164
|
+
server, `@valbuild/next` included.
|
|
165
|
+
- **A splat route no longer logs an error on every render.** TanStack returns
|
|
166
|
+
both `_splat` and `*` for the same parameter; Val reported the second as a
|
|
167
|
+
parameter it could not place in the path.
|
|
168
|
+
- The TanStack example and starter render a 404 page instead of throwing
|
|
169
|
+
`notFound()` from a component, which escaped to the error boundary and logged
|
|
170
|
+
`Error in renderToReadableStream` (and, with no not-found component
|
|
171
|
+
configured, aborted the response) on every miss.
|
|
172
|
+
|
|
173
|
+
- Updated dependencies [[`22f78b4`](https://github.com/valbuild/val/commit/22f78b471fd18e542f518f72b75bd472d7c3dc52), [`c390397`](https://github.com/valbuild/val/commit/c390397cb5e203eb1bedae3a6fab15726e850b90)]:
|
|
174
|
+
- @valbuild/language-server@0.125.0
|
|
175
|
+
- @valbuild/core@0.125.0
|
|
176
|
+
- @valbuild/shared@0.125.0
|
|
177
|
+
- @valbuild/eslint-plugin@0.125.0
|
|
178
|
+
- @valbuild/server@0.125.0
|
|
179
|
+
|
|
3
180
|
## 0.124.0
|
|
4
181
|
|
|
5
182
|
### Patch Changes
|
|
@@ -975,30 +975,33 @@ function isFileRef(value) {
|
|
|
975
975
|
return !!value && typeof value === "object" && "path" in value && typeof value.path === "string";
|
|
976
976
|
}
|
|
977
977
|
|
|
978
|
+
/**
|
|
979
|
+
* The versions of the Val packages this project has installed.
|
|
980
|
+
*
|
|
981
|
+
* Each is resolved from the project rather than declared, because the CLI is a
|
|
982
|
+
* dependency of the project and not the other way round — and a project has
|
|
983
|
+
* exactly one framework package, so the one that is absent is absent rather
|
|
984
|
+
* than broken. `undefined` is the honest answer for it.
|
|
985
|
+
*/
|
|
978
986
|
const getVersions = () => {
|
|
979
|
-
const coreVersion = (
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
983
|
-
return (_require = require("@valbuild/core")) === null || _require === void 0 || (_require = _require.Internal) === null || _require === void 0 || (_require = _require.VERSION) === null || _require === void 0 ? void 0 : _require.core;
|
|
984
|
-
} catch {
|
|
985
|
-
return null;
|
|
986
|
-
}
|
|
987
|
-
})();
|
|
988
|
-
const nextVersion = (() => {
|
|
989
|
-
try {
|
|
990
|
-
var _require2;
|
|
991
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
992
|
-
return (_require2 = require("@valbuild/next")) === null || _require2 === void 0 || (_require2 = _require2.Internal) === null || _require2 === void 0 || (_require2 = _require2.VERSION) === null || _require2 === void 0 ? void 0 : _require2.next;
|
|
993
|
-
} catch {
|
|
994
|
-
return null;
|
|
995
|
-
}
|
|
996
|
-
})();
|
|
987
|
+
const coreVersion = requireVersion("@valbuild/core", "core");
|
|
988
|
+
const nextVersion = requireVersion("@valbuild/next", "next");
|
|
989
|
+
const tanstackVersion = requireVersion("@valbuild/tanstack", "tanstack");
|
|
997
990
|
return {
|
|
998
991
|
coreVersion: coreVersion || undefined,
|
|
999
|
-
nextVersion: nextVersion || undefined
|
|
992
|
+
nextVersion: nextVersion || undefined,
|
|
993
|
+
tanstackVersion: tanstackVersion || undefined
|
|
1000
994
|
};
|
|
1001
995
|
};
|
|
996
|
+
function requireVersion(packageName, key) {
|
|
997
|
+
try {
|
|
998
|
+
var _require;
|
|
999
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
1000
|
+
return ((_require = require(packageName)) === null || _require === void 0 || (_require = _require.Internal) === null || _require === void 0 || (_require = _require.VERSION) === null || _require === void 0 ? void 0 : _require[key]) ?? null;
|
|
1001
|
+
} catch {
|
|
1002
|
+
return null;
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1002
1005
|
|
|
1003
1006
|
const host = process.env.VAL_BUILD_URL || "https://admin.val.build";
|
|
1004
1007
|
async function connect(options) {
|
|
@@ -1365,10 +1368,7 @@ function collectSchemaReferences(schema) {
|
|
|
1365
1368
|
visit(item, false);
|
|
1366
1369
|
}
|
|
1367
1370
|
break;
|
|
1368
|
-
case "union":
|
|
1369
|
-
if (typeof node.key !== "string") {
|
|
1370
|
-
visit(node.key, false);
|
|
1371
|
-
}
|
|
1371
|
+
case "discriminated-union":
|
|
1372
1372
|
for (const item of node.items) {
|
|
1373
1373
|
visit(item, false);
|
|
1374
1374
|
}
|
|
@@ -1597,6 +1597,7 @@ async function buildSnapshot(ctx, options = {}) {
|
|
|
1597
1597
|
versions: {
|
|
1598
1598
|
core: getVersions().coreVersion,
|
|
1599
1599
|
next: getVersions().nextVersion,
|
|
1600
|
+
tanstack: getVersions().tanstackVersion,
|
|
1600
1601
|
project: readProjectValVersions(ctx.projectRoot),
|
|
1601
1602
|
node: process.version,
|
|
1602
1603
|
platform: `${process.platform}-${process.arch}`
|
|
@@ -1692,9 +1693,18 @@ function generateValModules(moduleFilePaths) {
|
|
|
1692
1693
|
const withoutExt = moduleFilePath.replace(/\.(ts|js|tsx|jsx)$/, "");
|
|
1693
1694
|
return ` { def: () => import(".${withoutExt}") },`;
|
|
1694
1695
|
}).join("\n");
|
|
1696
|
+
/*
|
|
1697
|
+
* The framework package the captured project actually has.
|
|
1698
|
+
*
|
|
1699
|
+
* A snapshot is replayed by loading this file, so naming the wrong one makes
|
|
1700
|
+
* it fail to resolve on a machine that has the other. `getVersions` answers
|
|
1701
|
+
* from what is installed; the fallback matters only for a project with
|
|
1702
|
+
* neither, which could not have produced a snapshot anyway.
|
|
1703
|
+
*/
|
|
1704
|
+
const frameworkPackage = getVersions().tanstackVersion ? "@valbuild/tanstack" : "@valbuild/next";
|
|
1695
1705
|
return `// GENERATED by \`val debug\`: trimmed to the modules this snapshot carries.
|
|
1696
1706
|
// The project's original is kept as val.modules.original.ts.
|
|
1697
|
-
import { modules } from "
|
|
1707
|
+
import { modules } from "${frameworkPackage}";
|
|
1698
1708
|
import { config } from "./val.config";
|
|
1699
1709
|
|
|
1700
1710
|
export default modules(config, [
|
|
@@ -1709,7 +1719,7 @@ Captured ${manifest.generatedAt} from project \`${manifest.project ?? "(fs mode)
|
|
|
1709
1719
|
branch \`${manifest.branch ?? "?"}\`, commit \`${manifest.commit ?? "?"}\`.
|
|
1710
1720
|
|
|
1711
1721
|
- @valbuild/core: \`${manifest.versions.core ?? "?"}\`
|
|
1712
|
-
-
|
|
1722
|
+
- ${manifest.versions.tanstack ? `@valbuild/tanstack: \`${manifest.versions.tanstack}\`` : `@valbuild/next: \`${manifest.versions.next ?? "?"}\``}
|
|
1713
1723
|
- ${manifest.patchCount} pending patches, ${manifest.unappliablePatchCount} of which could not be applied.
|
|
1714
1724
|
|
|
1715
1725
|
## Replaying it
|
|
@@ -2234,5 +2244,15 @@ void main().catch(err => {
|
|
|
2234
2244
|
async function versions() {
|
|
2235
2245
|
const foundVersions = getVersions();
|
|
2236
2246
|
console.log(`${chalk__default["default"].cyan("@valbuild/core")}: ${foundVersions.coreVersion}`);
|
|
2237
|
-
|
|
2247
|
+
// Only the framework package this project actually has. Printing the other
|
|
2248
|
+
// as `undefined` reads as something missing rather than something absent.
|
|
2249
|
+
if (foundVersions.nextVersion) {
|
|
2250
|
+
console.log(`${chalk__default["default"].cyan("@valbuild/next")}: ${foundVersions.nextVersion}`);
|
|
2251
|
+
}
|
|
2252
|
+
if (foundVersions.tanstackVersion) {
|
|
2253
|
+
console.log(`${chalk__default["default"].cyan("@valbuild/tanstack")}: ${foundVersions.tanstackVersion}`);
|
|
2254
|
+
}
|
|
2255
|
+
if (!foundVersions.nextVersion && !foundVersions.tanstackVersion) {
|
|
2256
|
+
console.log(`${chalk__default["default"].yellow("No framework package found")}: install @valbuild/next or @valbuild/tanstack`);
|
|
2257
|
+
}
|
|
2238
2258
|
}
|
|
@@ -975,30 +975,33 @@ function isFileRef(value) {
|
|
|
975
975
|
return !!value && typeof value === "object" && "path" in value && typeof value.path === "string";
|
|
976
976
|
}
|
|
977
977
|
|
|
978
|
+
/**
|
|
979
|
+
* The versions of the Val packages this project has installed.
|
|
980
|
+
*
|
|
981
|
+
* Each is resolved from the project rather than declared, because the CLI is a
|
|
982
|
+
* dependency of the project and not the other way round — and a project has
|
|
983
|
+
* exactly one framework package, so the one that is absent is absent rather
|
|
984
|
+
* than broken. `undefined` is the honest answer for it.
|
|
985
|
+
*/
|
|
978
986
|
const getVersions = () => {
|
|
979
|
-
const coreVersion = (
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
983
|
-
return (_require = require("@valbuild/core")) === null || _require === void 0 || (_require = _require.Internal) === null || _require === void 0 || (_require = _require.VERSION) === null || _require === void 0 ? void 0 : _require.core;
|
|
984
|
-
} catch {
|
|
985
|
-
return null;
|
|
986
|
-
}
|
|
987
|
-
})();
|
|
988
|
-
const nextVersion = (() => {
|
|
989
|
-
try {
|
|
990
|
-
var _require2;
|
|
991
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
992
|
-
return (_require2 = require("@valbuild/next")) === null || _require2 === void 0 || (_require2 = _require2.Internal) === null || _require2 === void 0 || (_require2 = _require2.VERSION) === null || _require2 === void 0 ? void 0 : _require2.next;
|
|
993
|
-
} catch {
|
|
994
|
-
return null;
|
|
995
|
-
}
|
|
996
|
-
})();
|
|
987
|
+
const coreVersion = requireVersion("@valbuild/core", "core");
|
|
988
|
+
const nextVersion = requireVersion("@valbuild/next", "next");
|
|
989
|
+
const tanstackVersion = requireVersion("@valbuild/tanstack", "tanstack");
|
|
997
990
|
return {
|
|
998
991
|
coreVersion: coreVersion || undefined,
|
|
999
|
-
nextVersion: nextVersion || undefined
|
|
992
|
+
nextVersion: nextVersion || undefined,
|
|
993
|
+
tanstackVersion: tanstackVersion || undefined
|
|
1000
994
|
};
|
|
1001
995
|
};
|
|
996
|
+
function requireVersion(packageName, key) {
|
|
997
|
+
try {
|
|
998
|
+
var _require;
|
|
999
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
1000
|
+
return ((_require = require(packageName)) === null || _require === void 0 || (_require = _require.Internal) === null || _require === void 0 || (_require = _require.VERSION) === null || _require === void 0 ? void 0 : _require[key]) ?? null;
|
|
1001
|
+
} catch {
|
|
1002
|
+
return null;
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1002
1005
|
|
|
1003
1006
|
const host = process.env.VAL_BUILD_URL || "https://admin.val.build";
|
|
1004
1007
|
async function connect(options) {
|
|
@@ -1365,10 +1368,7 @@ function collectSchemaReferences(schema) {
|
|
|
1365
1368
|
visit(item, false);
|
|
1366
1369
|
}
|
|
1367
1370
|
break;
|
|
1368
|
-
case "union":
|
|
1369
|
-
if (typeof node.key !== "string") {
|
|
1370
|
-
visit(node.key, false);
|
|
1371
|
-
}
|
|
1371
|
+
case "discriminated-union":
|
|
1372
1372
|
for (const item of node.items) {
|
|
1373
1373
|
visit(item, false);
|
|
1374
1374
|
}
|
|
@@ -1597,6 +1597,7 @@ async function buildSnapshot(ctx, options = {}) {
|
|
|
1597
1597
|
versions: {
|
|
1598
1598
|
core: getVersions().coreVersion,
|
|
1599
1599
|
next: getVersions().nextVersion,
|
|
1600
|
+
tanstack: getVersions().tanstackVersion,
|
|
1600
1601
|
project: readProjectValVersions(ctx.projectRoot),
|
|
1601
1602
|
node: process.version,
|
|
1602
1603
|
platform: `${process.platform}-${process.arch}`
|
|
@@ -1692,9 +1693,18 @@ function generateValModules(moduleFilePaths) {
|
|
|
1692
1693
|
const withoutExt = moduleFilePath.replace(/\.(ts|js|tsx|jsx)$/, "");
|
|
1693
1694
|
return ` { def: () => import(".${withoutExt}") },`;
|
|
1694
1695
|
}).join("\n");
|
|
1696
|
+
/*
|
|
1697
|
+
* The framework package the captured project actually has.
|
|
1698
|
+
*
|
|
1699
|
+
* A snapshot is replayed by loading this file, so naming the wrong one makes
|
|
1700
|
+
* it fail to resolve on a machine that has the other. `getVersions` answers
|
|
1701
|
+
* from what is installed; the fallback matters only for a project with
|
|
1702
|
+
* neither, which could not have produced a snapshot anyway.
|
|
1703
|
+
*/
|
|
1704
|
+
const frameworkPackage = getVersions().tanstackVersion ? "@valbuild/tanstack" : "@valbuild/next";
|
|
1695
1705
|
return `// GENERATED by \`val debug\`: trimmed to the modules this snapshot carries.
|
|
1696
1706
|
// The project's original is kept as val.modules.original.ts.
|
|
1697
|
-
import { modules } from "
|
|
1707
|
+
import { modules } from "${frameworkPackage}";
|
|
1698
1708
|
import { config } from "./val.config";
|
|
1699
1709
|
|
|
1700
1710
|
export default modules(config, [
|
|
@@ -1709,7 +1719,7 @@ Captured ${manifest.generatedAt} from project \`${manifest.project ?? "(fs mode)
|
|
|
1709
1719
|
branch \`${manifest.branch ?? "?"}\`, commit \`${manifest.commit ?? "?"}\`.
|
|
1710
1720
|
|
|
1711
1721
|
- @valbuild/core: \`${manifest.versions.core ?? "?"}\`
|
|
1712
|
-
-
|
|
1722
|
+
- ${manifest.versions.tanstack ? `@valbuild/tanstack: \`${manifest.versions.tanstack}\`` : `@valbuild/next: \`${manifest.versions.next ?? "?"}\``}
|
|
1713
1723
|
- ${manifest.patchCount} pending patches, ${manifest.unappliablePatchCount} of which could not be applied.
|
|
1714
1724
|
|
|
1715
1725
|
## Replaying it
|
|
@@ -2234,5 +2244,15 @@ void main().catch(err => {
|
|
|
2234
2244
|
async function versions() {
|
|
2235
2245
|
const foundVersions = getVersions();
|
|
2236
2246
|
console.log(`${chalk__default["default"].cyan("@valbuild/core")}: ${foundVersions.coreVersion}`);
|
|
2237
|
-
|
|
2247
|
+
// Only the framework package this project actually has. Printing the other
|
|
2248
|
+
// as `undefined` reads as something missing rather than something absent.
|
|
2249
|
+
if (foundVersions.nextVersion) {
|
|
2250
|
+
console.log(`${chalk__default["default"].cyan("@valbuild/next")}: ${foundVersions.nextVersion}`);
|
|
2251
|
+
}
|
|
2252
|
+
if (foundVersions.tanstackVersion) {
|
|
2253
|
+
console.log(`${chalk__default["default"].cyan("@valbuild/tanstack")}: ${foundVersions.tanstackVersion}`);
|
|
2254
|
+
}
|
|
2255
|
+
if (!foundVersions.nextVersion && !foundVersions.tanstackVersion) {
|
|
2256
|
+
console.log(`${chalk__default["default"].yellow("No framework package found")}: install @valbuild/next or @valbuild/tanstack`);
|
|
2257
|
+
}
|
|
2238
2258
|
}
|
|
@@ -943,30 +943,33 @@ function isFileRef(value) {
|
|
|
943
943
|
return !!value && typeof value === "object" && "path" in value && typeof value.path === "string";
|
|
944
944
|
}
|
|
945
945
|
|
|
946
|
+
/**
|
|
947
|
+
* The versions of the Val packages this project has installed.
|
|
948
|
+
*
|
|
949
|
+
* Each is resolved from the project rather than declared, because the CLI is a
|
|
950
|
+
* dependency of the project and not the other way round — and a project has
|
|
951
|
+
* exactly one framework package, so the one that is absent is absent rather
|
|
952
|
+
* than broken. `undefined` is the honest answer for it.
|
|
953
|
+
*/
|
|
946
954
|
const getVersions = () => {
|
|
947
|
-
const coreVersion = (
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
951
|
-
return (_require = require("@valbuild/core")) === null || _require === void 0 || (_require = _require.Internal) === null || _require === void 0 || (_require = _require.VERSION) === null || _require === void 0 ? void 0 : _require.core;
|
|
952
|
-
} catch {
|
|
953
|
-
return null;
|
|
954
|
-
}
|
|
955
|
-
})();
|
|
956
|
-
const nextVersion = (() => {
|
|
957
|
-
try {
|
|
958
|
-
var _require2;
|
|
959
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
960
|
-
return (_require2 = require("@valbuild/next")) === null || _require2 === void 0 || (_require2 = _require2.Internal) === null || _require2 === void 0 || (_require2 = _require2.VERSION) === null || _require2 === void 0 ? void 0 : _require2.next;
|
|
961
|
-
} catch {
|
|
962
|
-
return null;
|
|
963
|
-
}
|
|
964
|
-
})();
|
|
955
|
+
const coreVersion = requireVersion("@valbuild/core", "core");
|
|
956
|
+
const nextVersion = requireVersion("@valbuild/next", "next");
|
|
957
|
+
const tanstackVersion = requireVersion("@valbuild/tanstack", "tanstack");
|
|
965
958
|
return {
|
|
966
959
|
coreVersion: coreVersion || undefined,
|
|
967
|
-
nextVersion: nextVersion || undefined
|
|
960
|
+
nextVersion: nextVersion || undefined,
|
|
961
|
+
tanstackVersion: tanstackVersion || undefined
|
|
968
962
|
};
|
|
969
963
|
};
|
|
964
|
+
function requireVersion(packageName, key) {
|
|
965
|
+
try {
|
|
966
|
+
var _require;
|
|
967
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
968
|
+
return ((_require = require(packageName)) === null || _require === void 0 || (_require = _require.Internal) === null || _require === void 0 || (_require = _require.VERSION) === null || _require === void 0 ? void 0 : _require[key]) ?? null;
|
|
969
|
+
} catch {
|
|
970
|
+
return null;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
970
973
|
|
|
971
974
|
const host = process.env.VAL_BUILD_URL || "https://admin.val.build";
|
|
972
975
|
async function connect(options) {
|
|
@@ -1333,10 +1336,7 @@ function collectSchemaReferences(schema) {
|
|
|
1333
1336
|
visit(item, false);
|
|
1334
1337
|
}
|
|
1335
1338
|
break;
|
|
1336
|
-
case "union":
|
|
1337
|
-
if (typeof node.key !== "string") {
|
|
1338
|
-
visit(node.key, false);
|
|
1339
|
-
}
|
|
1339
|
+
case "discriminated-union":
|
|
1340
1340
|
for (const item of node.items) {
|
|
1341
1341
|
visit(item, false);
|
|
1342
1342
|
}
|
|
@@ -1565,6 +1565,7 @@ async function buildSnapshot(ctx, options = {}) {
|
|
|
1565
1565
|
versions: {
|
|
1566
1566
|
core: getVersions().coreVersion,
|
|
1567
1567
|
next: getVersions().nextVersion,
|
|
1568
|
+
tanstack: getVersions().tanstackVersion,
|
|
1568
1569
|
project: readProjectValVersions(ctx.projectRoot),
|
|
1569
1570
|
node: process.version,
|
|
1570
1571
|
platform: `${process.platform}-${process.arch}`
|
|
@@ -1660,9 +1661,18 @@ function generateValModules(moduleFilePaths) {
|
|
|
1660
1661
|
const withoutExt = moduleFilePath.replace(/\.(ts|js|tsx|jsx)$/, "");
|
|
1661
1662
|
return ` { def: () => import(".${withoutExt}") },`;
|
|
1662
1663
|
}).join("\n");
|
|
1664
|
+
/*
|
|
1665
|
+
* The framework package the captured project actually has.
|
|
1666
|
+
*
|
|
1667
|
+
* A snapshot is replayed by loading this file, so naming the wrong one makes
|
|
1668
|
+
* it fail to resolve on a machine that has the other. `getVersions` answers
|
|
1669
|
+
* from what is installed; the fallback matters only for a project with
|
|
1670
|
+
* neither, which could not have produced a snapshot anyway.
|
|
1671
|
+
*/
|
|
1672
|
+
const frameworkPackage = getVersions().tanstackVersion ? "@valbuild/tanstack" : "@valbuild/next";
|
|
1663
1673
|
return `// GENERATED by \`val debug\`: trimmed to the modules this snapshot carries.
|
|
1664
1674
|
// The project's original is kept as val.modules.original.ts.
|
|
1665
|
-
import { modules } from "
|
|
1675
|
+
import { modules } from "${frameworkPackage}";
|
|
1666
1676
|
import { config } from "./val.config";
|
|
1667
1677
|
|
|
1668
1678
|
export default modules(config, [
|
|
@@ -1677,7 +1687,7 @@ Captured ${manifest.generatedAt} from project \`${manifest.project ?? "(fs mode)
|
|
|
1677
1687
|
branch \`${manifest.branch ?? "?"}\`, commit \`${manifest.commit ?? "?"}\`.
|
|
1678
1688
|
|
|
1679
1689
|
- @valbuild/core: \`${manifest.versions.core ?? "?"}\`
|
|
1680
|
-
-
|
|
1690
|
+
- ${manifest.versions.tanstack ? `@valbuild/tanstack: \`${manifest.versions.tanstack}\`` : `@valbuild/next: \`${manifest.versions.next ?? "?"}\``}
|
|
1681
1691
|
- ${manifest.patchCount} pending patches, ${manifest.unappliablePatchCount} of which could not be applied.
|
|
1682
1692
|
|
|
1683
1693
|
## Replaying it
|
|
@@ -2202,5 +2212,15 @@ void main().catch(err => {
|
|
|
2202
2212
|
async function versions() {
|
|
2203
2213
|
const foundVersions = getVersions();
|
|
2204
2214
|
console.log(`${chalk.cyan("@valbuild/core")}: ${foundVersions.coreVersion}`);
|
|
2205
|
-
|
|
2215
|
+
// Only the framework package this project actually has. Printing the other
|
|
2216
|
+
// as `undefined` reads as something missing rather than something absent.
|
|
2217
|
+
if (foundVersions.nextVersion) {
|
|
2218
|
+
console.log(`${chalk.cyan("@valbuild/next")}: ${foundVersions.nextVersion}`);
|
|
2219
|
+
}
|
|
2220
|
+
if (foundVersions.tanstackVersion) {
|
|
2221
|
+
console.log(`${chalk.cyan("@valbuild/tanstack")}: ${foundVersions.tanstackVersion}`);
|
|
2222
|
+
}
|
|
2223
|
+
if (!foundVersions.nextVersion && !foundVersions.tanstackVersion) {
|
|
2224
|
+
console.log(`${chalk.yellow("No framework package found")}: install @valbuild/next or @valbuild/tanstack`);
|
|
2225
|
+
}
|
|
2206
2226
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@valbuild/cli",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.126.0",
|
|
5
5
|
"description": "Val CLI tools",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -24,11 +24,11 @@
|
|
|
24
24
|
"jszip": "^3.10.1",
|
|
25
25
|
"meow": "^9.0.0",
|
|
26
26
|
"picocolors": "^1.1.1",
|
|
27
|
-
"@valbuild/core": "0.
|
|
28
|
-
"@valbuild/eslint-plugin": "0.
|
|
29
|
-
"@valbuild/language-server": "0.
|
|
30
|
-
"@valbuild/server": "0.
|
|
31
|
-
"@valbuild/shared": "0.
|
|
27
|
+
"@valbuild/core": "0.126.0",
|
|
28
|
+
"@valbuild/eslint-plugin": "0.125.0",
|
|
29
|
+
"@valbuild/language-server": "0.126.0",
|
|
30
|
+
"@valbuild/server": "0.126.0",
|
|
31
|
+
"@valbuild/shared": "0.126.0"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"prettier": "*",
|
package/src/cli.ts
CHANGED
|
@@ -228,5 +228,21 @@ void main().catch((err) => {
|
|
|
228
228
|
async function versions() {
|
|
229
229
|
const foundVersions = getVersions();
|
|
230
230
|
console.log(`${chalk.cyan("@valbuild/core")}: ${foundVersions.coreVersion}`);
|
|
231
|
-
|
|
231
|
+
// Only the framework package this project actually has. Printing the other
|
|
232
|
+
// as `undefined` reads as something missing rather than something absent.
|
|
233
|
+
if (foundVersions.nextVersion) {
|
|
234
|
+
console.log(
|
|
235
|
+
`${chalk.cyan("@valbuild/next")}: ${foundVersions.nextVersion}`,
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
if (foundVersions.tanstackVersion) {
|
|
239
|
+
console.log(
|
|
240
|
+
`${chalk.cyan("@valbuild/tanstack")}: ${foundVersions.tanstackVersion}`,
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
if (!foundVersions.nextVersion && !foundVersions.tanstackVersion) {
|
|
244
|
+
console.log(
|
|
245
|
+
`${chalk.yellow("No framework package found")}: install @valbuild/next or @valbuild/tanstack`,
|
|
246
|
+
);
|
|
247
|
+
}
|
|
232
248
|
}
|
|
@@ -150,10 +150,7 @@ function collectSchemaReferences(schema: SerializedSchema): SchemaReferences {
|
|
|
150
150
|
visit(item, false);
|
|
151
151
|
}
|
|
152
152
|
break;
|
|
153
|
-
case "union":
|
|
154
|
-
if (typeof node.key !== "string") {
|
|
155
|
-
visit(node.key, false);
|
|
156
|
-
}
|
|
153
|
+
case "discriminated-union":
|
|
157
154
|
for (const item of node.items) {
|
|
158
155
|
visit(item, false);
|
|
159
156
|
}
|
package/src/debug/snapshot.ts
CHANGED
|
@@ -39,6 +39,7 @@ export type SnapshotManifest = {
|
|
|
39
39
|
/** Resolved at runtime by the cli that captured this. */
|
|
40
40
|
core?: string;
|
|
41
41
|
next?: string;
|
|
42
|
+
tanstack?: string;
|
|
42
43
|
/**
|
|
43
44
|
* The @valbuild/* versions the project declares. This is what to check out
|
|
44
45
|
* in the val repo in order to replay on the code the customer was running.
|
|
@@ -253,6 +254,7 @@ export async function buildSnapshot(
|
|
|
253
254
|
versions: {
|
|
254
255
|
core: getVersions().coreVersion,
|
|
255
256
|
next: getVersions().nextVersion,
|
|
257
|
+
tanstack: getVersions().tanstackVersion,
|
|
256
258
|
project: readProjectValVersions(ctx.projectRoot),
|
|
257
259
|
node: process.version,
|
|
258
260
|
platform: `${process.platform}-${process.arch}`,
|
|
@@ -380,9 +382,20 @@ function generateValModules(moduleFilePaths: string[]): string {
|
|
|
380
382
|
return ` { def: () => import(".${withoutExt}") },`;
|
|
381
383
|
})
|
|
382
384
|
.join("\n");
|
|
385
|
+
/*
|
|
386
|
+
* The framework package the captured project actually has.
|
|
387
|
+
*
|
|
388
|
+
* A snapshot is replayed by loading this file, so naming the wrong one makes
|
|
389
|
+
* it fail to resolve on a machine that has the other. `getVersions` answers
|
|
390
|
+
* from what is installed; the fallback matters only for a project with
|
|
391
|
+
* neither, which could not have produced a snapshot anyway.
|
|
392
|
+
*/
|
|
393
|
+
const frameworkPackage = getVersions().tanstackVersion
|
|
394
|
+
? "@valbuild/tanstack"
|
|
395
|
+
: "@valbuild/next";
|
|
383
396
|
return `// GENERATED by \`val debug\`: trimmed to the modules this snapshot carries.
|
|
384
397
|
// The project's original is kept as val.modules.original.ts.
|
|
385
|
-
import { modules } from "
|
|
398
|
+
import { modules } from "${frameworkPackage}";
|
|
386
399
|
import { config } from "./val.config";
|
|
387
400
|
|
|
388
401
|
export default modules(config, [
|
|
@@ -398,7 +411,11 @@ Captured ${manifest.generatedAt} from project \`${manifest.project ?? "(fs mode)
|
|
|
398
411
|
branch \`${manifest.branch ?? "?"}\`, commit \`${manifest.commit ?? "?"}\`.
|
|
399
412
|
|
|
400
413
|
- @valbuild/core: \`${manifest.versions.core ?? "?"}\`
|
|
401
|
-
-
|
|
414
|
+
- ${
|
|
415
|
+
manifest.versions.tanstack
|
|
416
|
+
? `@valbuild/tanstack: \`${manifest.versions.tanstack}\``
|
|
417
|
+
: `@valbuild/next: \`${manifest.versions.next ?? "?"}\``
|
|
418
|
+
}
|
|
402
419
|
- ${manifest.patchCount} pending patches, ${manifest.unappliablePatchCount} of which could not be applied.
|
|
403
420
|
|
|
404
421
|
## Replaying it
|
package/src/getVersions.ts
CHANGED
|
@@ -1,25 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The versions of the Val packages this project has installed.
|
|
3
|
+
*
|
|
4
|
+
* Each is resolved from the project rather than declared, because the CLI is a
|
|
5
|
+
* dependency of the project and not the other way round — and a project has
|
|
6
|
+
* exactly one framework package, so the one that is absent is absent rather
|
|
7
|
+
* than broken. `undefined` is the honest answer for it.
|
|
8
|
+
*/
|
|
1
9
|
export const getVersions = (): {
|
|
2
10
|
coreVersion?: string;
|
|
3
11
|
nextVersion?: string;
|
|
12
|
+
tanstackVersion?: string;
|
|
4
13
|
} => {
|
|
5
|
-
const coreVersion = (
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
return require("@valbuild/core")?.Internal?.VERSION?.core;
|
|
9
|
-
} catch {
|
|
10
|
-
return null;
|
|
11
|
-
}
|
|
12
|
-
})();
|
|
13
|
-
const nextVersion = (() => {
|
|
14
|
-
try {
|
|
15
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
16
|
-
return require("@valbuild/next")?.Internal?.VERSION?.next;
|
|
17
|
-
} catch {
|
|
18
|
-
return null;
|
|
19
|
-
}
|
|
20
|
-
})();
|
|
14
|
+
const coreVersion = requireVersion("@valbuild/core", "core");
|
|
15
|
+
const nextVersion = requireVersion("@valbuild/next", "next");
|
|
16
|
+
const tanstackVersion = requireVersion("@valbuild/tanstack", "tanstack");
|
|
21
17
|
return {
|
|
22
18
|
coreVersion: coreVersion || undefined,
|
|
23
19
|
nextVersion: nextVersion || undefined,
|
|
20
|
+
tanstackVersion: tanstackVersion || undefined,
|
|
24
21
|
};
|
|
25
22
|
};
|
|
23
|
+
|
|
24
|
+
function requireVersion(packageName: string, key: string): string | null {
|
|
25
|
+
try {
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
27
|
+
return require(packageName)?.Internal?.VERSION?.[key] ?? null;
|
|
28
|
+
} catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|