@objectstack/objectql 6.8.1 → 6.9.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.d.mts CHANGED
@@ -81,15 +81,18 @@ type RegistryLogLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent';
81
81
  */
82
82
  interface SchemaRegistryOptions {
83
83
  /**
84
- * Whether the host kernel runs in multi-tenant mode. When `true` (default),
85
- * the registry auto-injects `organization_id` (lookup → sys_organization)
84
+ * Whether the host kernel runs in multi-tenant mode. When `true`, the
85
+ * registry auto-injects `organization_id` (lookup → sys_organization)
86
86
  * into every registered user object that doesn't already declare it and
87
87
  * isn't `managedBy` an external subsystem or explicitly opted-out via
88
88
  * `systemFields: false`.
89
89
  *
90
90
  * Sourced from the `OS_MULTI_TENANT` env var when not explicitly set —
91
91
  * matches how the SecurityPlugin and CLI startup banner pick the mode.
92
- * Pass an explicit boolean to override (useful in tests).
92
+ * Default is `false` (single-tenant) so local `dev`/`start` runs seed
93
+ * demo data inline at boot; set `OS_MULTI_TENANT=true` for cloud /
94
+ * production multi-org deployments. Pass an explicit boolean to override
95
+ * (useful in tests).
93
96
  */
94
97
  multiTenant?: boolean;
95
98
  }
package/dist/index.d.ts CHANGED
@@ -81,15 +81,18 @@ type RegistryLogLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent';
81
81
  */
82
82
  interface SchemaRegistryOptions {
83
83
  /**
84
- * Whether the host kernel runs in multi-tenant mode. When `true` (default),
85
- * the registry auto-injects `organization_id` (lookup → sys_organization)
84
+ * Whether the host kernel runs in multi-tenant mode. When `true`, the
85
+ * registry auto-injects `organization_id` (lookup → sys_organization)
86
86
  * into every registered user object that doesn't already declare it and
87
87
  * isn't `managedBy` an external subsystem or explicitly opted-out via
88
88
  * `systemFields: false`.
89
89
  *
90
90
  * Sourced from the `OS_MULTI_TENANT` env var when not explicitly set —
91
91
  * matches how the SecurityPlugin and CLI startup banner pick the mode.
92
- * Pass an explicit boolean to override (useful in tests).
92
+ * Default is `false` (single-tenant) so local `dev`/`start` runs seed
93
+ * demo data inline at boot; set `OS_MULTI_TENANT=true` for cloud /
94
+ * production multi-org deployments. Pass an explicit boolean to override
95
+ * (useful in tests).
93
96
  */
94
97
  multiTenant?: boolean;
95
98
  }
package/dist/index.js CHANGED
@@ -179,7 +179,7 @@ var SchemaRegistry = class {
179
179
  if (options.multiTenant !== void 0) {
180
180
  this.multiTenant = options.multiTenant;
181
181
  } else {
182
- this.multiTenant = String(process.env.OS_MULTI_TENANT ?? "true").toLowerCase() !== "false";
182
+ this.multiTenant = String(process.env.OS_MULTI_TENANT ?? "false").toLowerCase() !== "false";
183
183
  }
184
184
  }
