@onlineapps/conn-orch-api-mapper 1.0.30 → 1.0.32

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/ApiMapper.js +28 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onlineapps/conn-orch-api-mapper",
3
- "version": "1.0.30",
3
+ "version": "1.0.32",
4
4
  "description": "API mapping connector for OA Drive - maps cookbook operations to HTTP endpoints",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
package/src/ApiMapper.js CHANGED
@@ -39,9 +39,12 @@ class ApiMapper {
39
39
 
40
40
  this.openApiSpec = config.openApiSpec;
41
41
  this.serviceUrl = config.serviceUrl;
42
- this.service = config.service; // Express app for direct calls
42
+ this.service = config.service;
43
43
  this.directCall = config.directCall === true;
44
- this.logger = config.logger || console;
44
+ if (!config.logger || typeof config.logger.warn !== 'function') {
45
+ throw new Error('[ApiMapper] Logger is required — Expected object with warn() method');
46
+ }
47
+ this.logger = config.logger;
45
48
 
46
49
  // Parse OpenAPI to create operation map
47
50
  this.operations = this._parseOpenApiSpec(this.openApiSpec);
@@ -686,7 +689,7 @@ class ApiMapper {
686
689
  * @private
687
690
  * @param {Object} operation - Operation definition
688
691
  * @param {Object} input - Resolved input
689
- * @param {Object} context - Workflow context (must include _system.tenant_id + _system.workspace_id)
692
+ * @param {Object} context - Workflow context (must include _system.tenant_id + _system.default_workspace_id)
690
693
  * @returns {Object} Request object
691
694
  */
692
695
  _buildRequest(operation, input, context = {}) {
@@ -760,25 +763,40 @@ class ApiMapper {
760
763
  const sys = context && typeof context === 'object' ? context._system : null;
761
764
  if (!sys) {
762
765
  throw new Error(
763
- '[ApiMapper][TenantContext] Missing _system context - Expected context._system with tenant_id + workspace_id. ' +
764
- 'Fix: Gateway must set _system.tenant_id + _system.workspace_id.'
766
+ '[ApiMapper][TenantContext] Missing _system context - Expected context._system with tenant_id. ' +
767
+ 'Fix: Gateway must set _system.tenant_id.'
765
768
  );
766
769
  }
767
770
 
768
- if (sys.tenant_id === undefined || sys.workspace_id === undefined) {
771
+ if (sys.tenant_id === undefined) {
769
772
  throw new Error(
770
- '[ApiMapper][TenantContext] Missing tenant context - Expected _system.tenant_id + _system.workspace_id'
773
+ '[ApiMapper][TenantContext] Missing tenant context - Expected _system.tenant_id'
771
774
  );
772
775
  }
773
776
 
774
777
  const tenantId = Number.parseInt(String(sys.tenant_id), 10);
775
- const workspaceId = Number.parseInt(String(sys.workspace_id), 10);
776
778
  if (!Number.isInteger(tenantId) || tenantId <= 0) {
777
779
  throw new Error(`[ApiMapper][TenantContext] Invalid tenant_id - Expected positive integer, got: ${sys.tenant_id}`);
778
780
  }
781
+
782
+ // workspace_id: per-step override → cookbook default → error
783
+ // See: .cursor/rules/workspace-architecture.mdc
784
+ const stepDef = context._pointer?.currentStep || operation;
785
+ const rawStepWs = stepDef?.workspace_id;
786
+ const rawDefaultWs = sys.default_workspace_id;
787
+ const rawWorkspaceId = rawStepWs !== undefined && rawStepWs !== null ? rawStepWs : rawDefaultWs;
788
+
789
+ if (rawWorkspaceId === undefined || rawWorkspaceId === null) {
790
+ throw new Error(
791
+ '[ApiMapper][TenantContext] Missing workspace_id - set per-step workspace_id or cookbook defaults.workspace_id'
792
+ );
793
+ }
794
+
795
+ const workspaceId = Number.parseInt(String(rawWorkspaceId), 10);
779
796
  if (!Number.isInteger(workspaceId) || workspaceId <= 0) {
780
- throw new Error(`[ApiMapper][TenantContext] Invalid workspace_id - Expected positive integer, got: ${sys.workspace_id}`);
797
+ throw new Error(`[ApiMapper][TenantContext] Invalid workspace_id - Expected positive integer, got: ${rawWorkspaceId}`);
781
798
  }
799
+
782
800
  const personId = sys.person_id !== undefined && sys.person_id !== null
783
801
  ? Number.parseInt(String(sys.person_id), 10)
784
802
  : undefined;
@@ -786,6 +804,7 @@ class ApiMapper {
786
804
  throw new Error(`[ApiMapper][TenantContext] Invalid person_id - Expected positive integer, got: ${sys.person_id}`);
787
805
  }
788
806
 
807
+ // See: docs/standards/tenant-context-contract.md (§3 Data Flow)
789
808
  request.headers['x-tenant-id'] = String(tenantId);
790
809
  request.headers['x-workspace-id'] = String(workspaceId);
791
810
  request.headers['x-person-id'] = String(personId);