@daeda/mcp-pro 0.1.6 → 0.1.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.
Files changed (2) hide show
  1. package/dist/index.js +68 -11
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4224,11 +4224,13 @@ operationType MUST match the HubSpot property type:
4224
4224
  - MULTISTRING \u2192 for string properties (firstname, lastname, email, city, company, etc.). Operators: IS_EQUAL_TO, IS_NOT_EQUAL_TO, CONTAINS, DOES_NOT_CONTAIN, STARTS_WITH, ENDS_WITH.
4225
4225
  - NUMBER \u2192 for number properties. Operators: IS_EQUAL_TO, IS_NOT_EQUAL_TO, IS_BETWEEN, IS_GREATER_THAN, IS_LESS_THAN.
4226
4226
  - BOOL \u2192 for boolean properties. Operators: IS_EQUAL_TO, IS_NOT_EQUAL_TO.
4227
- - TIME_POINT \u2192 for date/datetime properties (single point comparison).
4228
- - TIME_RANGED \u2192 for date/datetime properties (range with lowerBoundTimePoint / upperBoundTimePoint).
4227
+ - TIME_POINT \u2192 for date/datetime properties (single point comparison). Operators: IS_AFTER, IS_BEFORE.
4228
+ - TIME_RANGED \u2192 for date/datetime properties (range). Operators: IS_BETWEEN. REQUIRED fields in the operation: lowerBoundEndpointBehavior, upperBoundEndpointBehavior, lowerBoundTimePoint, upperBoundTimePoint. Endpoint behaviors: lowerBoundEndpointBehavior is always "INCLUSIVE". upperBoundEndpointBehavior MUST be "EXCLUSIVE" when using referenceType "TODAY", and "INCLUSIVE" only when using referenceType "NOW". Offset format uses individual fields: { days: -90 } (NOT { unit: "DAY", amount: -90 }). For "last N days" ranges, use referenceType "TODAY" for the lower bound and "NOW" for the upper bound. Full TIME_RANGED "last 90 days" example: { operationType: "TIME_RANGED", operator: "IS_BETWEEN", lowerBoundEndpointBehavior: "INCLUSIVE", upperBoundEndpointBehavior: "INCLUSIVE", lowerBoundTimePoint: { timeType: "INDEXED", timezoneSource: "CUSTOM", zoneId: "US/Eastern", indexReference: { referenceType: "TODAY" }, offset: { days: -90 } }, upperBoundTimePoint: { timeType: "INDEXED", timezoneSource: "CUSTOM", zoneId: "US/Eastern", indexReference: { referenceType: "NOW" } } }.
4229
4229
  - ALL_PROPERTY \u2192 any property type. Operators: IS_KNOWN, IS_UNKNOWN, IS_BLANK, IS_NOT_BLANK. WARNING: IS_NOT_KNOWN is NOT valid \u2014 use IS_UNKNOWN instead.
4230
4230
  Enum filter example: { filterType: "PROPERTY", property: "lifecyclestage", operation: { operationType: "ENUMERATION", operator: "IS_ANY_OF", values: ["lead"] } }
4231
4231
 
4232
+ IMPORTANT: Some HubSpot properties are hidden and CANNOT be used in list filters. Hidden properties will cause an API error. Common hidden properties include hs_last_sales_activity_date \u2014 use hs_last_sales_activity_timestamp instead. If unsure whether a property is hidden, prefer well-known visible properties.
4233
+
4232
4234
  ASSOCIATION branches filter by associated records and MUST include these required fields:
4233
4235
  - filterBranchType: "ASSOCIATION"
4234
4236
  - objectTypeId: the associated object type ID (e.g. "0-3" for deals)
@@ -7116,6 +7118,51 @@ var collectPropertyFilters = (branches, parentObjectTypeId) => {
7116
7118
  }
7117
7119
  return refs;
7118
7120
  };
