@objectstack/runtime 10.0.0 → 10.2.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 CHANGED
@@ -987,6 +987,36 @@ var init_app_plugin = __esm({
987
987
  error: err?.message ?? String(err)
988
988
  });
989
989
  }
990
+ try {
991
+ const dsDefs = this.bundle.datasources;
992
+ const dsList = Array.isArray(dsDefs) ? dsDefs : dsDefs && typeof dsDefs === "object" ? Object.entries(dsDefs).map(([name, def]) => ({ name, ...def })) : [];
993
+ if (dsList.length > 0) {
994
+ let connection;
995
+ try {
996
+ connection = ctx.getService("datasource-connection");
997
+ } catch {
998
+ connection = void 0;
999
+ }
1000
+ if (typeof connection?.connectDeclared === "function") {
1001
+ const objects = Array.isArray(this.bundle.objects) ? this.bundle.objects : [];
1002
+ const results = await connection.connectDeclared({ datasources: dsList, objects });
1003
+ const connected = results.filter((r) => r.status === "connected");
1004
+ if (connected.length > 0) {
1005
+ ctx.logger.info("Auto-connected declared datasources", {
1006
+ appId,
1007
+ connected: connected.map((r) => r.name)
1008
+ });
1009
+ }
1010
+ } else {
1011
+ ctx.logger.debug("No datasource-connection service \u2014 declared datasources stay metadata-only", { appId });
1012
+ }
1013
+ }
1014
+ } catch (err) {
1015
+ ctx.logger.error(
1016
+ `[AppPlugin] declared-datasource auto-connect failed for app '${appId}': ${err?.message ?? String(err)}`
1017
+ );
1018
+ throw err;
1019
+ }
990
1020
  try {
991
1021
  const metadata = ctx.getService("metadata");
992
1022
  if (typeof metadata?.registerInMemory === "function") {
@@ -1549,55 +1579,55 @@ async function createStandaloneStack(config) {
1549
1579
  const explicitDriver = cfg.databaseDriver ?? process.env.OS_DATABASE_DRIVER?.trim();
1550
1580
  const dbDriver = explicitDriver ?? detectDriverFromUrl(dbUrl);
1551
1581
  let driverPlugin;
1552
- if (dbDriver === "memory") {
1553
- const { InMemoryDriver } = await import("@objectstack/driver-memory");
1554
- driverPlugin = new DriverPlugin2(new InMemoryDriver());
1555
- } else if (dbDriver === "postgres") {
1556
- const { SqlDriver } = await import("@objectstack/driver-sql");
1557
- driverPlugin = new DriverPlugin2(
1558
- new SqlDriver({
1559
- client: "pg",
1560
- connection: dbUrl,
1561
- pool: { min: 0, max: 5 }
1562
- })
1563
- );
1564
- } else if (dbDriver === "mongodb") {
1565
- let MongoDBDriver;
1566
- try {
1567
- ({ MongoDBDriver } = await import("@objectstack/driver-mongodb"));
1568
- } catch (err) {
1569
- throw new Error(
1570
- `[StandaloneStack] mongodb URL detected but @objectstack/driver-mongodb is not installed. Add it as a dependency or pass an explicit driverPlugin. (${err?.message ?? err})`
1571
- );
1572
- }
1573
- driverPlugin = new DriverPlugin2(new MongoDBDriver({ url: dbUrl }));
1574
- } else if (dbDriver === "sqlite-wasm") {
1582
+ if (dbDriver === "sqlite-wasm") {
1575
1583
  const { SqliteWasmDriver } = await import("@objectstack/driver-sqlite-wasm");
1576
- const filename = dbUrl.replace(/^wasm-sqlite:(\/\/)?/i, "").replace(/^file:(\/\/)?/i, "");
1577
- if (filename && filename !== ":memory:") {
1584
+ const filename = dbUrl.replace(/^wasm-sqlite:(\/\/)?/i, "").replace(/^file:(\/\/)?/i, "") || ":memory:";
1585
+ if (filename !== ":memory:") {
1578
1586
  (0, import_node_fs2.mkdirSync)((0, import_node_path3.resolve)(filename, ".."), { recursive: true });
1579
1587
  }
1580
1588
  driverPlugin = new DriverPlugin2(
1581
1589
  new SqliteWasmDriver({
1582
- filename: filename || ":memory:",
1583
- persist: filename && filename !== ":memory:" ? "on-write" : void 0
1590
+ filename,
1591
+ persist: filename !== ":memory:" ? "on-write" : void 0
1584
1592
  })
1585
1593
  );
1586
1594
  } else {
1587
- const { SqlDriver } = await import("@objectstack/driver-sql");
1588
- const filename = dbUrl.replace(/^file:(\/\/)?/, "");
1589
- if (!filename || /^[a-z][a-z0-9+.-]*:\/\//i.test(filename)) {
1590
- throw new Error(
1591
- `[StandaloneStack] sqlite driver was selected but the URL does not look like a file path: "${dbUrl}". Use file:/path/to/db.sqlite, or set OS_DATABASE_DRIVER explicitly.`
1592
- );
1595
+ const { createDefaultDatasourceDriverFactory } = await import("@objectstack/service-datasource");
1596
+ let driverId;
1597
+ let driverConfig;
1598
+ if (dbDriver === "memory") {
1599
+ driverId = "memory";
1600
+ driverConfig = {};
1601
+ } else if (dbDriver === "postgres") {
1602
+ driverId = "postgres";
1603
+ driverConfig = { url: dbUrl };
1604
+ } else if (dbDriver === "mongodb") {
1605
+ driverId = "mongodb";
1606
+ driverConfig = { url: dbUrl };
1607
+ } else {
1608
+ driverId = "sqlite";
1609
+ const filename = dbUrl.replace(/^file:(\/\/)?/, "");
1610
+ if (!filename || /^[a-z][a-z0-9+.-]*:\/\//i.test(filename)) {
1611
+ throw new Error(
1612
+ `[StandaloneStack] sqlite driver was selected but the URL does not look like a file path: "${dbUrl}". Use file:/path/to/db.sqlite, or set OS_DATABASE_DRIVER explicitly.`
1613
+ );
1614
+ }
1615
+ (0, import_node_fs2.mkdirSync)((0, import_node_path3.resolve)(filename, ".."), { recursive: true });
1616
+ driverConfig = { filename };
1617
+ }
1618
+ let driverHandle;
1619
+ try {
1620
+ driverHandle = await createDefaultDatasourceDriverFactory().create({ driver: driverId, config: driverConfig });
1621
+ } catch (err) {
1622
+ if (dbDriver === "mongodb") {
1623
+ throw new Error(
1624
+ `[StandaloneStack] mongodb URL detected but @objectstack/driver-mongodb is not installed. Add it as a dependency or pass an explicit driverPlugin. (${err?.message ?? err})`
1625
+ );
1626
+ }
1627
+ throw err;
1593
1628
  }
1594
- (0, import_node_fs2.mkdirSync)((0, import_node_path3.resolve)(filename, ".."), { recursive: true });
1595
1629
  driverPlugin = new DriverPlugin2(
1596
- new SqlDriver({
1597
- client: "better-sqlite3",
1598
- connection: { filename },
1599
- useNullAsDefault: true
1600
- })
1630
+ driverHandle?.driver ?? driverHandle
1601
1631
  );
1602
1632
  }
1603
1633
  const artifactBundle = await loadArtifactBundle(artifactPath, {
@@ -2770,7 +2800,7 @@ var _HttpDispatcher = class _HttpDispatcher {
2770
2800
  */
2771
2801
  async enforceProjectMembership(context, path) {
2772
2802
  if (!this.enforceMembership) return null;
2773
- const skipPaths = ["/auth", "/cloud", "/health", "/discovery"];
2803
+ const skipPaths = ["/auth", "/cloud", "/health", "/ready", "/discovery"];
2774
2804
  if (skipPaths.some((p) => path.startsWith(p))) return null;
2775
2805
  if (/(^|\/)share-links\/[^/]+\/(resolve|messages)$/.test(path)) return null;
2776
2806
  const environmentId = context.environmentId;
@@ -4587,6 +4617,10 @@ var _HttpDispatcher = class _HttpDispatcher {
4587
4617
  })
4588
4618
  };
4589
4619
  }
4620
+ if (cleanPath === "/ready" && method === "GET") {
4621
+ const state = typeof this.kernel?.getState === "function" ? this.kernel.getState() : "running";
4622
+ return state === "running" ? { handled: true, response: this.success({ status: "ready", state }) } : { handled: true, response: this.error("Service not ready", 503, { state }) };
4623
+ }
4590
4624
  if (cleanPath.startsWith("/auth")) {
4591
4625
  return this.handleAuth(cleanPath.substring(5), method, body, context);
4592
4626
  }