diff --git a/express/app.ts b/express/app.ts index eb044aa..66c26fd 100644 --- a/express/app.ts +++ b/express/app.ts @@ -3,13 +3,13 @@ import express, { type Response as ExpressResponse, } from "express"; import { match } from "path-to-regexp"; -import { Session } from "./auth"; -import { cli } from "./cli"; -import { contentTypes } from "./content-types"; -import { runWithContext } from "./context"; -import { core } from "./core"; -import { httpCodes } from "./http-codes"; -import { request } from "./request"; +import { Session } from "./diachron/auth"; +import { cli } from "./diachron/cli"; +import { contentTypes } from "./diachron/content-types"; +import { runWithContext } from "./diachron/context"; +import { core } from "./diachron/core"; +import { httpCodes } from "./diachron/http-codes"; +import { request } from "./diachron/request"; import { routes } from "./routes"; // import { URLPattern } from 'node:url'; @@ -25,7 +25,7 @@ import { type ProcessedRoute, type Result, type Route, -} from "./types"; +} from "./diachron/types"; const app = express(); diff --git a/express/auth/index.ts b/express/diachron/auth/index.ts similarity index 100% rename from express/auth/index.ts rename to express/diachron/auth/index.ts diff --git a/express/auth/password.spec.ts b/express/diachron/auth/password.spec.ts similarity index 100% rename from express/auth/password.spec.ts rename to express/diachron/auth/password.spec.ts diff --git a/express/auth/password.ts b/express/diachron/auth/password.ts similarity index 100% rename from express/auth/password.ts rename to express/diachron/auth/password.ts diff --git a/express/auth/routes.ts b/express/diachron/auth/routes.ts similarity index 100% rename from express/auth/routes.ts rename to express/diachron/auth/routes.ts diff --git a/express/auth/service.spec.ts b/express/diachron/auth/service.spec.ts similarity index 100% rename from express/auth/service.spec.ts rename to express/diachron/auth/service.spec.ts diff --git a/express/auth/service.ts b/express/diachron/auth/service.ts similarity index 100% rename from express/auth/service.ts rename to express/diachron/auth/service.ts diff --git a/express/auth/store.spec.ts b/express/diachron/auth/store.spec.ts similarity index 100% rename from express/auth/store.spec.ts rename to express/diachron/auth/store.spec.ts diff --git a/express/auth/store.ts b/express/diachron/auth/store.ts similarity index 100% rename from express/auth/store.ts rename to express/diachron/auth/store.ts diff --git a/express/auth/token.spec.ts b/express/diachron/auth/token.spec.ts similarity index 100% rename from express/auth/token.spec.ts rename to express/diachron/auth/token.spec.ts diff --git a/express/auth/token.ts b/express/diachron/auth/token.ts similarity index 100% rename from express/auth/token.ts rename to express/diachron/auth/token.ts diff --git a/express/auth/types.spec.ts b/express/diachron/auth/types.spec.ts similarity index 100% rename from express/auth/types.spec.ts rename to express/diachron/auth/types.spec.ts diff --git a/express/auth/types.ts b/express/diachron/auth/types.ts similarity index 100% rename from express/auth/types.ts rename to express/diachron/auth/types.ts diff --git a/express/basic/login.spec.ts b/express/diachron/basic/login.spec.ts similarity index 100% rename from express/basic/login.spec.ts rename to express/diachron/basic/login.spec.ts diff --git a/express/basic/login.ts b/express/diachron/basic/login.ts similarity index 100% rename from express/basic/login.ts rename to express/diachron/basic/login.ts diff --git a/express/basic/logout.spec.ts b/express/diachron/basic/logout.spec.ts similarity index 100% rename from express/basic/logout.spec.ts rename to express/diachron/basic/logout.spec.ts diff --git a/express/basic/logout.ts b/express/diachron/basic/logout.ts similarity index 100% rename from express/basic/logout.ts rename to express/diachron/basic/logout.ts diff --git a/express/basic/routes.spec.ts b/express/diachron/basic/routes.spec.ts similarity index 100% rename from express/basic/routes.spec.ts rename to express/diachron/basic/routes.spec.ts diff --git a/express/basic/routes.ts b/express/diachron/basic/routes.ts similarity index 96% rename from express/basic/routes.ts rename to express/diachron/basic/routes.ts index 4511e7c..4bd898e 100644 --- a/express/basic/routes.ts +++ b/express/diachron/basic/routes.ts @@ -1,5 +1,5 @@ import { DateTime } from "ts-luxon"; -import { get, User } from "../diachron/hydrators/user"; +import { get, User } from "../hydrators/user"; import { request } from "../request"; import { html, render } from "../request/util"; import type { Call, Result, Route } from "../types"; diff --git a/express/cli.ts b/express/diachron/cli.ts similarity index 100% rename from express/cli.ts rename to express/diachron/cli.ts diff --git a/express/content-types.ts b/express/diachron/content-types.ts similarity index 100% rename from express/content-types.ts rename to express/diachron/content-types.ts diff --git a/express/context.ts b/express/diachron/context.ts similarity index 100% rename from express/context.ts rename to express/diachron/context.ts diff --git a/express/core/index.ts b/express/diachron/core/index.ts similarity index 100% rename from express/core/index.ts rename to express/diachron/core/index.ts diff --git a/express/database.spec.ts b/express/diachron/database.spec.ts similarity index 100% rename from express/database.spec.ts rename to express/diachron/database.spec.ts diff --git a/express/database.ts b/express/diachron/database.ts similarity index 100% rename from express/database.ts rename to express/diachron/database.ts diff --git a/express/deps.ts b/express/diachron/deps.ts similarity index 100% rename from express/deps.ts rename to express/diachron/deps.ts diff --git a/express/develop/clear-db.ts b/express/diachron/develop/clear-db.ts similarity index 100% rename from express/develop/clear-db.ts rename to express/diachron/develop/clear-db.ts diff --git a/express/develop/reset-db.ts b/express/diachron/develop/reset-db.ts similarity index 100% rename from express/develop/reset-db.ts rename to express/diachron/develop/reset-db.ts diff --git a/express/develop/util.ts b/express/diachron/develop/util.ts similarity index 100% rename from express/develop/util.ts rename to express/diachron/develop/util.ts diff --git a/express/execution-context-schema.ts b/express/diachron/execution-context-schema.ts similarity index 100% rename from express/execution-context-schema.ts rename to express/diachron/execution-context-schema.ts diff --git a/express/execution-context.spec.ts b/express/diachron/execution-context.spec.ts similarity index 100% rename from express/execution-context.spec.ts rename to express/diachron/execution-context.spec.ts diff --git a/express/execution-context.ts b/express/diachron/execution-context.ts similarity index 100% rename from express/execution-context.ts rename to express/diachron/execution-context.ts diff --git a/express/extensible.ts b/express/diachron/extensible.ts similarity index 100% rename from express/extensible.ts rename to express/diachron/extensible.ts diff --git a/express/handlers.spec.ts b/express/diachron/handlers.spec.ts similarity index 100% rename from express/handlers.spec.ts rename to express/diachron/handlers.spec.ts diff --git a/express/handlers.ts b/express/diachron/handlers.ts similarity index 100% rename from express/handlers.ts rename to express/diachron/handlers.ts diff --git a/express/http-codes.ts b/express/diachron/http-codes.ts similarity index 100% rename from express/http-codes.ts rename to express/diachron/http-codes.ts diff --git a/express/diachron/hydrators/hydrator.ts b/express/diachron/hydrators/hydrator.ts index 5445365..e2fe8e3 100644 --- a/express/diachron/hydrators/hydrator.ts +++ b/express/diachron/hydrators/hydrator.ts @@ -1,6 +1,6 @@ import { Kysely, PostgresDialect } from "kysely"; import { Pool } from "pg"; -import { connectionConfig } from "../../database"; +import { connectionConfig } from "../database"; import type { DB } from "../../generated/db"; const db = new Kysely({ diff --git a/express/diachron/hydrators/index.ts b/express/diachron/hydrators/index.ts new file mode 100644 index 0000000..65d08f4 --- /dev/null +++ b/express/diachron/hydrators/index.ts @@ -0,0 +1 @@ +export type Hydrators = {}; diff --git a/express/diachron/hydrators/tests/setup.ts b/express/diachron/hydrators/tests/setup.ts index 1140f0e..df86679 100644 --- a/express/diachron/hydrators/tests/setup.ts +++ b/express/diachron/hydrators/tests/setup.ts @@ -2,7 +2,7 @@ // Run: DB_PORT=5433 DB_USER=diachron_test DB_PASSWORD=diachron_test DB_NAME=diachron_test npx tsx --test tests/*.test.ts import { Pool } from "pg"; -import { connectionConfig, migrate } from "../../../database"; +import { connectionConfig, migrate } from "../../database"; const pool = new Pool(connectionConfig); diff --git a/express/diachron/hydrators/user.ts b/express/diachron/hydrators/user.ts new file mode 100644 index 0000000..865c4bc --- /dev/null +++ b/express/diachron/hydrators/user.ts @@ -0,0 +1,59 @@ +import { + ColumnType, + Generated, + Insertable, + JSONColumnType, + Selectable, + Updateable, +} from "kysely"; +import type { TypeID } from "typeid-js"; +import { z } from "zod"; +import { db, Hydrator } from "./hydrator"; + +const parser = z.object({ + // id: z.uuidv7(), + id: z.uuid(), + display_name: z.string(), + // FIXME: status is duplicated elsewhere + status: z.union([ + z.literal("active"), + z.literal("suspended"), + z.literal("pending"), + ]), + email: z.email(), +}); + +const tp = parser.parse({ + id: "cfae0a19-6515-4813-bc2d-1e032b72b203", + display_name: "foo", + status: "active", + email: "mw@philologue.net", +}); + +export type User = z.infer; + +const get = async (id: string): Promise => { + const ret = await db + .selectFrom("users") + .where("users.id", "=", id) + .innerJoin("user_emails", "user_emails.user_id", "users.id") + .select([ + "users.id", + "users.status", + "users.display_name", + "user_emails.email", + ]) + .executeTakeFirst(); + + if (ret === undefined) { + return null; + } + + console.dir(ret); + + const parsed = parser.parse(ret); + + return parsed; +}; + +export { get }; diff --git a/express/interfaces.ts b/express/diachron/interfaces.ts similarity index 100% rename from express/interfaces.ts rename to express/diachron/interfaces.ts diff --git a/express/logging.spec.ts b/express/diachron/logging.spec.ts similarity index 100% rename from express/logging.spec.ts rename to express/diachron/logging.spec.ts diff --git a/express/logging.ts b/express/diachron/logging.ts similarity index 100% rename from express/logging.ts rename to express/diachron/logging.ts diff --git a/express/mgmt/add-user.ts b/express/diachron/mgmt/add-user.ts similarity index 100% rename from express/mgmt/add-user.ts rename to express/diachron/mgmt/add-user.ts diff --git a/express/migrate.ts b/express/diachron/migrate.ts similarity index 100% rename from express/migrate.ts rename to express/diachron/migrate.ts diff --git a/express/request/index.ts b/express/diachron/request/index.ts similarity index 100% rename from express/request/index.ts rename to express/diachron/request/index.ts diff --git a/express/request/util.ts b/express/diachron/request/util.ts similarity index 100% rename from express/request/util.ts rename to express/diachron/request/util.ts diff --git a/express/types.spec.ts b/express/diachron/types.spec.ts similarity index 100% rename from express/types.spec.ts rename to express/diachron/types.spec.ts diff --git a/express/types.ts b/express/diachron/types.ts similarity index 100% rename from express/types.ts rename to express/diachron/types.ts diff --git a/express/user.spec.ts b/express/diachron/user.spec.ts similarity index 100% rename from express/user.spec.ts rename to express/diachron/user.spec.ts diff --git a/express/user.ts b/express/diachron/user.ts similarity index 100% rename from express/user.ts rename to express/diachron/user.ts diff --git a/express/util.spec.ts b/express/diachron/util.spec.ts similarity index 100% rename from express/util.spec.ts rename to express/diachron/util.spec.ts diff --git a/express/util.ts b/express/diachron/util.ts similarity index 100% rename from express/util.ts rename to express/diachron/util.ts diff --git a/express/generated/.gitignore b/express/generated/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/express/generated/db.d.ts b/express/generated/db.d.ts new file mode 100644 index 0000000..7663d67 --- /dev/null +++ b/express/generated/db.d.ts @@ -0,0 +1,109 @@ +/** + * This file was generated by kysely-codegen. + * Please do not edit it manually. + */ + +import type { ColumnType } from "kysely"; + +export type Generated = + T extends ColumnType + ? ColumnType + : ColumnType; + +export type Timestamp = ColumnType; + +export interface _Migrations { + applied_at: Generated; + id: Generated; + name: string; +} + +export interface Capabilities { + description: string | null; + id: string; + name: string; +} + +export interface Groups { + created_at: Generated; + id: string; + name: string; +} + +export interface RoleCapabilities { + capability_id: string; + granted_at: Generated; + revoked_at: Timestamp | null; + role_id: string; +} + +export interface Roles { + description: string | null; + id: string; + name: string; +} + +export interface Sessions { + auth_method: string; + created_at: Generated; + expires_at: Timestamp; + id: Generated; + ip_address: string | null; + is_used: Generated; + revoked_at: Timestamp | null; + token_hash: string; + token_type: string; + user_agent: string | null; + user_email_id: string | null; + user_id: string; +} + +export interface UserCredentials { + created_at: Generated; + credential_type: Generated; + id: string; + password_hash: string | null; + updated_at: Generated; + user_id: string; +} + +export interface UserEmails { + created_at: Generated; + email: string; + id: string; + is_primary: Generated; + is_verified: Generated; + normalized_email: string; + revoked_at: Timestamp | null; + user_id: string; + verified_at: Timestamp | null; +} + +export interface UserGroupRoles { + granted_at: Generated; + group_id: string; + revoked_at: Timestamp | null; + role_id: string; + user_id: string; +} + +export interface Users { + created_at: Generated; + display_name: string | null; + id: string; + status: Generated; + updated_at: Generated; +} + +export interface DB { + _migrations: _Migrations; + capabilities: Capabilities; + groups: Groups; + role_capabilities: RoleCapabilities; + roles: Roles; + sessions: Sessions; + user_credentials: UserCredentials; + user_emails: UserEmails; + user_group_roles: UserGroupRoles; + users: Users; +} diff --git a/express/group.ts b/express/group.ts new file mode 100644 index 0000000..e69de29 diff --git a/express/migrations/.gitignore b/express/migrations/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/express/migrations/2026-01-15_01-create-test-application-table.sql b/express/migrations/2026-01-15_01-create-test-application-table.sql new file mode 100644 index 0000000..22f9728 --- /dev/null +++ b/express/migrations/2026-01-15_01-create-test-application-table.sql @@ -0,0 +1 @@ +CREATE TABLE test_application_table (); diff --git a/express/migrations/2026-01-15_01.sql b/express/migrations/2026-01-15_01.sql new file mode 100644 index 0000000..22f9728 --- /dev/null +++ b/express/migrations/2026-01-15_01.sql @@ -0,0 +1 @@ +CREATE TABLE test_application_table (); diff --git a/express/routes.ts b/express/routes.ts index 090b7aa..0e7b76b 100644 --- a/express/routes.ts +++ b/express/routes.ts @@ -2,13 +2,13 @@ import nunjucks from "nunjucks"; import { DateTime } from "ts-luxon"; -import { authRoutes } from "./auth/routes"; -import { routes as basicRoutes } from "./basic/routes"; -import { contentTypes } from "./content-types"; -import { core } from "./core"; -import { multiHandler } from "./handlers"; -import { httpCodes } from "./http-codes"; -import type { Call, Result, Route } from "./types"; +import { authRoutes } from "./diachron/auth/routes"; +import { routes as basicRoutes } from "./diachron/basic/routes"; +import { contentTypes } from "./diachron/content-types"; +import { core } from "./diachron/core"; +import { multiHandler } from "./diachron/handlers"; +import { httpCodes } from "./diachron/http-codes"; +import type { Call, Result, Route } from "./diachron/types"; // FIXME: Obviously put this somewhere else const okText = (result: string): Result => {