@carbonbox/domain 0.8.6 → 0.8.8

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.
@@ -4,18 +4,39 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
4
4
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
5
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
6
  };
7
- var _EmissionCalculationFormulaExpression_instances, _a, _EmissionCalculationFormulaExpression_guardAgainstInvalidLength, _EmissionCalculationFormulaExpression_guardAgainstInvalidFormulaStructure;
7
+ var _EmissionCalculationFormulaExpression_instances, _a, _EmissionCalculationFormulaExpression_guardAgainstInvalidLength, _EmissionCalculationFormulaExpression_guardAgainstInsecureContent;
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.EmissionCalculationFormulaExpression = void 0;
10
10
  const String_1 = require("../../../shared/domain/value-objects/String");
11
11
  const InvalidPropertyValueError_1 = require("../../../shared/domain/exceptions/InvalidPropertyValueError");
12
+ /**
13
+ * Domain value object for the formula expression string.
14
+ *
15
+ * The domain validates only what can be enforced without parsing the
16
+ * expression as math (the `@carbonbox/domain` package is zero-dependency
17
+ * by design — see CLAUDE.md):
18
+ *
19
+ * - Empty / type / length boundaries (storage invariants).
20
+ * - Defense-in-depth against script-injection-shaped substrings.
21
+ *
22
+ * The mathematical correctness of the expression — syntax, allowed
23
+ * functions, and that every referenced symbol is declared on the
24
+ * parent formula (variables + reserved `EF`/`GWP` tokens) — is a
25
+ * concern of the application layer, where `IFormulaValidationApplicationService`
26
+ * (backed by mathjs) parses the expression as a real AST.
27
+ *
28
+ * The handlers that build / activate / update a formula MUST run that
29
+ * application-side validation before constructing this VO. The VO does
30
+ * not assert it directly because doing so would require importing a
31
+ * mathematical parser into the pure domain layer.
32
+ */
12
33
  class EmissionCalculationFormulaExpression extends String_1.String {
13
34
  constructor(value, skipDomainValidation) {
14
35
  super(value, skipDomainValidation, _a.PROPERTY_NAME);
15
36
  _EmissionCalculationFormulaExpression_instances.add(this);
16
37
  if (skipDomainValidation === false) {
17
38
  __classPrivateFieldGet(this, _EmissionCalculationFormulaExpression_instances, "m", _EmissionCalculationFormulaExpression_guardAgainstInvalidLength).call(this, value);
18
- __classPrivateFieldGet(this, _EmissionCalculationFormulaExpression_instances, "m", _EmissionCalculationFormulaExpression_guardAgainstInvalidFormulaStructure).call(this, value);
39
+ __classPrivateFieldGet(this, _EmissionCalculationFormulaExpression_instances, "m", _EmissionCalculationFormulaExpression_guardAgainstInsecureContent).call(this, value);
19
40
  }
20
41
  }
21
42
  static create(value) {
@@ -24,20 +45,11 @@ class EmissionCalculationFormulaExpression extends String_1.String {
24
45
  return new _a(value, false);
25
46
  }
26
47
  static fromPrimitives(primitive) {
27
- const value = primitive;
28
- return new _a(value, true);
48
+ return new _a(primitive, true);
29
49
  }
30
50
  toPrimitives() {
31
51
  return this.value;
32
52
  }
33
- containsVariable(variableSymbol) {
34
- return this.value.includes(variableSymbol);
35
- }
36
- getVariableSymbols() {
37
- const variablePattern = /\b[A-Z][A-Z0-9]*\b/g;
38
- const matches = this.value.match(variablePattern) || [];
39
- return [...new Set(matches)].filter((match) => match !== 'EF' && match !== 'GWP');
40
- }
41
53
  }
42
54
  exports.EmissionCalculationFormulaExpression = EmissionCalculationFormulaExpression;
43
55
  _a = EmissionCalculationFormulaExpression, _EmissionCalculationFormulaExpression_instances = new WeakSet(), _EmissionCalculationFormulaExpression_guardAgainstInvalidLength = function _EmissionCalculationFormulaExpression_guardAgainstInvalidLength(value) {
@@ -47,24 +59,20 @@ _a = EmissionCalculationFormulaExpression, _EmissionCalculationFormulaExpression
47
59
  if (value.length > _a.MAX_LENGTH) {
48
60
  throw InvalidPropertyValueError_1.InvalidPropertyValueError.create(_a.PROPERTY_NAME, `at most ${_a.MAX_LENGTH} characters`, `${value.length} characters: "${value.substring(0, 50)}${value.length > 50 ? '...' : ''}"`);
49
61
  }
50
- }, _EmissionCalculationFormulaExpression_guardAgainstInvalidFormulaStructure = function _EmissionCalculationFormulaExpression_guardAgainstInvalidFormulaStructure(value) {
51
- const requiredComponents = ['EF', 'GWP'];
52
- for (const component of requiredComponents) {
53
- if (!value.includes(component)) {
54
- const componentName = component === 'EF' ? 'Emission Factor' : 'Global Warming Potential';
55
- throw InvalidPropertyValueError_1.InvalidPropertyValueError.create(_a.PROPERTY_NAME, `contain ${component} (${componentName})`, `missing required component: ${component}`);
56
- }
57
- }
58
- if (!value.includes('*') && !value.includes('×')) {
59
- throw InvalidPropertyValueError_1.InvalidPropertyValueError.create(_a.PROPERTY_NAME, 'contain multiplication operators (* or ×)', 'no multiplication operators found');
60
- }
61
- const forbiddenChars = ['<script>', '</script>', 'eval(', 'function('];
62
- for (const forbiddenChar of forbiddenChars) {
63
- if (value.toLowerCase().includes(forbiddenChar)) {
64
- throw InvalidPropertyValueError_1.InvalidPropertyValueError.create(_a.PROPERTY_NAME, 'safe formula content', `forbidden content found: ${forbiddenChar}`);
62
+ }, _EmissionCalculationFormulaExpression_guardAgainstInsecureContent = function _EmissionCalculationFormulaExpression_guardAgainstInsecureContent(value) {
63
+ const lowered = value.toLowerCase();
64
+ for (const forbidden of _a.FORBIDDEN_SUBSTRINGS) {
65
+ if (lowered.includes(forbidden)) {
66
+ throw InvalidPropertyValueError_1.InvalidPropertyValueError.create(_a.PROPERTY_NAME, 'safe formula content', `forbidden content found: ${forbidden}`);
65
67
  }
66
68
  }
67
69
  };
68
70
  EmissionCalculationFormulaExpression.PROPERTY_NAME = 'expression';
69
71
  EmissionCalculationFormulaExpression.MIN_LENGTH = 5;
70
72
  EmissionCalculationFormulaExpression.MAX_LENGTH = 2000;
73
+ EmissionCalculationFormulaExpression.FORBIDDEN_SUBSTRINGS = [
74
+ '<script>',
75
+ '</script>',
76
+ 'eval(',
77
+ 'function(',
78
+ ];
@@ -1,14 +1,34 @@
1
1
  import { String } from '../../../shared/domain/value-objects/String';
2
+ /**
3
+ * Domain value object for the formula expression string.
4
+ *
5
+ * The domain validates only what can be enforced without parsing the
6
+ * expression as math (the `@carbonbox/domain` package is zero-dependency
7
+ * by design — see CLAUDE.md):
8
+ *
9
+ * - Empty / type / length boundaries (storage invariants).
10
+ * - Defense-in-depth against script-injection-shaped substrings.
11
+ *
12
+ * The mathematical correctness of the expression — syntax, allowed
13
+ * functions, and that every referenced symbol is declared on the
14
+ * parent formula (variables + reserved `EF`/`GWP` tokens) — is a
15
+ * concern of the application layer, where `IFormulaValidationApplicationService`
16
+ * (backed by mathjs) parses the expression as a real AST.
17
+ *
18
+ * The handlers that build / activate / update a formula MUST run that
19
+ * application-side validation before constructing this VO. The VO does
20
+ * not assert it directly because doing so would require importing a
21
+ * mathematical parser into the pure domain layer.
22
+ */
2
23
  export declare class EmissionCalculationFormulaExpression extends String {
3
24
  #private;
4
25
  private static readonly PROPERTY_NAME;
5
26
  private static readonly MIN_LENGTH;
6
27
  private static readonly MAX_LENGTH;
28
+ private static readonly FORBIDDEN_SUBSTRINGS;
7
29
  private constructor();
8
30
  static create(value: string): EmissionCalculationFormulaExpression;
9
31
  static fromPrimitives(primitive: string): EmissionCalculationFormulaExpression;
10
32
  toPrimitives(): string;
11
- containsVariable(variableSymbol: string): boolean;
12
- getVariableSymbols(): string[];
13
33
  }
14
34
  //# sourceMappingURL=EmissionCalculationFormulaExpression.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EmissionCalculationFormulaExpression.d.ts","sourceRoot":"","sources":["../../../../../../src/carbonbox/emission-calculation-formulas/domain/value-objects/EmissionCalculationFormulaExpression.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,6CAA6C,CAAC;AAGrE,qBAAa,oCAAqC,SAAQ,MAAM;;IAC9D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAErD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAK;IAEvC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAQ;IAE1C,OAAO;WASgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,oCAAoC;WAO3D,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,oCAAoC;IAyD9E,YAAY,IAAI,MAAM;IAI/B,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO;IAIjD,kBAAkB,IAAI,MAAM,EAAE;CAKtC"}
1
+ {"version":3,"file":"EmissionCalculationFormulaExpression.d.ts","sourceRoot":"","sources":["../../../../../../src/carbonbox/emission-calculation-formulas/domain/value-objects/EmissionCalculationFormulaExpression.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,6CAA6C,CAAC;AAGrE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,oCAAqC,SAAQ,MAAM;;IAC9D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAErD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAK;IAEvC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAQ;IAE1C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAK1C;IAEF,OAAO;WASgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,oCAAoC;WAO3D,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,oCAAoC;IA0C9E,YAAY,IAAI,MAAM;CAGvC"}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "browser": false
4
4
  },
5
5
  "name": "@carbonbox/domain",
6
- "version": "0.8.6",
6
+ "version": "0.8.8",
7
7
  "description": "Domain package for CarbonBox Project",
8
8
  "main": "build/main/index.js",
9
9
  "types": "build/types/main/index.d.ts",