nucleus-core-ts 0.9.953 → 0.9.954
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/bin/cli.ts +131 -131
- package/dist/.build-ok +1 -1
- package/dist/src/Client/ApiCaller/index.d.ts +1 -1
- package/dist/src/Client/ApiCaller/types.d.ts +80 -3
- package/dist/src/Client/Proxy/wsProxy.js +26 -26
- package/package.json +1 -1
- package/scripts/generate-schema.ts +739 -739
package/bin/cli.ts
CHANGED
|
@@ -1,131 +1,131 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Nucleus CLI — the single front door to nucleus-core-ts.
|
|
5
|
-
*
|
|
6
|
-
* nucleus init scaffold a new project (interactive)
|
|
7
|
-
* nucleus dev … run locally (up | down | run)
|
|
8
|
-
* nucleus add … extend an existing project (entity | feature | oauth)
|
|
9
|
-
* nucleus validate validate config.json against the schema
|
|
10
|
-
* nucleus doctor check the local environment (bun, postgres, redis, …)
|
|
11
|
-
* nucleus generate generate the Drizzle schema from config.json
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import { spawn } from 'node:child_process'
|
|
15
|
-
import { dirname, join } from 'node:path'
|
|
16
|
-
import { fileURLToPath } from 'node:url'
|
|
17
|
-
import { banner, c, log } from './lib/ui'
|
|
18
|
-
import { doctorCommand } from './lib/commands/doctor'
|
|
19
|
-
import { validateCommand } from './lib/commands/validate'
|
|
20
|
-
import { initCommand } from './lib/commands/init'
|
|
21
|
-
import { devCommand } from './lib/commands/dev'
|
|
22
|
-
import { addCommand } from './lib/commands/add'
|
|
23
|
-
|
|
24
|
-
const here = dirname(fileURLToPath(import.meta.url))
|
|
25
|
-
const rootDir = join(here, '..')
|
|
26
|
-
|
|
27
|
-
const argv = process.argv.slice(2)
|
|
28
|
-
const firstArg = argv[0] ?? ''
|
|
29
|
-
const looksLikeFile = firstArg.endsWith('.json') || firstArg.startsWith('./') || firstArg.startsWith('/')
|
|
30
|
-
const command = looksLikeFile ? 'generate' : firstArg
|
|
31
|
-
|
|
32
|
-
async function pkgVersion(): Promise<string> {
|
|
33
|
-
try {
|
|
34
|
-
return (JSON.parse(await Bun.file(join(rootDir, 'package.json')).text()) as { version: string }).version
|
|
35
|
-
} catch {
|
|
36
|
-
return '?'
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function showHelp(version: string) {
|
|
41
|
-
banner(`Nucleus CLI v${version}`, 'nucleus-core-ts — config-driven backend framework')
|
|
42
|
-
log(`
|
|
43
|
-
${c.bold('Usage')} ${c.cyan('nucleus')} ${c.dim('<command> [options]')}
|
|
44
|
-
|
|
45
|
-
${c.bold('Create & evolve')}
|
|
46
|
-
${c.cyan('init')} ${c.dim('[--preset <p>] [-o <dir>] [-y]')} build a config + scaffold a runnable backend (zero-to-running)
|
|
47
|
-
${c.cyan('add')} ${c.dim('entity | feature <n> | oauth <p>')} extend this project's config in place (+ regenerate)
|
|
48
|
-
${c.cyan('scaffold')} full-project scaffold (backend+frontend+k8s+pipelines) from a config.json
|
|
49
|
-
${c.cyan('generate')} ${c.dim('<config.json> <outDir>')} generate the Drizzle schema + relations from config
|
|
50
|
-
${c.cyan('validate')} ${c.dim('[config.json]')} validate a config against the JSON-Schema + cross-field rules
|
|
51
|
-
|
|
52
|
-
${c.bold('Local dev')}
|
|
53
|
-
${c.cyan('dev')} ${c.dim('[up | down]')} run the app; ${c.dim('up')} starts Postgres+Redis, ${c.dim('down')} stops them
|
|
54
|
-
${c.cyan('doctor')} check the local environment can run a Nucleus project
|
|
55
|
-
|
|
56
|
-
${c.bold('Maintenance')}
|
|
57
|
-
${c.cyan('audit:purge-noise')} ${c.dim('[--execute]')} delete historical low-signal audit_logs rows (dry-run by default)
|
|
58
|
-
${c.cyan('help')}${c.dim(', ')}${c.cyan('--version')} this help / the installed version
|
|
59
|
-
|
|
60
|
-
${c.dim('init = preset → runnable backend · scaffold (= new) = full project · Aliases: generate = gen, validate = check')}
|
|
61
|
-
`)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function runScript(scriptRelPath: string, args: string[]): Promise<never> {
|
|
65
|
-
return new Promise<never>(() => {
|
|
66
|
-
const proc = spawn('bun', ['run', join(rootDir, scriptRelPath), ...args], { cwd: process.cwd(), stdio: 'inherit' })
|
|
67
|
-
proc.on('close', (code) => process.exit(code ?? 1))
|
|
68
|
-
})
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
switch (command) {
|
|
72
|
-
case 'init':
|
|
73
|
-
process.exit(await initCommand(argv.slice(1)))
|
|
74
|
-
break
|
|
75
|
-
|
|
76
|
-
case 'dev':
|
|
77
|
-
process.exit(await devCommand(argv.slice(1)))
|
|
78
|
-
break
|
|
79
|
-
|
|
80
|
-
case 'add':
|
|
81
|
-
process.exit(await addCommand(argv.slice(1)))
|
|
82
|
-
break
|
|
83
|
-
|
|
84
|
-
case 'scaffold':
|
|
85
|
-
case 'new': {
|
|
86
|
-
// Full-project scaffold (backend + frontend + k8s + pipelines) from an
|
|
87
|
-
// existing config.json. `init` is the leaner, config-building local-dev path.
|
|
88
|
-
const { scaffold } = await import(join(rootDir, 'infra', 'scripts', 'generate-project.ts'))
|
|
89
|
-
await scaffold(join(rootDir, 'infra'))
|
|
90
|
-
break
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
case 'generate':
|
|
94
|
-
case 'gen': {
|
|
95
|
-
const genArgs = looksLikeFile ? argv : argv.slice(1)
|
|
96
|
-
await runScript(join('scripts', 'generate-schema.ts'), genArgs)
|
|
97
|
-
break
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
case 'validate':
|
|
101
|
-
case 'check':
|
|
102
|
-
process.exit(await validateCommand(argv.slice(1)))
|
|
103
|
-
break
|
|
104
|
-
|
|
105
|
-
case 'doctor':
|
|
106
|
-
process.exit(await doctorCommand())
|
|
107
|
-
break
|
|
108
|
-
|
|
109
|
-
case 'audit:purge-noise':
|
|
110
|
-
case 'audit-purge-noise':
|
|
111
|
-
await runScript(join('scripts', 'audit-purge-noise.ts'), argv.slice(1))
|
|
112
|
-
break
|
|
113
|
-
|
|
114
|
-
case '--version':
|
|
115
|
-
case '-v':
|
|
116
|
-
log(await pkgVersion())
|
|
117
|
-
break
|
|
118
|
-
|
|
119
|
-
case 'help':
|
|
120
|
-
case '--help':
|
|
121
|
-
case '-h':
|
|
122
|
-
case '':
|
|
123
|
-
case undefined:
|
|
124
|
-
showHelp(await pkgVersion())
|
|
125
|
-
break
|
|
126
|
-
|
|
127
|
-
default:
|
|
128
|
-
log(`${c.red('Unknown command:')} ${command}\n`)
|
|
129
|
-
showHelp(await pkgVersion())
|
|
130
|
-
process.exit(1)
|
|
131
|
-
}
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Nucleus CLI — the single front door to nucleus-core-ts.
|
|
5
|
+
*
|
|
6
|
+
* nucleus init scaffold a new project (interactive)
|
|
7
|
+
* nucleus dev … run locally (up | down | run)
|
|
8
|
+
* nucleus add … extend an existing project (entity | feature | oauth)
|
|
9
|
+
* nucleus validate validate config.json against the schema
|
|
10
|
+
* nucleus doctor check the local environment (bun, postgres, redis, …)
|
|
11
|
+
* nucleus generate generate the Drizzle schema from config.json
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { spawn } from 'node:child_process'
|
|
15
|
+
import { dirname, join } from 'node:path'
|
|
16
|
+
import { fileURLToPath } from 'node:url'
|
|
17
|
+
import { banner, c, log } from './lib/ui'
|
|
18
|
+
import { doctorCommand } from './lib/commands/doctor'
|
|
19
|
+
import { validateCommand } from './lib/commands/validate'
|
|
20
|
+
import { initCommand } from './lib/commands/init'
|
|
21
|
+
import { devCommand } from './lib/commands/dev'
|
|
22
|
+
import { addCommand } from './lib/commands/add'
|
|
23
|
+
|
|
24
|
+
const here = dirname(fileURLToPath(import.meta.url))
|
|
25
|
+
const rootDir = join(here, '..')
|
|
26
|
+
|
|
27
|
+
const argv = process.argv.slice(2)
|
|
28
|
+
const firstArg = argv[0] ?? ''
|
|
29
|
+
const looksLikeFile = firstArg.endsWith('.json') || firstArg.startsWith('./') || firstArg.startsWith('/')
|
|
30
|
+
const command = looksLikeFile ? 'generate' : firstArg
|
|
31
|
+
|
|
32
|
+
async function pkgVersion(): Promise<string> {
|
|
33
|
+
try {
|
|
34
|
+
return (JSON.parse(await Bun.file(join(rootDir, 'package.json')).text()) as { version: string }).version
|
|
35
|
+
} catch {
|
|
36
|
+
return '?'
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function showHelp(version: string) {
|
|
41
|
+
banner(`Nucleus CLI v${version}`, 'nucleus-core-ts — config-driven backend framework')
|
|
42
|
+
log(`
|
|
43
|
+
${c.bold('Usage')} ${c.cyan('nucleus')} ${c.dim('<command> [options]')}
|
|
44
|
+
|
|
45
|
+
${c.bold('Create & evolve')}
|
|
46
|
+
${c.cyan('init')} ${c.dim('[--preset <p>] [-o <dir>] [-y]')} build a config + scaffold a runnable backend (zero-to-running)
|
|
47
|
+
${c.cyan('add')} ${c.dim('entity | feature <n> | oauth <p>')} extend this project's config in place (+ regenerate)
|
|
48
|
+
${c.cyan('scaffold')} full-project scaffold (backend+frontend+k8s+pipelines) from a config.json
|
|
49
|
+
${c.cyan('generate')} ${c.dim('<config.json> <outDir>')} generate the Drizzle schema + relations from config
|
|
50
|
+
${c.cyan('validate')} ${c.dim('[config.json]')} validate a config against the JSON-Schema + cross-field rules
|
|
51
|
+
|
|
52
|
+
${c.bold('Local dev')}
|
|
53
|
+
${c.cyan('dev')} ${c.dim('[up | down]')} run the app; ${c.dim('up')} starts Postgres+Redis, ${c.dim('down')} stops them
|
|
54
|
+
${c.cyan('doctor')} check the local environment can run a Nucleus project
|
|
55
|
+
|
|
56
|
+
${c.bold('Maintenance')}
|
|
57
|
+
${c.cyan('audit:purge-noise')} ${c.dim('[--execute]')} delete historical low-signal audit_logs rows (dry-run by default)
|
|
58
|
+
${c.cyan('help')}${c.dim(', ')}${c.cyan('--version')} this help / the installed version
|
|
59
|
+
|
|
60
|
+
${c.dim('init = preset → runnable backend · scaffold (= new) = full project · Aliases: generate = gen, validate = check')}
|
|
61
|
+
`)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function runScript(scriptRelPath: string, args: string[]): Promise<never> {
|
|
65
|
+
return new Promise<never>(() => {
|
|
66
|
+
const proc = spawn('bun', ['run', join(rootDir, scriptRelPath), ...args], { cwd: process.cwd(), stdio: 'inherit' })
|
|
67
|
+
proc.on('close', (code) => process.exit(code ?? 1))
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
switch (command) {
|
|
72
|
+
case 'init':
|
|
73
|
+
process.exit(await initCommand(argv.slice(1)))
|
|
74
|
+
break
|
|
75
|
+
|
|
76
|
+
case 'dev':
|
|
77
|
+
process.exit(await devCommand(argv.slice(1)))
|
|
78
|
+
break
|
|
79
|
+
|
|
80
|
+
case 'add':
|
|
81
|
+
process.exit(await addCommand(argv.slice(1)))
|
|
82
|
+
break
|
|
83
|
+
|
|
84
|
+
case 'scaffold':
|
|
85
|
+
case 'new': {
|
|
86
|
+
// Full-project scaffold (backend + frontend + k8s + pipelines) from an
|
|
87
|
+
// existing config.json. `init` is the leaner, config-building local-dev path.
|
|
88
|
+
const { scaffold } = await import(join(rootDir, 'infra', 'scripts', 'generate-project.ts'))
|
|
89
|
+
await scaffold(join(rootDir, 'infra'))
|
|
90
|
+
break
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
case 'generate':
|
|
94
|
+
case 'gen': {
|
|
95
|
+
const genArgs = looksLikeFile ? argv : argv.slice(1)
|
|
96
|
+
await runScript(join('scripts', 'generate-schema.ts'), genArgs)
|
|
97
|
+
break
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
case 'validate':
|
|
101
|
+
case 'check':
|
|
102
|
+
process.exit(await validateCommand(argv.slice(1)))
|
|
103
|
+
break
|
|
104
|
+
|
|
105
|
+
case 'doctor':
|
|
106
|
+
process.exit(await doctorCommand())
|
|
107
|
+
break
|
|
108
|
+
|
|
109
|
+
case 'audit:purge-noise':
|
|
110
|
+
case 'audit-purge-noise':
|
|
111
|
+
await runScript(join('scripts', 'audit-purge-noise.ts'), argv.slice(1))
|
|
112
|
+
break
|
|
113
|
+
|
|
114
|
+
case '--version':
|
|
115
|
+
case '-v':
|
|
116
|
+
log(await pkgVersion())
|
|
117
|
+
break
|
|
118
|
+
|
|
119
|
+
case 'help':
|
|
120
|
+
case '--help':
|
|
121
|
+
case '-h':
|
|
122
|
+
case '':
|
|
123
|
+
case undefined:
|
|
124
|
+
showHelp(await pkgVersion())
|
|
125
|
+
break
|
|
126
|
+
|
|
127
|
+
default:
|
|
128
|
+
log(`${c.red('Unknown command:')} ${command}\n`)
|
|
129
|
+
showHelp(await pkgVersion())
|
|
130
|
+
process.exit(1)
|
|
131
|
+
}
|
package/dist/.build-ok
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.9.
|
|
1
|
+
0.9.954
|
|
@@ -11,5 +11,5 @@ export { createServerFactory, type ServerFactory } from './server';
|
|
|
11
11
|
* in the app and not the one that holds the accounts.
|
|
12
12
|
*/
|
|
13
13
|
export { SYSTEM_TABLES } from './system-tables';
|
|
14
|
-
export type { AdminCreateUserPayload, AdminCreateUserResponse, AllGeneratedEndpoints, AllGeneratedEndpointsWithConfig, AllGeneratedEndpointsWithEntityTypes, ApiCallerConfig, ApiResponse, AuthEndpointDefinitions, AuthenticationConfig, AuthFeatureConfig, AuthFeatureKey, BaseErrorResponse, BulkCreateUsersPayload, BulkCreateUsersResponse, BulkEndpointKey, ChangeUserIdPayload, ChangeUserIdResponse, ChatActionResponse, ChatAttachmentDTO, ChatConversationDTO, ChatConversationListResponse, ChatConversationResponse, ChatCreateConversationPayload, ChatEndpointDefinitions, ChatMessageDTO, ChatMessageListResponse, ChatMessageResponse, ChatParticipantDTO, ChatParticipantsResponse, ChatReadResponse, ChatSendMessagePayload, CheckSubdomainPayload, CheckSubdomainResponse, ClientHookConfig, CohortBulkOpsResponse, CohortEndpointDefinitions, CohortPayload, CohortUpdatePayload, ConfigEndpointDefinitions, ConfigEnvResponse, ConfigGetResponse, ConfigOverridesClearResponse, ConfigOverridesGetResponse, ConfigRestartPayload, ConfigRestartResponse, ConfigSectionGetResponse, ConfigSectionMeta, ConfigSectionsListResponse, ConfigSectionUpdatePayload, ConfigSectionUpdateResponse, CookieStore, CreateHostnamePayload, CreateHostnameResponse, CreateRegistrationPayload, DeleteResponse, DnsInstructionDTO, DomainEndpointDefinitions, DomainHostnameDTO, DomainHostnameListResponse, DomainHostnameResponse, DomainInstructionsResponse, DomainRegistrationDTO, DomainRegistrationListResponse, DomainRegistrationResponse, DomainResolutionDTO, DomainResolveResponse, EndpointAction, EndpointActions, EndpointDefinition, EndpointMethod, EndpointState, EntityEndpointKey, EntityRecord, ExtraEndpoints, FlowDeleteResponse, FlowDetailResponse, FlowListResponse, FlowPublishResponse, FlowSavePayload, FlowSaveResponse, GeneratedAuthEndpoints, GeneratedEndpointsFromConfig, HeadersStore, HttpMethod, ImpersonatePayload, ImpersonateResponse, ImpersonateStopResponse, InferEntity, ListResponse, LiveCpuLog, LiveDaprEvent, LiveDaprEventType, LiveMemoryLog, LiveMonitoringChangeSettingsPayload, LiveMonitoringConfigs, LiveMonitoringLogLimits, LiveMonitoringLogsResponse, LiveMonitoringSettingsResponse, LiveMonitoringStreamSnapshot, LiveMonitoringStreamUpdate, LiveRequest, LiveWorkerInfo, LiveWsEvent, LiveWsEventType, LoginPayload, LoginSuccess, LoginSuccessData, MagicLinkPayload, MarketplaceBalanceDTO, MarketplaceBalanceResponse, MarketplaceEndpointDefinitions, MeResponse, MeResponseData, MeSuccessResponse, MonitoringEndpointDefinitions, MutationResponse, NotificationListResponse, NotificationSeenAllResponse, NotificationSeenResponse, NotificationUnseenCountResponse, OpenDisputePayload, PaginationMeta, PasswordChangePayload, PasswordResetConfirmPayload, PasswordResetRequestPayload, PasswordResetResponse, PasswordSetPayload, PaymentDisputeDTO, PaymentDisputeListResponse, PaymentDisputeResponse, PaymentSplitDTO, PaymentSplitListResponse, PaymentSplitResponse, PayoutRequestDTO, PayoutRequestListResponse, PayoutRequestResponse, ProvisionTenantPayload, ProvisionTenantResponse, RecordSplitPayload, RefreshSuccess, RefreshSuccessData, RegisterPayload, RegisterSuccess, RegisterSuccessData, RequestPayoutPayload, ResolvedEnvEntry, SelfSignupPayload, SelfSignupResponse, ServerFactoryConfig, SessionApprovePayload, SessionApproveResponse, SessionCurrentResponse, SessionInfo, SessionRejectPayload, SessionRejectResponse, SessionRevokeAllPayload, SessionRevokeAllResponse, SessionRevokePayload, SessionRevokeResponse, SessionStatsResponse, SessionsListResponse, SessionsPendingResponse, SettlementPolicyDTO, SettlementPolicyPayload, SettlementPolicyResponse, SingleResponse, StandardQueryParams, StandardReturn, StartOptions, SystemAddressEntity, SystemClaimEntity, SystemFileEntity, SystemMonitoringMetricEntity, SystemPhoneEntity, SystemProfileEntity, SystemRoleClaimEntity, SystemRoleEntity, SystemUserCohortEntity, SystemUserEntity, SystemUserRoleEntity, TenantDetailResponse, TenantEndpointDefinitions, TenantListItem, TenantListResponse, TenantReactivatePayload, TenantReactivateResponse, TenantSuspendPayload, TenantSuspendResponse, UserData, VerificationDecidePayload, VerificationDecideResponse, VerificationEndpointDefinitions, VerificationPendingResponse, VerificationStartPayload, VerificationStartResponse, VerificationStatusResponse, WebAuthnAuthenticationOptions, WebAuthnAuthenticationResponseJSON, WebAuthnAuthenticatorAttachment, WebAuthnAuthOptionsPayload, WebAuthnAuthOptionsResponse, WebAuthnAuthVerifyPayload, WebAuthnAuthVerifyResponse, WebAuthnCredentialSummary, WebAuthnDeviceType, WebAuthnListResponse, WebAuthnPublicKeyCredentialDescriptor, WebAuthnRegisterOptionsPayload, WebAuthnRegisterOptionsResponse, WebAuthnRegisterVerifyPayload, WebAuthnRegisterVerifyResponse, WebAuthnRegistrationOptions, WebAuthnRegistrationResponseJSON, WebAuthnRenamePayload, WebAuthnRenameResponse, WebAuthnRevokePayload, WebAuthnRevokeResponse, WebAuthnTransport, } from './types';
|
|
14
|
+
export type { AdminCreateUserPayload, AdminCreateUserResponse, AlertEvent, AlertType, AllGeneratedEndpoints, AllGeneratedEndpointsWithConfig, AllGeneratedEndpointsWithEntityTypes, ApiCallerConfig, ApiResponse, ApplicationMetrics, AuditCategory, AuditSeverity, AuthEndpointDefinitions, AuthenticationConfig, AuthFeatureConfig, AuthFeatureKey, BaseErrorResponse, BulkCreateUsersPayload, BulkCreateUsersResponse, BulkEndpointKey, ChangeUserIdPayload, ChangeUserIdResponse, ChatActionResponse, ChatAttachmentDTO, ChatConversationDTO, ChatConversationListResponse, ChatConversationResponse, ChatCreateConversationPayload, ChatEndpointDefinitions, ChatMessageDTO, ChatMessageListResponse, ChatMessageResponse, ChatParticipantDTO, ChatParticipantsResponse, ChatReadResponse, ChatSendMessagePayload, CheckSubdomainPayload, CheckSubdomainResponse, ClientHookConfig, CohortBulkOpsResponse, CohortEndpointDefinitions, CohortPayload, CohortUpdatePayload, ConfigEndpointDefinitions, ConfigEnvResponse, ConfigGetResponse, ConfigOverridesClearResponse, ConfigOverridesGetResponse, ConfigRestartPayload, ConfigRestartResponse, ConfigSectionGetResponse, ConfigSectionMeta, ConfigSectionsListResponse, ConfigSectionUpdatePayload, ConfigSectionUpdateResponse, CookieStore, CreateHostnamePayload, CreateHostnameResponse, CreateRegistrationPayload, DatabaseMetrics, DeleteResponse, DnsInstructionDTO, DomainEndpointDefinitions, DomainHostnameDTO, DomainHostnameListResponse, DomainHostnameResponse, DomainInstructionsResponse, DomainRegistrationDTO, DomainRegistrationListResponse, DomainRegistrationResponse, DomainResolutionDTO, DomainResolveResponse, EndpointAction, EndpointActions, EndpointDefinition, EndpointMethod, EndpointState, EntityEndpointKey, EntityRecord, ExtraEndpoints, FlowDeleteResponse, FlowDetailResponse, FlowListResponse, FlowPublishResponse, FlowSavePayload, FlowSaveResponse, GeneratedAuthEndpoints, GeneratedEndpointsFromConfig, HeadersStore, HttpMethod, ImpersonatePayload, ImpersonateResponse, ImpersonateStopResponse, InferEntity, ListResponse, LiveCpuLog, LiveDaprEvent, LiveDaprEventType, LiveMemoryLog, LiveMonitoringChangeSettingsPayload, LiveMonitoringConfigs, LiveMonitoringLogLimits, LiveMonitoringLogsResponse, LiveMonitoringSettingsResponse, LiveMonitoringStreamSnapshot, LiveMonitoringStreamUpdate, LiveRequest, LiveWorkerInfo, LiveWsEvent, LiveWsEventType, LoginPayload, LoginSuccess, LoginSuccessData, LogLevel, MagicLinkPayload, MarketplaceBalanceDTO, MarketplaceBalanceResponse, MarketplaceEndpointDefinitions, MeResponse, MeResponseData, MeSuccessResponse, MetricPeak, MonitoringAcknowledgeResponse, MonitoringAlertsResponse, MonitoringEndpointDefinitions, MonitoringHistoryResponse, MonitoringSnapshot, MonitoringSnapshotResponse, MutationResponse, NotificationListResponse, NotificationSeenAllResponse, NotificationSeenResponse, NotificationUnseenCountResponse, OpenDisputePayload, PaginationMeta, PasswordChangePayload, PasswordResetConfirmPayload, PasswordResetRequestPayload, PasswordResetResponse, PasswordSetPayload, PaymentDisputeDTO, PaymentDisputeListResponse, PaymentDisputeResponse, PaymentSplitDTO, PaymentSplitListResponse, PaymentSplitResponse, PayoutRequestDTO, PayoutRequestListResponse, PayoutRequestResponse, ProvisionTenantPayload, ProvisionTenantResponse, RecordSplitPayload, RedisMetrics, RefreshSuccess, RefreshSuccessData, RegisterPayload, RegisterSuccess, RegisterSuccessData, RequestPayoutPayload, ResolvedEnvEntry, SelfSignupPayload, SelfSignupResponse, ServerFactoryConfig, ServerLogPage, ServerLogQuery, ServerLogRecord, ServerLogSource, ServerLogsResponse, SessionApprovePayload, SessionApproveResponse, SessionCurrentResponse, SessionInfo, SessionRejectPayload, SessionRejectResponse, SessionRevokeAllPayload, SessionRevokeAllResponse, SessionRevokePayload, SessionRevokeResponse, SessionStatsResponse, SessionsListResponse, SessionsPendingResponse, SettlementPolicyDTO, SettlementPolicyPayload, SettlementPolicyResponse, SingleResponse, StandardQueryParams, StandardReturn, StartOptions, SystemAddressEntity, SystemClaimEntity, SystemFileEntity, SystemMetrics, SystemMonitoringMetricEntity, SystemPhoneEntity, SystemProfileEntity, SystemRoleClaimEntity, SystemRoleEntity, SystemUserCohortEntity, SystemUserEntity, SystemUserRoleEntity, TenantDetailResponse, TenantEndpointDefinitions, TenantListItem, TenantListResponse, TenantReactivatePayload, TenantReactivateResponse, TenantSuspendPayload, TenantSuspendResponse, UserData, VerificationDecidePayload, VerificationDecideResponse, VerificationEndpointDefinitions, VerificationPendingResponse, VerificationStartPayload, VerificationStartResponse, VerificationStatusResponse, WebAuthnAuthenticationOptions, WebAuthnAuthenticationResponseJSON, WebAuthnAuthenticatorAttachment, WebAuthnAuthOptionsPayload, WebAuthnAuthOptionsResponse, WebAuthnAuthVerifyPayload, WebAuthnAuthVerifyResponse, WebAuthnCredentialSummary, WebAuthnDeviceType, WebAuthnListResponse, WebAuthnPublicKeyCredentialDescriptor, WebAuthnRegisterOptionsPayload, WebAuthnRegisterOptionsResponse, WebAuthnRegisterVerifyPayload, WebAuthnRegisterVerifyResponse, WebAuthnRegistrationOptions, WebAuthnRegistrationResponseJSON, WebAuthnRenamePayload, WebAuthnRenameResponse, WebAuthnRevokePayload, WebAuthnRevokeResponse, WebAuthnTransport, } from './types';
|
|
15
15
|
export { AUTH_ENDPOINT_CONFIGS, AUTH_ENDPOINTS, CHAT_ENDPOINTS, COHORT_ENDPOINTS, CONFIG_ENDPOINTS, DOMAIN_ENDPOINTS, MARKETPLACE_ENDPOINTS, MONITORING_ENDPOINTS, PAYMENT_ENDPOINTS, TENANT_ENDPOINTS, VERIFICATION_ENDPOINTS, } from './types';
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AuditCategory as _AuditCategory, AuditSeverity as _AuditSeverity } from '../../Services/Logger/auditTaxonomy';
|
|
2
|
+
import type { ServerLogPage as _ServerLogPage, ServerLogQuery as _ServerLogQuery, ServerLogRecord as _ServerLogRecord, ServerLogSource as _ServerLogSource } from '../../Services/Logger/ServerLogBuffer';
|
|
3
|
+
import type { LogLevel as _LogLevel } from '../../Services/Logger/types';
|
|
4
|
+
import type { AlertEvent as _AlertEvent, AlertType as _AlertType, ApplicationMetrics as _ApplicationMetrics, DatabaseMetrics as _DatabaseMetrics, LiveCpuLog as _LiveCpuLog, LiveDaprEvent as _LiveDaprEvent, LiveDaprEventType as _LiveDaprEventType, LiveMemoryLog as _LiveMemoryLog, LiveMonitoringChangeSettingsPayload as _LiveMonitoringChangeSettingsPayload, LiveMonitoringConfigs as _LiveMonitoringConfigs, LiveMonitoringLogLimits as _LiveMonitoringLogLimits, LiveMonitoringLogsResponse as _LiveMonitoringLogsResponse, LiveMonitoringSettingsResponse as _LiveMonitoringSettingsResponse, LiveMonitoringStreamSnapshot as _LiveMonitoringStreamSnapshot, LiveMonitoringStreamUpdate as _LiveMonitoringStreamUpdate, LiveRequest as _LiveRequest, LiveWorkerInfo as _LiveWorkerInfo, LiveWsEvent as _LiveWsEvent, LiveWsEventType as _LiveWsEventType, MetricPeak as _MetricPeak, MonitoringSnapshot as _MonitoringSnapshot, RedisMetrics as _RedisMetrics, SystemMetrics as _SystemMetrics } from '../../Services/Monitoring/types';
|
|
2
5
|
import type { NucleusConfigOptions, NucleusTable, PaginationMeta, StandardQueryParams, StandardReturn } from '../../types';
|
|
3
6
|
import type { HttpMethod } from '../ServerFetch/types';
|
|
4
7
|
import type { SystemTables } from './system-tables';
|
|
5
|
-
export type { PaginationMeta, StandardQueryParams, StandardReturn };
|
|
6
|
-
export type { HttpMethod };
|
|
8
|
+
export type { HttpMethod, PaginationMeta, StandardQueryParams, StandardReturn };
|
|
7
9
|
export interface ApiResponse<TSuccess, TError> {
|
|
8
10
|
isSuccess: boolean;
|
|
9
11
|
data?: TSuccess;
|
|
@@ -2544,6 +2546,81 @@ export type LiveMonitoringChangeSettingsPayload = _LiveMonitoringChangeSettingsP
|
|
|
2544
2546
|
export type LiveMonitoringStreamSnapshot = _LiveMonitoringStreamSnapshot;
|
|
2545
2547
|
export type LiveMonitoringStreamUpdate = _LiveMonitoringStreamUpdate;
|
|
2546
2548
|
export type LiveMonitoringLogsResponse = _LiveMonitoringLogsResponse;
|
|
2549
|
+
/**
|
|
2550
|
+
* The metrics half of monitoring, for the panel that draws it.
|
|
2551
|
+
*
|
|
2552
|
+
* The live types above describe the per-request tail; these describe what the
|
|
2553
|
+
* collectors measured — and until now they existed only on the server side, so
|
|
2554
|
+
* every screen that wanted to render `/monitoring/snapshot` had to hand-write
|
|
2555
|
+
* its own copy of `SystemMetrics`. Two copies of a shape the server owns is two
|
|
2556
|
+
* places for it to drift, and the drift is silent: the panel keeps compiling
|
|
2557
|
+
* and quietly reads a field the server stopped sending.
|
|
2558
|
+
*/
|
|
2559
|
+
export type SystemMetrics = _SystemMetrics;
|
|
2560
|
+
export type ApplicationMetrics = _ApplicationMetrics;
|
|
2561
|
+
export type DatabaseMetrics = _DatabaseMetrics;
|
|
2562
|
+
export type RedisMetrics = _RedisMetrics;
|
|
2563
|
+
export type MetricPeak = _MetricPeak;
|
|
2564
|
+
export type MonitoringSnapshot = _MonitoringSnapshot;
|
|
2565
|
+
export type AlertType = _AlertType;
|
|
2566
|
+
export type AlertEvent = _AlertEvent;
|
|
2567
|
+
/** `GET {basePath}/snapshot` — `data` is null before the first collection. */
|
|
2568
|
+
export type MonitoringSnapshotResponse = {
|
|
2569
|
+
isSuccess: boolean;
|
|
2570
|
+
message: string;
|
|
2571
|
+
data: MonitoringSnapshot | null;
|
|
2572
|
+
};
|
|
2573
|
+
/** `GET {basePath}/history?minutes=N` — capped server-side at `history.maxMinutes`. */
|
|
2574
|
+
export type MonitoringHistoryResponse = {
|
|
2575
|
+
isSuccess: boolean;
|
|
2576
|
+
message: string;
|
|
2577
|
+
data: {
|
|
2578
|
+
minutes: number;
|
|
2579
|
+
count: number;
|
|
2580
|
+
snapshots: MonitoringSnapshot[];
|
|
2581
|
+
};
|
|
2582
|
+
};
|
|
2583
|
+
/** `GET {basePath}/alerts` — only alerts still active, acknowledged or not. */
|
|
2584
|
+
export type MonitoringAlertsResponse = {
|
|
2585
|
+
isSuccess: boolean;
|
|
2586
|
+
message: string;
|
|
2587
|
+
data: {
|
|
2588
|
+
count: number;
|
|
2589
|
+
alerts: AlertEvent[];
|
|
2590
|
+
};
|
|
2591
|
+
};
|
|
2592
|
+
/** `POST {basePath}/alerts/:alertId/acknowledge`. */
|
|
2593
|
+
export type MonitoringAcknowledgeResponse = {
|
|
2594
|
+
isSuccess: boolean;
|
|
2595
|
+
message: string;
|
|
2596
|
+
data: {
|
|
2597
|
+
alertId: string;
|
|
2598
|
+
} | null;
|
|
2599
|
+
};
|
|
2600
|
+
/**
|
|
2601
|
+
* The server's own log, as the admin panel reads it.
|
|
2602
|
+
*
|
|
2603
|
+
* Exported for the same reason as the metrics types above: the buffer and its
|
|
2604
|
+
* query shape live in the framework, so a panel that hand-writes them is a
|
|
2605
|
+
* second copy that drifts silently the day a field is added.
|
|
2606
|
+
*/
|
|
2607
|
+
export type LogLevel = _LogLevel;
|
|
2608
|
+
export type ServerLogSource = _ServerLogSource;
|
|
2609
|
+
export type ServerLogRecord = _ServerLogRecord;
|
|
2610
|
+
export type ServerLogQuery = _ServerLogQuery;
|
|
2611
|
+
export type ServerLogPage = _ServerLogPage;
|
|
2612
|
+
/** `GET {basePath}/server-logs` — a page, plus what is available to filter by. */
|
|
2613
|
+
export type ServerLogsResponse = {
|
|
2614
|
+
isSuccess: boolean;
|
|
2615
|
+
message: string;
|
|
2616
|
+
data: ServerLogPage & {
|
|
2617
|
+
scopes: string[];
|
|
2618
|
+
levelCounts: Record<LogLevel, number>;
|
|
2619
|
+
};
|
|
2620
|
+
};
|
|
2621
|
+
/** How `audit_logs` rows are classified, so a viewer can rank them the same way. */
|
|
2622
|
+
export type AuditSeverity = _AuditSeverity;
|
|
2623
|
+
export type AuditCategory = _AuditCategory;
|
|
2547
2624
|
export declare const MONITORING_ENDPOINTS: {
|
|
2548
2625
|
MONITORING_HEALTH_CHECK: {
|
|
2549
2626
|
method: "GET";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { deduplicatedRefresh } from './httpProxy';
|
|
2
2
|
import { addQueryParam, createProxyLogger, httpToWs, matchPath, parseCookies, rewritePath } from './utils';
|
|
3
|
-
/**
|
|
4
|
-
* True when an access token is absent or within `skewMs` of expiring. Decodes the JWT
|
|
5
|
-
* exp WITHOUT verifying (verification happens at the backend) — this only decides whether
|
|
6
|
-
* to pre-emptively refresh before the WS handshake.
|
|
3
|
+
/**
|
|
4
|
+
* True when an access token is absent or within `skewMs` of expiring. Decodes the JWT
|
|
5
|
+
* exp WITHOUT verifying (verification happens at the backend) — this only decides whether
|
|
6
|
+
* to pre-emptively refresh before the WS handshake.
|
|
7
7
|
*/ function accessTokenExpiringSoon(token, skewMs = 60000) {
|
|
8
8
|
if (!token) return true;
|
|
9
9
|
try {
|
|
@@ -16,20 +16,20 @@ import { addQueryParam, createProxyLogger, httpToWs, matchPath, parseCookies, re
|
|
|
16
16
|
return true;
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
-
/**
|
|
20
|
-
* Keeps the proxy→backend socket alive with a PROTOCOL ping, not a data frame.
|
|
21
|
-
*
|
|
22
|
-
* This used to send `''`. An empty text frame is still application data, so it
|
|
23
|
-
* arrived at the backend's `message` handler, where `JSON.parse('')` throws —
|
|
24
|
-
* and nucleus' own PubSub route logged "Failed to parse client message" once per
|
|
25
|
-
* interval per connected client. On a busy IDP that is the entire debug log, and
|
|
26
|
-
* it names the proxy's own heartbeat as a misbehaving client.
|
|
27
|
-
*
|
|
28
|
-
* `ping()` is a control frame: it never reaches `message`, the peer answers with
|
|
29
|
-
* pong automatically, and it resets the idle timer the same way. Bun's WebSocket
|
|
30
|
-
* client implements it; the JSON heartbeat is the fallback for a runtime that
|
|
31
|
-
* does not, because `{"type":"ping"}` is a frame the PubSub route understands and
|
|
32
|
-
* replies to, rather than one it can only fail to parse.
|
|
19
|
+
/**
|
|
20
|
+
* Keeps the proxy→backend socket alive with a PROTOCOL ping, not a data frame.
|
|
21
|
+
*
|
|
22
|
+
* This used to send `''`. An empty text frame is still application data, so it
|
|
23
|
+
* arrived at the backend's `message` handler, where `JSON.parse('')` throws —
|
|
24
|
+
* and nucleus' own PubSub route logged "Failed to parse client message" once per
|
|
25
|
+
* interval per connected client. On a busy IDP that is the entire debug log, and
|
|
26
|
+
* it names the proxy's own heartbeat as a misbehaving client.
|
|
27
|
+
*
|
|
28
|
+
* `ping()` is a control frame: it never reaches `message`, the peer answers with
|
|
29
|
+
* pong automatically, and it resets the idle timer the same way. Bun's WebSocket
|
|
30
|
+
* client implements it; the JSON heartbeat is the fallback for a runtime that
|
|
31
|
+
* does not, because `{"type":"ping"}` is a frame the PubSub route understands and
|
|
32
|
+
* replies to, rather than one it can only fail to parse.
|
|
33
33
|
*/ function pingBackend(backendWs) {
|
|
34
34
|
const withPing = backendWs;
|
|
35
35
|
if (typeof withPing.ping === 'function') {
|
|
@@ -51,14 +51,14 @@ export function createWsProxyHandler(config) {
|
|
|
51
51
|
}
|
|
52
52
|
return null;
|
|
53
53
|
}
|
|
54
|
-
/**
|
|
55
|
-
* The backend URL, plus whether this handshake carries a credential at all.
|
|
56
|
-
*
|
|
57
|
-
* The second half is the point. This function already KNEW when it had no
|
|
58
|
-
* token — it logged "No token found" and handed back a URL anyway, and the
|
|
59
|
-
* caller upgraded the socket regardless. That silence is what turns one
|
|
60
|
-
* logged-out browser tab into a permanent reconnect storm; see the refusal in
|
|
61
|
-
* `upgrade()` for the measurements.
|
|
54
|
+
/**
|
|
55
|
+
* The backend URL, plus whether this handshake carries a credential at all.
|
|
56
|
+
*
|
|
57
|
+
* The second half is the point. This function already KNEW when it had no
|
|
58
|
+
* token — it logged "No token found" and handed back a URL anyway, and the
|
|
59
|
+
* caller upgraded the socket regardless. That silence is what turns one
|
|
60
|
+
* logged-out browser tab into a permanent reconnect storm; see the refusal in
|
|
61
|
+
* `upgrade()` for the measurements.
|
|
62
62
|
*/ async function buildBackendUrl(path, target, cookies, query) {
|
|
63
63
|
let baseUrl = target.url.replace(/\/$/, '');
|
|
64
64
|
if (baseUrl.startsWith('http')) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nucleus-core-ts",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.954",
|
|
4
4
|
"description": "Production-ready, enterprise-grade TypeScript framework for building multi-tenant APIs",
|
|
5
5
|
"author": "Hidayet Can Özcan <hidayetcan@gmail.com>",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|