@hachej/boring-core 0.1.48 → 0.1.50

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.
@@ -1,17 +1,17 @@
1
- import { L as LoadConfigOptions } from '../authHook-DtzhSmqS.js';
2
- export { A as AuthHookOptions, B as BetterAuthInstance, C as CreateAuthOptions, a as authHook, b as buildRuntimeConfigPayload, c as createAuth, l as loadConfig, v as validateConfig, d as validatePasswordStrength } from '../authHook-DtzhSmqS.js';
1
+ import { L as LoadConfigOptions } from '../authHook-BbgCBHjP.js';
2
+ export { A as AuthHookOptions, B as BetterAuthInstance, C as CreateAuthOptions, a as authHook, b as buildRuntimeConfigPayload, c as createAuth, l as loadConfig, v as validateConfig, d as validatePasswordStrength } from '../authHook-BbgCBHjP.js';
3
3
  import { z } from 'zod';
4
- import { C as CoreConfig, M as MemberRole, d as WorkspaceRuntimeResourceSelector, e as WorkspaceRuntimeResource, f as WorkspaceRuntimeResourceInput } from '../types-CWtJ4kgd.js';
4
+ import { C as CoreConfig, M as MemberRole, W as WorkspaceRuntimeResourceSelector, a as WorkspaceRuntimeResource, b as WorkspaceRuntimeResourceInput } from '../types-Bb7I-83I.js';
5
5
  import * as fastify from 'fastify';
6
6
  import { FastifyInstance, FastifyPluginAsync, preHandlerHookHandler, FastifyRequest, FastifyReply } from 'fastify';
7
7
  import * as http from 'http';
8
8
  import { IncomingMessage } from 'node:http';
9
- import { C as CreateCoreAppOptions, D as Database, U as UserStore, W as WorkspaceStore, a as WorkspaceProvisioner } from '../connection-C5SiqoNc.js';
10
- export { A as AuthProvider, b as CapabilitiesContributor, P as ProvisionContext, d as ProvisionResult, c as createDatabase } from '../connection-C5SiqoNc.js';
9
+ import { C as CreateCoreAppOptions, D as Database, U as UserStore, W as WorkspaceStore, a as WorkspaceProvisioner } from '../connection-B1iC6B-w.js';
10
+ export { A as AuthProvider, b as CapabilitiesContributor, P as ProvisionContext, c as ProvisionResult, d as createDatabase } from '../connection-B1iC6B-w.js';
11
11
  import postgres from 'postgres';
12
- import { P as PostgresMeteringStore, C as CreditLedgerEntry } from '../PostgresMeteringStore-DhOVVtau.js';
13
- export { F as FinishReservationInput, G as GrantOnceInput, I as InsufficientCreditError, M as MeteringBalance, R as RecordUsageInput, a as RecordUsageResult, b as ReservationFinalStatus, c as ReserveInput, d as ReserveResult, r as runMigrations } from '../PostgresMeteringStore-DhOVVtau.js';
14
- import { TelemetrySink } from '../shared/index.js';
12
+ import { P as PostgresMeteringStore, C as CreditLedgerEntry } from '../PostgresMeteringStore-qjKGmVFr.js';
13
+ export { F as FinishReservationInput, G as GrantOnceInput, I as InsufficientCreditError, M as MeteringBalance, R as RecordUsageInput, a as RecordUsageResult, b as ReservationFinalStatus, c as ReserveInput, d as ReserveResult, r as runMigrations } from '../PostgresMeteringStore-qjKGmVFr.js';
14
+ import { T as TelemetrySink } from '../telemetry-DR18MeI0.js';
15
15
  import { AgentMeteringSink } from '@hachej/boring-agent/server';
16
16
  import 'better-auth';
17
17
  import 'drizzle-orm/postgres-js';
@@ -166,23 +166,6 @@ declare const coreConfigSchema: z.ZodObject<{
166
166
  inviteTtlDays?: number | undefined;
167
167
  }>;
