- Delete old Vite+Svelte frontend - Initialize new SvelteKit project with TypeScript - Configure Tailwind CSS v4 + DaisyUI - Implement JWT authentication with auto-refresh - Create login page with form validation (Zod) - Add protected route guards - Update Docker configuration for single-stage build - Add E2E tests with Playwright (6/11 passing) - Fix Svelte 5 reactivity with $state() runes Known issues: - 5 E2E tests failing (timing/async issues) - Token refresh implementation needs debugging - Validation error display timing
90 lines
4.9 KiB
TypeScript
90 lines
4.9 KiB
TypeScript
import type { array } from "./arrays.ts";
|
|
import type { conform, satisfy, show } from "./generics.ts";
|
|
import type { intersectParameters } from "./intersections.ts";
|
|
import { type Constructor } from "./objectKinds.ts";
|
|
import { NoopBase } from "./records.ts";
|
|
export type TraitImplementation = <traits extends TraitConstructor[], implementation extends implementationOf<s>, s extends CompositionState = composeTraits<[
|
|
...traits,
|
|
implementation
|
|
], "implementation">, cls extends TraitConstructor = TraitConstructor<s["params"], s["implemented"], s["statics"], s["abstractMethods"], s["abstractProps"], s["abstractStatics"]>>(...args: [...traits, implementation & ThisType<InstanceType<cls>>]) => cls;
|
|
export type TraitComposition = <traits extends TraitConstructor[], s extends CompositionState = composeTraits<traits, "abstract">>(...traits: conform<traits, s["validated"]>) => TraitConstructor<s["params"], s["implemented"], s["statics"], s["abstractMethods"], s["abstractProps"], s["abstractStatics"]>;
|
|
export declare const hasTrait: (traitClass: Constructor) => (o: unknown) => boolean;
|
|
export type TraitDeclaration = {
|
|
abstractMethods?: object;
|
|
abstractProps?: object;
|
|
abstractStatics?: object;
|
|
dynamicBase?: object;
|
|
};
|
|
/** @ts-ignore required to extend NoopBase */
|
|
export declare abstract class Trait<d extends TraitDeclaration = {}, abstractMethods extends object = d["abstractMethods"] & {}, abstractProps extends object = d["abstractProps"] & {}, abstractStatics extends object = d["abstractStatics"] & {}, dynamicBase extends object = d["dynamicBase"] & {}> extends NoopBase<abstractMethods & abstractProps & dynamicBase> {
|
|
abstractMethods: abstractMethods;
|
|
abstractProps: abstractProps;
|
|
abstractStatic: abstractStatics;
|
|
static get [Symbol.hasInstance](): (o: unknown) => boolean;
|
|
traitsOf(): readonly TraitConstructor[];
|
|
}
|
|
export declare const compose: TraitComposition;
|
|
export declare const implement: TraitImplementation;
|
|
export type TraitConstructor<params extends array = any[], instance extends object = {}, statics = {}, abstractMethods extends object = {}, abstractProps extends object = {}, abstractStatics extends object = {}> = statics & (new (...args: params) => Trait<{
|
|
abstractMethods: abstractMethods;
|
|
abstractProps: abstractProps;
|
|
abstractStatics: abstractStatics;
|
|
}> & instance);
|
|
type CompositionState = {
|
|
validated: array;
|
|
remaining: array;
|
|
params: array;
|
|
kind: TraitCompositionKind;
|
|
implemented: object;
|
|
abstractMethods: object;
|
|
abstractProps: object;
|
|
abstractStatics: object;
|
|
statics: object;
|
|
};
|
|
export type TraitCompositionKind = "abstract" | "implementation";
|
|
export type composeTraits<traits extends array, kind extends TraitCompositionKind> = _compose<{
|
|
validated: [];
|
|
remaining: traits;
|
|
kind: kind;
|
|
params: [];
|
|
implemented: {};
|
|
abstractMethods: {};
|
|
abstractProps: {};
|
|
abstractStatics: {};
|
|
statics: {};
|
|
}>;
|
|
type intersectImplementations<l, r> = {
|
|
[k in keyof l]: k extends keyof r ? l[k] extends (...args: infer lArgs) => infer lReturn ? r[k] extends (...args: infer rArgs) => infer rReturn ? (...args: intersectParameters<lArgs, rArgs>) => lReturn & rReturn : l[k] & r[k] : l[k] & r[k] : l[k];
|
|
} & Omit<r, keyof l>;
|
|
type _compose<s extends CompositionState> = s["remaining"] extends (readonly [
|
|
TraitConstructor<infer params, infer instance, infer statics, infer abstractMethods, infer abstractProps, infer abstractStatics>,
|
|
...infer tail
|
|
]) ? _compose<{
|
|
validated: [...s["validated"], s["remaining"][0]];
|
|
remaining: tail;
|
|
kind: s["kind"];
|
|
params: intersectParameters<s["params"], params>;
|
|
implemented: intersectImplementations<s["implemented"], Omit<instance, keyof abstractMethods | keyof abstractProps>>;
|
|
statics: intersectImplementations<s["statics"], Omit<statics, keyof abstractStatics>>;
|
|
abstractMethods: intersectImplementations<s["abstractMethods"], abstractMethods>;
|
|
abstractProps: intersectImplementations<s["abstractProps"], abstractProps>;
|
|
abstractStatics: intersectImplementations<s["abstractStatics"], abstractStatics>;
|
|
}> : finalizeState<s>;
|
|
type finalizeState<s extends CompositionState> = satisfy<CompositionState, {
|
|
params: s["params"];
|
|
validated: s["validated"];
|
|
remaining: s["remaining"];
|
|
kind: s["kind"];
|
|
implemented: show<s["implemented"]>;
|
|
statics: show<Omit<s["statics"], keyof typeof Trait>>;
|
|
abstractMethods: show<Omit<s["abstractMethods"], keyof s["implemented"]>>;
|
|
abstractProps: show<Omit<s["abstractProps"], keyof s["implemented"]>>;
|
|
abstractStatics: show<Omit<s["abstractStatics"], keyof s["statics"]>>;
|
|
}>;
|
|
export type implementationOf<s extends CompositionState> = s["abstractMethods"] & ({} extends s["abstractProps"] ? {} : {
|
|
construct: (...args: s["params"]) => s["abstractProps"];
|
|
}) & ({} extends s["abstractStatics"] ? {} : {
|
|
statics: s["abstractStatics"];
|
|
});
|
|
export {};
|