alchemy 0.51.2 → 0.52.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 (103) hide show
  1. package/lib/apply.js +1 -1
  2. package/lib/apply.js.map +1 -1
  3. package/lib/cloudflare/assets.d.ts +1 -1
  4. package/lib/cloudflare/assets.d.ts.map +1 -1
  5. package/lib/cloudflare/bindings.d.ts +12 -11
  6. package/lib/cloudflare/bindings.d.ts.map +1 -1
  7. package/lib/cloudflare/bindings.js.map +1 -1
  8. package/lib/cloudflare/bound.d.ts +11 -18
  9. package/lib/cloudflare/bound.d.ts.map +1 -1
  10. package/lib/cloudflare/bucket.d.ts +4 -5
  11. package/lib/cloudflare/bucket.d.ts.map +1 -1
  12. package/lib/cloudflare/bucket.js +1 -16
  13. package/lib/cloudflare/bucket.js.map +1 -1
  14. package/lib/cloudflare/compatibility-date.gen.d.ts +1 -1
  15. package/lib/cloudflare/compatibility-date.gen.js +1 -1
  16. package/lib/cloudflare/d1-database.d.ts +85 -26
  17. package/lib/cloudflare/d1-database.d.ts.map +1 -1
  18. package/lib/cloudflare/d1-database.js +66 -47
  19. package/lib/cloudflare/d1-database.js.map +1 -1
  20. package/lib/cloudflare/d1-local-migrations.d.ts +10 -0
  21. package/lib/cloudflare/d1-local-migrations.d.ts.map +1 -0
  22. package/lib/cloudflare/d1-local-migrations.js +39 -0
  23. package/lib/cloudflare/d1-local-migrations.js.map +1 -0
  24. package/lib/cloudflare/dispatch-namespace.d.ts +4 -6
  25. package/lib/cloudflare/dispatch-namespace.d.ts.map +1 -1
  26. package/lib/cloudflare/dispatch-namespace.js +1 -11
  27. package/lib/cloudflare/dispatch-namespace.js.map +1 -1
  28. package/lib/cloudflare/event-source.d.ts +3 -3
  29. package/lib/cloudflare/event-source.d.ts.map +1 -1
  30. package/lib/cloudflare/hyperdrive.d.ts +3 -4
  31. package/lib/cloudflare/hyperdrive.d.ts.map +1 -1
  32. package/lib/cloudflare/hyperdrive.js +1 -9
  33. package/lib/cloudflare/hyperdrive.js.map +1 -1
  34. package/lib/cloudflare/index.d.ts +1 -0
  35. package/lib/cloudflare/index.d.ts.map +1 -1
  36. package/lib/cloudflare/index.js +1 -0
  37. package/lib/cloudflare/index.js.map +1 -1
  38. package/lib/cloudflare/kv-namespace.d.ts +4 -5
  39. package/lib/cloudflare/kv-namespace.d.ts.map +1 -1
  40. package/lib/cloudflare/kv-namespace.js +1 -14
  41. package/lib/cloudflare/kv-namespace.js.map +1 -1
  42. package/lib/cloudflare/pipeline.d.ts +4 -5
  43. package/lib/cloudflare/pipeline.d.ts.map +1 -1
  44. package/lib/cloudflare/pipeline.js +1 -12
  45. package/lib/cloudflare/pipeline.js.map +1 -1
  46. package/lib/cloudflare/queue-consumer.d.ts +3 -3
  47. package/lib/cloudflare/queue-consumer.d.ts.map +1 -1
  48. package/lib/cloudflare/queue.d.ts +3 -4
  49. package/lib/cloudflare/queue.d.ts.map +1 -1
  50. package/lib/cloudflare/queue.js +1 -11
  51. package/lib/cloudflare/queue.js.map +1 -1
  52. package/lib/cloudflare/vectorize-index.d.ts +4 -5
  53. package/lib/cloudflare/vectorize-index.d.ts.map +1 -1
  54. package/lib/cloudflare/vectorize-index.js +1 -15
  55. package/lib/cloudflare/vectorize-index.js.map +1 -1
  56. package/lib/cloudflare/vectorize-metadata-index.d.ts +2 -2
  57. package/lib/cloudflare/vectorize-metadata-index.d.ts.map +1 -1
  58. package/lib/cloudflare/worker-ref.d.ts +41 -0
  59. package/lib/cloudflare/worker-ref.d.ts.map +1 -0
  60. package/lib/cloudflare/worker-ref.js +27 -0
  61. package/lib/cloudflare/worker-ref.js.map +1 -0
  62. package/lib/cloudflare/worker.d.ts +6 -68
  63. package/lib/cloudflare/worker.d.ts.map +1 -1
  64. package/lib/cloudflare/worker.js +5 -198
  65. package/lib/cloudflare/worker.js.map +1 -1
  66. package/lib/cloudflare/wrangler.json.js +1 -0
  67. package/lib/cloudflare/wrangler.json.js.map +1 -1
  68. package/lib/cloudflare/zone.d.ts.map +1 -1
  69. package/lib/cloudflare/zone.js +2 -2
  70. package/lib/cloudflare/zone.js.map +1 -1
  71. package/lib/esbuild/bundle.d.ts +2 -2
  72. package/lib/state/cloudflare-state-store.d.ts +3 -1
  73. package/lib/state/cloudflare-state-store.d.ts.map +1 -1
  74. package/lib/state/cloudflare-state-store.js +11 -2
  75. package/lib/state/cloudflare-state-store.js.map +1 -1
  76. package/lib/state/instrumented-state-store.d.ts +2 -0
  77. package/lib/state/instrumented-state-store.d.ts.map +1 -1
  78. package/lib/state/instrumented-state-store.js +2 -0
  79. package/lib/state/instrumented-state-store.js.map +1 -1
  80. package/package.json +1 -1
  81. package/src/apply.ts +1 -1
  82. package/src/cloudflare/bindings.ts +18 -17
  83. package/src/cloudflare/bound.ts +35 -18
  84. package/src/cloudflare/bucket.ts +5 -27
  85. package/src/cloudflare/compatibility-date.gen.ts +1 -1
  86. package/src/cloudflare/d1-database.ts +107 -100
  87. package/src/cloudflare/d1-local-migrations.ts +52 -0
  88. package/src/cloudflare/dispatch-namespace.ts +6 -25
  89. package/src/cloudflare/event-source.ts +3 -3
  90. package/src/cloudflare/hyperdrive.ts +4 -19
  91. package/src/cloudflare/index.ts +1 -0
  92. package/src/cloudflare/kv-namespace.ts +5 -28
  93. package/src/cloudflare/pipeline.ts +8 -27
  94. package/src/cloudflare/queue-consumer.ts +3 -3
  95. package/src/cloudflare/queue.ts +4 -22
  96. package/src/cloudflare/vectorize-index.ts +5 -27
  97. package/src/cloudflare/vectorize-metadata-index.ts +2 -2
  98. package/src/cloudflare/worker-ref.ts +51 -0
  99. package/src/cloudflare/worker.ts +16 -332
  100. package/src/cloudflare/wrangler.json.ts +1 -0
  101. package/src/cloudflare/zone.ts +9 -8
  102. package/src/state/cloudflare-state-store.ts +73 -54
  103. package/src/state/instrumented-state-store.ts +2 -0
