@selvajs/platform 0.14.2 → 0.15.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/dist/auth.d.ts +60 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +12 -0
- package/dist/auth.js.map +1 -0
- package/dist/compute.d.ts +47 -0
- package/dist/compute.d.ts.map +1 -0
- package/dist/compute.js +11 -0
- package/dist/compute.js.map +1 -0
- package/dist/computeServer/index.d.ts +2 -0
- package/dist/computeServer/index.d.ts.map +1 -1
- package/dist/computeServer/index.js +6 -0
- package/dist/computeServer/index.js.map +1 -1
- package/dist/computeServer/interface.d.ts +10 -0
- package/dist/computeServer/interface.d.ts.map +1 -1
- package/dist/computeServer/secrets.d.ts +53 -0
- package/dist/computeServer/secrets.d.ts.map +1 -0
- package/dist/computeServer/secrets.js +67 -0
- package/dist/computeServer/secrets.js.map +1 -0
- package/dist/context.d.ts +7 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +13 -0
- package/dist/context.js.map +1 -1
- package/dist/data/interface.d.ts +33 -0
- package/dist/data/interface.d.ts.map +1 -1
- package/dist/definitions/interface.d.ts +18 -0
- package/dist/definitions/interface.d.ts.map +1 -1
- package/dist/definitions/schemas.d.ts +1 -0
- package/dist/definitions/schemas.d.ts.map +1 -1
- package/dist/definitions/schemas.js +3 -0
- package/dist/definitions/schemas.js.map +1 -1
- package/dist/definitions/service.d.ts +62 -0
- package/dist/definitions/service.d.ts.map +1 -0
- package/dist/definitions/service.js +149 -0
- package/dist/definitions/service.js.map +1 -0
- package/dist/definitions/types.d.ts +24 -1
- package/dist/definitions/types.d.ts.map +1 -1
- package/dist/definitions.d.ts +146 -0
- package/dist/definitions.d.ts.map +1 -0
- package/dist/definitions.js +23 -0
- package/dist/definitions.js.map +1 -0
- package/dist/errors/interface.d.ts +44 -0
- package/dist/errors/interface.d.ts.map +1 -0
- package/dist/errors/interface.js +9 -0
- package/dist/errors/interface.js.map +1 -0
- package/dist/events/interface.d.ts +23 -0
- package/dist/events/interface.d.ts.map +1 -1
- package/dist/events/interface.js.map +1 -1
- package/dist/index.d.ts +14 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/invites/schemas.d.ts +24 -0
- package/dist/invites/schemas.d.ts.map +1 -0
- package/dist/invites/schemas.js +17 -0
- package/dist/invites/schemas.js.map +1 -0
- package/dist/metrics/interface.d.ts +6 -0
- package/dist/metrics/interface.d.ts.map +1 -1
- package/dist/metrics/interface.js.map +1 -1
- package/dist/organizations/index.d.ts +4 -3
- package/dist/organizations/index.d.ts.map +1 -1
- package/dist/organizations/index.js +2 -1
- package/dist/organizations/index.js.map +1 -1
- package/dist/organizations/interface.d.ts +1 -1
- package/dist/organizations/interface.d.ts.map +1 -1
- package/dist/organizations/paths.d.ts +22 -0
- package/dist/organizations/paths.d.ts.map +1 -0
- package/dist/organizations/paths.js +43 -0
- package/dist/organizations/paths.js.map +1 -0
- package/dist/organizations/schemas.d.ts +10 -0
- package/dist/organizations/schemas.d.ts.map +1 -1
- package/dist/organizations/schemas.js +6 -0
- package/dist/organizations/schemas.js.map +1 -1
- package/dist/organizations/types.d.ts +10 -1
- package/dist/organizations/types.d.ts.map +1 -1
- package/dist/organizations.d.ts +93 -0
- package/dist/organizations.d.ts.map +1 -0
- package/dist/organizations.js +14 -0
- package/dist/organizations.js.map +1 -0
- package/dist/solveCache/interface.d.ts +86 -0
- package/dist/solveCache/interface.d.ts.map +1 -0
- package/dist/solveCache/interface.js +12 -0
- package/dist/solveCache/interface.js.map +1 -0
- package/dist/storage/assetClasses.d.ts +59 -0
- package/dist/storage/assetClasses.d.ts.map +1 -0
- package/dist/storage/assetClasses.js +86 -0
- package/dist/storage/assetClasses.js.map +1 -0
- package/dist/storage/cacheBust.d.ts +21 -0
- package/dist/storage/cacheBust.d.ts.map +1 -0
- package/dist/storage/cacheBust.js +29 -0
- package/dist/storage/cacheBust.js.map +1 -0
- package/dist/storage/image.d.ts +6 -1
- package/dist/storage/image.d.ts.map +1 -1
- package/dist/storage/image.js +8 -3
- package/dist/storage/image.js.map +1 -1
- package/dist/storage/index.d.ts +3 -0
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +2 -0
- package/dist/storage/index.js.map +1 -1
- package/dist/testing/adapterSuite.d.ts +33 -0
- package/dist/testing/adapterSuite.d.ts.map +1 -0
- package/dist/testing/adapterSuite.js +166 -0
- package/dist/testing/adapterSuite.js.map +1 -0
- package/dist/testing/suites/definitionStoreSuite.d.ts.map +1 -1
- package/dist/testing/suites/definitionStoreSuite.js +87 -0
- package/dist/testing/suites/definitionStoreSuite.js.map +1 -1
- package/dist/testing/suites/eventSinkSuite.js +1 -0
- package/dist/testing/suites/eventSinkSuite.js.map +1 -1
- package/dist/testing/suites/orgStoreSuite.d.ts.map +1 -1
- package/dist/testing/suites/orgStoreSuite.js +12 -0
- package/dist/testing/suites/orgStoreSuite.js.map +1 -1
- package/dist/testing/suites/platformPermissionStoreSuite.d.ts +9 -0
- package/dist/testing/suites/platformPermissionStoreSuite.d.ts.map +1 -1
- package/dist/testing/suites/platformPermissionStoreSuite.js +34 -1
- package/dist/testing/suites/platformPermissionStoreSuite.js.map +1 -1
- package/dist/testing/suites/runner.d.ts +21 -0
- package/dist/testing/suites/runner.d.ts.map +1 -0
- package/dist/testing/suites/runner.js +7 -0
- package/dist/testing/suites/runner.js.map +1 -0
- package/dist/testing/suites/storageProviderSuite.d.ts.map +1 -1
- package/dist/testing/suites/storageProviderSuite.js +18 -0
- package/dist/testing/suites/storageProviderSuite.js.map +1 -1
- package/package.json +9 -24
- package/src/access/index.ts +0 -23
- package/src/access/rules.ts +0 -276
- package/src/auth/index.ts +0 -8
- package/src/auth/interface.ts +0 -279
- package/src/auth/types.ts +0 -32
- package/src/bindings/index.ts +0 -2
- package/src/bindings/interface.ts +0 -61
- package/src/computeServer/index.ts +0 -17
- package/src/computeServer/interface.ts +0 -62
- package/src/computeServer/types.ts +0 -74
- package/src/computeServer/utils.ts +0 -112
- package/src/config.ts +0 -99
- package/src/context.ts +0 -66
- package/src/data/index.ts +0 -1
- package/src/data/interface.ts +0 -70
- package/src/definitions/index.ts +0 -26
- package/src/definitions/interface.ts +0 -78
- package/src/definitions/paths.ts +0 -31
- package/src/definitions/schemas.ts +0 -64
- package/src/definitions/types.ts +0 -111
- package/src/errors.ts +0 -16
- package/src/events/audit.ts +0 -67
- package/src/events/index.ts +0 -9
- package/src/events/interface.ts +0 -102
- package/src/index.ts +0 -219
- package/src/invites/index.ts +0 -2
- package/src/invites/interface.ts +0 -38
- package/src/invites/types.ts +0 -39
- package/src/metrics/interface.ts +0 -86
- package/src/organizations/index.ts +0 -14
- package/src/organizations/interface.ts +0 -68
- package/src/organizations/schemas.ts +0 -52
- package/src/organizations/types.ts +0 -31
- package/src/pagination.ts +0 -45
- package/src/permissions/index.ts +0 -3
- package/src/permissions/interface.ts +0 -60
- package/src/permissions/types.ts +0 -21
- package/src/platformProjects/index.ts +0 -3
- package/src/platformProjects/interface.ts +0 -27
- package/src/platformProjects/schemas.ts +0 -13
- package/src/platformProjects/types.ts +0 -22
- package/src/projects/index.ts +0 -4
- package/src/projects/interface.ts +0 -58
- package/src/projects/schemas.ts +0 -28
- package/src/projects/types.ts +0 -36
- package/src/shareLinks/index.ts +0 -5
- package/src/shareLinks/interface.ts +0 -35
- package/src/shareLinks/schemas.ts +0 -21
- package/src/shareLinks/types.ts +0 -34
- package/src/storage/image.ts +0 -77
- package/src/storage/index.ts +0 -9
- package/src/storage/interface.ts +0 -27
- package/src/testing/index.ts +0 -47
- package/src/testing/suites/authProviderSuite.ts +0 -207
- package/src/testing/suites/computeServerStoreSuite.ts +0 -195
- package/src/testing/suites/definitionStoreSuite.ts +0 -585
- package/src/testing/suites/emailLinkAuthSuite.ts +0 -83
- package/src/testing/suites/eventSinkSuite.ts +0 -379
- package/src/testing/suites/helpers.ts +0 -87
- package/src/testing/suites/inviteStoreSuite.ts +0 -143
- package/src/testing/suites/orgStoreSuite.ts +0 -412
- package/src/testing/suites/platformPermissionStoreSuite.ts +0 -196
- package/src/testing/suites/platformProjectGrantStoreSuite.ts +0 -166
- package/src/testing/suites/projectStoreSuite.ts +0 -381
- package/src/testing/suites/shareLinkStoreSuite.ts +0 -203
- package/src/testing/suites/solveMetricSinkSuite.ts +0 -135
- package/src/testing/suites/storageProviderSuite.ts +0 -175
- package/src/testing/suites/userProfileStoreSuite.ts +0 -134
- package/src/userProfile/index.ts +0 -3
- package/src/userProfile/interface.ts +0 -48
- package/src/userProfile/types.ts +0 -24
- package/src/utils/audit.ts +0 -46
- package/src/utils/index.ts +0 -2
package/src/config.ts
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import type { IAuthProvider } from './auth/interface.js';
|
|
2
|
-
import type { IDataProvider } from './data/interface.js';
|
|
3
|
-
import type { IStorageProvider } from './storage/interface.js';
|
|
4
|
-
import type { IEventSink } from './events/interface.js';
|
|
5
|
-
import type { ISolveMetricSink } from './metrics/interface.js';
|
|
6
|
-
import type { IBindingResolver } from './bindings/interface.js';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* - `single`: one org per deployment. Setup creates it; `ctx.actingOrgId`
|
|
10
|
-
* resolves to that org for every authenticated user.
|
|
11
|
-
* - `multi`: orgs are first-class. Setup creates only a platform admin; orgs
|
|
12
|
-
* are created by users. `ctx.actingOrgId` resolves per-request.
|
|
13
|
-
*/
|
|
14
|
-
export type TenancyMode = 'single' | 'multi';
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* White-label branding. All fields optional; the selva app applies sensible
|
|
18
|
-
* "Selva" defaults for anything omitted. Use this to rebrand the instance
|
|
19
|
-
* (header name, footer copyright, landing-page copy, page titles) without
|
|
20
|
-
* forking the UI.
|
|
21
|
-
*/
|
|
22
|
-
export interface SelvaBranding {
|
|
23
|
-
/** Product name shown in header, footer, page titles. Default: "Selva". */
|
|
24
|
-
name?: string;
|
|
25
|
-
/** Footer copyright owner. Default: same as `name`. */
|
|
26
|
-
copyrightName?: string;
|
|
27
|
-
/** Landing-page tagline under the product name. */
|
|
28
|
-
tagline?: string;
|
|
29
|
-
/** Meta description for SEO / social previews. */
|
|
30
|
-
description?: string;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/** Opt-in platform features. All default false when absent. */
|
|
34
|
-
export interface SelvaFlags {
|
|
35
|
-
/** Projects with `visibility='public'` visible across orgs on the instance. */
|
|
36
|
-
ALLOW_CROSS_ORG_PUBLIC?: boolean;
|
|
37
|
-
/** Orgs may override the instance compute pool with their own server. */
|
|
38
|
-
ALLOW_ORG_COMPUTE_OVERRIDE?: boolean;
|
|
39
|
-
/** Authenticated users may create new orgs. */
|
|
40
|
-
ALLOW_ORG_CREATION?: boolean;
|
|
41
|
-
/**
|
|
42
|
-
* Per-definition share links — anonymous external access via tokenized URLs.
|
|
43
|
-
* When off, share-link admin routes reject mint/list/revoke and the
|
|
44
|
-
* token-resolution path stops honouring any existing tokens.
|
|
45
|
-
*/
|
|
46
|
-
ENABLE_SHARING?: boolean;
|
|
47
|
-
/**
|
|
48
|
-
* Platform projects — projects owned by instance admins and granted to orgs
|
|
49
|
-
* or individual users without normal membership. When off, the
|
|
50
|
-
* `/admin/projects` surface 404s, platform-visibility projects are hidden
|
|
51
|
-
* from every list, and access rules treat them as inaccessible. Existing
|
|
52
|
-
* data is preserved; flipping back on restores access.
|
|
53
|
-
*/
|
|
54
|
-
ENABLE_PLATFORM_PROJECTS?: boolean;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export interface SelvaConfig {
|
|
58
|
-
tenancy?: TenancyMode;
|
|
59
|
-
flags?: SelvaFlags;
|
|
60
|
-
branding?: SelvaBranding;
|
|
61
|
-
auth: IAuthProvider;
|
|
62
|
-
/**
|
|
63
|
-
* Orgs, projects, members, definitions, compute config, user profiles,
|
|
64
|
-
* and platform permissions. All database-layer concerns live here.
|
|
65
|
-
*/
|
|
66
|
-
data: IDataProvider;
|
|
67
|
-
/** Blob storage — .gh/.ghx files, archived versions, images. */
|
|
68
|
-
storage: IStorageProvider;
|
|
69
|
-
/** Optional. Defaults to `NoopEventSink`. */
|
|
70
|
-
events?: IEventSink;
|
|
71
|
-
/**
|
|
72
|
-
* Optional. Records per-solve timing (wall time of the Rhino.Compute solve
|
|
73
|
-
* call). Defaults to `NoopSolveMetricSink`, which discards every metric.
|
|
74
|
-
* Supply a real sink to persist or aggregate solve durations.
|
|
75
|
-
*/
|
|
76
|
-
solveMetrics?: ISolveMetricSink;
|
|
77
|
-
/**
|
|
78
|
-
* Optional. Resolves values for inputs marked as `source.kind === 'server'`
|
|
79
|
-
* in the schema. Defaults to `NoopBindingResolver`, which returns nothing
|
|
80
|
-
* — combined with the schema's `onMissing: 'fail'` default, that causes
|
|
81
|
-
* any solve involving a server-resolved input to error loudly until a real
|
|
82
|
-
* resolver is configured. Hosts that want server-resolved inputs must supply one.
|
|
83
|
-
*/
|
|
84
|
-
bindingResolver?: IBindingResolver;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export type SelvaConfigFactory = (env: Record<string, string | undefined>) => SelvaConfig;
|
|
88
|
-
|
|
89
|
-
/** Safe accessor — omitted flags resolve to false. */
|
|
90
|
-
export function isFlagEnabled(config: SelvaConfig, flag: keyof SelvaFlags): boolean {
|
|
91
|
-
return Boolean(config.flags?.[flag]);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/** For TypeScript inference / IDE autocomplete only, Vite-style. */
|
|
95
|
-
export function defineConfig(
|
|
96
|
-
config: SelvaConfig | SelvaConfigFactory
|
|
97
|
-
): SelvaConfig | SelvaConfigFactory {
|
|
98
|
-
return config;
|
|
99
|
-
}
|
package/src/context.ts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import type { PlatformPermission } from './permissions/types.js';
|
|
2
|
-
import { ALL_PLATFORM_PERMISSIONS } from './permissions/types.js';
|
|
3
|
-
import type { OrgPermission } from './organizations/schemas.js';
|
|
4
|
-
import { ALL_ORG_PERMISSIONS } from './organizations/schemas.js';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Per-request identity + scope passed to every data provider call. Built
|
|
8
|
-
* once per HTTP request from the authenticated session.
|
|
9
|
-
*
|
|
10
|
-
* `actingOrgId` is the org the user is currently acting as — NOT "an org the
|
|
11
|
-
* user is a member of." Tenancy checks compare it to the resource's `orgId`.
|
|
12
|
-
*
|
|
13
|
-
* `instance_admin` implies every other permission, everywhere — encoded by
|
|
14
|
-
* `hasPermission`. `system: true` is a trusted server-internal call;
|
|
15
|
-
* adapters with RLS treat it as fully authorized.
|
|
16
|
-
*/
|
|
17
|
-
export interface RequestContext {
|
|
18
|
-
/** Empty string for system contexts. */
|
|
19
|
-
userId: string;
|
|
20
|
-
/** Undefined for instance-admin global reads and pre-org routes. */
|
|
21
|
-
actingOrgId?: string;
|
|
22
|
-
platformPermissions: PlatformPermission[];
|
|
23
|
-
/** Empty when `actingOrgId` is undefined. */
|
|
24
|
-
orgPermissions: OrgPermission[];
|
|
25
|
-
/** Never derive from a user session. */
|
|
26
|
-
system?: true;
|
|
27
|
-
/**
|
|
28
|
-
* Opaque adapter payload. The Supabase adapter passes the user JWT through
|
|
29
|
-
* for RLS; local ignores it.
|
|
30
|
-
*/
|
|
31
|
-
adapterContext?: unknown;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* For server-internal operations outside any HTTP request (bootstrap,
|
|
36
|
-
* janitors, migrations). Treated as fully authorized.
|
|
37
|
-
*/
|
|
38
|
-
export const SYSTEM_CONTEXT: RequestContext = {
|
|
39
|
-
userId: '',
|
|
40
|
-
platformPermissions: [...ALL_PLATFORM_PERMISSIONS],
|
|
41
|
-
orgPermissions: [...ALL_ORG_PERMISSIONS],
|
|
42
|
-
system: true
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Does NOT cross-check `ctx.actingOrgId` — the caller builds a context scoped
|
|
47
|
-
* to the org they're acting on. An org permission against a ctx without
|
|
48
|
-
* `actingOrgId` returns false unless `instance_admin` or `system`.
|
|
49
|
-
*/
|
|
50
|
-
export function hasPermission(
|
|
51
|
-
ctx: RequestContext,
|
|
52
|
-
permission: PlatformPermission | OrgPermission
|
|
53
|
-
): boolean {
|
|
54
|
-
if (ctx.system) return true;
|
|
55
|
-
if (ctx.platformPermissions.includes('instance_admin')) return true;
|
|
56
|
-
if (isPlatformPermission(permission)) {
|
|
57
|
-
return ctx.platformPermissions.includes(permission);
|
|
58
|
-
}
|
|
59
|
-
return ctx.orgPermissions.includes(permission);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const PLATFORM_PERMISSION_VALUES = new Set<string>(ALL_PLATFORM_PERMISSIONS);
|
|
63
|
-
|
|
64
|
-
function isPlatformPermission(p: string): p is PlatformPermission {
|
|
65
|
-
return PLATFORM_PERMISSION_VALUES.has(p);
|
|
66
|
-
}
|
package/src/data/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export type { IDataProvider } from './interface.js';
|
package/src/data/interface.ts
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `IDataProvider` is the composition root that bundles every store an adapter
|
|
3
|
-
* implements. Individual interfaces (`IOrgStore`, `IProjectStore`, …) live
|
|
4
|
-
* next to their types in their respective subdirs — only the composition
|
|
5
|
-
* lives here.
|
|
6
|
-
*
|
|
7
|
-
* Every store method takes a `RequestContext` first. **The query itself is
|
|
8
|
-
* the security boundary** — adapters MUST scope reads/writes by `ctx`. An
|
|
9
|
-
* unauthorized caller sees an empty page, `null`, or a `ProviderError`.
|
|
10
|
-
*
|
|
11
|
-
* Access-control predicates live in `@selvajs/platform/access` (pure rules).
|
|
12
|
-
* Stores do storage; rules do rules.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import type { IOrgStore } from '../organizations/interface.js';
|
|
16
|
-
import type { IProjectStore } from '../projects/interface.js';
|
|
17
|
-
import type { IDefinitionStore } from '../definitions/interface.js';
|
|
18
|
-
import type { IComputeServerStore } from '../computeServer/interface.js';
|
|
19
|
-
import type { IShareLinkStore } from '../shareLinks/interface.js';
|
|
20
|
-
import type { IPlatformProjectGrantStore } from '../platformProjects/interface.js';
|
|
21
|
-
import type { IInviteStore } from '../invites/interface.js';
|
|
22
|
-
import type { IUserProfileStore } from '../userProfile/interface.js';
|
|
23
|
-
import type { IPlatformPermissionStore } from '../permissions/interface.js';
|
|
24
|
-
import type { IAuditQuery } from '../events/audit.js';
|
|
25
|
-
import type { RequestContext } from '../context.js';
|
|
26
|
-
|
|
27
|
-
export interface IDataProvider {
|
|
28
|
-
orgs: IOrgStore;
|
|
29
|
-
projects: IProjectStore;
|
|
30
|
-
definitions: IDefinitionStore;
|
|
31
|
-
computeServer: IComputeServerStore;
|
|
32
|
-
invites: IInviteStore;
|
|
33
|
-
shareLinks: IShareLinkStore;
|
|
34
|
-
userProfile: IUserProfileStore;
|
|
35
|
-
permissions: IPlatformPermissionStore;
|
|
36
|
-
platformProjectGrants: IPlatformProjectGrantStore;
|
|
37
|
-
/**
|
|
38
|
-
* Read-side for the persisted event log. Optional — providers whose event
|
|
39
|
-
* sink is a noop (local-provider) leave this undefined and the
|
|
40
|
-
* `/admin/audit` UI degrades to its "no backend wired" state.
|
|
41
|
-
*/
|
|
42
|
-
auditQuery?: IAuditQuery;
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Idempotently register a user in the data layer. Called by `hooks.server.ts`
|
|
46
|
-
* after `verifyToken` succeeds, so the data layer always has a row for the
|
|
47
|
-
* authenticated user regardless of which auth provider issued the ID.
|
|
48
|
-
*
|
|
49
|
-
* Adapters with a DB-side trigger that auto-seeds on auth signup (Supabase)
|
|
50
|
-
* make this a no-op. Adapters that own a separate user-data table without a
|
|
51
|
-
* trigger (local-provider) upsert here.
|
|
52
|
-
*
|
|
53
|
-
* MUST be safe to call concurrently and on every request. MUST NOT throw on
|
|
54
|
-
* a duplicate userId.
|
|
55
|
-
*/
|
|
56
|
-
ensureUser(ctx: RequestContext, userId: string): Promise<void>;
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Cascade hook called after the auth provider deletes a user. Removes any
|
|
60
|
-
* data-layer rows tied to that user (the user-data row, anything else
|
|
61
|
-
* keyed by `userId` that should die with the identity).
|
|
62
|
-
*
|
|
63
|
-
* Adapters whose data-layer FKs cascade on delete (Supabase via
|
|
64
|
-
* `on delete cascade` against `auth.users`) no-op. Adapters that own
|
|
65
|
-
* separate tables (local-provider) clean up here.
|
|
66
|
-
*
|
|
67
|
-
* MUST tolerate a missing user (idempotent — caller may retry).
|
|
68
|
-
*/
|
|
69
|
-
onUserDeleted(ctx: RequestContext, userId: string): Promise<void>;
|
|
70
|
-
}
|
package/src/definitions/index.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
export type {
|
|
2
|
-
DefinitionFileExt,
|
|
3
|
-
DefinitionRecord,
|
|
4
|
-
DefinitionRecordPatch,
|
|
5
|
-
DefinitionStatus,
|
|
6
|
-
DefinitionVersion,
|
|
7
|
-
DefinitionChannel
|
|
8
|
-
} from './types.js';
|
|
9
|
-
export type { IDefinitionStore } from './interface.js';
|
|
10
|
-
export type { UISchema } from '@selvajs/schemas';
|
|
11
|
-
export {
|
|
12
|
-
GH_EXTENSIONS,
|
|
13
|
-
COVER_IMAGE_EXTENSIONS,
|
|
14
|
-
ALLOWED_UPLOAD_EXTENSIONS,
|
|
15
|
-
COVER_IMAGE_CONTENT_TYPES
|
|
16
|
-
} from './types.js';
|
|
17
|
-
export { definitionPaths } from './paths.js';
|
|
18
|
-
export type { UpdateMetadataInput } from './schemas.js';
|
|
19
|
-
export {
|
|
20
|
-
DefinitionChannelSchema,
|
|
21
|
-
PublishVersionInputSchema,
|
|
22
|
-
CreateDefinitionInputSchema,
|
|
23
|
-
UpdateMetadataInputSchema,
|
|
24
|
-
GuidSchema,
|
|
25
|
-
UUID_REGEX
|
|
26
|
-
} from './schemas.js';
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import type { RequestContext } from '../context.js';
|
|
2
|
-
import type { ListOptions, DefinitionListOptions, Page } from '../pagination.js';
|
|
3
|
-
import type { UISchema } from '@selvajs/schemas';
|
|
4
|
-
import type { DefinitionRecord, DefinitionRecordPatch, DefinitionVersion } from './types.js';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Definition metadata + version store. Blob contents live in `IStorageProvider`;
|
|
8
|
-
* this interface tracks the parent record plus immutable version rows and the
|
|
9
|
-
* `live` / `draft` channel pointers.
|
|
10
|
-
*/
|
|
11
|
-
export interface IDefinitionStore {
|
|
12
|
-
// Definitions
|
|
13
|
-
list(ctx: RequestContext, opts?: DefinitionListOptions): Promise<Page<DefinitionRecord>>;
|
|
14
|
-
listByProject(
|
|
15
|
-
ctx: RequestContext,
|
|
16
|
-
projectId: string,
|
|
17
|
-
opts?: DefinitionListOptions
|
|
18
|
-
): Promise<Page<DefinitionRecord>>;
|
|
19
|
-
/**
|
|
20
|
-
* List definitions whose parent project has `visibility === 'public'`.
|
|
21
|
-
* Pass `orgId` to restrict to one org; omit for cross-org listing within
|
|
22
|
-
* whatever tenant boundary the adapter already enforces.
|
|
23
|
-
*/
|
|
24
|
-
listPublic(
|
|
25
|
-
ctx: RequestContext,
|
|
26
|
-
opts?: DefinitionListOptions & { orgId?: string }
|
|
27
|
-
): Promise<Page<DefinitionRecord>>;
|
|
28
|
-
get(ctx: RequestContext, guid: string): Promise<DefinitionRecord | null>;
|
|
29
|
-
create(ctx: RequestContext, record: DefinitionRecord): Promise<void>;
|
|
30
|
-
update(ctx: RequestContext, guid: string, patch: DefinitionRecordPatch): Promise<void>;
|
|
31
|
-
delete(ctx: RequestContext, guid: string): Promise<void>;
|
|
32
|
-
|
|
33
|
-
/** Atomic +1 on the solve counter. No-op if the record doesn't exist. */
|
|
34
|
-
incrementSolveCount(ctx: RequestContext, guid: string): Promise<void>;
|
|
35
|
-
|
|
36
|
-
// Versions (immutable rows)
|
|
37
|
-
createVersion(ctx: RequestContext, version: DefinitionVersion): Promise<void>;
|
|
38
|
-
/** Newest first by `versionNumber`. */
|
|
39
|
-
listVersions(
|
|
40
|
-
ctx: RequestContext,
|
|
41
|
-
definitionId: string,
|
|
42
|
-
opts?: ListOptions
|
|
43
|
-
): Promise<Page<DefinitionVersion>>;
|
|
44
|
-
getVersion(ctx: RequestContext, versionId: string): Promise<DefinitionVersion | null>;
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Set the cached compute-extracted schema on a version row. Used by the
|
|
48
|
-
* upload path (writes the schema validated up-front) and the temporary
|
|
49
|
-
* solve-time backfill bridge (see selva/specs/SchemaCaching.md). No-op if
|
|
50
|
-
* the version doesn't exist.
|
|
51
|
-
*/
|
|
52
|
-
setVersionSchema(ctx: RequestContext, versionId: string, schema: UISchema): Promise<void>;
|
|
53
|
-
/**
|
|
54
|
-
* Throws 409 if the version is referenced by `liveVersionId` or
|
|
55
|
-
* `draftVersionId`. Caller deletes the blob separately.
|
|
56
|
-
*/
|
|
57
|
-
deleteVersion(ctx: RequestContext, versionId: string): Promise<void>;
|
|
58
|
-
|
|
59
|
-
/** Atomically point `liveVersionId` at a target version of this definition. */
|
|
60
|
-
setLiveVersion(ctx: RequestContext, definitionId: string, versionId: string): Promise<void>;
|
|
61
|
-
setDraftVersion(ctx: RequestContext, definitionId: string, versionId: string): Promise<void>;
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Atomic `'pending'` → `'draft'` bootstrap. Sets BOTH `liveVersionId` and
|
|
65
|
-
* `draftVersionId` to `versionId` and flips `status` to `'draft'` in a
|
|
66
|
-
* single update — used by the create flow so a mid-flight failure can't
|
|
67
|
-
* leave the record half-promoted (status='draft' with a null channel
|
|
68
|
-
* pointer, or status='pending' with channels set).
|
|
69
|
-
*
|
|
70
|
-
* Validates that `versionId` belongs to `definitionId` (404 if not).
|
|
71
|
-
*
|
|
72
|
-
* Does NOT emit `definition.published`. The bootstrap is covered by the
|
|
73
|
-
* parent's `definition.created` + `definition_version.created` pair;
|
|
74
|
-
* `definition.published` is reserved for explicit publish ops via
|
|
75
|
-
* `setLiveVersion`.
|
|
76
|
-
*/
|
|
77
|
-
attachInitialVersion(ctx: RequestContext, definitionId: string, versionId: string): Promise<void>;
|
|
78
|
-
}
|
package/src/definitions/paths.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import type { DefinitionFileExt } from './types.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Path-segment safety check. Blocks traversal, separators, NUL, and empty
|
|
5
|
-
* segments. Allowed alphabet `[A-Za-z0-9._-]+` covers GUIDs and sanitized
|
|
6
|
-
* refs. Called by every helper so a malicious `guid` can't escape the
|
|
7
|
-
* `definitions/` prefix.
|
|
8
|
-
*/
|
|
9
|
-
function assertSafeKey(value: string, label: string): void {
|
|
10
|
-
if (!value || !/^[A-Za-z0-9._-]+$/.test(value) || value === '.' || value === '..') {
|
|
11
|
-
throw new Error(`Unsafe ${label}: ${JSON.stringify(value)}`);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const definitionPaths = {
|
|
16
|
-
version: (guid: string, versionNumber: number, ext: DefinitionFileExt) => {
|
|
17
|
-
assertSafeKey(guid, 'guid');
|
|
18
|
-
if (!Number.isInteger(versionNumber) || versionNumber < 1) {
|
|
19
|
-
throw new Error(`Unsafe versionNumber: ${versionNumber}`);
|
|
20
|
-
}
|
|
21
|
-
return `definitions/${guid}/versions/v${versionNumber}.${ext}`;
|
|
22
|
-
},
|
|
23
|
-
image: (guid: string) => {
|
|
24
|
-
assertSafeKey(guid, 'guid');
|
|
25
|
-
return `definitions/${guid}/cover.webp`;
|
|
26
|
-
},
|
|
27
|
-
prefix: (guid: string) => {
|
|
28
|
-
assertSafeKey(guid, 'guid');
|
|
29
|
-
return `definitions/${guid}/`;
|
|
30
|
-
}
|
|
31
|
-
} as const;
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
|
|
3
|
-
export const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
4
|
-
|
|
5
|
-
export const GuidSchema = z.string().regex(UUID_REGEX, 'Invalid GUID format');
|
|
6
|
-
|
|
7
|
-
export const DefinitionStatusSchema = z.enum(['draft', 'published', 'archived']);
|
|
8
|
-
|
|
9
|
-
export const DefinitionFileExtSchema = z.enum(['gh', 'ghx']);
|
|
10
|
-
|
|
11
|
-
export const DefinitionVersionSchema = z.object({
|
|
12
|
-
id: GuidSchema,
|
|
13
|
-
definitionId: GuidSchema,
|
|
14
|
-
versionNumber: z.number().int().min(1),
|
|
15
|
-
fileExt: DefinitionFileExtSchema,
|
|
16
|
-
fileKey: z.string().min(1),
|
|
17
|
-
originalFilename: z.string().max(256).optional(),
|
|
18
|
-
uploadedBy: z.string().min(1),
|
|
19
|
-
uploadedAt: z.string(),
|
|
20
|
-
changeNote: z.string().max(1000).optional(),
|
|
21
|
-
// Cached compute-extracted UI schema. Structural correctness is validated by
|
|
22
|
-
// Rhino.Compute at upload, not here — this only asserts it's an object.
|
|
23
|
-
schema: z.record(z.string(), z.unknown()).optional(),
|
|
24
|
-
schemaExtractedAt: z.string().optional()
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
export const DefinitionChannelSchema = z.enum(['live', 'draft']);
|
|
28
|
-
|
|
29
|
-
/** HTTP-body validator for new-definition input. */
|
|
30
|
-
export const CreateDefinitionInputSchema = z.object({
|
|
31
|
-
displayName: z.string().min(1, 'Display name is required').max(256),
|
|
32
|
-
description: z.string().max(2000).optional(),
|
|
33
|
-
coverImage: z.string().max(2048).optional(),
|
|
34
|
-
category: z.string().max(128).optional(),
|
|
35
|
-
tags: z.array(z.string().max(64)).max(20).optional(),
|
|
36
|
-
projectId: GuidSchema,
|
|
37
|
-
computeServerId: GuidSchema.optional()
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* PATCH validator. Field semantics match `DefinitionRecordPatch`:
|
|
42
|
-
* - missing / `undefined` — leave unchanged
|
|
43
|
-
* - `null` — clear (only on nullable fields)
|
|
44
|
-
* - value — set
|
|
45
|
-
*/
|
|
46
|
-
export const UpdateMetadataInputSchema = z.object({
|
|
47
|
-
displayName: z.string().min(1, 'Display name is required').max(256).optional(),
|
|
48
|
-
description: z.string().max(2000).nullable().optional(),
|
|
49
|
-
coverImage: z.string().max(2048).nullable().optional(),
|
|
50
|
-
category: z.string().max(128).nullable().optional(),
|
|
51
|
-
tags: z.array(z.string().max(64)).max(20).nullable().optional(),
|
|
52
|
-
projectId: GuidSchema.optional(),
|
|
53
|
-
computeServerId: GuidSchema.nullable().optional(),
|
|
54
|
-
status: DefinitionStatusSchema.optional()
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
export type UpdateMetadataInput = z.infer<typeof UpdateMetadataInputSchema>;
|
|
58
|
-
|
|
59
|
-
/** Body for `POST /api/definitions/[guid]/publish`. */
|
|
60
|
-
export const PublishVersionInputSchema = z
|
|
61
|
-
.object({
|
|
62
|
-
versionId: GuidSchema.optional()
|
|
63
|
-
})
|
|
64
|
-
.default({});
|
package/src/definitions/types.ts
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import type { UISchema } from '@selvajs/schemas';
|
|
2
|
-
|
|
3
|
-
export type DefinitionFileExt = 'gh' | 'ghx';
|
|
4
|
-
|
|
5
|
-
export const GH_EXTENSIONS: string[] = ['.gh', '.ghx'];
|
|
6
|
-
export const COVER_IMAGE_EXTENSIONS: string[] = ['.jpg', '.jpeg', '.png', '.webp', '.gif'];
|
|
7
|
-
export const ALLOWED_UPLOAD_EXTENSIONS: string[] = [...GH_EXTENSIONS, ...COVER_IMAGE_EXTENSIONS];
|
|
8
|
-
|
|
9
|
-
export const COVER_IMAGE_CONTENT_TYPES: Record<string, string> = {
|
|
10
|
-
'.jpg': 'image/jpeg',
|
|
11
|
-
'.jpeg': 'image/jpeg',
|
|
12
|
-
'.png': 'image/png',
|
|
13
|
-
'.webp': 'image/webp',
|
|
14
|
-
'.gif': 'image/gif'
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* - `pending` — internal: metadata written, blob upload may be in flight.
|
|
19
|
-
* - `draft` — work in progress, not visible to runners.
|
|
20
|
-
* - `published` — live, visible to all with solve access.
|
|
21
|
-
* - `archived` — retired but preserved. Versions and channel pointers remain
|
|
22
|
-
* intact; restore via `update({ status: 'draft' | 'published' })`.
|
|
23
|
-
*
|
|
24
|
-
* List endpoints filter `pending` and `archived` by default (opt in via
|
|
25
|
-
* `DefinitionListOptions.includePending` / `includeArchived`, or pass an
|
|
26
|
-
* explicit `statuses` filter).
|
|
27
|
-
*/
|
|
28
|
-
export type DefinitionStatus = 'pending' | 'draft' | 'published' | 'archived';
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Immutable snapshot of a definition's `.gh` file at a point in time. New
|
|
32
|
-
* uploads create new versions; rollback re-points the parent's
|
|
33
|
-
* `liveVersionId` (it never mutates the version itself).
|
|
34
|
-
*/
|
|
35
|
-
export interface DefinitionVersion {
|
|
36
|
-
id: string;
|
|
37
|
-
definitionId: string;
|
|
38
|
-
/** Monotonic integer starting at 1; never reused. */
|
|
39
|
-
versionNumber: number;
|
|
40
|
-
fileExt: DefinitionFileExt;
|
|
41
|
-
/** Full storage key. Opaque to callers. */
|
|
42
|
-
fileKey: string;
|
|
43
|
-
originalFilename?: string;
|
|
44
|
-
uploadedBy: string;
|
|
45
|
-
uploadedAt: string;
|
|
46
|
-
/** Free-form note describing what changed in this version. */
|
|
47
|
-
changeNote?: string;
|
|
48
|
-
/**
|
|
49
|
-
* Compute-extracted UI schema, cached at upload so the render path doesn't
|
|
50
|
-
* re-fetch it from Rhino.Compute on every load. Optional only because of the
|
|
51
|
-
* lazy-backfill bridge for pre-existing versions (see
|
|
52
|
-
* selva/specs/SchemaCaching.md); new uploads always set it.
|
|
53
|
-
*/
|
|
54
|
-
schema?: UISchema;
|
|
55
|
-
/** ISO timestamp of when `schema` was extracted. */
|
|
56
|
-
schemaExtractedAt?: string;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export interface DefinitionRecord {
|
|
60
|
-
guid: string;
|
|
61
|
-
projectId: string;
|
|
62
|
-
/** Current owner — separate from `createdBy` so ownership can transfer. */
|
|
63
|
-
ownerId: string;
|
|
64
|
-
createdBy: string;
|
|
65
|
-
updatedBy: string;
|
|
66
|
-
/** Falls back to the org default, then the platform default. */
|
|
67
|
-
computeServerId?: string;
|
|
68
|
-
displayName: string;
|
|
69
|
-
description?: string;
|
|
70
|
-
category?: string;
|
|
71
|
-
tags?: string[];
|
|
72
|
-
/** Provider-dependent public URL — must be safe to send to clients. */
|
|
73
|
-
coverImage?: string;
|
|
74
|
-
status: DefinitionStatus;
|
|
75
|
-
solveCount: number;
|
|
76
|
-
/**
|
|
77
|
-
* Both null only during the brief `pending` window between metadata create
|
|
78
|
-
* and v1 upload; otherwise both reference live `DefinitionVersion` rows.
|
|
79
|
-
*/
|
|
80
|
-
liveVersionId: string | null;
|
|
81
|
-
draftVersionId: string | null;
|
|
82
|
-
createdAt: string;
|
|
83
|
-
updatedAt: string;
|
|
84
|
-
deletedAt?: string | null;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Patch omits immutable fields and provider-managed ones (use
|
|
89
|
-
* `setLiveVersion`/`setDraftVersion` for the latter).
|
|
90
|
-
*
|
|
91
|
-
* - `undefined` — leave unchanged
|
|
92
|
-
* - `null` — clear (only on nullable fields)
|
|
93
|
-
* - value — set
|
|
94
|
-
*
|
|
95
|
-
* Use `incrementSolveCount` for atomic +1 bumps instead of patching `solveCount`.
|
|
96
|
-
*/
|
|
97
|
-
export interface DefinitionRecordPatch {
|
|
98
|
-
displayName?: string;
|
|
99
|
-
description?: string | null;
|
|
100
|
-
category?: string | null;
|
|
101
|
-
tags?: string[] | null;
|
|
102
|
-
coverImage?: string | null;
|
|
103
|
-
projectId?: string;
|
|
104
|
-
computeServerId?: string | null;
|
|
105
|
-
status?: DefinitionStatus;
|
|
106
|
-
/** Ownership transfer. */
|
|
107
|
-
ownerId?: string;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/** Channel for solve dispatch. */
|
|
111
|
-
export type DefinitionChannel = 'live' | 'draft';
|
package/src/errors.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Thrown by providers to signal an expected failure that the API layer
|
|
3
|
-
* should forward with a specific status. Unknown errors should propagate as
|
|
4
|
-
* plain `Error` and become 500s.
|
|
5
|
-
*
|
|
6
|
-
* Conventional values: 400, 401, 403, 404, 409, 422, 429, 500.
|
|
7
|
-
*/
|
|
8
|
-
export class ProviderError extends Error {
|
|
9
|
-
readonly statusCode: number;
|
|
10
|
-
|
|
11
|
-
constructor(message: string, statusCode: number = 400) {
|
|
12
|
-
super(message);
|
|
13
|
-
this.name = 'ProviderError';
|
|
14
|
-
this.statusCode = statusCode;
|
|
15
|
-
}
|
|
16
|
-
}
|
package/src/events/audit.ts
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import type { RequestContext } from '../context.js';
|
|
2
|
-
import type { DomainEvent, DomainEventType } from './interface.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Read-side counterpart to `IEventSink`. Persisted by the sink, queried by
|
|
6
|
-
* operator-facing UIs (admin audit log) and future analytics consumers.
|
|
7
|
-
*
|
|
8
|
-
* Kept on its own interface so:
|
|
9
|
-
* - dev-mode `NoopEventSink` doesn't need a fake `query` returning empty;
|
|
10
|
-
* `auditQuery` simply stays undefined on the data provider.
|
|
11
|
-
* - future webhook-dispatcher sinks aren't forced to implement a query path.
|
|
12
|
-
* - the contract here can throw on backend failure without violating the
|
|
13
|
-
* sink's "MUST NOT throw" rule.
|
|
14
|
-
*
|
|
15
|
-
* Authorisation is the caller's job — implementations read from a privileged
|
|
16
|
-
* client (Supabase service-role, etc.) and assume the route layer has already
|
|
17
|
-
* gated on `instance_admin`.
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
export interface AuditEventRow {
|
|
21
|
-
/** Stable row id from the persistent store (e.g. uuid). */
|
|
22
|
-
id: string;
|
|
23
|
-
/** ISO 8601. The persisted timestamp, not when the originating mutation occurred. */
|
|
24
|
-
occurredAt: string;
|
|
25
|
-
type: DomainEventType;
|
|
26
|
-
actorId: string;
|
|
27
|
-
/** The full `DomainEvent` payload as recorded. */
|
|
28
|
-
data: DomainEvent;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Keyset cursor. `(occurredAt, id)` lexicographic — `occurredAt` alone isn't
|
|
33
|
-
* unique under bursty writes, so a tie-breaker is required to avoid skipped
|
|
34
|
-
* rows on page boundaries.
|
|
35
|
-
*/
|
|
36
|
-
export interface AuditCursor {
|
|
37
|
-
occurredAt: string;
|
|
38
|
-
id: string;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export interface AuditQueryFilters {
|
|
42
|
-
/** Restrict to these event types. Empty / undefined = all types. */
|
|
43
|
-
types?: readonly DomainEventType[];
|
|
44
|
-
/** Restrict to events emitted by this actor id (or `'system'`). */
|
|
45
|
-
actorId?: string;
|
|
46
|
-
/** Inclusive lower bound on `occurredAt`. ISO 8601. */
|
|
47
|
-
sinceIso?: string;
|
|
48
|
-
/** Inclusive upper bound on `occurredAt`. ISO 8601. */
|
|
49
|
-
untilIso?: string;
|
|
50
|
-
/**
|
|
51
|
-
* Page size. Implementations clamp to a sane upper bound (≤200) — callers
|
|
52
|
-
* shouldn't be able to request unbounded reads.
|
|
53
|
-
*/
|
|
54
|
-
limit?: number;
|
|
55
|
-
/** Keyset cursor from a previous page's `nextCursor`. */
|
|
56
|
-
cursor?: AuditCursor;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export interface AuditQueryResult {
|
|
60
|
-
rows: AuditEventRow[];
|
|
61
|
-
/** Null when there are no more rows past this page. */
|
|
62
|
-
nextCursor: AuditCursor | null;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export interface IAuditQuery {
|
|
66
|
-
list(ctx: RequestContext, filters: AuditQueryFilters): Promise<AuditQueryResult>;
|
|
67
|
-
}
|
package/src/events/index.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export type { DomainEvent, DomainEventType, IEventSink } from './interface.js';
|
|
2
|
-
export { actorFrom, NoopEventSink } from './interface.js';
|
|
3
|
-
export type {
|
|
4
|
-
AuditEventRow,
|
|
5
|
-
AuditCursor,
|
|
6
|
-
AuditQueryFilters,
|
|
7
|
-
AuditQueryResult,
|
|
8
|
-
IAuditQuery
|
|
9
|
-
} from './audit.js';
|