diff --git a/.changeset/brown-pots-rush.md b/.changeset/brown-pots-rush.md new file mode 100644 index 000000000000..518a41979d94 --- /dev/null +++ b/.changeset/brown-pots-rush.md @@ -0,0 +1,6 @@ +--- +"@studiocms/migrator": patch +"studiocms": patch +--- + +Update imports for Migrator to `@withstudiocms/sdk/migrator` diff --git a/.changeset/young-rabbits-ask.md b/.changeset/young-rabbits-ask.md new file mode 100644 index 000000000000..9308db27f08a --- /dev/null +++ b/.changeset/young-rabbits-ask.md @@ -0,0 +1,6 @@ +--- +"@withstudiocms/kysely": patch +"@withstudiocms/sdk": patch +--- + +Move custom StudioCMS migrations from `@withstudiocms/kysely` package to `@withstudiocms/sdk` diff --git a/package.json b/package.json index fb7ad8434c39..79e47f5577f5 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "build:studiocms": "pnpm build:packages", "build:packages": "pnpm --filter studiocms --filter @studiocms/* --filter @withstudiocms/* build", - "create-migration": "pnpm --filter @withstudiocms/kysely create-migration", + "create-migration": "pnpm --filter @withstudiocms/sdk create-migration", "playground:dev": "pnpm dev", "playground:preview": "pnpm --filter node-playground preview", diff --git a/packages/@studiocms/migrator/src/db/client.ts b/packages/@studiocms/migrator/src/db/client.ts index 28fb50c13ac3..8aa1d12b7762 100644 --- a/packages/@studiocms/migrator/src/db/client.ts +++ b/packages/@studiocms/migrator/src/db/client.ts @@ -1,7 +1,7 @@ import { runEffect } from '@withstudiocms/effect'; import { getDBClientLive } from '@withstudiocms/kysely/client'; import { sql } from '@withstudiocms/kysely/kysely'; -import { getMigratorLive } from '@withstudiocms/kysely/migrator'; +import { getMigratorLive } from '@withstudiocms/sdk/migrator'; import type { StudioCMSDatabaseSchema } from '@withstudiocms/sdk/tables'; import { type KyselyTableKeys, kyselyTableKeys } from '../lib/tableMap'; diff --git a/packages/@withstudiocms/kysely/package.json b/packages/@withstudiocms/kysely/package.json index 134a15127561..aa077f704c4f 100644 --- a/packages/@withstudiocms/kysely/package.json +++ b/packages/@withstudiocms/kysely/package.json @@ -31,7 +31,6 @@ "build": "pnpm buildkit build 'src/**/*.{ts,json}'", "dev": "pnpm buildkit dev 'src/**/*.{ts,json}'", "typecheck": "tspc -p tsconfig.tspc.json", - "create-migration": "tsx scripts/create-migration.ts", "test": "vitest" }, "exports": { @@ -47,10 +46,6 @@ "types": "./dist/client.d.ts", "default": "./dist/client.js" }, - "./migrator": { - "types": "./dist/migrator.d.ts", - "default": "./dist/migrator.js" - }, "./plugin": { "types": "./dist/plugin.d.ts", "default": "./dist/plugin.js" @@ -71,8 +66,9 @@ "types": "./dist/drivers/*.d.ts", "default": "./dist/drivers/*.js" }, - "./schemas/*": { - "default": "./dist/schemas/*.json" + "./utils/*": { + "types": "./dist/utils/*.d.ts", + "default": "./dist/utils/*.js" } }, "type": "module", @@ -82,8 +78,7 @@ }, "devDependencies": { "@types/node": "catalog:", - "@types/pg": "catalog:kysely", - "tsx": "^4.21.0" + "@types/pg": "catalog:kysely" }, "peerDependencies": { "effect": "catalog:effect", diff --git a/packages/@withstudiocms/kysely/src/core/migrator.ts b/packages/@withstudiocms/kysely/src/core/migrator.ts index 6f0c56d65ab0..8de7de402c35 100644 --- a/packages/@withstudiocms/kysely/src/core/migrator.ts +++ b/packages/@withstudiocms/kysely/src/core/migrator.ts @@ -98,13 +98,13 @@ export class PassthroughMigrationProvider implements MigrationProvider { * const migratorInstance = getMigrator(kyselyInstance); */ const kyselyMigrator = - (migrationFolder: Record) => + (migrations: Record) => (db: Kysely) => useWithError( () => new Migrator({ db, - provider: new PassthroughMigrationProvider(migrationFolder), + provider: new PassthroughMigrationProvider(migrations), }) ); @@ -127,11 +127,9 @@ const kyselyMigrator = * Note: This function returns an Effect (deferred computation). You must run/interpret the Effect * to obtain and invoke the migration helpers. */ -const makeMigrator = (migrationFolder: Record) => +const makeMigrator = (migrations: Record) => Effect.gen(function* () { - const base = yield* kyselyClient().pipe( - Effect.flatMap(kyselyMigrator(migrationFolder)) - ); + const base = yield* kyselyClient().pipe(Effect.flatMap(kyselyMigrator(migrations))); const toLatest = useWithErrorPromise(() => base.migrateToLatest()); const down = useWithErrorPromise(() => base.migrateDown()); @@ -162,13 +160,10 @@ const makeMigrator = (migrationFolder: Record) => * @example * // Run the returned Effect to obtain and use the migrator in your application runtime. */ -export const makeMigratorLive = ( - dialect: Dialect, - migrationFolder: Record -) => +export const makeMigratorLive = (dialect: Dialect, migrations: Record) => Effect.gen(function* () { const { db } = yield* makeDBClientLive(dialect); - return yield* makeMigrator(migrationFolder).pipe( + return yield* makeMigrator(migrations).pipe( Effect.provideService(kyselyClient(), db) ); }); diff --git a/packages/@withstudiocms/kysely/src/index.ts b/packages/@withstudiocms/kysely/src/index.ts index 478e9efcd91e..7edd926aaec4 100644 --- a/packages/@withstudiocms/kysely/src/index.ts +++ b/packages/@withstudiocms/kysely/src/index.ts @@ -1,9 +1,3 @@ -/** - * Migrator is left out of this index to avoid issues with `node:` imports in ESM/CJS - * environments that do not support them. Users should import migrator-related - * functions directly from the migrator module. `@withstudiocms/kysely/migrator`. - */ - export * from './client.js'; // TODO: Create a new Astro integration to handle an Astro-DB like setup diff --git a/packages/@withstudiocms/kysely/src/test-utils.ts b/packages/@withstudiocms/kysely/src/test-utils.ts index 5d5c408b5d95..ac59ecc5abac 100644 --- a/packages/@withstudiocms/kysely/src/test-utils.ts +++ b/packages/@withstudiocms/kysely/src/test-utils.ts @@ -4,7 +4,6 @@ import { createClient } from '@libsql/client/node'; import { Effect } from 'effect'; import { LibSQLDialect } from 'kysely-turso/libsql'; import { getDBClientLive } from './client.js'; -import { getMigratorLive } from './migrator.js'; type DBFixtureOptions = { suiteName: string; @@ -15,7 +14,6 @@ type DBFixtureOptions = { * Should be `import.meta.url` from the calling module. */ cwd: string; - migrationsDir?: string; }; function normalize(str: string) { @@ -108,16 +106,6 @@ export class DBFixture { const dialect = this.getDialect(); return getDBClientLive(dialect); }, - - /** - * Creates and returns a migrator instance configured for the test database. - * - * @returns A migrator instance for managing database migrations. - */ - getMigrator: () => { - const dialect = this.getDialect(); - return getMigratorLive(dialect); - }, }; /** JavaScript-based utilities for managing the test database fixture. */ @@ -139,12 +127,5 @@ export class DBFixture { * @returns A Kysely client instance connected to the test database. */ getClient: () => this.run(this.effect.getClient()), - - /** - * Creates and returns a migrator instance configured for the test database. - * - * @returns A migrator instance for managing database migrations. - */ - getMigrator: () => this.run(this.effect.getMigrator()), }; } diff --git a/packages/@withstudiocms/kysely/test/core/migrator.test.ts b/packages/@withstudiocms/kysely/test/core/migrator.test.ts deleted file mode 100644 index 0e01d1483c5c..000000000000 --- a/packages/@withstudiocms/kysely/test/core/migrator.test.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { afterEach, beforeEach, describe, expect } from 'vitest'; -import { allureTester, DBClientFixture, parentSuiteName, sharedTags } from '../test-utils'; - -const localSuiteName = 'Migrator Core Functionality'; - -describe(parentSuiteName, () => { - const test = allureTester({ - suiteParentName: parentSuiteName, - suiteName: localSuiteName, - }); - - const { js: dbFixture, run } = DBClientFixture(localSuiteName); - - beforeEach(async () => { - await dbFixture.cleanup(); - }); - - afterEach(async () => { - await dbFixture.cleanup(); - }); - - test('Kysely migrator can perform migrations', async ({ setupAllure, step }) => { - await setupAllure({ - subSuiteName: 'Kysely migrator can perform migrations', - tags: [...sharedTags], - }); - - const migrator = await dbFixture.getMigrator(); - - await step('should apply migrations successfully', async () => { - const migrationResult = await run(migrator.toLatest); - expect(migrationResult.results?.length).toBeGreaterThan(0); - }); - - await step('should rollback migrations successfully', async () => { - const rollbackResult = await run(migrator.down); - expect(rollbackResult.results?.length).toBeGreaterThan(0); - }); - }); - - test('Kysely migrator can report current migration state', async ({ setupAllure, step }) => { - await setupAllure({ - subSuiteName: 'Kysely migrator can report current migration state', - tags: [...sharedTags], - }); - - const migrator = await dbFixture.getMigrator(); - - await step('should report current migration state accurately', async () => { - // Apply migrations first - await run(migrator.toLatest); - - const currentState = await run(migrator.status); - - expect(currentState.length).toBeGreaterThan(0); - expect(currentState.find((m) => m.name === '20251025T040912_init')?.name).toBeDefined(); - }); - }); -}); diff --git a/packages/@withstudiocms/kysely/test/test-utils.ts b/packages/@withstudiocms/kysely/test/test-utils.ts index fc7e8751da0c..88c1f031aaa1 100644 --- a/packages/@withstudiocms/kysely/test/test-utils.ts +++ b/packages/@withstudiocms/kysely/test/test-utils.ts @@ -1,5 +1,3 @@ -import path from 'node:path'; -import { fileURLToPath } from 'node:url'; import * as allure from 'allure-js-commons'; import { test as baseTest } from 'vitest'; import { DBFixture } from '../src/test-utils'; @@ -7,13 +5,6 @@ import { DBFixture } from '../src/test-utils'; export const parentSuiteName = '@withstudiocms/kysely Package Tests'; export const sharedTags = ['package:@withstudiocms/kysely', 'type:unit', 'scope:withstudiocms']; -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); - -// Path to the migrations folder for tests -// This ensures that the migrator in tests uses the compiled migrations preventing issues with missing files while allowing correct coverage reporting. -const migrationFolder = path.join(__dirname, '../dist/migrations'); - /** * Extends the base test fixture with Allure helpers tailored for tests. * @@ -112,6 +103,5 @@ export const DBClientFixture = (suite: string) => { return new DBFixture({ suiteName: suite, cwd: import.meta.url, - migrationsDir: migrationFolder, }); }; diff --git a/packages/@withstudiocms/sdk/package.json b/packages/@withstudiocms/sdk/package.json index a0d6207a1f7a..41abbba40fe3 100644 --- a/packages/@withstudiocms/sdk/package.json +++ b/packages/@withstudiocms/sdk/package.json @@ -29,6 +29,7 @@ "scripts": { "build": "pnpm buildkit build 'src/**/*.{ts,json}'", "dev": "pnpm buildkit dev 'src/**/*.{ts,json}'", + "create-migration": "tsx scripts/create-migration.ts", "typecheck": "tspc -p tsconfig.tspc.json" }, "exports": { @@ -48,6 +49,10 @@ "types": "./dist/types.d.ts", "default": "./dist/types.js" }, + "./migrator": { + "types": "./dist/migrator.d.ts", + "default": "./dist/migrator.js" + }, "./*": "./dist/*" }, "type": "module", @@ -57,7 +62,8 @@ "zod": "^3.25.76" }, "devDependencies": { - "@types/node": "catalog:" + "@types/node": "catalog:", + "tsx": "^4.21.0" }, "peerDependencies": { "@withstudiocms/effect": "workspace:*", diff --git a/packages/@withstudiocms/kysely/scripts/create-migration.ts b/packages/@withstudiocms/sdk/scripts/create-migration.ts similarity index 100% rename from packages/@withstudiocms/kysely/scripts/create-migration.ts rename to packages/@withstudiocms/sdk/scripts/create-migration.ts diff --git a/packages/@withstudiocms/kysely/src/migrations/20251025T040912_init.ts b/packages/@withstudiocms/sdk/src/migrations/20251025T040912_init.ts similarity index 98% rename from packages/@withstudiocms/kysely/src/migrations/20251025T040912_init.ts rename to packages/@withstudiocms/sdk/src/migrations/20251025T040912_init.ts index 108b6862060f..c663585a848e 100644 --- a/packages/@withstudiocms/kysely/src/migrations/20251025T040912_init.ts +++ b/packages/@withstudiocms/sdk/src/migrations/20251025T040912_init.ts @@ -11,8 +11,12 @@ */ /** biome-ignore-all lint/suspicious/noExplicitAny: Requirement from Kysely */ -import type { Kysely } from 'kysely'; -import { rollbackMigration, syncDatabaseSchema, type TableDefinition } from '../utils/migrator.js'; +import type { Kysely } from '@withstudiocms/kysely/kysely'; +import { + rollbackMigration, + syncDatabaseSchema, + type TableDefinition, +} from '@withstudiocms/kysely/utils/migrator'; // import { schemaDefinition as previousSchema } from './placeholder-for-previous-migration.js'; diff --git a/packages/@withstudiocms/kysely/src/migrations/20251130T150847_drop_deprecated.ts b/packages/@withstudiocms/sdk/src/migrations/20251130T150847_drop_deprecated.ts similarity index 98% rename from packages/@withstudiocms/kysely/src/migrations/20251130T150847_drop_deprecated.ts rename to packages/@withstudiocms/sdk/src/migrations/20251130T150847_drop_deprecated.ts index 6a563d62f16f..b67b57847e88 100644 --- a/packages/@withstudiocms/kysely/src/migrations/20251130T150847_drop_deprecated.ts +++ b/packages/@withstudiocms/sdk/src/migrations/20251130T150847_drop_deprecated.ts @@ -7,8 +7,12 @@ */ /** biome-ignore-all lint/suspicious/noExplicitAny: Requirement from Kysely */ -import type { Kysely } from 'kysely'; -import { rollbackMigration, syncDatabaseSchema, type TableDefinition } from '../utils/migrator.js'; +import type { Kysely } from '@withstudiocms/kysely/kysely'; +import { + rollbackMigration, + syncDatabaseSchema, + type TableDefinition, +} from '@withstudiocms/kysely/utils/migrator'; import { schemaDefinition as previousSchema } from './20251025T040912_init.js'; diff --git a/packages/@withstudiocms/kysely/src/migrations/20251221T002125_url-mapping.ts b/packages/@withstudiocms/sdk/src/migrations/20251221T002125_url-mapping.ts similarity index 97% rename from packages/@withstudiocms/kysely/src/migrations/20251221T002125_url-mapping.ts rename to packages/@withstudiocms/sdk/src/migrations/20251221T002125_url-mapping.ts index 63ff656b11e3..bba800dbffd5 100644 --- a/packages/@withstudiocms/kysely/src/migrations/20251221T002125_url-mapping.ts +++ b/packages/@withstudiocms/sdk/src/migrations/20251221T002125_url-mapping.ts @@ -7,8 +7,12 @@ */ /** biome-ignore-all lint/suspicious/noExplicitAny: Requirement from Kysely */ -import type { Kysely } from 'kysely'; -import { rollbackMigration, syncDatabaseSchema, type TableDefinition } from '../utils/migrator.js'; +import type { Kysely } from '@withstudiocms/kysely/kysely'; +import { + rollbackMigration, + syncDatabaseSchema, + type TableDefinition, +} from '@withstudiocms/kysely/utils/migrator'; import { schemaDefinition as previousSchema } from './20251130T150847_drop_deprecated.js'; diff --git a/packages/@withstudiocms/kysely/src/migrator.ts b/packages/@withstudiocms/sdk/src/migrator.ts similarity index 71% rename from packages/@withstudiocms/kysely/src/migrator.ts rename to packages/@withstudiocms/sdk/src/migrator.ts index 2159d5449c57..714d679698e4 100644 --- a/packages/@withstudiocms/kysely/src/migrator.ts +++ b/packages/@withstudiocms/sdk/src/migrator.ts @@ -1,15 +1,16 @@ /// /** biome-ignore-all lint/suspicious/noExplicitAny: Kysely Requirement */ -import type { Dialect, Kysely, Migration } from 'kysely'; -import { makeMigratorLive } from './core/migrator.js'; -// TODO: Migrate custom migrations to the StudioCMS SDK package -// These where not meant to be here long term, but are here temporarily -// to facilitate the migration to Kysely without blocking early development. -// -// Note: when moving the migrations to the SDK package, don't forget to also move -// the migration files, and the utility script for creating new migrations. -// (i.e, packages/@withstudiocms/kysely/scripts/create-migration.ts) +import type { Effect } from '@withstudiocms/effect'; +import type { MigratorError } from '@withstudiocms/kysely/core/errors'; +import { makeMigratorLive } from '@withstudiocms/kysely/core/migrator'; +import type { + Dialect, + Kysely, + Migration, + MigrationInfo, + MigrationResultSet, +} from '@withstudiocms/kysely/kysely'; /** * Dynamically imports a migration module by its name. @@ -30,8 +31,7 @@ const importMigration = async (name: string): Promise => { throw new Error(`Migration not found: ${name}`); } - const { up, down } = await migrations[migrationPath](); - return { up, down }; + return await migrations[migrationPath](); } return await import(`./migrations/${name}.js`).then(({ up, down }) => ({ up, down })); @@ -60,5 +60,15 @@ const migrationIndex: Record = { * const migrator = getMigratorLive(yourDriver); * await migrator.migrateToLatest(); */ -export const getMigratorLive = (dialect: Dialect) => - makeMigratorLive(dialect, migrationIndex); +export const getMigratorLive = ( + dialect: Dialect +): Effect.Effect< + { + readonly toLatest: Effect.Effect; + readonly down: Effect.Effect; + readonly up: Effect.Effect; + readonly status: Effect.Effect; + }, + MigratorError, + never +> => makeMigratorLive(dialect, migrationIndex); diff --git a/packages/studiocms/src/cli/migrator/index.ts b/packages/studiocms/src/cli/migrator/index.ts index 5d4e18a10808..9ba7daf1f8a1 100644 --- a/packages/studiocms/src/cli/migrator/index.ts +++ b/packages/studiocms/src/cli/migrator/index.ts @@ -4,7 +4,7 @@ import { label } from '@withstudiocms/cli-kit/messages'; import { Cli, Effect, runEffect } from '@withstudiocms/effect'; import { intro, log, outro, select, tasks } from '@withstudiocms/effect/clack'; import type { MigrationInfo, MigrationResult } from '@withstudiocms/kysely/kysely'; -import { getMigratorLive } from '@withstudiocms/kysely/migrator'; +import { getMigratorLive } from '@withstudiocms/sdk/migrator'; import { getDbDriver, parseDbDialect } from '../../db/index.js'; import { genLogger } from '../../effect.js'; import type { StudioCMSConfig } from '../../schemas/index.js'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cbf41fa9d224..bae354abea9f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -949,9 +949,6 @@ importers: '@types/pg': specifier: catalog:kysely version: 8.16.0 - tsx: - specifier: ^4.21.0 - version: 4.21.0 packages/@withstudiocms/sdk: dependencies: @@ -974,6 +971,9 @@ importers: '@types/node': specifier: 'catalog:' version: 22.19.3 + tsx: + specifier: ^4.21.0 + version: 4.21.0 packages/@withstudiocms/template-lang: devDependencies: