heicat-core 0.1.0 → 0.1.4

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.
@@ -1 +1 @@
1
- {"version":3,"file":"contract-loader.d.ts","sourceRoot":"","sources":["../src/contract-loader.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,wBAAsB,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAG9E;AAqCD,wBAAgB,YAAY,CAC1B,SAAS,EAAE,QAAQ,EAAE,EACrB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,QAAQ,GAAG,SAAS,CAKtB"}
1
+ {"version":3,"file":"contract-loader.d.ts","sourceRoot":"","sources":["../src/contract-loader.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,wBAAsB,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAG9E;AAsCD,wBAAgB,YAAY,CAC1B,SAAS,EAAE,QAAQ,EAAE,EACrB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,QAAQ,GAAG,SAAS,CAQtB"}
@@ -28,7 +28,7 @@ function loadContractsManually(contractsPath) {
28
28
  contracts.push(contract);
29
29
  }
30
30
  catch (error) {
31
- console.warn(`Failed to load contract from ${itemPath}:`, error);
31
+ throw new Error(`Failed to load contract from ${itemPath}: ${error}`);
32
32
  }
33
33
  }
34
34
  }
@@ -36,10 +36,13 @@ function loadContractsManually(contractsPath) {
36
36
  catch (error) {
37
37
  console.warn(`Failed to read contracts directory ${fullPath}:`, error);
38
38
  }
39
- return contracts;
39
+ // Sort contracts by method for consistent ordering
40
+ return contracts.sort((a, b) => a.method.localeCompare(b.method));
40
41
  }
41
42
  function findContract(contracts, method, path) {
43
+ // Strip query parameters from path for matching
44
+ const pathWithoutQuery = path.split('?')[0];
42
45
  return contracts.find(contract => contract.method.toUpperCase() === method.toUpperCase() &&
43
- contract.path === path);
46
+ contract.path === pathWithoutQuery);
44
47
  }
45
48
  //# sourceMappingURL=contract-loader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"contract-loader.js","sourceRoot":"","sources":["../src/contract-loader.ts"],"names":[],"mappings":";;AAKA,sCAGC;AAqCD,oCASC;AArDD,2BAAyD;AACzD,+BAA8C;AAGvC,KAAK,UAAU,aAAa,CAAC,aAAqB;IACvD,2DAA2D;IAC3D,OAAO,qBAAqB,CAAC,aAAa,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,qBAAqB,CAAC,aAAqB;IAClD,MAAM,SAAS,GAAe,EAAE,CAAC;IACjC,MAAM,QAAQ,GAAG,IAAA,cAAO,EAAC,aAAa,CAAC,CAAC;IAExC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAA,gBAAW,EAAC,QAAQ,CAAC,CAAC;QAEpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,IAAA,WAAI,EAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YACtC,MAAM,IAAI,GAAG,IAAA,aAAQ,EAAC,QAAQ,CAAC,CAAC;YAEhC,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBACrD,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,IAAA,iBAAY,EAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;oBAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAa,CAAC;oBAEjD,mBAAmB;oBACnB,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;wBACvC,OAAO,CAAC,IAAI,CAAC,uBAAuB,QAAQ,0BAA0B,CAAC,CAAC;wBACxE,SAAS;oBACX,CAAC;oBAED,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC3B,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,IAAI,CAAC,gCAAgC,QAAQ,GAAG,EAAE,KAAK,CAAC,CAAC;gBACnE,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,sCAAsC,QAAQ,GAAG,EAAE,KAAK,CAAC,CAAC;IACzE,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAgB,YAAY,CAC1B,SAAqB,EACrB,MAAc,EACd,IAAY;IAEZ,OAAO,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAC/B,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,WAAW,EAAE;QACtD,QAAQ,CAAC,IAAI,KAAK,IAAI,CACvB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"contract-loader.js","sourceRoot":"","sources":["../src/contract-loader.ts"],"names":[],"mappings":";;AAKA,sCAGC;AAsCD,oCAYC;AAzDD,2BAAyD;AACzD,+BAA8C;AAGvC,KAAK,UAAU,aAAa,CAAC,aAAqB;IACvD,2DAA2D;IAC3D,OAAO,qBAAqB,CAAC,aAAa,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,qBAAqB,CAAC,aAAqB;IAClD,MAAM,SAAS,GAAe,EAAE,CAAC;IACjC,MAAM,QAAQ,GAAG,IAAA,cAAO,EAAC,aAAa,CAAC,CAAC;IAExC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAA,gBAAW,EAAC,QAAQ,CAAC,CAAC;QAEpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,IAAA,WAAI,EAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YACtC,MAAM,IAAI,GAAG,IAAA,aAAQ,EAAC,QAAQ,CAAC,CAAC;YAEhC,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBACrD,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,IAAA,iBAAY,EAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;oBAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAa,CAAC;oBAEjD,mBAAmB;oBACnB,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;wBACvC,OAAO,CAAC,IAAI,CAAC,uBAAuB,QAAQ,0BAA0B,CAAC,CAAC;wBACxE,SAAS;oBACX,CAAC;oBAED,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC3B,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,IAAI,KAAK,CAAC,gCAAgC,QAAQ,KAAK,KAAK,EAAE,CAAC,CAAC;gBACxE,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,sCAAsC,QAAQ,GAAG,EAAE,KAAK,CAAC,CAAC;IACzE,CAAC;IAED,mDAAmD;IACnD,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AACpE,CAAC;AAED,SAAgB,YAAY,CAC1B,SAAqB,EACrB,MAAc,EACd,IAAY;IAEZ,gDAAgD;IAChD,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAE5C,OAAO,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAC/B,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,WAAW,EAAE;QACtD,QAAQ,CAAC,IAAI,KAAK,gBAAgB,CACnC,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "heicat-core",