168
168
  }, "strip", z.ZodTypeAny, {
169
- appId: string;
170
- appName: string;
171
- appLogo: string | null;
172
- port: number;
173
- host: string;
174
- staticDir: string | null;
175
- databaseUrl: string | null;
176
- stores: "postgres" | "local";
177
- cors: {
178
- origins: string[];
179
- credentials: true;
180
- };
181
- bodyLimit: number;
182
- logLevel: "error" | "fatal" | "warn" | "info" | "debug" | "trace";
183
- encryption: {
184
- workspaceSettingsKey: string;
185
- };
186
169
  auth: {
187
170
  secret: string;
188
171
  url: string;
@@ -201,6 +184,23 @@ declare const coreConfigSchema: z.ZodObject<{
201
184
  transportUrl: string;
202
185
  } | undefined;
203
186
  };
187
+ appId: string;
188
+ appName: string;
189
+ appLogo: string | null;
190
+ port: number;
191
+ host: string;
192
+ staticDir: string | null;
193
+ databaseUrl: string | null;
194
+ stores: "postgres" | "local";
195
+ cors: {
196
+ origins: string[];
197
+ credentials: true;
198
+ };
199
+ bodyLimit: number;
200
+ logLevel: "error" | "fatal" | "warn" | "info" | "debug" | "trace";
201
+ encryption: {
202
+ workspaceSettingsKey: string;
203
+ };
204
204
  features: {
205
205
  githubOauth: boolean;
206
206
  googleOauth: boolean;
@@ -219,23 +219,6 @@ declare const coreConfigSchema: z.ZodObject<{
219
219
  };
220
220
  } | undefined;
221
221
  }, {
222
- appId: string;
223
- appName: string;
224
- appLogo: string | null;
225
- port: number;
226
- host: string;
227
- staticDir: string | null;
228
- databaseUrl: string | null;
229
- stores: "postgres" | "local";
230
- cors: {
231
- origins: string[];
232
- credentials: true;
233
- };
234
- bodyLimit: number;
235
- logLevel: "error" | "fatal" | "warn" | "info" | "debug" | "trace";
236
- encryption: {
237
- workspaceSettingsKey: string;
238
- };
239
222
  auth: {
240
223
  secret: string;
241
224
  url: string;
@@ -254,6 +237,23 @@ declare const coreConfigSchema: z.ZodObject<{
254
237
  transportUrl: string;
255
238
  } | undefined;
256
239
  };
240
+ appId: string;
241
+ appName: string;
242
+ appLogo: string | null;
243
+ port: number;
244
+ host: string;
245
+ staticDir: string | null;
246
+ databaseUrl: string | null;
247
+ stores: "postgres" | "local";
248
+ cors: {
249
+ origins: string[];
250
+ credentials: true;
251
+ };
252
+ bodyLimit: number;
253
+ logLevel: "error" | "fatal" | "warn" | "info" | "debug" | "trace";
254
+ encryption: {
255
+ workspaceSettingsKey: string;
256
+ };
257
257
  features: {
258
258
  githubOauth: boolean;
259
259
  googleOauth: boolean;
@@ -533,16 +533,21 @@ interface CreditsConfig {
533
533
  /** Days until the signup grant expires; null = never. */
534
534
  signupGrantExpiresAfterDays: number | null;
535
535
  /**
536
- * Per-run hold, in credit micros. This is the per-run overdraft bound: a run
537
- * is admitted against this hold, but the actual charge is posted afterward, so
538
- * a single run can overshoot the hold by (actualCost − hold). Set this to
539
- * cover your worst-case single run (max tokens on the priciest enabled model)
540
- * so the hard stop is effectively exact.
536
+ * Per-run hold, in credit micros. This is the per-run fallback-charge / usage
537
+ * budget: the actual charge is posted afterward, so a single run can overshoot
538
+ * the hold by (actualCost − hold).
541
539
  */
542
540
  runReservationMicros: number;
543
541
  reservationTtlSeconds: number;
544
- /** Floor below which a run is refused. */
542
+ /** Floor kept available after placing the hold when runAdmissionMicros is unset. */
545
543
  minBalanceMicros: number;
544
+ /**
545
+ * Available balance required before a run can start. Defaults to
546
+ * runReservationMicros + minBalanceMicros for the conservative no-debt posture.
547
+ * Apps may set this lower intentionally to let users spend down to a product
548
+ * threshold, accepting bounded recoverable debt for low-balance runs.
549
+ */
550
+ runAdmissionMicros?: number;
546
551
  pricing: CreditPricingConfig;
547
552
  }
548
553
  declare const DEFAULT_CREDITS_CONFIG: CreditsConfig;
@@ -24,20 +24,21 @@ import {
24
24
  requireWorkspaceMember,
25
25
  validateConfig,
26
26
  validatePasswordStrength
27
- } from "../chunk-6GAQRQKO.js";
27
+ } from "../chunk-ZMS6O4CY.js";
28
28
  import {
29
29
  InsufficientCreditError,
30
30
  PostgresMeteringStore,
31
31
  createDatabase,
32
32
  runMigrations
33
- } from "../chunk-FZC3VL5D.js";
33
+ } from "../chunk-BVZ2YT3M.js";
34
34
  import {
35
35
  noopTelemetry,
36
36
  safeCapture
37
37
  } from "../chunk-AQBXNPMD.js";
