@selvajs/platform 0.14.3-beta.0 → 0.15.0-beta.2

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.
Files changed (154) hide show
  1. package/LICENSE +1 -1
  2. package/dist/computeServer/index.d.ts +1 -1
  3. package/dist/computeServer/index.d.ts.map +1 -1
  4. package/dist/computeServer/interface.d.ts +29 -1
  5. package/dist/computeServer/interface.d.ts.map +1 -1
  6. package/dist/computeServer/types.d.ts +12 -1
  7. package/dist/computeServer/types.d.ts.map +1 -1
  8. package/dist/computeServer/types.js.map +1 -1
  9. package/dist/data/index.d.ts +2 -1
  10. package/dist/data/index.d.ts.map +1 -1
  11. package/dist/data/index.js +1 -1
  12. package/dist/data/index.js.map +1 -1
  13. package/dist/data/interface.d.ts +69 -8
  14. package/dist/data/interface.d.ts.map +1 -1
  15. package/dist/data/interface.js +7 -1
  16. package/dist/data/interface.js.map +1 -1
  17. package/dist/definitions/interface.d.ts +16 -1
  18. package/dist/definitions/interface.d.ts.map +1 -1
  19. package/dist/definitions/schemas.d.ts +1 -0
  20. package/dist/definitions/schemas.d.ts.map +1 -1
  21. package/dist/definitions/schemas.js +8 -0
  22. package/dist/definitions/schemas.js.map +1 -1
  23. package/dist/definitions/types.d.ts +24 -1
  24. package/dist/definitions/types.d.ts.map +1 -1
  25. package/dist/events/index.d.ts +1 -1
  26. package/dist/events/index.d.ts.map +1 -1
  27. package/dist/events/index.js +1 -1
  28. package/dist/events/index.js.map +1 -1
  29. package/dist/events/interface.d.ts +30 -0
  30. package/dist/events/interface.d.ts.map +1 -1
  31. package/dist/events/interface.js +7 -0
  32. package/dist/events/interface.js.map +1 -1
  33. package/dist/index.d.ts +9 -4
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +5 -2
  36. package/dist/index.js.map +1 -1
  37. package/dist/logging/interface.d.ts +82 -0
  38. package/dist/logging/interface.d.ts.map +1 -0
  39. package/dist/logging/interface.js +33 -0
  40. package/dist/logging/interface.js.map +1 -0
  41. package/dist/metrics/interface.d.ts +6 -0
  42. package/dist/metrics/interface.d.ts.map +1 -1
  43. package/dist/metrics/interface.js.map +1 -1
  44. package/dist/organizations/__tests__/slug-schema.test.d.ts +2 -0
  45. package/dist/organizations/__tests__/slug-schema.test.d.ts.map +1 -0
  46. package/dist/organizations/__tests__/slug-schema.test.js +38 -0
  47. package/dist/organizations/__tests__/slug-schema.test.js.map +1 -0
  48. package/dist/organizations/index.d.ts +1 -1
  49. package/dist/organizations/index.d.ts.map +1 -1
  50. package/dist/organizations/index.js +1 -1
  51. package/dist/organizations/index.js.map +1 -1
  52. package/dist/organizations/schemas.d.ts +16 -2
  53. package/dist/organizations/schemas.d.ts.map +1 -1
  54. package/dist/organizations/schemas.js +32 -2
  55. package/dist/organizations/schemas.js.map +1 -1
  56. package/dist/solveCache/interface.d.ts +86 -0
  57. package/dist/solveCache/interface.d.ts.map +1 -0
  58. package/dist/solveCache/interface.js +12 -0
  59. package/dist/solveCache/interface.js.map +1 -0
  60. package/dist/testing/suites/definitionStoreSuite.d.ts.map +1 -1
  61. package/dist/testing/suites/definitionStoreSuite.js +57 -0
  62. package/dist/testing/suites/definitionStoreSuite.js.map +1 -1
  63. package/dist/testing/suites/eventSinkSuite.js +1 -0
  64. package/dist/testing/suites/eventSinkSuite.js.map +1 -1
  65. package/dist/testing/suites/platformPermissionStoreSuite.d.ts +9 -0
  66. package/dist/testing/suites/platformPermissionStoreSuite.d.ts.map +1 -1
  67. package/dist/testing/suites/platformPermissionStoreSuite.js +34 -1
  68. package/dist/testing/suites/platformPermissionStoreSuite.js.map +1 -1
  69. package/dist/testing/suites/solveMetricSinkSuite.d.ts +5 -0
  70. package/dist/testing/suites/solveMetricSinkSuite.d.ts.map +1 -1
  71. package/dist/testing/suites/solveMetricSinkSuite.js +17 -8
  72. package/dist/testing/suites/solveMetricSinkSuite.js.map +1 -1
  73. package/dist/testing/suites/storageProviderSuite.d.ts.map +1 -1
  74. package/dist/testing/suites/storageProviderSuite.js +23 -2
  75. package/dist/testing/suites/storageProviderSuite.js.map +1 -1
  76. package/package.json +9 -24
  77. package/src/access/index.ts +0 -23
  78. package/src/access/rules.ts +0 -276
  79. package/src/auth/index.ts +0 -8
  80. package/src/auth/interface.ts +0 -279
  81. package/src/auth/types.ts +0 -32
  82. package/src/bindings/index.ts +0 -2
  83. package/src/bindings/interface.ts +0 -61
  84. package/src/computeServer/index.ts +0 -28
  85. package/src/computeServer/interface.ts +0 -73
  86. package/src/computeServer/secrets.ts +0 -102
  87. package/src/computeServer/types.ts +0 -74
  88. package/src/computeServer/utils.ts +0 -112
  89. package/src/config.ts +0 -99
  90. package/src/context.ts +0 -80
  91. package/src/data/index.ts +0 -1
  92. package/src/data/interface.ts +0 -70
  93. package/src/definitions/index.ts +0 -26
  94. package/src/definitions/interface.ts +0 -87
  95. package/src/definitions/paths.ts +0 -31
  96. package/src/definitions/schemas.ts +0 -64
  97. package/src/definitions/types.ts +0 -111
  98. package/src/errors/interface.ts +0 -45
  99. package/src/errors.ts +0 -16
  100. package/src/events/audit.ts +0 -67
  101. package/src/events/index.ts +0 -9
  102. package/src/events/interface.ts +0 -102
  103. package/src/index.ts +0 -247
  104. package/src/invites/index.ts +0 -2
  105. package/src/invites/interface.ts +0 -38
  106. package/src/invites/types.ts +0 -39
  107. package/src/metrics/interface.ts +0 -86
  108. package/src/organizations/index.ts +0 -23
  109. package/src/organizations/interface.ts +0 -68
  110. package/src/organizations/paths.ts +0 -45
  111. package/src/organizations/schemas.ts +0 -61
  112. package/src/organizations/types.ts +0 -41
  113. package/src/pagination.ts +0 -45
  114. package/src/permissions/index.ts +0 -3
  115. package/src/permissions/interface.ts +0 -60
  116. package/src/permissions/types.ts +0 -21
  117. package/src/platformProjects/index.ts +0 -3
  118. package/src/platformProjects/interface.ts +0 -27
  119. package/src/platformProjects/schemas.ts +0 -13
  120. package/src/platformProjects/types.ts +0 -22
  121. package/src/projects/index.ts +0 -4
  122. package/src/projects/interface.ts +0 -58
  123. package/src/projects/schemas.ts +0 -28
  124. package/src/projects/types.ts +0 -36
  125. package/src/shareLinks/index.ts +0 -5
  126. package/src/shareLinks/interface.ts +0 -35
  127. package/src/shareLinks/schemas.ts +0 -21
  128. package/src/shareLinks/types.ts +0 -34
  129. package/src/storage/assetClasses.ts +0 -134
  130. package/src/storage/cacheBust.ts +0 -26
  131. package/src/storage/image.ts +0 -82
  132. package/src/storage/index.ts +0 -12
  133. package/src/storage/interface.ts +0 -27
  134. package/src/testing/index.ts +0 -47
  135. package/src/testing/suites/authProviderSuite.ts +0 -207
  136. package/src/testing/suites/computeServerStoreSuite.ts +0 -195
  137. package/src/testing/suites/definitionStoreSuite.ts +0 -630
  138. package/src/testing/suites/emailLinkAuthSuite.ts +0 -83
  139. package/src/testing/suites/eventSinkSuite.ts +0 -379
  140. package/src/testing/suites/helpers.ts +0 -87
  141. package/src/testing/suites/inviteStoreSuite.ts +0 -143
  142. package/src/testing/suites/orgStoreSuite.ts +0 -429
  143. package/src/testing/suites/platformPermissionStoreSuite.ts +0 -196
  144. package/src/testing/suites/platformProjectGrantStoreSuite.ts +0 -166
  145. package/src/testing/suites/projectStoreSuite.ts +0 -381
  146. package/src/testing/suites/shareLinkStoreSuite.ts +0 -203
  147. package/src/testing/suites/solveMetricSinkSuite.ts +0 -135
  148. package/src/testing/suites/storageProviderSuite.ts +0 -196
  149. package/src/testing/suites/userProfileStoreSuite.ts +0 -134
  150. package/src/userProfile/index.ts +0 -3
  151. package/src/userProfile/interface.ts +0 -48
  152. package/src/userProfile/types.ts +0 -24
  153. package/src/utils/audit.ts +0 -46
  154. package/src/utils/index.ts +0 -2
