@k2b/cloud 0.47.0 → 0.49.0
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/package.json +3 -3
- package/src/_internal/app-access-manager-sql.ts +10 -0
- package/src/_internal/app-access-resources.ts +2 -1
- package/src/_internal/app-capabilities.ts +73 -0
- package/src/_internal/app-event-catalog.ts +1 -1
- package/src/_internal/app-queries.ts +1 -1
- package/src/_internal/application-package.ts +2 -1
- package/src/_internal/bounded-json.ts +7 -1
- package/src/_internal/capabilities.ts +25 -2
- package/src/_internal/define-app.ts +33 -2
- package/src/_internal/heartbeat.ts +2 -0
- package/src/_internal/nats-connection.ts +10 -9
- package/src/_internal/process-sync.ts +6 -6
- package/src/_internal/public-surface.ts +76 -0
- package/src/_internal/purpose-name.ts +7 -0
- package/src/_internal/registry-validation.ts +1 -0
- package/src/_internal/registry.ts +49 -3
- package/src/_internal/workload-credential.ts +2 -1
- package/src/ai/app-skill-store.ts +2 -1
- package/src/ai/app-skills.ts +2 -1
- package/src/ai/approvals.ts +2 -1
- package/src/ai/chat-tasks.ts +2 -1
- package/src/ai/credentials.ts +2 -1
- package/src/ai/dictation-runtime.ts +1 -1
- package/src/ai/dictations.ts +1 -1
- package/src/ai/files-store.ts +2 -1
- package/src/ai/inference-calls.ts +2 -1
- package/src/ai/map-store.ts +1 -1
- package/src/ai/map-tool.ts +1 -1
- package/src/ai/memories.ts +1 -1
- package/src/ai/memory-learning-runs.ts +1 -1
- package/src/ai/memory-learning.ts +1 -1
- package/src/ai/memory-workflow-evidence.ts +1 -1
- package/src/ai/message-queue.ts +2 -1
- package/src/ai/migrate.ts +1 -1
- package/src/ai/model-access-migrate.ts +1 -1
- package/src/ai/model-access.ts +1 -1
- package/src/ai/model-catalog.ts +1 -1
- package/src/ai/model-delete.ts +1 -1
- package/src/ai/model-usage.ts +2 -1
- package/src/ai/open-questions.ts +1 -1
- package/src/ai/openai-api-slots.ts +2 -1
- package/src/ai/prefs.ts +2 -1
- package/src/ai/projects.ts +2 -1
- package/src/ai/provider-connections.ts +1 -1
- package/src/ai/quota-limits.ts +2 -1
- package/src/ai/quota-provider.ts +2 -1
- package/src/ai/quota-report.ts +2 -1
- package/src/ai/quotas-migrate.ts +2 -1
- package/src/ai/quotas.ts +2 -1
- package/src/ai/request-headers.ts +2 -1
- package/src/ai/review-content.ts +2 -1
- package/src/ai/skill-search.ts +2 -1
- package/src/ai/skills.ts +2 -1
- package/src/ai/store.ts +2 -1
- package/src/ai/structured-runs.ts +2 -1
- package/src/ai/tool-audit.ts +2 -1
- package/src/ai/turn-timing.ts +1 -1
- package/src/ai/usage.ts +2 -1
- package/src/ai/web-provenance.ts +2 -1
- package/src/api/admin-ai-quotas.ts +1 -1
- package/src/api/admin-ai.ts +1 -1
- package/src/api/admin-app-domains.ts +62 -0
- package/src/api/admin-app-keys.ts +47 -3
- package/src/api/admin-core-settings.ts +1 -1
- package/src/api/admin-outgoing-mail.ts +1 -1
- package/src/api/app-bootstrap.ts +153 -0
- package/src/api/app-events.ts +1 -1
- package/src/api/auth.ts +1 -1
- package/src/api/authenticate-app-request.ts +129 -0
- package/src/api/capabilities.ts +87 -6
- package/src/api/index.ts +7 -0
- package/src/api/me.ts +1 -1
- package/src/api/search.bench.ts +1 -1
- package/src/app-pwa/service.ts +2 -1
- package/src/app-pwa/transaction.ts +4 -2
- package/src/capabilities/claims.ts +2 -1
- package/src/capabilities/executions.ts +8 -4
- package/src/capabilities/geo-client.ts +1 -1
- package/src/capabilities/migrate.ts +3 -1
- package/src/capabilities/resource-readers.ts +2 -2
- package/src/capabilities/response.ts +2 -1
- package/src/capabilities/server-invoke.ts +73 -20
- package/src/capabilities/server.ts +2 -1
- package/src/cli/admin/app-domains.ts +140 -0
- package/src/cli/admin/app-keys.ts +25 -3
- package/src/cli/admin/index.ts +107 -88
- package/src/config/env.ts +10 -4
- package/src/contracts/app-domains.ts +91 -0
- package/src/contracts/app-status.ts +104 -0
- package/src/contracts/capabilities.ts +37 -2
- package/src/contracts/index.ts +1 -0
- package/src/contracts/outgoing-mail.ts +1 -1
- package/src/contracts/registry.ts +2 -0
- package/src/events/app-event-delivery.ts +1 -1
- package/src/events/live-delivery.ts +2 -1
- package/src/index.ts +1 -0
- package/src/runtime/bootstrap-client.ts +195 -0
- package/src/runtime/bootstrap-protocol.ts +67 -0
- package/src/runtime/clients.ts +6 -2
- package/src/runtime/connections.ts +9 -0
- package/src/server/app-key.ts +14 -0
- package/src/server/index.ts +2 -0
- package/src/server/ratelimit.ts +1 -1
- package/src/server/services/access.ts +2 -1
- package/src/services/account-category-policy.ts +1 -1
- package/src/services/account-lifecycle/audit.ts +1 -1
- package/src/services/account-lifecycle/index.ts +1 -1
- package/src/services/account-lifecycle/ipa-backfill.ts +2 -1
- package/src/services/accounts/app.ts +1 -1
- package/src/services/accounts/avatar.ts +1 -1
- package/src/services/accounts/base-group.ts +1 -1
- package/src/services/accounts/directory-shares.ts +1 -1
- package/src/services/accounts/duplicate-emails.ts +1 -1
- package/src/services/accounts/entities.ts +2 -1
- package/src/services/accounts/group-sql.ts +2 -1
- package/src/services/accounts/groups.ts +1 -1
- package/src/services/accounts/identities.ts +13 -11
- package/src/services/accounts/ipa-data.ts +1 -1
- package/src/services/accounts/local-groups.ts +2 -1
- package/src/services/accounts/machine-group-management.ts +2 -1
- package/src/services/accounts/posix.ts +13 -12
- package/src/services/accounts/request-policy.ts +2 -1
- package/src/services/accounts/switching.ts +1 -1
- package/src/services/accounts/users.ts +2 -1
- package/src/services/announcements/index.ts +1 -1
- package/src/services/app-access-management.ts +3 -9
- package/src/services/app-access.ts +2 -1
- package/src/services/app-admin-facts.ts +160 -0
- package/src/services/app-approval.ts +34 -30
- package/src/services/app-bootstrap.ts +217 -0
- package/src/services/app-details.ts +3 -2
- package/src/services/app-domain-check.ts +152 -0
- package/src/services/app-domains.ts +172 -0
- package/src/services/app-events/accept.ts +5 -5
- package/src/services/app-events/admin.ts +15 -15
- package/src/services/app-events/declarations.ts +6 -3
- package/src/services/app-events/deliver.ts +6 -6
- package/src/services/app-events.ts +3 -2
- package/src/services/app-keys.ts +45 -11
- package/src/services/approvals/content.ts +1 -1
- package/src/services/approvals/index.ts +2 -1
- package/src/services/approvals/list.ts +1 -1
- package/src/services/approvals/migrate.ts +1 -1
- package/src/services/audit/index.ts +2 -1
- package/src/services/auth-flows/ipa.ts +1 -1
- package/src/services/auth-flows/magic-link.ts +1 -1
- package/src/services/auth-flows/password-reset.ts +1 -1
- package/src/services/auth-flows/proxy-return.ts +1 -1
- package/src/services/downstream-budget.ts +2 -2
- package/src/services/geo/admin.ts +13 -12
- package/src/services/geo/identity.ts +46 -0
- package/src/services/geo/ledger.ts +118 -106
- package/src/services/geo/migrate.ts +2 -1
- package/src/services/geo/route-chain.ts +3 -3
- package/src/services/geo/service.ts +4 -24
- package/src/services/geoip/index.ts +5 -5
- package/src/services/geoip/store.ts +24 -21
- package/src/services/help/index.ts +2 -1
- package/src/services/help/store.ts +2 -1
- package/src/services/identity/app-request.ts +44 -0
- package/src/services/identity/constants.ts +1 -0
- package/src/services/identity/index.ts +1 -0
- package/src/services/identity/invocation-actor.ts +2 -1
- package/src/services/identity/invocation-token.ts +112 -0
- package/src/services/identity/key-ring.ts +2 -2
- package/src/services/identity/resource-readers.ts +1 -1
- package/src/services/identity/routes.ts +11 -3
- package/src/services/identity/runtime-config.ts +14 -3
- package/src/services/identity/workload-auth.ts +2 -0
- package/src/services/identity/workload-runtime.ts +3 -3
- package/src/services/index.ts +4 -0
- package/src/services/ipa/groups.ts +1 -1
- package/src/services/ipa/profile.ts +1 -1
- package/src/services/ipa/search.ts +1 -1
- package/src/services/ipa/sync.ts +1 -1
- package/src/services/ipa/users.ts +1 -1
- package/src/services/known-browsers.ts +2 -1
- package/src/services/legal-consent.ts +1 -1
- package/src/services/links/index.ts +16 -0
- package/src/services/links/runtime.ts +44 -0
- package/src/services/links/store.ts +105 -0
- package/src/services/logging/index.ts +13 -8
- package/src/services/logging/redaction.ts +6 -1
- package/src/services/logging/trace.ts +9 -9
- package/src/services/logging/web-vitals.ts +1 -1
- package/src/services/mandates/index.ts +2 -1
- package/src/services/notifications/batches.ts +1 -1
- package/src/services/notifications/browser.ts +1 -1
- package/src/services/notifications/catalog.ts +1 -1
- package/src/services/notifications/dispatcher.ts +1 -1
- package/src/services/notifications/index.ts +1 -1
- package/src/services/notifications/observability.ts +2 -1
- package/src/services/notifications/platform.ts +1 -1
- package/src/services/notifications/quiet.ts +1 -1
- package/src/services/notifications/user.ts +1 -1
- package/src/services/oauth-tokens.ts +1 -1
- package/src/services/outbox.ts +15 -14
- package/src/services/outgoing-mail/admin.ts +1 -1
- package/src/services/outgoing-mail/dispatcher.ts +1 -1
- package/src/services/outgoing-mail/drain.ts +2 -1
- package/src/services/outgoing-mail/enqueue.ts +2 -1
- package/src/services/outgoing-mail/messages.ts +2 -1
- package/src/services/outgoing-mail/retention.ts +1 -1
- package/src/services/outgoing-mail/send.ts +1 -1
- package/src/services/outgoing-mail/store.ts +2 -1
- package/src/services/panel-context-consent.ts +32 -28
- package/src/services/providers/local/auth.ts +1 -1
- package/src/services/providers/local/users.ts +1 -1
- package/src/services/pwa-devices.ts +2 -1
- package/src/services/rail-preferences.ts +16 -12
- package/src/services/rail-shortcuts.ts +12 -10
- package/src/services/request-cache-redis.ts +3 -3
- package/src/services/service-account-credentials.ts +2 -1
- package/src/services/service-accounts.ts +2 -1
- package/src/services/session/index.ts +2 -1
- package/src/services/session/user.ts +2 -1
- package/src/services/settings/core-settings.ts +20 -0
- package/src/services/settings/crypto.ts +2 -2
- package/src/services/settings/index.ts +1 -1
- package/src/services/settings/store.ts +6 -1
- package/src/services/settings/versions.ts +2 -1
- package/src/services/weather/forecast.ts +2 -1
- package/src/services/weather/locations.ts +1 -1
- package/src/services/weather/migrate.ts +2 -1
- package/src/services/weather/short-id.ts +2 -1
- package/src/services/webauthn.ts +1 -1
- package/src/ssr/admin-navigation.ts +0 -1
- package/src/ssr/compact-shell.browser-harness.ts +2 -0
- package/src/ssr/platform-messages.ts +0 -2
- package/src/start.ts +35 -14
- package/src/workflows/ai/store.ts +2 -1
- package/src/workflows/store/budget.ts +2 -1
- package/src/workflows/store/definitions.ts +2 -1
- package/src/workflows/store/events.ts +2 -1
- package/src/workflows/store/observability.ts +2 -1
- package/src/workflows/store/retention.ts +2 -1
- package/src/workflows/store/runs.ts +2 -1
- package/src/workflows/store/transaction.ts +2 -1
- package/src/workflows/store/worker.ts +2 -1
package/src/cli/admin/index.ts
CHANGED
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
* them. The groups map to the admin UI areas, so a command and the page that
|
|
6
6
|
* shows the same data stay easy to find together.
|
|
7
7
|
*/
|
|
8
|
+
|
|
8
9
|
import { defineCliCommands } from "../commands";
|
|
10
|
+
import { type CloudCliContext, localizeCloudCliText } from "../index";
|
|
9
11
|
import { accountAdministrationCommands } from "./account-administration";
|
|
10
12
|
import { accountCategoryCommands } from "./account-categories";
|
|
11
13
|
import { agentCommands } from "./agents";
|
|
@@ -14,6 +16,7 @@ import { aiQuotaCommands } from "./ai-quotas";
|
|
|
14
16
|
import { aiSkillCommands } from "./ai-skills";
|
|
15
17
|
import { aiUsageCommands } from "./ai-usage";
|
|
16
18
|
import { appCredentialCommands } from "./app-credentials";
|
|
19
|
+
import { appDomainCommands } from "./app-domains";
|
|
17
20
|
import { appKeyCommands } from "./app-keys";
|
|
18
21
|
import { appSignInCommands } from "./app-sign-in";
|
|
19
22
|
import { dataCommands } from "./data";
|
|
@@ -35,91 +38,107 @@ import { telemetryCommands } from "./telemetry";
|
|
|
35
38
|
import { webhookCommands } from "./webhooks";
|
|
36
39
|
import { workflowCommands } from "./workflows";
|
|
37
40
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
41
|
+
const build = (locale?: string) =>
|
|
42
|
+
defineCliCommands({
|
|
43
|
+
name: "admin",
|
|
44
|
+
summary: "Inspect and operate Cloud administration surfaces.",
|
|
45
|
+
groupSummaries: {
|
|
46
|
+
accounts: "Manage account policy and account administration.",
|
|
47
|
+
ai: "Manage AI models, quotas, Skills, and usage.",
|
|
48
|
+
"ai models": "Manage AI model configuration.",
|
|
49
|
+
"ai providers": "Manage AI provider connections.",
|
|
50
|
+
"ai variants": "Manage named model variants.",
|
|
51
|
+
"ai classes": "Manage model classes and tools.",
|
|
52
|
+
"ai quotas background": "Inspect and release the background emergency stop.",
|
|
53
|
+
"ai skills": "Inspect Assistant Skills and trusted templates.",
|
|
54
|
+
"ai usage": "Inspect AI runs and usage facets.",
|
|
55
|
+
announcements: "Manage platform announcements and banners.",
|
|
56
|
+
"app-credentials": "Manage per-application credentials for background work.",
|
|
57
|
+
agents: "Create, list, revoke, and re-key agent accounts with OAuth client credentials, and change their pictures.",
|
|
58
|
+
"agents avatar": "Show and change an agent's picture: its robot parts or a photo.",
|
|
59
|
+
"app-sign-in": "Manage app sign-in and pairing.",
|
|
60
|
+
apps: localizeCloudCliText(locale, {
|
|
61
|
+
en: "Inspect registered apps and manage app keys and domains.",
|
|
62
|
+
de: "Registrierte Apps prüfen und App-Schlüssel und App-Domains verwalten.",
|
|
63
|
+
}),
|
|
64
|
+
"apps domains": localizeCloudCliText(locale, {
|
|
65
|
+
en: "Assign app domains and inspect DNS, TLS and gateway reachability.",
|
|
66
|
+
de: "App-Domains zuordnen und DNS, TLS und Gateway-Erreichbarkeit prüfen.",
|
|
67
|
+
}),
|
|
68
|
+
"apps keys": "Create, list, and revoke Ed25519 app keys.",
|
|
69
|
+
documentation: "Manage the administration documentation website.",
|
|
70
|
+
geoip: "Replace and inspect sign-in location databases.",
|
|
71
|
+
jobs: "Inspect background jobs and their runs.",
|
|
72
|
+
logs: "Search, inspect, and clean up retained logs.",
|
|
73
|
+
metrics: "Inspect collectors and manage metrics access.",
|
|
74
|
+
"metrics tokens": "Manage metrics bearer tokens.",
|
|
75
|
+
nats: "Inspect NATS nodes, streams, and consumers.",
|
|
76
|
+
"nats consumers": "Inspect NATS consumers.",
|
|
77
|
+
"nats streams": "Find NATS streams and buckets.",
|
|
78
|
+
"notification-batches": "Manage account notification batches.",
|
|
79
|
+
"outgoing-mail": "Manage outgoing mail sender profiles, application access, and the send log.",
|
|
80
|
+
"outgoing-mail profiles": "Manage outgoing mail sender profiles.",
|
|
81
|
+
"outgoing-mail apps": "Manage application outgoing mail access.",
|
|
82
|
+
"outgoing-mail log": "Read and cancel application mail in the send log.",
|
|
83
|
+
"outgoing-mail retention": "Show or change how long the send log keeps mail.",
|
|
84
|
+
notifications: "Inspect and resend email notifications.",
|
|
85
|
+
postgres: "Inspect Postgres diagnostics.",
|
|
86
|
+
redis: "Inspect Valkey diagnostics.",
|
|
87
|
+
routes: "Inspect gateway routes.",
|
|
88
|
+
settings: "Inspect environment migration and change administrator settings.",
|
|
89
|
+
sync: "Inspect Sync resources, schedules, and dead letters.",
|
|
90
|
+
"sync dead-letters": "Inspect, replay, requeue, or remove dead letters.",
|
|
91
|
+
"sync resources": "List Sync resource declarations.",
|
|
92
|
+
"sync schedules": "Inspect and run Sync schedules.",
|
|
93
|
+
"sync schedules runs": "Read Sync schedule run results.",
|
|
94
|
+
telemetry: "Inspect request telemetry.",
|
|
95
|
+
webhooks: "Manage gateway health webhooks.",
|
|
96
|
+
workflows: "Inspect and operate workflow runs and effects.",
|
|
97
|
+
"app-sign-in config": "Manage the trusted app website and pairing policy.",
|
|
98
|
+
"accounts config": "Manage account types and sign-in visibility.",
|
|
99
|
+
"accounts administration": "Manage account requests and account/group follow-up notices.",
|
|
100
|
+
"ai quotas": "Manage direct Assistant chat limits and consumption.",
|
|
101
|
+
"ai quotas config": "Export and replace quota policies with revision checks.",
|
|
102
|
+
legal: "Manage Terms, Privacy, and Imprint.",
|
|
103
|
+
linux: "Prepare Linux identities.",
|
|
104
|
+
"linux config": "Manage Linux identity defaults and allocation range.",
|
|
105
|
+
},
|
|
106
|
+
commands: [
|
|
107
|
+
...appCredentialCommands,
|
|
108
|
+
...appKeyCommands,
|
|
109
|
+
...appDomainCommands(locale),
|
|
110
|
+
...agentCommands,
|
|
111
|
+
...documentationCommands,
|
|
112
|
+
...appSignInCommands,
|
|
113
|
+
...accountCategoryCommands,
|
|
114
|
+
...accountAdministrationCommands,
|
|
115
|
+
...aiUsageCommands,
|
|
116
|
+
...aiModelCommands,
|
|
117
|
+
...aiQuotaCommands,
|
|
118
|
+
...aiSkillCommands,
|
|
119
|
+
...instanceCommands,
|
|
120
|
+
...gatewayCommands,
|
|
121
|
+
...logCommands,
|
|
122
|
+
...telemetryCommands,
|
|
123
|
+
...jobCommands,
|
|
124
|
+
...legalCommands,
|
|
125
|
+
...geoipCommands,
|
|
126
|
+
...linuxCommands,
|
|
127
|
+
...workflowCommands,
|
|
128
|
+
...dataCommands,
|
|
129
|
+
...notificationCommands,
|
|
130
|
+
...outgoingMailCommands,
|
|
131
|
+
...webhookCommands,
|
|
132
|
+
...metricsCommands,
|
|
133
|
+
...natsCommands,
|
|
134
|
+
...syncCommands,
|
|
135
|
+
...settingsCommands,
|
|
136
|
+
],
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
const admin = build();
|
|
140
|
+
export default {
|
|
141
|
+
...admin,
|
|
142
|
+
help: (locale?: string) => build(locale).help?.(locale) ?? "",
|
|
143
|
+
run: (ctx: CloudCliContext) => build(ctx.options.locale).run(ctx),
|
|
144
|
+
};
|
package/src/config/env.ts
CHANGED
|
@@ -164,17 +164,23 @@ const registry = defineEnv({
|
|
|
164
164
|
schema: z.string(),
|
|
165
165
|
scope: "secret",
|
|
166
166
|
secretFile: true,
|
|
167
|
-
doc: "Core and OAuth
|
|
167
|
+
doc: "Deprecated: Core and OAuth legacy 64-hex broker secret, used only when OAuth has no app key. Configure an OAuth app key instead; retained for this release.",
|
|
168
|
+
},
|
|
169
|
+
CLOUD_APP_KEY: {
|
|
170
|
+
schema: z.string(),
|
|
171
|
+
scope: "secret",
|
|
172
|
+
secretFile: true,
|
|
173
|
+
doc: "App Ed25519 private key for startup bootstrap, background calls and OAuth issuance; alternatively mount CLOUD_APP_KEY_FILE. Requires the direct Core origin. Core and Gateway refuse app keys. Keep infrastructure env until the platform-client import migration is complete.",
|
|
168
174
|
},
|
|
169
175
|
CLOUD_CORE_INTERNAL_ORIGIN: {
|
|
170
176
|
schema: z.string(),
|
|
171
|
-
doc: "Direct Core listener origin for OAuth issuance, mandate-backed background work and internal callbacks; host
|
|
177
|
+
doc: "Direct Core listener origin for app connection bootstrap, OAuth issuance, mandate-backed background work and internal callbacks; never the gateway. Cross-host bootstrap requires verified TLS; install private CAs through NODE_EXTRA_CA_CERTS before the first fetch.",
|
|
172
178
|
},
|
|
173
179
|
CLOUD_APP_CREDENTIAL: {
|
|
174
180
|
schema: z.string(),
|
|
175
181
|
scope: "secret",
|
|
176
182
|
secretFile: true,
|
|
177
|
-
doc: "
|
|
183
|
+
doc: "Deprecated: host-run override for the automatically delivered workload credential when no app key is configured; use CLOUD_APP_KEY or CLOUD_APP_KEY_FILE instead. Retained for this release.",
|
|
178
184
|
},
|
|
179
185
|
CLOUD_IDENTITY_JWKS_ORIGIN: {
|
|
180
186
|
schema: z.string(),
|
|
@@ -182,7 +188,7 @@ const registry = defineEnv({
|
|
|
182
188
|
},
|
|
183
189
|
CLOUD_OAUTH_JWKS_ORIGIN: {
|
|
184
190
|
schema: z.string(),
|
|
185
|
-
doc: "
|
|
191
|
+
doc: "Deprecated: explicit legacy OAuth JWKS origin, honored for this release. Unset uses Core internal OAuth JWKS through CLOUD_CORE_INTERNAL_ORIGIN, then the public issuer origin.",
|
|
186
192
|
},
|
|
187
193
|
|
|
188
194
|
// Build and standalone development
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { SQL } from "bun";
|
|
2
|
+
import { PWA_COOKIES } from "./pwa";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* App public surface and app domains: the contract Core, the platform, and the gateway share.
|
|
6
|
+
*
|
|
7
|
+
* An app with `defineApp({ public: true })` serves `app.public`. The platform mounts that router below
|
|
8
|
+
* `PUBLIC_SURFACE_PREFIX` on the app upstream. Only the gateway sends requests there, for a host an
|
|
9
|
+
* administrator assigned to the app, and sets `PUBLIC_HOST_HEADER` to the request authority (that host plus the
|
|
10
|
+
* client's port, if its Host header had one). The gateway strips both
|
|
11
|
+
* the prefix and the header from every incoming request on every host.
|
|
12
|
+
*/
|
|
13
|
+
export const PUBLIC_SURFACE_PREFIX = "/_cloud/public";
|
|
14
|
+
export const PUBLIC_HOST_HEADER = "X-Cloud-Public-Host";
|
|
15
|
+
|
|
16
|
+
/** The only Cloud path on an app domain: `GET <prefix><nonce>` answers the nonce while Core checks the domain. */
|
|
17
|
+
export const DOMAIN_CHECK_PATH_PREFIX = "/_cloud/domain-check/";
|
|
18
|
+
/**
|
|
19
|
+
* Valkey key Core sets before it requests the check path, with TTL `DOMAIN_CHECK_TTL_SECONDS`. Its value is a
|
|
20
|
+
* separate random answer that never appears in the request; the gateway responds with it, so an unrelated server
|
|
21
|
+
* that echoes the path cannot pass the check.
|
|
22
|
+
*/
|
|
23
|
+
export const domainCheckKey = (host: string, nonce: string): string => `cloud:domain-check:${host}:${nonce}`;
|
|
24
|
+
export const DOMAIN_CHECK_TTL_SECONDS = 60;
|
|
25
|
+
|
|
26
|
+
export type AppDomain = {
|
|
27
|
+
/** Normalized host: lowercase ASCII (IDNA), no port, no wildcard. */
|
|
28
|
+
host: string;
|
|
29
|
+
appId: string;
|
|
30
|
+
/** Another domain of the same app; requests then answer 301 (GET/HEAD) or 308 with path and query kept. */
|
|
31
|
+
redirectTo: string | null;
|
|
32
|
+
createdAt: string;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/** Durable assignment, owned by Core's migration. Readers before that migration see no table and no domains. */
|
|
36
|
+
export const APP_DOMAINS_DDL = `
|
|
37
|
+
CREATE TABLE IF NOT EXISTS settings.app_domains (
|
|
38
|
+
host TEXT PRIMARY KEY,
|
|
39
|
+
app_id TEXT NOT NULL,
|
|
40
|
+
redirect_to TEXT NULL,
|
|
41
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
42
|
+
)
|
|
43
|
+
`;
|
|
44
|
+
|
|
45
|
+
const HOST_LABEL = /^(?!-)[a-z0-9-]{1,63}(?<!-)$/;
|
|
46
|
+
|
|
47
|
+
/** Returns the normalized host, or null when `input` is not a single DNS host name without port or wildcard. */
|
|
48
|
+
export const normalizeAppDomainHost = (input: string): string | null => {
|
|
49
|
+
const trimmed = input.trim().replace(/\.$/, "");
|
|
50
|
+
if (!trimmed || /[/\\:@?#*\s]/.test(trimmed)) return null;
|
|
51
|
+
let host: string;
|
|
52
|
+
try {
|
|
53
|
+
host = new URL(`http://${trimmed}`).hostname;
|
|
54
|
+
} catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
if (host.length > 253 || /^\d+(\.\d+){3}$/.test(host) || host.startsWith("[")) return null;
|
|
58
|
+
const labels = host.split(".");
|
|
59
|
+
if (labels.length < 2 && !host.endsWith("localhost")) return null;
|
|
60
|
+
return labels.every((label) => HOST_LABEL.test(label)) ? host : null;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/** Reads all assignments. A database without Core's table yet has none. */
|
|
64
|
+
export const readAppDomains = async (db: SQL): Promise<AppDomain[]> => {
|
|
65
|
+
try {
|
|
66
|
+
const rows = await db<{ host: string; app_id: string; redirect_to: string | null; created_at: Date }[]>`
|
|
67
|
+
SELECT host, app_id, redirect_to, created_at FROM settings.app_domains ORDER BY host
|
|
68
|
+
`;
|
|
69
|
+
return rows.map((row) => ({ host: row.host, appId: row.app_id, redirectTo: row.redirect_to, createdAt: row.created_at.toISOString() }));
|
|
70
|
+
} catch (error) {
|
|
71
|
+
const code = error && typeof error === "object" && "errno" in error ? String(error.errno) : "";
|
|
72
|
+
if (code === "42P01") return [];
|
|
73
|
+
throw error;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/** Whether a registry entry declares `public: true`, read structurally so older entries stay valid. */
|
|
78
|
+
export const declaresPublicSurface = (entry: object): boolean => "public" in entry && entry.public === true;
|
|
79
|
+
|
|
80
|
+
/** Cookies that carry a Cloud credential. The gateway removes them from every request to a public surface. */
|
|
81
|
+
export const isCloudCredentialCookie = (name: string): boolean =>
|
|
82
|
+
name === "session_token" ||
|
|
83
|
+
name === PWA_COOKIES.session ||
|
|
84
|
+
name === PWA_COOKIES.device ||
|
|
85
|
+
name === PWA_COOKIES.pairing ||
|
|
86
|
+
name === "cloud_browser" ||
|
|
87
|
+
name === "__Host-cloud_browser" ||
|
|
88
|
+
name.startsWith("__Secure-cloud-app-pwa-") ||
|
|
89
|
+
// Access proofs that built-in apps set on the Cloud host.
|
|
90
|
+
name === "mail_attachment_grant" ||
|
|
91
|
+
name === "filesv2-share-access";
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { CapabilityAppIdSchema, type CapabilityManifest } from "./capabilities";
|
|
3
|
+
import { type CapabilityContractIssue, capabilityContractIssues } from "./capability-compatibility";
|
|
4
|
+
|
|
5
|
+
export const AppStatusWindowSchema = z.enum(["1h", "6h", "24h", "7d", "30d"]);
|
|
6
|
+
export type AppStatusWindow = z.infer<typeof AppStatusWindowSchema>;
|
|
7
|
+
export const AppStatusSummaryInputSchema = z
|
|
8
|
+
.object({
|
|
9
|
+
appIds: z.array(CapabilityAppIdSchema).min(1).max(200).describe("Application IDs whose status is requested."),
|
|
10
|
+
window: AppStatusWindowSchema.describe("Traffic observation window."),
|
|
11
|
+
})
|
|
12
|
+
.strict();
|
|
13
|
+
export const AppStatusDetailInputSchema = z
|
|
14
|
+
.object({
|
|
15
|
+
appId: CapabilityAppIdSchema.describe("Application ID."),
|
|
16
|
+
window: AppStatusWindowSchema.describe("Traffic observation window."),
|
|
17
|
+
cursor: z.string().min(1).max(2048).optional().describe("Opaque continuation cursor from this provider."),
|
|
18
|
+
})
|
|
19
|
+
.strict();
|
|
20
|
+
export const AppStatusForgetInputSchema = z.object({ appId: CapabilityAppIdSchema.describe("Offline application ID to forget.") }).strict();
|
|
21
|
+
const count = z.number().int().nonnegative();
|
|
22
|
+
export const AppStatusTrafficSchema = z
|
|
23
|
+
.object({
|
|
24
|
+
requests: count,
|
|
25
|
+
errors: count,
|
|
26
|
+
avgMs: z.number().nonnegative().nullable(),
|
|
27
|
+
})
|
|
28
|
+
.strict();
|
|
29
|
+
export const AppStatusLinkSchema = z
|
|
30
|
+
.object({
|
|
31
|
+
kind: z.enum(["logs", "metrics", "routes", "capabilities"]).optional(),
|
|
32
|
+
label: z.string().min(1).max(120),
|
|
33
|
+
href: z
|
|
34
|
+
.string()
|
|
35
|
+
.max(2048)
|
|
36
|
+
.regex(/^\/admin\/[^\\\s\u0000-\u001f\u007f]*$/),
|
|
37
|
+
})
|
|
38
|
+
.strict();
|
|
39
|
+
export const AppStatusAppSchema = z
|
|
40
|
+
.object({
|
|
41
|
+
appId: CapabilityAppIdSchema.describe("Application ID."),
|
|
42
|
+
traffic: AppStatusTrafficSchema.nullable(),
|
|
43
|
+
links: z.array(AppStatusLinkSchema).max(4),
|
|
44
|
+
lastSeenAt: z.string().datetime({ offset: true }).nullable().optional(),
|
|
45
|
+
})
|
|
46
|
+
.strict();
|
|
47
|
+
export const AppStatusSummaryDataSchema = z
|
|
48
|
+
.object({
|
|
49
|
+
// Requested apps plus the fifty provider-only apps; their rows carry lastSeenAt.
|
|
50
|
+
apps: z.array(AppStatusAppSchema).max(250),
|
|
51
|
+
otherApps: z.array(CapabilityAppIdSchema).max(50),
|
|
52
|
+
})
|
|
53
|
+
.strict();
|
|
54
|
+
export const AppStatusDetailDataSchema = z
|
|
55
|
+
.object({
|
|
56
|
+
routes: z.array(z.object({ prefix: z.string().min(1).max(2048), requests: count, errors: count }).strict()).max(200),
|
|
57
|
+
failedRequests: z
|
|
58
|
+
.array(
|
|
59
|
+
z
|
|
60
|
+
.object({
|
|
61
|
+
at: z.string().datetime({ offset: true }),
|
|
62
|
+
method: z.string().min(1).max(32),
|
|
63
|
+
path: z.string().min(1).max(2048),
|
|
64
|
+
status: z.number().int().min(100).max(599),
|
|
65
|
+
})
|
|
66
|
+
.strict(),
|
|
67
|
+
)
|
|
68
|
+
.max(50),
|
|
69
|
+
totalFailedRequests: count.nullable().optional(),
|
|
70
|
+
nextCursor: z.string().min(1).max(2048).nullable(),
|
|
71
|
+
})
|
|
72
|
+
.strict();
|
|
73
|
+
export const AppStatusForgetDataSchema = z.object({ forgotten: z.boolean() }).strict();
|
|
74
|
+
export type AppStatusSummaryData = z.infer<typeof AppStatusSummaryDataSchema>;
|
|
75
|
+
export type AppStatusDetailData = z.infer<typeof AppStatusDetailDataSchema>;
|
|
76
|
+
|
|
77
|
+
/** Shared role validation at startup, registry read, and consumer discovery. */
|
|
78
|
+
export const appStatusIssues = (manifest: CapabilityManifest): CapabilityContractIssue[] => {
|
|
79
|
+
const role = manifest.appStatus;
|
|
80
|
+
if (!role) return [];
|
|
81
|
+
const issues: CapabilityContractIssue[] = [];
|
|
82
|
+
for (const [localId, input, data] of [
|
|
83
|
+
[role.summary, AppStatusSummaryInputSchema, AppStatusSummaryDataSchema],
|
|
84
|
+
[role.detail, AppStatusDetailInputSchema, AppStatusDetailDataSchema],
|
|
85
|
+
] as const) {
|
|
86
|
+
const query = manifest.queries.find((query) => query.localId === localId);
|
|
87
|
+
if (!query) issues.push({ code: "kind", path: "$", message: `Missing app-status Query ${localId}` });
|
|
88
|
+
else {
|
|
89
|
+
issues.push(...capabilityContractIssues({ kind: "query", input, data }, { kind: "query", operation: query }));
|
|
90
|
+
if (query.appOnly || query.openWorld)
|
|
91
|
+
issues.push({ code: "kind", path: "$", message: "App-status Queries must be closed-world and person-readable" });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const action = manifest.actions.find((action) => action.localId === role.forget);
|
|
95
|
+
if (!action) issues.push({ code: "kind", path: "$", message: `Missing app-status Action ${role.forget}` });
|
|
96
|
+
else
|
|
97
|
+
issues.push(
|
|
98
|
+
...capabilityContractIssues(
|
|
99
|
+
{ kind: "action", input: AppStatusForgetInputSchema, data: AppStatusForgetDataSchema, idempotency: "required" },
|
|
100
|
+
{ kind: "action", operation: action },
|
|
101
|
+
),
|
|
102
|
+
);
|
|
103
|
+
return issues;
|
|
104
|
+
};
|
|
@@ -12,6 +12,7 @@ import { z } from "zod";
|
|
|
12
12
|
import type { RequestAuthority } from "../server/middleware/auth";
|
|
13
13
|
import type { AppEventDefinition, AppEventSubscriptionDefinition } from "./app-events";
|
|
14
14
|
import { CommandPathSchema } from "./commands";
|
|
15
|
+
import { type PlatformPermission, PlatformPermissionSchema } from "./outgoing-mail";
|
|
15
16
|
import type { AccessSubject, RequestActor, User } from "./shared";
|
|
16
17
|
import { AuthenticatedPrincipalSchema } from "./shared";
|
|
17
18
|
|
|
@@ -955,12 +956,12 @@ export type CapabilityPresentationCatalog = {
|
|
|
955
956
|
|
|
956
957
|
/** App authority has no grant-bearing subject, user, nested exchange, or interactive credential. */
|
|
957
958
|
export type CapabilityAppExecutionContext = {
|
|
958
|
-
actor: { kind: "app"; appId: string };
|
|
959
|
+
actor: { kind: "app"; appId: string; keyId?: string };
|
|
959
960
|
accessSubject: { type: "none" };
|
|
960
961
|
user: null;
|
|
961
962
|
authority?: never;
|
|
962
963
|
query?: never;
|
|
963
|
-
idempotencyKey?:
|
|
964
|
+
idempotencyKey?: string;
|
|
964
965
|
locale: string;
|
|
965
966
|
requestId: string;
|
|
966
967
|
origin: CapabilityOrigin;
|
|
@@ -968,8 +969,18 @@ export type CapabilityAppExecutionContext = {
|
|
|
968
969
|
signal: AbortSignal;
|
|
969
970
|
};
|
|
970
971
|
|
|
972
|
+
/** Explicit provider entry for calls paid for and authorized as the calling application. */
|
|
973
|
+
export type CapabilityAppHandler<Input extends z.ZodType, Data extends z.ZodType> = {
|
|
974
|
+
permission: PlatformPermission;
|
|
975
|
+
run: (
|
|
976
|
+
input: z.output<Input>,
|
|
977
|
+
context: CapabilityAppExecutionContext,
|
|
978
|
+
) => CapabilityInvocationResult<z.output<Data>> | Promise<CapabilityInvocationResult<z.output<Data>>>;
|
|
979
|
+
};
|
|
980
|
+
|
|
971
981
|
export type CapabilityQueryDefinition<Input extends z.ZodType = z.ZodType<any>, Data extends z.ZodType = z.ZodType<any>> = {
|
|
972
982
|
appOnly?: never;
|
|
983
|
+
app?: CapabilityAppHandler<Input, Data>;
|
|
973
984
|
title: string;
|
|
974
985
|
description: string;
|
|
975
986
|
input: Input;
|
|
@@ -988,6 +999,7 @@ export type CapabilityActionApprovalPolicy = "rememberable" | "none";
|
|
|
988
999
|
|
|
989
1000
|
export type CapabilityActionDefinition<Input extends z.ZodType = z.ZodType<any>, Data extends z.ZodType = z.ZodType<any>> = {
|
|
990
1001
|
appOnly?: never;
|
|
1002
|
+
app?: CapabilityAppHandler<Input, Data>;
|
|
991
1003
|
title: string;
|
|
992
1004
|
description: string;
|
|
993
1005
|
input: Input;
|
|
@@ -1039,6 +1051,8 @@ export type CapabilityFileProviderDeclaration = { list: string; read: string; sa
|
|
|
1039
1051
|
|
|
1040
1052
|
export type CapabilityCalendarSourceDeclaration = { calendars: string; events: string; update?: string; move?: string; delete?: string };
|
|
1041
1053
|
|
|
1054
|
+
export type CapabilityAppStatusDeclaration = { summary: string; detail: string; forget: string };
|
|
1055
|
+
|
|
1042
1056
|
export type CapabilityDiscussionsDeclaration = { item: string; containers: string; activity?: string };
|
|
1043
1057
|
|
|
1044
1058
|
export type CapabilityDefinitions = {
|
|
@@ -1051,6 +1065,7 @@ export type CapabilityDefinitions = {
|
|
|
1051
1065
|
fileProvider?: CapabilityFileProviderDeclaration;
|
|
1052
1066
|
calendarSource?: CapabilityCalendarSourceDeclaration;
|
|
1053
1067
|
discussions?: CapabilityDiscussionsDeclaration;
|
|
1068
|
+
appStatus?: CapabilityAppStatusDeclaration;
|
|
1054
1069
|
events?: CapabilityDefinitionCatalog<AppEventDefinition>;
|
|
1055
1070
|
subscribes?: CapabilityDefinitionCatalog<AppEventSubscriptionDefinition>;
|
|
1056
1071
|
};
|
|
@@ -1101,6 +1116,7 @@ const CapabilityOperationManifestBaseSchema = z
|
|
|
1101
1116
|
inputSchema: z.record(z.string(), z.unknown()),
|
|
1102
1117
|
dataSchema: z.record(z.string(), z.unknown()),
|
|
1103
1118
|
stream: CapabilityStreamPolicySchema.optional(),
|
|
1119
|
+
appPermission: PlatformPermissionSchema.optional(),
|
|
1104
1120
|
schemaHash: z.string().regex(/^[a-f0-9]{64}$/),
|
|
1105
1121
|
})
|
|
1106
1122
|
.strict();
|
|
@@ -1179,6 +1195,14 @@ export const CapabilityResourcePageManifestSchema = z
|
|
|
1179
1195
|
})
|
|
1180
1196
|
.strict();
|
|
1181
1197
|
|
|
1198
|
+
export const CapabilityAppStatusManifestSchema = z
|
|
1199
|
+
.object({
|
|
1200
|
+
summary: CapabilityLocalIdSchema,
|
|
1201
|
+
detail: CapabilityLocalIdSchema,
|
|
1202
|
+
forget: CapabilityLocalIdSchema,
|
|
1203
|
+
})
|
|
1204
|
+
.strict();
|
|
1205
|
+
|
|
1182
1206
|
export const CapabilityDiscussionsManifestSchema = z
|
|
1183
1207
|
.object({
|
|
1184
1208
|
item: CapabilityLocalIdSchema,
|
|
@@ -1268,6 +1292,7 @@ const readableManifest = (value: unknown, personCatalog = false): unknown => {
|
|
|
1268
1292
|
resourcePages: sentPages,
|
|
1269
1293
|
resourceTypes: sentModels,
|
|
1270
1294
|
discussions: sentDiscussions,
|
|
1295
|
+
appStatus: sentAppStatus,
|
|
1271
1296
|
...rest
|
|
1272
1297
|
} = sent;
|
|
1273
1298
|
const models = readEntries(sentModels ?? [], CapabilityResourceTypeModelSchema) ?? [];
|
|
@@ -1309,6 +1334,14 @@ const readableManifest = (value: unknown, personCatalog = false): unknown => {
|
|
|
1309
1334
|
(!role.data.activity || queryIds.has(role.data.activity))
|
|
1310
1335
|
? role.data
|
|
1311
1336
|
: undefined;
|
|
1337
|
+
const statusRole = CapabilityAppStatusManifestSchema.safeParse(sentAppStatus);
|
|
1338
|
+
const appStatus =
|
|
1339
|
+
statusRole.success &&
|
|
1340
|
+
queryIds.has(statusRole.data.summary) &&
|
|
1341
|
+
queryIds.has(statusRole.data.detail) &&
|
|
1342
|
+
readableActions.some((action) => action.localId === statusRole.data.forget)
|
|
1343
|
+
? statusRole.data
|
|
1344
|
+
: undefined;
|
|
1312
1345
|
const provider = CapabilityFileProviderManifestSchema.safeParse(sentProvider);
|
|
1313
1346
|
const calendar = CapabilityCalendarSourceManifestSchema.safeParse(sentCalendarSource);
|
|
1314
1347
|
const pageCounts = new Map<string, number>();
|
|
@@ -1328,6 +1361,7 @@ const readableManifest = (value: unknown, personCatalog = false): unknown => {
|
|
|
1328
1361
|
...rest,
|
|
1329
1362
|
...(sentModels !== undefined ? { resourceTypes } : {}),
|
|
1330
1363
|
...(discussions ? { discussions } : {}),
|
|
1364
|
+
...(appStatus ? { appStatus } : {}),
|
|
1331
1365
|
...(sentPages !== undefined ? { resourcePages } : {}),
|
|
1332
1366
|
...(provider.success ? { fileProvider: provider.data } : {}),
|
|
1333
1367
|
...(calendar.success ? { calendarSource: calendar.data } : {}),
|
|
@@ -1371,6 +1405,7 @@ export const CapabilityManifestSchema = z.preprocess(
|
|
|
1371
1405
|
fileProvider: CapabilityFileProviderManifestSchema.optional(),
|
|
1372
1406
|
calendarSource: CapabilityCalendarSourceManifestSchema.optional(),
|
|
1373
1407
|
discussions: CapabilityDiscussionsManifestSchema.optional(),
|
|
1408
|
+
appStatus: CapabilityAppStatusManifestSchema.optional(),
|
|
1374
1409
|
resourceTypes: z.array(CapabilityResourceTypeModelSchema).max(MAX_MANIFEST_ENTRIES).optional(),
|
|
1375
1410
|
policies: z.record(CapabilityLocalIdSchema, CapabilityActionPolicySchema).optional(),
|
|
1376
1411
|
events: z.array(CapabilityEventManifestSchema).max(MAX_MANIFEST_ENTRIES).optional(),
|
package/src/contracts/index.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { PageParams, Paginated, ServiceError } from "@k2b/stdlib";
|
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { type RequestActor, ServiceAccountSchema, UserSchema } from "./shared";
|
|
4
4
|
|
|
5
|
-
export const PlatformPermissionSchema = z.enum(["mail:send", "mail:read", "resources:readers"]);
|
|
5
|
+
export const PlatformPermissionSchema = z.enum(["mail:send", "mail:read", "resources:readers", "geo:query"]);
|
|
6
6
|
export type PlatformPermission = z.infer<typeof PlatformPermissionSchema>;
|
|
7
7
|
export const MailRetentionSchema = z.object({ contentDays: z.int().min(1).max(36500), recordDays: z.int().min(1).max(36500) }).strict();
|
|
8
8
|
export type MailRetention = z.infer<typeof MailRetentionSchema> & {
|
|
@@ -83,6 +83,8 @@ export type AppRuntimeMetadata = {
|
|
|
83
83
|
};
|
|
84
84
|
|
|
85
85
|
export type AppRegistryEntry = {
|
|
86
|
+
/** Opt-in public site, served only through the app public router. */
|
|
87
|
+
public?: true;
|
|
86
88
|
access?: AppAccessRule;
|
|
87
89
|
platformPermissions?: readonly PlatformPermission[];
|
|
88
90
|
id: string;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { Topic, TopicConfig } from "@k2b/sync";
|
|
2
|
-
import { sql } from "bun";
|
|
3
2
|
import { assertAppEventSize } from "../_internal/app-event-schemas";
|
|
4
3
|
import { lazySync } from "../_internal/process-sync";
|
|
5
4
|
import { type AppEventEnvelope, AppEventEnvelopeSchema } from "../contracts/app-events";
|
|
5
|
+
import { sql } from "../runtime/clients";
|
|
6
6
|
import { logger } from "../services/logging";
|
|
7
7
|
import { createPgOutbox } from "../services/outbox";
|
|
8
8
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { Topic, TopicConfig } from "@k2b/sync";
|
|
2
|
-
import {
|
|
2
|
+
import type { SQL } from "bun";
|
|
3
3
|
import type { z } from "zod";
|
|
4
4
|
import { lazySync } from "../_internal/process-sync";
|
|
5
|
+
import { sql } from "../runtime/clients";
|
|
5
6
|
import { logger } from "../services/logging";
|
|
6
7
|
import { createPgOutbox } from "../services/outbox";
|
|
7
8
|
import type { LiveEnvelope } from "./live-engine";
|
package/src/index.ts
CHANGED
|
@@ -64,6 +64,7 @@ export { createRedis, createSql, redis, type SqlPoolOptions, sql } from "./runti
|
|
|
64
64
|
export {
|
|
65
65
|
type ConnectionSource,
|
|
66
66
|
connections,
|
|
67
|
+
type PlatformBootstrapMetadata,
|
|
67
68
|
type PlatformConnectionSources,
|
|
68
69
|
type PlatformConnections,
|
|
69
70
|
type PlatformConnectionValues,
|