@wopr-network/platform-core 0.1.0 → 1.0.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/.github/workflows/ci.yml +43 -0
- package/.github/workflows/dependabot-auto-merge.yml +11 -0
- package/.github/workflows/publish.yml +12 -0
- package/.pr_agent.toml +10 -0
- package/coverage/coverage-summary.json +119 -0
- package/dist/admin/index.d.ts +1 -1
- package/dist/billing/drizzle-webhook-seen-repository.d.ts +1 -1
- package/dist/billing/index.d.ts +4 -4
- package/dist/billing/index.js +4 -4
- package/dist/billing/payram/webhook.test.js +1 -1
- package/dist/billing/stripe/index.d.ts +5 -5
- package/dist/billing/stripe/index.js +2 -2
- package/dist/billing/stripe/stripe-payment-processor.js +1 -1
- package/dist/credits/auto-topup-charge.d.ts +2 -2
- package/dist/credits/auto-topup-charge.test.js +1 -1
- package/dist/credits/auto-topup-schedule.d.ts +1 -1
- package/dist/credits/auto-topup-schedule.test.js +1 -1
- package/dist/credits/auto-topup-settings-repository.test.js +1 -1
- package/dist/credits/auto-topup-usage.d.ts +1 -1
- package/dist/credits/auto-topup-usage.test.js +1 -1
- package/dist/credits/index.d.ts +1 -1
- package/dist/credits/index.js +1 -1
- package/dist/db/schema/index.d.ts +1 -1
- package/dist/db/schema/index.js +1 -1
- package/dist/email/index.d.ts +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +4 -3
- package/dist/metering/aggregator.test.js +1 -1
- package/dist/metering/emitter.test.js +1 -1
- package/dist/metering/load-test.bench.js +1 -1
- package/dist/metering/metering.test.js +1 -1
- package/dist/metering/reconciliation-cron.test.js +2 -2
- package/dist/metering/reconciliation-repository.test.js +1 -1
- package/dist/middleware/index.d.ts +3 -3
- package/dist/middleware/index.js +2 -2
- package/dist/security/credential-vault/index.d.ts +2 -2
- package/dist/security/index.d.ts +7 -7
- package/dist/security/index.js +7 -7
- package/dist/security/redirect-allowlist.js +10 -8
- package/dist/security/tenant-keys/index.d.ts +6 -6
- package/dist/security/tenant-keys/index.js +3 -3
- package/dist/tenancy/index.d.ts +3 -3
- package/dist/tenancy/org-service.d.ts +1 -1
- package/dist/tenancy/org-service.test.js +1 -1
- package/dist/trpc/index.d.ts +1 -1
- package/dist/trpc/index.js +1 -1
- package/dist/trpc/init.test.js +3 -5
- package/package.json +10 -1
- package/src/admin/index.ts +1 -1
- package/src/auth/better-auth.ts +1 -1
- package/src/billing/drizzle-webhook-seen-repository.ts +1 -1
- package/src/billing/index.ts +11 -13
- package/src/billing/payram/webhook.test.ts +1 -1
- package/src/billing/stripe/index.ts +17 -5
- package/src/billing/stripe/stripe-payment-processor.test.ts +2 -3
- package/src/billing/stripe/stripe-payment-processor.ts +1 -1
- package/src/credits/auto-topup-charge.test.ts +2 -2
- package/src/credits/auto-topup-charge.ts +2 -2
- package/src/credits/auto-topup-schedule.test.ts +1 -1
- package/src/credits/auto-topup-schedule.ts +1 -1
- package/src/credits/auto-topup-settings-repository.test.ts +1 -1
- package/src/credits/auto-topup-usage.test.ts +1 -1
- package/src/credits/auto-topup-usage.ts +1 -1
- package/src/credits/index.ts +1 -1
- package/src/db/schema/index.ts +1 -1
- package/src/email/index.ts +3 -3
- package/src/index.ts +13 -17
- package/src/metering/aggregator.test.ts +1 -1
- package/src/metering/emitter.test.ts +1 -1
- package/src/metering/load-test.bench.ts +1 -1
- package/src/metering/metering.test.ts +1 -1
- package/src/metering/reconciliation-cron.test.ts +2 -2
- package/src/metering/reconciliation-repository.test.ts +2 -2
- package/src/middleware/index.ts +5 -5
- package/src/middleware/rate-limit.test.ts +1 -1
- package/src/middleware/rate-limit.ts +1 -1
- package/src/security/credential-vault/index.ts +2 -2
- package/src/security/index.ts +43 -38
- package/src/security/redirect-allowlist.ts +11 -8
- package/src/security/tenant-keys/index.ts +10 -6
- package/src/tenancy/index.ts +3 -3
- package/src/tenancy/org-service.test.ts +1 -1
- package/src/tenancy/org-service.ts +1 -1
- package/src/trpc/index.ts +5 -5
- package/src/trpc/init.test.ts +8 -10
- package/vitest.config.ts +4 -0
- package/dist/email/require-verified.test.d.ts +0 -1
- package/dist/email/require-verified.test.js +0 -62
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { unlinkSync } from "node:fs";
|
|
2
2
|
import { afterEach, beforeEach, bench, describe } from "vitest";
|
|
3
|
-
import { createTestDb } from "../test/db.js";
|
|
4
3
|
import { Credit } from "../credits/credit.js";
|
|
4
|
+
import { createTestDb } from "../test/db.js";
|
|
5
5
|
import { MeterAggregator } from "./aggregator.js";
|
|
6
6
|
import { DrizzleUsageSummaryRepository } from "./drizzle-usage-summary-repository.js";
|
|
7
7
|
import { MeterEmitter } from "./emitter.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { existsSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { eq, sql } from "drizzle-orm";
|
|
3
3
|
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
|
4
|
+
import { Credit } from "../credits/credit.js";
|
|
4
5
|
import { meterEvents } from "../db/schema/meter-events.js";
|
|
5
6
|
import { createTestDb, truncateAllTables } from "../test/db.js";
|
|
6
|
-
import { Credit } from "../credits/credit.js";
|
|
7
7
|
import { MeterAggregator } from "./aggregator.js";
|
|
8
8
|
import { DrizzleUsageSummaryRepository } from "./drizzle-usage-summary-repository.js";
|
|
9
9
|
import { MeterEmitter } from "./emitter.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
2
|
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
|
3
|
-
import { usageSummaries } from "../db/schema/meter-events.js";
|
|
4
|
-
import { createTestDb, truncateAllTables } from "../test/db.js";
|
|
5
3
|
import { Credit } from "../credits/credit.js";
|
|
6
4
|
import { CreditLedger } from "../credits/credit-ledger.js";
|
|
5
|
+
import { usageSummaries } from "../db/schema/meter-events.js";
|
|
6
|
+
import { createTestDb, truncateAllTables } from "../test/db.js";
|
|
7
7
|
import { runReconciliation } from "./reconciliation-cron.js";
|
|
8
8
|
import { DrizzleAdapterUsageRepository, DrizzleUsageSummaryRepository } from "./reconciliation-repository.js";
|
|
9
9
|
/** Today's date as YYYY-MM-DD (UTC). We use "today" as targetDate since the
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
2
|
import { afterAll, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
|
3
|
-
import { createTestDb, seedUsageSummary, truncateAllTables } from "../test/db.js";
|
|
4
3
|
import { Credit } from "../credits/credit.js";
|
|
5
4
|
import { CreditLedger } from "../credits/credit-ledger.js";
|
|
5
|
+
import { createTestDb, seedUsageSummary, truncateAllTables } from "../test/db.js";
|
|
6
6
|
import { DrizzleAdapterUsageRepository, DrizzleUsageSummaryRepository } from "./reconciliation-repository.js";
|
|
7
7
|
let pool;
|
|
8
8
|
let db;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export type
|
|
1
|
+
export { type CsrfOptions, csrfProtection, validateCsrfOrigin } from "./csrf.js";
|
|
2
2
|
export { DrizzleRateLimitRepository } from "./drizzle-rate-limit-repository.js";
|
|
3
|
-
export { rateLimit, rateLimitByRoute, getClientIp, parseTrustedProxies, type RateLimitConfig, type RateLimitRule, } from "./rate-limit.js";
|
|
4
3
|
export { getClientIpFromContext } from "./get-client-ip.js";
|
|
5
|
-
export {
|
|
4
|
+
export { getClientIp, parseTrustedProxies, type RateLimitConfig, type RateLimitRule, rateLimit, rateLimitByRoute, } from "./rate-limit.js";
|
|
5
|
+
export type { IRateLimitRepository, RateLimitEntry } from "./rate-limit-repository.js";
|
package/dist/middleware/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
+
export { csrfProtection, validateCsrfOrigin } from "./csrf.js";
|
|
1
2
|
export { DrizzleRateLimitRepository } from "./drizzle-rate-limit-repository.js";
|
|
2
|
-
export { rateLimit, rateLimitByRoute, getClientIp, parseTrustedProxies, } from "./rate-limit.js";
|
|
3
3
|
export { getClientIpFromContext } from "./get-client-ip.js";
|
|
4
|
-
export {
|
|
4
|
+
export { getClientIp, parseTrustedProxies, rateLimit, rateLimitByRoute, } from "./rate-limit.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export type {
|
|
1
|
+
export type { ISecretAuditRepository, SecretAuditEvent } from "./audit-repository.js";
|
|
2
2
|
export { DrizzleSecretAuditRepository } from "./audit-repository.js";
|
|
3
|
-
export type { CredentialRow, CredentialSummaryRow,
|
|
3
|
+
export type { CredentialRow, CredentialSummaryRow, ICredentialMigrationAccess, ICredentialRepository, IMigrationTenantKeyAccess, InsertCredentialRow, } from "./credential-repository.js";
|
|
4
4
|
export { DrizzleCredentialRepository, DrizzleMigrationTenantKeyAccess } from "./credential-repository.js";
|
|
5
5
|
export type { RotationResult } from "./key-rotation.js";
|
|
6
6
|
export { reEncryptAllCredentials } from "./key-rotation.js";
|
package/dist/security/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export type
|
|
2
|
-
export {
|
|
3
|
-
export { deriveInstanceKey, generateInstanceKey, encrypt, decrypt } from "./encryption.js";
|
|
1
|
+
export { type AuthType, auditCredentialEncryption, type CreateCredentialInput, type CredentialRow, type CredentialSummary, type CredentialSummaryRow, CredentialVaultStore, type DecryptedCredential, DrizzleCredentialRepository, DrizzleMigrationTenantKeyAccess, DrizzleSecretAuditRepository, getVaultEncryptionKey, type ICredentialMigrationAccess, type ICredentialRepository, type ICredentialVaultStore, type IMigrationTenantKeyAccess, type InsertCredentialRow, type ISecretAuditRepository, type MigrationResult, migratePlaintextCredentials, type PlaintextFinding, type RotateCredentialInput, type RotationResult, reEncryptAllCredentials, type SecretAuditEvent, } from "./credential-vault/index.js";
|
|
2
|
+
export { decrypt, deriveInstanceKey, encrypt, generateInstanceKey } from "./encryption.js";
|
|
4
3
|
export { validateNodeHost } from "./host-validation.js";
|
|
5
|
-
export { assertSafeRedirectUrl } from "./redirect-allowlist.js";
|
|
6
4
|
export type { KeyLeakMatch } from "./key-audit.js";
|
|
7
5
|
export { scanForKeyLeaks } from "./key-audit.js";
|
|
8
|
-
export {
|
|
6
|
+
export { forwardSecretsToInstance, writeEncryptedSeed } from "./key-injection.js";
|
|
9
7
|
export { PROVIDER_ENDPOINTS, validateProviderKey } from "./key-validation.js";
|
|
10
|
-
export {
|
|
11
|
-
export {
|
|
8
|
+
export { assertSafeRedirectUrl } from "./redirect-allowlist.js";
|
|
9
|
+
export { ALL_CAPABILITIES, buildPooledKeysMap, type CapabilityName, CapabilitySettingsStore, DrizzleKeyResolutionRepository, DrizzleOrgMembershipRepository, type ICapabilitySettingsRepository, type IKeyResolutionRepository, type IOrgMembershipRepository, type ITenantKeyRepository, type OrgResolvedKey, type ResolvedKey, resolveApiKey, resolveApiKeyWithOrgFallback, type TenantApiKey, type TenantCapabilitySetting, TenantKeyRepository, } from "./tenant-keys/index.js";
|
|
10
|
+
export type { EncryptedPayload, Provider, ProviderEndpoint, ValidateKeyRequest, ValidateKeyResponse, WriteSecretsRequest, } from "./types.js";
|
|
11
|
+
export { providerSchema, validateKeyRequestSchema, writeSecretsRequestSchema } from "./types.js";
|
package/dist/security/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
export {
|
|
1
|
+
// Credential vault
|
|
2
|
+
export { auditCredentialEncryption, CredentialVaultStore, DrizzleCredentialRepository, DrizzleMigrationTenantKeyAccess, DrizzleSecretAuditRepository, getVaultEncryptionKey, migratePlaintextCredentials, reEncryptAllCredentials, } from "./credential-vault/index.js";
|
|
3
|
+
export { decrypt, deriveInstanceKey, encrypt, generateInstanceKey } from "./encryption.js";
|
|
3
4
|
export { validateNodeHost } from "./host-validation.js";
|
|
4
|
-
export { assertSafeRedirectUrl } from "./redirect-allowlist.js";
|
|
5
5
|
export { scanForKeyLeaks } from "./key-audit.js";
|
|
6
|
-
export {
|
|
6
|
+
export { forwardSecretsToInstance, writeEncryptedSeed } from "./key-injection.js";
|
|
7
7
|
export { PROVIDER_ENDPOINTS, validateProviderKey } from "./key-validation.js";
|
|
8
|
-
|
|
9
|
-
export { DrizzleSecretAuditRepository, DrizzleCredentialRepository, DrizzleMigrationTenantKeyAccess, reEncryptAllCredentials, migratePlaintextCredentials, auditCredentialEncryption, CredentialVaultStore, getVaultEncryptionKey, } from "./credential-vault/index.js";
|
|
8
|
+
export { assertSafeRedirectUrl } from "./redirect-allowlist.js";
|
|
10
9
|
// Tenant keys
|
|
11
|
-
export {
|
|
10
|
+
export { ALL_CAPABILITIES, buildPooledKeysMap, CapabilitySettingsStore, DrizzleKeyResolutionRepository, DrizzleOrgMembershipRepository, resolveApiKey, resolveApiKeyWithOrgFallback, TenantKeyRepository, } from "./tenant-keys/index.js";
|
|
11
|
+
export { providerSchema, validateKeyRequestSchema, writeSecretsRequestSchema } from "./types.js";
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
]
|
|
1
|
+
const STATIC_ORIGINS = ["https://app.wopr.bot", "https://wopr.network"];
|
|
2
|
+
function getAllowedOrigins() {
|
|
3
|
+
return [
|
|
4
|
+
...STATIC_ORIGINS,
|
|
5
|
+
...(process.env.NODE_ENV !== "production" ? ["http://localhost:3000", "http://localhost:3001"] : []),
|
|
6
|
+
...(process.env.PLATFORM_UI_URL ? [process.env.PLATFORM_UI_URL] : []),
|
|
7
|
+
...(process.env.NODE_ENV !== "production" ? ["https://example.com"] : []),
|
|
8
|
+
];
|
|
9
|
+
}
|
|
8
10
|
/**
|
|
9
11
|
* Throws if `url` is not rooted at one of the allowed origins.
|
|
10
12
|
* Comparison is scheme + host (origin), not prefix string match,
|
|
@@ -22,7 +24,7 @@ export function assertSafeRedirectUrl(url) {
|
|
|
22
24
|
throw new Error("Invalid redirect URL");
|
|
23
25
|
}
|
|
24
26
|
const origin = parsed.origin;
|
|
25
|
-
const allowed =
|
|
27
|
+
const allowed = getAllowedOrigins().some((o) => {
|
|
26
28
|
try {
|
|
27
29
|
return origin === new URL(o).origin;
|
|
28
30
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
export type { CapabilityName, ICapabilitySettingsRepository, TenantCapabilitySetting, } from "./capability-settings-store.js";
|
|
2
|
+
export { ALL_CAPABILITIES, CapabilitySettingsStore } from "./capability-settings-store.js";
|
|
3
|
+
export type { ResolvedKey } from "./key-resolution.js";
|
|
4
|
+
export { buildPooledKeysMap, resolveApiKey } from "./key-resolution.js";
|
|
1
5
|
export type { IKeyResolutionRepository } from "./key-resolution-repository.js";
|
|
2
6
|
export { DrizzleKeyResolutionRepository } from "./key-resolution-repository.js";
|
|
3
|
-
export type { ResolvedKey } from "./key-resolution.js";
|
|
4
|
-
export { resolveApiKey, buildPooledKeysMap } from "./key-resolution.js";
|
|
5
|
-
export type { TenantApiKey, ITenantKeyRepository } from "./tenant-key-repository.js";
|
|
6
|
-
export { TenantKeyRepository } from "./tenant-key-repository.js";
|
|
7
|
-
export type { CapabilityName, TenantCapabilitySetting, ICapabilitySettingsRepository } from "./capability-settings-store.js";
|
|
8
|
-
export { ALL_CAPABILITIES, CapabilitySettingsStore } from "./capability-settings-store.js";
|
|
9
7
|
export type { IOrgMembershipRepository, OrgResolvedKey } from "./org-key-resolution.js";
|
|
10
8
|
export { DrizzleOrgMembershipRepository, resolveApiKeyWithOrgFallback } from "./org-key-resolution.js";
|
|
9
|
+
export type { ITenantKeyRepository, TenantApiKey } from "./tenant-key-repository.js";
|
|
10
|
+
export { TenantKeyRepository } from "./tenant-key-repository.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { DrizzleKeyResolutionRepository } from "./key-resolution-repository.js";
|
|
2
|
-
export { resolveApiKey, buildPooledKeysMap } from "./key-resolution.js";
|
|
3
|
-
export { TenantKeyRepository } from "./tenant-key-repository.js";
|
|
4
1
|
export { ALL_CAPABILITIES, CapabilitySettingsStore } from "./capability-settings-store.js";
|
|
2
|
+
export { buildPooledKeysMap, resolveApiKey } from "./key-resolution.js";
|
|
3
|
+
export { DrizzleKeyResolutionRepository } from "./key-resolution-repository.js";
|
|
5
4
|
export { DrizzleOrgMembershipRepository, resolveApiKeyWithOrgFallback } from "./org-key-resolution.js";
|
|
5
|
+
export { TenantKeyRepository } from "./tenant-key-repository.js";
|
package/dist/tenancy/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export type {
|
|
1
|
+
export type { IOrgRepository, Tenant } from "./drizzle-org-repository.js";
|
|
2
2
|
export { DrizzleOrgRepository } from "./drizzle-org-repository.js";
|
|
3
|
-
export type {
|
|
3
|
+
export type { IOrgMemberRepository, OrgInviteRow, OrgMemberRow } from "./org-member-repository.js";
|
|
4
4
|
export { DrizzleOrgMemberRepository } from "./org-member-repository.js";
|
|
5
|
-
export type {
|
|
5
|
+
export type { OrgInvitePublic, OrgMemberWithUser, OrgServiceOptions, OrgWithMembers } from "./org-service.js";
|
|
6
6
|
export { OrgService } from "./org-service.js";
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* IOrgMemberRepository (members/invites data).
|
|
5
5
|
*/
|
|
6
6
|
import type { PlatformDb } from "../db/index.js";
|
|
7
|
-
import type { IOrgMemberRepository, OrgInviteRow } from "./org-member-repository.js";
|
|
8
7
|
import type { IOrgRepository, Tenant } from "./drizzle-org-repository.js";
|
|
8
|
+
import type { IOrgMemberRepository, OrgInviteRow } from "./org-member-repository.js";
|
|
9
9
|
export interface OrgWithMembers extends Tenant {
|
|
10
10
|
members: OrgMemberWithUser[];
|
|
11
11
|
invites: OrgInvitePublic[];
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { TRPCError } from "@trpc/server";
|
|
2
2
|
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
|
3
|
-
import { DrizzleOrgMemberRepository } from "./org-member-repository.js";
|
|
4
3
|
import { createTestDb, truncateAllTables } from "../test/db.js";
|
|
5
4
|
import { DrizzleOrgRepository } from "./drizzle-org-repository.js";
|
|
5
|
+
import { DrizzleOrgMemberRepository } from "./org-member-repository.js";
|
|
6
6
|
import { OrgService } from "./org-service.js";
|
|
7
7
|
async function setup(db) {
|
|
8
8
|
const orgRepo = new DrizzleOrgRepository(db);
|
package/dist/trpc/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { adminProcedure, createCallerFactory, orgMemberProcedure, protectedProcedure, publicProcedure, router, setTrpcOrgMemberRepo, type TRPCContext, tenantProcedure, } from "./init.js";
|
package/dist/trpc/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { adminProcedure, createCallerFactory, orgMemberProcedure, protectedProcedure, publicProcedure, router, setTrpcOrgMemberRepo, tenantProcedure, } from "./init.js";
|
package/dist/trpc/init.test.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { describe, expect, it, vi
|
|
2
|
-
import {
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { adminProcedure, createCallerFactory, orgMemberProcedure, protectedProcedure, publicProcedure, router, setTrpcOrgMemberRepo, tenantProcedure, } from "./init.js";
|
|
3
3
|
// ---------------------------------------------------------------------------
|
|
4
4
|
// Helpers
|
|
5
5
|
// ---------------------------------------------------------------------------
|
|
@@ -28,9 +28,7 @@ const appRouter = router({
|
|
|
28
28
|
protectedHello: protectedProcedure.query(() => "protected-ok"),
|
|
29
29
|
adminHello: adminProcedure.query(() => "admin-ok"),
|
|
30
30
|
tenantHello: tenantProcedure.query(() => "tenant-ok"),
|
|
31
|
-
orgAction: orgMemberProcedure
|
|
32
|
-
.input((v) => v)
|
|
33
|
-
.mutation(() => "org-ok"),
|
|
31
|
+
orgAction: orgMemberProcedure.input((v) => v).mutation(() => "org-ok"),
|
|
34
32
|
});
|
|
35
33
|
const createCaller = createCallerFactory(appRouter);
|
|
36
34
|
// ---------------------------------------------------------------------------
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wopr-network/platform-core",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -45,6 +45,8 @@
|
|
|
45
45
|
"@trpc/server": "^11.12.0",
|
|
46
46
|
"@types/node": "^25.4.0",
|
|
47
47
|
"@types/pg": "^8.18.0",
|
|
48
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
49
|
+
"@wopr-network/semantic-release-config": "^1.0.0",
|
|
48
50
|
"better-auth": "^1.5.4",
|
|
49
51
|
"drizzle-kit": "^0.31.9",
|
|
50
52
|
"drizzle-orm": "^0.45.1",
|
|
@@ -60,5 +62,12 @@
|
|
|
60
62
|
"winston": "^3.19.0",
|
|
61
63
|
"zod": "^4.3.6"
|
|
62
64
|
},
|
|
65
|
+
"release": {
|
|
66
|
+
"extends": "@wopr-network/semantic-release-config"
|
|
67
|
+
},
|
|
68
|
+
"repository": {
|
|
69
|
+
"type": "git",
|
|
70
|
+
"url": "https://github.com/wopr-network/platform-core.git"
|
|
71
|
+
},
|
|
63
72
|
"packageManager": "pnpm@10.31.0"
|
|
64
73
|
}
|
package/src/admin/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type { IAdminAuditLogRepository } from "./admin-audit-log-repository.js";
|
|
2
2
|
export { DrizzleAdminAuditLogRepository } from "./admin-audit-log-repository.js";
|
|
3
|
-
export type { AuditCategory, AuditEntry,
|
|
3
|
+
export type { AdminAuditLogRow, AuditCategory, AuditEntry, AuditFilters } from "./audit-log.js";
|
|
4
4
|
export { AdminAuditLog } from "./audit-log.js";
|
|
5
5
|
export type { Role, UserRoleRow } from "./role-store.js";
|
|
6
6
|
export { isValidRole, RoleStore } from "./role-store.js";
|
package/src/auth/better-auth.ts
CHANGED
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
import { type BetterAuthOptions, betterAuth } from "better-auth";
|
|
12
12
|
import { twoFactor } from "better-auth/plugins";
|
|
13
13
|
import type { Pool } from "pg";
|
|
14
|
-
import type { PlatformDb } from "../db/index.js";
|
|
15
14
|
import { RoleStore } from "../admin/role-store.js";
|
|
16
15
|
import { logger } from "../config/logger.js";
|
|
17
16
|
import { initTwoFactorSchema } from "../db/auth-user-repository.js";
|
|
17
|
+
import type { PlatformDb } from "../db/index.js";
|
|
18
18
|
import { getEmailClient } from "../email/client.js";
|
|
19
19
|
import { passwordResetEmailTemplate, verifyEmailTemplate } from "../email/templates.js";
|
|
20
20
|
import { generateVerificationToken, initVerificationSchema, PgEmailVerifier } from "../email/verification.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { and, eq, lt } from "drizzle-orm";
|
|
2
|
+
import type { WebhookSeenEvent } from "../credits/repository-types.js";
|
|
2
3
|
import type { PlatformDb } from "../db/index.js";
|
|
3
4
|
import { webhookSeenEvents } from "../db/schema/index.js";
|
|
4
|
-
import type { WebhookSeenEvent } from "../credits/repository-types.js";
|
|
5
5
|
import type { IWebhookSeenRepository } from "./webhook-seen-repository.js";
|
|
6
6
|
|
|
7
7
|
export class DrizzleWebhookSeenRepository implements IWebhookSeenRepository {
|
package/src/billing/index.ts
CHANGED
|
@@ -1,22 +1,20 @@
|
|
|
1
|
+
export { DrizzleWebhookSeenRepository } from "./drizzle-webhook-seen-repository.js";
|
|
1
2
|
export type {
|
|
2
|
-
SavedPaymentMethod,
|
|
3
|
-
CheckoutOpts,
|
|
4
|
-
CheckoutSession,
|
|
5
3
|
ChargeOpts,
|
|
6
4
|
ChargeResult,
|
|
7
|
-
|
|
5
|
+
CheckoutOpts,
|
|
6
|
+
CheckoutSession,
|
|
7
|
+
Invoice,
|
|
8
|
+
IPaymentProcessor,
|
|
8
9
|
PortalOpts,
|
|
10
|
+
SavedPaymentMethod,
|
|
11
|
+
SetupResult,
|
|
9
12
|
WebhookResult,
|
|
10
|
-
IPaymentProcessor,
|
|
11
|
-
Invoice,
|
|
12
13
|
} from "./payment-processor.js";
|
|
13
14
|
export { PaymentMethodOwnershipError } from "./payment-processor.js";
|
|
14
|
-
export type { IWebhookSeenRepository } from "./webhook-seen-repository.js";
|
|
15
|
-
export { noOpReplayGuard } from "./webhook-seen-repository.js";
|
|
16
|
-
export { DrizzleWebhookSeenRepository } from "./drizzle-webhook-seen-repository.js";
|
|
17
|
-
|
|
18
|
-
// Stripe
|
|
19
|
-
export * from "./stripe/index.js";
|
|
20
|
-
|
|
21
15
|
// PayRam
|
|
22
16
|
export * from "./payram/index.js";
|
|
17
|
+
// Stripe
|
|
18
|
+
export * from "./stripe/index.js";
|
|
19
|
+
export type { IWebhookSeenRepository } from "./webhook-seen-repository.js";
|
|
20
|
+
export { noOpReplayGuard } from "./webhook-seen-repository.js";
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
import type { PGlite } from "@electric-sql/pglite";
|
|
9
9
|
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
|
10
|
+
import { CreditLedger } from "../../credits/credit-ledger.js";
|
|
10
11
|
import type { PlatformDb } from "../../db/index.js";
|
|
11
12
|
import { createTestDb, truncateAllTables } from "../../test/db.js";
|
|
12
|
-
import { CreditLedger } from "../../credits/credit-ledger.js";
|
|
13
13
|
import { DrizzleWebhookSeenRepository } from "../drizzle-webhook-seen-repository.js";
|
|
14
14
|
import { noOpReplayGuard } from "../webhook-seen-repository.js";
|
|
15
15
|
import { PayRamChargeRepository } from "./charge-store.js";
|
|
@@ -1,14 +1,26 @@
|
|
|
1
1
|
export { createCreditCheckoutSession, createVpsCheckoutSession } from "./checkout.js";
|
|
2
2
|
export { createStripeClient, loadStripeConfig } from "./client.js";
|
|
3
|
-
export type {
|
|
4
|
-
export {
|
|
5
|
-
|
|
3
|
+
export type { CreditPriceMap, CreditPricePoint } from "./credit-prices.js";
|
|
4
|
+
export {
|
|
5
|
+
CREDIT_PRICE_POINTS,
|
|
6
|
+
getConfiguredPriceIds,
|
|
7
|
+
getCreditAmountForPurchase,
|
|
8
|
+
loadCreditPriceMap,
|
|
9
|
+
lookupCreditPrice,
|
|
10
|
+
} from "./credit-prices.js";
|
|
6
11
|
export type { DetachPaymentMethodOpts } from "./payment-methods.js";
|
|
12
|
+
export { detachAllPaymentMethods, detachPaymentMethod } from "./payment-methods.js";
|
|
7
13
|
export { createPortalSession } from "./portal.js";
|
|
8
14
|
export type { SetupIntentOpts } from "./setup-intent.js";
|
|
9
15
|
export { createSetupIntent } from "./setup-intent.js";
|
|
10
|
-
export type {
|
|
16
|
+
export type { StripePaymentProcessorDeps, StripeWebhookHandlerResult } from "./stripe-payment-processor.js";
|
|
11
17
|
export { StripePaymentProcessor } from "./stripe-payment-processor.js";
|
|
12
18
|
export type { ITenantCustomerRepository } from "./tenant-store.js";
|
|
13
19
|
export { DrizzleTenantCustomerRepository, TenantCustomerRepository } from "./tenant-store.js";
|
|
14
|
-
export type {
|
|
20
|
+
export type {
|
|
21
|
+
CreditCheckoutOpts,
|
|
22
|
+
PortalSessionOpts,
|
|
23
|
+
StripeBillingConfig,
|
|
24
|
+
TenantCustomerRow,
|
|
25
|
+
VpsCheckoutOpts,
|
|
26
|
+
} from "./types.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type Stripe from "stripe";
|
|
2
2
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
3
|
-
import { Credit } from "../../credits/credit.js";
|
|
4
3
|
import type { IAutoTopupEventLogRepository } from "../../credits/auto-topup-event-log-repository.js";
|
|
4
|
+
import { Credit } from "../../credits/credit.js";
|
|
5
5
|
import type { CreditTransaction, ICreditLedger } from "../../credits/credit-ledger.js";
|
|
6
6
|
import { PaymentMethodOwnershipError } from "../payment-processor.js";
|
|
7
7
|
import type { CreditPriceMap } from "./credit-prices.js";
|
|
@@ -309,7 +309,6 @@ describe("StripePaymentProcessor", () => {
|
|
|
309
309
|
tenantRepo: mocks.tenantRepo,
|
|
310
310
|
webhookSecret: "whsec_test",
|
|
311
311
|
creditLedger: mocks.creditLedger,
|
|
312
|
-
|
|
313
312
|
});
|
|
314
313
|
|
|
315
314
|
await expect(
|
|
@@ -447,7 +446,7 @@ describe("StripePaymentProcessor", () => {
|
|
|
447
446
|
tenantRepo: mocks.tenantRepo,
|
|
448
447
|
webhookSecret: "whsec_test",
|
|
449
448
|
creditLedger: mocks.creditLedger,
|
|
450
|
-
|
|
449
|
+
|
|
451
450
|
priceMap,
|
|
452
451
|
});
|
|
453
452
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type Stripe from "stripe";
|
|
2
|
-
import { Credit } from "../../credits/credit.js";
|
|
3
2
|
import { chargeAutoTopup } from "../../credits/auto-topup-charge.js";
|
|
4
3
|
import type { IAutoTopupEventLogRepository } from "../../credits/auto-topup-event-log-repository.js";
|
|
4
|
+
import { Credit } from "../../credits/credit.js";
|
|
5
5
|
import type { ICreditLedger } from "../../credits/credit-ledger.js";
|
|
6
6
|
import {
|
|
7
7
|
type ChargeOpts,
|
|
@@ -5,11 +5,11 @@ import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vites
|
|
|
5
5
|
import type { PlatformDb } from "../db/index.js";
|
|
6
6
|
import { creditAutoTopup } from "../db/schema/credit-auto-topup.js";
|
|
7
7
|
import { createTestDb, truncateAllTables } from "../test/db.js";
|
|
8
|
-
import { Credit } from "./credit.js";
|
|
9
|
-
import type { ITenantCustomerRepository } from "./tenant-customer-repository.js";
|
|
10
8
|
import { type AutoTopupChargeDeps, chargeAutoTopup, MAX_CONSECUTIVE_FAILURES } from "./auto-topup-charge.js";
|
|
11
9
|
import { DrizzleAutoTopupEventLogRepository } from "./auto-topup-event-log-repository.js";
|
|
10
|
+
import { Credit } from "./credit.js";
|
|
12
11
|
import { CreditLedger } from "./credit-ledger.js";
|
|
12
|
+
import type { ITenantCustomerRepository } from "./tenant-customer-repository.js";
|
|
13
13
|
|
|
14
14
|
function mockStripe(overrides?: {
|
|
15
15
|
paymentIntentId?: string;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import Stripe from "stripe";
|
|
2
2
|
import { logger } from "../config/logger.js";
|
|
3
|
-
import type { Credit } from "./credit.js";
|
|
4
|
-
import type { ITenantCustomerRepository } from "./tenant-customer-repository.js";
|
|
5
3
|
import type { IAutoTopupEventLogRepository } from "./auto-topup-event-log-repository.js";
|
|
4
|
+
import type { Credit } from "./credit.js";
|
|
6
5
|
import type { ICreditLedger } from "./credit-ledger.js";
|
|
6
|
+
import type { ITenantCustomerRepository } from "./tenant-customer-repository.js";
|
|
7
7
|
|
|
8
8
|
/** After this many consecutive Stripe failures, the auto-topup mode is disabled. */
|
|
9
9
|
export const MAX_CONSECUTIVE_FAILURES = 3;
|
|
@@ -2,9 +2,9 @@ import type { PGlite } from "@electric-sql/pglite";
|
|
|
2
2
|
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
|
3
3
|
import type { PlatformDb } from "../db/index.js";
|
|
4
4
|
import { beginTestTransaction, createTestDb, endTestTransaction, rollbackTestTransaction } from "../test/db.js";
|
|
5
|
-
import { Credit } from "./credit.js";
|
|
6
5
|
import { runScheduledTopups, type ScheduleTopupDeps } from "./auto-topup-schedule.js";
|
|
7
6
|
import { DrizzleAutoTopupSettingsRepository } from "./auto-topup-settings-repository.js";
|
|
7
|
+
import { Credit } from "./credit.js";
|
|
8
8
|
|
|
9
9
|
describe("runScheduledTopups", () => {
|
|
10
10
|
let pool: PGlite;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { logger } from "../config/logger.js";
|
|
2
|
-
import type { Credit } from "./credit.js";
|
|
3
2
|
import type { AutoTopupChargeResult } from "./auto-topup-charge.js";
|
|
4
3
|
import { MAX_CONSECUTIVE_FAILURES } from "./auto-topup-charge.js";
|
|
5
4
|
import type { IAutoTopupSettingsRepository } from "./auto-topup-settings-repository.js";
|
|
5
|
+
import type { Credit } from "./credit.js";
|
|
6
6
|
|
|
7
7
|
export interface ScheduleTopupDeps {
|
|
8
8
|
settingsRepo: IAutoTopupSettingsRepository;
|
|
@@ -2,8 +2,8 @@ import type { PGlite } from "@electric-sql/pglite";
|
|
|
2
2
|
import { afterAll, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
|
3
3
|
import type { PlatformDb } from "../db/index.js";
|
|
4
4
|
import { beginTestTransaction, createTestDb, endTestTransaction, rollbackTestTransaction } from "../test/db.js";
|
|
5
|
-
import { Credit } from "./credit.js";
|
|
6
5
|
import { DrizzleAutoTopupSettingsRepository } from "./auto-topup-settings-repository.js";
|
|
6
|
+
import { Credit } from "./credit.js";
|
|
7
7
|
|
|
8
8
|
describe("DrizzleAutoTopupSettingsRepository", () => {
|
|
9
9
|
let pool: PGlite;
|
|
@@ -2,9 +2,9 @@ import type { PGlite } from "@electric-sql/pglite";
|
|
|
2
2
|
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
|
3
3
|
import type { PlatformDb } from "../db/index.js";
|
|
4
4
|
import { createTestDb, truncateAllTables } from "../test/db.js";
|
|
5
|
-
import { Credit } from "./credit.js";
|
|
6
5
|
import { DrizzleAutoTopupSettingsRepository } from "./auto-topup-settings-repository.js";
|
|
7
6
|
import { maybeTriggerUsageTopup, type UsageTopupDeps } from "./auto-topup-usage.js";
|
|
7
|
+
import { Credit } from "./credit.js";
|
|
8
8
|
import { CreditLedger } from "./credit-ledger.js";
|
|
9
9
|
|
|
10
10
|
describe("maybeTriggerUsageTopup", () => {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { logger } from "../config/logger.js";
|
|
2
|
-
import type { Credit } from "./credit.js";
|
|
3
2
|
import type { AutoTopupChargeResult } from "./auto-topup-charge.js";
|
|
4
3
|
import { MAX_CONSECUTIVE_FAILURES } from "./auto-topup-charge.js";
|
|
5
4
|
import type { IAutoTopupSettingsRepository } from "./auto-topup-settings-repository.js";
|
|
5
|
+
import type { Credit } from "./credit.js";
|
|
6
6
|
import type { ICreditLedger } from "./credit-ledger.js";
|
|
7
7
|
|
|
8
8
|
export interface UsageTopupDeps {
|
package/src/credits/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ export {
|
|
|
9
9
|
computeNextScheduleAt,
|
|
10
10
|
DrizzleAutoTopupSettingsRepository,
|
|
11
11
|
} from "./auto-topup-settings-repository.js";
|
|
12
|
+
export { Credit } from "./credit.js";
|
|
12
13
|
export type { CreditExpiryCronConfig, CreditExpiryCronResult } from "./credit-expiry-cron.js";
|
|
13
14
|
export { runCreditExpiryCron } from "./credit-expiry-cron.js";
|
|
14
15
|
export type {
|
|
@@ -21,5 +22,4 @@ export type {
|
|
|
21
22
|
} from "./credit-ledger.js";
|
|
22
23
|
export { CreditLedger, DrizzleCreditLedger, InsufficientBalanceError } from "./credit-ledger.js";
|
|
23
24
|
export { grantSignupCredits, SIGNUP_GRANT } from "./signup-grant.js";
|
|
24
|
-
export { Credit } from "./credit.js";
|
|
25
25
|
export type { ITenantCustomerRepository, TenantCustomerRow } from "./tenant-customer-repository.js";
|
package/src/db/schema/index.ts
CHANGED
|
@@ -5,9 +5,9 @@ export * from "./admin-users.js";
|
|
|
5
5
|
export * from "./affiliate.js";
|
|
6
6
|
export * from "./affiliate-fraud.js";
|
|
7
7
|
export * from "./coupon-codes.js";
|
|
8
|
-
export * from "./credits.js";
|
|
9
8
|
export * from "./credit-auto-topup.js";
|
|
10
9
|
export * from "./credit-auto-topup-settings.js";
|
|
10
|
+
export * from "./credits.js";
|
|
11
11
|
export * from "./dividend-distributions.js";
|
|
12
12
|
export * from "./email-notifications.js";
|
|
13
13
|
export * from "./meter-events.js";
|
package/src/email/index.ts
CHANGED
|
@@ -20,12 +20,12 @@ export { DrizzleNotificationPreferencesStore } from "./notification-preferences-
|
|
|
20
20
|
export type { INotificationQueueRepository } from "./notification-queue-store.js";
|
|
21
21
|
export { DrizzleNotificationQueueStore } from "./notification-queue-store.js";
|
|
22
22
|
export type {
|
|
23
|
-
NotificationPrefs,
|
|
24
|
-
NotificationStatus,
|
|
25
|
-
QueuedNotification,
|
|
26
23
|
NotificationEmailType,
|
|
27
24
|
NotificationInput,
|
|
25
|
+
NotificationPrefs,
|
|
28
26
|
NotificationRow,
|
|
27
|
+
NotificationStatus,
|
|
28
|
+
QueuedNotification,
|
|
29
29
|
} from "./notification-repository-types.js";
|
|
30
30
|
export { NotificationService } from "./notification-service.js";
|
|
31
31
|
export type { TemplateName as NotificationTemplateName } from "./notification-templates.js";
|
package/src/index.ts
CHANGED
|
@@ -1,36 +1,32 @@
|
|
|
1
1
|
// Database
|
|
2
|
-
export type { PlatformDb, PlatformSchema } from "./db/index.js";
|
|
3
|
-
export { createDb, schema } from "./db/index.js";
|
|
4
2
|
|
|
5
3
|
// Admin
|
|
6
4
|
export * from "./admin/index.js";
|
|
7
|
-
|
|
8
5
|
// Auth
|
|
9
6
|
export * from "./auth/index.js";
|
|
10
|
-
|
|
11
7
|
// Billing (selective — ITenantCustomerRepository/TenantCustomerRow also in credits)
|
|
12
8
|
export {
|
|
13
|
-
PaymentMethodOwnershipError,
|
|
14
|
-
noOpReplayGuard,
|
|
15
|
-
DrizzleWebhookSeenRepository,
|
|
16
|
-
type SavedPaymentMethod,
|
|
17
|
-
type CheckoutOpts,
|
|
18
|
-
type CheckoutSession,
|
|
19
9
|
type ChargeOpts,
|
|
20
10
|
type ChargeResult,
|
|
21
|
-
type
|
|
22
|
-
type
|
|
23
|
-
|
|
24
|
-
type IPaymentProcessor,
|
|
11
|
+
type CheckoutOpts,
|
|
12
|
+
type CheckoutSession,
|
|
13
|
+
DrizzleWebhookSeenRepository,
|
|
25
14
|
type Invoice,
|
|
15
|
+
type IPaymentProcessor,
|
|
26
16
|
type IWebhookSeenRepository,
|
|
17
|
+
noOpReplayGuard,
|
|
18
|
+
PaymentMethodOwnershipError,
|
|
19
|
+
type PortalOpts,
|
|
20
|
+
type SavedPaymentMethod,
|
|
21
|
+
type SetupResult,
|
|
22
|
+
type WebhookResult,
|
|
27
23
|
} from "./billing/index.js";
|
|
28
|
-
|
|
29
24
|
// Config
|
|
30
|
-
export {
|
|
31
|
-
|
|
25
|
+
export { billingConfigSchema, config, type PlatformConfig } from "./config/index.js";
|
|
32
26
|
// Credits
|
|
33
27
|
export * from "./credits/index.js";
|
|
28
|
+
export type { PlatformDb, PlatformSchema } from "./db/index.js";
|
|
29
|
+
export { createDb, schema } from "./db/index.js";
|
|
34
30
|
|
|
35
31
|
// Email
|
|
36
32
|
export * from "./email/index.js";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
2
|
import type { PGlite } from "@electric-sql/pglite";
|
|
3
3
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
4
|
+
import { Credit } from "../credits/credit.js";
|
|
4
5
|
import type { PlatformDb } from "../db/index.js";
|
|
5
6
|
import { meterEvents, usageSummaries } from "../db/schema/meter-events.js";
|
|
6
7
|
import { createTestDb } from "../test/db.js";
|
|
7
|
-
import { Credit } from "../credits/credit.js";
|
|
8
8
|
import { DrizzleMeterAggregator } from "./aggregator.js";
|
|
9
9
|
import { DrizzleUsageSummaryRepository } from "./drizzle-usage-summary-repository.js";
|
|
10
10
|
|