38
+ import "../chunk-I4PGL4ZD.js";
38
39
  import {
39
40
  ERROR_CODES
40
- } from "../chunk-LIBHVT7V.js";
41
+ } from "../chunk-QZGYKLXB.js";
41
42
  import "../chunk-MLKGABMK.js";
42
43
 
43
44
  // src/server/security/safeRedirect.ts
@@ -254,6 +255,7 @@ var CreditsService = class {
254
255
  if (!nonNegInt(config.signupGrantMicros)) throw new Error("credits: signupGrantMicros must be a non-negative safe integer");
255
256
  if (!posInt(config.runReservationMicros)) throw new Error("credits: runReservationMicros must be a positive safe integer");
256
257
  if (!nonNegInt(config.minBalanceMicros)) throw new Error("credits: minBalanceMicros must be a non-negative safe integer");
258
+ if (config.runAdmissionMicros !== void 0 && !nonNegInt(config.runAdmissionMicros)) throw new Error("credits: runAdmissionMicros must be a non-negative safe integer");
257
259
  if (!posInt(config.reservationTtlSeconds)) throw new Error("credits: reservationTtlSeconds must be a positive safe integer");
258
260
  if (!Number.isSafeInteger(config.runReservationMicros + config.minBalanceMicros)) {
259
261
  throw new Error("credits: runReservationMicros + minBalanceMicros exceeds the safe integer range");
@@ -362,9 +364,9 @@ var CreditsService = class {
362
364
  source: "pi-chat",
363
365
  amountMicros: this.config.runReservationMicros,
364
366
  ttlSeconds: this.config.reservationTtlSeconds,
365
- // Must keep minBalanceMicros available AFTER placing the hold, so a run
366
- // is admitted only when available hold + floor (matches the config doc).
367
- minAvailableMicros: this.config.runReservationMicros + this.config.minBalanceMicros
367
+ // Conservative default is hold + floor; apps can explicitly lower this
368
+ // threshold with runAdmissionMicros to allow bounded-debt low-balance runs.
369
+ minAvailableMicros: this.config.runAdmissionMicros ?? this.config.runReservationMicros + this.config.minBalanceMicros
368
370
  });
369
371
  if (created) safeCapture(this.telemetry, { name: "run.started", distinctId: input.userId });
370
372
  return reservationId;
@@ -1,15 +1,9 @@
1
- export { g as CapabilitiesResponse, h as ConfigFetchError, i as ConfigValidationError, j as CoreCapabilities, C as CoreConfig, E as ERROR_CODES, k as ErrorCode, H as HttpError, J as JsonValue, M as MemberRole, l as RateLimitEndpointOverride, R as RuntimeConfig, m as SessionPayload, S as SessionState, U as User, W as Workspace, b as WorkspaceInvite, a as WorkspaceMember, c as WorkspaceRuntime } from '../types-CWtJ4kgd.js';
1
+ import { U as User, C as CoreConfig, R as RuntimeConfig } from '../types-Bb7I-83I.js';
2
+ export { g as CapabilitiesResponse, h as ConfigFetchError, i as ConfigValidationError, j as CoreCapabilities, E as ERROR_CODES, k as ErrorCode, H as HttpError, J as JsonValue, M as MemberRole, l as RateLimitEndpointOverride, m as SessionPayload, S as SessionState, c as Workspace, e as WorkspaceInvite, d as WorkspaceMember, f as WorkspaceRuntime } from '../types-Bb7I-83I.js';
3
+ export { a as TelemetryEvent, T as TelemetrySink, n as noopTelemetry, s as safeCapture } from '../telemetry-DR18MeI0.js';
2
4
 
3
- interface TelemetrySink {
4
- capture(event: TelemetryEvent): void | Promise<void>;
5
- flush?(): void | Promise<void>;
6
- }
7
- interface TelemetryEvent {
8
- name: string;
9
- distinctId?: string;
10
- properties?: Record<string, unknown>;
11
- }
12
- declare const noopTelemetry: TelemetrySink;
13
- declare function safeCapture(telemetry: TelemetrySink, event: TelemetryEvent): void;
5
+ declare function isCoreEmailVerificationEnabled(config: Pick<CoreConfig, 'auth'>): boolean;
6
+ declare function isRuntimeEmailVerificationEnabled(config: Pick<RuntimeConfig, 'features'> | null | undefined): boolean;
7
+ declare function canUseProtectedApi(user: Pick<User, 'emailVerified'> | null | undefined, requireEmailVerification: boolean): boolean;
14
8
 
15
- export { type TelemetryEvent, type TelemetrySink, noopTelemetry, safeCapture };
9
+ export { CoreConfig, RuntimeConfig, User, canUseProtectedApi, isCoreEmailVerificationEnabled, isRuntimeEmailVerificationEnabled };
@@ -2,18 +2,26 @@ import {
2
2
  noopTelemetry,
3
3
  safeCapture
4
4
  } from "../chunk-AQBXNPMD.js";
5
+ import {
6
+ canUseProtectedApi,
7
+ isCoreEmailVerificationEnabled,
8
+ isRuntimeEmailVerificationEnabled
9
+ } from "../chunk-I4PGL4ZD.js";
5
10
  import {
6
11
  ConfigFetchError,
7
12
  ConfigValidationError,
8
13
  ERROR_CODES,
9
14
  HttpError
10
- } from "../chunk-LIBHVT7V.js";
15
+ } from "../chunk-QZGYKLXB.js";
11
16
  import "../chunk-MLKGABMK.js";
