rwsdk 0.1.0 → 0.1.2-test.20250626055636

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 (44) hide show
  1. package/dist/runtime/lib/db/SqliteDurableObject.d.ts +1 -1
  2. package/dist/runtime/lib/db/createDb.js +11 -5
  3. package/dist/runtime/lib/db/index.d.ts +1 -0
  4. package/dist/runtime/lib/db/typeInference/builders/alterColumn.d.ts +12 -0
  5. package/dist/runtime/lib/db/typeInference/builders/alterColumn.js +1 -0
  6. package/dist/runtime/lib/db/typeInference/builders/alterTable.d.ts +21 -0
  7. package/dist/runtime/lib/db/typeInference/builders/alterTable.js +1 -0
  8. package/dist/runtime/lib/db/typeInference/builders/columnDefinition.d.ts +9 -0
  9. package/dist/runtime/lib/db/typeInference/builders/columnDefinition.js +1 -0
  10. package/dist/runtime/lib/db/typeInference/builders/createTable.d.ts +14 -0
  11. package/dist/runtime/lib/db/typeInference/builders/createTable.js +1 -0
  12. package/dist/runtime/lib/db/typeInference/builders/createView.d.ts +13 -0
  13. package/dist/runtime/lib/db/typeInference/builders/createView.js +1 -0
  14. package/dist/runtime/lib/db/typeInference/builders/dropTable.d.ts +7 -0
  15. package/dist/runtime/lib/db/typeInference/builders/dropTable.js +1 -0
  16. package/dist/runtime/lib/db/typeInference/builders/dropView.d.ts +7 -0
  17. package/dist/runtime/lib/db/typeInference/builders/dropView.js +1 -0
  18. package/dist/runtime/lib/db/typeInference/builders/schema.d.ts +12 -0
  19. package/dist/runtime/lib/db/typeInference/builders/schema.js +1 -0
  20. package/dist/runtime/lib/db/typeInference/builders/table.d.ts +10 -0
  21. package/dist/runtime/lib/db/typeInference/builders/table.js +1 -0
  22. package/dist/runtime/lib/db/typeInference/database.d.ts +38 -0
  23. package/dist/runtime/lib/db/typeInference/database.js +1 -0
  24. package/dist/runtime/lib/db/typeInference/typetests/alterTable.typetest.d.ts +1 -0
  25. package/dist/runtime/lib/db/typeInference/typetests/alterTable.typetest.js +102 -0
  26. package/dist/runtime/lib/db/typeInference/typetests/createTable.typetest.d.ts +1 -0
  27. package/dist/runtime/lib/db/typeInference/typetests/createTable.typetest.js +33 -0
  28. package/dist/runtime/lib/db/typeInference/typetests/dropTable.typetest.d.ts +1 -0
  29. package/dist/runtime/lib/db/typeInference/typetests/dropTable.typetest.js +77 -0
  30. package/dist/runtime/lib/db/typeInference/typetests/testUtils.d.ts +2 -0
  31. package/dist/runtime/lib/db/typeInference/typetests/testUtils.js +1 -0
  32. package/dist/runtime/lib/db/typeInference/typetests/typeInference.typetest.d.ts +1 -0
  33. package/dist/runtime/lib/db/typeInference/typetests/typeInference.typetest.js +18 -0
  34. package/dist/runtime/lib/db/typeInference/utils.d.ts +14 -0
  35. package/dist/runtime/lib/db/typeInference/utils.js +1 -0
  36. package/dist/vite/configPlugin.d.mts +2 -2
  37. package/dist/vite/configPlugin.mjs +2 -4
  38. package/dist/vite/injectVitePreamblePlugin.d.mts +2 -2
  39. package/dist/vite/injectVitePreamblePlugin.mjs +5 -2
  40. package/dist/vite/reactConditionsResolverPlugin.d.mts +1 -1
  41. package/dist/vite/reactConditionsResolverPlugin.mjs +64 -59
  42. package/dist/vite/redwoodPlugin.d.mts +1 -1
  43. package/dist/vite/redwoodPlugin.mjs +16 -5
  44. package/package.json +1 -1