185
185
  get logLevel() {
@@ -1229,6 +1229,7 @@ var TYPE_TO_SCHEMA = {
1229
1229
  flow: import_automation.FlowSchema,
1230
1230
  workflow: import_automation.WorkflowRuleSchema,
1231
1231
  approval: import_automation.ApprovalProcessSchema,
1232
+ job: import_system.JobSchema,
1232
1233
  hook: import_data2.HookSchema
1233
1234
  };
1234
1235
  var TYPE_TO_FORM = {
@@ -1361,6 +1362,81 @@ var HAND_CRAFTED_SCHEMAS = {
1361
1362
  },
1362
1363
  required: ["name", "label", "type"],
1363
1364
  additionalProperties: true
1365
+ },
1366
+ // Validation rules live inside `object.validations[]`. The canonical
1367
+ // ValidationRuleSchema is a discriminated union of 9 variants; the
1368
+ // generic SchemaForm renderer treats unions as opaque JSON, so we
1369
+ // ship a *flat* form-friendly schema covering the common base
1370
+ // properties plus every variant-specific field as optional. Save-time
1371
+ // validation is unaffected — the union schema is still authoritative
1372
+ // at write time.
1373
+ validation: {
1374
+ type: "object",
1375
+ properties: {
1376
+ // --- Base fields (all variants) ---
1377
+ name: { type: "string", description: "Unique rule name (snake_case)" },
1378
+ label: { type: "string" },
1379
+ description: { type: "string" },
1380
+ type: {
1381
+ type: "string",
1382
+ enum: [
1383
+ "script",
1384
+ "unique",
1385
+ "state_machine",
1386
+ "format",
1387
+ "cross_field",
1388
+ "json",
1389
+ "async",
1390
+ "custom",
1391
+ "conditional"
1392
+ ],
1393
+ default: "script",
1394
+ description: "Validation variant"
1395
+ },
1396
+ active: { type: "boolean", default: true },
1397
+ events: {
1398
+ type: "array",
1399
+ items: { type: "string", enum: ["insert", "update", "delete"] },
1400
+ default: ["insert", "update"]
1401
+ },
1402
+ priority: { type: "number", default: 100, minimum: 0, maximum: 9999 },
1403
+ severity: {
1404
+ type: "string",
1405
+ enum: ["error", "warning", "info"],
1406
+ default: "error"
1407
+ },
1408
+ message: { type: "string" },
1409
+ tags: { type: "array", items: { type: "string" } },
1410
+ // --- Variant-specific (all optional, gated by `type`) ---
1411
+ condition: {
1412
+ type: "string",
1413
+ description: "CEL predicate (type=script). True \u21D2 validation fails."
1414
+ },
1415
+ fields: {
1416
+ type: "array",
1417
+ items: { type: "string" },
1418
+ description: "Fields (type=unique / cross_field)."
1419
+ },
1420
+ scope: { type: "string", description: "CEL scope predicate (type=unique)." },
1421
+ caseSensitive: { type: "boolean", default: true },
1422
+ field: { type: "string", description: "Single field (type=state_machine / format)." },
1423
+ transitions: {
1424
+ type: "object",
1425
+ additionalProperties: { type: "array", items: { type: "string" } },
1426
+ description: "Map { OldState: [AllowedNewStates] } (type=state_machine)."
1427
+ },
1428
+ regex: { type: "string", description: "Regex (type=format)." },
1429
+ format: {
1430
+ type: "string",
1431
+ enum: ["email", "url", "phone", "json"],
1432
+ description: "Built-in format (type=format)."
1433
+ },
1434
+ url: { type: "string", description: "Endpoint URL (type=async)." },
1435
+ handler: { type: "string", description: "Handler reference (type=custom)." },
1436
+ when: { type: "string", description: "Outer condition (type=conditional)." }
1437
+ },
1438
+ required: ["name", "type", "message"],
1439
+ additionalProperties: true
1364
1440
  }
1365
1441
  };
1366
1442
  var FORM_VIEW_TYPES = /* @__PURE__ */ new Set(["simple", "tabbed", "wizard", "split", "drawer", "modal"]);
@@ -4791,6 +4867,7 @@ var _ObjectQL = class _ObjectQL {
4791
4867
  "workflows",
4792
4868
  "approvals",
4793
4869
  "webhooks",
4870
+ "jobs",
4794
4871
  // Security Protocol
4795
4872
  "roles",
4796
4873
  "permissions",
@@ -6150,7 +6227,29 @@ var ObjectQLPlugin = class {
6150
6227
  ctx.registerService("protocol", protocolShim);
6151
6228
  ctx.logger.info("Protocol service registered");
6152
6229
  ctx.registerService("analytics", {
6153
- query: (body) => protocolShim.analyticsQuery(body),
6230
+ // HttpDispatcher passes the raw POST body (AnalyticsQuery shape:
6231
+ // `{ cube, measures, dimensions, where?, filters?, ... }`). The
6232
+ // protocol shim's `analyticsQuery` expects the wrapped envelope
6233
+ // `{ cube, query }` and destructures `request.query` for dims /
6234
+ // measures. Reshape here so the destructure resolves to the
6235
+ // analytics query instead of `undefined` (which caused
6236
+ // "Cannot read properties of undefined (reading 'dimensions')").
6237
+ //
6238
+ // `analyticsQuery` also returns its own `{ success, data: { rows,
6239
+ // fields } }` envelope. HttpDispatcher wraps service responses
6240
+ // again with `success(result)`, so without unwrapping here the
6241
+ // client sees `{success, data:{success, data:{rows, fields}}}` —
6242
+ // KPI widgets read `data.rows` and silently get nothing. Unwrap
6243
+ // to the inner `{ rows, fields }` payload so a single wrap from
6244
+ // the dispatcher yields the canonical shape.
6245
+ query: async (body) => {
6246
+ const envelope = body && typeof body === "object" && "query" in body && "cube" in body ? body : { cube: body?.cube, query: body };
6247
+ const result = await protocolShim.analyticsQuery(envelope);
6248
+ if (result && typeof result === "object" && "success" in result && "data" in result) {
6249
+ return result.data;
6250
+ }
6251
+ return result;
6252
+ },
6154
6253
  getMeta: async () => ({
6155
6254
  cubes: [],
6156
6255
  message: "Analytics meta endpoint not implemented by ObjectQL adapter"