@tinybirdco/sdk 0.0.44 → 0.0.46

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 (86) hide show
  1. package/README.md +61 -8
  2. package/dist/api/api.d.ts.map +1 -1
  3. package/dist/api/api.js +8 -3
  4. package/dist/api/api.js.map +1 -1
  5. package/dist/api/api.test.js +24 -6
  6. package/dist/api/api.test.js.map +1 -1
  7. package/dist/cli/commands/migrate.d.ts.map +1 -1
  8. package/dist/cli/commands/migrate.js +4 -3
  9. package/dist/cli/commands/migrate.js.map +1 -1
  10. package/dist/cli/commands/migrate.test.js +42 -4
  11. package/dist/cli/commands/migrate.test.js.map +1 -1
  12. package/dist/client/base.d.ts +1 -1
  13. package/dist/client/base.js +1 -1
  14. package/dist/generator/connection.d.ts +1 -1
  15. package/dist/generator/connection.d.ts.map +1 -1
  16. package/dist/generator/connection.js +25 -2
  17. package/dist/generator/connection.js.map +1 -1
  18. package/dist/generator/connection.test.js +37 -14
  19. package/dist/generator/connection.test.js.map +1 -1
  20. package/dist/generator/datasource.d.ts.map +1 -1
  21. package/dist/generator/datasource.js +23 -0
  22. package/dist/generator/datasource.js.map +1 -1
  23. package/dist/generator/datasource.test.js +53 -9
  24. package/dist/generator/datasource.test.js.map +1 -1
  25. package/dist/index.d.ts +3 -3
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +1 -1
  28. package/dist/index.js.map +1 -1
  29. package/dist/infer/index.d.ts +3 -3
  30. package/dist/migrate/emit-ts.d.ts.map +1 -1
  31. package/dist/migrate/emit-ts.js +69 -13
  32. package/dist/migrate/emit-ts.js.map +1 -1
  33. package/dist/migrate/parse-connection.d.ts +2 -2
  34. package/dist/migrate/parse-connection.d.ts.map +1 -1
  35. package/dist/migrate/parse-connection.js +61 -18
  36. package/dist/migrate/parse-connection.js.map +1 -1
  37. package/dist/migrate/parse-datasource.d.ts.map +1 -1
  38. package/dist/migrate/parse-datasource.js +31 -0
  39. package/dist/migrate/parse-datasource.js.map +1 -1
  40. package/dist/migrate/types.d.ts +18 -1
  41. package/dist/migrate/types.d.ts.map +1 -1
  42. package/dist/schema/connection.d.ts +49 -6
  43. package/dist/schema/connection.d.ts.map +1 -1
  44. package/dist/schema/connection.js +44 -9
  45. package/dist/schema/connection.js.map +1 -1
  46. package/dist/schema/connection.test.js +72 -17
  47. package/dist/schema/connection.test.js.map +1 -1
  48. package/dist/schema/datasource.d.ts +16 -1
  49. package/dist/schema/datasource.d.ts.map +1 -1
  50. package/dist/schema/datasource.js +3 -0
  51. package/dist/schema/datasource.js.map +1 -1
  52. package/dist/schema/datasource.test.js +21 -0
  53. package/dist/schema/datasource.test.js.map +1 -1
  54. package/dist/schema/params.d.ts +3 -3
  55. package/dist/schema/params.d.ts.map +1 -1
  56. package/dist/schema/params.js +3 -3
  57. package/dist/schema/params.js.map +1 -1
  58. package/dist/schema/project.d.ts +3 -3
  59. package/dist/schema/project.js +3 -3
  60. package/dist/schema/types.d.ts +8 -8
  61. package/dist/schema/types.d.ts.map +1 -1
  62. package/dist/schema/types.js +4 -4
  63. package/dist/schema/types.js.map +1 -1
  64. package/package.json +1 -1
  65. package/src/api/api.test.ts +32 -6
  66. package/src/api/api.ts +14 -3
  67. package/src/cli/commands/migrate.test.ts +58 -4
  68. package/src/cli/commands/migrate.ts +6 -4
  69. package/src/client/base.ts +1 -1
  70. package/src/generator/connection.test.ts +45 -14
  71. package/src/generator/connection.ts +30 -2
  72. package/src/generator/datasource.test.ts +61 -9
  73. package/src/generator/datasource.ts +38 -1
  74. package/src/index.ts +12 -1
  75. package/src/infer/index.ts +3 -3
  76. package/src/migrate/emit-ts.ts +80 -16
  77. package/src/migrate/parse-connection.ts +108 -30
  78. package/src/migrate/parse-datasource.ts +46 -1
  79. package/src/migrate/types.ts +24 -2
  80. package/src/schema/connection.test.ts +92 -17
  81. package/src/schema/connection.ts +86 -10
  82. package/src/schema/datasource.test.ts +25 -0
  83. package/src/schema/datasource.ts +21 -1
  84. package/src/schema/params.ts +3 -3
  85. package/src/schema/project.ts +3 -3
  86. package/src/schema/types.ts +10 -10
