diff --git a/packages/core/src/date.ts b/packages/core/src/date.ts index 63c4e8c..5b88a71 100644 --- a/packages/core/src/date.ts +++ b/packages/core/src/date.ts @@ -37,6 +37,16 @@ function stringToMilliseconds(timeString: string): number { return totalMilliseconds; } +/** + * Create a date instance from a time string. + */ +export function dateCreate(timeString?: string) { + if (!timeString) { + return new Date(); + } + return new Date(Date.now() + stringToMilliseconds(timeString)); +} + /** * Create a numeric date value. Needed typically for bearers. */ @@ -48,3 +58,13 @@ export function dateNumeric(date?: Date | string) { } return (date?.getTime() ?? new Date().getTime()); }; + +/** + * Alias for `dateCreate`. + */ +export const d = dateCreate; + +/** + * Alias for `dateNumeric`. + */ +export const dN = dateNumeric; diff --git a/packages/core/src/io/context.test.ts b/packages/core/src/io/context.test.ts index 9723a4f..729bd2b 100644 --- a/packages/core/src/io/context.test.ts +++ b/packages/core/src/io/context.test.ts @@ -44,9 +44,6 @@ test('should create a context', () => { }); const context = contextify({ - meta: async () => ({ - scope: 'none', - }), adapter: { db: databaseAdapter } diff --git a/packages/core/src/io/context.ts b/packages/core/src/io/context.ts index f0d35d1..34608ba 100644 --- a/packages/core/src/io/context.ts +++ b/packages/core/src/io/context.ts @@ -1,32 +1,27 @@ - -import type { Action } from './action'; -// import { Ambit } from './ambit'; -import type { Input } from './input'; import type { Adapter } from './adapter'; +import { Input } from './input'; +import { Output } from './output'; export interface Context< - Meta extends Record = Record, A extends Adapter = Adapter, AL extends Record = Record, - I = Input>, > { - meta: (input: I) => Promise; adapter: AL; + middleware: ((input: Input, next: (input: Input) => Output) => Output)[]; } /** * Constructs a full context object with placeholder values. */ export function contextify< - M extends Record, A extends Adapter = Adapter, AL extends Record = Record, >({ - meta = async () => ({} as M), adapter = {} as AL, -}: Partial>) { + middleware = [], +}: Partial>) { return { - meta, adapter, + middleware }; } diff --git a/packages/core/src/utility/memoize.ts b/packages/core/src/utility/memoize.ts index b5af04a..b038f4c 100644 --- a/packages/core/src/utility/memoize.ts +++ b/packages/core/src/utility/memoize.ts @@ -1,10 +1,10 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ + /** * The cache object. */ type MemoizedCache any> = { value: ReturnType; - set: number; + set?: number; }; /** @@ -13,6 +13,8 @@ type MemoizedCache any> = { interface MemoizeOptions { /** * The amount of time the cache has to live in milliseconds. + * + * @default undefined */ ttl?: number; } @@ -25,8 +27,7 @@ export function memoize< >( fn: T, { - // Default time to live is 5 minutes. - ttl = 5 * 60 * 1000, + ttl, }: MemoizeOptions = {}, ) { const cache = new Map>(); @@ -39,7 +40,7 @@ export function memoize< const goods = cache.get(key) ?? {} as MemoizedCache; const set = goods?.set; const value = goods?.value; - if (set && set < Date.now()) { + if (!!set && set < Date.now()) { cache.delete(key); } else { return value as ReturnType; @@ -47,7 +48,7 @@ export function memoize< } const value = fn(...args) as ReturnType; - cache.set(key, { value, set: Date.now() + ttl }); + cache.set(key, { value, set: ttl && Date.now() + ttl }); return value; }; diff --git a/packages/data/scripts/data.sql b/packages/data/scripts/data.sql index 9edcdd0..42dc574 100644 --- a/packages/data/scripts/data.sql +++ b/packages/data/scripts/data.sql @@ -22,12 +22,6 @@ CREATE TABLE IF NOT EXISTS "action" ( "description" varchar(1024) ); --> statement-breakpoint -CREATE TABLE IF NOT EXISTS "ambit" ( - "id" varchar(64) PRIMARY KEY NOT NULL, - "name" varchar(256) NOT NULL, - "description" varchar(1024) -); ---> statement-breakpoint CREATE TABLE IF NOT EXISTS "dispatch" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "subject_id" uuid NOT NULL, @@ -66,6 +60,15 @@ CREATE TABLE IF NOT EXISTS "entity_locale" ( CONSTRAINT "entity_locale_code_name_unique" UNIQUE("code","name") ); --> statement-breakpoint +CREATE TABLE IF NOT EXISTS "permit" ( + "id" uuid PRIMARY KEY NOT NULL, + "entity_id" uuid NOT NULL, + "action_id" varchar(64) NOT NULL, + "ambit" smallint DEFAULT 0, + "rate" smallint DEFAULT 0, + CONSTRAINT "permit_entity_id_action_id_unique" UNIQUE("entity_id","action_id") +); +--> statement-breakpoint CREATE TABLE IF NOT EXISTS "entity_phone" ( "id" uuid PRIMARY KEY NOT NULL, "user_id" uuid, @@ -151,26 +154,17 @@ CREATE TABLE IF NOT EXISTS "entity_file" ( CONSTRAINT "entity_file_name_unique" UNIQUE("name") ); --> statement-breakpoint -CREATE TABLE IF NOT EXISTS "entitle" ( - "entity_id" uuid NOT NULL, - "target_id" uuid NOT NULL, - "action_id" varchar(64) NOT NULL, - CONSTRAINT "entitle_entity_id_target_id_action_id_pk" PRIMARY KEY("entity_id","target_id","action_id") -); ---> statement-breakpoint CREATE TABLE IF NOT EXISTS "join_assignment" ( "entity_id" uuid NOT NULL, "role_id" uuid NOT NULL, CONSTRAINT "join_assignment_entity_id_role_id_pk" PRIMARY KEY("entity_id","role_id") ); --> statement-breakpoint -CREATE TABLE IF NOT EXISTS "permit" ( - "id" uuid PRIMARY KEY NOT NULL, +CREATE TABLE IF NOT EXISTS "entitle" ( "entity_id" uuid NOT NULL, + "target_id" uuid NOT NULL, "action_id" varchar(64) NOT NULL, - "ambit" smallint DEFAULT 0, - "rate" smallint DEFAULT 0, - CONSTRAINT "permit_entity_id_action_id_unique" UNIQUE("entity_id","action_id") + CONSTRAINT "entitle_entity_id_target_id_action_id_pk" PRIMARY KEY("entity_id","target_id","action_id") ); --> statement-breakpoint CREATE TABLE IF NOT EXISTS "mutate" ( @@ -245,103 +239,103 @@ EXCEPTION END $$; --> statement-breakpoint DO $$ BEGIN - ALTER TABLE "entity_phone" ADD CONSTRAINT "entity_phone_id_entity_id_fk" FOREIGN KEY ("id") REFERENCES "public"."entity"("id") ON DELETE cascade ON UPDATE no action; + ALTER TABLE "permit" ADD CONSTRAINT "permit_id_entity_id_fk" FOREIGN KEY ("id") REFERENCES "public"."entity"("id") ON DELETE cascade ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint DO $$ BEGIN - ALTER TABLE "entity_phone" ADD CONSTRAINT "entity_phone_user_id_entity_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."entity_user"("id") ON DELETE no action ON UPDATE no action; + ALTER TABLE "permit" ADD CONSTRAINT "permit_entity_id_entity_id_fk" FOREIGN KEY ("entity_id") REFERENCES "public"."entity"("id") ON DELETE cascade ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint DO $$ BEGIN - ALTER TABLE "entity_profile" ADD CONSTRAINT "entity_profile_id_entity_id_fk" FOREIGN KEY ("id") REFERENCES "public"."entity"("id") ON DELETE cascade ON UPDATE no action; + ALTER TABLE "permit" ADD CONSTRAINT "permit_action_id_action_id_fk" FOREIGN KEY ("action_id") REFERENCES "public"."action"("id") ON DELETE cascade ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint DO $$ BEGIN - ALTER TABLE "entity_profile" ADD CONSTRAINT "entity_profile_user_id_entity_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."entity_user"("id") ON DELETE no action ON UPDATE no action; + ALTER TABLE "entity_phone" ADD CONSTRAINT "entity_phone_id_entity_id_fk" FOREIGN KEY ("id") REFERENCES "public"."entity"("id") ON DELETE cascade ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint DO $$ BEGIN - ALTER TABLE "entity_profile" ADD CONSTRAINT "entity_profile_picture_id_entity_file_image_id_fk" FOREIGN KEY ("picture_id") REFERENCES "public"."entity_file_image"("id") ON DELETE no action ON UPDATE no action; + ALTER TABLE "entity_phone" ADD CONSTRAINT "entity_phone_user_id_entity_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."entity_user"("id") ON DELETE no action ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint DO $$ BEGIN - ALTER TABLE "entity_profile" ADD CONSTRAINT "entity_profile_cover_id_entity_file_image_id_fk" FOREIGN KEY ("cover_id") REFERENCES "public"."entity_file_image"("id") ON DELETE no action ON UPDATE no action; + ALTER TABLE "entity_profile" ADD CONSTRAINT "entity_profile_id_entity_id_fk" FOREIGN KEY ("id") REFERENCES "public"."entity"("id") ON DELETE cascade ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint DO $$ BEGIN - ALTER TABLE "entity_role" ADD CONSTRAINT "entity_role_id_entity_id_fk" FOREIGN KEY ("id") REFERENCES "public"."entity"("id") ON DELETE cascade ON UPDATE no action; + ALTER TABLE "entity_profile" ADD CONSTRAINT "entity_profile_user_id_entity_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."entity_user"("id") ON DELETE no action ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint DO $$ BEGIN - ALTER TABLE "entity_role" ADD CONSTRAINT "entity_role_avatar_id_entity_file_image_id_fk" FOREIGN KEY ("avatar_id") REFERENCES "public"."entity_file_image"("id") ON DELETE no action ON UPDATE no action; + ALTER TABLE "entity_profile" ADD CONSTRAINT "entity_profile_picture_id_entity_file_image_id_fk" FOREIGN KEY ("picture_id") REFERENCES "public"."entity_file_image"("id") ON DELETE no action ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint DO $$ BEGIN - ALTER TABLE "entity_user" ADD CONSTRAINT "entity_user_id_entity_id_fk" FOREIGN KEY ("id") REFERENCES "public"."entity"("id") ON DELETE cascade ON UPDATE no action; + ALTER TABLE "entity_profile" ADD CONSTRAINT "entity_profile_cover_id_entity_file_image_id_fk" FOREIGN KEY ("cover_id") REFERENCES "public"."entity_file_image"("id") ON DELETE no action ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint DO $$ BEGIN - ALTER TABLE "entity_user" ADD CONSTRAINT "entity_user_avatar_id_entity_file_image_id_fk" FOREIGN KEY ("avatar_id") REFERENCES "public"."entity_file_image"("id") ON DELETE no action ON UPDATE no action; + ALTER TABLE "entity_role" ADD CONSTRAINT "entity_role_id_entity_id_fk" FOREIGN KEY ("id") REFERENCES "public"."entity"("id") ON DELETE cascade ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint DO $$ BEGIN - ALTER TABLE "entity_file_audio" ADD CONSTRAINT "entity_file_audio_id_entity_file_id_fk" FOREIGN KEY ("id") REFERENCES "public"."entity_file"("id") ON DELETE cascade ON UPDATE no action; + ALTER TABLE "entity_role" ADD CONSTRAINT "entity_role_avatar_id_entity_file_image_id_fk" FOREIGN KEY ("avatar_id") REFERENCES "public"."entity_file_image"("id") ON DELETE no action ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint DO $$ BEGIN - ALTER TABLE "entity_file_image" ADD CONSTRAINT "entity_file_image_id_entity_file_id_fk" FOREIGN KEY ("id") REFERENCES "public"."entity_file"("id") ON DELETE cascade ON UPDATE no action; + ALTER TABLE "entity_user" ADD CONSTRAINT "entity_user_id_entity_id_fk" FOREIGN KEY ("id") REFERENCES "public"."entity"("id") ON DELETE cascade ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint DO $$ BEGIN - ALTER TABLE "entity_file_video" ADD CONSTRAINT "entity_file_video_id_entity_file_id_fk" FOREIGN KEY ("id") REFERENCES "public"."entity_file"("id") ON DELETE cascade ON UPDATE no action; + ALTER TABLE "entity_user" ADD CONSTRAINT "entity_user_avatar_id_entity_file_image_id_fk" FOREIGN KEY ("avatar_id") REFERENCES "public"."entity_file_image"("id") ON DELETE no action ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint DO $$ BEGIN - ALTER TABLE "entity_file" ADD CONSTRAINT "entity_file_id_entity_id_fk" FOREIGN KEY ("id") REFERENCES "public"."entity"("id") ON DELETE cascade ON UPDATE no action; + ALTER TABLE "entity_file_audio" ADD CONSTRAINT "entity_file_audio_id_entity_file_id_fk" FOREIGN KEY ("id") REFERENCES "public"."entity_file"("id") ON DELETE cascade ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint DO $$ BEGIN - ALTER TABLE "entitle" ADD CONSTRAINT "entitle_entity_id_entity_id_fk" FOREIGN KEY ("entity_id") REFERENCES "public"."entity"("id") ON DELETE no action ON UPDATE no action; + ALTER TABLE "entity_file_image" ADD CONSTRAINT "entity_file_image_id_entity_file_id_fk" FOREIGN KEY ("id") REFERENCES "public"."entity_file"("id") ON DELETE cascade ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint DO $$ BEGIN - ALTER TABLE "entitle" ADD CONSTRAINT "entitle_target_id_entity_id_fk" FOREIGN KEY ("target_id") REFERENCES "public"."entity"("id") ON DELETE no action ON UPDATE no action; + ALTER TABLE "entity_file_video" ADD CONSTRAINT "entity_file_video_id_entity_file_id_fk" FOREIGN KEY ("id") REFERENCES "public"."entity_file"("id") ON DELETE cascade ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint DO $$ BEGIN - ALTER TABLE "entitle" ADD CONSTRAINT "entitle_action_id_action_id_fk" FOREIGN KEY ("action_id") REFERENCES "public"."action"("id") ON DELETE no action ON UPDATE no action; + ALTER TABLE "entity_file" ADD CONSTRAINT "entity_file_id_entity_id_fk" FOREIGN KEY ("id") REFERENCES "public"."entity"("id") ON DELETE cascade ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$; @@ -359,19 +353,19 @@ EXCEPTION END $$; --> statement-breakpoint DO $$ BEGIN - ALTER TABLE "permit" ADD CONSTRAINT "permit_id_entity_id_fk" FOREIGN KEY ("id") REFERENCES "public"."entity"("id") ON DELETE cascade ON UPDATE no action; + ALTER TABLE "entitle" ADD CONSTRAINT "entitle_entity_id_entity_id_fk" FOREIGN KEY ("entity_id") REFERENCES "public"."entity"("id") ON DELETE no action ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint DO $$ BEGIN - ALTER TABLE "permit" ADD CONSTRAINT "permit_entity_id_entity_id_fk" FOREIGN KEY ("entity_id") REFERENCES "public"."entity"("id") ON DELETE cascade ON UPDATE no action; + ALTER TABLE "entitle" ADD CONSTRAINT "entitle_target_id_entity_id_fk" FOREIGN KEY ("target_id") REFERENCES "public"."entity"("id") ON DELETE no action ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint DO $$ BEGIN - ALTER TABLE "permit" ADD CONSTRAINT "permit_action_id_action_id_fk" FOREIGN KEY ("action_id") REFERENCES "public"."action"("id") ON DELETE cascade ON UPDATE no action; + ALTER TABLE "entitle" ADD CONSTRAINT "entitle_action_id_action_id_fk" FOREIGN KEY ("action_id") REFERENCES "public"."action"("id") ON DELETE no action ON UPDATE no action; EXCEPTION WHEN duplicate_object THEN null; END $$; @@ -388,7 +382,6 @@ EXCEPTION WHEN duplicate_object THEN null; END $$; --> statement-breakpoint -CREATE INDEX IF NOT EXISTS "ambit_name_idx" ON "ambit" USING btree ("name");--> statement-breakpoint CREATE INDEX IF NOT EXISTS "credential_client_id_idx" ON "entity_credential" USING btree ("client_id");--> statement-breakpoint CREATE INDEX IF NOT EXISTS "email_address_idx" ON "entity_email" USING btree ("address");--> statement-breakpoint CREATE INDEX IF NOT EXISTS "locale_code_idx" ON "entity_locale" USING btree ("code");--> statement-breakpoint diff --git a/packages/data/src/schema.ts b/packages/data/src/schema.ts index 3334181..4caace5 100644 --- a/packages/data/src/schema.ts +++ b/packages/data/src/schema.ts @@ -14,6 +14,7 @@ import * as locale from './schema/entity/entity_locale.ts'; import * as phone from './schema/entity/entity_phone.ts'; import * as profile from './schema/entity/entity_profile.ts'; import * as role from './schema/entity/entity_role.ts'; +import * as permit from './schema/entity/entity_permit.ts'; import * as user from './schema/entity/entity_user.ts'; // Entity -> Files @@ -24,8 +25,7 @@ import * as video from './schema/entity/file/entity_file_video.ts'; // Join Tables import * as assignment from './schema/join/join_assignment.ts'; -import * as entitle from './schema/join/entitle.ts'; -import * as permit from './schema/join/permit.ts'; +import * as entitle from './schema/join/join_entitle.ts'; /** * Flattens a schema item group into a table and relates object. @@ -165,6 +165,7 @@ export const core_entity = { profile, role, user, + permit, file, }; @@ -207,5 +208,4 @@ export type CoreEntityFileSelect = { export const join = { assignment, entitle, - permit, }; diff --git a/packages/data/src/schema/entity/entity.ts b/packages/data/src/schema/entity/entity.ts index 7807174..f23bc04 100644 --- a/packages/data/src/schema/entity/entity.ts +++ b/packages/data/src/schema/entity/entity.ts @@ -6,8 +6,8 @@ import { import { table as mutate } from '../mutate.ts'; import { table as assignment } from '../join/join_assignment.ts'; -import { table as permit } from '../join/permit.ts'; -import { table as entitle } from '../join/entitle.ts'; +import { table as entitle } from '../join/join_entitle.ts'; +import { table as permit } from './entity_permit.ts'; import { table as credential } from './entity_credential.ts'; /** diff --git a/packages/data/src/schema/join/permit.ts b/packages/data/src/schema/entity/entity_permit.ts similarity index 96% rename from packages/data/src/schema/join/permit.ts rename to packages/data/src/schema/entity/entity_permit.ts index 017e572..b34fb22 100644 --- a/packages/data/src/schema/join/permit.ts +++ b/packages/data/src/schema/entity/entity_permit.ts @@ -1,7 +1,7 @@ import { relations } from 'drizzle-orm'; import { pgTable, uuid, unique, varchar, smallint } from 'drizzle-orm/pg-core'; -import { table as entity } from '../entity/entity.ts'; +import { table as entity } from './entity.ts'; import { table as action } from '../action.ts'; /** diff --git a/packages/data/src/schema/join/entitle.ts b/packages/data/src/schema/join/join_entitle.ts similarity index 100% rename from packages/data/src/schema/join/entitle.ts rename to packages/data/src/schema/join/join_entitle.ts diff --git a/packages/data/src/seed.ts b/packages/data/src/seed.ts index 45e7bb0..cd8f640 100644 --- a/packages/data/src/seed.ts +++ b/packages/data/src/seed.ts @@ -7,6 +7,7 @@ import { Database } from './pglite'; import * as system from './seed/system'; import * as action from './seed/action'; +import * as entity_role from './seed/entity_role'; import * as entity_locale from './seed/entity_locale'; @@ -17,6 +18,7 @@ export interface SeedModule { export const modules = { system, action, + entity_role, entity_locale, };