@@ -1,45 +0,0 @@
1
- /**
2
- * Structured context attached to a reported error. All fields optional — a
3
- * report can fire before any request context is built (e.g. an
4
- * `unhandledRejection` with no active request). Deliberately NOT a
5
- * `RequestContext`: reporters must never receive the opaque `authToken`, so
6
- * only non-sensitive routing/identity fields are surfaced here.
7
- */
8
- export interface ErrorContext {
9
- /** HTTP method, when the error happened inside a request. */
10
- method?: string;
11
- /** Route pathname (never the query string — it can carry share tokens). */
12
- route?: string;
13
- /** Acting user id, when known. */
14
- userId?: string;
15
- /** Org the user was acting as, when known. */
16
- orgId?: string;
17
- /** Non-sensitive tags for grouping/search in the backend. */
18
- tags?: Record<string, string>;
19
- }
20
-
21
- /**
22
- * Sink for unexpected server errors. Called from `handleError` and the
23
- * process-level `unhandledRejection`/`uncaughtException` hooks.
24
- *
25
- * MUST NOT throw — reporting is best-effort and sits on the error path, where a
26
- * second failure would mask the first. Implementations catch and log their own
27
- * failures. MAY be fire-and-forget.
28
- */
29
- export interface IErrorReporter {
30
- /**
31
- * Report an unexpected error. `error` is whatever was thrown/rejected —
32
- * often an `Error`, but adapters occasionally reject with a plain object,
33
- * so implementations must render defensively.
34
- */
35
- capture(error: unknown, context?: ErrorContext): void;
36
- }
37
-
38
- /**
39
- * Default `IErrorReporter` — discards every report. Used when no error-tracking
40
- * backend is configured (e.g. `SENTRY_DSN` unset), so call sites can report
41
- * unconditionally. Swap in a real reporter to ship errors off-box.
42
- */
43
- export class NoopErrorReporter implements IErrorReporter {
44
- capture(_error: unknown, _context?: ErrorContext): void {}
45
- }
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
- }
@@ -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
- }
@@ -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';
@@ -1,102 +0,0 @@
1
- /**
2
- * Domain-event sink. Stores call `emit` AFTER a successful mutation; failed
3
- * writes do not emit. `emit` MUST NOT throw — failures are the sink's
4
- * problem to log and swallow.
5
- *
6
- * `actorId` is the user who triggered the change, or `'system'` for
7
- * SYSTEM_CONTEXT mutations (bootstrap, janitor, migrations).
8
- */
9
-
10
- export type DomainEvent =
11
- | { type: 'org.created'; orgId: string; actorId: string }
12
- | { type: 'org.deleted'; orgId: string; actorId: string }
13
- | { type: 'org_member.added'; orgId: string; userId: string; actorId: string }
14
- | { type: 'org_member.removed'; orgId: string; userId: string; actorId: string }
15
- | {
16
- type: 'org_member.role_changed';
17
- orgId: string;
18
- userId: string;
19
- role: string;
20
- actorId: string;
21
- }
22
- | {
23
- type: 'org_member.permissions_changed';
24
- orgId: string;
25
- userId: string;
26
- permissions: readonly string[];
27
- actorId: string;
28
- }
29
- | { type: 'project.created'; projectId: string; orgId: string; actorId: string }
30
- | { type: 'project.deleted'; projectId: string; actorId: string }
31
- | { type: 'project_member.added'; projectId: string; userId: string; actorId: string }
32
- | { type: 'project_member.removed'; projectId: string; userId: string; actorId: string }
33
- | {
34
- type: 'project_member.role_changed';
35
- projectId: string;
36
- userId: string;
37
- role: string;
38
- actorId: string;
39
- }
40
- | { type: 'definition.created'; definitionId: string; projectId: string; actorId: string }
41
- | { type: 'definition.deleted'; definitionId: string; actorId: string }
42
- | { type: 'definition.published'; definitionId: string; versionId: string; actorId: string }
43
- | {
44
- type: 'definition_version.created';
45
- versionId: string;
46
- definitionId: string;
47
- actorId: string;
48
- }
49
- | { type: 'definition_version.deleted'; versionId: string; actorId: string }
50
- | { type: 'share_link.minted'; linkId: string; definitionId: string; actorId: string }
51
- | { type: 'share_link.revoked'; linkId: string; actorId: string }
52
- | {
53
- type: 'invite.created';
54
- inviteId: string;
55
- orgId: string;
56
- email: string;
57
- actorId: string;
58
- }
59
- | { type: 'invite.accepted'; inviteId: string; orgId: string; userId: string; actorId: string }
60
- | { type: 'invite.revoked'; inviteId: string; orgId: string; actorId: string };
61
-
62
- export type DomainEventType = DomainEvent['type'];
63
-
64
- export interface IEventSink {
65
- /**
66
- * Record a domain event. Called by stores AFTER a successful mutation; a
67
- * failed write does not emit.
68
- *
69
- * MUST NOT throw — this method is on the hot path of every mutating
70
- * operation, and an exception here would surface as a failed write even
71
- * though the actual mutation already committed. Implementations MUST
72
- * catch network errors, queue overflows, and any other transient or
73
- * persistent failures internally and log them; the only side effect
74
- * visible to the caller is a fulfilled promise.
75
- *
76
- * MAY be fire-and-forget — the contract is "best-effort durable
77
- * recording," not synchronous persistence. Adapters that queue + flush
78
- * asynchronously are valid as long as they preserve event ordering per
79
- * `actorId`.
80
- */
81
- emit(event: DomainEvent): Promise<void>;
82
- }
83
-
84
- /**
85
- * Resolve the actor id from a RequestContext. Returns `ctx.userId` when set,
86
- * `'system'` otherwise — matches the `SYSTEM_CONTEXT` convention where
87
- * `userId === ''` denotes a server-internal caller (bootstrap, janitors,
88
- * migrations).
89
- */
90
- export function actorFrom(ctx: { userId: string; system?: boolean }): string {
91
- return ctx.userId || 'system';
92
- }
93
-
94
- /**
95
- * Default `IEventSink` — discards every event. Used when `SelvaConfig.events`
96
- * is omitted, and as the safe fallback for adapters whose data layer has no
97
- * event log (local-provider). Drop-in replace via `SelvaConfig.events` once a
98
- * real dispatcher is wired.
99
- */
100
- export class NoopEventSink implements IEventSink {
101
- async emit(_event: DomainEvent): Promise<void> {}
102
- }
package/src/index.ts DELETED
@@ -1,247 +0,0 @@
1
- // @selvajs/platform — published API contract. Every symbol here is breaking-change-protected.
2
-
3
- // auth
4
- export type { AuthUser, UserManagementResult, LoginResult } from './auth/types.js';
5
- export type {
6
- IAuthProvider,
7
- IOAuthAuth,
8
- IPasswordAuth,
9
- IEmailLinkAuth,
10
- IProxyAuth
11
- } from './auth/interface.js';
12
-
13
- // ---------------------------------------------------------------------------
14
- // permissions
15
- // ---------------------------------------------------------------------------
16
- export type { PlatformPermission } from './permissions/types.js';
17
- export { PlatformPermissionSchema, ALL_PLATFORM_PERMISSIONS } from './permissions/types.js';
18
- export type { IPlatformPermissionStore } from './permissions/interface.js';
19
-
20
- // userProfile
21
- export type { IUserProfileStore } from './userProfile/interface.js';
22
- export type { UserProfile, RecentRun } from './userProfile/types.js';
23
- export { emptyProfile } from './userProfile/types.js';
24
-
25
- // organizations
26
- export type { Organization, OrgMember, OrgAssets } from './organizations/types.js';
27
- export type { IOrgStore } from './organizations/interface.js';
28
- export { orgPaths } from './organizations/paths.js';
29
- export type {
30
- OrgRole,
31
- OrgPermission,
32
- OrgAssetKind,
33
- CreateOrgInput,
34
- UpdateOrgInput
35
- } from './organizations/schemas.js';
36
- export {
37
- OrgRoleSchema,
38
- OrgPermissionSchema,
39
- OrgAssetKindSchema,
40
- ALL_ORG_ASSET_KINDS,
41
- SlugSchema,
42
- CreateOrgSchema,
43
- UpdateOrgSchema,
44
- ALL_ORG_PERMISSIONS,
45
- DEFAULT_ORG_PERMISSIONS,
46
- OWNER_ADMIN_ONLY_PERMISSIONS,
47
- MEMBER_ASSIGNABLE_PERMISSIONS
48
- } from './organizations/schemas.js';
49
-
50
- // invites
51
- export type { Invite } from './invites/types.js';
52
- export type { IInviteStore } from './invites/interface.js';
53
-
54
- // projects
55
- export type { Project, ProjectMember } from './projects/types.js';
56
- export type { IProjectStore } from './projects/interface.js';
57
- export type { ProjectVisibility, ProjectRole } from './projects/schemas.js';
58
- export {
59
- ProjectVisibilitySchema,
60
- ProjectRoleSchema,
61
- validateProjectFlags
62
- } from './projects/schemas.js';
63
-
64
- // platformProjects
65
- export type { PlatformProjectGrant, PlatformProjectGranteeType } from './platformProjects/types.js';
66
- export type { IPlatformProjectGrantStore } from './platformProjects/interface.js';
67
- export {
68
- PlatformProjectGrantSchema,
69
- PlatformProjectGranteeTypeSchema
70
- } from './platformProjects/schemas.js';
71
-
72
- // definitions
73
- export type {
74
- DefinitionFileExt,
75
- DefinitionRecord,
76
- DefinitionRecordPatch,
77
- DefinitionStatus,
78
- DefinitionVersion,
79
- DefinitionChannel
80
- } from './definitions/types.js';
81
- export type { IDefinitionStore } from './definitions/interface.js';
82
- export type { UISchema } from '@selvajs/schemas';
83
- export {
84
- GH_EXTENSIONS,
85
- COVER_IMAGE_EXTENSIONS,
86
- ALLOWED_UPLOAD_EXTENSIONS,
87
- COVER_IMAGE_CONTENT_TYPES
88
- } from './definitions/types.js';
89
- export { definitionPaths } from './definitions/paths.js';
90
- export type { UpdateMetadataInput } from './definitions/schemas.js';
91
- export {
92
- DefinitionChannelSchema,
93
- PublishVersionInputSchema,
94
- CreateDefinitionInputSchema,
95
- UpdateMetadataInputSchema,
96
- GuidSchema,
97
- UUID_REGEX
98
- } from './definitions/schemas.js';
99
-
100
- // ---------------------------------------------------------------------------
101
- // shareLinks
102
- // ---------------------------------------------------------------------------
103
- export type { ShareLink } from './shareLinks/types.js';
104
- export type { IShareLinkStore } from './shareLinks/interface.js';
105
- export { DEFAULT_SHARE_LINK_MAX_SOLVES } from './shareLinks/types.js';
106
- export type { CreateShareLinkInput } from './shareLinks/schemas.js';
107
- export { CreateShareLinkInputSchema } from './shareLinks/schemas.js';
108
-
109
- // ---------------------------------------------------------------------------
110
- // storage
111
- // ---------------------------------------------------------------------------
112
- export type { IStorageProvider } from './storage/interface.js';
113
- export {
114
- IMAGE_MAX_WIDTH,
115
- IMAGE_WEBP_QUALITY,
116
- isImageUpload,
117
- toWebpPath,
118
- transcodeImageIfNeeded
119
- } from './storage/image.js';
120
- export type { TranscodeResult } from './storage/image.js';
121
- export { ASSET_CLASSES, classifyAssetPath, isPublicAssetPath } from './storage/assetClasses.js';
122
- export type {
123
- AssetVisibility,
124
- AssetScope,
125
- AssetClass,
126
- AssetMatch
127
- } from './storage/assetClasses.js';
128
- export { withCacheBust } from './storage/cacheBust.js';
129
-
130
- // ---------------------------------------------------------------------------
131
- // data (composition root)
132
- // ---------------------------------------------------------------------------
133
- export type { IDataProvider } from './data/interface.js';
134
-
135
- // ---------------------------------------------------------------------------
136
- // computeServer
137
- // ---------------------------------------------------------------------------
138
- export type {
139
- ComputeServerConfig,
140
- ComputeConfig,
141
- PlatformComputeServer,
142
- OrgComputeServer
143
- } from './computeServer/types.js';
144
- export { isPlatformServer, isOrgServer } from './computeServer/types.js';
145
- export type { IComputeServerStore } from './computeServer/interface.js';
146
- // NOTE: the at-rest secret crypto FUNCTIONS (`encryptSecret` etc.) are NOT
147
- // re-exported here — they use `node:crypto` and this barrel is imported by
148
- // client `.svelte` code, so a browser bundle would fail to resolve them. Import
149
- // them from `@selvajs/platform/computeServer` (server-only) instead. The report
150
- // TYPES are erased at build, so they stay here for convenience.
151
- export type {
152
- SecretVerificationReport,
153
- SecretVerificationFailure,
154
- SecretVerificationFailureReason
155
- } from './computeServer/secrets.js';
156
- export type { ResolveOptions } from './computeServer/utils.js';
157
- export {
158
- serversVisibleTo,
159
- defaultServerIdFor,
160
- resolveServerForOrg,
161
- findServerById,
162
- platformServers,
163
- orgServersFor
164
- } from './computeServer/utils.js';
165
-
166
- // ---------------------------------------------------------------------------
167
- // access (pure permission predicates)
168
- // ---------------------------------------------------------------------------
169
- export type {
170
- ProjectAccessInput,
171
- DefinitionAccessInput,
172
- VisibilityChangeInput,
173
- ReclaimAccessInput,
174
- CreateProjectAccessInput,
175
- OwnerRemovalInput,
176
- OwnerRemovalCheck
177
- } from './access/rules.js';
178
- export {
179
- canView,
180
- canSolve,
181
- canEdit,
182
- canManage,
183
- canEditProjectSettings,
184
- canChangeVisibilityToPublic,
185
- canEditDefinition,
186
- canReclaim,
187
- canCreateProject,
188
- checkOwnerRemoval,
189
- withAdminBypass
190
- } from './access/rules.js';
191
-
192
- // ---------------------------------------------------------------------------
193
- // events
194
- // ---------------------------------------------------------------------------
195
- export type { DomainEvent, DomainEventType, IEventSink } from './events/interface.js';
196
- export { actorFrom, NoopEventSink } from './events/interface.js';
197
- export type {
198
- AuditEventRow,
199
- AuditCursor,
200
- AuditQueryFilters,
201
- AuditQueryResult,
202
- IAuditQuery
203
- } from './events/audit.js';
204
-
205
- // ---------------------------------------------------------------------------
206
- // metrics (per-solve timing telemetry)
207
- // ---------------------------------------------------------------------------
208
- export type { ISolveMetricSink, SolveMetric, SolveFailureKind } from './metrics/interface.js';
209
- export { NoopSolveMetricSink } from './metrics/interface.js';
210
-
211
- // ---------------------------------------------------------------------------
212
- // errors (unexpected-error reporting)
213
- // ---------------------------------------------------------------------------
214
- export type { IErrorReporter, ErrorContext } from './errors/interface.js';
215
- export { NoopErrorReporter } from './errors/interface.js';
216
-
217
- // ---------------------------------------------------------------------------
218
- // bindings (server-side resolver for schema inputs marked `source.kind === 'server'`)
219
- // ---------------------------------------------------------------------------
220
- export type { IBindingResolver } from './bindings/interface.js';
221
- export { NoopBindingResolver } from './bindings/interface.js';
222
-
223
- // ---------------------------------------------------------------------------
224
- // utils
225
- // ---------------------------------------------------------------------------
226
- export type { AuditUpdate, AuditSoftDelete } from './utils/audit.js';
227
- export { auditUpdate, auditSoftDelete } from './utils/audit.js';
228
-
229
- // ---------------------------------------------------------------------------
230
- // top-level (context, pagination, config, errors)
231
- // ---------------------------------------------------------------------------
232
- export type { RequestContext } from './context.js';
233
- export { SYSTEM_CONTEXT, hasPermission, requireActingOrg } from './context.js';
234
-
235
- export type { ListOptions, DefinitionListOptions, Page } from './pagination.js';
236
- export { DEFAULT_PAGE_LIMIT, MAX_PAGE_LIMIT } from './pagination.js';
237
-
238
- export type {
239
- TenancyMode,
240
- SelvaFlags,
241
- SelvaBranding,
242
- SelvaConfig,
243
- SelvaConfigFactory
244
- } from './config.js';
245
- export { isFlagEnabled, defineConfig } from './config.js';
246
-
247
- export { ProviderError } from './errors.js';
@@ -1,2 +0,0 @@
1
- export type { Invite } from './types.js';
2
- export type { IInviteStore } from './interface.js';
@@ -1,38 +0,0 @@
1
- import type { RequestContext } from '../context.js';
2
- import type { ListOptions, Page } from '../pagination.js';
3
- import type { Invite } from './types.js';
4
-
5
- /**
6
- * "Admin invites a user, user clicks link and joins" flow. Decoupled from
7
- * `IAuthProvider` so accept works regardless of how credentials are owned.
8
- *
9
- * Mutations require a session (gated by route layer). `getByTokenHash` and
10
- * `markAccepted` accept `SYSTEM_CONTEXT` because the token is the capability
11
- * — the public /accept-invite page has no session yet.
12
- */
13
- export interface IInviteStore {
14
- create(ctx: RequestContext, invite: Invite): Promise<void>;
15
-
16
- /**
17
- * Lookup by HMAC hash of the raw token. Caller hashes the inbound token
18
- * (e.g. via `packages/selva/src/lib/server/invites/token.server.ts`) and
19
- * passes the digest here. Returns null for unknown, expired, or
20
- * consumed invites.
21
- */
22
- getByTokenHash(ctx: RequestContext, tokenHash: string): Promise<Invite | null>;
23
-
24
- listByOrg(ctx: RequestContext, orgId: string, opts?: ListOptions): Promise<Page<Invite>>;
25
-
26
- /** No-op if already accepted. */
27
- markAccepted(ctx: RequestContext, id: string, userId: string): Promise<void>;
28
-
29
- /** No-op if already consumed or missing. */
30
- revoke(ctx: RequestContext, id: string): Promise<void>;
31
-
32
- /**
33
- * Hard-delete every invite belonging to an org. Called from `deleteOrg`
34
- * cascade — pending invites to a deleted org are unredeemable, so leaving
35
- * them behind only creates orphans.
36
- */
37
- deleteByOrg(ctx: RequestContext, orgId: string): Promise<void>;
38
- }
@@ -1,39 +0,0 @@
1
- import type { OrgRole, OrgPermission } from '../organizations/schemas.js';
2
-
3
- /**
4
- * "The holder of the raw token whose hash is `tokenHash` may join `orgId` at
5
- * `orgRole` with these org permissions." Accepting creates the user (if
6
- * needed), the org membership, and marks the invite consumed.
7
- *
8
- * The raw token is shown to the admin once at mint time and embedded in the
9
- * accept URL; the store sees only `HMAC-SHA256(secret, rawToken)`. A DB-only
10
- * leak therefore can't be replayed — the attacker would need the instance
11
- * secret too. Mirrors the share-link design (`ShareLink.tokenHash`).
12
- *
13
- * `getByTokenHash` is callable without a session — knowing a valid token
14
- * (and therefore being able to hash it) is the auth.
15
- */
16
- export interface Invite {
17
- id: string;
18
- /**
19
- * `HMAC-SHA256(INVITE_TOKEN_SECRET, rawToken)` — base64url. The raw token
20
- * never crosses the store boundary; the route layer hashes inbound tokens
21
- * before lookup.
22
- */
23
- tokenHash: string;
24
- /** Lowercase email the invite was issued for. */
25
- email: string;
26
- orgId: string;
27
- orgRole: OrgRole;
28
- /**
29
- * Permissions to grant on accept. May be empty — adapters may seed from
30
- * `DEFAULT_ORG_PERMISSIONS` in that case.
31
- */
32
- orgPermissions: OrgPermission[];
33
- invitedBy: string;
34
- createdAt: string;
35
- expiresAt: string;
36
- /** Set when consumed. Consumed invites are not re-usable. */
37
- acceptedAt?: string;
38
- acceptedByUserId?: string;
39
- }
@@ -1,86 +0,0 @@
1
- import type { RequestContext } from '../context.js';
2
-
3
- /**
4
- * Why a solve did not produce a usable result. `ok` means the solve completed
5
- * (it may still carry Grasshopper runtime errors — see `errorCount`). The
6
- * failure kinds mirror the distinct branches the compute route already
7
- * distinguishes, so the recorded reason matches the HTTP status the client saw.
8
- */
9
- export type SolveFailureKind =
10
- /** Solve completed; the response was returned to the client. */
11
- | 'ok'
12
- /** Scheduler deadline exceeded (HTTP 504). */
13
- | 'timeout'
14
- /** Client disconnected mid-solve; the request signal aborted (HTTP 499). */
15
- | 'client_abort'
16
- /** Rejected by the per-key rate limiter before solving (HTTP 429). */
17
- | 'rate_limited'
18
- /** Share-link solve cap reached before solving (HTTP 429). */
19
- | 'share_cap'
20
- /** Result exceeded the response size limit (HTTP 413). */
21
- | 'too_large'
22
- /** Compute server unreachable or the solve threw for any other reason. */
23
- | 'compute_error';
24
-
25
- /**
26
- * One solve's timing and outcome, recorded once per solve attempt — including
27
- * attempts rejected before `scheduler.solve()` runs (rate limit, share cap).
28
- *
29
- * `durationMs` is wall time around the Rhino.Compute solve call only — it
30
- * excludes definition loading, auth, schema work, and result serialization. It
31
- * is 0 for attempts rejected before the solve started.
32
- */
33
- export interface SolveMetric {
34
- /** Definition the solve ran against. `local:<guid>` or a remote URL. */
35
- definitionUrl: string;
36
- /**
37
- * Local definition id (the `local:` guid), or null for remote-URL solves.
38
- * Stored alongside `definitionUrl` so timings join to the definition record.
39
- */
40
- definitionId: string | null;
41
- /**
42
- * The exact version solved, or null for remote-URL solves (and for local
43
- * attempts rejected before the version resolved). Lets you compare timings
44
- * across versions of the same definition.
45
- */
46
- versionId: string | null;
47
- /** Channel solved, mirroring the compute request. */
48
- channel: 'live' | 'draft';
49
- /** Org whose compute pool served the solve, or null for remote definitions. */
50
- orgId: string | null;
51
- /** Wall-clock duration of `scheduler.solve()` in milliseconds. 0 if never started. */
52
- durationMs: number;
53
- /** Whether the solve completed and returned a result. */
54
- ok: boolean;
55
- /** Why the solve did not return a result; `'ok'` when it did. */
56
- failureKind: SolveFailureKind;
57
- /**
58
- * Count of Grasshopper runtime errors in the solve response. A solve can be
59
- * `ok` yet still report component-level errors — this is distinct from
60
- * `failureKind`. 0 when the solve never returned a response.
61
- */
62
- errorCount: number;
63
- /** Count of Grasshopper runtime warnings in the solve response. */
64
- warningCount: number;
65
- }
66
-
67
- /**
68
- * Sink for per-solve timing telemetry. Called once per solve attempt from the
69
- * compute route, AFTER the solve resolves or rejects.
70
- *
71
- * MUST NOT throw — recording is best-effort and sits on the hot path of every
72
- * solve. Implementations catch and log their own failures; the only side
73
- * effect visible to the caller is a fulfilled promise. MAY be fire-and-forget.
74
- */
75
- export interface ISolveMetricSink {
76
- record(ctx: RequestContext, metric: SolveMetric): Promise<void>;
77
- }
78
-
79
- /**
80
- * Default `ISolveMetricSink` — discards every metric. Used when
81
- * `SelvaConfig.solveMetrics` is omitted. Swap in a real sink to persist or
82
- * aggregate solve timings.
83
- */
84
- export class NoopSolveMetricSink implements ISolveMetricSink {
85
- async record(_ctx: RequestContext, _metric: SolveMetric): Promise<void> {}
86
- }
@@ -1,23 +0,0 @@
1
- export type { Organization, OrgMember, OrgAssets } from './types.js';
2
- export type { IOrgStore } from './interface.js';
3
- export { orgPaths } from './paths.js';
4
- export type {
5
- OrgRole,
6
- OrgPermission,
7
- OrgAssetKind,
8
- CreateOrgInput,
9
- UpdateOrgInput
10
- } from './schemas.js';
11
- export {
12
- OrgRoleSchema,
13
- OrgPermissionSchema,
14
- OrgAssetKindSchema,
15
- ALL_ORG_ASSET_KINDS,
16
- SlugSchema,
17
- CreateOrgSchema,
18
- UpdateOrgSchema,
19
- ALL_ORG_PERMISSIONS,
20
- DEFAULT_ORG_PERMISSIONS,
21
- OWNER_ADMIN_ONLY_PERMISSIONS,
22
- MEMBER_ASSIGNABLE_PERMISSIONS
23
- } from './schemas.js';