@visus-io/notion-sdk-ts 3.2.0 → 3.3.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.
Files changed (42) hide show
  1. package/dist/api/blocks.api.d.ts +1083 -224
  2. package/dist/api/blocks.api.js +4 -0
  3. package/dist/api/comments.api.d.ts +19 -1
  4. package/dist/api/comments.api.js +1 -1
  5. package/dist/api/dataSources.api.d.ts +36 -0
  6. package/dist/api/databases.api.d.ts +36 -0
  7. package/dist/api/databases.api.js +1 -0
  8. package/dist/api/fileUploads.api.d.ts +17 -7
  9. package/dist/api/fileUploads.api.js +30 -16
  10. package/dist/api/pages.api.d.ts +50 -0
  11. package/dist/api/pages.api.js +5 -0
  12. package/dist/client.d.ts +64 -2
  13. package/dist/client.js +150 -36
  14. package/dist/errors.d.ts +36 -3
  15. package/dist/errors.js +59 -4
  16. package/dist/helpers/filter.helpers.d.ts +11 -4
  17. package/dist/helpers/filter.helpers.js +73 -30
  18. package/dist/helpers/pagination.helpers.d.ts +7 -2
  19. package/dist/helpers/pagination.helpers.js +26 -5
  20. package/dist/models/page.model.d.ts +20 -1
  21. package/dist/models/page.model.js +33 -2
  22. package/dist/schemas/block.schema.d.ts +1082 -224
  23. package/dist/schemas/block.schema.js +40 -25
  24. package/dist/schemas/comment.schema.d.ts +18 -0
  25. package/dist/schemas/dataSource.schema.d.ts +36 -0
  26. package/dist/schemas/database.schema.d.ts +36 -0
  27. package/dist/schemas/meetingNotesQuery.schema.d.ts +1082 -224
  28. package/dist/schemas/page.schema.d.ts +46 -0
  29. package/dist/schemas/page.schema.js +2 -1
  30. package/dist/schemas/pageMarkdown.schema.js +1 -1
  31. package/dist/schemas/pageProperties.schema.d.ts +99 -1
  32. package/dist/schemas/pageProperties.schema.js +16 -1
  33. package/dist/schemas/pagination.schema.d.ts +1 -1
  34. package/dist/schemas/propertyObjects.schema.js +2 -1
  35. package/dist/schemas/richText.schema.d.ts +36 -0
  36. package/dist/schemas/richText.schema.js +21 -0
  37. package/dist/schemas/shared.schema.d.ts +3 -7
  38. package/dist/schemas/shared.schema.js +5 -9
  39. package/dist/schemas/view.schema.d.ts +46 -0
  40. package/dist/validation.d.ts +8 -0
  41. package/dist/validation.js +16 -0
  42. package/package.json +2 -2
package/dist/client.js CHANGED
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NotionClient = exports.NOTION_VERSION = void 0;
4
4
  const errors_1 = require("./errors");
5
+ const validation_1 = require("./validation");
5
6
  /**
6
7
  * The Notion API version this SDK uses.
7
8
  * All schemas, request bodies, helpers, and models depend on this version.
@@ -9,6 +10,8 @@ const errors_1 = require("./errors");
9
10
  * @category Client & Core
10
11
  */
11
12
  exports.NOTION_VERSION = '2026-03-11';
13
+ /** Upper bound for a single retry wait, in milliseconds. */
14
+ const MAX_RETRY_DELAY_MS = 60_000;
12
15
  /**
13
16
  * Base HTTP client for Notion API requests.
14
17
  */
@@ -36,13 +39,18 @@ class NotionClient {
36
39
  return await this.makeRequest(options);
37
40
  }
