mirror of
https://github.com/webstudio-is/webstudio.git
synced 2026-10-28 07:37:36 +09:00
## Outcome Restore the Marketplace section for projects without existing marketplace metadata, make the complete review-submission workflow available over MCP, clarify shared Assets database diagnostics, and reduce published database size by materializing fully static Assets queries. ## Implementation ### Marketplace and MCP - Initialize the Marketplace form from a safe partial default instead of rendering nothing when metadata is unconfigured. - Keep review submission disabled until the complete metadata schema is valid. - Allow `get-marketplace-product` to return `null` and `update-marketplace-product` to create the first marketplace product through ProjectSession/MCP. - Add a confirmed `submit-marketplace-product` server operation that validates configured metadata before setting review status to `PENDING`. - Document the MCP workflow: upload the thumbnail, update metadata, publish production, then submit. - Correct the Marketplace thumbnail upload example to use the current MCP input field. ### Assets database - Show query size and merged published-database size separately in resource diagnostics. - Clarify that only the merged database counts toward the publish limit. - Allow the Assets query editor to scroll long query source. - Materialize fully static metadata-only Assets queries at publish time. - Store materialized results as compact field columns and rows keyed by a deterministic normalized-query hash. - Serve materialized rows through the existing Assets response contract without candidate documents or a runtime field catalog. - Keep route- or variable-dependent queries on the existing document-backed runtime path. - Exclude overview-only fields from dynamic detail documents so the merged database does not duplicate them. - Preserve byte-limit selection, truncation diagnostics, integrity verification, caching, and backward compatibility with existing artifacts. ### Release - Keep the release lockfile stable when preparing the CLI package. - Regenerate runtime contracts, server-only API metadata, and CLI documentation where required. ## Todo - [x] Restore the empty Marketplace settings state - [x] Prevent empty review submissions - [x] Support first-time Marketplace metadata creation over MCP - [x] Add MCP review submission - [x] Document the end-to-end MCP workflow - [x] Correct query and merged-database diagnostics - [x] Make long Assets query source scrollable - [x] Materialize static overview queries - [x] Preserve dynamic detail-query behavior - [x] Add regression coverage with fail/pass proof - [x] Run relevant package and integration checks ## Verification - [x] Content engine tests: 158 passed - [x] Asset uploader tests: 179 passed - [x] SDK tests: 505 passed - [x] CLI tests: 921 passed - [x] CLI prebuild integration tests: 46 passed - [x] Builder Assets resource and diagnostics tests: 14 passed - [x] Project runtime and ProjectSession tests: 133 passed - [x] Builder API router tests: 30 passed - [x] Protocol operation tests: 18 passed - [x] Content engine build and declaration generation - [x] Content engine, asset uploader, SDK, Builder, and CLI typechecks - [x] Repository lint and formatting checks - [x] Generated API and documentation checks - [x] New materialization tests demonstrated failing with the implementation disabled and passing after restoration ## Notes - The representative five-post overview fixture shrinks from 2,122 bytes to 1,197 bytes while returning the same sorted and paginated result. - Materialization is intentionally limited to static, metadata-only field queries without runtime asset fields. Unsupported or data-incompatible queries safely use the existing runtime database. - The complete `pnpm evaluations` agent suite was not run because repository policy requires separate explicit approval. - No database schema or migration changes are required.
72 lines
2.0 KiB
TypeScript
72 lines
2.0 KiB
TypeScript
import { access, readdir, readFile } from "node:fs/promises";
|
|
import { join, relative } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { expect, test } from "vitest";
|
|
|
|
const workspaceRoot = fileURLToPath(new URL("../../..", import.meta.url));
|
|
const releaseVersionPlaceholder = "0.0.0-webstudio-version";
|
|
const dependencyGroups = [
|
|
"dependencies",
|
|
"devDependencies",
|
|
"optionalDependencies",
|
|
"peerDependencies",
|
|
] as const;
|
|
|
|
const listPackageFiles = async (parent: string) => {
|
|
const directories = await readdir(join(workspaceRoot, parent), {
|
|
withFileTypes: true,
|
|
});
|
|
const candidates = directories
|
|
.filter((entry) => entry.isDirectory())
|
|
.map((entry) => join(workspaceRoot, parent, entry.name, "package.json"));
|
|
return (
|
|
await Promise.all(
|
|
candidates.map(async (path) => {
|
|
try {
|
|
await access(path);
|
|
return path;
|
|
} catch {
|
|
return;
|
|
}
|
|
})
|
|
)
|
|
).filter((path) => path !== undefined);
|
|
};
|
|
|
|
test("keeps release placeholders out of workspace dependency protocols", async () => {
|
|
const packageFiles = (
|
|
await Promise.all(
|
|
["apps", "packages", "fixtures", "packages/cli/templates"].map(
|
|
listPackageFiles
|
|
)
|
|
)
|
|
).flat();
|
|
const invalidDependencies: string[] = [];
|
|
|
|
for (const packageFile of packageFiles) {
|
|
const manifest = JSON.parse(await readFile(packageFile, "utf8")) as Record<
|
|
string,
|
|
unknown
|
|
>;
|
|
for (const group of dependencyGroups) {
|
|
const dependencies = manifest[group];
|
|
if (typeof dependencies !== "object" || dependencies === null) {
|
|
continue;
|
|
}
|
|
for (const [name, specifier] of Object.entries(dependencies)) {
|
|
if (
|
|
typeof specifier === "string" &&
|
|
specifier.startsWith("workspace:") &&
|
|
specifier.includes(releaseVersionPlaceholder)
|
|
) {
|
|
invalidDependencies.push(
|
|
`${relative(workspaceRoot, packageFile)}: ${name}=${specifier}`
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
expect(invalidDependencies).toEqual([]);
|
|
});
|