@@ -1,6 +1,6 @@
1
1
  import type { Context } from "../context.ts";
2
2
  import { Resource, ResourceKind } from "../resource.ts";
3
- import { bind, type Bound } from "../runtime/bind.ts";
3
+ import { Scope } from "../scope.ts";
4
4
  import { logger } from "../util/logger.ts";
5
5
  import { CloudflareApiError, handleApiError } from "./api-error.ts";
6
6
  import {
@@ -9,8 +9,20 @@ import {
9
9
  type CloudflareApiOptions,
10
10
  } from "./api.ts";
11
11
  import { cloneD1Database } from "./d1-clone.ts";
12
+ import { applyLocalD1Migrations } from "./d1-local-migrations.ts";
12
13
  import { applyMigrations, listMigrationsFiles } from "./d1-migrations.ts";
13
14
 
15
+ const DEFAULT_MIGRATIONS_TABLE = "d1_migrations";
16
+
17
+ type PrimaryLocationHint =
18
+ | "wnam"
19
+ | "enam"
20
+ | "weur"
21
+ | "eeur"
22
+ | "apac"
23
+ | "auto"
24
+ | (string & {});
25
+
14
26
  /**
15
27
  * Properties for creating or updating a D1 Database
16
28
  */
@@ -26,14 +38,7 @@ export interface D1DatabaseProps extends CloudflareApiOptions {
26
38
  * Optional primary location hint for the database
27
39
  * Indicates the primary geographical location data will be stored
28
40
  */
29
- primaryLocationHint?:
30
- | "wnam"
31
- | "enam"
32
- | "weur"
33
- | "eeur"
34
- | "apac"
35
- | "auto"
36
- | string;
41
+ primaryLocationHint?: PrimaryLocationHint;
37
42
 
38
43
  /**
39
44
  * Read replication configuration
@@ -102,20 +107,31 @@ export interface D1DatabaseProps extends CloudflareApiOptions {
102
107
  * @default false
103
108
  */
104
109
  remote?: boolean;
110
+
111
+ /**
112
+ * Set when `Scope.local` is true to force update to the database even if it was already deployed live.
113
+ * @internal
114
+ */
115
+ force?: boolean;
105
116
  };
106
117
  }