38
41
  catch (error) {
39
- // Retry rate-limited requests (if enabled) and service-overload (529)
40
- // responses, which the API recommends always retrying.
42
+ // Retry per isRetryable(); retryOnRateLimit:false suppresses only HTTP 429
43
+ // (isRateLimited() is status-based, so this holds regardless of a
44
+ // malformed body's `code`). options.retryOnGatewayTimeout:false suppresses
45
+ // only HTTP 504; `status` is always authoritative there too (see
46
+ // handleErrorResponse()).
41
47
  if (error instanceof errors_1.NotionAPIError &&
42
- ((error.isRateLimited() && this.retryOnRateLimit) || error.isServiceOverloaded()) &&
48
+ error.isRetryable() &&
49
+ !(error.isRateLimited() && !this.retryOnRateLimit) &&
50
+ !(error.status === 504 && options.retryOnGatewayTimeout === false) &&
43
51
  attempt < this.maxRetries) {
44
- // Prefer the server-supplied Retry-After value; fall back to
45
- // exponential backoff when the header is absent.
52
+ // Prefer the server-supplied Retry-After value (header or body fallback);
53
+ // fall back to exponential backoff when neither is present or valid.
46
54
  const retryAfter = error.retryAfterMs ?? this.getRetryAfter(attempt);
47
55
  await this.sleep(retryAfter);
48
56
  lastError = error;
@@ -55,21 +63,46 @@ class NotionClient {
55
63
  // If we exhausted all retries, throw the last error
56
64
  throw lastError ?? new Error('Request failed after all retries');
57
65
  }
66
+ /**
67
+ * Send a `multipart/form-data` `POST` to a Notion file-upload URL. Reuses the
68
+ * configured `fetch` and the request timeout. Does not retry. Does not set
69
+ * `Content-Type`, so `fetch` adds the multipart boundary.
70
+ *
71
+ * @param uploadUrl - The absolute `upload_url` from `fileUploads.initiate()`.
72
+ * @param form - A `FormData` body with the file bytes under the `file` key.
73
+ * @throws {NotionValidationError} If `uploadUrl` is not a valid `https` URL.
74
+ * @throws {NotionAPIError} If the endpoint returns an error response.
75
+ * @throws {NotionRequestTimeoutError} If the request exceeds the timeout.
76
+ * @throws {NotionNetworkError} If a network problem blocks the request.
77
+ */
78
+ async sendFileUpload(uploadUrl, form) {
79
+ this.assertHttpsUrl(uploadUrl);
80
+ const { 'Content-Type': _contentType, ...headers } = this.requestHeaders;
81
+ try {
82
+ const response = await this.fetchWithTimeout(uploadUrl, {
83
+ method: 'POST',
84
+ headers,
85
+ body: form,
86
+ });
87
+ if (!response.ok) {
88
+ await this.handleErrorResponse(response);
89
+ }
90
+ }
91
+ catch (error) {
92
+ this.mapTransportError(error);
93
+ }
94
+ }
58
95
  /**
59
96
  * Send one HTTP request to the Notion API.
60
97
  */
61
98
  async makeRequest(options) {
62
99
  const url = this.buildUrl(options.path, options.query);
63
- const controller = new AbortController();
64
- const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
65
100
  try {
66
- const response = await this.fetchImpl(url, {
101
+ const response = await this.fetchWithTimeout(url, {
67
102
  method: options.method,
68
103
  headers: this.requestHeaders,
69
104
  body: options.body ? JSON.stringify(options.body) : undefined,
70
- signal: controller.signal,
71
105
  });
72
- clearTimeout(timeoutId);
73
106
  if (!response.ok) {
74
107
  await this.handleErrorResponse(response);
75
108
  }
@@ -81,18 +114,56 @@ class NotionClient {
81
114
  return data;
82
115
  }
83
116
  catch (error) {
117
+ this.mapTransportError(error);
118
+ }
119
+ }
120
+ /**
121
+ * Call the configured `fetch` with an abort timeout of `timeoutMs`.
122
+ * Clear the timer as soon as the response headers arrive or the request fails.
123
+ */
124
+ async fetchWithTimeout(url, init) {
125
+ const controller = new AbortController();
126
+ const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
127
+ try {
128
+ return await this.fetchImpl(url, { ...init, signal: controller.signal });
129
+ }
130
+ finally {
84
131
  clearTimeout(timeoutId);
85
- if (error instanceof errors_1.NotionAPIError) {
86
- throw error;
87
- }
88
- if (error instanceof Error) {
89
- if (error.name === 'AbortError') {
90
- throw new errors_1.NotionRequestTimeoutError(`Request timed out after ${this.timeoutMs}ms`);
91
- }
92
- throw new errors_1.NotionNetworkError('Network request failed', error);
93
- }
132
+ }
133
+ }
134
+ /**
135
+ * Map a transport-layer failure to the matching SDK error and throw it.
136
+ * Rethrow a `NotionAPIError` unchanged. Map an `AbortError` to
137
+ * `NotionRequestTimeoutError`. Map any other `Error` to `NotionNetworkError`.
138
+ */
139
+ mapTransportError(error) {
140
+ if (error instanceof errors_1.NotionAPIError) {
94
141
  throw error;
95
142
  }
143
+ if (error instanceof Error) {
144
+ if (error.name === 'AbortError') {
145
+ throw new errors_1.NotionRequestTimeoutError(`Request timed out after ${this.timeoutMs}ms`);
146
+ }
147
+ throw new errors_1.NotionNetworkError('Network request failed', error);
148
+ }
149
+ throw error;
150
+ }
151
+ /**
152
+ * Assert that `url` is a valid `https` URL. The SDK sends the API token in the
153
+ * `Authorization` header of a file upload. Reject a plaintext `http` URL so the
154
+ * token never travels unencrypted.
155
+ */
156
+ assertHttpsUrl(url) {
157
+ let protocol;
158
+ try {
159
+ protocol = new URL(url).protocol;
160
+ }
161
+ catch {
162
+ throw new validation_1.NotionValidationError(`Invalid file upload URL: ${url}`);
163
+ }
164
+ if (protocol !== 'https:') {
165
+ throw new validation_1.NotionValidationError(`File upload URL must use https, got "${protocol}"`);
166
+ }
96
167
  }
97
168
  /**
98
169
  * Calculate a fallback retry delay with exponential backoff.
@@ -101,7 +172,7 @@ class NotionClient {
101
172
  */
102
173
  getRetryAfter(attempt) {
103
174
  const backoffMs = Math.pow(2, attempt) * 1000;
104
- return Math.min(backoffMs, 60000); // Cap at 60 seconds
175
+ return Math.min(backoffMs, MAX_RETRY_DELAY_MS);
105
176
  }
106
177
  /**
107
178
  * Pause for the given duration, in milliseconds.
@@ -130,38 +201,81 @@ class NotionClient {
130
201
  return url.toString();
131
202
  }
132
203
  /**
133
- * Parse the `Retry-After` response header into milliseconds.
134
- * Return `undefined` if the header is missing or not a valid non-negative number.
204
+ * Convert a whole-seconds string into milliseconds, clamped to
205
+ * {@link MAX_RETRY_DELAY_MS}. `value` comes from an unvalidated header or
206
+ * JSON body, so this accepts `unknown`. Return `undefined` if it is not a
207
+ * non-blank string, or not a valid non-negative number.
135
208
  */
136
- parseRetryAfterHeader(response) {
137
- const header = response.headers.get('Retry-After');
138
- if (header === null) {
209
+ secondsToClampedMs(value) {
210
+ if (typeof value !== 'string' || value.trim() === '') {
139
211
  return undefined;
140
212
  }
141
- const seconds = Number(header);
213
+ const seconds = Number(value);
142
214
  if (!Number.isFinite(seconds) || seconds < 0) {
143
215
  return undefined;
144
216
  }
145
- return Math.ceil(seconds) * 1000;
217
+ return Math.min(Math.ceil(seconds) * 1000, MAX_RETRY_DELAY_MS);
218
+ }
219
+ /**
220
+ * Parse the `Retry-After` response header into milliseconds, clamped to
221
+ * {@link MAX_RETRY_DELAY_MS}. Return `undefined` if the header is missing,
222
+ * blank, or not a valid non-negative number.
223
+ */
224
+ parseRetryAfterHeader(response) {
225
+ return this.secondsToClampedMs(response.headers.get('Retry-After'));
226
+ }
227
+ /**
228
+ * Parse `additional_data.retry_after` from the error body into milliseconds,
229
+ * clamped to {@link MAX_RETRY_DELAY_MS}. The Notion API repeats the
230
+ * `Retry-After` value here for clients that cannot read response headers.
231
+ * Return `undefined` if the field is missing, blank, or not a valid
232
+ * non-negative number.
233
+ */
234
+ parseRetryAfterBody(errorBody) {
235
+ return this.secondsToClampedMs(errorBody.additional_data?.retry_after);
236
+ }
237
+ /**
238
+ * Check if `value` is a plain, non-null, non-array object. Use this to
239
+ * guard a cast from unvalidated JSON before treating it as a record.
240
+ */
241
+ isRecord(value) {
242
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
243
+ }
244
+ /**
245
+ * Build a generic error body for a response the SDK cannot parse into a
246
+ * {@link NotionErrorResponse}.
247
+ */
248
+ genericErrorBody(response) {
249
+ return {
250
+ object: 'error',
251
+ status: response.status,
252
+ code: 'internal_server_error',
253
+ message: response.statusText || 'Unknown error occurred',
254
+ };
146
255
  }
147
256
  /**
148
257
  * Handle an error response from the API.
149
258
  */
150
259
  async handleErrorResponse(response) {
151
- const retryAfterMs = this.parseRetryAfterHeader(response);
152
260
  let errorBody;
153
261
  try {
154
- errorBody = (await response.json());
262
+ const parsed = await response.json();
263
+ // A syntactically valid body can still be non-object JSON, such as `null`
264
+ // or a bare string. Fall back to a generic error body in that case too;
265
+ // otherwise assigning `status` below would throw.
266
+ errorBody = this.isRecord(parsed)
267
+ ? parsed
268
+ : this.genericErrorBody(response);
155
269
  }
156
270
  catch {
157
- // If we can't parse the error body, create a generic error
158
- errorBody = {
159
- object: 'error',
160
- status: response.status,
161
- code: 'internal_server_error',
162
- message: response.statusText || 'Unknown error occurred',
163
- };
271
+ // If the SDK cannot parse the error body, create a generic error
272
+ errorBody = this.genericErrorBody(response);
164
273
  }
274
+ // The HTTP response status is authoritative. A proxy or a malformed body
275
+ // can report a `status` field that disagrees with it, or omit it.
276
+ errorBody.status = response.status;
277
+ // Prefer the header. Use the body only when the header is missing or invalid.
278
+ const retryAfterMs = this.parseRetryAfterHeader(response) ?? this.parseRetryAfterBody(errorBody);
165
279
  throw new errors_1.NotionAPIError(errorBody, retryAfterMs);
166
280
  }
167
281
  }
package/dist/errors.d.ts CHANGED
@@ -3,7 +3,28 @@
3
3
  *
4
4
  * @category Errors
5
5
  */
6
- export type NotionErrorCode = 'invalid_json' | 'invalid_request_url' | 'invalid_request' | 'validation_error' | 'missing_version' | 'unauthorized' | 'restricted_resource' | 'object_not_found' | 'conflict_error' | 'rate_limited' | 'internal_server_error' | 'service_unavailable' | 'service_overload' | 'database_connection_unavailable' | 'gateway_timeout';
6
+ export declare const NOTION_ERROR_CODES: readonly ["invalid_json", "invalid_request_url", "invalid_request", "validation_error", "missing_version", "unauthorized", "restricted_resource", "object_not_found", "conflict_error", "rate_limited", "internal_server_error", "service_unavailable", "service_overload", "database_connection_unavailable", "gateway_timeout"];
7
+ /**
8
+ * Notion may add new error codes over time. Treat an unrecognized code the
9
+ * same as any other error response; read `status` to classify it.
10
+ *
11
+ * @category Errors
12
+ */
13
+ export type NotionErrorCode = (typeof NOTION_ERROR_CODES)[number] | (string & Record<never, never>);
14
+ /**
15
+ * Reasons the Notion API gives for a `rate_limited` response.
16
+ * Appears in `NotionErrorResponse.additional_data.rate_limit_reason`.
17
+ *
18
+ * @category Errors
19
+ */
20
+ export declare const RATE_LIMIT_REASONS: readonly ["public_api_request_rate_limit", "public_api_space_request_rate_limit", "public_api_endpoint_rate_limit", "mcp_tool_rate_limit", "collection_router_upstream_429", "public_api_request_blocked"];
21
+ /**
22
+ * Notion may add new reason strings over time. Treat an unrecognized value the
23
+ * same as any other `rate_limited` response.
24
+ *
25
+ * @category Errors
26
+ */
27
+ export type RateLimitReason = (typeof RATE_LIMIT_REASONS)[number] | (string & Record<never, never>);
7
28
  /**
8
29
  * Notion API error response structure.
9
30
  *
@@ -15,7 +36,12 @@ export interface NotionErrorResponse {
15
36
  code: NotionErrorCode;
16
37
  message: string;
17
38
  /** Extra machine-readable context for some error codes, for example `restricted_resource`. */
18
- additional_data?: Record<string, unknown>;
39
+ additional_data?: {
40
+ /** Present on `rate_limited` responses. Duplicates `Retry-After` as whole seconds. */
41
+ retry_after?: string;
42
+ /** Present on `rate_limited` responses. Identifies why the API rate-limited the request. */
43
+ rate_limit_reason?: RateLimitReason;
44
+ } & Record<string, unknown>;
19
45
  }
20
46
  /**
21
47
  * Thrown when the Notion API returns an error response.
@@ -27,9 +53,14 @@ export declare class NotionAPIError extends Error {
27
53
  readonly code: NotionErrorCode;
28
54
  readonly body: NotionErrorResponse;
29
55
  readonly retryAfterMs?: number;
56
+ readonly rateLimitReason?: RateLimitReason;
30
57
  constructor(response: NotionErrorResponse, retryAfterMs?: number);
31
58
  /**
32
- * Check if the error is a rate limit error.
59
+ * Check if the error is a rate limit error (HTTP 429).
60
+ * Check `status`, not `code`. A malformed body could report the wrong
61
+ * `code` for a real 429, or report `rate_limited` for a real non-429
62
+ * status. `status` always matches the real HTTP response. See
63
+ * `NotionClient.handleErrorResponse()`.
33
64
  */
34
65
  isRateLimited(): boolean;
35
66
  /**
@@ -59,6 +90,8 @@ export declare class NotionAPIError extends Error {
59
90
  isServerError(): boolean;
60
91
  /**
61
92
  * Check if the error is retryable (rate limit or server error).
93
+ * A `429` is not retryable when `rateLimitReason` is `public_api_request_blocked`,
94
+ * since the request cannot succeed.
62
95
  */
63
96
  isRetryable(): boolean;
64
97
  }
package/dist/errors.js CHANGED
@@ -1,6 +1,42 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.NotionNetworkError = exports.NotionRequestTimeoutError = exports.NotionAPIError = void 0;
3
+ exports.NotionNetworkError = exports.NotionRequestTimeoutError = exports.NotionAPIError = exports.RATE_LIMIT_REASONS = exports.NOTION_ERROR_CODES = void 0;
4
+ /**
5
+ * Notion API error codes based on official documentation.
6
+ *
7
+ * @category Errors
8
+ */
9
+ exports.NOTION_ERROR_CODES = [
10
+ 'invalid_json',
11
+ 'invalid_request_url',
12
+ 'invalid_request',
13
+ 'validation_error',
14
+ 'missing_version',
15
+ 'unauthorized',
16
+ 'restricted_resource',
17
+ 'object_not_found',
18
+ 'conflict_error',
19
+ 'rate_limited',
20
+ 'internal_server_error',
21
+ 'service_unavailable',
22
+ 'service_overload',
23
+ 'database_connection_unavailable',
24
+ 'gateway_timeout',
25
+ ];
26
+ /**
27
+ * Reasons the Notion API gives for a `rate_limited` response.
28
+ * Appears in `NotionErrorResponse.additional_data.rate_limit_reason`.
29
+ *
30
+ * @category Errors
31
+ */
32
+ exports.RATE_LIMIT_REASONS = [
33
+ 'public_api_request_rate_limit',
34
+ 'public_api_space_request_rate_limit',
35
+ 'public_api_endpoint_rate_limit',
36
+ 'mcp_tool_rate_limit',
37
+ 'collection_router_upstream_429',
38
+ 'public_api_request_blocked',
39
+ ];
4
40
  /**
5
41
  * Thrown when the Notion API returns an error response.
6
42
  *
@@ -11,19 +47,33 @@ class NotionAPIError extends Error {
11
47
  super(response.message);
12
48
  this.name = 'NotionAPIError';
13
49
  this.status = response.status;
14
- this.code = response.code;
15
50
  this.body = response;
16
51
  this.retryAfterMs = retryAfterMs;
52
+ // response comes from an unvalidated JSON body cast to NotionErrorResponse, so
53
+ // `code` could be any JSON type at runtime despite its string type. Check the
54
+ // runtime type before exposing it. Fall back to a generic code; `status` stays
55
+ // the authoritative field for classifying the error.
56
+ const rawCode = response.code;
57
+ this.code = typeof rawCode === 'string' ? rawCode : 'internal_server_error';
58
+ // additional_data comes from the same unvalidated body, so rate_limit_reason
59
+ // could likewise be any JSON type at runtime despite its string type. Check
60
+ // the runtime type before exposing it on this public property.
61
+ const rawRateLimitReason = response.additional_data?.rate_limit_reason;
62
+ this.rateLimitReason = typeof rawRateLimitReason === 'string' ? rawRateLimitReason : undefined;
17
63
  // Maintain proper stack trace for V8 engines
18
64
  if ('captureStackTrace' in Error) {
19
65
  Error.captureStackTrace(this, NotionAPIError);
20
66
  }
21
67
  }
22
68
  /**
23
- * Check if the error is a rate limit error.
69
+ * Check if the error is a rate limit error (HTTP 429).
70
+ * Check `status`, not `code`. A malformed body could report the wrong
71
+ * `code` for a real 429, or report `rate_limited` for a real non-429
72
+ * status. `status` always matches the real HTTP response. See
73
+ * `NotionClient.handleErrorResponse()`.
24
74
  */
25
75
  isRateLimited() {
26
- return this.code === 'rate_limited';
76
+ return this.status === 429;
27
77
  }
28
78
  /**
29
79
  * Check if the error is a service overload error (HTTP 529).
@@ -64,8 +114,13 @@ class NotionAPIError extends Error {
64
114
  }
65
115
  /**
66
116
  * Check if the error is retryable (rate limit or server error).
117
+ * A `429` is not retryable when `rateLimitReason` is `public_api_request_blocked`,
118
+ * since the request cannot succeed.
67
119
  */
68
120
  isRetryable() {
121
+ if (this.isRateLimited() && this.rateLimitReason === 'public_api_request_blocked') {
122
+ return false;
123
+ }
69
124
  return this.isRateLimited() || this.isServerError();
70
125
  }
71
126
  }
@@ -4,7 +4,9 @@ type FilterCondition = Record<string, unknown>;
4
4
  declare class TextFilter {
5
5
  private readonly property;
6
6
  private readonly propertyType;
7
- constructor(property: string, propertyType: string);
7
+ private readonly isFormula;
8
+ constructor(property: string, propertyType: string, isFormula?: boolean);
9
+ private build;
8
10
  equals(value: string): FilterCondition;
9
11
  doesNotEqual(value: string): FilterCondition;
10
12
  contains(value: string): FilterCondition;
@@ -17,7 +19,9 @@ declare class TextFilter {
17
19
  /** Operators for number properties. */
18
20
  declare class NumberFilter {
19
21
  private readonly property;
20
- constructor(property: string);
22
+ private readonly isFormula;
23
+ constructor(property: string, isFormula?: boolean);
24
+ private build;
21
25
  equals(value: number): FilterCondition;
22
26
  doesNotEqual(value: number): FilterCondition;
23
27
  greaterThan(value: number): FilterCondition;
@@ -30,7 +34,9 @@ declare class NumberFilter {
30
34
  /** Operators for checkbox properties. */
31
35
  declare class CheckboxFilter {
32
36
  private readonly property;
33
- constructor(property: string);
37
+ private readonly isFormula;
38
+ constructor(property: string, isFormula?: boolean);
39
+ private build;
34
40
  equals(value: boolean): FilterCondition;
35
41
  doesNotEqual(value: boolean): FilterCondition;
36
42
  }
@@ -65,7 +71,8 @@ declare class StatusFilter {
65
71
  declare class DateFilter {
66
72
  private readonly key;
67
73
  private readonly isTimestamp;
68
- constructor(key: string, isTimestamp: boolean);
74
+ private readonly isFormula;
75
+ constructor(key: string, isTimestamp: boolean, isFormula?: boolean);
69
76
  private wrap;
70
77
  equals(value: string): FilterCondition;
71
78
  before(value: string): FilterCondition;