|
| 1 | +# Upgrading to ObjectStack 11 |
| 2 | + |
| 3 | +ObjectStack 11 is a focused breaking release: it sharpens the **open edition** down |
| 4 | +to what is actually shipped and dogfooded, and removes a batch of long-deprecated |
| 5 | +APIs. This guide lists every breaking change from **10.x → 11.x** with a concrete |
| 6 | +migration for each. |
| 7 | + |
| 8 | +> The breaking changes are spread across the 11 line (11.0.0 + 11.1.0). There is |
| 9 | +> one migration target: **the latest 11.x**. Pin `@objectstack/*` to `^11`. |
| 10 | +
|
| 11 | +## Quick checklist |
| 12 | + |
| 13 | +- [ ] AI authoring service is no longer bundled in the open edition → see [MCP-only](#open-edition-is-mcp-only). |
| 14 | +- [ ] Using a non-Hono HTTP adapter (Express/Fastify/Next/Nest/Nuxt/SvelteKit) or `@objectstack/plugin-msw`? → [Adapters](#http-adapters-hono-only). |
| 15 | +- [ ] Flow nodes typed `http_request` / `http_call` / `webhook` → rename to `http`. |
| 16 | +- [ ] `@objectstack/client-react` `useQuery` using `select`/`filters`/`sort`/`top`/`skip` → canonical names. |
| 17 | +- [ ] Code referencing `IUIService` → `IMetadataService`. |
| 18 | +- [ ] Driver code typed `DriverInterface` (the alias) → `IDataDriver`. |
| 19 | +- [ ] `.env` using `OS_MULTI_TENANT` / `OBJECTSTACK_METADATA_WRITABLE` / `AUTH_BASE_URL` → rename. |
| 20 | +- [ ] Stack `policies` / `definePolicy` → removed (was never enforced). |
| 21 | + |
| 22 | +--- |
| 23 | + |
| 24 | +## Open edition is MCP-only |
| 25 | + |
| 26 | +The bundled AI authoring service (`@objectstack/service-ai`) is **no longer part of |
| 27 | +the open distribution** (ADR-0025). AI integrates through MCP (`@objectstack/mcp`) |
| 28 | +plus the documented opt-in seam. |
| 29 | + |
| 30 | +**Migration** |
| 31 | +- If you don't use AI authoring: nothing to do. |
| 32 | +- If you do: declare `@objectstack/service-ai` / `@objectstack/service-ai-studio` |
| 33 | + as an app dependency (the CLI auto-registers the service only when the host app |
| 34 | + declares it), or run on the commercial distribution. MCP tooling is unaffected. |
| 35 | + |
| 36 | +## HTTP adapters: Hono only |
| 37 | + |
| 38 | +The open edition now ships **only the Hono adapter** (`@objectstack/hono`). These |
| 39 | +packages were removed (zero internal consumers, not dogfooded): |
| 40 | +`@objectstack/express`, `@objectstack/fastify`, `@objectstack/nextjs`, |
| 41 | +`@objectstack/nestjs`, `@objectstack/nuxt`, `@objectstack/sveltekit`, and |
| 42 | +`@objectstack/plugin-msw`. |
| 43 | + |
| 44 | +**Migration** |
| 45 | +- **On Hono already** → no change. |
| 46 | +- **On another framework** → either move to Hono (`createHonoApp` / `objectStackMiddleware`, |
| 47 | + runs on Node/Bun/Deno/Workers), or build a thin adapter on the public |
| 48 | + `HttpDispatcher` API / `createDispatcherPlugin` (the removed adapters were ~50-line |
| 49 | + wrappers; you can vendor one out-of-tree). |
| 50 | +- **Used `@objectstack/plugin-msw`** for test mocking → use `msw` directly, or |
| 51 | + drive the kernel via `@objectstack/hono` in tests. |
| 52 | + |
| 53 | +```ts |
| 54 | +// before: import { objectStackPlugin } from '@objectstack/fastify'; |
| 55 | +import { createHonoApp } from '@objectstack/hono'; |
| 56 | +const app = createHonoApp({ kernel, prefix: '/api/v1' }); |
| 57 | +``` |
| 58 | + |
| 59 | +## Flow node type: `http` |
| 60 | + |
| 61 | +The deprecated flow-node aliases `http_request` / `http_call` / `webhook` are |
| 62 | +removed; the canonical type is **`http`** (same behavior — durable outbox when |
| 63 | +`config.durable`, inline fetch otherwise). Authoring a removed type now fails fast |
| 64 | +at parse instead of silently resolving. |
| 65 | + |
| 66 | +```ts |
| 67 | +// before: { id: 'call', type: 'http_request', config: { url, method } } |
| 68 | +{ id: 'call', type: 'http', config: { url, method } } |
| 69 | +``` |
| 70 | + |
| 71 | +> The trigger `eventType: 'webhook'` and the `webhook` resume event are unchanged — |
| 72 | +> only the HTTP **node** aliases were removed. |
| 73 | +
|
| 74 | +## `@objectstack/client-react`: canonical query fields |
| 75 | + |
| 76 | +`useQuery` / `useInfiniteQuery` no longer accept the legacy aliases: |
| 77 | + |
| 78 | +| removed | use | |
| 79 | +|---|---| |
| 80 | +| `select` | `fields` | |
| 81 | +| `filters` | `where` | |
| 82 | +| `sort` | `orderBy` | |
| 83 | +| `top` | `limit` | |
| 84 | +| `skip` | `offset` | |
| 85 | + |
| 86 | +```ts |
| 87 | +// before: useQuery('account', { select: ['name'], filters, sort, top: 20, skip: 40 }) |
| 88 | +useQuery('account', { fields: ['name'], where, orderBy, limit: 20, offset: 40 }); |
| 89 | +``` |
| 90 | + |
| 91 | +## `IUIService` → `IMetadataService` |
| 92 | + |
| 93 | +The deprecated `IUIService` contract is removed. Views and dashboards are metadata: |
| 94 | + |
| 95 | +```ts |
| 96 | +// before: ui.getView(name) / ui.registerView(name, def) |
| 97 | +metadata.get('view', name); |
| 98 | +metadata.register('view', name, def); |
| 99 | +``` |
| 100 | + |
| 101 | +## `DriverInterface` (alias) → `IDataDriver` |
| 102 | + |
| 103 | +The deprecated `DriverInterface` type alias (`= IDataDriver`) is removed. Use |
| 104 | +`IDataDriver` — the shape is identical. |
| 105 | + |
| 106 | +```ts |
| 107 | +// before: import { DriverInterface } from '@objectstack/runtime'; |
| 108 | +import type { IDataDriver } from '@objectstack/spec/contracts'; |
| 109 | +``` |
| 110 | + |
| 111 | +> Unrelated and unchanged: the live `IDataEngine` (engine-layer contract) and the |
| 112 | +> zod-derived `DriverInterface` / `DriverInterfaceSchema` in `@objectstack/spec/data`. |
| 113 | +
|
| 114 | +## Environment variables: ObjectStack's own renames removed |
| 115 | + |
| 116 | +The framework's **own** legacy env names are removed — rename them: |
| 117 | + |
| 118 | +| removed | use | |
| 119 | +|---|---| |
| 120 | +| `OS_MULTI_TENANT` | `OS_MULTI_ORG_ENABLED` | |
| 121 | +| `OBJECTSTACK_METADATA_WRITABLE` | `OS_METADATA_WRITABLE` | |
| 122 | +| `OS_AUTH_BASE_URL`, `AUTH_BASE_URL` | `OS_AUTH_URL` | |
| 123 | + |
| 124 | +**Ecosystem-standard names still work** (and no longer warn): `DATABASE_URL`, |
| 125 | +`AUTH_SECRET`, `BETTER_AUTH_SECRET`, `BETTER_AUTH_URL`, `PORT`, `CORS_*`, |
| 126 | +`LOG_LEVEL`, `ROOT_DOMAIN`, `MCP_SERVER_*`. |
| 127 | + |
| 128 | +## `PolicySchema` / `definePolicy` removed |
| 129 | + |
| 130 | +The "org security policy" schema (`PolicySchema`, `definePolicy`, and the stack |
| 131 | +`policies` collection) is removed — it was parsed but **never enforced** at runtime |
| 132 | +(ADR-0049). `better-auth` governs session/password behavior; there is no functional |
| 133 | +loss. |
| 134 | + |
| 135 | +**Migration**: delete `policies: [...]` from `defineStack(...)` and any |
| 136 | +`definePolicy(...)` definitions. For real password/session policy, configure |
| 137 | +`@objectstack/plugin-auth`. `SharingRule` / `PermissionSet` / RLS are unaffected. |
| 138 | + |
| 139 | +--- |
| 140 | + |
| 141 | +## Behavioral changes to be aware of (not API-breaking) |
| 142 | + |
| 143 | +11 also hardens authentication (ADR-0069). These don't change your code but can |
| 144 | +change runtime behavior for end users: |
| 145 | + |
| 146 | +- Breached passwords are rejected (HIBP). |
| 147 | +- Account lockout + login rate-limiting. |
| 148 | +- Optional password expiry, history/no-reuse, complexity, and enforced MFA |
| 149 | + (per-org). Review your `@objectstack/plugin-auth` configuration before rollout. |
| 150 | + |
| 151 | +## Getting help |
| 152 | + |
| 153 | +If a removed adapter or API blocks you, open an issue — thin adapters and the |
| 154 | +`HttpDispatcher` API are public, so out-of-tree maintenance is straightforward. |
0 commit comments