@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.cjs CHANGED
@@ -258,6 +258,18 @@ function isMetaEnvelope(value) {
258
258
  return !!value && typeof value === "object" && typeof value.type === "string" && typeof value.name === "string" && value.item != null && typeof value.item === "object" && !Array.isArray(value.item);
259
259
  }
260
260
  function mapDataError(error, object) {
261
+ if (error?.code === "DELETE_RESTRICTED") {
262
+ return {
263
+ status: 409,
264
+ body: {
265
+ error: error?.message ?? "Cannot delete: dependent records exist",
266
+ code: "DELETE_RESTRICTED",
267
+ ...error?.dependentObject ? { dependentObject: error.dependentObject } : {},
268
+ ...typeof error?.dependentCount === "number" ? { dependentCount: error.dependentCount } : {},
269
+ ...object ? { object } : {}
270
+ }
271
+ };
272
+ }
261
273
  if (error?.code === "CONCURRENT_UPDATE" || error?.name === "ConcurrentUpdateError") {
262
274
  return {
263
275
  status: 409,
@@ -2366,51 +2378,18 @@ var RestServer = class {
2366
2378
  }
2367
2379
  /**
2368
2380
  * Register object-specific action endpoints that don't fit the
2369
- * generic CRUD shape. These are domain operations (Salesforce
2370
- * convertLead, etc.) where the protocol implementation does its own
2371
- * multi-record orchestration and we just need a thin HTTP route.
2381
+ * generic CRUD shape domain operations where the protocol does its
2382
+ * own orchestration and we just need a thin HTTP route.
2372
2383
  *
2373
- * POST {basePath}/data/lead/:id/convertM10.6 lead conversion.
2384
+ * POST {basePath}/data/:object/:id/clonerecord clone (gated by
2385
+ * `enable.clone`). This is object-agnostic by design: it works for any
2386
+ * authored object regardless of namespace, unlike a hardcoded
2387
+ * per-object route would.
2374
2388
  */
2375
2389
  registerDataActionEndpoints(basePath) {
2376
2390
  const isScoped = basePath.includes("/environments/:environmentId");
2377
2391
  const { crud } = this.config;
2378
2392
  const dataPath = `${basePath}${crud.dataPrefix}`;
2379
- this.routeManager.register({
2380
- method: "POST",
2381
- path: `${dataPath}/lead/:id/convert`,
2382
- handler: async (req, res) => {
2383
- try {
2384
- const environmentId = isScoped ? req.params?.environmentId : void 0;
2385
- const p = await this.resolveProtocol(environmentId, req);
2386
- const context = await this.resolveExecCtx(environmentId, req);
2387
- if (this.enforceAuth(req, res, context)) return;
2388
- const convertLead = p.convertLead;
2389
- if (typeof convertLead !== "function") {
2390
- res.status(501).json({ code: "NOT_IMPLEMENTED", error: "Lead convert not supported by this protocol" });
2391
- return;
2392
- }
2393
- const body = req.body ?? {};
2394
- const result = await convertLead.call(p, {
2395
- leadId: req.params.id,
2396
- accountId: body.accountId,
2397
- contactId: body.contactId,
2398
- createOpportunity: body.createOpportunity,
2399
- opportunity: body.opportunity,
2400
- convertedStatus: body.convertedStatus,
2401
- ...context ? { context } : {}
2402
- });
2403
- res.json(result);
2404
- } catch (error) {
2405
- logError("[REST] Unhandled error:", error);
2406
- sendError(res, error, "lead");
2407
- }
2408
- },
2409
- metadata: {
2410
- summary: "Convert a Lead into Account + Contact (+ optional Opportunity)",
2411
- tags: ["data", "lead"]
2412
- }
2413
- });
2414
2393
  this.routeManager.register({
2415
2394
  method: "POST",
2416
2395
  path: `${dataPath}/:object/:id/clone`,
@@ -2844,6 +2823,9 @@ var RestServer = class {
2844
2823
  }
2845
2824
  }
2846
2825
  }
2826
+ if (view.viewKind === "form" && view.config && typeof view.config === "object" && view.config.sharing) {
2827
+ candidates.push({ form: view.config, key: view.name });
2828
+ }
2847
2829
  for (const c of candidates) {
2848
2830
  const sharing = c.form?.sharing;
2849
2831
  if (!sharing || sharing.allowAnonymous !== true) continue;