@objectstack/runtime 5.2.0 → 6.0.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/dist/index.cjs +560 -33620
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +120 -114
- package/dist/index.d.ts +120 -114
- package/dist/index.js +556 -33643
- package/dist/index.js.map +1 -1
- package/package.json +18 -17
package/dist/index.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { SeedLoaderRequest, SeedLoaderResult, ObjectDependencyGraph, Dataset, Se
|
|
|
10
10
|
import { MetricsRegistry, ErrorReporter } from '@objectstack/observability';
|
|
11
11
|
export { CapturedError, ErrorReporter, InMemoryErrorReporter, InMemoryMetricsRegistry, MetricSample, MetricsRegistry, NoopErrorReporter, NoopMetricsRegistry, OBSERVABILITY_ERRORS_SERVICE, OBSERVABILITY_METRICS_SERVICE, RUNTIME_METRICS } from '@objectstack/observability';
|
|
12
12
|
import { MiddlewareConfig, MiddlewareType } from '@objectstack/spec/system';
|
|
13
|
-
import {
|
|
13
|
+
import { EnvironmentArtifact } from '@objectstack/spec/cloud';
|
|
14
14
|
export { RestApiPluginConfig, RestServer, RouteEntry, RouteGroupBuilder, RouteManager, createRestApiPlugin } from '@objectstack/rest';
|
|
15
15
|
|
|
16
16
|
interface RuntimeConfig {
|
|
@@ -78,10 +78,11 @@ declare const StandaloneStackConfigSchema: z.ZodObject<{
|
|
|
78
78
|
memory: "memory";
|
|
79
79
|
postgres: "postgres";
|
|
80
80
|
sqlite: "sqlite";
|
|
81
|
+
"sqlite-wasm": "sqlite-wasm";
|
|
81
82
|
turso: "turso";
|
|
82
83
|
mongodb: "mongodb";
|
|
83
84
|
}>>;
|
|
84
|
-
|
|
85
|
+
environmentId: z.ZodOptional<z.ZodString>;
|
|
85
86
|
artifactPath: z.ZodOptional<z.ZodString>;
|
|
86
87
|
}, z.core.$strip>;
|
|
87
88
|
type StandaloneStackConfig = z.input<typeof StandaloneStackConfigSchema>;
|
|
@@ -185,7 +186,7 @@ declare class DriverPlugin implements Plugin {
|
|
|
185
186
|
* usages may omit this — no catalog hooks are emitted in that case.
|
|
186
187
|
*/
|
|
187
188
|
interface AppPluginProjectContext {
|
|
188
|
-
|
|
189
|
+
environmentId: string;
|
|
189
190
|
organizationId: string;
|
|
190
191
|
projectName?: string;
|
|
191
192
|
/** When the app comes from a package installation, the source package id. */
|
|
@@ -587,16 +588,16 @@ interface DispatcherPluginConfig {
|
|
|
587
588
|
* routes stay in lockstep with /data and /meta.
|
|
588
589
|
*
|
|
589
590
|
* When `enableProjectScoping` is true and `projectResolution` is:
|
|
590
|
-
* - `required` — only `/
|
|
591
|
+
* - `required` — only `/environments/:environmentId/...` variants are registered.
|
|
591
592
|
* - `optional` / `auto` — both unscoped and scoped variants are registered
|
|
592
|
-
* (the scoped handler forwards `req.params.
|
|
593
|
+
* (the scoped handler forwards `req.params.environmentId` into context).
|
|
593
594
|
*/
|
|
594
595
|
scoping?: {
|
|
595
596
|
enableProjectScoping?: boolean;
|
|
596
597
|
projectResolution?: 'required' | 'optional' | 'auto';
|
|
597
598
|
};
|
|
598
599
|
/**
|
|
599
|
-
* Enforce per-project membership (`
|
|
600
|
+
* Enforce per-project membership (`sys_environment_member`) on scoped
|
|
600
601
|
* data-plane routes. Returns 403 for non-members unless they are
|
|
601
602
|
* staff (platform org) or the project is the well-known system
|
|
602
603
|
* project.
|
|
@@ -671,10 +672,10 @@ declare function createDispatcherPlugin(config?: DispatcherPluginConfig): Plugin
|
|
|
671
672
|
|
|
672
673
|
/**
|
|
673
674
|
* The well-known UUID for the built-in system project.
|
|
674
|
-
* Kept in lockstep with `ProjectProvisioningService.
|
|
675
|
+
* Kept in lockstep with `ProjectProvisioningService.provisionSystemEnvironment`.
|
|
675
676
|
*/
|
|
676
|
-
declare const
|
|
677
|
-
interface
|
|
677
|
+
declare const SYSTEM_ENVIRONMENT_ID = "00000000-0000-0000-0000-000000000001";
|
|
678
|
+
interface SystemEnvironmentPluginConfig {
|
|
678
679
|
/**
|
|
679
680
|
* Service name that resolves to a `ProjectProvisioningService`-shaped
|
|
680
681
|
* object. Defaults to `tenant.provisioning` (convention used by
|
|
@@ -692,8 +693,8 @@ interface SystemProjectPluginConfig {
|
|
|
692
693
|
* System Project Bootstrap Plugin
|
|
693
694
|
*
|
|
694
695
|
* Ensures the built-in system project (well-known UUID
|
|
695
|
-
* {@link
|
|
696
|
-
* runtime starts. Calls are idempotent — `
|
|
696
|
+
* {@link SYSTEM_ENVIRONMENT_ID}) exists on the control plane the first time the
|
|
697
|
+
* runtime starts. Calls are idempotent — `provisionSystemEnvironment()` returns
|
|
697
698
|
* the existing row when the project has already been created.
|
|
698
699
|
*
|
|
699
700
|
* Register AFTER the tenant service is available so the provisioning service
|
|
@@ -702,10 +703,10 @@ interface SystemProjectPluginConfig {
|
|
|
702
703
|
* @example
|
|
703
704
|
* ```ts
|
|
704
705
|
* kernel.use(tenantPlugin);
|
|
705
|
-
* kernel.use(
|
|
706
|
+
* kernel.use(createSystemEnvironmentPlugin());
|
|
706
707
|
* ```
|
|
707
708
|
*/
|
|
708
|
-
declare function
|
|
709
|
+
declare function createSystemEnvironmentPlugin(config?: SystemEnvironmentPluginConfig): Plugin;
|
|
709
710
|
|
|
710
711
|
/**
|
|
711
712
|
* HttpServer - Unified HTTP Server Abstraction
|
|
@@ -794,16 +795,16 @@ declare class HttpServer implements IHttpServer {
|
|
|
794
795
|
/**
|
|
795
796
|
* Factory contract for instantiating a per-project {@link ObjectKernel}.
|
|
796
797
|
*
|
|
797
|
-
* Given a `
|
|
798
|
-
* 1. Read control-plane metadata (`
|
|
798
|
+
* Given a `environmentId`, the factory is expected to:
|
|
799
|
+
* 1. Read control-plane metadata (`sys_environment` + credentials + subscribed packages).
|
|
799
800
|
* 2. Construct a fresh `ObjectKernel` with project-scoped driver + plugins + Apps.
|
|
800
801
|
* 3. Return a **bootstrapped** kernel ready to serve requests.
|
|
801
802
|
*/
|
|
802
|
-
interface
|
|
803
|
-
create(
|
|
803
|
+
interface EnvironmentKernelFactory {
|
|
804
|
+
create(environmentId: string): Promise<ObjectKernel>;
|
|
804
805
|
}
|
|
805
806
|
interface KernelManagerConfig {
|
|
806
|
-
factory:
|
|
807
|
+
factory: EnvironmentKernelFactory;
|
|
807
808
|
/** Maximum number of kernels to keep resident. Defaults to 32. */
|
|
808
809
|
maxSize?: number;
|
|
809
810
|
/**
|
|
@@ -826,7 +827,7 @@ interface KernelManagerConfig {
|
|
|
826
827
|
* Implements ADR-0003 multi-kernel scheduling: each project gets an
|
|
827
828
|
* isolated kernel (App/plugin/metadata namespaces) that is lazily built
|
|
828
829
|
* on first request and evicted under memory / idle pressure. Concurrent
|
|
829
|
-
* `getOrCreate()` calls for the same
|
|
830
|
+
* `getOrCreate()` calls for the same environmentId share a single in-flight
|
|
830
831
|
* factory invocation (singleflight).
|
|
831
832
|
*/
|
|
832
833
|
declare class KernelManager {
|
|
@@ -837,36 +838,36 @@ declare class KernelManager {
|
|
|
837
838
|
private readonly cache;
|
|
838
839
|
private readonly pending;
|
|
839
840
|
constructor(config: KernelManagerConfig);
|
|
840
|
-
/** Returns the currently cached
|
|
841
|
+
/** Returns the currently cached environmentIds (ordered by insertion). */
|
|
841
842
|
keys(): string[];
|
|
842
843
|
/** Cache size for diagnostics. */
|
|
843
844
|
get size(): number;
|
|
844
845
|
/**
|
|
845
|
-
* Resolve or construct the kernel for `
|
|
846
|
+
* Resolve or construct the kernel for `environmentId`.
|
|
846
847
|
*
|
|
847
848
|
* - Cache hit (fresh): bumps `lastAccess` and returns immediately.
|
|
848
849
|
* - Cache hit (TTL expired): evicts then falls through to factory.
|
|
849
850
|
* - Cache miss: dedupes concurrent callers through `pending`.
|
|
850
851
|
*/
|
|
851
|
-
getOrCreate(
|
|
852
|
+
getOrCreate(environmentId: string): Promise<ObjectKernel>;
|
|
852
853
|
/**
|
|
853
|
-
* Evict the kernel for `
|
|
854
|
+
* Evict the kernel for `environmentId` and invoke `kernel.shutdown()`.
|
|
854
855
|
* No-op when the entry is absent.
|
|
855
856
|
*/
|
|
856
|
-
evict(
|
|
857
|
+
evict(environmentId: string): Promise<void>;
|
|
857
858
|
/** Evict all resident kernels. Used on runtime shutdown. */
|
|
858
859
|
evictAll(): Promise<void>;
|
|
859
860
|
private enforceMaxSize;
|
|
860
861
|
}
|
|
861
862
|
|
|
862
|
-
/** Minimal local interface — full
|
|
863
|
-
interface
|
|
864
|
-
touch(
|
|
863
|
+
/** Minimal local interface — full EnvironmentScopeManager was removed in Phase R. */
|
|
864
|
+
interface EnvironmentScopeManager {
|
|
865
|
+
touch(environmentId: string): void;
|
|
865
866
|
}
|
|
866
867
|
interface HttpProtocolContext {
|
|
867
868
|
request: any;
|
|
868
869
|
response?: any;
|
|
869
|
-
|
|
870
|
+
environmentId?: string;
|
|
870
871
|
dataDriver?: any;
|
|
871
872
|
/**
|
|
872
873
|
* Identity envelope resolved by `resolveExecutionContext` and threaded
|
|
@@ -893,17 +894,17 @@ interface HttpDispatcherOptions {
|
|
|
893
894
|
enforceProjectMembership?: boolean;
|
|
894
895
|
/**
|
|
895
896
|
* Optional {@link KernelManager}. When present, the dispatcher resolves
|
|
896
|
-
* `context.
|
|
897
|
-
* project's dedicated kernel via `kernelManager.getOrCreate(
|
|
898
|
-
* Requests that fail to resolve a
|
|
897
|
+
* `context.environmentId` first and then routes the request against the
|
|
898
|
+
* project's dedicated kernel via `kernelManager.getOrCreate(environmentId)`.
|
|
899
|
+
* Requests that fail to resolve a environmentId fall through to the
|
|
899
900
|
* constructor-supplied kernel (self-hosted / legacy behavior).
|
|
900
901
|
*/
|
|
901
902
|
kernelManager?: KernelManager;
|
|
902
903
|
/**
|
|
903
|
-
* Optional {@link
|
|
904
|
+
* Optional {@link EnvironmentScopeManager}. When present, `touch(environmentId)` is
|
|
904
905
|
* called on every scoped request so idle projects are evicted after TTL.
|
|
905
906
|
*/
|
|
906
|
-
scopeManager?:
|
|
907
|
+
scopeManager?: EnvironmentScopeManager;
|
|
907
908
|
}
|
|
908
909
|
/**
|
|
909
910
|
* @deprecated Use `createDispatcherPlugin()` from `@objectstack/runtime` instead.
|
|
@@ -922,22 +923,22 @@ declare class HttpDispatcher {
|
|
|
922
923
|
private scopeManager?;
|
|
923
924
|
/**
|
|
924
925
|
* When `true`, scoped data-plane routes enforce a
|
|
925
|
-
* `
|
|
926
|
-
* Defaults to `true` when a
|
|
926
|
+
* `sys_environment_member` lookup and return 403 for non-members.
|
|
927
|
+
* Defaults to `true` when a environmentId is resolvable — legacy callers
|
|
927
928
|
* can opt out via the third constructor argument (see
|
|
928
929
|
* `DispatcherConfig.enforceProjectMembership`).
|
|
929
930
|
*/
|
|
930
931
|
private enforceMembership;
|
|
931
932
|
/**
|
|
932
933
|
* In-memory cache of positive membership checks, keyed by
|
|
933
|
-
* `${
|
|
934
|
+
* `${environmentId}:${userId}`. Entries expire 60 seconds after insertion
|
|
934
935
|
* — a short TTL is acceptable because a user whose access was just
|
|
935
936
|
* revoked sees stale access for at most one minute.
|
|
936
937
|
*/
|
|
937
938
|
private membershipCache;
|
|
938
939
|
private static readonly MEMBERSHIP_CACHE_TTL_MS;
|
|
939
940
|
/** Well-known system project id — bypassed for any authenticated user. */
|
|
940
|
-
private static readonly
|
|
941
|
+
private static readonly SYSTEM_ENVIRONMENT_ID;
|
|
941
942
|
/** Well-known platform org id — members bypass project membership. */
|
|
942
943
|
private static readonly PLATFORM_ORG_ID;
|
|
943
944
|
constructor(kernel: ObjectKernel, envRegistry?: any, options?: HttpDispatcherOptions);
|
|
@@ -958,22 +959,27 @@ declare class HttpDispatcher {
|
|
|
958
959
|
private callData;
|
|
959
960
|
/**
|
|
960
961
|
* Parse a project UUID out of a scoped URL path such as
|
|
961
|
-
* `/api/v1/
|
|
962
|
+
* `/api/v1/environments/abc-123/data/task` or `/projects/abc-123/meta`.
|
|
962
963
|
* Returns `undefined` when the path does not match the scoped pattern.
|
|
963
964
|
*/
|
|
964
|
-
|
|
965
|
+
/**
|
|
966
|
+
* Parse an environment UUID out of a scoped URL path such as
|
|
967
|
+
* `/api/v1/environments/abc-123/data/task` or `/environments/abc-123/meta`.
|
|
968
|
+
* Returns `undefined` when the path does not match the scoped pattern.
|
|
969
|
+
*/
|
|
970
|
+
private extractEnvironmentIdFromPath;
|
|
965
971
|
/**
|
|
966
972
|
* Resolve environment context for incoming request.
|
|
967
973
|
*
|
|
968
974
|
* Precedence:
|
|
969
|
-
* 0. URL path matches `/
|
|
975
|
+
* 0. URL path matches `/environments/:environmentId/...` OR request.params.environmentId set by router
|
|
970
976
|
* → envRegistry.resolveById(id)
|
|
971
977
|
* 1. request.headers.host → envRegistry.resolveByHostname(host)
|
|
972
|
-
* 2. request.headers['x-
|
|
978
|
+
* 2. request.headers['x-environment-id'] → envRegistry.resolveById(id)
|
|
973
979
|
* 3. session.activeEnvironmentId → envRegistry.resolveById(id)
|
|
974
980
|
* 4. session.activeOrganizationId → find default project → envRegistry.resolveById(id)
|
|
975
|
-
* 5. single-
|
|
976
|
-
* → envRegistry.resolveById(defaultProject.
|
|
981
|
+
* 5. single-environment default (registered by `createSingleEnvironmentPlugin`)
|
|
982
|
+
* → envRegistry.resolveById(defaultProject.environmentId). Lets bare
|
|
977
983
|
* `/api/v1/data/...` URLs resolve to the lone project in
|
|
978
984
|
* `cloudUrl: 'local'` deployments.
|
|
979
985
|
*
|
|
@@ -983,13 +989,13 @@ declare class HttpDispatcher {
|
|
|
983
989
|
private resolveEnvironmentContext;
|
|
984
990
|
/**
|
|
985
991
|
* Check whether the authenticated user is a member of
|
|
986
|
-
* `context.
|
|
992
|
+
* `context.environmentId`. Runs after {@link resolveEnvironmentContext}
|
|
987
993
|
* and is a no-op when:
|
|
988
994
|
*
|
|
989
995
|
* - Membership enforcement is disabled via the constructor.
|
|
990
996
|
* - The route is control-plane (`/auth/*`, `/cloud/*`, `/health`,
|
|
991
997
|
* `/discovery`) — already skipped upstream.
|
|
992
|
-
* - No `
|
|
998
|
+
* - No `environmentId` was resolved (e.g. unscoped legacy routes).
|
|
993
999
|
* - The project is the well-known system project (bypassed so any
|
|
994
1000
|
* authenticated user can read platform metadata).
|
|
995
1001
|
* - The user's active organization is the platform org (staff).
|
|
@@ -1323,23 +1329,23 @@ declare class HttpDispatcher {
|
|
|
1323
1329
|
* Cloud / Environment Control-Plane routes.
|
|
1324
1330
|
*
|
|
1325
1331
|
* - GET /cloud/drivers → list registered ObjectQL drivers (for env provisioning)
|
|
1326
|
-
* - GET /cloud/
|
|
1327
|
-
* - POST /cloud/
|
|
1328
|
-
* - GET /cloud/
|
|
1329
|
-
* - PATCH /cloud/
|
|
1330
|
-
* - DELETE /cloud/
|
|
1332
|
+
* - GET /cloud/environments → list
|
|
1333
|
+
* - POST /cloud/environments → provision (driver: memory | turso | <any registered driver>)
|
|
1334
|
+
* - GET /cloud/environments/:id → detail (+ db, credential, membership)
|
|
1335
|
+
* - PATCH /cloud/environments/:id → update displayName / plan / status / isDefault / metadata
|
|
1336
|
+
* - DELETE /cloud/environments/:id[?force=1] → cascade-delete the project (cred/member/package install rows + physical DB)
|
|
1331
1337
|
* - DELETE /cloud/organizations/:id → cascade-delete every project (and its DB) for the org, then drop the org
|
|
1332
|
-
* - POST /cloud/
|
|
1333
|
-
* - POST /cloud/
|
|
1334
|
-
* - POST /cloud/
|
|
1335
|
-
* - GET /cloud/
|
|
1336
|
-
* - GET /cloud/
|
|
1337
|
-
* - POST /cloud/
|
|
1338
|
-
* - GET /cloud/
|
|
1339
|
-
* - PATCH /cloud/
|
|
1340
|
-
* - PATCH /cloud/
|
|
1341
|
-
* - DELETE /cloud/
|
|
1342
|
-
* - POST /cloud/
|
|
1338
|
+
* - POST /cloud/environments/:id/retry → re-run provisioning for a failed environment
|
|
1339
|
+
* - POST /cloud/environments/:id/activate → mark as active for session (stub)
|
|
1340
|
+
* - POST /cloud/environments/:id/credentials/rotate → rotate credential
|
|
1341
|
+
* - GET /cloud/environments/:id/members → list members
|
|
1342
|
+
* - GET /cloud/environments/:id/packages → list installed packages
|
|
1343
|
+
* - POST /cloud/environments/:id/packages → install package into env
|
|
1344
|
+
* - GET /cloud/environments/:id/packages/:pkgId → get installation detail
|
|
1345
|
+
* - PATCH /cloud/environments/:id/packages/:pkgId/enable → enable package
|
|
1346
|
+
* - PATCH /cloud/environments/:id/packages/:pkgId/disable → disable package
|
|
1347
|
+
* - DELETE /cloud/environments/:id/packages/:pkgId → uninstall (scope=platform forbidden)
|
|
1348
|
+
* - POST /cloud/environments/:id/packages/:pkgId/upgrade → upgrade to newer version
|
|
1343
1349
|
*
|
|
1344
1350
|
* Driver binding
|
|
1345
1351
|
* --------------
|
|
@@ -1351,11 +1357,11 @@ declare class HttpDispatcher {
|
|
|
1351
1357
|
* If `driver` is omitted, the dispatcher auto-selects the first available
|
|
1352
1358
|
* in preference order: turso → memory → any other registered driver.
|
|
1353
1359
|
*
|
|
1354
|
-
* Backed by ObjectQL
|
|
1355
|
-
*
|
|
1360
|
+
* Backed by ObjectQL sys_environment / sys_environment_credential /
|
|
1361
|
+
* sys_environment_member tables (registered by
|
|
1356
1362
|
* `@objectstack/service-tenant`'s `createTenantPlugin`).
|
|
1357
1363
|
* Physical database addressing (database_url, database_driver, etc.)
|
|
1358
|
-
* is stored directly on the
|
|
1364
|
+
* is stored directly on the sys_environment row.
|
|
1359
1365
|
*/
|
|
1360
1366
|
/**
|
|
1361
1367
|
* Resolve the calling user id from the request session, if any.
|
|
@@ -1367,7 +1373,7 @@ declare class HttpDispatcher {
|
|
|
1367
1373
|
/**
|
|
1368
1374
|
* Cascade-delete a project: cred / member / package_installation rows,
|
|
1369
1375
|
* then the physical database via the provisioning adapter, then the
|
|
1370
|
-
* `
|
|
1376
|
+
* `sys_environment` row itself. Used by both `DELETE /cloud/environments/:id`
|
|
1371
1377
|
* and the org-cascade in `DELETE /cloud/organizations/:id`.
|
|
1372
1378
|
*
|
|
1373
1379
|
* Idempotent and best-effort: missing rows / unreachable adapters
|
|
@@ -1590,10 +1596,10 @@ declare function mergeRuntimeModule(bundle: any, artifactAbsPath: string, tag?:
|
|
|
1590
1596
|
* The control plane is expected to expose two endpoints:
|
|
1591
1597
|
*
|
|
1592
1598
|
* GET {controlPlaneUrl}/api/v1/cloud/resolve-hostname?host={hostname}
|
|
1593
|
-
* → {
|
|
1599
|
+
* → { environmentId: string, organizationId?: string, runtime?: EnvironmentRuntimeConfig }
|
|
1594
1600
|
*
|
|
1595
|
-
* GET {controlPlaneUrl}/api/v1/cloud/
|
|
1596
|
-
* →
|
|
1601
|
+
* GET {controlPlaneUrl}/api/v1/cloud/environments/:environmentId/artifact
|
|
1602
|
+
* → EnvironmentArtifactResponse (EnvironmentArtifact + optional `runtime` block)
|
|
1597
1603
|
*
|
|
1598
1604
|
* Both endpoints accept an optional `Authorization: Bearer <apiKey>`.
|
|
1599
1605
|
*
|
|
@@ -1608,7 +1614,7 @@ declare function mergeRuntimeModule(bundle: any, artifactAbsPath: string, tag?:
|
|
|
1608
1614
|
* connect to (this is *not* part of the developer-authored compiled
|
|
1609
1615
|
* artifact — the control plane mints it when serving the API).
|
|
1610
1616
|
*/
|
|
1611
|
-
interface
|
|
1617
|
+
interface EnvironmentRuntimeConfig {
|
|
1612
1618
|
organizationId?: string;
|
|
1613
1619
|
hostname?: string;
|
|
1614
1620
|
/** Driver type — e.g. `sqlite`, `postgres`, `turso`, `memory`. */
|
|
@@ -1629,18 +1635,18 @@ interface ProjectRuntimeConfig {
|
|
|
1629
1635
|
* Hostname resolution response.
|
|
1630
1636
|
*/
|
|
1631
1637
|
interface ResolvedHostname {
|
|
1632
|
-
|
|
1638
|
+
environmentId: string;
|
|
1633
1639
|
organizationId?: string;
|
|
1634
1640
|
/** Optional runtime config — when present, callers can skip the artifact fetch's runtime block. */
|
|
1635
|
-
runtime?:
|
|
1641
|
+
runtime?: EnvironmentRuntimeConfig;
|
|
1636
1642
|
}
|
|
1637
1643
|
/**
|
|
1638
|
-
* Artifact response wrapping the spec's `
|
|
1644
|
+
* Artifact response wrapping the spec's `EnvironmentArtifact` envelope plus
|
|
1639
1645
|
* an optional `runtime` block carrying the project's database
|
|
1640
1646
|
* connection details.
|
|
1641
1647
|
*/
|
|
1642
|
-
interface
|
|
1643
|
-
runtime?:
|
|
1648
|
+
interface EnvironmentArtifactResponse extends EnvironmentArtifact {
|
|
1649
|
+
runtime?: EnvironmentRuntimeConfig;
|
|
1644
1650
|
}
|
|
1645
1651
|
interface ArtifactApiClientConfig {
|
|
1646
1652
|
/** Control-plane base URL (no trailing slash). */
|
|
@@ -1686,32 +1692,32 @@ declare class ArtifactApiClient {
|
|
|
1686
1692
|
* independently (the cache key includes the commit id) so the preview
|
|
1687
1693
|
* runtime can hold multiple versions in memory simultaneously.
|
|
1688
1694
|
*/
|
|
1689
|
-
fetchArtifact(
|
|
1695
|
+
fetchArtifact(environmentId: string, opts?: {
|
|
1690
1696
|
commit?: string;
|
|
1691
|
-
}): Promise<
|
|
1697
|
+
}): Promise<EnvironmentArtifactResponse | null>;
|
|
1692
1698
|
/**
|
|
1693
1699
|
* Resolve an 8-hex project short id (first 8 hex chars of the UUID,
|
|
1694
|
-
* dashes stripped) to the full
|
|
1700
|
+
* dashes stripped) to the full environmentId. Used by the preview
|
|
1695
1701
|
* runtime, which encodes project ids in subdomains.
|
|
1696
1702
|
*
|
|
1697
1703
|
* Returns `null` on 404 or ambiguity (the control plane returns 409
|
|
1698
1704
|
* if the prefix matches more than one project).
|
|
1699
1705
|
*/
|
|
1700
1706
|
lookupProjectByShortId(shortId: string): Promise<{
|
|
1701
|
-
|
|
1707
|
+
environmentId: string;
|
|
1702
1708
|
organizationId?: string;
|
|
1703
1709
|
} | null>;
|
|
1704
1710
|
/**
|
|
1705
1711
|
* Fetch the head commit of a branch. Returns the commit id (and the
|
|
1706
1712
|
* matching revision row's `published_at` for cache-validity checks).
|
|
1707
|
-
* Reuses the existing `GET /cloud/
|
|
1713
|
+
* Reuses the existing `GET /cloud/environments/:id/branches` endpoint.
|
|
1708
1714
|
*/
|
|
1709
|
-
fetchBranchHead(
|
|
1715
|
+
fetchBranchHead(environmentId: string, branchName: string): Promise<{
|
|
1710
1716
|
commitId: string;
|
|
1711
1717
|
publishedAt?: string | null;
|
|
1712
1718
|
} | null>;
|
|
1713
1719
|
/** Drop cached entries for a project (and any matching hostname). */
|
|
1714
|
-
invalidate(
|
|
1720
|
+
invalidate(environmentId: string): void;
|
|
1715
1721
|
/** Drop everything. Used on shutdown / hot-reload. */
|
|
1716
1722
|
clear(): void;
|
|
1717
1723
|
private request;
|
|
@@ -1727,9 +1733,9 @@ interface FileArtifactApiClientConfig {
|
|
|
1727
1733
|
artifactPath?: string;
|
|
1728
1734
|
/**
|
|
1729
1735
|
* Project id every hostname maps to. Defaults to
|
|
1730
|
-
* `process.env.
|
|
1736
|
+
* `process.env.OS_ENVIRONMENT_ID` or `'proj_local'`.
|
|
1731
1737
|
*/
|
|
1732
|
-
|
|
1738
|
+
environmentId?: string;
|
|
1733
1739
|
/**
|
|
1734
1740
|
* Organization id surfaced alongside the project. Defaults to
|
|
1735
1741
|
* `process.env.OS_ORGANIZATION_ID` or `'org_local'`.
|
|
@@ -1739,9 +1745,9 @@ interface FileArtifactApiClientConfig {
|
|
|
1739
1745
|
* Override runtime config. When unset, the client tries to derive
|
|
1740
1746
|
* one from the artifact's `datasources` array; if that fails it
|
|
1741
1747
|
* falls back to a local-file SQLite DB at
|
|
1742
|
-
* `<cwd>/.objectstack/data/<
|
|
1748
|
+
* `<cwd>/.objectstack/data/<environmentId>.db`.
|
|
1743
1749
|
*/
|
|
1744
|
-
runtime?:
|
|
1750
|
+
runtime?: EnvironmentRuntimeConfig;
|
|
1745
1751
|
/**
|
|
1746
1752
|
* Reload the artifact on every fetch instead of caching the first
|
|
1747
1753
|
* read. Useful when iterating on a project's metadata without
|
|
@@ -1757,7 +1763,7 @@ interface FileArtifactApiClientConfig {
|
|
|
1757
1763
|
}
|
|
1758
1764
|
declare class FileArtifactApiClient {
|
|
1759
1765
|
private readonly artifactPath;
|
|
1760
|
-
private readonly
|
|
1766
|
+
private readonly environmentId;
|
|
1761
1767
|
private readonly organizationId;
|
|
1762
1768
|
private readonly overrideRuntime?;
|
|
1763
1769
|
private readonly watch;
|
|
@@ -1765,18 +1771,18 @@ declare class FileArtifactApiClient {
|
|
|
1765
1771
|
private cached?;
|
|
1766
1772
|
constructor(config?: FileArtifactApiClientConfig);
|
|
1767
1773
|
resolveHostname(_host: string): Promise<ResolvedHostname | null>;
|
|
1768
|
-
fetchArtifact(
|
|
1774
|
+
fetchArtifact(_environmentId: string, _opts?: {
|
|
1769
1775
|
commit?: string;
|
|
1770
|
-
}): Promise<
|
|
1776
|
+
}): Promise<EnvironmentArtifactResponse | null>;
|
|
1771
1777
|
lookupProjectByShortId(_shortId: string): Promise<{
|
|
1772
|
-
|
|
1778
|
+
environmentId: string;
|
|
1773
1779
|
organizationId?: string;
|
|
1774
1780
|
} | null>;
|
|
1775
|
-
fetchBranchHead(
|
|
1781
|
+
fetchBranchHead(_environmentId: string, _branchName: string): Promise<{
|
|
1776
1782
|
commitId: string;
|
|
1777
1783
|
publishedAt?: string | null;
|
|
1778
1784
|
} | null>;
|
|
1779
|
-
invalidate(
|
|
1785
|
+
invalidate(_environmentId: string): void;
|
|
1780
1786
|
clear(): void;
|
|
1781
1787
|
private loadArtifact;
|
|
1782
1788
|
private readRuntimeFromArtifact;
|
|
@@ -1996,22 +2002,22 @@ type IDataDriver$1 = Contracts.IDataDriver;
|
|
|
1996
2002
|
interface EnvironmentDriverRegistry {
|
|
1997
2003
|
/** Resolve a project by hostname. Returns `null` when unknown. */
|
|
1998
2004
|
resolveByHostname(host: string): Promise<{
|
|
1999
|
-
|
|
2005
|
+
environmentId: string;
|
|
2000
2006
|
driver: IDataDriver$1;
|
|
2001
2007
|
} | null>;
|
|
2002
2008
|
/** Resolve a project's driver by ID. Returns `null` when unknown. */
|
|
2003
|
-
resolveById(
|
|
2009
|
+
resolveById(environmentId: string): Promise<IDataDriver$1 | null>;
|
|
2004
2010
|
/**
|
|
2005
2011
|
* Look up the cached project row + driver by ID without triggering a
|
|
2006
2012
|
* remote/file fetch. Returns the full cached entry when fresh.
|
|
2007
2013
|
*/
|
|
2008
|
-
peekById(
|
|
2009
|
-
|
|
2014
|
+
peekById(environmentId: string): {
|
|
2015
|
+
environmentId: string;
|
|
2010
2016
|
driver: IDataDriver$1;
|
|
2011
2017
|
project: any;
|
|
2012
2018
|
} | null;
|
|
2013
2019
|
/** Drop cached entries for the given project. */
|
|
2014
|
-
invalidate(
|
|
2020
|
+
invalidate(environmentId: string): void;
|
|
2015
2021
|
}
|
|
2016
2022
|
|
|
2017
2023
|
/**
|
|
@@ -2020,11 +2026,11 @@ interface EnvironmentDriverRegistry {
|
|
|
2020
2026
|
*
|
|
2021
2027
|
* Mirrors {@link DefaultEnvironmentDriverRegistry} from `environment-registry.ts`
|
|
2022
2028
|
* but does **not** read from a local control-plane database. Hostname →
|
|
2023
|
-
*
|
|
2029
|
+
* environmentId resolution and per-project runtime config (database URL /
|
|
2024
2030
|
* driver) come from the control plane API.
|
|
2025
2031
|
*
|
|
2026
2032
|
* The cached `project` payload exposed by `peekById()` is shaped to look
|
|
2027
|
-
* like a `
|
|
2033
|
+
* like a `sys_environment` row so callers downstream (notably
|
|
2028
2034
|
* `ArtifactKernelFactory`) can read `id`, `organization_id`,
|
|
2029
2035
|
* `database_url` and `database_driver` without branching.
|
|
2030
2036
|
*/
|
|
@@ -2050,16 +2056,16 @@ declare class ArtifactEnvironmentRegistry implements EnvironmentDriverRegistry {
|
|
|
2050
2056
|
private readonly pending;
|
|
2051
2057
|
constructor(config: ArtifactEnvironmentRegistryConfig);
|
|
2052
2058
|
resolveByHostname(host: string): Promise<{
|
|
2053
|
-
|
|
2059
|
+
environmentId: string;
|
|
2054
2060
|
driver: IDataDriver;
|
|
2055
2061
|
} | null>;
|
|
2056
|
-
resolveById(
|
|
2057
|
-
peekById(
|
|
2058
|
-
|
|
2062
|
+
resolveById(environmentId: string): Promise<IDataDriver | null>;
|
|
2063
|
+
peekById(environmentId: string): {
|
|
2064
|
+
environmentId: string;
|
|
2059
2065
|
driver: IDataDriver;
|
|
2060
2066
|
project: any;
|
|
2061
2067
|
} | null;
|
|
2062
|
-
invalidate(
|
|
2068
|
+
invalidate(environmentId: string): void;
|
|
2063
2069
|
private buildCacheEntry;
|
|
2064
2070
|
}
|
|
2065
2071
|
|
|
@@ -2076,19 +2082,19 @@ interface ArtifactKernelFactoryConfig {
|
|
|
2076
2082
|
kernelConfig?: ConstructorParameters<typeof ObjectKernel>[0];
|
|
2077
2083
|
/**
|
|
2078
2084
|
* Base secret used to derive per-project AuthPlugin secrets via
|
|
2079
|
-
* HKDF-style HMAC-SHA256(baseSecret,
|
|
2085
|
+
* HKDF-style HMAC-SHA256(baseSecret, environmentId). Falls back to
|
|
2080
2086
|
* `process.env.OS_AUTH_SECRET` / `AUTH_SECRET` at construction time.
|
|
2081
2087
|
*/
|
|
2082
2088
|
authBaseSecret?: string;
|
|
2083
2089
|
}
|
|
2084
|
-
declare class ArtifactKernelFactory implements
|
|
2090
|
+
declare class ArtifactKernelFactory implements EnvironmentKernelFactory {
|
|
2085
2091
|
private readonly client;
|
|
2086
2092
|
private readonly envRegistry;
|
|
2087
2093
|
private readonly logger;
|
|
2088
2094
|
private readonly kernelConfig?;
|
|
2089
2095
|
private readonly authBaseSecret;
|
|
2090
2096
|
constructor(config: ArtifactKernelFactoryConfig);
|
|
2091
|
-
create(
|
|
2097
|
+
create(environmentId: string): Promise<ObjectKernel>;
|
|
2092
2098
|
}
|
|
2093
2099
|
|
|
2094
2100
|
/**
|
|
@@ -2134,10 +2140,10 @@ declare const PLATFORM_SSO_PROVIDER_ID = "objectstack-cloud";
|
|
|
2134
2140
|
* Derive the per-project OAuth client_id used in `sys_oauth_application`
|
|
2135
2141
|
* (cloud side) and {@link genericOAuth} config (project side).
|
|
2136
2142
|
*/
|
|
2137
|
-
declare function derivePlatformSsoClientId(
|
|
2143
|
+
declare function derivePlatformSsoClientId(environmentId: string): string;
|
|
2138
2144
|
/**
|
|
2139
2145
|
* Derive the per-project OAuth client_secret deterministically from the
|
|
2140
|
-
* shared master secret. HMAC-SHA256(baseSecret, 'oauth-client:' +
|
|
2146
|
+
* shared master secret. HMAC-SHA256(baseSecret, 'oauth-client:' + environmentId)
|
|
2141
2147
|
* yields a 64-char hex string that is:
|
|
2142
2148
|
* - stable across container cold-starts (no DB lookup needed)
|
|
2143
2149
|
* - independent per project (compromising one does not compromise others)
|
|
@@ -2149,7 +2155,7 @@ declare function derivePlatformSsoClientId(projectId: string): string;
|
|
|
2149
2155
|
* defaults to `storeClientSecret: 'hashed'` (SHA-256 + base64url) when the JWT
|
|
2150
2156
|
* plugin is enabled, and looks up the row by hashing the presented secret.
|
|
2151
2157
|
*/
|
|
2152
|
-
declare function derivePlatformSsoClientSecret(baseSecret: string,
|
|
2158
|
+
declare function derivePlatformSsoClientSecret(baseSecret: string, environmentId: string): string;
|
|
2153
2159
|
/**
|
|
2154
2160
|
* Build the redirect_uri better-auth's `genericOAuth` plugin will use
|
|
2155
2161
|
* when the project kernel mounts the provider with id
|
|
@@ -2171,7 +2177,7 @@ interface SeedPlatformSsoClientOptions {
|
|
|
2171
2177
|
update: (object: string, data: any, where: any, opts?: any) => Promise<any>;
|
|
2172
2178
|
};
|
|
2173
2179
|
/** Project id (also used to derive client_id + client_secret). */
|
|
2174
|
-
|
|
2180
|
+
environmentId: string;
|
|
2175
2181
|
/**
|
|
2176
2182
|
* Project hostname (e.g. `acme-crm.objectos.app`). Optional — projects
|
|
2177
2183
|
* may be created before a hostname is assigned, in which case no
|
|
@@ -2194,7 +2200,7 @@ interface SeedPlatformSsoClientOptions {
|
|
|
2194
2200
|
}
|
|
2195
2201
|
/**
|
|
2196
2202
|
* Idempotently upsert a `sys_oauth_application` row for the given project.
|
|
2197
|
-
* Re-running with the same `
|
|
2203
|
+
* Re-running with the same `environmentId` is a no-op (the deterministic
|
|
2198
2204
|
* `client_id` is uniquely indexed and the secret derivation is stable).
|
|
2199
2205
|
* Re-running with a new `hostname` adds the new redirect_uri to the
|
|
2200
2206
|
* existing row's JSON array.
|
|
@@ -2212,7 +2218,7 @@ interface BackfillPlatformSsoClientsOptions {
|
|
|
2212
2218
|
limit?: number;
|
|
2213
2219
|
}
|
|
2214
2220
|
/**
|
|
2215
|
-
* Scan `
|
|
2221
|
+
* Scan `sys_environment` and ensure every active project has a corresponding
|
|
2216
2222
|
* `sys_oauth_application` row. Intended to run once at cloud boot — the
|
|
2217
2223
|
* happy path is dominated by the project-create hook
|
|
2218
2224
|
* ({@link seedPlatformSsoClient}); the backfill exists so projects
|
|
@@ -2224,7 +2230,7 @@ declare function backfillPlatformSsoClients(opts: BackfillPlatformSsoClientsOpti
|
|
|
2224
2230
|
seeded: number;
|
|
2225
2231
|
alreadyExisted: number;
|
|
2226
2232
|
failures: Array<{
|
|
2227
|
-
|
|
2233
|
+
environmentId: string;
|
|
2228
2234
|
error: string;
|
|
2229
2235
|
}>;
|
|
2230
2236
|
}>;
|
|
@@ -2459,4 +2465,4 @@ declare function actionBodyRunnerFactory(runner: ScriptRunner, opts: FactoryOpti
|
|
|
2459
2465
|
timeoutMs?: number;
|
|
2460
2466
|
}) => ((actionCtx: any) => Promise<unknown>) | undefined;
|
|
2461
2467
|
|
|
2462
|
-
export { AppPlugin, ArtifactApiClient, type ArtifactApiClientConfig, ArtifactEnvironmentRegistry, type ArtifactEnvironmentRegistryConfig, ArtifactKernelFactory, type ArtifactKernelFactoryConfig, AuthProxyPlugin, type BackfillPlatformSsoClientsOptions, DEFAULT_CLOUD_URL, DEFAULT_RATE_LIMITS, type DefaultHostConfigOptions, type DefaultHostConfigResult, type DispatcherPluginConfig, DriverPlugin, type EnvironmentDriverRegistry, FileArtifactApiClient, type FileArtifactApiClientConfig, HttpDispatcher, type HttpDispatcherResult, type HttpProtocolContext, HttpServer, KernelManager, type KernelManagerConfig, type LoadArtifactBundleOptions, MarketplaceInstallLocalPlugin, type MarketplaceInstallLocalPluginConfig, MarketplaceProxyPlugin, type MarketplaceProxyPluginConfig, MiddlewareManager, type ObjectOSStackConfig, type ObjectOSStackResult, ObservabilityServicePlugin, type ObservabilityServicePluginOptions, PLATFORM_SSO_PROVIDER_ID,
|
|
2468
|
+
export { AppPlugin, ArtifactApiClient, type ArtifactApiClientConfig, ArtifactEnvironmentRegistry, type ArtifactEnvironmentRegistryConfig, ArtifactKernelFactory, type ArtifactKernelFactoryConfig, AuthProxyPlugin, type BackfillPlatformSsoClientsOptions, DEFAULT_CLOUD_URL, DEFAULT_RATE_LIMITS, type DefaultHostConfigOptions, type DefaultHostConfigResult, type DispatcherPluginConfig, DriverPlugin, type EnvironmentArtifactResponse, type EnvironmentDriverRegistry, type EnvironmentKernelFactory, type EnvironmentRuntimeConfig, FileArtifactApiClient, type FileArtifactApiClientConfig, HttpDispatcher, type HttpDispatcherResult, type HttpProtocolContext, HttpServer, KernelManager, type KernelManagerConfig, type LoadArtifactBundleOptions, MarketplaceInstallLocalPlugin, type MarketplaceInstallLocalPluginConfig, MarketplaceProxyPlugin, type MarketplaceProxyPluginConfig, MiddlewareManager, type ObjectOSStackConfig, type ObjectOSStackResult, ObservabilityServicePlugin, type ObservabilityServicePluginOptions, PLATFORM_SSO_PROVIDER_ID, QuickJSScriptRunner, type QuickJSScriptRunnerOptions, type RateLimitBucketConfig, type RateLimitDecision, type RateLimitDefaults, type RateLimitStore, RateLimiter, type ResolvedHostname, Runtime, type RuntimeConfig, SYSTEM_ENVIRONMENT_ID, SandboxError, type ScriptContext, type ScriptOrigin, type ScriptResult, type ScriptRunOptions, type ScriptRunner, type SecurityHeadersOptions, SeedLoaderService, type SeedPlatformSsoClientOptions, type StandaloneStackConfig, type StandaloneStackResult, type SystemEnvironmentPluginConfig, type TraceContext, UnimplementedScriptRunner, actionBodyRunnerFactory, backfillPlatformSsoClients, buildPlatformSsoRedirectUri, buildSecurityHeaders, collectBundleActions, collectBundleFunctions, collectBundleHooks, createDefaultHostConfig, createDispatcherPlugin, createObjectOSStack, createStandaloneStack, createSystemEnvironmentPlugin, derivePlatformSsoClientId, derivePlatformSsoClientSecret, extractRequestId, formatTraceparent, generateRequestId, hookBodyRunnerFactory, isHttpUrl, loadArtifactBundle, mergeRuntimeModule, parseTraceparent, readArtifactSource, resolveCloudUrl, resolveDefaultArtifactPath, resolveErrorReporter, resolveMetrics, resolveRequestId, seedPlatformSsoClient };
|