@@ -6,7 +6,7 @@ export declare class SqliteDurableObject<T = any> extends DurableObject {
6
6
  private initialized;
7
7
  private migrationTableName;
8
8
  constructor(ctx: DurableObjectState, env: any, migrations: Record<string, any>, migrationTableName?: string);
9
- private initialize;
9
+ initialize(): Promise<void>;
10
10
  kyselyExecuteQuery<R>(compiledQuery: {
11
11
  sql: string;
12
12
  parameters: readonly unknown[];
@@ -4,19 +4,25 @@ import { DOWorkerDialect } from "./DOWorkerDialect.js";
4
4
  const createDurableObjectDb = (durableObjectBinding, name = "main") => {
5
5
  const durableObjectId = durableObjectBinding.idFromName(name);
6
6
  const stub = durableObjectBinding.get(durableObjectId);
7
+ stub.initialize();
7
8
  return new Kysely({
8
9
  dialect: new DOWorkerDialect({ stub }),
9
10
  });
10
11
  };
11
12
  export function createDb(durableObjectBinding, name = "main") {
12
13
  const cacheKey = `${durableObjectBinding}_${name}`;
14
+ const doCreateDb = () => {
15
+ let db = requestInfo.rw.databases.get(cacheKey);
16
+ if (!db) {
17
+ db = createDurableObjectDb(durableObjectBinding, name);
18
+ requestInfo.rw.databases.set(cacheKey, db);
19
+ }
20
+ return db;
21
+ };
22
+ doCreateDb();
13
23
  return new Proxy({}, {
14
24
  get(target, prop, receiver) {
15
- let db = requestInfo.rw.databases.get(cacheKey);
16
- if (!db) {
17
- db = createDurableObjectDb(durableObjectBinding, name);
18
- requestInfo.rw.databases.set(cacheKey, db);
19
- }
25
+ const db = doCreateDb();
20
26
  const value = db[prop];
21
27
  if (typeof value === "function") {
22
28
  return value.bind(db);
@@ -1,3 +1,4 @@
1
1
  export * from "./migrations.js";
2
2
  export * from "./SqliteDurableObject.js";
3
3
  export * from "./createDb.js";
4
+ export type * from "./typeInference/database.js";
@@ -0,0 +1,12 @@
1
+ export interface AlterColumnBuilder {
2
+ setDataType<T extends string>(dataType: T): AlteredColumnBuilder<"setDataType", T>;
3
+ setDefault<T>(value: T): AlteredColumnBuilder<"setDefault", T>;
4
+ dropDefault(): AlteredColumnBuilder<"dropDefault", true>;
5
+ setNotNull(): AlteredColumnBuilder<"setNotNull", true>;
6
+ dropNotNull(): AlteredColumnBuilder<"dropNotNull", true>;
7
+ }
8
+ export interface AlteredColumnBuilder<Kind extends string, Value> {
9
+ readonly kind: Kind;
10
+ readonly value: Value;
11
+ }
12
+ export type AlterColumnBuilderCallback = (builder: AlterColumnBuilder) => AlteredColumnBuilder<any, any>;
@@ -0,0 +1,21 @@
1
+ import { SqlToTsType, ExecutedBuilder, Prettify } from "../utils";
2
+ import { ColumnDefinitionBuilder } from "./columnDefinition";
3
+ import { AlterColumnBuilderCallback } from "./alterColumn";
4
+ export interface AlterTableBuilder<TName extends string, TSchema extends Record<string, any> = {}> {
5
+ readonly __tableName: TName;
6
+ readonly __addedColumns: TSchema;
7
+ renameTo<TNewName extends string>(newTableName: TNewName): AlterTableBuilder<TNewName, TSchema>;
8
+ setSchema(newSchema: string): AlterTableBuilder<TName, TSchema>;
9
+ addColumn<K extends string, T extends string>(name: K, type: T, build?: (col: ColumnDefinitionBuilder<SqlToTsType<T>>) => ColumnDefinitionBuilder<SqlToTsType<T>>): AlterTableBuilder<TName, Prettify<TSchema & Record<K, SqlToTsType<T>>>>;
10
+ dropColumn<K extends string>(name: K): AlterTableBuilder<TName, Prettify<TSchema & {
11
+ [P in K]: never;
12
+ }>>;
13
+ renameColumn<KFrom extends string, KTo extends string>(from: KFrom, to: KTo): AlterTableBuilder<TName, Prettify<TSchema & {
14
+ [P in KFrom]: never;
15
+ } & {
16
+ [P in KTo]: any;
17
+ }>>;
18
+ alterColumn<K extends string>(column: K, alteration: AlterColumnBuilderCallback): AlterTableBuilder<TName, TSchema>;
19
+ modifyColumn<K extends string, T extends string>(column: K, type: T, build?: (col: ColumnDefinitionBuilder<SqlToTsType<T>>) => ColumnDefinitionBuilder<SqlToTsType<T>>): AlterTableBuilder<TName, Prettify<TSchema & Record<K, SqlToTsType<T>>>>;
20
+ execute(): ExecutedBuilder<this>;
21
+ }
@@ -0,0 +1,9 @@
1
+ export interface ColumnDefinitionBuilder<T = any> {
2
+ primaryKey(): ColumnDefinitionBuilder<T>;
3
+ notNull(): ColumnDefinitionBuilder<T>;
4
+ unique(): ColumnDefinitionBuilder<T>;
5
+ defaultTo<V extends T>(value: V): ColumnDefinitionBuilder<T>;
6
+ references(ref: string): ColumnDefinitionBuilder<T>;
7
+ onDelete(action: "cascade" | "restrict" | "set null"): ColumnDefinitionBuilder<T>;
8
+ unsigned(): ColumnDefinitionBuilder<T>;
9
+ }
@@ -0,0 +1,14 @@
1
+ import { SqlToTsType, ExecutedBuilder, Prettify } from "../utils";
2
+ import { ColumnDefinitionBuilder } from "./columnDefinition";
3
+ export interface CreateTableBuilder<TName extends string, TSchema extends Record<string, any> = {}> {
4
+ readonly __tableName: TName;
5
+ readonly __addedColumns: TSchema;
6
+ temporary(): CreateTableBuilder<TName, TSchema>;
7
+ onCommit(onCommit: "preserve rows" | "delete rows" | "drop"): CreateTableBuilder<TName, TSchema>;
8
+ ifNotExists(): CreateTableBuilder<TName, TSchema>;
9
+ addColumn<K extends string, T extends string>(name: K, type: T, build?: (col: ColumnDefinitionBuilder<SqlToTsType<T>>) => ColumnDefinitionBuilder<SqlToTsType<T>>): CreateTableBuilder<TName, Prettify<TSchema & Record<K, SqlToTsType<T>>>>;
10
+ modifyFront(modifier: string): CreateTableBuilder<TName, TSchema>;
11
+ modifyEnd(modifier: string): CreateTableBuilder<TName, TSchema>;
12
+ as(expression: string): CreateTableBuilder<TName, TSchema>;
13
+ execute(): ExecutedBuilder<this>;
14
+ }
@@ -0,0 +1,13 @@
1
+ import { ExecutedBuilder } from "../utils";
2
+ export interface CreateViewBuilder<TName extends string, TSchema extends Record<string, any> = {}, TColumns extends string[] = []> {
3
+ readonly __viewName: TName;
4
+ readonly __schema: TSchema;
5
+ readonly __columns: TColumns;
6
+ withSchema<S extends Record<string, any>>(): CreateViewBuilder<TName, S, TColumns>;
7
+ temporary(): CreateViewBuilder<TName, TSchema, TColumns>;
8
+ orReplace(): CreateViewBuilder<TName, TSchema, TColumns>;
9
+ ifNotExists(): CreateViewBuilder<TName, TSchema, TColumns>;
10
+ columns<C extends string[]>(columns: C): CreateViewBuilder<TName, TSchema, C>;
11
+ as<E extends string>(expression: E): CreateViewBuilder<TName, TSchema, TColumns>;
12
+ execute(): ExecutedBuilder<this>;
13
+ }
@@ -0,0 +1,7 @@
1
+ import { ExecutedBuilder } from "../utils";
2
+ export interface DropTableBuilder<TName extends string> {
3
+ readonly __tableName: TName;
4
+ ifExists(): DropTableBuilder<TName>;
5
+ cascade(): DropTableBuilder<TName>;
6
+ execute(): ExecutedBuilder<this>;
7
+ }
@@ -0,0 +1,7 @@
1
+ import { ExecutedBuilder } from "../utils";
2
+ export interface DropViewBuilder<TName extends string> {
3
+ readonly __viewName: TName;
4
+ ifExists(): DropViewBuilder<TName>;
5
+ cascade(): DropViewBuilder<TName>;
6
+ execute(): ExecutedBuilder<this>;
7
+ }
@@ -0,0 +1,12 @@
1
+ import { TableBuilder } from "./table";
2
+ import { AlterTableBuilder } from "./alterTable";
3
+ import { DropTableBuilder } from "./dropTable";
4
+ import { CreateViewBuilder } from "./createView";
5
+ import { DropViewBuilder } from "./dropView";
6
+ export interface SchemaBuilder {
7
+ createTable<TName extends string>(name: TName): TableBuilder<TName, {}>;
8
+ alterTable<TName extends string>(name: TName): AlterTableBuilder<TName, {}>;
9
+ dropTable<TName extends string>(name: TName): DropTableBuilder<TName>;
10
+ createView<TName extends string>(name: TName): CreateViewBuilder<TName, {}>;
11
+ dropView<TName extends string>(name: TName): DropViewBuilder<TName>;
12
+ }
@@ -0,0 +1,10 @@
1
+ import { SqlToTsType, ExecutedBuilder, Prettify } from "../utils";
2
+ import { ColumnDefinitionBuilder } from "./columnDefinition";
3
+ export interface TableBuilder<TName extends string, TSchema extends Record<string, any> = {}> {
4
+ readonly __tableName: TName;
5
+ readonly __schema: TSchema;
6
+ addColumn<K extends string, T extends string>(name: K, type: T, build?: (col: ColumnDefinitionBuilder<SqlToTsType<T>>) => ColumnDefinitionBuilder<SqlToTsType<T>>): TableBuilder<TName, Prettify<TSchema & Record<K, SqlToTsType<T>>>>;
7
+ temporary(): this;
8
+ ifNotExists(): this;
9
+ execute(): ExecutedBuilder<this>;
10
+ }
@@ -0,0 +1,38 @@
1
+ import { Kysely } from "kysely";
2
+ import { ExecutedBuilder, Prettify, MergeSchemas, OmitNever, UnionToIntersection } from "./utils";
3
+ import { TableBuilder } from "./builders/table";
4
+ import { CreateViewBuilder } from "./builders/createView.js";
5
+ import { AlterTableBuilder } from "./builders/alterTable.js";
6
+ import { DropTableBuilder } from "./builders/dropTable.js";
7
+ import { DropViewBuilder } from "./builders/dropView.js";
8
+ import { SchemaBuilder } from "./builders/schema";
9
+ export interface InferenceBuilder {
10
+ schema: SchemaBuilder;
11
+ }
12
+ export type MigrationBuilder = InferenceBuilder & Kysely<any>;
13
+ export interface Migration<TUpReturn = unknown> {
14
+ up(db: MigrationBuilder): TUpReturn;
15
+ down?(db: Kysely<any>): any;
16
+ }
17
+ export type Migrations = Record<string, Migration>;
18
+ type GetBuilder<T> = T extends ExecutedBuilder<infer B> ? B : never;
19
+ type BuildersFromMigration<TMigration extends Migration> = TMigration extends Migration<infer TUpReturn> ? Awaited<TUpReturn> extends Array<infer Item> ? GetBuilder<Item> : GetBuilder<Awaited<TUpReturn>> : never;
20
+ type AllBuilders<TMigrations extends Migrations> = BuildersFromMigration<TMigrations[keyof TMigrations]>;
21
+ type CreatedTables<TMigrations extends Migrations> = UnionToIntersection<ExtractTableSchema<Extract<AllBuilders<TMigrations>, TableBuilder<any, any>>>>;
22
+ type CreatedViews<TMigrations extends Migrations> = UnionToIntersection<ExtractViewSchema<Extract<AllBuilders<TMigrations>, CreateViewBuilder<any, any>>>>;
23
+ type AlteredTables<TMigrations extends Migrations> = UnionToIntersection<ExtractAlterSchema<Extract<AllBuilders<TMigrations>, AlterTableBuilder<any, any>>>>;
24
+ type DroppedTableNames<TMigrations extends Migrations> = ExtractDroppedTableName<Extract<AllBuilders<TMigrations>, DropTableBuilder<any>>>;
25
+ type DroppedViewNames<TMigrations extends Migrations> = ExtractDroppedViewName<Extract<AllBuilders<TMigrations>, DropViewBuilder<any>>>;
26
+ type AllCreated<TMigrations extends Migrations> = MergeSchemas<CreatedTables<TMigrations>, CreatedViews<TMigrations>>;
27
+ type MergedSchemaBeforeDrop<TMigrations extends Migrations> = MergeSchemas<AllCreated<TMigrations>, AlteredTables<TMigrations>>;
28
+ type CleanedSchema<T> = {
29
+ [K in keyof T]: OmitNever<T[K]>;
30
+ };
31
+ type InferredDatabase<TMigrations extends Migrations> = Omit<Omit<CleanedSchema<MergedSchemaBeforeDrop<TMigrations>>, DroppedTableNames<TMigrations>>, DroppedViewNames<TMigrations>>;
32
+ export type Database<TMigrations extends Migrations = Migrations> = Prettify<InferredDatabase<TMigrations>>;
33
+ export type ExtractTableSchema<T> = T extends TableBuilder<infer TName, infer TSchema> ? Record<TName, TSchema> : never;
34
+ export type ExtractViewSchema<T> = T extends CreateViewBuilder<infer TName, infer TSchema> ? Record<TName, TSchema> : never;
35
+ export type ExtractAlterSchema<T> = T extends AlterTableBuilder<infer TName, infer TSchema> ? Record<TName, TSchema> : never;
36
+ export type ExtractDroppedTableName<T> = T extends DropTableBuilder<infer TName> ? TName : never;
37
+ export type ExtractDroppedViewName<T> = T extends DropViewBuilder<infer TName> ? TName : never;
38
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,102 @@
1
+ (_it = "alterTable addColumn") => {
2
+ const migrations = {
3
+ "0": {
4
+ async up(db) {
5
+ return [
6
+ db.schema
7
+ .createTable("users")
8
+ .addColumn("username", "text", (col) => col.notNull().unique())
9
+ .execute(),
10
+ ];
11
+ },
12
+ },
13
+ "1": {
14
+ async up(db) {
15
+ return [
16
+ db.schema
17
+ .alterTable("users")
18
+ .addColumn("displayName", "text")
19
+ .execute(),
20
+ ];
21
+ },
22
+ },
23
+ };
24
+ (_test) => { };
25
+ };
26
+ (_it = "alterTable renameColumn and dropColumn") => {
27
+ const migrations = {
28
+ "0": {
29
+ async up(db) {
30
+ return [
31
+ db.schema
32
+ .createTable("users")
33
+ .addColumn("username", "text")
34
+ .addColumn("displayName", "text")
35
+ .execute(),
36
+ ];
37
+ },
38
+ },
39
+ "1": {
40
+ async up(db) {
41
+ return [
42
+ db.schema
43
+ .alterTable("users")
44
+ .renameColumn("displayName", "nickname")
45
+ .dropColumn("username")
46
+ .execute(),
47
+ ];
48
+ },
49
+ },
50
+ };
51
+ (_test) => { };
52
+ };
53
+ (_it = "alterTable alterColumn setDataType and setDefault") => {
54
+ const migrations = {
55
+ "0": {
56
+ async up(db) {
57
+ return [
58
+ db.schema.createTable("users").addColumn("age", "integer").execute(),
59
+ ];
60
+ },
61
+ },
62
+ "1": {
63
+ async up(db) {
64
+ return [
65
+ db.schema
66
+ .alterTable("users")
67
+ .alterColumn("age", (col) => col.setDataType("text"))
68
+ .alterColumn("age", (col) => col.setDefault("unknown"))
69
+ .execute(),
70
+ ];
71
+ },
72
+ },
73
+ };
74
+ // todo(justinvdm, 2024-01-08): Support setDataType()
75
+ // @ts-ignore
76
+ (_test) => { };
77
+ };
78
+ (_it = "alterTable alterColumn dropDefault, setNotNull, dropNotNull") => {
79
+ const migrations = {
80
+ "0": {
81
+ async up(db) {
82
+ return [
83
+ db.schema.createTable("users").addColumn("age", "integer").execute(),
84
+ ];
85
+ },
86
+ },
87
+ "1": {
88
+ async up(db) {
89
+ return [
90
+ db.schema
91
+ .alterTable("users")
92
+ .alterColumn("age", (col) => col.dropDefault())
93
+ .alterColumn("age", (col) => col.setNotNull())
94
+ .alterColumn("age", (col) => col.dropNotNull())
95
+ .execute(),
96
+ ];
97
+ },
98
+ },
99
+ };
100
+ (_test) => { };
101
+ };
102
+ export {};
@@ -0,0 +1,33 @@
1
+ (_it = "createTable") => {
2
+ const migrations = {
3
+ "001_init": {
4
+ async up(db) {
5
+ return [
6
+ db.schema
7
+ .createTable("users")
8
+ .addColumn("username", "text", (col) => col.notNull().unique())
9
+ .execute(),
10
+ ];
11
+ },
12
+ },
13
+ };
14
+ (_test) => { };
15
+ };
16
+ (_it = "createTable with multiple columns and defaults") => {
17
+ const migrations = {
18
+ "001_init": {
19
+ async up(db) {
20
+ return [
21
+ db.schema
22
+ .createTable("users")
23
+ .addColumn("username", "text", (col) => col.notNull())
24
+ .addColumn("age", "integer", (col) => col.defaultTo(18))
25
+ .addColumn("active", "boolean", (col) => col.defaultTo(true))
26
+ .execute(),
27
+ ];
28
+ },
29
+ },
30
+ };
31
+ (_test) => { };
32
+ };
33
+ export {};
@@ -0,0 +1,77 @@
1
+ (_it = "dropTable") => {
2
+ const migrations = {
3
+ "0": {
4
+ async up(db) {
5
+ return [
6
+ db.schema
7
+ .createTable("users")
8
+ .addColumn("username", "text", (col) => col.notNull().unique())
9
+ .execute(),
10
+ db.schema.createTable("posts").addColumn("title", "text").execute(),
11
+ ];
12
+ },
13
+ },
14
+ "1": {
15
+ async up(db) {
16
+ return [db.schema.dropTable("posts").execute()];
17
+ },
18
+ },
19
+ };
20
+ (_test) => { };
21
+ };
22
+ (_it = "dropTable non-existent table") => {
23
+ const migrations = {
24
+ "0": {
25
+ async up(db) {
26
+ return [db.schema.dropTable("ghost").execute()];
27
+ },
28
+ },
29
+ };
30
+ (_test) => { };
31
+ };
32
+ (_it = "dropTable all tables") => {
33
+ const migrations = {
34
+ "0": {
35
+ async up(db) {
36
+ return [
37
+ db.schema.createTable("a").addColumn("x", "text").execute(),
38
+ db.schema.createTable("b").addColumn("y", "text").execute(),
39
+ ];
40
+ },
41
+ },
42
+ "1": {
43
+ async up(db) {
44
+ return [
45
+ db.schema.dropTable("a").execute(),
46
+ db.schema.dropTable("b").execute(),
47
+ ];
48
+ },
49
+ },
50
+ };
51
+ (_test) => { };
52
+ };
53
+ (_it = "chaining createTable and dropTable") => {
54
+ const migrations = {
55
+ "0": {
56
+ async up(db) {
57
+ return [
58
+ db.schema
59
+ .createTable("users")
60
+ .addColumn("username", "text")
61
+ .execute(),
62
+ db.schema.createTable("posts").addColumn("title", "text").execute(),
63
+ ];
64
+ },
65
+ },
66
+ "1": {
67
+ async up(db) {
68
+ return [
69
+ db.schema.dropTable("posts").execute(),
70
+ db.schema.createTable("comments").addColumn("text", "text").execute(),
71
+ ];
72
+ },
73
+ },
74
+ };
75
+ (_test) => { };
76
+ };
77
+ export {};
@@ -0,0 +1,2 @@
1
+ export type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false;
2
+ export type Expect<T extends true> = T;
@@ -0,0 +1,18 @@
1
+ (_it = "addColumn with default value") => {
2
+ const migrations = {
3
+ "0": {
4
+ async up(db) {
5
+ return [
6
+ db.schema
7
+ .createTable("users")
8
+ .addColumn("username", "text", (col) => col.notNull().unique())
9
+ .addColumn("posts", "integer", (col) => col.defaultTo(0).notNull())
10
+ .execute(),
11
+ ];
12
+ },
13
+ },
14
+ };
15
+ (_test) => { };
16
+ };
17
+ export {};
18
+ // All tests for createTable, dropTable, and alterTable have been moved to their own files.
@@ -0,0 +1,14 @@
1
+ export type SqlToTsType<T extends string> = T extends "text" ? string : T extends "integer" ? number : T extends "blob" ? Uint8Array : T extends "real" ? number : T extends "boolean" ? boolean : never;
2
+ export type Prettify<T> = {
3
+ [K in keyof T]: T[K];
4
+ } & {};
5
+ export type ExecutedBuilder<T> = Promise<void> & {
6
+ __builder_type: T;
7
+ };
8
+ export type MergeSchemas<A, B> = {
9
+ [K in keyof A | keyof B]: K extends keyof A ? K extends keyof B ? Prettify<A[K] & B[K]> : A[K] : K extends keyof B ? B[K] : never;
10
+ };
11
+ export type OmitNever<T> = {
12
+ [K in keyof T as T[K] extends never ? never : K]: T[K];
13
+ };
14
+ export type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,10 +1,10 @@
1
1
  import { Plugin } from "vite";
2
2
  export declare const cloudflareBuiltInModules: string[];
3
3
  export declare const externalModules: string[];
4
- export declare const configPlugin: ({ mode, silent, projectRootDir, clientEntryPathname, workerEntryPathname, }: {
4
+ export declare const configPlugin: ({ mode, silent, projectRootDir, clientEntryPathnames, workerEntryPathname, }: {
5
5
  mode: "development" | "production";
6
6
  silent: boolean;
7
7
  projectRootDir: string;
8
- clientEntryPathname: string;
8
+ clientEntryPathnames: string[];
9
9
  workerEntryPathname: string;
10
10
  }) => Plugin;
@@ -15,7 +15,7 @@ export const externalModules = [
15
15
  ...builtinModules,
16
16
  ...builtinModules.map((m) => `node:${m}`),
17
17
  ];
18
- export const configPlugin = ({ mode, silent, projectRootDir, clientEntryPathname, workerEntryPathname, }) => ({
18
+ export const configPlugin = ({ mode, silent, projectRootDir, clientEntryPathnames, workerEntryPathname, }) => ({
19
19
  name: "rwsdk:config",
20
20
  config: (_, { command }) => {
21
21
  const baseConfig = {
@@ -39,9 +39,7 @@ export const configPlugin = ({ mode, silent, projectRootDir, clientEntryPathname
39
39
  outDir: resolve(projectRootDir, "dist", "client"),
40
40
  manifest: true,
41
41
  rollupOptions: {
42
- input: {
43
- client: clientEntryPathname,
44
- },
42
+ input: clientEntryPathnames,
45
43
  },
46
44
  },
47
45
  define: {
@@ -1,5 +1,5 @@
1
1
  import { type Plugin } from "vite";
2
- export declare const injectVitePreamble: ({ clientEntryPathname, mode, }: {
3
- clientEntryPathname: string;
2
+ export declare const injectVitePreamble: ({ clientEntryPathnames, mode, }: {
3
+ clientEntryPathnames: string[];
4
4
  mode: "development" | "production";
5
5
  }) => Plugin;
@@ -1,9 +1,12 @@
1
1
  import MagicString from "magic-string";
2
- export const injectVitePreamble = ({ clientEntryPathname, mode, }) => ({
2
+ export const injectVitePreamble = ({ clientEntryPathnames, mode, }) => ({
3
3
  name: "rwsdk:inject-vite-preamble",
4
4
  apply: "serve",
5
5
  transform(code, id) {
6
- if (id !== clientEntryPathname) {
6
+ if (this.environment.name !== "client") {
7
+ return;
8
+ }
9
+ if (!clientEntryPathnames.includes(id)) {
7
10
  return;
8
11
  }
9
12
  // Only inject preamble in development mode
@@ -13,4 +13,4 @@ export declare const ENV_RESOLVERS: {
13
13
  export declare const ENV_IMPORT_MAPPINGS: {
14
14
  [k: string]: Map<string, string>;
15
15
  };
16
- export declare const reactConditionsResolverPlugin: () => Promise<Plugin>;
16
+ export declare const reactConditionsResolverPlugin: () => Plugin[];
@@ -95,71 +95,76 @@ function createEsbuildResolverPlugin(envName) {
95
95
  },
96
96
  };
97
97
  }
98
- export const reactConditionsResolverPlugin = async () => {
98
+ export const reactConditionsResolverPlugin = () => {
99
99
  log("Initializing react conditions resolver plugin");
100
100
  let isBuild = false;
101
- return {
102
- name: "rwsdk:react-conditions-resolver",
103
- enforce: "post",
104
- config(config, { command }) {
105
- isBuild = command === "build";
106
- log("Configuring plugin for command=%s", command);
101
+ return [
102
+ {
103
+ name: "rwsdk:react-conditions-resolver:config",
104
+ enforce: "post",
105
+ config(config, { command }) {
106
+ isBuild = command === "build";
107
+ log("Configuring plugin for command=%s", command);
108
+ },
109
+ configResolved(config) {
110
+ log("Setting up resolve aliases and optimizeDeps for each environment");
111
+ // Set up aliases and optimizeDeps for each environment
112
+ for (const [envName, mappings] of Object.entries(ENV_IMPORT_MAPPINGS)) {
113
+ const reactImports = ENV_REACT_IMPORTS[envName];
114
+ // Ensure environment config exists
115
+ if (!config.environments) {
116
+ config.environments = {};
117
+ }
118
+ if (!config.environments[envName]) {
119
+ config.environments[envName] = {};
120
+ }
121
+ const envConfig = config.environments[envName];
122
+ const esbuildPlugin = createEsbuildResolverPlugin(envName);
123
+ if (esbuildPlugin && mappings) {
124
+ envConfig.optimizeDeps ??= {};
125
+ envConfig.optimizeDeps.esbuildOptions ??= {};
126
+ envConfig.optimizeDeps.esbuildOptions.define ??= {};
127
+ envConfig.optimizeDeps.esbuildOptions.define["process.env.NODE_ENV"] = JSON.stringify(process.env.NODE_ENV ?? "production");
128
+ envConfig.optimizeDeps.esbuildOptions.plugins ??= [];
129
+ envConfig.optimizeDeps.esbuildOptions.plugins.push(esbuildPlugin);
130
+ envConfig.optimizeDeps.include ??= [];
131
+ envConfig.optimizeDeps.include.push(...reactImports);
132
+ log("Added esbuild plugin and optimizeDeps includes for environment: %s", envName);
133
+ }
134
+ const aliases = ensureAliasArray(envConfig);
135
+ for (const [find, replacement] of mappings) {
136
+ const findRegex = new RegExp(`^${find.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&")}$`);
137
+ aliases.push({ find: findRegex, replacement });
138
+ log("Added alias for env=%s: %s -> %s", envName, find, replacement);
139
+ }
140
+ log("Environment %s configured with %d aliases and %d optimizeDeps includes", envName, mappings.size, reactImports.length);
141
+ }
142
+ },
107
143
  },
108
- configResolved(config) {
109
- log("Setting up resolve aliases and optimizeDeps for each environment");
110
- // Set up aliases and optimizeDeps for each environment
111
- for (const [envName, mappings] of Object.entries(ENV_IMPORT_MAPPINGS)) {
112
- const reactImports = ENV_REACT_IMPORTS[envName];
113
- // Ensure environment config exists
114
- if (!config.environments) {
115
- config.environments = {};
144
+ {
145
+ name: "rwsdk:react-conditions-resolver:resolveId",
146
+ enforce: "pre",
147
+ async resolveId(id, importer) {
148
+ if (!isBuild) {
149
+ return;
116
150
  }
117
- if (!config.environments[envName]) {
118
- config.environments[envName] = {};
151
+ const envName = this.environment?.name;
152
+ if (!envName) {
153
+ return;
119
154
  }
120
- const envConfig = config.environments[envName];
121
- const esbuildPlugin = createEsbuildResolverPlugin(envName);
122
- if (esbuildPlugin && mappings) {
123
- envConfig.optimizeDeps ??= {};
124
- envConfig.optimizeDeps.esbuildOptions ??= {};
125
- envConfig.optimizeDeps.esbuildOptions.define ??= {};
126
- envConfig.optimizeDeps.esbuildOptions.define["process.env.NODE_ENV"] =
127
- JSON.stringify(process.env.NODE_ENV ?? "production");
128
- envConfig.optimizeDeps.esbuildOptions.plugins ??= [];
129
- envConfig.optimizeDeps.esbuildOptions.plugins.push(esbuildPlugin);
130
- envConfig.optimizeDeps.include ??= [];
131
- envConfig.optimizeDeps.include.push(...reactImports);
132
- log("Added esbuild plugin and optimizeDeps includes for environment: %s", envName);
155
+ verboseLog("Resolving id=%s, environment=%s, importer=%s", id, envName, importer);
156
+ const mappings = ENV_IMPORT_MAPPINGS[envName];
157
+ if (!mappings) {
158
+ verboseLog("No mappings found for environment: %s", envName);
159
+ return;
133
160
  }
134
- const aliases = ensureAliasArray(envConfig);
135
- for (const [find, replacement] of mappings) {
136
- const findRegex = new RegExp(`^${find.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&")}$`);
137
- aliases.push({ find: findRegex, replacement });
138
- log("Added alias for env=%s: %s -> %s", envName, find, replacement);
161
+ const resolved = mappings.get(id);
162
+ if (resolved) {
163
+ log("Resolved %s -> %s for env=%s", id, resolved, envName);
164
+ return resolved;
139
165
  }
140
- log("Environment %s configured with %d aliases and %d optimizeDeps includes", envName, mappings.size, reactImports.length);
141
- }
166
+ verboseLog("No resolution found for id=%s in env=%s", id, envName);
167
+ },
142
168
  },
143
- async resolveId(id, importer) {
144
- if (!isBuild) {
145
- return;
146
- }
147
- const envName = this.environment?.name;
148
- if (!envName) {
149
- return;
150
- }
151
- verboseLog("Resolving id=%s, environment=%s, importer=%s", id, envName, importer);
152
- const mappings = ENV_IMPORT_MAPPINGS[envName];
153
- if (!mappings) {
154
- verboseLog("No mappings found for environment: %s", envName);
155
- return;
156
- }
157
- const resolved = mappings.get(id);
158
- if (resolved) {
159
- log("Resolved %s -> %s for env=%s", id, resolved, envName);
160
- return resolved;
161
- }
162
- verboseLog("No resolution found for id=%s in env=%s", id, envName);
163
- },
164
- };
169
+ ];
165
170
  };
@@ -6,7 +6,7 @@ export type RedwoodPluginOptions = {
6
6
  includeCloudflarePlugin?: boolean;
7
7
  configPath?: string;
8
8
  entry?: {
9
- client?: string;
9
+ client?: string | string[];
10
10
  worker?: string;
11
11
  };
12
12
  };
@@ -1,4 +1,5 @@
1
1
  import { resolve } from "node:path";
2
+ import { unstable_readConfig } from "wrangler";
2
3
  import { cloudflare } from "@cloudflare/vite-plugin";
3
4
  import { hasOwnCloudflareVitePlugin } from "./hasOwnCloudflareVitePlugin.mjs";
4
5
  import reactPlugin from "@vitejs/plugin-react";
@@ -20,12 +21,22 @@ import { prismaPlugin } from "./prismaPlugin.mjs";
20
21
  import { ssrBridgePlugin } from "./ssrBridgePlugin.mjs";
21
22
  import { hasPkgScript } from "../lib/hasPkgScript.mjs";
22
23
  import { devServerTimingPlugin } from "./devServerTimingPlugin.mjs";
24
+ const determineWorkerEntryPathname = async (projectRootDir, workerConfigPath, options) => {
25
+ if (options.entry?.worker) {
26
+ return resolve(projectRootDir, options.entry.worker);
27
+ }
28
+ const workerConfig = unstable_readConfig({ config: workerConfigPath });
29
+ return resolve(projectRootDir, workerConfig.main ?? "src/worker.tsx");
30
+ };
23
31
  export const redwoodPlugin = async (options = {}) => {
24
32
  const projectRootDir = process.cwd();
25
33
  const mode = options.mode ??
26
34
  (process.env.NODE_ENV === "development" ? "development" : "production");
27
- const clientEntryPathname = resolve(projectRootDir, options?.entry?.client ?? "src/client.tsx");
28
- const workerEntryPathname = resolve(projectRootDir, options?.entry?.worker ?? "src/worker.tsx");
35
+ const workerConfigPath = options.configPath ?? (await findWranglerConfig(projectRootDir));
36
+ const workerEntryPathname = await determineWorkerEntryPathname(projectRootDir, workerConfigPath, options);
37
+ const clientEntryPathnames = (Array.isArray(options.entry?.client)
38
+ ? options.entry.client
39
+ : [options.entry?.client ?? "src/client.tsx"]).map((entry) => resolve(projectRootDir, entry));
29
40
  const clientFiles = new Set();
30
41
  const serverFiles = new Set();
31
42
  const shouldIncludeCloudflarePlugin = options.includeCloudflarePlugin ??
@@ -49,7 +60,7 @@ export const redwoodPlugin = async (options = {}) => {
49
60
  mode,
50
61
  silent: options.silent ?? false,
51
62
  projectRootDir,
52
- clientEntryPathname,
63
+ clientEntryPathnames,
53
64
  workerEntryPathname,
54
65
  }),
55
66
  ssrBridgePlugin({
@@ -62,7 +73,7 @@ export const redwoodPlugin = async (options = {}) => {
62
73
  shouldIncludeCloudflarePlugin
63
74
  ? cloudflare({
64
75
  viteEnvironment: { name: "worker" },
65
- configPath: options.configPath ?? (await findWranglerConfig(projectRootDir)),
76
+ configPath: workerConfigPath,
66
77
  })
67
78
  : [],
68
79
  miniflareHMRPlugin({
@@ -77,7 +88,7 @@ export const redwoodPlugin = async (options = {}) => {
77
88
  serverFiles,
78
89
  }),
79
90
  vitePreamblePlugin(),
80
- injectVitePreamble({ clientEntryPathname, mode }),
91
+ injectVitePreamble({ clientEntryPathnames, mode }),
81
92
  useClientLookupPlugin({
82
93
  projectRootDir,
83
94
  clientFiles,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rwsdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.2-test.20250626055636",
4
4
  "description": "Build fast, server-driven webapps on Cloudflare with SSR, RSC, and realtime",
5
5
  "type": "module",
6
6
  "bin": {