7121
+ var getUpperBoundRefType = (op) => {
7122
+ const upper = op.upperBoundTimePoint;
7123
+ if (!upper) return void 0;
7124
+ const ref = upper.indexReference;
7125
+ return ref?.referenceType;
7126
+ };
7127
+ var collectTimeRangeIssues = (branches, index) => {
7128
+ const issues = [];
7129
+ for (const branch of branches) {
7130
+ const filters = branch.filters;
7131
+ if (filters) {
7132
+ for (const f of filters) {
7133
+ const op = f.operation;
7134
+ if (op?.operationType === "TIME_RANGED") {
7135
+ const missing = [];
7136
+ if (op.lowerBoundEndpointBehavior == null) missing.push("lowerBoundEndpointBehavior");
7137
+ if (op.upperBoundEndpointBehavior == null) missing.push("upperBoundEndpointBehavior");
7138
+ if (missing.length > 0) {
7139
+ issues.push({
7140
+ severity: "error",
7141
+ operation_index: index,
7142
+ code: "INVALID_TIME_RANGE_ENDPOINT",
7143
+ message: `TIME_RANGED filter on '${f.property ?? "unknown"}' is missing required field(s): ${missing.join(", ")}. Set lowerBoundEndpointBehavior to "INCLUSIVE" and upperBoundEndpointBehavior to "EXCLUSIVE" (or "INCLUSIVE" only with referenceType "NOW").`
7144
+ });
7145
+ } else if (op.upperBoundEndpointBehavior === "INCLUSIVE") {
7146
+ const upperRef = getUpperBoundRefType(op);
7147
+ if (upperRef && upperRef !== "NOW") {
7148
+ issues.push({
7149
+ severity: "error",
7150
+ operation_index: index,
7151
+ code: "INVALID_TIME_RANGE_ENDPOINT",
7152
+ message: `TIME_RANGED filter on '${f.property ?? "unknown"}' has upperBoundEndpointBehavior "INCLUSIVE" but upper bound uses referenceType "${upperRef}". HubSpot only accepts "INCLUSIVE" with referenceType "NOW" \u2014 use "EXCLUSIVE" instead, or change the upper bound to referenceType "NOW".`
7153
+ });
7154
+ }
7155
+ }
7156
+ }
7157
+ }
7158
+ }
7159
+ const nested = branch.filterBranches;
7160
+ if (nested?.length) {
7161
+ issues.push(...collectTimeRangeIssues(nested, index));
7162
+ }
7163
+ }
7164
+ return issues;
7165
+ };
7119
7166
  var collectAssociationIssues = (branches, index) => {
7120
7167
  const issues = [];
7121
7168
  for (const branch of branches) {
@@ -7200,6 +7247,7 @@ var createListHandler = {
7200
7247
  }
7201
7248
  if (branches?.length) {
7202
7249
  issues.push(...collectAssociationIssues(branches, index));
7250
+ issues.push(...collectTimeRangeIssues(branches, index));
7203
7251
  }
7204
7252
  }
7205
7253
  }
@@ -7245,28 +7293,37 @@ var createListHandler = {
7245
7293
  )
7246
7294
  ),
7247
7295
  Effect53.map((results) => {
7248
- const propTypeByObject = /* @__PURE__ */ new Map();
7296
+ const propInfoByObject = /* @__PURE__ */ new Map();
7249
7297
  for (const [ot, defs] of results) {
7250
7298
  const m = /* @__PURE__ */ new Map();
7251
- for (const d of defs) m.set(d.name, d.type);
7252
- propTypeByObject.set(ot, m);
7299
+ for (const d of defs) m.set(d.name, { type: d.type, hidden: d.hidden });
7300
+ propInfoByObject.set(ot, m);
7253
7301
  }
7254
7302
  const issues = [];
7255
7303
  for (const ref of filterRefs) {
7256
- const propMap = propTypeByObject.get(ref.objectTypeId);
7304
+ const propMap = propInfoByObject.get(ref.objectTypeId);
7257
7305
  if (!propMap) continue;
7258
- const propType = propMap.get(ref.property);
7259
- if (!propType) continue;
7260
- const expected = OPERATION_TYPE_FOR_PROPERTY_TYPE[propType];
7306
+ const propInfo = propMap.get(ref.property);
7307
+ if (!propInfo) continue;
7308
+ if (propInfo.hidden) {
7309
+ issues.push({
7310
+ severity: "error",
7311
+ operation_index: index,
7312
+ code: "HIDDEN_PROPERTY_IN_FILTER",
7313
+ message: `Property '${ref.property}' is hidden and cannot be used in list filters. Use an alternative visible property instead.`
7314
+ });
7315
+ continue;
7316
+ }
7317
+ const expected = OPERATION_TYPE_FOR_PROPERTY_TYPE[propInfo.type];
7261
7318
  if (!expected) continue;
7262
7319
  if (ref.operationType === expected) continue;
7263
7320
  if (ref.operationType === "ALL_PROPERTY") continue;
7264
- if (ref.operationType === "TIME_RANGED" && (propType === "date" || propType === "datetime")) continue;
7321
+ if (ref.operationType === "TIME_RANGED" && (propInfo.type === "date" || propInfo.type === "datetime")) continue;
7265
7322
  issues.push({
7266
7323
  severity: "error",
7267
7324
  operation_index: index,
7268
7325
  code: "INVALID_OPERATION_TYPE",
7269
- message: `Property '${ref.property}' has type '${propType}' but filter uses operationType '${ref.operationType}'. Use '${expected}' instead.${propType === "enumeration" ? " For enumeration properties use operators like IS_ANY_OF, IS_NONE_OF (not IS_EQUAL_TO)." : ""}`
7326
+ message: `Property '${ref.property}' has type '${propInfo.type}' but filter uses operationType '${ref.operationType}'. Use '${expected}' instead.${propInfo.type === "enumeration" ? " For enumeration properties use operators like IS_ANY_OF, IS_NONE_OF (not IS_EQUAL_TO)." : ""}`
7270
7327
  });
7271
7328
  }
7272
7329
  return issues;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@daeda/mcp-pro",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "MCP server for HubSpot CRM — sync, query, and manage your portal data",
5
5
  "type": "module",
6
6
  "bin": {