diff --git a/CHANGELOG.md b/CHANGELOG.md index b804cce..d91654d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## 0.17.0 (unreleased) + +The hub is the project `identity-hub`, a name that says what the project holds. + +- `Convex.HubClient` and the command `alchemy-convex hub-client` find the hub in the project + `identity-hub`. Rename the project with `PATCH /projects/{project_id}` and `name: "identity-hub"`. + The slug does not matter, because the lookup uses the name. +- Upgrade every stack that has a hub client together with the rename. A run on an older version + fails with a clear error when it must register or delete a client. A new preview that fails this + way keeps its deployment, so rerun the stack after the upgrade, or destroy the stage. A deployment + whose client exists keeps working, because a deploy calls the hub only for a change. + ## 0.16.0 (unreleased) The state store has its own project again, `alchemy-state-store`, the name of the Cloudflare state diff --git a/README.md b/README.md index 3809ad6..44e80ec 100644 --- a/README.md +++ b/README.md @@ -276,7 +276,7 @@ call. - `Convex.HubClient`: `{ team, app, redirectUri, deploymentType, clientName, softwareVersion? }` registers one deployment as a client of the identity hub of the team. The hub is the production - deployment of the project `samebase`. The resource finds it by name and runs + deployment of the project `identity-hub`. The resource finds it by name and runs its internal function `identityBroker:registerClient` with a short-lived key, so the stack needs no other credential and no hub address. The first client of an `app` creates the app. Outputs `issuer`, `clientId`, `clientSecret`, `redirectUri`, `deploymentType`, and `clientName`, which the diff --git a/docs/design/convex-state.md b/docs/design/convex-state.md index 2c46736..d3c55ba 100644 --- a/docs/design/convex-state.md +++ b/docs/design/convex-state.md @@ -201,8 +201,9 @@ hub, so that a team would have one project. That was reversed for three reasons, - The one-credential benefit does not need one project: the team token reaches every project of the team, and `Convex.HubClient` finds the hub by the name of its project. -The hub stays in the project `samebase`. Renaming it while an older version of this package can run -is unsafe: that version finds no project of that name and creates an empty store. +The hub stayed in the project `samebase` at first, because a rename was unsafe while a version of this +package that looks for its store under that name could run. Since 0.17.0 the hub is the project +`identity-hub`, found by name. A team renames the project together with the upgrade of its stacks. ## The project was named samebase (0.13.0 to 0.15.0) diff --git a/package.json b/package.json index e8045b5..96c31e8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@samebase/alchemy-convex", - "version": "0.16.0", + "version": "0.17.0", "description": "The Convex plane for Alchemy v2: projects, deployments, environment variables, and the push of the functions", "keywords": [ "alchemy", diff --git a/src/HubClient.ts b/src/HubClient.ts index 10effad..55950f7 100644 --- a/src/HubClient.ts +++ b/src/HubClient.ts @@ -1,7 +1,7 @@ // Convex.HubClient: one deployment of an app as a client of the identity hub // of its team. // -// The hub is the production deployment of the project `samebase` of the team. +// The hub is the production deployment of the project `identity-hub` of the team. // It has the internal functions of `@samebase/identity-broker` in its module // `identityBroker`. This resource finds the project by name and runs those // functions with a short-lived key, so a stack that has the Convex credential @@ -26,12 +26,12 @@ import { withPushKey } from "./Push.ts"; import { type FunctionApi, makeFunctionApi, RUN_KEY_ACTIONS } from "./State.ts"; /** The name of the project of the hub in each team. */ -export const HUB_PROJECT_NAME = "samebase"; +export const HUB_PROJECT_NAME = "identity-hub"; export type HubDeploymentType = "production" | "development" | "preview"; export interface HubClientProps { - /** The Convex team, a slug or an id, whose project `samebase` holds the hub. */ + /** The Convex team, a slug or an id, whose project `identity-hub` holds the hub. */ readonly team: string | number; /** The app on the hub, such as `scout`. The first client of an app creates it, as a first-party app. */ readonly app: string; diff --git a/test/HubClient.test.ts b/test/HubClient.test.ts index 74afad8..41dd3d0 100644 --- a/test/HubClient.test.ts +++ b/test/HubClient.test.ts @@ -128,7 +128,7 @@ describe("Convex.HubClient", () => { new FakeConvex().install(); const error = yield* Effect.flip(stack.deploy(client(props()))); expect(error).toBeInstanceOf(Convex.HubClientFailed); - expect(error.message).toContain("no project samebase"); + expect(error.message).toContain("no project identity-hub"); }), );