Fix remote files upload issues - #450
Conversation
…and more practical validation errors
…key (looks nice IMO)
🦋 Changeset detectedLatest commit: 21c430e The changes in this PR will be included in the next version bump. This PR includes changesets to release 6 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
Pull request overview
This PR broadens file handling to support storing and validating files anywhere under /public (instead of only /public/val), and refactors server-side Val module loading away from QuickJS toward a Node vm-based loader. It also improves CLI validation UX (grouped diagnostics + code frames) and adds a watch mode for continuous validation.
Changes:
- Expand path/ref handling from
/public/val/...to/public/...across core remote refs, schema options, server/CLI validation, and UI utilities. - Replace the server’s QuickJS-based module evaluation with a
vm-based loader (loadValModules) andextractValModules, and expose new module-path → source-range helpers. - Enhance CLI validation output with clickable
file:line:col+ code frames, add--watch, and improve handling of unregistered modules and key-vs-value diagnostics.
Reviewed changes
Copilot reviewed 51 out of 54 changed files in this pull request and generated 12 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Dependency lock updates (incl. chokidar) and metadata changes. |
| packages/ui/spa/utils/getFilenameFromRef.ts | Updates folder/filename parsing to align with /public/... refs. |
| packages/ui/spa/search/search.worker.ts | Adjusts file/image indexing label extraction for /public/... paths. |
| packages/ui/spa/components/fields/RichTextField.tsx | Removes config-based directory fallback; relies on schema/module directory defaults. |
| packages/ui/spa/components/fields/ModuleGallery.tsx | Updates remote filePath typing/format to support public/... not only public/val/.... |
| packages/ui/spa/components/fields/ImageField.tsx | Removes config-based directory fallback; relies on schema/module directory defaults. |
| packages/ui/spa/components/fields/FileField.tsx | Updates remote ref filePath typing/format to support public/.... |
| packages/shared/src/internal/SharedValConfig.ts | Removes shared files config; documents per-schema directories as source of truth. |
| packages/shared/src/internal/richtext/conversion/remirrorToRichTextSource.ts | Updates remote filePath typing/format to public/.... |
| packages/server/src/ValQuickJSRuntime.ts | Removed (QuickJS runtime no longer used). |
| packages/server/src/readValFile.ts | Removed (QuickJS-based module reading no longer used). |
| packages/server/src/readValFile.test.ts | Removed (tests for QuickJS reader removed). |
| packages/server/src/patchValFile.ts | Removes unused QuickJS runtime parameter. |
| packages/server/src/Service.ts | Refactors service to load modules via loadValModules + extractValModules; adds module path listing. |
| packages/server/src/loadValModules.ts | New vm-based recursive CommonJS loader for val.modules.* and related imports. |
| packages/server/src/modulePathMap.ts | New module-path → source-range mapping utility for better diagnostics locations. |
| packages/server/src/modulePathMap.test.ts | Adds unit tests for modulePathMap and key/value range targeting. |
| packages/server/src/index.ts | Exports modulePathMap utilities/types from @valbuild/server. |
| packages/server/src/createFixPatch.ts | Improves gallery fix errors to point at per-entry sourcePath and mark key errors. |
| packages/server/src/checkRemoteRef.ts | Updates remote ref validation rules to public/... paths. |
| packages/server/package.json | Removes quickjs-emscripten dependency; retains other deps. |
| packages/react/src/stega/index.ts | Updates comment to reference new stub loader. |
| packages/react/src/internal/index.ts | Updates comment to reference new stub loader. |
| packages/core/src/source/remote.ts | Broadens RemoteRef/filePath template types to public/.... |
| packages/core/src/remote/splitRemoteRef.ts | Updates remote ref parsing/typing to accept public/.... |
| packages/core/src/initVal.ts | Broadens ConfigDirectory to /public and /public/.... |
| packages/core/src/schema/images.ts | Makes images options optional; defaults accept to image/* and keeps directory defaulting. |
| packages/core/src/schema/record.ts | Marks gallery media validation errors as key errors for better UX. |
| packages/core/src/selector/file.ts | Fixes conditional type grouping/precedence. |
| packages/cli/src/cli.ts | Adds validate --watch flag and disallows --watch with --fix. |
| packages/cli/src/validate.ts | Reworks validation output into grouped reports + code frames; adds watch mode via chokidar. |
| packages/cli/src/utils/sourcePathToFileLocation.ts | New sourcePath → file/line/col + code frame utilities using modulePathMap. |
| packages/cli/src/utils/evalValConfigFile.ts | Broadens config validation for files.directory to /public or /public/.... |
| packages/cli/src/runValidation.ts | Adds keyError plumbing, validates only modules registered in val.modules, and broadens public path constraints. |
| packages/cli/src/listUnusedFiles.ts | Uses configured files.directory and skips non-registered modules when scanning usage. |
| packages/cli/src/fixtures/basic/val.modules.ts | Adds a fixture val.modules.ts for basic CLI scenarios. |
| packages/cli/src/fixtures/basic/val.config.ts | Exposes config from initVal fixture to support modules registry. |
| packages/cli/package.json | Adds chokidar dependency for --watch. |
| examples/next/content/media.val.ts | Updates example image metadata values. |
| examples/next/app/page.val.ts | Updates example image ref path to /public/val/images/logo.png. |
| examples/next/app/blogs/[blog]/page.val.ts | Relax schema constraint in example (maxLength removed). |
| .changeset/validation-error-code-frames.md | Documents new CLI validation frames and server exports. |
| .changeset/public-dir-not-only-public-val.md | Documents /public/... support and SharedValConfig change. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
| const filename = source[FILE_REF_PROP] as string; | ||
| // Extract just the filename from the path | ||
| const filenameOnly = filename.replace("/public/val/", ""); | ||
| const filenameOnly = filename.replace("/public", ""); | ||
| const metadata = source?.metadata; |
There was a problem hiding this comment.
Yes, the filename should not be a path it should be just the file. Soon we will show folder in the UI so it is clear where filename is
| ), | ||
| fileHash: remoteFileHash, | ||
| filePath: `${(directory ?? "/public/val").slice(1) as `public/val/${string}`}/${newFilePath}`, | ||
| filePath: `${(directory ?? "/public/val").slice(1) as `public/${string}`}/${newFilePath}`, |
| validationHash, | ||
| fileHash: remoteFileHash, | ||
| filePath: `${directory.slice(1) as `public/val/${string}`}/${newFilename}`, | ||
| filePath: `${directory.slice(1) as `public/${string}`}/${newFilename}`, |
| resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} | ||
| engines: {node: '>=10'} | ||
| deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me | ||
| deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exhorbitant rates) by contacting i@izs.me |
| const cleanPath = cleanRefPath(ref); | ||
| const filename = cleanPath.split("/").pop() || cleanPath; | ||
| const folder = | ||
| cleanPath.replace("/public/val", "").replace(/\/[^/]+$/, "") || "/"; | ||
| cleanPath.replace("/public", "").replace(/\/[^/]+$/, "") || "/"; | ||
| return { cleanPath, filename, folder }; |
| const compilerOptions = getCompilerOptions(projectRoot, host); | ||
| const sourceFileHandler = new ValSourceFileHandler( | ||
| projectRoot, | ||
| compilerOptions, | ||
| host, | ||
| ); | ||
| const module = await newQuickJSWASMModule(); | ||
| const runtime = await newValQuickJSRuntime( | ||
| module, | ||
| loader || | ||
| new ValModuleLoader( | ||
| projectRoot, | ||
| compilerOptions, | ||
| sourceFileHandler, | ||
| host, | ||
| opts.disableCache === undefined | ||
| ? process.env.NODE_ENV === "development" | ||
| ? false | ||
| : true | ||
| : opts.disableCache, | ||
| ), | ||
| ); | ||
| return new Service(projectRoot, sourceFileHandler, runtime); | ||
| const valModules = loadValModules(projectRoot); | ||
| const extracted = await extractValModules(valModules); |
There was a problem hiding this comment.
Yes fix so we use host
| console.log(getModulePathRange('"text"', modulePathMap)); | ||
| assert.deepStrictEqual(getModulePathRange('"text"', modulePathMap), { | ||
| end: { character: 6, line: 48 }, | ||
| start: { character: 2, line: 48 }, | ||
| }); |
| console.log(getModulePathRange('"nested"."text"', modulePathMap)); | ||
| assert.deepStrictEqual( | ||
| getModulePathRange('"nested"."text"', modulePathMap), | ||
| { end: { character: 8, line: 50 }, start: { character: 4, line: 50 } }, | ||
| ); |
| const modulePathMap = createModulePathMap(sourceFile); | ||
| assert(!!modulePathMap, "modulePathMap is undefined"); | ||
|
|
||
| console.log(modulePathMap); |
No description provided.