diff --git a/CHANGELOG.md b/CHANGELOG.md index ce05e63..62aabb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Preview a single-file data app locally with `altertable app dev --file index.tsx`. The file's `defineDataApp` scope must match the selected profile, and queries run through the CLI's loopback proxy. + ### Fixed - Complete stdin-based credential configuration before exiting on Windows. @@ -24,6 +28,8 @@ If credentials were saved inside a project, sign in again after upgrading and re ### Changed +- Use the published 0.72.0 manifest extractor and Bun preview server for single-file data app development; align starter and browser-test packages at 0.72.0. + - Generate data apps with the split core, React, and Bun packages at 0.71.0; keep declared data-app packages aligned during upgrades. - Update generated data apps and fixtures to `@altertable/data-app` 0.69.0. diff --git a/COMMANDS.md b/COMMANDS.md index 89f01b2..a3d47ee 100644 --- a/COMMANDS.md +++ b/COMMANDS.md @@ -423,7 +423,7 @@ altertable app create|dev|build|lint|upgrade|validate|publish|update **Subcommands** - `create` — Create a local data app project with a live connection check. -- `dev` — Preview a data app locally with lakehouse access. +- `dev` — Preview a local data app directory, or a single-file data app, with lakehouse access. - `build` — Typecheck and build a local data app without Altertable credentials. - `lint` — Lint a local data app project: format, lint rules, types, contracts, build, and client credential boundary. - `upgrade` — Update a local data app's package to the CLI's tested version. @@ -436,6 +436,7 @@ altertable app create|dev|build|lint|upgrade|validate|publish|update ```bash altertable app create my-app altertable app dev +altertable app dev --file index.tsx altertable app lint altertable app build altertable app upgrade @@ -477,7 +478,7 @@ altertable --profile production app create product-pulse #### `altertable app dev` -Preview a data app locally with lakehouse access. +Preview a local data app directory, or a single-file data app, with lakehouse access. **Usage** @@ -490,7 +491,8 @@ altertable app dev [options] | Option | Description | | --- | --- | | `--dir ` | App directory (default: current directory). | -| `--port ` | Local dev server port (1–65535; default: app setting). | +| `--file ` | Path to a single-file React data app (index.tsx) to preview instead of --dir. Queries are declared in the file via defineDataApp. | +| `--port ` | Local dev server port (1–65535; default: app setting, or 25837 for --file). | **Examples** @@ -498,6 +500,7 @@ altertable app dev [options] altertable app dev altertable app dev --port 3022 altertable --profile staging app dev --dir ./my-app +altertable app dev --file ./index.tsx ``` #### `altertable app build` diff --git a/cli-reference.json b/cli-reference.json index a5a47f3..20d685b 100644 --- a/cli-reference.json +++ b/cli-reference.json @@ -823,6 +823,7 @@ "examples": [ "altertable app create my-app", "altertable app dev", + "altertable app dev --file index.tsx", "altertable app lint", "altertable app build", "altertable app upgrade", @@ -884,7 +885,7 @@ { "id": "altertable-app-dev", "command": "altertable app dev", - "description": "Preview a data app locally with lakehouse access.", + "description": "Preview a local data app directory, or a single-file data app, with lakehouse access.", "usage": [ "altertable app dev [options]" ], @@ -901,11 +902,21 @@ "scope": "command", "values": [] }, + { + "name": "file", + "aliases": [], + "type": "string", + "description": "Path to a single-file React data app (index.tsx) to preview instead of --dir. Queries are declared in the file via defineDataApp.", + "required": false, + "repeatable": false, + "scope": "command", + "values": [] + }, { "name": "port", "aliases": [], "type": "string", - "description": "Local dev server port (1–65535; default: app setting).", + "description": "Local dev server port (1–65535; default: app setting, or 25837 for --file).", "required": false, "repeatable": false, "scope": "command", @@ -915,7 +926,8 @@ "examples": [ "altertable app dev", "altertable app dev --port 3022", - "altertable --profile staging app dev --dir ./my-app" + "altertable --profile staging app dev --dir ./my-app", + "altertable app dev --file ./index.tsx" ], "subcommands": [] }, diff --git a/cli/bun.lock b/cli/bun.lock index f8bd11d..7a112f1 100644 --- a/cli/bun.lock +++ b/cli/bun.lock @@ -5,6 +5,7 @@ "": { "name": "cli", "dependencies": { + "@altertable/data-app-manifest": "0.72.0", "@clack/prompts": "1.7.0", "oauth4webapi": "3.8.7", "yaml": "2.9.0", @@ -22,6 +23,8 @@ }, }, "packages": { + "@altertable/data-app-manifest": ["@altertable/data-app-manifest@0.72.0", "", { "dependencies": { "typescript": "5.9.3" } }, "sha512-404JXukgR2zGt52NbgDohuvtlx2kt8v54Yb8EWs2b2RjDKmOwQ2gnQJBQzAIUtsFu1Gup6awv4gc9qj7eazvPA=="], + "@babel/code-frame": ["@babel/code-frame@7.29.7", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw=="], "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="], @@ -332,6 +335,8 @@ "zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="], + "@altertable/data-app-manifest/typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + "tinyglobby/picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="], } } diff --git a/cli/package.json b/cli/package.json index 934fbd8..6cf5bd0 100644 --- a/cli/package.json +++ b/cli/package.json @@ -48,6 +48,7 @@ "data-app:test:browser": "cd ../data-app/tests && bun run test" }, "dependencies": { + "@altertable/data-app-manifest": "0.72.0", "@clack/prompts": "1.7.0", "oauth4webapi": "3.8.7", "yaml": "2.9.0" diff --git a/cli/scripts/smoke-data-app.ts b/cli/scripts/smoke-data-app.ts index aa67c2e..80553e2 100644 --- a/cli/scripts/smoke-data-app.ts +++ b/cli/scripts/smoke-data-app.ts @@ -114,7 +114,7 @@ export async function smokeDataApp(command: string[], scaffoldOnly = false): Pro "@altertable/data-app-react", "@altertable/data-app-bun", ]) { - if (manifest.dependencies?.[name] !== "0.71.0") + if (manifest.dependencies?.[name] !== "0.72.0") throw new Error(`Packaged starter must pin ${name} to the tested release`); } for (const name of ["@altertable/data-app-embed", "@altertable/data-app-worker"]) { diff --git a/cli/src/commands/app/dev.ts b/cli/src/commands/app/dev.ts index c21d000..b6f4bab 100644 --- a/cli/src/commands/app/dev.ts +++ b/cli/src/commands/app/dev.ts @@ -1,3 +1,5 @@ +import { resolve } from "node:path"; +import { prepareFilePreview } from "@/commands/app/lib/file-dev.ts"; import { checkAppScope } from "@/commands/app/lib/scope.ts"; import { defineCommand } from "@/lib/command.ts"; import { CliError, EXIT_GENERIC } from "@/lib/errors.ts"; @@ -12,29 +14,44 @@ import { export const appDevCommand = defineCommand({ metadata: { name: "dev", - description: "Preview a data app locally with lakehouse access.", + description: + "Preview a local data app directory, or a single-file data app, with lakehouse access.", examples: [ "altertable app dev", "altertable app dev --port 3022", "altertable --profile staging app dev --dir ./my-app", + "altertable app dev --file ./index.tsx", ], }, args: { dir: { type: "string", description: "App directory (default: current directory)." }, - port: { type: "string", description: "Local dev server port (1–65535; default: app setting)." }, + file: { + type: "string", + description: + "Path to a single-file React data app (index.tsx) to preview instead of --dir. Queries are declared in the file via defineDataApp.", + completion: "file", + }, + port: { + type: "string", + description: "Local dev server port (1–65535; default: app setting, or 25837 for --file).", + }, }, async run({ args, execution, runtime }) { assertAppOutputMode(runtime.context.json, runtime.context.agent); - const port = appPort(args.port); - const directory = appDirectory(args.dir); + const file = args.file === undefined ? undefined : appFile(args.file, args.dir); + const port = appPort(args.port) ?? (file ? "25837" : undefined); + const directory = file + ? await prepareFilePreview(file, execution.profile) + : appDirectory(args.dir); requireAppScripts(directory, ["dev"]); - await checkAppScope(directory, execution.profile); - const installExitCode = await runAppCommand("install", directory); + if (!file) await checkAppScope(directory, execution.profile); + const installExitCode = await runAppCommand(file ? "install-frozen" : "install", directory); if (installExitCode !== 0) return { exitCode: EXIT_GENERIC }; const proxy = startAppDevProxy(execution); try { const environment = { ...proxy.environment, + ...(file ? { ALTERTABLE_APP_FILE: file } : {}), ...(port ? { PORT: port } : {}), }; const exitCode = await runAppCommand("dev", directory, environment); @@ -45,6 +62,14 @@ export const appDevCommand = defineCommand({ }, }); +function appFile(file: unknown, dir: unknown): string { + if (dir !== undefined) throw new CliError("Pass either --dir or --file."); + if (typeof file !== "string" || file.length === 0) { + throw new CliError("--file requires a file path."); + } + return resolve(file); +} + function appPort(value: unknown): string | undefined { if (value === undefined) return undefined; if (typeof value !== "string" || !/^[1-9]\d{0,4}$/.test(value) || Number(value) > 65535) { diff --git a/cli/src/commands/app/index.test.ts b/cli/src/commands/app/index.test.ts index 9b24241..b56ece3 100644 --- a/cli/src/commands/app/index.test.ts +++ b/cli/src/commands/app/index.test.ts @@ -179,4 +179,28 @@ describe("app commands", () => { expect(build.exitCode).toBe(1); expect(existsSync(join(directory, "build.json"))).toBe(false); }); + + test("dev validates a single file before preparing its preview", async () => { + const file = workspace.writeFile( + "index.tsx", + `import { defineDataApp } from "@altertable/data-app"; +defineDataApp({ scope: { organization: "acme", environment: "staging" } });`, + ); + async function failure(args: string[]): Promise { + return runAppCommand(["app", "dev", ...args]).catch((error: unknown) => error); + } + function message(text: string) { + return { message: expect.stringContaining(text) }; + } + + expect(await failure(["--file", file])).toMatchObject(message("data app file scope")); + expect(await failure(["--dir", directory, "--file", file])).toMatchObject( + message("either --dir or --file"), + ); + expect(await failure(["--file", ""])).toMatchObject(message("--file requires a file path")); + expect(await failure(["--file", join(directory, "missing.tsx")])).toMatchObject( + message("Could not read source"), + ); + expect(await failure(["--file", directory])).toMatchObject(message("Could not read source")); + }); }); diff --git a/cli/src/commands/app/index.ts b/cli/src/commands/app/index.ts index e68e29d..7f43ecd 100644 --- a/cli/src/commands/app/index.ts +++ b/cli/src/commands/app/index.ts @@ -17,6 +17,7 @@ export const appCommand = defineCommand({ examples: [ "altertable app create my-app", "altertable app dev", + "altertable app dev --file index.tsx", "altertable app lint", "altertable app build", "altertable app upgrade", diff --git a/cli/src/commands/app/lib/distribution.test.ts b/cli/src/commands/app/lib/distribution.test.ts index 4985af4..07c5fc1 100644 --- a/cli/src/commands/app/lib/distribution.test.ts +++ b/cli/src/commands/app/lib/distribution.test.ts @@ -40,9 +40,9 @@ test("distribution embeds a deterministic starter with an exact package pin and recommendedDataAppVersion(), ); expect(JSON.parse(files["package.json"]!).dependencies).toMatchObject({ - "@altertable/data-app": "0.71.0", - "@altertable/data-app-react": "0.71.0", - "@altertable/data-app-bun": "0.71.0", + "@altertable/data-app": "0.72.0", + "@altertable/data-app-react": "0.72.0", + "@altertable/data-app-bun": "0.72.0", }); expect(files["src/main.tsx"]).toContain('from "@altertable/data-app-react"'); expect(files["src/preview.ts"]).toContain('from "@altertable/data-app-bun/preview"'); diff --git a/cli/src/commands/app/lib/file-dev-server.ts.txt b/cli/src/commands/app/lib/file-dev-server.ts.txt new file mode 100644 index 0000000..0ba47a5 --- /dev/null +++ b/cli/src/commands/app/lib/file-dev-server.ts.txt @@ -0,0 +1,17 @@ +import { localLakehouse } from "@altertable/data-app-bun"; +import { serveAppFile } from "@altertable/data-app-bun/preview"; + +const preview = await serveAppFile({ + file: process.env.ALTERTABLE_APP_FILE, + port: Number(process.env.PORT), + lakehouse: localLakehouse(), + resolveDependency: (specifier) => Bun.resolveSync(specifier, import.meta.dir), +}); + +for (const signal of ["SIGINT", "SIGTERM"]) { + process.once(signal, async () => { + await preview.stop(); + process.exit(0); + }); +} +console.log(`Data app running at ${preview.url} (${process.env.ALTERTABLE_APP_FILE})`); diff --git a/cli/src/commands/app/lib/file-dev.test.ts b/cli/src/commands/app/lib/file-dev.test.ts new file mode 100644 index 0000000..d709ec4 --- /dev/null +++ b/cli/src/commands/app/lib/file-dev.test.ts @@ -0,0 +1,64 @@ +import { rejects } from "node:assert/strict"; +import { existsSync } from "node:fs"; +import { readFile } from "node:fs/promises"; +import { join } from "node:path"; +import { afterEach, beforeEach, expect, test } from "bun:test"; +import { prepareFilePreview } from "@/commands/app/lib/file-dev.ts"; +import { dataAppPayload } from "@/commands/app/lib/payload.ts"; +import { FROM_ENV_PSEUDOPROFILE_NAME } from "@/lib/profile-store.ts"; +import { createLakehouseTestWorkspace } from "@/test-utils/lakehouse.ts"; + +let workspace: ReturnType; +let savedEnvironment: Record; +beforeEach(() => { + savedEnvironment = { + ALTERTABLE_CONFIG_HOME: process.env.ALTERTABLE_CONFIG_HOME, + ALTERTABLE_ENV: process.env.ALTERTABLE_ENV, + }; + workspace = createLakehouseTestWorkspace("file-dev"); + process.env.ALTERTABLE_CONFIG_HOME = workspace.home; + process.env.ALTERTABLE_ENV = "production"; +}); +afterEach(() => { + workspace.cleanup(); + for (const [key, value] of Object.entries(savedEnvironment)) { + if (value === undefined) delete process.env[key]; + else process.env[key] = value; + } +}); + +function app(scope: string): string { + return `import { defineDataApp as define } from "@altertable/data-app"; +const app = define({ scope: ${scope}, queries: {} });`; +} + +async function prepare(source: string): Promise { + const file = workspace.writeFile("index.tsx", source); + return prepareFilePreview(file, FROM_ENV_PSEUDOPROFILE_NAME); +} + +test("prepares a reusable dev project from the released manifest without executing the app", async () => { + const directory = await prepare( + `${app('{ organization: "acme", environment: "production" }')} +throw new Error("must not execute");`, + ); + const manifest = JSON.parse(await readFile(join(directory, "package.json"), "utf8")); + const starter = JSON.parse(dataAppPayload.starter["package.json"]!); + expect(manifest.dependencies).toEqual(starter.dependencies); + expect(manifest.scripts).toEqual({ dev: "bun server.ts" }); + expect(await readFile(join(directory, "bun.lock"), "utf8")).toBe( + dataAppPayload.starter["bun.lock"]!, + ); + expect(await readFile(join(directory, "server.ts"), "utf8")).toContain( + "@altertable/data-app-bun/preview", + ); + expect(await prepare(app('{ organization: "acme", environment: "production" }'))).toBe(directory); +}); + +test("rejects invalid declarations and mismatched scopes before creating the runtime", async () => { + await rejects(prepare("export const app = 1;"), /Could not extract the data app manifest\.\n1:/); + for (const scope of ["null", "{}", '{ organization: "acme", environment: "staging" }']) { + await rejects(prepare(app(scope)), /data app file scope does not match/); + } + expect(existsSync(join(workspace.home, "data-app-dev"))).toBe(false); +}); diff --git a/cli/src/commands/app/lib/file-dev.ts b/cli/src/commands/app/lib/file-dev.ts new file mode 100644 index 0000000..d6d71e6 --- /dev/null +++ b/cli/src/commands/app/lib/file-dev.ts @@ -0,0 +1,41 @@ +import { mkdir, writeFile } from "node:fs/promises"; +import { join } from "node:path"; +import serverScript from "@/commands/app/lib/file-dev-server.ts.txt"; +import { recommendedDataAppVersion } from "@/commands/app/lib/package.ts"; +import { dataAppPayload } from "@/commands/app/lib/payload.ts"; +import { readRequiredFile } from "@/commands/app/lib/remote.ts"; +import { assertAppScope, profileAppScope } from "@/commands/app/lib/scope.ts"; +import { configDir } from "@/lib/config-files.ts"; +import { ConfigurationError } from "@/lib/errors.ts"; + +/** Prepare a regular dev project backed by the starter's pinned runtime. */ +export async function prepareFilePreview(file: string, profile: string): Promise { + const source = await readRequiredFile(file, "source"); + // Keep the TypeScript compiler off the startup path of other CLI commands. + const { extractDataAppManifest } = await import("@altertable/data-app-manifest"); + const { manifest, diagnostics } = extractDataAppManifest(source); + if (!manifest) { + const details = diagnostics + .slice(0, 3) + .map(({ message, start }) => `${start.line}:${start.column}: ${message}`) + .join("\n"); + throw new ConfigurationError(`Could not extract the data app manifest.\n${details}`); + } + assertAppScope(manifest.scope, profileAppScope(profile), "data app file"); + + const directory = join(configDir(), "data-app-dev", recommendedDataAppVersion()); + const starter = dataAppPayload.starter; + const packageJson = JSON.parse(starter["package.json"]!); + packageJson.scripts = { dev: "bun server.ts" }; + await mkdir(directory, { recursive: true }); + const files = { + "package.json": `${JSON.stringify(packageJson, null, 2)}\n`, + "bun.lock": starter["bun.lock"]!, + "bunfig.toml": starter["bunfig.toml"]!, + "server.ts": serverScript, + }; + await Promise.all( + Object.entries(files).map(([name, content]) => writeFile(join(directory, name), content)), + ); + return directory; +} diff --git a/cli/src/commands/app/lib/scope.ts b/cli/src/commands/app/lib/scope.ts index 019d0e8..9e3fa15 100644 --- a/cli/src/commands/app/lib/scope.ts +++ b/cli/src/commands/app/lib/scope.ts @@ -8,6 +8,7 @@ import { ConfigurationError } from "@/lib/errors.ts"; export function assertAppScope( scope: unknown, profile: { organization?: string; organizationName?: string; environment?: string }, + source = "app.json", ): void { const value = scope as { organization?: unknown; environment?: unknown } | null; if ( @@ -21,11 +22,21 @@ export function assertAppScope( (Boolean(profile.environment) && value.environment !== profile.environment) ) { throw new ConfigurationError( - "app.json scope does not match the selected profile. Select the matching profile or update the app scope before querying.", + `${source} scope does not match the selected profile. Select the matching profile or update the app scope before querying.`, ); } } +export function profileAppScope(profile: string) { + return { + organization: configGet("organization_slug", profile).trim(), + organizationName: configGet("organization_name", profile).trim(), + environment: isFromEnvProfile(profile) + ? readEnv("ALTERTABLE_ENV") + : configGet("api_key_env", profile).trim(), + }; +} + export async function checkAppScope(directory: string, profile: string): Promise { let manifest; try { @@ -33,11 +44,5 @@ export async function checkAppScope(directory: string, profile: string): Promise } catch { throw new ConfigurationError("Cannot read a valid app.json for profile scope verification."); } - assertAppScope(manifest?.scope, { - organization: configGet("organization_slug", profile).trim(), - organizationName: configGet("organization_name", profile).trim(), - environment: isFromEnvProfile(profile) - ? readEnv("ALTERTABLE_ENV") - : configGet("api_key_env", profile).trim(), - }); + assertAppScope(manifest?.scope, profileAppScope(profile)); } diff --git a/data-app/starter/bun.lock b/data-app/starter/bun.lock index 047bc1a..93b990c 100644 --- a/data-app/starter/bun.lock +++ b/data-app/starter/bun.lock @@ -5,9 +5,9 @@ "": { "name": "data-app-starter", "dependencies": { - "@altertable/data-app": "0.71.0", - "@altertable/data-app-bun": "0.71.0", - "@altertable/data-app-react": "0.71.0", + "@altertable/data-app": "0.72.0", + "@altertable/data-app-bun": "0.72.0", + "@altertable/data-app-react": "0.72.0", "react": "19.3.0", "react-dom": "19.3.0", }, @@ -23,11 +23,11 @@ }, }, "packages": { - "@altertable/data-app": ["@altertable/data-app@0.71.0", "", { "dependencies": { "@internationalized/date": "3.12.4" } }, "sha512-2v4vy3BJnKHFp7LJ60xwSipBrwZED+6v+iFKmKYy0k3hHEf5iUjApR7NwUJVNC5dJxDoQPLGLesQZrA18VoOuw=="], + "@altertable/data-app": ["@altertable/data-app@0.72.0", "", { "dependencies": { "@internationalized/date": "3.12.4" } }, "sha512-F1wgk5ANgxrl2y48w2D0PpWkv8SHTiPapBbmGrlrb4OQjgj2JAjmitVBUW/luMj0M3E7hwVAjOvld4JT6KbloQ=="], - "@altertable/data-app-bun": ["@altertable/data-app-bun@0.71.0", "", { "dependencies": { "@altertable/data-app": "0.71.0", "@altertable/lakehouse": "0.4.1", "get-tsconfig": "4.14.3" } }, "sha512-uxYbvGeWhfRAVfdWAHWDKDW17csmpQocIK/STewR5Cb+X7HS51CJY/hdXSKXBBMsejMH6CW69oy49PBOnq1rTw=="], + "@altertable/data-app-bun": ["@altertable/data-app-bun@0.72.0", "", { "dependencies": { "@altertable/data-app": "0.72.0", "@altertable/lakehouse": "0.4.1", "get-tsconfig": "4.14.3" } }, "sha512-fMjSn8TIBo5oSQbimlHHyfUauZ/xxKvKCl7Jze7xUrIPSLccZXAesHjBIHwoKmKjXstBheWp47asrjooN5pLgw=="], - "@altertable/data-app-react": ["@altertable/data-app-react@0.71.0", "", { "dependencies": { "@altertable/data-app": "0.71.0", "@floating-ui/react": "0.27.20", "@internationalized/date": "3.12.4", "@tanstack/react-query": "5.104.0", "fflate": "0.8.3", "fuzzysort": "4.0.2", "html-to-image": "1.11.13", "lucide-react": "1.48.0", "react-aria-components": "1.21.1", "recharts": "3.10.1" }, "peerDependencies": { "react": ">=19.2.0", "react-dom": ">=19.2.0" } }, "sha512-1qT4h94ZUWUh6dkJnqpo1a+b0HNSdZeu6Fs32bIQQy/qZyevPhuE0HKK2O6pEgzcQmYJPlUKmxTn7HquKtprNQ=="], + "@altertable/data-app-react": ["@altertable/data-app-react@0.72.0", "", { "dependencies": { "@altertable/data-app": "0.72.0", "@floating-ui/react": "0.27.20", "@internationalized/date": "3.12.4", "@tanstack/react-query": "5.104.0", "fflate": "0.8.3", "fuzzysort": "4.0.2", "html-to-image": "1.11.13", "lucide-react": "1.48.0", "react-aria-components": "1.21.1", "recharts": "3.10.1" }, "peerDependencies": { "react": ">=19.2.0", "react-dom": ">=19.2.0" } }, "sha512-SEJ3tHdZ6oUZm+pJLiesfnknYQfSd3/Aymhip3qA08gu3uJCQ1I2ocXLmzj6zcZZXFmtDwGhkWprVGXiomtxGA=="], "@altertable/lakehouse": ["@altertable/lakehouse@0.4.1", "", {}, "sha512-m7d15cWt+WUGW7lVw2KYGD+Se8MzO25G7SWSuFd+OasBxWmOJNa2IrgvOHGVEbnZ+kexTUy9NjAGQ69sG4V91w=="], diff --git a/data-app/starter/package.json b/data-app/starter/package.json index ac9b6f6..389733e 100644 --- a/data-app/starter/package.json +++ b/data-app/starter/package.json @@ -15,9 +15,9 @@ "build": "bun build src/index.html --outdir=dist --production" }, "dependencies": { - "@altertable/data-app": "0.71.0", - "@altertable/data-app-react": "0.71.0", - "@altertable/data-app-bun": "0.71.0", + "@altertable/data-app": "0.72.0", + "@altertable/data-app-bun": "0.72.0", + "@altertable/data-app-react": "0.72.0", "react": "19.3.0", "react-dom": "19.3.0" }, diff --git a/data-app/tests/bun.lock b/data-app/tests/bun.lock index e327efa..6f2b44b 100644 --- a/data-app/tests/bun.lock +++ b/data-app/tests/bun.lock @@ -5,7 +5,7 @@ "": { "name": "data-app-browser-tests", "dependencies": { - "@altertable/data-app": "0.71.0", + "@altertable/data-app": "0.72.0", }, "devDependencies": { "@playwright/test": "1.63.0", @@ -16,7 +16,7 @@ }, }, "packages": { - "@altertable/data-app": ["@altertable/data-app@0.71.0", "", { "dependencies": { "@internationalized/date": "3.12.4" } }, "sha512-2v4vy3BJnKHFp7LJ60xwSipBrwZED+6v+iFKmKYy0k3hHEf5iUjApR7NwUJVNC5dJxDoQPLGLesQZrA18VoOuw=="], + "@altertable/data-app": ["@altertable/data-app@0.72.0", "", { "dependencies": { "@internationalized/date": "3.12.4" } }, "sha512-F1wgk5ANgxrl2y48w2D0PpWkv8SHTiPapBbmGrlrb4OQjgj2JAjmitVBUW/luMj0M3E7hwVAjOvld4JT6KbloQ=="], "@internationalized/date": ["@internationalized/date@3.12.4", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-M1dEn4c1U1HsSlaVR8upZtSqvXrTkHDfv18H01uCSJyjVLDxnBR38v/fMxecmlwXKR4i9HeZcmgQAPE6A+aGJQ=="], diff --git a/data-app/tests/package.json b/data-app/tests/package.json index d012dc6..ec16dee 100644 --- a/data-app/tests/package.json +++ b/data-app/tests/package.json @@ -15,6 +15,6 @@ "typescript": "7.0.2" }, "dependencies": { - "@altertable/data-app": "0.71.0" + "@altertable/data-app": "0.72.0" } }