@objectstack/rest 9.8.0 → 9.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.cts CHANGED
@@ -451,11 +451,13 @@ declare class RestServer {
451
451
  private registerCrudEndpoints;
452
452
  /**
453
453
  * Register object-specific action endpoints that don't fit the
454
- * generic CRUD shape. These are domain operations (Salesforce
455
- * convertLead, etc.) where the protocol implementation does its own
456
- * multi-record orchestration and we just need a thin HTTP route.
454
+ * generic CRUD shape domain operations where the protocol does its
455
+ * own orchestration and we just need a thin HTTP route.
457
456
  *
458
- * POST {basePath}/data/lead/:id/convertM10.6 lead conversion.
457
+ * POST {basePath}/data/:object/:id/clonerecord clone (gated by
458
+ * `enable.clone`). This is object-agnostic by design: it works for any
459
+ * authored object regardless of namespace, unlike a hardcoded
460
+ * per-object route would.
459
461
  */
460
462
  private registerDataActionEndpoints;
461
463
  /**
package/dist/index.d.ts CHANGED
@@ -451,11 +451,13 @@ declare class RestServer {
451
451
  private registerCrudEndpoints;
452
452
  /**
453
453
  * Register object-specific action endpoints that don't fit the
454
- * generic CRUD shape. These are domain operations (Salesforce
455
- * convertLead, etc.) where the protocol implementation does its own
456
- * multi-record orchestration and we just need a thin HTTP route.
454
+ * generic CRUD shape domain operations where the protocol does its
455
+ * own orchestration and we just need a thin HTTP route.
457
456
  *
458
- * POST {basePath}/data/lead/:id/convertM10.6 lead conversion.
457
+ * POST {basePath}/data/:object/:id/clonerecord clone (gated by
458
+ * `enable.clone`). This is object-agnostic by design: it works for any
459
+ * authored object regardless of namespace, unlike a hardcoded
460
+ * per-object route would.
459
461
  */
460
462
  private registerDataActionEndpoints;
461
463
  /**
package/dist/index.js CHANGED
@@ -218,6 +218,18 @@ function isMetaEnvelope(value) {
218
218
  return !!value && typeof value === "object" && typeof value.type === "string" && typeof value.name === "string" && value.item != null && typeof value.item === "object" && !Array.isArray(value.item);
219
219
  }
220
220
  function mapDataError(error, object) {
221
+ if (error?.code === "DELETE_RESTRICTED") {
222
+ return {
223
+ status: 409,
224
+ body: {
225
+ error: error?.message ?? "Cannot delete: dependent records exist",
226
+ code: "DELETE_RESTRICTED",
227
+ ...error?.dependentObject ? { dependentObject: error.dependentObject } : {},
228
+ ...typeof error?.dependentCount === "number" ? { dependentCount: error.dependentCount } : {},
229
+ ...object ? { object } : {}
230
+ }
231
+ };
232
+ }
221
233
  if (error?.code === "CONCURRENT_UPDATE" || error?.name === "ConcurrentUpdateError") {
222
234
  return {
223
235
  status: 409,
@@ -2326,51 +2338,18 @@ var RestServer = class {
2326
2338
  }
2327
2339
  /**
2328
2340
  * Register object-specific action endpoints that don't fit the
2329
- * generic CRUD shape. These are domain operations (Salesforce
2330
- * convertLead, etc.) where the protocol implementation does its own
2331
- * multi-record orchestration and we just need a thin HTTP route.
2341
+ * generic CRUD shape domain operations where the protocol does its
2342
+ * own orchestration and we just need a thin HTTP route.
2332
2343
  *
2333
- * POST {basePath}/data/lead/:id/convertM10.6 lead conversion.
2344
+ * POST {basePath}/data/:object/:id/clonerecord clone (gated by
2345
+ * `enable.clone`). This is object-agnostic by design: it works for any
2346
+ * authored object regardless of namespace, unlike a hardcoded
2347
+ * per-object route would.
2334
2348
  */
2335
2349
  registerDataActionEndpoints(basePath) {
2336
2350
  const isScoped = basePath.includes("/environments/:environmentId");
2337
2351
  const { crud } = this.config;
2338
2352
  const dataPath = `${basePath}${crud.dataPrefix}`;
2339
- this.routeManager.register({
2340
- method: "POST",
2341
- path: `${dataPath}/lead/:id/convert`,
2342
- handler: async (req, res) => {
2343
- try {
2344
- const environmentId = isScoped ? req.params?.environmentId : void 0;
2345
- const p = await this.resolveProtocol(environmentId, req);
2346
- const context = await this.resolveExecCtx(environmentId, req);
2347
- if (this.enforceAuth(req, res, context)) return;
2348
- const convertLead = p.convertLead;
2349
- if (typeof convertLead !== "function") {
2350
- res.status(501).json({ code: "NOT_IMPLEMENTED", error: "Lead convert not supported by this protocol" });
2351
- return;
2352
- }
2353
- const body = req.body ?? {};
2354
- const result = await convertLead.call(p, {
2355
- leadId: req.params.id,
2356
- accountId: body.accountId,
2357
- contactId: body.contactId,
2358
- createOpportunity: body.createOpportunity,
2359
- opportunity: body.opportunity,
2360
- convertedStatus: body.convertedStatus,
2361
- ...context ? { context } : {}
2362
- });
2363
- res.json(result);
2364
- } catch (error) {
2365
- logError("[REST] Unhandled error:", error);
2366
- sendError(res, error, "lead");
2367
- }
2368
- },
2369
- metadata: {
2370
- summary: "Convert a Lead into Account + Contact (+ optional Opportunity)",
2371
- tags: ["data", "lead"]
2372
- }
2373
- });
2374
2353
  this.routeManager.register({
2375
2354
  method: "POST",
2376
2355
  path: `${dataPath}/:object/:id/clone`,
@@ -2804,6 +2783,9 @@ var RestServer = class {
2804
2783
  }
2805
2784
  }
2806
2785
  }
2786
+ if (view.viewKind === "form" && view.config && typeof view.config === "object" && view.config.sharing) {
2787
+ candidates.push({ form: view.config, key: view.name });
2788
+ }
2807
2789
  for (const c of candidates) {
2808
2790
  const sharing = c.form?.sharing;
2809
2791
  if (!sharing || sharing.allowAnonymous !== true) continue;