diff --git a/apps/backend/migrations/deployment.json b/apps/backend/migrations/deployment.json new file mode 100644 index 000000000..2908db73a --- /dev/null +++ b/apps/backend/migrations/deployment.json @@ -0,0 +1,199 @@ +[ + { + "idx": 0, + "when": 1723098293272, + "tag": "0000_lively_warstar", + "hash": "b8aef406c9ddaadba238f67801ba00437abcf19b75a9ebce747d77de499b4e2e", + "sql": [ + "CREATE TABLE `undb_api_token` (\r`id` text PRIMARY KEY NOT NULL,\r`name` text NOT NULL,\r`user_id` text NOT NULL,\r`space_id` text NOT NULL,\r`token` text NOT NULL,\rFOREIGN KEY (`user_id`) REFERENCES `undb_user`(`id`) ON UPDATE no action ON DELETE no action,\rFOREIGN KEY (`space_id`) REFERENCES `undb_space`(`id`) ON UPDATE no action ON DELETE no action\r);", + "CREATE TABLE `undb_attachment_mapping` (\r`attachment_id` text NOT NULL,\r`table_id` text NOT NULL,\r`record_id` text NOT NULL,\r`field_id` text NOT NULL,\rPRIMARY KEY(`attachment_id`, `field_id`, `record_id`, `table_id`),\rFOREIGN KEY (`attachment_id`) REFERENCES `undb_attachment`(`id`) ON UPDATE no action ON DELETE no action,\rFOREIGN KEY (`table_id`) REFERENCES `undb_table`(`id`) ON UPDATE no action ON DELETE no action\r);", + "CREATE TABLE `undb_attachment` (\r`id` text PRIMARY KEY NOT NULL,\r`name` text NOT NULL,\r`size` integer NOT NULL,\r`mime_type` text NOT NULL,\r`url` text NOT NULL,\r`token` text,\r`created_at` integer NOT NULL,\r`created_by` text NOT NULL,\r`space_id` text NOT NULL,\rFOREIGN KEY (`created_by`) REFERENCES `undb_user`(`id`) ON UPDATE no action ON DELETE no action,\rFOREIGN KEY (`space_id`) REFERENCES `undb_space`(`id`) ON UPDATE no action ON DELETE no action\r);", + "CREATE TABLE `undb_audit` (\r`id` text PRIMARY KEY NOT NULL,\r`timestamp` integer NOT NULL,\r`detail` text,\r`meta` text,\r`op` text NOT NULL,\r`table_id` text NOT NULL,\r`record_id` text NOT NULL,\r`operator_id` text NOT NULL,\r`space_id` text NOT NULL,\rFOREIGN KEY (`space_id`) REFERENCES `undb_space`(`id`) ON UPDATE no action ON DELETE no action\r);", + "CREATE TABLE `undb_base` (\r`id` text PRIMARY KEY NOT NULL,\r`name` text NOT NULL,\r`space_id` text NOT NULL,\r`created_at` text DEFAULT (CURRENT_TIMESTAMP) NOT NULL,\r`created_by` text NOT NULL,\r`updated_at` text NOT NULL,\r`updated_by` text NOT NULL,\rFOREIGN KEY (`space_id`) REFERENCES `undb_space`(`id`) ON UPDATE no action ON DELETE no action,\rFOREIGN KEY (`created_by`) REFERENCES `undb_user`(`id`) ON UPDATE no action ON DELETE no action,\rFOREIGN KEY (`updated_by`) REFERENCES `undb_user`(`id`) ON UPDATE no action ON DELETE no action\r);", + "CREATE TABLE `undb_email_verification_code` (\r`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,\r`code` text NOT NULL,\r`user_id` text,\r`email` text NOT NULL,\r`expires_at` integer NOT NULL,\rFOREIGN KEY (`user_id`) REFERENCES `undb_user`(`id`) ON UPDATE no action ON DELETE no action\r);", + "CREATE TABLE `undb_invitation` (\r`id` text PRIMARY KEY NOT NULL,\r`email` text NOT NULL,\r`role` text NOT NULL,\r`status` text NOT NULL,\r`space_id` text NOT NULL,\r`invited_at` integer NOT NULL,\r`inviter_id` text NOT NULL,\rFOREIGN KEY (`space_id`) REFERENCES `undb_space`(`id`) ON UPDATE no action ON DELETE no action,\rFOREIGN KEY (`inviter_id`) REFERENCES `undb_user`(`id`) ON UPDATE no action ON DELETE no action\r);", + "CREATE TABLE `undb_oauth_account` (\r`provider_id` text NOT NULL,\r`provider_user_id` text NOT NULL,\r`user_id` text NOT NULL,\rPRIMARY KEY(`provider_id`, `provider_user_id`),\rFOREIGN KEY (`user_id`) REFERENCES `undb_user`(`id`) ON UPDATE no action ON DELETE no action\r);", + "CREATE TABLE `undb_outbox` (\r`id` text PRIMARY KEY NOT NULL,\r`payload` text NOT NULL,\r`meta` text,\r`timestamp` integer NOT NULL,\r`operator_id` text NOT NULL,\r`name` text NOT NULL,\r`space_id` text NOT NULL,\rFOREIGN KEY (`space_id`) REFERENCES `undb_space`(`id`) ON UPDATE no action ON DELETE no action\r);", + "CREATE TABLE `undb_reference_id_mapping` (\r`field_id` text NOT NULL,\r`table_id` text NOT NULL,\r`symmetric_field_id` text NOT NULL,\r`foreign_table_id` text NOT NULL,\rFOREIGN KEY (`table_id`) REFERENCES `undb_table`(`id`) ON UPDATE no action ON DELETE no action,\rFOREIGN KEY (`foreign_table_id`) REFERENCES `undb_table`(`id`) ON UPDATE no action ON DELETE no action\r);", + "CREATE TABLE `undb_rollup_id_mapping` (\r`field_id` text NOT NULL,\r`table_id` text NOT NULL,\r`rollup_id` text NOT NULL,\r`rollup_table_id` text NOT NULL,\rPRIMARY KEY(`field_id`, `rollup_id`),\rFOREIGN KEY (`table_id`) REFERENCES `undb_table`(`id`) ON UPDATE no action ON DELETE no action,\rFOREIGN KEY (`rollup_table_id`) REFERENCES `undb_table`(`id`) ON UPDATE no action ON DELETE no action\r);", + "CREATE TABLE `undb_session` (\r`id` text PRIMARY KEY NOT NULL,\r`user_id` text NOT NULL,\r`expires_at` integer NOT NULL,\r`space_id` text NOT NULL,\rFOREIGN KEY (`user_id`) REFERENCES `undb_user`(`id`) ON UPDATE no action ON DELETE no action,\rFOREIGN KEY (`space_id`) REFERENCES `undb_space`(`id`) ON UPDATE no action ON DELETE no action\r);", + "CREATE TABLE `undb_share` (\r`id` text PRIMARY KEY NOT NULL,\r`target_type` text NOT NULL,\r`target_id` text NOT NULL,\r`enabled` integer NOT NULL,\r`space_id` text NOT NULL,\rFOREIGN KEY (`space_id`) REFERENCES `undb_space`(`id`) ON UPDATE no action ON DELETE no action\r);", + "CREATE TABLE `undb_space` (\r`id` text PRIMARY KEY NOT NULL,\r`name` text,\r`is_personal` integer NOT NULL,\r`avatar` text,\r`created_at` text DEFAULT (CURRENT_TIMESTAMP) NOT NULL,\r`created_by` text NOT NULL,\r`updated_at` text NOT NULL,\r`updated_by` text NOT NULL,\r`deleted_at` integer,\r`deleted_by` text,\rFOREIGN KEY (`created_by`) REFERENCES `undb_user`(`id`) ON UPDATE no action ON DELETE no action,\rFOREIGN KEY (`updated_by`) REFERENCES `undb_user`(`id`) ON UPDATE no action ON DELETE no action,\rFOREIGN KEY (`deleted_by`) REFERENCES `undb_user`(`id`) ON UPDATE no action ON DELETE no action\r);", + "CREATE TABLE `undb_space_member` (\r`id` text PRIMARY KEY NOT NULL,\r`user_id` text NOT NULL,\r`role` text NOT NULL,\r`space_id` text NOT NULL,\rFOREIGN KEY (`user_id`) REFERENCES `undb_user`(`id`) ON UPDATE no action ON DELETE no action,\rFOREIGN KEY (`space_id`) REFERENCES `undb_space`(`id`) ON UPDATE no action ON DELETE no action\r);", + "CREATE TABLE `undb_table_id_mapping` (\r`table_id` text NOT NULL,\r`subject_id` text NOT NULL,\rPRIMARY KEY(`subject_id`, `table_id`),\rFOREIGN KEY (`table_id`) REFERENCES `undb_table`(`id`) ON UPDATE no action ON DELETE no action\r);", + "CREATE TABLE `undb_table` (\r`id` text PRIMARY KEY NOT NULL,\r`name` text NOT NULL,\r`base_id` text NOT NULL,\r`space_id` text NOT NULL,\r`schema` text NOT NULL,\r`views` text NOT NULL,\r`forms` text,\r`rls` text,\r`created_at` text DEFAULT (CURRENT_TIMESTAMP) NOT NULL,\r`created_by` text NOT NULL,\r`updated_at` text NOT NULL,\r`updated_by` text NOT NULL,\rFOREIGN KEY (`base_id`) REFERENCES `undb_base`(`id`) ON UPDATE no action ON DELETE no action,\rFOREIGN KEY (`space_id`) REFERENCES `undb_space`(`id`) ON UPDATE no action ON DELETE no action,\rFOREIGN KEY (`created_by`) REFERENCES `undb_user`(`id`) ON UPDATE no action ON DELETE no action,\rFOREIGN KEY (`updated_by`) REFERENCES `undb_user`(`id`) ON UPDATE no action ON DELETE no action\r);", + "CREATE TABLE `undb_user` (\r`id` text PRIMARY KEY NOT NULL,\r`username` text NOT NULL,\r`email` text NOT NULL,\r`email_verified` integer DEFAULT false NOT NULL,\r`password` text NOT NULL,\r`avatar` text\r);", + "CREATE TABLE `undb_webhook` (\r`id` text PRIMARY KEY NOT NULL,\r`name` text NOT NULL,\r`url` text NOT NULL,\r`method` text NOT NULL,\r`enabled` integer NOT NULL,\r`table_id` text NOT NULL,\r`headers` text NOT NULL,\r`condition` text,\r`event` text NOT NULL,\r`space_id` text NOT NULL,\rFOREIGN KEY (`table_id`) REFERENCES `undb_table`(`id`) ON UPDATE no action ON DELETE no action,\rFOREIGN KEY (`space_id`) REFERENCES `undb_space`(`id`) ON UPDATE no action ON DELETE no action\r);", + "CREATE UNIQUE INDEX `undb_api_token_user_id_unique` ON `undb_api_token` (`user_id`);", + "CREATE UNIQUE INDEX `undb_api_token_token_unique` ON `undb_api_token` (`token`);", + "CREATE INDEX `api_token_space_id_idx` ON `undb_api_token` (`space_id`);", + "CREATE INDEX `api_token_user_id_idx` ON `undb_api_token` (`user_id`);", + "CREATE INDEX `attachment_size_idx` ON `undb_attachment` (`size`);", + "CREATE INDEX `attachment_space_id_idx` ON `undb_attachment` (`space_id`);", + "CREATE INDEX `audit_table_id_idx` ON `undb_audit` (`table_id`);", + "CREATE INDEX `audit_space_id_idx` ON `undb_audit` (`space_id`);", + "CREATE INDEX `audit_record_id_idx` ON `undb_audit` (`record_id`);", + "CREATE INDEX `base_space_id_idx` ON `undb_base` (`space_id`);", + "CREATE UNIQUE INDEX `base_name_unique_idx` ON `undb_base` (`name`,`space_id`);", + "CREATE UNIQUE INDEX `undb_email_verification_code_user_id_unique` ON `undb_email_verification_code` (`user_id`);", + "CREATE UNIQUE INDEX `undb_invitation_email_unique` ON `undb_invitation` (`email`);", + "CREATE INDEX `invitation_space_id_idx` ON `undb_invitation` (`space_id`);", + "CREATE INDEX `outbox_space_id_idx` ON `undb_outbox` (`space_id`);", + "CREATE UNIQUE INDEX `reference_id_mapping_unique_idx` ON `undb_reference_id_mapping` (`field_id`,`table_id`,`symmetric_field_id`,`foreign_table_id`);", + "CREATE INDEX `share_space_id_idx` ON `undb_share` (`space_id`);", + "CREATE UNIQUE INDEX `share_unique_idx` ON `undb_share` (`target_type`,`target_id`);", + "CREATE INDEX `space_name_idx` ON `undb_space` (`name`);", + "CREATE UNIQUE INDEX `space_member_unique_idx` ON `undb_space_member` (`user_id`,`space_id`);", + "CREATE INDEX `table_base_id_idx` ON `undb_table` (`base_id`);", + "CREATE INDEX `table_space_id_idx` ON `undb_table` (`space_id`);", + "CREATE UNIQUE INDEX `table_name_unique_idx` ON `undb_table` (`name`,`base_id`);", + "CREATE UNIQUE INDEX `undb_user_email_unique` ON `undb_user` (`email`);", + "CREATE INDEX `user_username_idx` ON `undb_user` (`username`);", + "CREATE INDEX `user_email_idx` ON `undb_user` (`email`);", + "CREATE INDEX `webhook_table_id_idx` ON `undb_webhook` (`table_id`);", + "CREATE INDEX `webhook_space_id_idx` ON `undb_webhook` (`space_id`);", + "CREATE INDEX `webhook_url_idx` ON `undb_webhook` (`url`);" + ] + }, + { + "idx": 1, + "when": 1723706193281, + "tag": "0001_familiar_joshua_kane", + "hash": "449cb4879eb4bfe997b556ae5a80e48267c76c76b1777160d9a9f3b5b31ac108", + "sql": [ + "CREATE TABLE `undb_password_reset_token` (\r`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,\r`token` text NOT NULL,\r`user_id` text NOT NULL,\r`expires_at` integer NOT NULL,\rFOREIGN KEY (`user_id`) REFERENCES `undb_user`(`id`) ON UPDATE no action ON DELETE no action\r);", + "CREATE UNIQUE INDEX `undb_password_reset_token_token_unique` ON `undb_password_reset_token` (`token`);", + "CREATE INDEX `password_reset_token_user_id_idx` ON `undb_password_reset_token` (`user_id`);" + ] + }, + { + "idx": 2, + "when": 1723731591583, + "tag": "0002_fixed_lockjaw", + "hash": "01e006b7337199bc08c073b2fb752f1653b3d0e7827aa7ec8bb9b8d237cf3bf3", + "sql": [ + "DROP INDEX IF EXISTS `undb_invitation_email_unique`;", + "CREATE UNIQUE INDEX `invitation_unique_idx` ON `undb_invitation` (`email`,`space_id`);" + ] + }, + { + "idx": 3, + "when": 1723898576164, + "tag": "0003_dry_starhawk", + "hash": "806733d43aa2f171fabae7d64792ad1df65e3e77b00e7e1275d2ffa864969f6e", + "sql": [ + "ALTER TABLE `undb_base` ADD `allow_template` integer DEFAULT false NOT NULL;" + ] + }, + { + "idx": 4, + "when": 1724054589804, + "tag": "0004_tricky_phil_sheldon", + "hash": "5f712f6dc5b40f3ac407cf989b2b5a7ed865691799b7e7bb4fc68da24fa2d952", + "sql": [ + "DROP INDEX IF EXISTS `undb_api_token_user_id_unique`;" + ] + }, + { + "idx": 5, + "when": 1724391158180, + "tag": "0005_narrow_khan", + "hash": "ebf973841c3869a871e21e0399de8ae6e9dcc09259a812032f0aa4cfda4fd12c", + "sql": [ + "ALTER TABLE `undb_base` DROP COLUMN `allow_template`;" + ] + }, + { + "idx": 6, + "when": 1728358607342, + "tag": "0006_mature_madame_web", + "hash": "51995ae2bf0f8a52b57786978a421040330fb22121753aa6fbb0a51cb013ebde", + "sql": [ + "ALTER TABLE `undb_outbox` ADD `user_id` text;", + "ALTER TABLE `undb_outbox` DROP COLUMN `operator_id`;" + ] + }, + { + "idx": 7, + "when": 1728539365470, + "tag": "0007_steep_dragon_lord", + "hash": "2a1edb5e858eb7018e6a9c5e25c509b35e28d1e4f812c53f7b3a937476517923", + "sql": [ + "ALTER TABLE `undb_table` ADD `widgets` text;" + ] + }, + { + "idx": 8, + "when": 1728814857375, + "tag": "0008_bored_terror", + "hash": "5628ded36ba9889dc55a3ba938722857bde7537039d5cc1aec3120204f9f15c1", + "sql": [ + "CREATE TABLE `undb_dashboard` (\r`id` text PRIMARY KEY NOT NULL,\r`name` text NOT NULL,\r`base_id` text NOT NULL,\r`space_id` text NOT NULL,\r`created_at` text DEFAULT (CURRENT_TIMESTAMP) NOT NULL,\r`created_by` text NOT NULL,\r`updated_at` text NOT NULL,\r`updated_by` text NOT NULL,\rFOREIGN KEY (`base_id`) REFERENCES `undb_base`(`id`) ON UPDATE no action ON DELETE no action,\rFOREIGN KEY (`space_id`) REFERENCES `undb_space`(`id`) ON UPDATE no action ON DELETE no action,\rFOREIGN KEY (`created_by`) REFERENCES `undb_user`(`id`) ON UPDATE no action ON DELETE no action,\rFOREIGN KEY (`updated_by`) REFERENCES `undb_user`(`id`) ON UPDATE no action ON DELETE no action\r);", + "CREATE INDEX `dashboard_base_id_idx` ON `undb_dashboard` (`base_id`);", + "CREATE INDEX `dashboard_space_id_idx` ON `undb_dashboard` (`space_id`);", + "CREATE UNIQUE INDEX `dashboard_name_unique_idx` ON `undb_dashboard` (`name`,`base_id`);" + ] + }, + { + "idx": 9, + "when": 1728874533782, + "tag": "0009_workable_scorpion", + "hash": "f29952122ea89f1b717963b62111302ab5321e6b1c777cf675dd9ee18313dbf5", + "sql": [ + "ALTER TABLE `undb_dashboard` ADD `widgets` text;", + "ALTER TABLE `undb_dashboard` ADD `layout` text;" + ] + }, + { + "idx": 10, + "when": 1729306799169, + "tag": "0010_nostalgic_nehzno", + "hash": "c0ffe9e7e3b0523d65603d7cd4ee444fbc8bae9b4f1959741b4c01085c345d44", + "sql": [ + "CREATE TABLE `undb_dashboard_table_id_mapping` (`dashboard_id` text NOT NULL,`table_id` text NOT NULL,PRIMARY KEY(`dashboard_id`, `table_id`),FOREIGN KEY (`dashboard_id`) REFERENCES `undb_dashboard`(`id`) ON UPDATE no action ON DELETE no action,FOREIGN KEY (`table_id`) REFERENCES `undb_table`(`id`) ON UPDATE no action ON DELETE no action);" + ] + }, + { + "idx": 11, + "when": 1729514235861, + "tag": "0011_serious_marvex", + "hash": "78f2cb161b43636a6e0758dda3e0ada24f45103d395b2a66c21f699f9374eea6", + "sql": [ + "PRAGMA foreign_keys=OFF;", + "CREATE TABLE `__new_undb_reference_id_mapping` (\r`field_id` text NOT NULL,\r`table_id` text NOT NULL,\r`symmetric_field_id` text,\r`foreign_table_id` text NOT NULL,\rFOREIGN KEY (`table_id`) REFERENCES `undb_table`(`id`) ON UPDATE no action ON DELETE no action,\rFOREIGN KEY (`foreign_table_id`) REFERENCES `undb_table`(`id`) ON UPDATE no action ON DELETE no action\r);", + "INSERT INTO `__new_undb_reference_id_mapping`(\"field_id\", \"table_id\", \"symmetric_field_id\", \"foreign_table_id\") SELECT \"field_id\", \"table_id\", \"symmetric_field_id\", \"foreign_table_id\" FROM `undb_reference_id_mapping`;", + "DROP TABLE `undb_reference_id_mapping`;", + "ALTER TABLE `__new_undb_reference_id_mapping` RENAME TO `undb_reference_id_mapping`;", + "PRAGMA foreign_keys=ON;", + "CREATE UNIQUE INDEX `reference_id_mapping_unique_idx` ON `undb_reference_id_mapping` (`field_id`,`table_id`,`symmetric_field_id`,`foreign_table_id`);" + ] + }, + { + "idx": 12, + "when": 1729559227374, + "tag": "0012_lying_tomorrow_man", + "hash": "0f505e5a2716077ef9c514c943933273ea18a1264781a490feefb3f0059ce6cc", + "sql": [ + "ALTER TABLE `undb_dashboard` ADD `description` text;" + ] + }, + { + "idx": 13, + "when": 1730979840099, + "tag": "0013_lovely_mordo", + "hash": "59f5936ab2e03fbff473d3d56883ecce0832b71521b02bfa2ad2907d242dc00b", + "sql": [ + "PRAGMA foreign_keys=OFF;", + "CREATE TABLE `__new_undb_reference_id_mapping` (`field_id` text NOT NULL,`table_id` text NOT NULL,`symmetric_field_id` text,`foreign_table_id` text NOT NULL);", + "INSERT INTO `__new_undb_reference_id_mapping`(\"field_id\", \"table_id\", \"symmetric_field_id\", \"foreign_table_id\") SELECT \"field_id\", \"table_id\", \"symmetric_field_id\", \"foreign_table_id\" FROM `undb_reference_id_mapping`;", + "DROP TABLE `undb_reference_id_mapping`;", + "ALTER TABLE `__new_undb_reference_id_mapping` RENAME TO `undb_reference_id_mapping`;", + "PRAGMA foreign_keys=ON;", + "CREATE UNIQUE INDEX `reference_id_mapping_unique_idx` ON `undb_reference_id_mapping` (`field_id`,`table_id`,`symmetric_field_id`,`foreign_table_id`);", + "CREATE TABLE `__new_undb_rollup_id_mapping` (`field_id` text NOT NULL,`table_id` text NOT NULL,`rollup_id` text NOT NULL,`rollup_table_id` text NOT NULL,PRIMARY KEY(`field_id`, `rollup_id`));", + "INSERT INTO `__new_undb_rollup_id_mapping`(\"field_id\", \"table_id\", \"rollup_id\", \"rollup_table_id\") SELECT \"field_id\", \"table_id\", \"rollup_id\", \"rollup_table_id\" FROM `undb_rollup_id_mapping`;", + "DROP TABLE `undb_rollup_id_mapping`;", + "ALTER TABLE `__new_undb_rollup_id_mapping` RENAME TO `undb_rollup_id_mapping`;" + ] + } +] \ No newline at end of file diff --git a/apps/frontend/src/routes/(authed)/+layout.ts b/apps/frontend/src/routes/(authed)/+layout.ts index b9c7118c9..6cb951e19 100644 --- a/apps/frontend/src/routes/(authed)/+layout.ts +++ b/apps/frontend/src/routes/(authed)/+layout.ts @@ -8,6 +8,23 @@ export const load: LayoutLoad = async (event) => { // const search = new URLSearchParams({ redirect: redirectURL }) + // const db = await createSqljsDatabase() + // const drizzleDB = await createDrizzleDatabase(db) + // migrate(drizzleDB) + + // const qb = await createSqljsQueryBuilder(db) + // await qb + // .insertInto("undb_user") + // .values({ + // id: "1", + // email: "test@test.com", + // password: "password", + // username: "test", + // }) + // .execute() + // const users = await qb.selectFrom("undb_user").selectAll().execute() + // console.log({ users }) + const me = await event.fetch("/api/me") if (me.redirected) { throw redirect(301, me.url) diff --git a/package.json b/package.json index f44b79f94..5053fbf8d 100644 --- a/package.json +++ b/package.json @@ -15,10 +15,11 @@ "format": "prettier --write \"**/*.{ts,tsx,md,svelte}\"", "studio": "drizzle-kit studio --config drizzle.config.ts", "studio:turso": "drizzle-kit studio --config drizzle.turso.config.ts", - "generate": "bun generate:db", + "generate": "run-s generate:db migrate:deploy", "generate:db": "drizzle-kit generate --config drizzle.config.ts", "migrate:db": "drizzle-kit push --config drizzle.config.ts", "move-assets": "bun run ./scripts/move-assets.ts", + "migrate:deploy": "bun run ./scripts/migrate.ts", "prepare": "husky || echo 1" }, "devDependencies": { diff --git a/packages/persistence/src/api-token/api-token.query-repository.ts b/packages/persistence/src/api-token/api-token.query-repository.ts index 487f475bf..159468b95 100644 --- a/packages/persistence/src/api-token/api-token.query-repository.ts +++ b/packages/persistence/src/api-token/api-token.query-repository.ts @@ -1,8 +1,8 @@ import { singleton } from "@undb/di" import { None, Some, type Option } from "@undb/domain" import { type ApiTokenSpecification, type IApiTokenDTO, type IApiTokenQueryRepository } from "@undb/openapi" -import type { IQueryBuilder } from "../qb" import { injectQueryBuilder } from "../qb.provider" +import type { IQueryBuilder } from "../qb.server" import { ApiTokenFilterVisitor } from "./api-token.filter-visitor" @singleton() diff --git a/packages/persistence/src/api-token/api-token.repository.ts b/packages/persistence/src/api-token/api-token.repository.ts index 1f9a4fd27..de30bfeb0 100644 --- a/packages/persistence/src/api-token/api-token.repository.ts +++ b/packages/persistence/src/api-token/api-token.repository.ts @@ -2,8 +2,8 @@ import { singleton } from "@undb/di" import type { ApiTokenDo, IApiTokenRepository } from "@undb/openapi" import type { ITxContext } from "../ctx.interface" import { injectTxCTX } from "../ctx.provider" -import type { IQueryBuilder } from "../qb" import { injectQueryBuilder } from "../qb.provider" +import type { IQueryBuilder } from "../qb.server" @singleton() export class ApiTokenRepository implements IApiTokenRepository { diff --git a/packages/persistence/src/audit/audit.mapper.ts b/packages/persistence/src/audit/audit.mapper.ts index becac4745..ef9e4534b 100644 --- a/packages/persistence/src/audit/audit.mapper.ts +++ b/packages/persistence/src/audit/audit.mapper.ts @@ -4,7 +4,7 @@ import { singleton } from "@undb/di" import type { Mapper } from "@undb/domain" import { pick } from "radash" import type { Audit } from "../db" -import { json } from "../qb" +import { json } from "../qb.server" @singleton() export class AuditMapper implements Mapper { diff --git a/packages/persistence/src/audit/audit.query-repository.ts b/packages/persistence/src/audit/audit.query-repository.ts index dd19c1de7..816bbf2a5 100644 --- a/packages/persistence/src/audit/audit.query-repository.ts +++ b/packages/persistence/src/audit/audit.query-repository.ts @@ -1,8 +1,8 @@ import type { AuditSpecification, IAuditDTO, IAuditQueryRepository } from "@undb/audit" import { injectContext, type IContext } from "@undb/context" import { inject, singleton } from "@undb/di" -import type { IQueryBuilder } from "../qb" import { injectQueryBuilder } from "../qb.provider" +import type { IQueryBuilder } from "../qb.server" import { AuditFilterVisitor } from "./audit.filter-visitor" import { AuditMapper } from "./audit.mapper" diff --git a/packages/persistence/src/audit/audit.repository.ts b/packages/persistence/src/audit/audit.repository.ts index ed5e2685c..5cdef9474 100644 --- a/packages/persistence/src/audit/audit.repository.ts +++ b/packages/persistence/src/audit/audit.repository.ts @@ -2,8 +2,8 @@ import type { Audit, AuditSpecification, IAuditRepository } from "@undb/audit" import { injectContext, type IContext } from "@undb/context" import { inject, singleton } from "@undb/di" import type { Option } from "@undb/domain" -import type { IQueryBuilder } from "../qb" import { injectQueryBuilder } from "../qb.provider" +import type { IQueryBuilder } from "../qb.server" import { AuditMapper } from "./audit.mapper" @singleton() diff --git a/packages/persistence/src/base/base.query-repository.ts b/packages/persistence/src/base/base.query-repository.ts index 10f39e116..778dad504 100644 --- a/packages/persistence/src/base/base.query-repository.ts +++ b/packages/persistence/src/base/base.query-repository.ts @@ -1,8 +1,8 @@ import { WithBaseId, type IBaseDTO, type IBaseQueryRepository, type IBaseSpecification } from "@undb/base" import { inject, singleton } from "@undb/di" import { None, Some, type Option } from "@undb/domain" -import type { IQueryBuilder } from "../qb" import { injectQueryBuilder } from "../qb.provider" +import type { IQueryBuilder } from "../qb.server" import { BaseFilterVisitor } from "./base.filter-visitor" import { BaseMapper } from "./base.mapper" diff --git a/packages/persistence/src/base/base.repository.ts b/packages/persistence/src/base/base.repository.ts index 1109beb21..0b5691bee 100644 --- a/packages/persistence/src/base/base.repository.ts +++ b/packages/persistence/src/base/base.repository.ts @@ -14,8 +14,8 @@ import { None, Some, type Option } from "@undb/domain" import { injectTableRepository, TableBaseIdSpecification, type ITableRepository } from "@undb/table" import type { ITxContext } from "../ctx.interface" import { injectTxCTX } from "../ctx.provider" -import type { IQueryBuilder } from "../qb" import { injectQueryBuilder } from "../qb.provider" +import type { IQueryBuilder } from "../qb.server" import { UnderlyingTableService } from "../underlying/underlying-table.service" import { BaseFilterVisitor } from "./base.filter-visitor" import { BaseMapper } from "./base.mapper" diff --git a/packages/persistence/src/client.ts b/packages/persistence/src/client.ts index f45347cc7..fec190714 100644 --- a/packages/persistence/src/client.ts +++ b/packages/persistence/src/client.ts @@ -1,2 +1,3 @@ export { isIdbSupported, isOpfsSupported } from "kysely-wasqlite-worker" +export * from "./migrate.client" export * from "./qb.client" diff --git a/packages/persistence/src/ctx.ts b/packages/persistence/src/ctx.ts index 10d74b063..145399377 100644 --- a/packages/persistence/src/ctx.ts +++ b/packages/persistence/src/ctx.ts @@ -1,8 +1,8 @@ import { inject, singleton } from "@undb/di" import { AsyncLocalStorage } from "node:async_hooks" import type { ITxContext } from "./ctx.interface" -import type { IQueryBuilder } from "./qb" import { injectQueryBuilder } from "./qb.provider" +import type { IQueryBuilder } from "./qb.server" import type { AnonymousTx, Tx } from "./qb.type" export interface TxContext { diff --git a/packages/persistence/src/dashboard/dashboard.filter-visitor.ts b/packages/persistence/src/dashboard/dashboard.filter-visitor.ts index f03e5c94a..089b73eb2 100644 --- a/packages/persistence/src/dashboard/dashboard.filter-visitor.ts +++ b/packages/persistence/src/dashboard/dashboard.filter-visitor.ts @@ -16,7 +16,7 @@ import type { DuplicatedDashboardSpecification } from "@undb/dashboard/src/speci import type { ExpressionBuilder } from "kysely" import { AbstractQBVisitor } from "../abstract-qb.visitor" import type { Database } from "../db" -import type { IQueryBuilder } from "../qb" +import type { IQueryBuilder } from "../qb.server" export class DashboardFilterVisitor extends AbstractQBVisitor implements IDashboardSpecVisitor { constructor( diff --git a/packages/persistence/src/dashboard/dashboard.mapper.ts b/packages/persistence/src/dashboard/dashboard.mapper.ts index 400228bd2..0ee936d48 100644 --- a/packages/persistence/src/dashboard/dashboard.mapper.ts +++ b/packages/persistence/src/dashboard/dashboard.mapper.ts @@ -2,7 +2,7 @@ import { DashboardFactory, type Dashboard as DashboardDo, type IDashboardDTO } f import { singleton } from "@undb/di" import type { Mapper } from "@undb/domain" import type { Dashboard } from "../db" -import { json } from "../qb" +import { json } from "../qb.server" @singleton() export class DashboardMapper implements Mapper { diff --git a/packages/persistence/src/dashboard/dashboard.mutate-visitor.ts b/packages/persistence/src/dashboard/dashboard.mutate-visitor.ts index 55989dcac..338e9aef6 100644 --- a/packages/persistence/src/dashboard/dashboard.mutate-visitor.ts +++ b/packages/persistence/src/dashboard/dashboard.mutate-visitor.ts @@ -14,7 +14,7 @@ import type { WithDashboardWidgets, } from "@undb/dashboard" import { AbstractQBMutationVisitor } from "../abstract-qb.visitor" -import { json, type IQueryBuilder } from "../qb" +import { json, type IQueryBuilder } from "../qb.server" export class DashboardMutateVisitor extends AbstractQBMutationVisitor implements IDashboardSpecVisitor { constructor( diff --git a/packages/persistence/src/dashboard/dashboard.query-repository.ts b/packages/persistence/src/dashboard/dashboard.query-repository.ts index 269f111ab..bc005fa77 100644 --- a/packages/persistence/src/dashboard/dashboard.query-repository.ts +++ b/packages/persistence/src/dashboard/dashboard.query-repository.ts @@ -8,8 +8,8 @@ import { inject, singleton } from "@undb/di" import { None, Some, type Option } from "@undb/domain" import type { ITxContext } from "../ctx.interface" import { injectTxCTX } from "../ctx.provider" -import type { IQueryBuilder } from "../qb" import { injectQueryBuilder } from "../qb.provider" +import type { IQueryBuilder } from "../qb.server" import { DashboardFilterVisitor } from "./dashboard.filter-visitor" import { DashboardMapper } from "./dashboard.mapper" import { DashboardReferenceVisitor } from "./dashboard.reference-visitor" diff --git a/packages/persistence/src/dashboard/dashboard.repository.ts b/packages/persistence/src/dashboard/dashboard.repository.ts index f24cc52b8..b759ea22c 100644 --- a/packages/persistence/src/dashboard/dashboard.repository.ts +++ b/packages/persistence/src/dashboard/dashboard.repository.ts @@ -12,8 +12,8 @@ import { inject, singleton } from "@undb/di" import { None, Some, type Option } from "@undb/domain" import type { ITxContext } from "../ctx.interface" import { injectTxCTX } from "../ctx.provider" -import type { IQueryBuilder } from "../qb" import { injectQueryBuilder } from "../qb.provider" +import type { IQueryBuilder } from "../qb.server" import { DashboardFilterVisitor } from "./dashboard.filter-visitor" import { DashboardMapper } from "./dashboard.mapper" import { DashboardMutateVisitor } from "./dashboard.mutate-visitor" diff --git a/packages/persistence/src/member/invitation.query-repository.ts b/packages/persistence/src/member/invitation.query-repository.ts index a9162b0e4..3aa56aae0 100644 --- a/packages/persistence/src/member/invitation.query-repository.ts +++ b/packages/persistence/src/member/invitation.query-repository.ts @@ -4,8 +4,8 @@ import { singleton } from "@undb/di" import { None, Some, type Option } from "@undb/domain" import type { ITxContext } from "../ctx.interface" import { injectTxCTX } from "../ctx.provider" -import type { IQueryBuilder } from "../qb" import { injectQueryBuilder } from "../qb.provider" +import type { IQueryBuilder } from "../qb.server" import { InvitationFilterVisitor } from "./invitation.filter-visitor" @singleton() diff --git a/packages/persistence/src/member/space-member.filter-visitor.ts b/packages/persistence/src/member/space-member.filter-visitor.ts index 9aa497ef3..91931924b 100644 --- a/packages/persistence/src/member/space-member.filter-visitor.ts +++ b/packages/persistence/src/member/space-member.filter-visitor.ts @@ -11,7 +11,7 @@ import type { WithSpaceMemberUserId } from "@undb/authz/src/space-member/specifi import type { ExpressionBuilder } from "kysely" import { AbstractQBVisitor } from "../abstract-qb.visitor" import type { Database } from "../db" -import type { IQueryBuilder } from "../qb" +import type { IQueryBuilder } from "../qb.server" export class SpaceMemberFilterVisitor extends AbstractQBVisitor implements ISpaceMemberVisitor { constructor( diff --git a/packages/persistence/src/member/space-member.query-repository.ts b/packages/persistence/src/member/space-member.query-repository.ts index ba6d83ce1..48d095706 100644 --- a/packages/persistence/src/member/space-member.query-repository.ts +++ b/packages/persistence/src/member/space-member.query-repository.ts @@ -1,8 +1,8 @@ import { SpaceMemberComositeSpecification, type ISpaceMemberDTO, type ISpaceMemberQueryRepository } from "@undb/authz" import { inject, singleton } from "@undb/di" import { None, Option, Some } from "@undb/domain" -import type { IQueryBuilder } from "../qb" import { injectQueryBuilder } from "../qb.provider" +import type { IQueryBuilder } from "../qb.server" import { MemberMapper } from "./member.mapper" import { SpaceMemberFilterVisitor } from "./space-member.filter-visitor" diff --git a/packages/persistence/src/member/space-member.repository.ts b/packages/persistence/src/member/space-member.repository.ts index 34850d718..d482b1f27 100644 --- a/packages/persistence/src/member/space-member.repository.ts +++ b/packages/persistence/src/member/space-member.repository.ts @@ -1,10 +1,10 @@ -import { SpaceMember,SpaceMemberComositeSpecification,type ISpaceMemberRepository } from "@undb/authz" +import { SpaceMember, SpaceMemberComositeSpecification, type ISpaceMemberRepository } from "@undb/authz" import { singleton } from "@undb/di" -import { None,Some,type Option } from "@undb/domain" +import { None, Some, type Option } from "@undb/domain" import type { ITxContext } from "../ctx.interface" import { injectTxCTX } from "../ctx.provider" -import type { IQueryBuilder } from "../qb" import { injectQueryBuilder } from "../qb.provider" +import type { IQueryBuilder } from "../qb.server" import { SpaceMemberFilterVisitor } from "./space-member.filter-visitor" @singleton() @@ -17,7 +17,8 @@ export class SpaceMemberRepository implements ISpaceMemberRepository { ) {} async exists(spec: SpaceMemberComositeSpecification): Promise { - const user = await this.txContext.getCurrentTransaction() + const user = await this.txContext + .getCurrentTransaction() .selectFrom("undb_space_member") .selectAll() .where((eb) => { @@ -31,7 +32,8 @@ export class SpaceMemberRepository implements ISpaceMemberRepository { } async findOne(spec: SpaceMemberComositeSpecification): Promise> { - const member = await this.txContext.getCurrentTransaction() + const member = await this.txContext + .getCurrentTransaction() .selectFrom("undb_space_member") .selectAll() .where((eb) => { @@ -60,7 +62,8 @@ export class SpaceMemberRepository implements ISpaceMemberRepository { } async insert(member: SpaceMember): Promise { const json = member.toJSON() - await this.txContext.getCurrentTransaction() + await this.txContext + .getCurrentTransaction() .insertInto("undb_space_member") .values({ id: json.id, diff --git a/packages/persistence/src/migrate.client.ts b/packages/persistence/src/migrate.client.ts new file mode 100644 index 000000000..e24324abb --- /dev/null +++ b/packages/persistence/src/migrate.client.ts @@ -0,0 +1,62 @@ +import { sql } from "drizzle-orm" +import { type SQLJsDatabase } from "drizzle-orm/sql-js" + +import config from "../../../apps/backend/migrations/deployment.json" + +export function migrate>(db: SQLJsDatabase) { + const TABLE_NAME = sql.identifier("__drizzle_migrations") + + db.run( + sql` + CREATE TABLE IF NOT EXISTS ${TABLE_NAME} ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + hash TEXT NOT NULL, + tag TEXT NOT NULL, + created_at INTEGER NOT NULL + ); + `, + ) + + const deployments = db.values<[number, string, string]>( + sql` + SELECT id, + hash, + created_at + FROM ${TABLE_NAME} + ORDER BY created_at DESC + LIMIT 1; + `, + ) + + const deployment = deployments.at(0) + + const migrations = config.filter((migration) => { + const timestamp = deployment?.at(2) + return !deployment || Number(timestamp) < migration.when + }) + + if (migrations.length === 0) { + return console.log("There, currently, are no migrations to deploy") + } + + db.transaction((tx) => { + migrations.forEach((migration, i) => { + console.info("%d. Deploying migration:", i + 1) + console.info(" TAG => %s", migration.tag) + console.info(" HASH => %s", migration.hash) + migration.sql.forEach((stmt) => tx.run(stmt)) + + tx.run( + sql` + INSERT INTO ${TABLE_NAME} ("hash", "created_at", "tag") VALUES ( + ${sql.raw(`'${migration.hash}'`)}, + ${sql.raw(`${migration.when}`)}, + ${sql.raw(`'${migration.tag}'`)} + ); + `, + ) + }) + }) + + console.info("Database up to date!") +} diff --git a/packages/persistence/src/migrate.ts b/packages/persistence/src/migrate.server.ts similarity index 100% rename from packages/persistence/src/migrate.ts rename to packages/persistence/src/migrate.server.ts diff --git a/packages/persistence/src/outbox.mapper.ts b/packages/persistence/src/outbox.mapper.ts index 7c065b8fd..8fcaf0bd8 100644 --- a/packages/persistence/src/outbox.mapper.ts +++ b/packages/persistence/src/outbox.mapper.ts @@ -1,7 +1,7 @@ import type { IContext } from "@undb/context" import type { BaseEvent } from "@undb/domain" import type { InsertOutbox } from "./db" -import { json } from "./qb" +import { json } from "./qb.server" export class OutboxMapper { static fromEvent(event: BaseEvent, context: IContext): InsertOutbox { diff --git a/packages/persistence/src/qb.client.ts b/packages/persistence/src/qb.client.ts index 95174a495..884cca409 100644 --- a/packages/persistence/src/qb.client.ts +++ b/packages/persistence/src/qb.client.ts @@ -1,12 +1,20 @@ +import { drizzle } from "drizzle-orm/sql-js" import { SqlJsDialect } from "kysely-wasm" import InitSqlJs from "sql.js" import { createQueryBuilderWithDialect } from "./qb.util" -export const createSqljsQueryBuilder = async () => { +export const createSqljsDatabase = async () => { const SQL = await InitSqlJs({ locateFile: (file) => `/${file}`, }) - const db = new SQL.Database() + return new SQL.Database() +} + +export const createDrizzleDatabase = async (db: InitSqlJs.Database) => { + return drizzle(db) +} + +export const createSqljsQueryBuilder = async (db: InitSqlJs.Database) => { const dialect = new SqlJsDialect({ async database() { return db diff --git a/packages/persistence/src/qb.ts b/packages/persistence/src/qb.server.ts similarity index 100% rename from packages/persistence/src/qb.ts rename to packages/persistence/src/qb.server.ts diff --git a/packages/persistence/src/record/record-query-creator-visitor.ts b/packages/persistence/src/record/record-query-creator-visitor.ts index 3d7824b82..aaad9b502 100644 --- a/packages/persistence/src/record/record-query-creator-visitor.ts +++ b/packages/persistence/src/record/record-query-creator-visitor.ts @@ -32,7 +32,7 @@ import { import type { FormulaField } from "@undb/table/src/modules/schema/fields/variants/formula-field" import { getTableName } from "drizzle-orm" import { sql, type QueryCreator, type SelectExpression } from "kysely" -import type { IRecordQueryBuilder } from "../qb" +import type { IRecordQueryBuilder } from "../qb.server" import { users } from "../tables" import { JoinTable } from "../underlying/reference/join-table" import { UnderlyingTable } from "../underlying/underlying-table" diff --git a/packages/persistence/src/record/record-query-spec-creator-visitor.ts b/packages/persistence/src/record/record-query-spec-creator-visitor.ts index e3335cc40..299280d29 100644 --- a/packages/persistence/src/record/record-query-spec-creator-visitor.ts +++ b/packages/persistence/src/record/record-query-spec-creator-visitor.ts @@ -63,7 +63,7 @@ import { type UserEqual, } from "@undb/table" import { type QueryCreator } from "kysely" -import type { IRecordQueryBuilder } from "../qb" +import type { IRecordQueryBuilder } from "../qb.server" export class RecordQuerySpecCreatorVisitor implements IRecordVisitor { private getFieldId(spec: RecordComositeSpecification) { diff --git a/packages/persistence/src/record/record-query.helper.ts b/packages/persistence/src/record/record-query.helper.ts index 48ab42df4..663b26f0c 100644 --- a/packages/persistence/src/record/record-query.helper.ts +++ b/packages/persistence/src/record/record-query.helper.ts @@ -5,8 +5,8 @@ import { FieldIdVo, type Field, type IViewSort, type RecordComositeSpecification import { sql, type ExpressionBuilder, type SelectQueryBuilder } from "kysely" import type { ITxContext } from "../ctx.interface" import { injectTxCTX } from "../ctx.provider" -import type { IRecordQueryBuilder } from "../qb" import { injectQueryBuilder } from "../qb.provider" +import type { IRecordQueryBuilder } from "../qb.server" import { UnderlyingTable } from "../underlying/underlying-table" import { RecordQueryCreatorVisitor } from "./record-query-creator-visitor" import { RecordQuerySpecCreatorVisitor } from "./record-query-spec-creator-visitor" diff --git a/packages/persistence/src/record/record.mutate-visitor.ts b/packages/persistence/src/record/record.mutate-visitor.ts index 3842d2ee3..f89d554b2 100644 --- a/packages/persistence/src/record/record.mutate-visitor.ts +++ b/packages/persistence/src/record/record.mutate-visitor.ts @@ -76,7 +76,7 @@ import { startOfDay, startOfToday, startOfTomorrow, startOfYesterday } from "dat import { sql, type ExpressionBuilder } from "kysely" import { unique } from "radash" import { AbstractQBMutationVisitor } from "../abstract-qb.visitor" -import type { IQueryBuilder, IRecordQueryBuilder } from "../qb" +import type { IQueryBuilder, IRecordQueryBuilder } from "../qb.server" import { JoinTable } from "../underlying/reference/join-table" import { getDateRangeFieldName } from "../underlying/underlying-table.util" diff --git a/packages/persistence/src/record/record.query-repository.ts b/packages/persistence/src/record/record.query-repository.ts index 2dc5a5ce5..35837fb10 100644 --- a/packages/persistence/src/record/record.query-repository.ts +++ b/packages/persistence/src/record/record.query-repository.ts @@ -27,8 +27,8 @@ import { } from "@undb/table" import { getTableName } from "drizzle-orm" import { sql, type AliasedExpression, type Expression, type ExpressionBuilder } from "kysely" -import type { IRecordQueryBuilder } from "../qb" import { injectQueryBuilder } from "../qb.provider" +import type { IRecordQueryBuilder } from "../qb.server" import { users } from "../tables" import { UnderlyingTable } from "../underlying/underlying-table" import { RecordQueryHelper } from "./record-query.helper" diff --git a/packages/persistence/src/server.ts b/packages/persistence/src/server.ts index 8a5748360..03e427cdc 100644 --- a/packages/persistence/src/server.ts +++ b/packages/persistence/src/server.ts @@ -5,9 +5,9 @@ export * from "./ctx" export * from "./dashboard" export { type Base, type Outbox, type Table } from "./db" export * from "./member" -export * from "./migrate" -export * from "./qb" +export * from "./migrate.server" export * from "./qb.provider" +export * from "./qb.server" export * from "./record" export * from "./share" export * from "./space" @@ -21,5 +21,5 @@ export { type Client } from "@libsql/client" export * from "./ctx.interface" export * from "./ctx.provider" export { SQLITE_CLIENT, createSqliteClient, createTursoClient, injectSqliteClient } from "./db-client" -export { type IQueryBuilder } from "./qb" export { injectQueryBuilder } from "./qb.provider" +export { type IQueryBuilder } from "./qb.server" diff --git a/packages/persistence/src/share/share.query-repository.ts b/packages/persistence/src/share/share.query-repository.ts index 328798245..bb3f139c8 100644 --- a/packages/persistence/src/share/share.query-repository.ts +++ b/packages/persistence/src/share/share.query-repository.ts @@ -1,8 +1,8 @@ import { inject, singleton } from "@undb/di" import { None, Some, type Option } from "@undb/domain" import type { IShareDTO, IShareQueryRepository, ShareSpecification } from "@undb/share" -import type { IQueryBuilder } from "../qb" import { injectQueryBuilder } from "../qb.provider" +import type { IQueryBuilder } from "../qb.server" import { ShareFilterVisitor } from "./share.filter-visitor" import { ShareMapper } from "./share.mapper" diff --git a/packages/persistence/src/share/share.repository.ts b/packages/persistence/src/share/share.repository.ts index f3fd92435..1a94ae88e 100644 --- a/packages/persistence/src/share/share.repository.ts +++ b/packages/persistence/src/share/share.repository.ts @@ -3,8 +3,8 @@ import { None, Some, type Option } from "@undb/domain" import { WithShareId, type IShareRepository, type Share, type ShareSpecification } from "@undb/share" import type { ITxContext } from "../ctx.interface" import { injectTxCTX } from "../ctx.provider" -import type { IQueryBuilder } from "../qb" import { injectQueryBuilder } from "../qb.provider" +import type { IQueryBuilder } from "../qb.server" import { ShareFilterVisitor } from "./share.filter-visitor" import { ShareMapper } from "./share.mapper" diff --git a/packages/persistence/src/space/space.filter-visitor.ts b/packages/persistence/src/space/space.filter-visitor.ts index 08957813a..b353fa7d6 100644 --- a/packages/persistence/src/space/space.filter-visitor.ts +++ b/packages/persistence/src/space/space.filter-visitor.ts @@ -14,7 +14,7 @@ import type { import type { ExpressionBuilder } from "kysely" import { AbstractQBVisitor } from "../abstract-qb.visitor" import type { Database } from "../db" -import type { IQueryBuilder } from "../qb" +import type { IQueryBuilder } from "../qb.server" export class SpaceFilterVisitor extends AbstractQBVisitor implements ISpaceSpecVisitor { constructor( diff --git a/packages/persistence/src/space/space.query-repository.ts b/packages/persistence/src/space/space.query-repository.ts index d36168054..c4f7b832a 100644 --- a/packages/persistence/src/space/space.query-repository.ts +++ b/packages/persistence/src/space/space.query-repository.ts @@ -1,8 +1,8 @@ import { singleton } from "@undb/di" import { None, Some, type Option } from "@undb/domain" import type { ISpaceDTO, ISpaceQueryRepository, ISpaceSpecification } from "@undb/space" -import type { IQueryBuilder } from "../qb" import { injectQueryBuilder } from "../qb.provider" +import type { IQueryBuilder } from "../qb.server" import { SpaceFilterVisitor } from "./space.filter-visitor" @singleton() diff --git a/packages/persistence/src/space/space.repository.ts b/packages/persistence/src/space/space.repository.ts index 80ae9929b..852493d75 100644 --- a/packages/persistence/src/space/space.repository.ts +++ b/packages/persistence/src/space/space.repository.ts @@ -4,8 +4,8 @@ import { None, Some, type Option } from "@undb/domain" import { SpaceFactory, type ISpaceRepository, type ISpaceSpecification, type Space } from "@undb/space" import type { ITxContext } from "../ctx.interface" import { injectTxCTX } from "../ctx.provider" -import type { IQueryBuilder } from "../qb" import { injectQueryBuilder } from "../qb.provider" +import type { IQueryBuilder } from "../qb.server" import { SpaceFilterVisitor } from "./space.filter-visitor" import { SpaceMutateVisitor } from "./space.mutate-visitor" diff --git a/packages/persistence/src/table/table-db.query-spec-handler.ts b/packages/persistence/src/table/table-db.query-spec-handler.ts index ffa68f3be..e7d141d58 100644 --- a/packages/persistence/src/table/table-db.query-spec-handler.ts +++ b/packages/persistence/src/table/table-db.query-spec-handler.ts @@ -1,7 +1,7 @@ import { Option } from "@undb/domain" import type { TableComositeSpecification } from "@undb/table" import type { ExpressionBuilder } from "kysely" -import type { IQueryBuilder } from "../qb" +import type { IQueryBuilder } from "../qb.server" import { TableFilterVisitor } from "./table.filter-visitor" export class TableDbQuerySpecHandler { diff --git a/packages/persistence/src/table/table.filter-visitor.ts b/packages/persistence/src/table/table.filter-visitor.ts index 5642b05a3..47aaac22c 100644 --- a/packages/persistence/src/table/table.filter-visitor.ts +++ b/packages/persistence/src/table/table.filter-visitor.ts @@ -38,7 +38,7 @@ import type { import type { ExpressionBuilder } from "kysely" import { AbstractQBVisitor } from "../abstract-qb.visitor" import type { Database } from "../db" -import type { IQueryBuilder } from "../qb" +import type { IQueryBuilder } from "../qb.server" export class TableFilterVisitor extends AbstractQBVisitor implements ITableSpecVisitor { constructor( diff --git a/packages/persistence/src/table/table.mutation-visitor.ts b/packages/persistence/src/table/table.mutation-visitor.ts index 232b94753..953401531 100644 --- a/packages/persistence/src/table/table.mutation-visitor.ts +++ b/packages/persistence/src/table/table.mutation-visitor.ts @@ -36,7 +36,7 @@ import type { WithoutView, } from "@undb/table" import { AbstractQBMutationVisitor } from "../abstract-qb.visitor" -import { json, type IQueryBuilder } from "../qb" +import { json, type IQueryBuilder } from "../qb.server" import { tables } from "../tables" export class TableMutationVisitor extends AbstractQBMutationVisitor implements ITableSpecVisitor { diff --git a/packages/persistence/src/table/table.query-repository.ts b/packages/persistence/src/table/table.query-repository.ts index 7c328b25a..c669f9687 100644 --- a/packages/persistence/src/table/table.query-repository.ts +++ b/packages/persistence/src/table/table.query-repository.ts @@ -8,8 +8,8 @@ import { type TableComositeSpecification, type TableId, } from "@undb/table" -import type { IQueryBuilder } from "../qb" import { injectQueryBuilder } from "../qb.provider" +import type { IQueryBuilder } from "../qb.server" import { TableDbQuerySpecHandler } from "./table-db.query-spec-handler" import { TableMapper } from "./table.mapper" import { TableReferenceVisitor } from "./table.reference-visitor" diff --git a/packages/persistence/src/table/table.repository.ts b/packages/persistence/src/table/table.repository.ts index 68de688bc..59319d287 100644 --- a/packages/persistence/src/table/table.repository.ts +++ b/packages/persistence/src/table/table.repository.ts @@ -15,8 +15,8 @@ import { import type { ITxContext } from "../ctx.interface" import { injectTxCTX } from "../ctx.provider" import type { InsertTable, InsertTableIdMapping } from "../db" -import { json, type IQueryBuilder } from "../qb" import { injectQueryBuilder } from "../qb.provider" +import { json, type IQueryBuilder } from "../qb.server" import { UnderlyingTableService } from "../underlying/underlying-table.service" import { TableDbQuerySpecHandler } from "./table-db.query-spec-handler" import { TableMapper } from "./table.mapper" diff --git a/packages/persistence/src/underlying/conversion/conversion.factory.ts b/packages/persistence/src/underlying/conversion/conversion.factory.ts index 7bc3210aa..5e9d445cd 100644 --- a/packages/persistence/src/underlying/conversion/conversion.factory.ts +++ b/packages/persistence/src/underlying/conversion/conversion.factory.ts @@ -1,7 +1,7 @@ import type { Field, FieldType, TableDo } from "@undb/table" import type { AlterTableBuilder } from "kysely" import { match } from "ts-pattern" -import type { IRecordQueryBuilder } from "../../qb" +import type { IRecordQueryBuilder } from "../../qb.server.ts" import type { UnderlyingConversionStrategy } from "./conversion.interface" import { NoopConversionStrategy } from "./noop.strategy" import { AnyToCurrencyStrategy } from "./strategies/any-to-currency.strategy" diff --git a/packages/persistence/src/underlying/conversion/conversion.interface.ts b/packages/persistence/src/underlying/conversion/conversion.interface.ts index ecdb1e457..13d8a353f 100644 --- a/packages/persistence/src/underlying/conversion/conversion.interface.ts +++ b/packages/persistence/src/underlying/conversion/conversion.interface.ts @@ -1,6 +1,6 @@ import type { Field, TableDo } from "@undb/table" import type { AlterTableBuilder, ColumnDataType, CompiledQuery } from "kysely" -import type { IRecordQueryBuilder } from "../../qb" +import type { IRecordQueryBuilder } from "../../qb.server" import { TEMP_FIELD_PREFIX } from "./conversion.constant" export abstract class UnderlyingConversionStrategy implements IConversionStrategy { diff --git a/packages/persistence/src/underlying/conversion/strategies/any-to-number.strategy.ts b/packages/persistence/src/underlying/conversion/strategies/any-to-number.strategy.ts index a07d4ade6..b71b407e3 100644 --- a/packages/persistence/src/underlying/conversion/strategies/any-to-number.strategy.ts +++ b/packages/persistence/src/underlying/conversion/strategies/any-to-number.strategy.ts @@ -1,7 +1,7 @@ import type { Field, TableDo } from "@undb/table" import { AlterTableBuilder, CaseWhenBuilder, sql, type ColumnDataType } from "kysely" import { match } from "ts-pattern" -import type { IRecordQueryBuilder } from "../../../qb" +import type { IRecordQueryBuilder } from "../../../qb.server" import { TEMP_FIELD_PREFIX } from "../conversion.constant" import { UnderlyingConversionStrategy } from "../conversion.interface" diff --git a/packages/persistence/src/underlying/underlying-table-field-updated.visitor.ts b/packages/persistence/src/underlying/underlying-table-field-updated.visitor.ts index faccc00b5..2bc073430 100644 --- a/packages/persistence/src/underlying/underlying-table-field-updated.visitor.ts +++ b/packages/persistence/src/underlying/underlying-table-field-updated.visitor.ts @@ -32,7 +32,7 @@ import { import type { FormulaField } from "@undb/table/src/modules/schema/fields/variants/formula-field" import { AlterTableBuilder, sql } from "kysely" import { AbstractQBMutationVisitor } from "../abstract-qb.visitor" -import type { IRecordQueryBuilder } from "../qb" +import type { IRecordQueryBuilder } from "../qb.server" import { getUnderlyingFormulaType } from "./underlying-formula.util" import { UnderlyingFormulaVisitor } from "./underlying-formula.visitor" import type { UnderlyingTable } from "./underlying-table" diff --git a/packages/persistence/src/underlying/underlying-table-field.visitor.ts b/packages/persistence/src/underlying/underlying-table-field.visitor.ts index 01c2034f1..8db900242 100644 --- a/packages/persistence/src/underlying/underlying-table-field.visitor.ts +++ b/packages/persistence/src/underlying/underlying-table-field.visitor.ts @@ -31,7 +31,7 @@ import { import type { CurrencyField } from "@undb/table/src/modules/schema/fields/variants/currency-field" import type { EmailField } from "@undb/table/src/modules/schema/fields/variants/email-field" import { AlterTableBuilder, AlterTableColumnAlteringBuilder, CompiledQuery, CreateTableBuilder, sql } from "kysely" -import type { IQueryBuilder } from "../qb" +import type { IQueryBuilder } from "../qb.server" import { JoinTable } from "./reference/join-table" import { getUnderlyingFormulaType } from "./underlying-formula.util" import { UnderlyingFormulaVisitor } from "./underlying-formula.visitor" diff --git a/packages/persistence/src/underlying/underlying-table-spec.visitor.ts b/packages/persistence/src/underlying/underlying-table-spec.visitor.ts index 2774a385a..6dbc2cf84 100644 --- a/packages/persistence/src/underlying/underlying-table-spec.visitor.ts +++ b/packages/persistence/src/underlying/underlying-table-spec.visitor.ts @@ -47,7 +47,7 @@ import type { } from "@undb/table/src/specifications/table-forms.specification" import type { WithTableRLS } from "@undb/table/src/specifications/table-rls.specification" import { AlterTableBuilder, AlterTableColumnAlteringBuilder, CompiledQuery, CreateTableBuilder, sql } from "kysely" -import type { IRecordQueryBuilder } from "../qb" +import type { IRecordQueryBuilder } from "../qb.server" import { ConversionContext } from "./conversion/conversion.context" import { ConversionFactory } from "./conversion/conversion.factory" import { JoinTable } from "./reference/join-table" diff --git a/packages/persistence/src/user/user.query-repository.ts b/packages/persistence/src/user/user.query-repository.ts index 8985df24b..e7b0b7f44 100644 --- a/packages/persistence/src/user/user.query-repository.ts +++ b/packages/persistence/src/user/user.query-repository.ts @@ -1,8 +1,8 @@ import { singleton } from "@undb/di" import { None, Some, type Option } from "@undb/domain" import type { IUser, IUserQueryRepository } from "@undb/user" -import type { IQueryBuilder } from "../qb" import { injectQueryBuilder } from "../qb.provider" +import type { IQueryBuilder } from "../qb.server" @singleton() export class UserQueryRepository implements IUserQueryRepository { diff --git a/packages/persistence/src/webhook/webhook.mapper.ts b/packages/persistence/src/webhook/webhook.mapper.ts index 0262fbf03..e450e0c1f 100644 --- a/packages/persistence/src/webhook/webhook.mapper.ts +++ b/packages/persistence/src/webhook/webhook.mapper.ts @@ -3,7 +3,7 @@ import { singleton } from "@undb/di" import type { Mapper } from "@undb/domain" import { WebhookDo, WebhookFactory, type IWebhookDTO } from "@undb/webhook" import type { Webhook } from "../db" -import { json } from "../qb" +import { json } from "../qb.server" @singleton() export class WebhookMapper implements Mapper { diff --git a/packages/persistence/src/webhook/webhook.mutation-visitor.ts b/packages/persistence/src/webhook/webhook.mutation-visitor.ts index c1c435f3b..be08c56f1 100644 --- a/packages/persistence/src/webhook/webhook.mutation-visitor.ts +++ b/packages/persistence/src/webhook/webhook.mutation-visitor.ts @@ -12,7 +12,7 @@ import type { WithWebhookURL, } from "@undb/webhook" import { AbstractQBMutationVisitor } from "../abstract-qb.visitor" -import { json } from "../qb" +import { json } from "../qb.server" export class WebhookMutationVisitor extends AbstractQBMutationVisitor implements IWebhookSpecVisitor { idEqual(s: WithWebhookId): void { diff --git a/packages/persistence/src/webhook/webhook.query-repository.ts b/packages/persistence/src/webhook/webhook.query-repository.ts index 06f957152..833d7cf7f 100644 --- a/packages/persistence/src/webhook/webhook.query-repository.ts +++ b/packages/persistence/src/webhook/webhook.query-repository.ts @@ -2,8 +2,8 @@ import { injectContext, type IContext } from "@undb/context" import { inject, singleton } from "@undb/di" import { None, Some, type IPagination, type Option } from "@undb/domain" import type { IWebhookDTO, IWebhookQueryRepository, WebhookSpecification } from "@undb/webhook" -import type { IQueryBuilder } from "../qb" import { injectQueryBuilder } from "../qb.provider" +import type { IQueryBuilder } from "../qb.server" import { WebhookFilterVisitor } from "./webhook.filter-visitor" import { WebhookMapper } from "./webhook.mapper" diff --git a/packages/persistence/src/webhook/webhook.repository.ts b/packages/persistence/src/webhook/webhook.repository.ts index 6fafa0583..5f3bf2cff 100644 --- a/packages/persistence/src/webhook/webhook.repository.ts +++ b/packages/persistence/src/webhook/webhook.repository.ts @@ -4,8 +4,8 @@ import { None, Some, type Option } from "@undb/domain" import { type IWebhookRepository, type WebhookDo, type WebhookSpecification } from "@undb/webhook" import type { ITxContext } from "../ctx.interface" import { injectTxCTX } from "../ctx.provider" -import type { IQueryBuilder } from "../qb" import { injectQueryBuilder } from "../qb.provider" +import type { IQueryBuilder } from "../qb.server" import { WebhookFilterVisitor } from "./webhook.filter-visitor" import { WebhookMapper } from "./webhook.mapper" import { WebhookMutationVisitor } from "./webhook.mutation-visitor" diff --git a/scripts/migrate.ts b/scripts/migrate.ts new file mode 100644 index 000000000..3751bc6da --- /dev/null +++ b/scripts/migrate.ts @@ -0,0 +1,51 @@ +import crypto from "node:crypto" +import fs from "node:fs" +import path from "node:path" +import url from "node:url" + +const { default: journal } = await import("../apps/backend/drizzle/meta/_journal.json", { + with: { type: "json" }, +}) + +interface Migration { + idx: number + when: number + tag: string + hash: string + sql: string[] +} + +const migrate: Migration[] = [] + +const root = path.resolve(url.fileURLToPath(path.dirname(import.meta.url)), "..") +const outdir = path.resolve(root, "./apps/backend/migrations/") +const outfile = path.resolve(outdir, "deployment.json") + +console.log() + +for (let index = 0; index < journal.entries.length; index++) { + const { when, idx, tag } = journal.entries[index] + + console.log('(%d) Parsing migration tagged "%s"', index + 1, tag) + + const filepath = path.resolve(root, "./apps/backend/drizzle", `${tag}.sql`) + const migration_file = fs.readFileSync(filepath).toString() + + migrate.push({ + idx, + when, + tag, + hash: crypto.createHash("sha256").update(migration_file).digest("hex"), + sql: migration_file + .replace(/\n\t?/g, "") + .split("--> statement-breakpoint") + .map((x) => x.trim()), + }) +} + +if (fs.existsSync(outdir) === false) fs.mkdirSync(outdir) + +fs.writeFileSync(outfile, JSON.stringify(migrate, null, 2)) + +console.log() +console.log('Migration deployment config file written out to "%s"\n', outfile)