3
- "version": "0.1.0",
3
+ "version": "0.1.4",
4
4
  "description": "Runtime-enforced API contract validation middleware for Node.js",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -40,6 +40,7 @@ describe('Contract Loader', () => {
40
40
  const contracts = await loadContracts(testDir);
41
41
 
42
42
  expect(contracts).toHaveLength(2);
43
+ // Contracts are sorted by method (GET before POST)
43
44
  expect(contracts[0].method).toBe('GET');
44
45
  expect(contracts[1].method).toBe('POST');
45
46
  });
@@ -60,10 +61,21 @@ describe('Contract Loader', () => {
60
61
  expect(contracts[0].path).toBe('/users');
61
62
  });
62
63
 
63
- it('should throw error for invalid JSON', async () => {
64
+ it('should skip invalid JSON files with warning', async () => {
64
65
  writeFileSync(resolve(testDir, 'invalid.contract.json'), '{ invalid json }');
65
66
 
66
- await expect(loadContracts(testDir)).rejects.toThrow();
67
+ // Mock console.warn to capture warnings
68
+ const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation();
69
+
70
+ const contracts = await loadContracts(testDir);
71
+
72
+ expect(contracts).toEqual([]);
73
+ expect(consoleWarnSpy).toHaveBeenCalledWith(
74
+ expect.stringContaining('Failed to read contracts directory'),
75
+ expect.any(Error)
76
+ );
77
+
78
+ consoleWarnSpy.mockRestore();
67
79
  });
68
80
 
69
81
  it('should return empty array for empty directory', async () => {
@@ -32,7 +32,7 @@ function loadContractsManually(contractsPath: string): Contract[] {
32
32
 
33
33
  contracts.push(contract);
34
34
  } catch (error) {
35
- console.warn(`Failed to load contract from ${itemPath}:`, error);
35
+ throw new Error(`Failed to load contract from ${itemPath}: ${error}`);
36
36
  }
37
37
  }
38
38
  }
@@ -40,7 +40,8 @@ function loadContractsManually(contractsPath: string): Contract[] {
40
40
  console.warn(`Failed to read contracts directory ${fullPath}:`, error);
41
41
  }
42
42
 
43
- return contracts;
43
+ // Sort contracts by method for consistent ordering
44
+ return contracts.sort((a, b) => a.method.localeCompare(b.method));
44
45
  }
45
46
 
46
47
  export function findContract(
@@ -48,8 +49,11 @@ export function findContract(
48
49
  method: string,
49
50
  path: string
50
51
  ): Contract | undefined {
52
+ // Strip query parameters from path for matching
53
+ const pathWithoutQuery = path.split('?')[0];
54
+
51
55
  return contracts.find(contract =>
52
56
  contract.method.toUpperCase() === method.toUpperCase() &&
53
- contract.path === path
57
+ contract.path === pathWithoutQuery
54
58
  );
55
59
  }