@@ -1,15 +1,17 @@
1
1
  import { describe, it, expect } from "vitest";
2
2
  import {
3
- createKafkaConnection,
3
+ defineKafkaConnection,
4
+ defineS3Connection,
4
5
  isConnectionDefinition,
5
6
  isKafkaConnectionDefinition,
7
+ isS3ConnectionDefinition,
6
8
  getConnectionType,
7
9
  } from "./connection.js";
8
10
 
9
11
  describe("Connection Schema", () => {
10
- describe("createKafkaConnection", () => {
12
+ describe("defineKafkaConnection", () => {
11
13
  it("creates a Kafka connection with required fields", () => {
12
- const conn = createKafkaConnection("my_kafka", {
14
+ const conn = defineKafkaConnection("my_kafka", {
13
15
  bootstrapServers: "kafka.example.com:9092",
14
16
  });
15
17
 
@@ -20,7 +22,7 @@ describe("Connection Schema", () => {
20
22
  });
21
23
 
22
24
  it("creates a Kafka connection with all options", () => {
23
- const conn = createKafkaConnection("my_kafka", {
25
+ const conn = defineKafkaConnection("my_kafka", {
24
26
  bootstrapServers: "kafka.example.com:9092",
25
27
  securityProtocol: "SASL_SSL",
26
28
  saslMechanism: "PLAIN",
@@ -37,19 +39,19 @@ describe("Connection Schema", () => {
37
39
  });
38
40
 
39
41
  it("supports different SASL mechanisms", () => {
40
- const scramConn = createKafkaConnection("scram_kafka", {
42
+ const scramConn = defineKafkaConnection("scram_kafka", {
41
43
  bootstrapServers: "kafka.example.com:9092",
42
44
  saslMechanism: "SCRAM-SHA-256",
43
45
  });
44
46
  expect(scramConn.options.saslMechanism).toBe("SCRAM-SHA-256");
45
47
 
46
- const scram512Conn = createKafkaConnection("scram512_kafka", {
48
+ const scram512Conn = defineKafkaConnection("scram512_kafka", {
47
49
  bootstrapServers: "kafka.example.com:9092",
48
50
  saslMechanism: "SCRAM-SHA-512",
49
51
  });
50
52
  expect(scram512Conn.options.saslMechanism).toBe("SCRAM-SHA-512");
51
53
 
52
- const oauthConn = createKafkaConnection("oauth_kafka", {
54
+ const oauthConn = defineKafkaConnection("oauth_kafka", {
53
55
  bootstrapServers: "kafka.example.com:9092",
54
56
  saslMechanism: "OAUTHBEARER",
55
57
  });
@@ -57,13 +59,13 @@ describe("Connection Schema", () => {
57
59
  });
58
60
 
59
61
  it("supports different security protocols", () => {
60
- const plaintext = createKafkaConnection("plaintext_kafka", {
62
+ const plaintext = defineKafkaConnection("plaintext_kafka", {
61
63
  bootstrapServers: "localhost:9092",
62
64
  securityProtocol: "PLAINTEXT",
63
65
  });
64
66
  expect(plaintext.options.securityProtocol).toBe("PLAINTEXT");
65
67
 
66
- const saslPlaintext = createKafkaConnection("sasl_plaintext_kafka", {
68
+ const saslPlaintext = defineKafkaConnection("sasl_plaintext_kafka", {
67
69
  bootstrapServers: "localhost:9092",
68
70
  securityProtocol: "SASL_PLAINTEXT",
69
71
  });
@@ -72,40 +74,88 @@ describe("Connection Schema", () => {
72
74
 
73
75
  it("throws error for invalid connection name", () => {
74
76
  expect(() =>
75
- createKafkaConnection("123invalid", {
77
+ defineKafkaConnection("123invalid", {
76
78
  bootstrapServers: "kafka.example.com:9092",
77
79
  })
78
80
  ).toThrow("Invalid connection name");
79
81
 
80
82
  expect(() =>
81
- createKafkaConnection("my-connection", {
83
+ defineKafkaConnection("my-connection", {
82
84
  bootstrapServers: "kafka.example.com:9092",
83
85
  })
84
86
  ).toThrow("Invalid connection name");
85
87
 
86
88
  expect(() =>
87
- createKafkaConnection("", {
89
+ defineKafkaConnection("", {
88
90
  bootstrapServers: "kafka.example.com:9092",
89
91
  })
90
92
  ).toThrow("Invalid connection name");
91
93
  });
92
94
 
93
95
  it("allows valid naming patterns", () => {
94
- const conn1 = createKafkaConnection("_private_kafka", {
96
+ const conn1 = defineKafkaConnection("_private_kafka", {
95
97
  bootstrapServers: "kafka.example.com:9092",
96
98
  });
97
99
  expect(conn1._name).toBe("_private_kafka");
98
100
 
99
- const conn2 = createKafkaConnection("kafka_v2", {
101
+ const conn2 = defineKafkaConnection("kafka_v2", {
100
102
  bootstrapServers: "kafka.example.com:9092",
101
103
  });
102
104
  expect(conn2._name).toBe("kafka_v2");
103
105
  });
104
106
  });
105
107
 
108
+ describe("defineS3Connection", () => {
109
+ it("creates an S3 connection with IAM role auth", () => {
110
+ const conn = defineS3Connection("my_s3", {
111
+ region: "us-east-1",
112
+ arn: "arn:aws:iam::123456789012:role/tinybird-s3-access",
113
+ });
114
+
115
+ expect(conn._name).toBe("my_s3");
116
+ expect(conn._type).toBe("connection");
117
+ expect(conn._connectionType).toBe("s3");
118
+ expect(conn.options.region).toBe("us-east-1");
119
+ expect(conn.options.arn).toBe("arn:aws:iam::123456789012:role/tinybird-s3-access");
120
+ });
121
+
122
+ it("creates an S3 connection with access key auth", () => {
123
+ const conn = defineS3Connection("my_s3", {
124
+ region: "us-east-1",
125
+ accessKey: '{{ tb_secret("S3_ACCESS_KEY") }}',
126
+ secret: '{{ tb_secret("S3_SECRET") }}',
127
+ });
128
+
129
+ expect(conn.options.accessKey).toBe('{{ tb_secret("S3_ACCESS_KEY") }}');
130
+ expect(conn.options.secret).toBe('{{ tb_secret("S3_SECRET") }}');
131
+ });
132
+
133
+ it("throws when auth config is incomplete", () => {
134
+ expect(() =>
135
+ defineS3Connection("my_s3", {
136
+ region: "us-east-1",
137
+ })
138
+ ).toThrow("S3 connection requires either `arn` or both `accessKey` and `secret`.");
139
+
140
+ expect(() =>
141
+ defineS3Connection("my_s3", {
142
+ region: "us-east-1",
143
+ accessKey: "key-only",
144
+ })
145
+ ).toThrow("S3 connection requires either `arn` or both `accessKey` and `secret`.");
146
+
147
+ expect(() =>
148
+ defineS3Connection("my_s3", {
149
+ region: "us-east-1",
150
+ secret: "secret-only",
151
+ })
152
+ ).toThrow("S3 connection requires either `arn` or both `accessKey` and `secret`.");
153
+ });
154
+ });
155
+
106
156
  describe("isConnectionDefinition", () => {
107
157
  it("returns true for valid connection", () => {
108
- const conn = createKafkaConnection("my_kafka", {
158
+ const conn = defineKafkaConnection("my_kafka", {
109
159
  bootstrapServers: "kafka.example.com:9092",
110
160
  });
111
161
 
@@ -124,7 +174,7 @@ describe("Connection Schema", () => {
124
174
 
125
175
  describe("isKafkaConnectionDefinition", () => {
126
176
  it("returns true for Kafka connection", () => {
127
- const conn = createKafkaConnection("my_kafka", {
177
+ const conn = defineKafkaConnection("my_kafka", {
128
178
  bootstrapServers: "kafka.example.com:9092",
129
179
  });
130
180
 
@@ -137,13 +187,38 @@ describe("Connection Schema", () => {
137
187
  });
138
188
  });
139
189
 
190
+ describe("isS3ConnectionDefinition", () => {
191
+ it("returns true for S3 connection", () => {
192
+ const conn = defineS3Connection("my_s3", {
193
+ region: "us-east-1",
194
+ arn: "arn:aws:iam::123456789012:role/tinybird-s3-access",
195
+ });
196
+
197
+ expect(isS3ConnectionDefinition(conn)).toBe(true);
198
+ });
199
+
200
+ it("returns false for non-S3 objects", () => {
201
+ expect(isS3ConnectionDefinition({})).toBe(false);
202
+ expect(isS3ConnectionDefinition(null)).toBe(false);
203
+ });
204
+ });
205
+
140
206
  describe("getConnectionType", () => {
141
207
  it("returns the connection type", () => {
142
- const conn = createKafkaConnection("my_kafka", {
208
+ const conn = defineKafkaConnection("my_kafka", {
143
209
  bootstrapServers: "kafka.example.com:9092",
144
210
  });
145
211
 
146
212
  expect(getConnectionType(conn)).toBe("kafka");
147
213
  });
214
+
215
+ it("returns the s3 connection type", () => {
216
+ const conn = defineS3Connection("my_s3", {
217
+ region: "us-east-1",
218
+ arn: "arn:aws:iam::123456789012:role/tinybird-s3-access",
219
+ });
220
+
221
+ expect(getConnectionType(conn)).toBe("s3");
222
+ });
148
223
  });
149
224
  });
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Connection definition for Tinybird
3
- * Define external connections (Kafka, etc.) as TypeScript with full type safety
3
+ * Define external connections (Kafka, S3, etc.) as TypeScript with full type safety
4
4
  */
5
5
 
6
6
  // Symbol for brand typing - use Symbol.for() for global registry
@@ -50,13 +50,50 @@ export interface KafkaConnectionDefinition {
50
50
  readonly options: KafkaConnectionOptions;
51
51
  }
52
52
 
53
+ /**
54
+ * Options for defining an S3 connection
55
+ */
56
+ export interface S3ConnectionOptions {
57
+ /** S3 bucket region (for example: us-east-1) */
58
+ region: string;
59
+ /** IAM role ARN used by Tinybird to access the bucket */
60
+ arn?: string;
61
+ /** S3 access key for key/secret auth */
62
+ accessKey?: string;
63
+ /** S3 secret key for key/secret auth */
64
+ secret?: string;
65
+ }
66
+
67
+ /**
68
+ * S3-specific connection definition
69
+ */
70
+ export interface S3ConnectionDefinition {
71
+ readonly [CONNECTION_BRAND]: true;
72
+ /** Connection name */
73
+ readonly _name: string;
74
+ /** Type marker for inference */
75
+ readonly _type: "connection";
76
+ /** Connection type */
77
+ readonly _connectionType: "s3";
78
+ /** S3 options */
79
+ readonly options: S3ConnectionOptions;
80
+ }
81
+
53
82
  /**
54
83
  * A connection definition - union of all connection types
55
84
  */
56
- export type ConnectionDefinition = KafkaConnectionDefinition;
85
+ export type ConnectionDefinition = KafkaConnectionDefinition | S3ConnectionDefinition;
86
+
87
+ function validateConnectionName(name: string): void {
88
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {
89
+ throw new Error(
90
+ `Invalid connection name: "${name}". Must start with a letter or underscore and contain only alphanumeric characters and underscores.`
91
+ );
92
+ }
93
+ }
57
94
 
58
95
  /**
59
- * Create a Kafka connection
96
+ * Define a Kafka connection
60
97
  *
61
98
  * @param name - The connection name (must be valid identifier)
62
99
  * @param options - Kafka connection configuration
@@ -64,9 +101,9 @@ export type ConnectionDefinition = KafkaConnectionDefinition;
64
101
  *
65
102
  * @example
66
103
  * ```ts
67
- * import { createKafkaConnection } from '@tinybirdco/sdk';
104
+ * import { defineKafkaConnection } from '@tinybirdco/sdk';
68
105
  *
69
- * export const myKafka = createKafkaConnection('my_kafka', {
106
+ * export const myKafka = defineKafkaConnection('my_kafka', {
70
107
  * bootstrapServers: 'kafka.example.com:9092',
71
108
  * securityProtocol: 'SASL_SSL',
72
109
  * saslMechanism: 'PLAIN',
@@ -75,22 +112,54 @@ export type ConnectionDefinition = KafkaConnectionDefinition;
75
112
  * });
76
113
  * ```
77
114
  */
78
- export function createKafkaConnection(
115
+ export function defineKafkaConnection(
79
116
  name: string,
80
117
  options: KafkaConnectionOptions
81
118
  ): KafkaConnectionDefinition {
82
- // Validate name is a valid identifier
83
- if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {
119
+ validateConnectionName(name);
120
+
121
+ return {
122
+ [CONNECTION_BRAND]: true,
123
+ _name: name,
124
+ _type: "connection",
125
+ _connectionType: "kafka",
126
+ options,
127
+ };
128
+ }
129
+
130
+ /**
131
+ * @deprecated Use defineKafkaConnection instead.
132
+ */
133
+ export const createKafkaConnection = defineKafkaConnection;
134
+
135
+ /**
136
+ * Define an S3 connection
137
+ *
138
+ * @param name - The connection name (must be valid identifier)
139
+ * @param options - S3 connection configuration
140
+ * @returns A connection definition that can be used in a project
141
+ */
142
+ export function defineS3Connection(
143
+ name: string,
144
+ options: S3ConnectionOptions
145
+ ): S3ConnectionDefinition {
146
+ validateConnectionName(name);
147
+
148
+ if (!options.arn && !(options.accessKey && options.secret)) {
84
149
  throw new Error(
85
- `Invalid connection name: "${name}". Must start with a letter or underscore and contain only alphanumeric characters and underscores.`
150
+ "S3 connection requires either `arn` or both `accessKey` and `secret`."
86
151
  );
87
152
  }
88
153
 
154
+ if ((options.accessKey && !options.secret) || (!options.accessKey && options.secret)) {
155
+ throw new Error("S3 connection `accessKey` and `secret` must be provided together.");
156
+ }
157
+
89
158
  return {
90
159
  [CONNECTION_BRAND]: true,
91
160
  _name: name,
92
161
  _type: "connection",
93
- _connectionType: "kafka",
162
+ _connectionType: "s3",
94
163
  options,
95
164
  };
96
165
  }
@@ -114,6 +183,13 @@ export function isKafkaConnectionDefinition(value: unknown): value is KafkaConne
114
183
  return isConnectionDefinition(value) && value._connectionType === "kafka";
115
184
  }
116
185
 
186
+ /**
187
+ * Check if a value is an S3 connection definition
188
+ */
189
+ export function isS3ConnectionDefinition(value: unknown): value is S3ConnectionDefinition {
190
+ return isConnectionDefinition(value) && value._connectionType === "s3";
191
+ }
192
+
117
193
  /**
118
194
  * Get the connection type from a connection definition
119
195
  */
@@ -9,6 +9,7 @@ import {
9
9
  } from "./datasource.js";
10
10
  import { t } from "./types.js";
11
11
  import { engine } from "./engines.js";
12
+ import { defineKafkaConnection, defineS3Connection } from "./connection.js";
12
13
 
13
14
  describe("Datasource Schema", () => {
14
15
  describe("defineDatasource", () => {
@@ -85,6 +86,30 @@ describe("Datasource Schema", () => {
85
86
  });
86
87
  expect(ds2._name).toBe("events_v2");
87
88
  });
89
+
90
+ it("throws when both kafka and s3 ingestion are configured", () => {
91
+ const kafkaConn = defineKafkaConnection("my_kafka", {
92
+ bootstrapServers: "kafka.example.com:9092",
93
+ });
94
+ const s3Conn = defineS3Connection("my_s3", {
95
+ region: "us-east-1",
96
+ arn: "arn:aws:iam::123456789012:role/tinybird-s3-access",
97
+ });
98
+
99
+ expect(() =>
100
+ defineDatasource("events", {
101
+ schema: { id: t.string() },
102
+ kafka: {
103
+ connection: kafkaConn,
104
+ topic: "events",
105
+ },
106
+ s3: {
107
+ connection: s3Conn,
108
+ bucketUri: "s3://my-bucket/events/*.csv",
109
+ },
110
+ })
111
+ ).toThrow("Datasource cannot define both `kafka` and `s3` ingestion options.");
112
+ });
88
113
  });
89
114
 
90
115
  describe("isDatasourceDefinition", () => {
@@ -5,7 +5,7 @@
5
5
 
6
6
  import type { AnyTypeValidator } from "./types.js";
7
7
  import type { EngineConfig } from "./engines.js";
8
- import type { KafkaConnectionDefinition } from "./connection.js";
8
+ import type { KafkaConnectionDefinition, S3ConnectionDefinition } from "./connection.js";
9
9
  import type { TokenDefinition, DatasourceTokenScope } from "./token.js";
10
10
 
11
11
  // Symbol for brand typing - use Symbol.for() for global registry
@@ -68,6 +68,20 @@ export interface KafkaConfig {
68
68
  autoOffsetReset?: "earliest" | "latest";
69
69
  }
70
70
 
71
+ /**
72
+ * S3 import configuration for a datasource
73
+ */
74
+ export interface S3Config {
75
+ /** S3 connection to use */
76
+ connection: S3ConnectionDefinition;
77
+ /** S3 bucket URI, for example: s3://my-bucket/path/*.csv */
78
+ bucketUri: string;
79
+ /** Import schedule, for example: @auto or @once */
80
+ schedule?: string;
81
+ /** Incremental import lower bound timestamp expression */
82
+ fromTimestamp?: string;
83
+ }
84
+
71
85
  /**
72
86
  * Options for defining a datasource
73
87
  */
@@ -95,6 +109,8 @@ export interface DatasourceOptions<TSchema extends SchemaDefinition> {
95
109
  forwardQuery?: string;
96
110
  /** Kafka ingestion configuration */
97
111
  kafka?: KafkaConfig;
112
+ /** S3 ingestion configuration */
113
+ s3?: S3Config;
98
114
  }
99
115
 
100
116
  /**
@@ -152,6 +168,10 @@ export function defineDatasource<TSchema extends SchemaDefinition>(
152
168
  );
153
169
  }
154
170
 
171
+ if (options.kafka && options.s3) {
172
+ throw new Error("Datasource cannot define both `kafka` and `s3` ingestion options.");
173
+ }
174
+
155
175
  return {
156
176
  [DATASOURCE_BRAND]: true,
157
177
  _name: name,
@@ -173,13 +173,13 @@ export const p = {
173
173
 
174
174
  // ============ Date/Time Types ============
175
175
 
176
- /** Date parameter (YYYY-MM-DD format) */
176
+ /** Date parameter (YYYY-MM-DD format, e.g. 2024-01-15) */
177
177
  date: () => createParamValidator<string, "Date">("Date"),
178
178
 
179
- /** DateTime parameter (YYYY-MM-DD HH:MM:SS format) */
179
+ /** DateTime parameter (YYYY-MM-DD HH:MM:SS format, e.g. 2024-01-15 10:30:00) */
180
180
  dateTime: () => createParamValidator<string, "DateTime">("DateTime"),
181
181
 
182
- /** DateTime64 parameter with sub-second precision */
182
+ /** DateTime64 parameter (YYYY-MM-DD HH:MM:SS[.fraction] format, e.g. 2024-01-15 10:30:00.123) */
183
183
  dateTime64: () => createParamValidator<string, "DateTime64">("DateTime64"),
184
184
 
185
185
  // ============ Array Types ============
@@ -272,13 +272,13 @@ interface TinybirdConstructor {
272
272
  *
273
273
  * // Query a pipe (fully typed)
274
274
  * const result = await tinybird.topPages.query({
275
- * start_date: new Date('2024-01-01'),
276
- * end_date: new Date('2024-01-31'),
275
+ * start_date: '2024-01-01 00:00:00',
276
+ * end_date: '2024-01-31 23:59:59',
277
277
  * });
278
278
  *
279
279
  * // Ingest an event (fully typed)
280
280
  * await tinybird.pageViews.ingest({
281
- * timestamp: new Date(),
281
+ * timestamp: '2024-01-15 10:30:00',
282
282
  * pathname: '/home',
283
283
  * session_id: 'abc123',
284
284
  * });
@@ -203,25 +203,25 @@ export const t = {
203
203
 
204
204
  // ============ Date/Time Types ============
205
205
 
206
- /** Date - date without time (YYYY-MM-DD) */
207
- date: () => createValidator<Date, "Date">("Date"),
206
+ /** Date - string in YYYY-MM-DD format (e.g. 2024-01-15) */
207
+ date: () => createValidator<string, "Date">("Date"),
208
208
 
209
- /** Date32 - extended date range */
210
- date32: () => createValidator<Date, "Date32">("Date32"),
209
+ /** Date32 - string in YYYY-MM-DD format (e.g. 2024-01-15, extended date range) */
210
+ date32: () => createValidator<string, "Date32">("Date32"),
211
211
 
212
- /** DateTime - date and time with second precision */
212
+ /** DateTime - string in YYYY-MM-DD HH:MM:SS format (e.g. 2024-01-15 10:30:00) */
213
213
  dateTime: (timezone?: string) =>
214
214
  timezone
215
- ? createValidator<Date, `DateTime('${string}')`>(`DateTime('${timezone}')`)
216
- : createValidator<Date, "DateTime">("DateTime"),
215
+ ? createValidator<string, `DateTime('${string}')`>(`DateTime('${timezone}')`)
216
+ : createValidator<string, "DateTime">("DateTime"),
217
217
 
218
- /** DateTime64 - date and time with sub-second precision */
218
+ /** DateTime64 - string in YYYY-MM-DD HH:MM:SS[.fraction] format (e.g. 2024-01-15 10:30:00.123) */
219
219
  dateTime64: (precision: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 = 3, timezone?: string) =>
220
220
  timezone
221
- ? createValidator<Date, `DateTime64(${number}, '${string}')`>(
221
+ ? createValidator<string, `DateTime64(${number}, '${string}')`>(
222
222
  `DateTime64(${precision}, '${timezone}')`
223
223
  )
224
- : createValidator<Date, `DateTime64(${number})`>(`DateTime64(${precision})`),
224
+ : createValidator<string, `DateTime64(${number})`>(`DateTime64(${precision})`),
225
225
 
226
226
  // ============ Complex Types ============
227
227