12
17
  export {
13
18
  ConfigFetchError,
14
19
  ConfigValidationError,
15
20
  ERROR_CODES,
16
21
  HttpError,
22
+ canUseProtectedApi,
23
+ isCoreEmailVerificationEnabled,
24
+ isRuntimeEmailVerificationEnabled,
17
25
  noopTelemetry,
18
26
  safeCapture
19
27
  };
@@ -0,0 +1,13 @@
1
+ interface TelemetrySink {
2
+ capture(event: TelemetryEvent): void | Promise<void>;
3
+ flush?(): void | Promise<void>;
4
+ }
5
+ interface TelemetryEvent {
6
+ name: string;
7
+ distinctId?: string;
8
+ properties?: Record<string, unknown>;
9
+ }
10
+ declare const noopTelemetry: TelemetrySink;
11
+ declare function safeCapture(telemetry: TelemetrySink, event: TelemetryEvent): void;
12
+
13
+ export { type TelemetrySink as T, type TelemetryEvent as a, noopTelemetry as n, safeCapture as s };
@@ -3,6 +3,7 @@ declare const ERROR_CODES: {
3
3
  readonly FORBIDDEN: "forbidden";
4
4
  readonly WEAK_PASSWORD: "weak_password";
5
5
  readonly EMAIL_IN_USE: "email_in_use";
6
+ readonly EMAIL_NOT_VERIFIED: "email_not_verified";
6
7
  readonly NOT_MEMBER: "not_member";
7
8
  readonly LAST_OWNER: "last_owner";
8
9
  readonly INVITE_NOT_FOUND: "invite_not_found";
@@ -239,6 +240,7 @@ interface RuntimeConfig {
239
240
  googleOauth: boolean;
240
241
  invitesEnabled: boolean;
241
242
  sendWelcomeEmail: boolean;
243
+ emailVerification: boolean;
242
244
  };
243
245
  }