107
118
 
108
- export function isD1Database(
109
- resource: Resource,
110
- ): resource is D1DatabaseResource {
119
+ export function isD1Database(resource: Resource): resource is D1Database {
111
120
  return resource[ResourceKind] === "cloudflare::D1Database";
112
121
  }
113
122
 
114
123
  /**
115
124
  * Output returned after D1 Database creation/update
116
125
  */
117
- export type D1DatabaseResource = Resource<"cloudflare::D1Database"> &
118
- D1DatabaseProps & {
126
+ export type D1Database = Resource<"cloudflare::D1Database"> &
127
+ Pick<
128
+ D1DatabaseProps,
129
+ | "dev"
130
+ | "migrationsDir"
131
+ | "migrationsTable"
132
+ | "primaryLocationHint"
133
+ | "readReplication"
134
+ > & {
119
135
  type: "d1";
120
136
  /**
121
137
  * The unique ID of the database (UUID)
@@ -126,61 +142,8 @@ export type D1DatabaseResource = Resource<"cloudflare::D1Database"> &
126
142
  * The name of the database
127
143
  */
128
144
  name: string;
129
-
130
- /**
131
- * File size of the database
132
- */
133
- fileSize: number;
134
-
135
- /**
136
- * Number of tables in the database
137
- */
138
- numTables: number;
139
-
140
- /**
141
- * Version of the database
142
- */
143
- version: string;
144
-
145
- /**
146
- * Read replication configuration
147
- */
148
- readReplication?: {
149
- /**
150
- * Read replication mode
151
- */
152
- mode: "auto" | "disabled";
153
- };
154
145
  };
155
146
 
156
- export type D1Database = D1DatabaseResource & Bound<D1DatabaseResource>;
157
-
158
- export async function D1Database(
159
- id: string,
160
- props: Omit<D1DatabaseProps, "migrationsFiles"> = {},
161
- ): Promise<D1Database> {
162
- const migrationsFiles = props.migrationsDir
163
- ? await listMigrationsFiles(props.migrationsDir)
164
- : [];
165
-
166
- const db = await D1DatabaseResource(id, {
167
- ...props,
168
- migrationsFiles,
169
- });
170
- const binding = await bind(db);
171
- return {
172
- ...db,
173
- batch: binding.batch,
174
- exec: binding.exec,
175
- prepare: binding.prepare,
176
- withSession: binding.withSession,
177
- /**
178
- * @deprecated
179
- */
180
- dump: binding.dump,
181
- };
182
- }
183
-
184
147
  /**
185
148
  * Creates and manages Cloudflare D1 Databases.
186
149
  *
@@ -257,13 +220,33 @@ export async function D1Database(
257
220
  *
258
221
  * @see https://developers.cloudflare.com/d1/
259
222
  */
260
- const D1DatabaseResource = Resource(
223
+ export async function D1Database(
224
+ id: string,
225
+ props: Omit<D1DatabaseProps, "migrationsFiles"> = {},
226
+ ): Promise<D1Database> {
227
+ const migrationsFiles = props.migrationsDir
228
+ ? await listMigrationsFiles(props.migrationsDir)
229
+ : [];
230
+
231
+ return _D1Database(id, {
232
+ ...props,
233
+ migrationsFiles,
234
+ dev: {
235
+ ...(props.dev ?? {}),
236
+ // force local migrations to run even if the database was already deployed live
237
+ // this property will oscillate from true to false depending on the dev vs live deployment
238
+ force: Scope.current.local,
239
+ },
240
+ });
241
+ }
242
+
243
+ const _D1Database = Resource(
261
244
  "cloudflare::D1Database",
262
245
  async function (
263
- this: Context<D1DatabaseResource>,
246
+ this: Context<D1Database>,
264
247
  id: string,
265
248
  props: D1DatabaseProps = {},
266
- ): Promise<D1DatabaseResource> {
249
+ ): Promise<D1Database> {
267
250
  const api = await createCloudflareApi(props);
268
251
  const databaseName = props.name ?? id;
269
252
 
@@ -276,7 +259,33 @@ const D1DatabaseResource = Resource(
276
259
  }
277
260
  let dbData: CloudflareD1Response;
278
261
 
279
- if (this.phase === "create") {
262
+ if (this.scope.local && !props.dev?.remote) {
263
+ if (props.migrationsFiles && props.migrationsFiles.length > 0) {
264
+ await applyLocalD1Migrations({
265
+ databaseId: this.output?.id ?? id,
266
+ migrationsTable: props.migrationsTable ?? DEFAULT_MIGRATIONS_TABLE,
267
+ migrations: props.migrationsFiles,
268
+ });
269
+ }
270
+ return this({
271
+ type: "d1",
272
+ // we may not have an ID yet if we're creating a new database locally first
273
+ // so set it to the resource ID which we can later use to detect that a DB needs to be created during an `update`
274
+ id: this.output?.id ?? id,
275
+ name: databaseName,
276
+ readReplication: props.readReplication,
277
+ primaryLocationHint: props.primaryLocationHint,
278
+ migrationsDir: props.migrationsDir,
279
+ migrationsTable: props.migrationsTable ?? DEFAULT_MIGRATIONS_TABLE,
280
+ dev: props.dev,
281
+ });
282
+ } else if (
283
+ this.phase === "create" ||
284
+ // this is true IFF the database was created locally before any live deployment
285
+ // in that case, we should still go through the create flow for "update"
286
+ // after that, the ID will remain the UUID for the lifetime of the database
287
+ this.output.id === id
288
+ ) {
280
289
  logger.log("Creating D1 database:", databaseName);
281
290
  try {
282
291
  dbData = await createDatabase(api, databaseName, props);
@@ -323,35 +332,33 @@ const D1DatabaseResource = Resource(
323
332
  throw error;
324
333
  }
325
334
  }
326
- } else {
327
- // Update operation
328
- if (this.output?.id) {
329
- // Only read_replication can be modified in update
330
- if (
331
- props.primaryLocationHint &&
332
- props.primaryLocationHint !== this.output?.primaryLocationHint
333
- ) {
334
- throw new Error(
335
- `Cannot update primaryLocationHint from '${this.output.primaryLocationHint}' to '${props.primaryLocationHint}' after database creation.`,
336
- );
337
- }
338
- logger.log("Updating D1 database:", databaseName);
339
- // Update the database with new properties
340
- dbData = await updateDatabase(api, this.output.id, props);
341
- } else {
342
- // If no ID exists, fall back to creating a new database
343
- logger.log(
344
- "No existing database ID found, creating new D1 database:",
345
- databaseName,
335
+ } else if (this.output?.id) {
336
+ // Only read_replication can be modified in update
337
+ if (
338
+ props.primaryLocationHint &&
339
+ props.primaryLocationHint !== this.output?.primaryLocationHint
340
+ ) {
341
+ throw new Error(
342
+ `Cannot update primaryLocationHint from '${this.output.primaryLocationHint}' to '${props.primaryLocationHint}' after database creation.`,
346
343
  );
347
- dbData = await createDatabase(api, databaseName, props);
348
344
  }
345
+ logger.log("Updating D1 database:", databaseName);
346
+ // Update the database with new properties
347
+ dbData = await updateDatabase(api, this.output.id, props);
348
+ } else {
349
+ // If no ID exists, fall back to creating a new database
350
+ logger.log(
351
+ "No existing database ID found, creating new D1 database:",
352
+ databaseName,
353
+ );
354
+ dbData = await createDatabase(api, databaseName, props);
349
355
  }
350
356
 
351
357
  // Run migrations if provided
352
358
  if (props.migrationsFiles && props.migrationsFiles.length > 0) {
353
359
  try {
354
- const migrationsTable = props.migrationsTable || "d1_migrations";
360
+ const migrationsTable =
361
+ props.migrationsTable || DEFAULT_MIGRATIONS_TABLE;
355
362
  const databaseId = dbData.result.uuid || this.output?.id;
356
363
 
357
364
  if (!databaseId) {
@@ -370,19 +377,19 @@ const D1DatabaseResource = Resource(
370
377
  throw migrationErr;
371
378
  }
372
379
  }
373
-
380
+ if (!dbData.result.uuid) {
381
+ // TODO(sam): why would this ever happen?
382
+ throw new Error("Database ID not found");
383
+ }
374
384
  return this({
375
385
  type: "d1",
376
- id: dbData.result.uuid || "",
386
+ id: dbData.result.uuid!,
377
387
  name: databaseName,
378
- dev: props.dev,
379
- fileSize: dbData.result.file_size,
380
- numTables: dbData.result.num_tables,
381
- version: dbData.result.version,
382
388
  readReplication: dbData.result.read_replication,
383
389
  primaryLocationHint: props.primaryLocationHint,
384
- accountId: api.accountId,
390
+ dev: props.dev,
385
391
  migrationsDir: props.migrationsDir,
392
+ migrationsTable: props.migrationsTable ?? DEFAULT_MIGRATIONS_TABLE,
386
393
  });
387
394
  },
388
395
  );
@@ -0,0 +1,52 @@
1
+ import * as mf from "miniflare";
2
+ import path from "node:path";
3
+
4
+ export interface D1LocalMigrationOptions {
5
+ databaseId: string;
6
+ migrationsTable: string;
7
+ migrations: { id: string; sql: string }[];
8
+ }
9
+
10
+ export const applyLocalD1Migrations = async (
11
+ options: D1LocalMigrationOptions,
12
+ ) => {
13
+ const miniflare = new mf.Miniflare({
14
+ script: "",
15
+ modules: true,
16
+ defaultPersistRoot: path.join(process.cwd(), ".alchemy/miniflare"),
17
+ d1Persist: true,
18
+ d1Databases: { DB: options.databaseId },
19
+ log: process.env.DEBUG ? new mf.Log(mf.LogLevel.DEBUG) : undefined,
20
+ });
21
+ try {
22
+ await miniflare.ready;
23
+ const db = await miniflare.getD1Database("DB");
24
+ const session = db.withSession("first-primary");
25
+ await session
26
+ .prepare(
27
+ `CREATE TABLE IF NOT EXISTS ${options.migrationsTable} (
28
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
29
+ name TEXT NOT NULL,
30
+ applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
31
+ )`,
32
+ )
33
+ .run();
34
+ const appliedMigrations = await session
35
+ .prepare(
36
+ `SELECT name FROM ${options.migrationsTable} ORDER BY applied_at ASC`,
37
+ )
38
+ .all<{ name: string }>();
39
+ const insertRecord = session.prepare(
40
+ `INSERT INTO ${options.migrationsTable} (name) VALUES (?)`,
41
+ );
42
+ for (const migration of options.migrations) {
43
+ if (appliedMigrations.results.some((m) => m.name === migration.id)) {
44
+ continue;
45
+ }
46
+ await session.prepare(migration.sql).run();
47
+ await insertRecord.bind(migration.id).run();
48
+ }
49
+ } finally {
50
+ await miniflare.dispose();
51
+ }
52
+ };
@@ -1,6 +1,5 @@
1
1
  import type { Context } from "../context.ts";
2
2
  import { Resource, ResourceKind } from "../resource.ts";
3
- import { bind } from "../runtime/bind.ts";
4
3
  import { logger } from "../util/logger.ts";
5
4
  import { CloudflareApiError, handleApiError } from "./api-error.ts";
6
5
  import {
@@ -37,14 +36,14 @@ export interface DispatchNamespaceProps extends CloudflareApiOptions {
37
36
 
38
37
  export function isDispatchNamespace(
39
38
  resource: Resource,
40
- ): resource is DispatchNamespaceResource {
39
+ ): resource is DispatchNamespace {
41
40
  return resource[ResourceKind] === "cloudflare::DispatchNamespace";
42
41
  }
43
42
 
44
43
  /**
45
44
  * Output returned after Dispatch Namespace creation/update
46
45
  */
47
- export interface DispatchNamespaceResource
46
+ export interface DispatchNamespace
48
47
  extends Resource<"cloudflare::DispatchNamespace">,
49
48
  Omit<DispatchNamespaceProps, "delete"> {
50
49
  type: "dispatch_namespace";
@@ -74,10 +73,6 @@ export interface DispatchNamespaceResource
74
73
  modifiedAt: number;
75
74
  }
76
75
 
77
- export type DispatchNamespace = DispatchNamespaceResource & {
78
- get(name: string): Fetcher;
79
- };
80
-
81
76
  /**
82
77
  * A Cloudflare Dispatch Namespace enables routing worker requests to different scripts based on patterns.
83
78
  *
@@ -107,27 +102,13 @@ export type DispatchNamespace = DispatchNamespaceResource & {
107
102
  * delete: false
108
103
  * });
109
104
  */
110
-
111
- export async function DispatchNamespace(
112
- name: string,
113
- props: DispatchNamespaceProps = {},
114
- ): Promise<DispatchNamespace> {
115
- const dispatchNamespace = await _DispatchNamespace(name, props);
116
- const binding = await bind(dispatchNamespace);
117
- return {
118
- ...dispatchNamespace,
119
- // Add runtime methods that dispatch namespaces have
120
- get: binding.get,
121
- };
122
- }
123
-
124
- const _DispatchNamespace = Resource(
105
+ export const DispatchNamespace = Resource(
125
106
  "cloudflare::DispatchNamespace",
126
107
  async function (
127
- this: Context<DispatchNamespaceResource>,
108
+ this: Context<DispatchNamespace>,
128
109
  id: string,
129
- props: DispatchNamespaceProps,
130
- ): Promise<DispatchNamespaceResource> {
110
+ props: DispatchNamespaceProps = {},
111
+ ): Promise<DispatchNamespace> {
131
112
  // Create Cloudflare API client with automatic account discovery
132
113
  const api = await createCloudflareApi(props);
133
114
 
@@ -1,10 +1,10 @@
1
1
  import type { QueueConsumerSettings } from "./queue-consumer.ts";
2
- import type { QueueResource } from "./queue.ts";
2
+ import type { Queue } from "./queue.ts";
3
3
 
4
4
  /**
5
5
  * Base interface for event sources that can be bound to a Worker
6
6
  */
7
- export type EventSource = QueueEventSource | QueueResource;
7
+ export type EventSource = QueueEventSource | Queue;
8
8
 
9
9
  /**
10
10
  * Configuration for a Queue as an event source for a Worker
@@ -13,7 +13,7 @@ export interface QueueEventSource {
13
13
  /**
14
14
  * The queue to consume messages from
15
15
  */
16
- readonly queue: QueueResource;
16
+ readonly queue: Queue;
17
17
 
18
18
  /**
19
19
  * Optional settings for configuring how the Worker consumes the queue
@@ -1,11 +1,9 @@
1
1
  import type { Context } from "../context.ts";
2
2
  import { Resource } from "../resource.ts";
3
- import { tryGetBinding } from "../runtime/bind.ts";
4
3
  import type { Secret } from "../secret.ts";
5
4
  import { logger } from "../util/logger.ts";
6
5
  import { handleApiError } from "./api-error.ts";
7
6
  import { createCloudflareApi, type CloudflareApiOptions } from "./api.ts";
8
- import type { Bound } from "./bound.ts";
9
7
 
10
8
  /**
11
9
  * Origin configuration for a PostgreSQL or MySQL database connection
@@ -156,7 +154,7 @@ export interface HyperdriveProps extends CloudflareApiOptions {
156
154
  * Output returned after Cloudflare Hyperdrive creation/update.
157
155
  * IMPORTANT: The interface name MUST match the exported resource name.
158
156
  */
159
- export interface HyperdriveResource
157
+ export interface Hyperdrive
160
158
  extends Resource<"cloudflare::Hyperdrive">,
161
159
  Omit<HyperdriveProps, "origin"> {
162
160
  /**
@@ -181,8 +179,6 @@ export interface HyperdriveResource
181
179
  type: "hyperdrive";
182
180
  }
183
181
 
184
- export type Hyperdrive = HyperdriveResource & Bound<HyperdriveResource>;
185
-
186
182
  /**
187
183
  * Represents a Cloudflare Hyperdrive configuration.
188
184
  *
@@ -261,24 +257,13 @@ export type Hyperdrive = HyperdriveResource & Bound<HyperdriveResource>;
261
257
  * }
262
258
  * });
263
259
  */
264
- export async function Hyperdrive(
265
- name: string,
266
- props: HyperdriveProps,
267
- ): Promise<Hyperdrive> {
268
- const resource = await HyperdriveResource(name, props);
269
- return {
270
- ...resource,
271
- ...tryGetBinding(resource),
272
- } as Hyperdrive;
273
- }
274
-
275
- const HyperdriveResource = Resource(
260
+ export const Hyperdrive = Resource(
276
261
  "cloudflare::Hyperdrive",
277
262
  async function (
278
- this: Context<HyperdriveResource>,
263
+ this: Context<Hyperdrive>,
279
264
  id: string,
280
265
  props: HyperdriveProps,
281
- ): Promise<HyperdriveResource> {
266
+ ): Promise<Hyperdrive> {
282
267
  const api = await createCloudflareApi(props);
283
268
  const configsPath = `/accounts/${api.accountId}/hyperdrive/configs`;
284
269
 
@@ -55,6 +55,7 @@ export * from "./vectorize-metadata-index.ts";
55
55
  export * from "./version-metadata.ts";
56
56
  export * from "./vite.ts";
57
57
  export * from "./website.ts";
58
+ export * from "./worker-ref.ts";
58
59
  export * from "./worker-stub.ts";
59
60
  export * from "./worker-subdomain.ts";
60
61
  export * from "./worker.ts";
@@ -1,6 +1,5 @@
1
1
  import type { Context } from "../context.ts";
2
2
  import { Resource, ResourceKind } from "../resource.ts";
3
- import { bind } from "../runtime/bind.ts";
4
3
  import { logger } from "../util/logger.ts";
5
4
  import { withExponentialBackoff } from "../util/retry.ts";
6
5
  import { handleApiError } from "./api-error.ts";
@@ -9,7 +8,6 @@ import {
9
8
  type CloudflareApi,
10
9
  type CloudflareApiOptions,
11
10
  } from "./api.ts";
12
- import type { Bound } from "./bound.ts";
13
11
 
14
12
  /**
15
13
  * Properties for creating or updating a KV Namespace
@@ -84,16 +82,14 @@ export interface KVPair {
84
82
  metadata?: any;
85
83
  }
86
84
 
87
- export function isKVNamespace(
88
- resource: Resource,
89
- ): resource is KVNamespaceResource {
85
+ export function isKVNamespace(resource: Resource): resource is KVNamespace {
90
86
  return resource[ResourceKind] === "cloudflare::KVNamespace";
91
87
  }
92
88
 
93
89
  /**
94
90
  * Output returned after KV Namespace creation/update
95
91
  */
96
- export interface KVNamespaceResource
92
+ export interface KVNamespace
97
93
  extends Resource<"cloudflare::KVNamespace">,
98
94
  Omit<KVNamespaceProps, "delete"> {
99
95
  type: "kv_namespace";
@@ -113,8 +109,6 @@ export interface KVNamespaceResource
113
109
  modifiedAt: number;
114
110
  }
115
111
 
116
- export type KVNamespace = KVNamespaceResource & Bound<KVNamespaceResource>;
117
-
118
112
  /**
119
113
  * A Cloudflare KV Namespace is a key-value store that can be used to store data for your application.
120
114
  *
@@ -169,30 +163,13 @@ export type KVNamespace = KVNamespaceResource & Bound<KVNamespaceResource>;
169
163
  * delete: false
170
164
  * });
171
165
  */
172
-
173
- export async function KVNamespace(
174
- name: string,
175
- props: KVNamespaceProps = {},
176
- ): Promise<KVNamespace> {
177
- const kv = await _KVNamespace(name, props);
178
- const binding = await bind(kv);
179
- return {
180
- ...kv,
181
- delete: binding.delete,
182
- get: binding.get,
183
- getWithMetadata: binding.getWithMetadata,
184
- list: binding.list,
185
- put: binding.put,
186
- };
187
- }
188
-
189
- const _KVNamespace = Resource(
166
+ export const KVNamespace = Resource(
190
167
  "cloudflare::KVNamespace",
191
168
  async function (
192
- this: Context<KVNamespaceResource>,
169
+ this: Context<KVNamespace>,
193
170
  id: string,
194
171
  props: KVNamespaceProps,
195
- ): Promise<KVNamespaceResource> {
172
+ ): Promise<KVNamespace> {
196
173
  // Create Cloudflare API client with automatic account discovery
197
174
  const api = await createCloudflareApi(props);
198
175
 
@@ -1,6 +1,5 @@
1
1
  import type { Context } from "../context.ts";
2
2
  import { Resource, ResourceKind } from "../resource.ts";
3
- import { bind } from "../runtime/bind.ts";
4
3
  import type { Secret } from "../secret.ts";
5
4
  import { logger } from "../util/logger.ts";
6
5
  import { CloudflareApiError, handleApiError } from "./api-error.ts";
@@ -9,7 +8,6 @@ import {
9
8
  type CloudflareApi,
10
9
  type CloudflareApiOptions,
11
10
  } from "./api.ts";
12
- import type { Bound } from "./bound.ts";
13
11
 
14
12
  /**
15
13
  * Settings for compression of pipeline output
@@ -229,10 +227,14 @@ export interface PipelineRecord {
229
227
  [key: string]: any;
230
228
  }
231
229
 
230
+ export function isPipeline(resource: Resource): resource is Pipeline {
231
+ return resource[ResourceKind] === "cloudflare::Pipeline";
232
+ }
233
+
232
234
  /**
233
235
  * Output returned after Pipeline creation/update
234
236
  */
235
- export interface PipelineResource<_T extends PipelineRecord = PipelineRecord>
237
+ export interface Pipeline<_T extends PipelineRecord = PipelineRecord>
236
238
  extends Resource<"cloudflare::Pipeline">,
237
239
  PipelineProps {
238
240
  /**
@@ -261,13 +263,6 @@ export interface PipelineResource<_T extends PipelineRecord = PipelineRecord>
261
263
  version: number;
262
264
  }
263
265
 
264
- export function isPipeline(resource: Resource): resource is PipelineResource {
265
- return resource[ResourceKind] === "cloudflare::Pipeline";
266
- }
267
-
268
- export type Pipeline<T extends PipelineRecord = PipelineRecord> =
269
- PipelineResource<T> & Bound<PipelineResource<T>>;
270
-
271
266
  /**
272
267
  * Creates and manages Cloudflare Pipelines.
273
268
  *
@@ -334,24 +329,10 @@ export type Pipeline<T extends PipelineRecord = PipelineRecord> =
334
329
  *
335
330
  * @see https://developers.cloudflare.com/pipelines/
336
331
  */
337
- export async function Pipeline<T extends PipelineRecord = PipelineRecord>(
338
- name: string,
339
- props: PipelineProps,
340
- ): Promise<Pipeline<T>> {
341
- const pipeline = await PipelineResource(name, props);
342
- const binding = await bind(pipeline, {
343
- bindThis: false,
344
- });
345
- return {
346
- ...pipeline,
347
- send: binding.send,
348
- };
349
- }
350
-
351
- const PipelineResource = Resource("cloudflare::Pipeline", async function <
332
+ export const Pipeline = Resource("cloudflare::Pipeline", async function <
352
333
  T extends PipelineRecord = PipelineRecord,
353
- >(this: Context<PipelineResource<T>>, id: string, props: PipelineProps): Promise<
354
- PipelineResource<T>
334
+ >(this: Context<Pipeline<T>>, id: string, props: PipelineProps): Promise<
335
+ Pipeline<T>
355
336
  > {
356
337
  const api = await createCloudflareApi(props);
357
338
  const pipelineName = props.name ?? id;
@@ -7,7 +7,7 @@ import {
7
7
  type CloudflareApi,
8
8
  type CloudflareApiOptions,
9
9
  } from "./api.ts";
10
- import type { Queue, QueueResource } from "./queue.ts";
10
+ import type { Queue } from "./queue.ts";
11
11
 
12
12
  /**
13
13
  * Settings for configuring a Queue Consumer
@@ -55,9 +55,9 @@ export interface QueueConsumerSettings {
55
55
  */
56
56
  export interface QueueConsumerProps extends CloudflareApiOptions {
57
57
  /**
58
- * The {@link QueueResource} or Queue ID to consume
58
+ * The {@link Queue} or Queue ID to consume
59
59
  */
60
- queue: string | QueueResource;
60
+ queue: string | Queue;
61
61
 
62
62
  /**
63
63
  * Name of the worker script that will consume the queue