244
246
  type JsonValue = string | number | boolean | null | JsonValue[] | {
@@ -274,4 +276,4 @@ type CapabilitiesResponse = {
274
276
  [contributorName: string]: JsonValue | CoreCapabilities | undefined;
275
277
  };
276
278
 
277
- export { type CoreConfig as C, ERROR_CODES as E, HttpError as H, type JsonValue as J, type MemberRole as M, type RuntimeConfig as R, type SessionState as S, type User as U, type Workspace as W, type WorkspaceMember as a, type WorkspaceInvite as b, type WorkspaceRuntime as c, type WorkspaceRuntimeResourceSelector as d, type WorkspaceRuntimeResource as e, type WorkspaceRuntimeResourceInput as f, type CapabilitiesResponse as g, ConfigFetchError as h, ConfigValidationError as i, type CoreCapabilities as j, type ErrorCode as k, type RateLimitEndpointOverride as l, type SessionPayload as m };
279
+ export { type CoreConfig as C, ERROR_CODES as E, HttpError as H, type JsonValue as J, type MemberRole as M, type RuntimeConfig as R, type SessionState as S, type User as U, type WorkspaceRuntimeResourceSelector as W, type WorkspaceRuntimeResource as a, type WorkspaceRuntimeResourceInput as b, type Workspace as c, type WorkspaceMember as d, type WorkspaceInvite as e, type WorkspaceRuntime as f, type CapabilitiesResponse as g, ConfigFetchError as h, ConfigValidationError as i, type CoreCapabilities as j, type ErrorCode as k, type RateLimitEndpointOverride as l, type SessionPayload as m };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hachej/boring-core",
3
- "version": "0.1.48",
3
+ "version": "0.1.50",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Foundation package for boring-ui-v2 apps: DB, auth, config, HTTP app factory, and frontend app shell.",
@@ -79,9 +79,9 @@
79
79
  "react-router-dom": "^7.14.2",
80
80
  "smol-toml": "^1.6.1",
81
81
  "zod": "^3.25.76",
82
- "@hachej/boring-agent": "0.1.48",
83
- "@hachej/boring-ui-kit": "0.1.48",
84
- "@hachej/boring-workspace": "0.1.48"
82
+ "@hachej/boring-agent": "0.1.50",
83
+ "@hachej/boring-ui-kit": "0.1.50",
84
+ "@hachej/boring-workspace": "0.1.50"
85
85
  },
86
86
  "devDependencies": {
87
87
  "@testing-library/jest-dom": "^6.9.1",
@@ -113,7 +113,8 @@
113
113
  }
114
114
  },
115
115
  "scripts": {
116
- "build": "tsup && cp src/front/theme.css dist/front/theme.css && mkdir -p dist/app/front && cp src/app/front/styles.css dist/app/front/styles.css",
116
+ "build": "tsup && pnpm run build:assert",
117
+ "build:assert": "node ./scripts/assert-build-artifacts.mjs",
117
118
  "dev": "tsup --watch",
118
119
  "test": "vitest run --no-file-parallelism",
119
120
  "test:watch": "vitest",