rwsdk 0.1.8 → 0.1.10
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.
- package/bin/rwsync +11 -1
- package/dist/runtime/lib/db/typeInference/assert.d.ts +2 -0
- package/dist/runtime/lib/db/typeInference/assert.js +1 -0
- package/dist/runtime/lib/db/typeInference/builders/alterColumn.d.ts +25 -10
- package/dist/runtime/lib/db/typeInference/builders/alterTable.d.ts +48 -16
- package/dist/runtime/lib/db/typeInference/builders/columnDefinition.d.ts +25 -8
- package/dist/runtime/lib/db/typeInference/builders/createTable.d.ts +39 -4
- package/dist/runtime/lib/db/typeInference/builders/createView.d.ts +6 -2
- package/dist/runtime/lib/db/typeInference/builders/dropTable.d.ts +4 -0
- package/dist/runtime/lib/db/typeInference/builders/dropView.d.ts +5 -0
- package/dist/runtime/lib/db/typeInference/builders/schema.d.ts +16 -4
- package/dist/runtime/lib/db/typeInference/database.d.ts +13 -24
- package/dist/runtime/lib/db/typeInference/typetests/alterTable.typetest.js +272 -17
- package/dist/runtime/lib/db/typeInference/typetests/dropTable.typetest.js +57 -0
- package/dist/runtime/lib/db/typeInference/typetests/print.d.ts +3 -0
- package/dist/runtime/lib/db/typeInference/typetests/print.js +1 -0
- package/dist/runtime/lib/db/typeInference/utils.d.ts +72 -4
- package/dist/runtime/lib/db/typeInference/utils.js +1 -0
- package/dist/runtime/lib/realtime/client.js +2 -2
- package/dist/scripts/debug-sync.d.mts +1 -3
- package/dist/scripts/debug-sync.mjs +152 -64
- package/package.json +4 -1
package/bin/rwsync
CHANGED
|
@@ -1,2 +1,12 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
|
-
|
|
2
|
+
set -e
|
|
3
|
+
|
|
4
|
+
# This script is a lightweight wrapper that passes all arguments to the underlying
|
|
5
|
+
# debug:sync Node.js script.
|
|
6
|
+
# The RWSDK_REPO env var should point to the root of the sdk repo.
|
|
7
|
+
|
|
8
|
+
# Capture the current directory *before* changing it
|
|
9
|
+
TARGET_DIR=$PWD
|
|
10
|
+
|
|
11
|
+
cd "${RWSDK_REPO}/sdk"
|
|
12
|
+
pnpm debug:sync "$TARGET_DIR" "$@"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,12 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
dropNotNull(): AlteredColumnBuilder<"dropNotNull", true>;
|
|
1
|
+
import { AlterColumnNode } from "kysely";
|
|
2
|
+
import { Alteration } from "../utils";
|
|
3
|
+
export interface AlteredColumnBuilder<TAlteration extends Alteration> {
|
|
4
|
+
readonly __alteration: TAlteration;
|
|
5
|
+
toOperationNode(): AlterColumnNode;
|
|
7
6
|
}
|
|
8
|
-
export interface
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
export interface AlterColumnBuilder {
|
|
8
|
+
setDataType<T extends string>(dataType: T): AlteredColumnBuilder<{
|
|
9
|
+
kind: "setDataType";
|
|
10
|
+
dataType: T;
|
|
11
|
+
}>;
|
|
12
|
+
setDefault<T>(value: T): AlteredColumnBuilder<{
|
|
13
|
+
kind: "setDefault";
|
|
14
|
+
value: T;
|
|
15
|
+
}>;
|
|
16
|
+
dropDefault(): AlteredColumnBuilder<{
|
|
17
|
+
kind: "dropDefault";
|
|
18
|
+
}>;
|
|
19
|
+
setNotNull(): AlteredColumnBuilder<{
|
|
20
|
+
kind: "setNotNull";
|
|
21
|
+
}>;
|
|
22
|
+
dropNotNull(): AlteredColumnBuilder<{
|
|
23
|
+
kind: "dropNotNull";
|
|
24
|
+
}>;
|
|
25
|
+
$call<T>(func: (qb: this) => T): T;
|
|
11
26
|
}
|
|
12
|
-
export type AlterColumnBuilderCallback = (builder: AlterColumnBuilder) => AlteredColumnBuilder<any
|
|
27
|
+
export type AlterColumnBuilderCallback = (builder: AlterColumnBuilder) => AlteredColumnBuilder<any>;
|
|
@@ -1,21 +1,53 @@
|
|
|
1
|
-
import { SqlToTsType, ExecutedBuilder,
|
|
1
|
+
import { SqlToTsType, ExecutedBuilder, AlterOperation, AddColumnOp, DropColumnOp, RenameColumnOp, AlterColumnOp, ModifyColumnOp } from "../utils";
|
|
2
2
|
import { ColumnDefinitionBuilder } from "./columnDefinition";
|
|
3
3
|
import { AlterColumnBuilderCallback } from "./alterColumn";
|
|
4
|
-
|
|
4
|
+
import { ForeignKeyConstraintBuilder, Expression, CheckConstraintNode, UniqueConstraintNode, PrimaryKeyConstraintNode, sql } from "kysely";
|
|
5
|
+
type DataTypeExpression = string | typeof sql;
|
|
6
|
+
interface CheckConstraintBuilder {
|
|
7
|
+
$call<T>(func: (qb: this) => T): T;
|
|
8
|
+
toOperationNode(): CheckConstraintNode;
|
|
9
|
+
}
|
|
10
|
+
interface UniqueConstraintBuilder {
|
|
11
|
+
nullsNotDistinct(): UniqueConstraintBuilder;
|
|
12
|
+
deferrable(): UniqueConstraintBuilder;
|
|
13
|
+
notDeferrable(): UniqueConstraintBuilder;
|
|
14
|
+
initiallyDeferred(): UniqueConstraintBuilder;
|
|
15
|
+
initiallyImmediate(): UniqueConstraintBuilder;
|
|
16
|
+
$call<T>(func: (qb: this) => T): T;
|
|
17
|
+
toOperationNode(): UniqueConstraintNode;
|
|
18
|
+
}
|
|
19
|
+
interface PrimaryKeyConstraintBuilder {
|
|
20
|
+
deferrable(): PrimaryKeyConstraintBuilder;
|
|
21
|
+
notDeferrable(): PrimaryKeyConstraintBuilder;
|
|
22
|
+
initiallyDeferred(): PrimaryKeyConstraintBuilder;
|
|
23
|
+
initiallyImmediate(): PrimaryKeyConstraintBuilder;
|
|
24
|
+
$call<T>(func: (qb: this) => T): T;
|
|
25
|
+
toOperationNode(): PrimaryKeyConstraintNode;
|
|
26
|
+
}
|
|
27
|
+
export interface AlterTableBuilder<TName extends string, TOps extends AlterOperation[] = []> {
|
|
5
28
|
readonly __tableName: TName;
|
|
6
|
-
readonly
|
|
7
|
-
renameTo<TNewName extends string>(newTableName: TNewName): AlterTableBuilder<TNewName,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
renameColumn<KFrom extends string, KTo extends string>(from: KFrom, to: KTo): AlterTableBuilder<TName,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
[
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
29
|
+
readonly __operations: TOps;
|
|
30
|
+
renameTo<TNewName extends string>(newTableName: TNewName): AlterTableBuilder<TNewName, TOps> & {
|
|
31
|
+
readonly __renamedFrom: TName;
|
|
32
|
+
};
|
|
33
|
+
setSchema(newSchema: string): AlterTableBuilder<TName, TOps>;
|
|
34
|
+
addColumn<K extends string, T extends DataTypeExpression>(name: K, type: T, build?: (col: ColumnDefinitionBuilder<SqlToTsType<T>>) => ColumnDefinitionBuilder<SqlToTsType<T>>): AlterTableBuilder<TName, [...TOps, AddColumnOp<K, T>]>;
|
|
35
|
+
dropColumn<K extends string>(name: K): AlterTableBuilder<TName, [...TOps, DropColumnOp<K>]>;
|
|
36
|
+
renameColumn<KFrom extends string, KTo extends string>(from: KFrom, to: KTo): AlterTableBuilder<TName, [...TOps, RenameColumnOp<KFrom, KTo>]>;
|
|
37
|
+
alterColumn<K extends string, const TCallback extends AlterColumnBuilderCallback>(column: K, alteration: TCallback): AlterTableBuilder<TName, [
|
|
38
|
+
...TOps,
|
|
39
|
+
AlterColumnOp<K, ReturnType<TCallback>["__alteration"]>
|
|
40
|
+
]>;
|
|
41
|
+
modifyColumn<K extends string, T extends DataTypeExpression>(column: K, type: T, build?: (col: ColumnDefinitionBuilder<SqlToTsType<T>>) => ColumnDefinitionBuilder<SqlToTsType<T>>): AlterTableBuilder<TName, [...TOps, ModifyColumnOp<K, T>]>;
|
|
42
|
+
addUniqueConstraint(constraintName: string, columns: string[], build?: (builder: UniqueConstraintBuilder) => UniqueConstraintBuilder): AlterTableBuilder<TName, TOps>;
|
|
43
|
+
addPrimaryKeyConstraint(constraintName: string, columns: string[], build?: (builder: PrimaryKeyConstraintBuilder) => PrimaryKeyConstraintBuilder): AlterTableBuilder<TName, TOps>;
|
|
44
|
+
addCheckConstraint(constraintName: string, checkExpression: Expression<any>, build?: (builder: CheckConstraintBuilder) => CheckConstraintBuilder): AlterTableBuilder<TName, TOps>;
|
|
45
|
+
addForeignKeyConstraint(constraintName: string, columns: string[], targetTable: string, targetColumns: string[], build?: (builder: ForeignKeyConstraintBuilder) => ForeignKeyConstraintBuilder): AlterTableBuilder<TName, TOps>;
|
|
46
|
+
dropConstraint(constraintName: string): AlterTableBuilder<TName, TOps>;
|
|
47
|
+
renameConstraint(oldName: string, newName: string): AlterTableBuilder<TName, TOps>;
|
|
48
|
+
addIndex(indexName: string): AlterTableBuilder<TName, TOps>;
|
|
49
|
+
dropIndex(indexName: string): AlterTableBuilder<TName, TOps>;
|
|
20
50
|
execute(): Promise<ExecutedBuilder<this>>;
|
|
51
|
+
$call<T>(func: (qb: this) => T): T;
|
|
21
52
|
}
|
|
53
|
+
export {};
|
|
@@ -1,9 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { Expression, sql, ColumnDefinitionNode } from "kysely";
|
|
2
|
+
type DefaultValueExpression = string | number | boolean | null | typeof sql;
|
|
3
|
+
export interface ColumnDefinitionBuilder<TType> {
|
|
4
|
+
autoIncrement(): ColumnDefinitionBuilder<TType>;
|
|
5
|
+
identity(): ColumnDefinitionBuilder<TType>;
|
|
6
|
+
primaryKey(): ColumnDefinitionBuilder<TType>;
|
|
7
|
+
references(ref: string): ColumnDefinitionBuilder<TType>;
|
|
8
|
+
onDelete(onDelete: "no action" | "restrict" | "cascade" | "set null" | "set default"): ColumnDefinitionBuilder<TType>;
|
|
9
|
+
onUpdate(onUpdate: "no action" | "restrict" | "cascade" | "set null" | "set default"): ColumnDefinitionBuilder<TType>;
|
|
10
|
+
unique(): ColumnDefinitionBuilder<TType>;
|
|
11
|
+
notNull(): ColumnDefinitionBuilder<TType>;
|
|
12
|
+
unsigned(): ColumnDefinitionBuilder<TType>;
|
|
13
|
+
defaultTo(value: DefaultValueExpression): ColumnDefinitionBuilder<TType>;
|
|
14
|
+
check(expression: Expression<any>): ColumnDefinitionBuilder<TType>;
|
|
15
|
+
generatedAlwaysAs(expression: Expression<any>): ColumnDefinitionBuilder<TType>;
|
|
16
|
+
generatedAlwaysAsIdentity(): ColumnDefinitionBuilder<TType>;
|
|
17
|
+
generatedByDefaultAsIdentity(): ColumnDefinitionBuilder<TType>;
|
|
18
|
+
stored(): ColumnDefinitionBuilder<TType>;
|
|
19
|
+
modifyFront(modifier: Expression<any>): ColumnDefinitionBuilder<TType>;
|
|
20
|
+
nullsNotDistinct(): ColumnDefinitionBuilder<TType>;
|
|
21
|
+
ifNotExists(): ColumnDefinitionBuilder<TType>;
|
|
22
|
+
modifyEnd(modifier: Expression<any>): ColumnDefinitionBuilder<TType>;
|
|
23
|
+
$call<T>(func: (qb: this) => T): T;
|
|
24
|
+
toOperationNode(): ColumnDefinitionNode;
|
|
9
25
|
}
|
|
26
|
+
export {};
|
|
@@ -1,14 +1,49 @@
|
|
|
1
1
|
import { SqlToTsType, ExecutedBuilder, Prettify } from "../utils";
|
|
2
2
|
import { ColumnDefinitionBuilder } from "./columnDefinition";
|
|
3
|
+
import { CompiledQuery, CreateTableNode, Expression, ForeignKeyConstraintBuilder, CheckConstraintNode, UniqueConstraintNode, PrimaryKeyConstraintNode } from "kysely";
|
|
4
|
+
interface CheckConstraintBuilder {
|
|
5
|
+
$call<T>(func: (qb: this) => T): T;
|
|
6
|
+
toOperationNode(): CheckConstraintNode;
|
|
7
|
+
}
|
|
8
|
+
interface UniqueConstraintBuilder {
|
|
9
|
+
nullsNotDistinct(): UniqueConstraintBuilder;
|
|
10
|
+
deferrable(): UniqueConstraintBuilder;
|
|
11
|
+
notDeferrable(): UniqueConstraintBuilder;
|
|
12
|
+
initiallyDeferred(): UniqueConstraintBuilder;
|
|
13
|
+
initiallyImmediate(): UniqueConstraintBuilder;
|
|
14
|
+
$call<T>(func: (qb: this) => T): T;
|
|
15
|
+
toOperationNode(): UniqueConstraintNode;
|
|
16
|
+
}
|
|
17
|
+
interface PrimaryKeyConstraintBuilder {
|
|
18
|
+
deferrable(): PrimaryKeyConstraintBuilder;
|
|
19
|
+
notDeferrable(): PrimaryKeyConstraintBuilder;
|
|
20
|
+
initiallyDeferred(): PrimaryKeyConstraintBuilder;
|
|
21
|
+
initiallyImmediate(): PrimaryKeyConstraintBuilder;
|
|
22
|
+
$call<T>(func: (qb: this) => T): T;
|
|
23
|
+
toOperationNode(): PrimaryKeyConstraintNode;
|
|
24
|
+
}
|
|
3
25
|
export interface CreateTableBuilder<TName extends string, TSchema extends Record<string, any> = {}> {
|
|
4
26
|
readonly __tableName: TName;
|
|
5
27
|
readonly __addedColumns: TSchema;
|
|
6
28
|
temporary(): CreateTableBuilder<TName, TSchema>;
|
|
7
29
|
onCommit(onCommit: "preserve rows" | "delete rows" | "drop"): CreateTableBuilder<TName, TSchema>;
|
|
8
30
|
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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
31
|
+
addColumn<K extends string, T extends string>(name: K, type: T, build?: (col: ColumnDefinitionBuilder<SqlToTsType<T>>) => ColumnDefinitionBuilder<SqlToTsType<T>>): CreateTableBuilder<TName, Prettify<(TSchema extends Record<string, any> ? TSchema : {}) & Record<K, SqlToTsType<T>>>>;
|
|
32
|
+
addUniqueConstraint(constraintName: string, columns: (keyof TSchema)[], build?: (builder: UniqueConstraintBuilder) => UniqueConstraintBuilder): CreateTableBuilder<TName, TSchema>;
|
|
33
|
+
addPrimaryKeyConstraint(constraintName: string, columns: (keyof TSchema)[], build?: (builder: PrimaryKeyConstraintBuilder) => PrimaryKeyConstraintBuilder): CreateTableBuilder<TName, TSchema>;
|
|
34
|
+
addCheckConstraint(constraintName: string, checkExpression: Expression<any>, build?: (builder: CheckConstraintBuilder) => CheckConstraintBuilder): CreateTableBuilder<TName, TSchema>;
|
|
35
|
+
addForeignKeyConstraint(constraintName: string, columns: (keyof TSchema)[], targetTable: string, targetColumns: string[], build?: (builder: ForeignKeyConstraintBuilder) => ForeignKeyConstraintBuilder): CreateTableBuilder<TName, TSchema>;
|
|
36
|
+
modifyFront(modifier: Expression<any>): CreateTableBuilder<TName, TSchema>;
|
|
37
|
+
modifyEnd(modifier: Expression<any>): CreateTableBuilder<TName, TSchema>;
|
|
38
|
+
as(expression: Expression<any>): CreateTableBuilder<TName, TSchema>;
|
|
13
39
|
execute(): Promise<ExecutedBuilder<this>>;
|
|
40
|
+
$call<T>(func: (qb: this) => T): T;
|
|
41
|
+
compile(): CompiledQuery;
|
|
42
|
+
toOperationNode(): CreateTableNode;
|
|
43
|
+
withSchema(schema: string): CreateTableBuilder<TName, TSchema>;
|
|
44
|
+
ownerTo(owner: string): CreateTableBuilder<TName, TSchema>;
|
|
45
|
+
replace(): CreateTableBuilder<TName, TSchema>;
|
|
46
|
+
ignore(): CreateTableBuilder<TName, TSchema>;
|
|
47
|
+
withoutTableConstraintValidation(): CreateTableBuilder<TName, TSchema>;
|
|
14
48
|
}
|
|
49
|
+
export {};
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { ExecutedBuilder } from "../utils";
|
|
2
|
+
import { CreateViewNode, CompiledQuery, SelectQueryBuilder, RawBuilder } from "kysely";
|
|
2
3
|
export interface CreateViewBuilder<TName extends string, TSchema extends Record<string, any> = {}, TColumns extends string[] = []> {
|
|
3
4
|
readonly __viewName: TName;
|
|
4
5
|
readonly __schema: TSchema;
|
|
5
6
|
readonly __columns: TColumns;
|
|
6
|
-
withSchema<S extends Record<string, any>>(): CreateViewBuilder<TName, S, TColumns>;
|
|
7
7
|
temporary(): CreateViewBuilder<TName, TSchema, TColumns>;
|
|
8
8
|
orReplace(): CreateViewBuilder<TName, TSchema, TColumns>;
|
|
9
9
|
ifNotExists(): CreateViewBuilder<TName, TSchema, TColumns>;
|
|
10
10
|
columns<C extends string[]>(columns: C): CreateViewBuilder<TName, TSchema, C>;
|
|
11
|
-
as<
|
|
11
|
+
as(query: SelectQueryBuilder<any, any, any> | RawBuilder<any>): CreateViewBuilder<TName, TSchema, TColumns>;
|
|
12
12
|
execute(): Promise<ExecutedBuilder<this>>;
|
|
13
|
+
toOperationNode(): CreateViewNode;
|
|
14
|
+
compile(): CompiledQuery;
|
|
15
|
+
$call<T>(func: (qb: this) => T): T;
|
|
16
|
+
materialized(): CreateViewBuilder<TName, TSchema, TColumns>;
|
|
13
17
|
}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { ExecutedBuilder } from "../utils";
|
|
2
|
+
import { DropTableNode, CompiledQuery } from "kysely";
|
|
2
3
|
export interface DropTableBuilder<TName extends string> {
|
|
3
4
|
readonly __tableName: TName;
|
|
4
5
|
ifExists(): DropTableBuilder<TName>;
|
|
5
6
|
cascade(): DropTableBuilder<TName>;
|
|
6
7
|
execute(): Promise<ExecutedBuilder<this>>;
|
|
8
|
+
toOperationNode(): DropTableNode;
|
|
9
|
+
compile(): CompiledQuery;
|
|
10
|
+
$call<T>(func: (qb: this) => T): T;
|
|
7
11
|
}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { ExecutedBuilder } from "../utils";
|
|
2
|
+
import { DropViewNode, CompiledQuery } from "kysely";
|
|
2
3
|
export interface DropViewBuilder<TName extends string> {
|
|
3
4
|
readonly __viewName: TName;
|
|
4
5
|
ifExists(): DropViewBuilder<TName>;
|
|
5
6
|
cascade(): DropViewBuilder<TName>;
|
|
6
7
|
execute(): Promise<ExecutedBuilder<this>>;
|
|
8
|
+
toOperationNode(): DropViewNode;
|
|
9
|
+
compile(): CompiledQuery;
|
|
10
|
+
$call<T>(func: (qb: this) => T): T;
|
|
11
|
+
materialized(): DropViewBuilder<TName>;
|
|
7
12
|
}
|
|
@@ -1,12 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CreateTableBuilder } from "./createTable";
|
|
2
2
|
import { AlterTableBuilder } from "./alterTable";
|
|
3
3
|
import { DropTableBuilder } from "./dropTable";
|
|
4
4
|
import { CreateViewBuilder } from "./createView";
|
|
5
5
|
import { DropViewBuilder } from "./dropView";
|
|
6
|
+
import { CreateIndexBuilder, DropIndexBuilder, CreateSchemaBuilder, DropSchemaBuilder, CreateTypeBuilder, DropTypeBuilder, KyselyPlugin, RefreshMaterializedViewBuilder } from "kysely";
|
|
6
7
|
export interface SchemaBuilder {
|
|
7
|
-
createTable<TName extends string>(name: TName):
|
|
8
|
-
alterTable<TName extends string>(name: TName): AlterTableBuilder<TName,
|
|
8
|
+
createTable<TName extends string>(name: TName): CreateTableBuilder<TName, {}>;
|
|
9
|
+
alterTable<TName extends string>(name: TName): AlterTableBuilder<TName, []>;
|
|
9
10
|
dropTable<TName extends string>(name: TName): DropTableBuilder<TName>;
|
|
10
|
-
createView<TName extends string>(name: TName): CreateViewBuilder<TName,
|
|
11
|
+
createView<TName extends string>(name: TName): CreateViewBuilder<TName, never>;
|
|
11
12
|
dropView<TName extends string>(name: TName): DropViewBuilder<TName>;
|
|
13
|
+
withSchema(schema: string): this;
|
|
14
|
+
createIndex(name: string): CreateIndexBuilder;
|
|
15
|
+
dropIndex(name: string): DropIndexBuilder;
|
|
16
|
+
createSchema(name: string): CreateSchemaBuilder;
|
|
17
|
+
dropSchema(name: string): DropSchemaBuilder;
|
|
18
|
+
createType(name: string): CreateTypeBuilder;
|
|
19
|
+
dropType(name: string): DropTypeBuilder;
|
|
20
|
+
refreshMaterializedView(viewName: string): RefreshMaterializedViewBuilder;
|
|
21
|
+
$call<T>(func: (qb: this) => T): T;
|
|
22
|
+
withPlugin(plugin: KyselyPlugin): this;
|
|
23
|
+
withoutPlugins(): this;
|
|
12
24
|
}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { Kysely } from "kysely";
|
|
2
|
-
import { ExecutedBuilder, Prettify,
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { DropTableBuilder } from "./builders/dropTable.js";
|
|
7
|
-
import { DropViewBuilder } from "./builders/dropView.js";
|
|
2
|
+
import { ExecutedBuilder, Prettify, ProcessAlteredTable, UnionToTuple } from "./utils";
|
|
3
|
+
import { CreateTableBuilder } from "./builders/createTable";
|
|
4
|
+
import { AlterTableBuilder } from "./builders/alterTable";
|
|
5
|
+
import { DropTableBuilder } from "./builders/dropTable";
|
|
8
6
|
import { SchemaBuilder } from "./builders/schema";
|
|
9
7
|
export interface InferenceBuilder {
|
|
10
8
|
schema: SchemaBuilder;
|
|
@@ -17,22 +15,13 @@ export interface Migration<TUpReturn = unknown> {
|
|
|
17
15
|
export type Migrations = Record<string, Migration>;
|
|
18
16
|
type GetBuilder<T> = T extends ExecutedBuilder<infer B> ? B : never;
|
|
19
17
|
type BuildersFromMigration<TMigration extends Migration> = TMigration extends Migration<infer TUpReturn> ? Awaited<TUpReturn> extends Array<infer Item> ? GetBuilder<Item> : GetBuilder<Awaited<TUpReturn>> : never;
|
|
20
|
-
type
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
type
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
type
|
|
28
|
-
type
|
|
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;
|
|
18
|
+
type ApplyBuilder<TSchema, TBuilder> = TBuilder extends CreateTableBuilder<infer TName, infer TSch> ? Prettify<TSchema & Record<TName, TSch>> : TBuilder extends DropTableBuilder<infer TName> ? Omit<TSchema, TName> : TBuilder extends AlterTableBuilder<infer TName, infer TOps> ? TBuilder extends {
|
|
19
|
+
__renamedFrom: infer From extends string;
|
|
20
|
+
} ? From extends keyof TSchema ? Prettify<Omit<TSchema, From> & Record<TName, ProcessAlteredTable<TSchema[From], TOps>>> : TSchema : TName extends keyof TSchema ? Prettify<Omit<TSchema, TName> & Record<TName, ProcessAlteredTable<TSchema[TName], TOps>>> : TSchema : TSchema;
|
|
21
|
+
type ApplyBuilders<TSchema, TBuildersTuple> = TBuildersTuple extends [
|
|
22
|
+
infer THead,
|
|
23
|
+
...infer TRest
|
|
24
|
+
] ? ApplyBuilders<ApplyBuilder<TSchema, THead>, TRest> : TSchema;
|
|
25
|
+
type ProcessMigrations<TMigrations extends Migrations, TKeys, TSchema = {}> = TKeys extends [infer THeadKey, ...infer TRestKeys] ? THeadKey extends keyof TMigrations ? ProcessMigrations<TMigrations, TRestKeys, ApplyBuilders<TSchema, UnionToTuple<BuildersFromMigration<TMigrations[THeadKey]>>>> : TSchema : TSchema;
|
|
26
|
+
export type Database<TMigrations extends Migrations = Migrations> = ProcessMigrations<TMigrations, UnionToTuple<keyof TMigrations>>;
|
|
38
27
|
export {};
|
|
@@ -23,15 +23,37 @@
|
|
|
23
23
|
};
|
|
24
24
|
(_test) => { };
|
|
25
25
|
};
|
|
26
|
-
(_it = "alterTable renameColumn
|
|
26
|
+
(_it = "alterTable renameColumn") => {
|
|
27
|
+
const migrations = {
|
|
28
|
+
"0001_initial": {
|
|
29
|
+
up: async (db) => [
|
|
30
|
+
await db.schema
|
|
31
|
+
.createTable("users")
|
|
32
|
+
.addColumn("id", "integer", (c) => c.primaryKey().autoIncrement())
|
|
33
|
+
.addColumn("username", "text")
|
|
34
|
+
.addColumn("displayName", "text")
|
|
35
|
+
.execute(),
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
"0002_rename_column": {
|
|
39
|
+
up: async (db) => [
|
|
40
|
+
await db.schema
|
|
41
|
+
.alterTable("users")
|
|
42
|
+
.renameColumn("displayName", "nickname")
|
|
43
|
+
.execute(),
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
(_test) => { };
|
|
48
|
+
};
|
|
49
|
+
(_it = "alterTable alterColumn setDataType and setDefault") => {
|
|
27
50
|
const migrations = {
|
|
28
51
|
"0": {
|
|
29
52
|
async up(db) {
|
|
30
53
|
return [
|
|
31
54
|
await db.schema
|
|
32
55
|
.createTable("users")
|
|
33
|
-
.addColumn("
|
|
34
|
-
.addColumn("displayName", "text")
|
|
56
|
+
.addColumn("age", "integer")
|
|
35
57
|
.execute(),
|
|
36
58
|
];
|
|
37
59
|
},
|
|
@@ -41,8 +63,8 @@
|
|
|
41
63
|
return [
|
|
42
64
|
await db.schema
|
|
43
65
|
.alterTable("users")
|
|
44
|
-
.
|
|
45
|
-
.
|
|
66
|
+
.alterColumn("age", (col) => col.setDataType("text"))
|
|
67
|
+
.alterColumn("age", (col) => col.setDefault("unknown"))
|
|
46
68
|
.execute(),
|
|
47
69
|
];
|
|
48
70
|
},
|
|
@@ -50,32 +72,60 @@
|
|
|
50
72
|
};
|
|
51
73
|
(_test) => { };
|
|
52
74
|
};
|
|
53
|
-
(_it = "alterTable alterColumn
|
|
75
|
+
(_it = "alterTable alterColumn dropDefault, setNotNull, dropNotNull") => {
|
|
54
76
|
const migrations = {
|
|
55
77
|
"0": {
|
|
56
78
|
async up(db) {
|
|
57
79
|
return [
|
|
58
|
-
db.schema
|
|
80
|
+
await db.schema
|
|
81
|
+
.createTable("users")
|
|
82
|
+
.addColumn("age", "integer")
|
|
83
|
+
.execute(),
|
|
59
84
|
];
|
|
60
85
|
},
|
|
61
86
|
},
|
|
62
87
|
"1": {
|
|
63
88
|
async up(db) {
|
|
64
89
|
return [
|
|
65
|
-
db.schema
|
|
90
|
+
await db.schema
|
|
66
91
|
.alterTable("users")
|
|
67
|
-
.alterColumn("age", (col) => col.
|
|
68
|
-
.alterColumn("age", (col) => col.
|
|
92
|
+
.alterColumn("age", (col) => col.dropDefault())
|
|
93
|
+
.alterColumn("age", (col) => col.setNotNull())
|
|
94
|
+
.alterColumn("age", (col) => col.dropNotNull())
|
|
69
95
|
.execute(),
|
|
70
96
|
];
|
|
71
97
|
},
|
|
72
98
|
},
|
|
73
99
|
};
|
|
74
|
-
//
|
|
75
|
-
// @ts-ignore
|
|
76
|
-
(_test) => { };
|
|
100
|
+
//(_test: Expect<Equal<Actual, Expected>>) => {};
|
|
77
101
|
};
|
|
78
|
-
(_it = "alterTable
|
|
102
|
+
(_it = "alterTable addUniqueConstraint") => {
|
|
103
|
+
const migrations = {
|
|
104
|
+
"0": {
|
|
105
|
+
async up(db) {
|
|
106
|
+
return [
|
|
107
|
+
await db.schema
|
|
108
|
+
.createTable("users")
|
|
109
|
+
.addColumn("firstName", "text")
|
|
110
|
+
.addColumn("lastName", "text")
|
|
111
|
+
.execute(),
|
|
112
|
+
];
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
"1": {
|
|
116
|
+
async up(db) {
|
|
117
|
+
return [
|
|
118
|
+
await db.schema
|
|
119
|
+
.alterTable("users")
|
|
120
|
+
.addUniqueConstraint("unique_name", ["firstName", "lastName"])
|
|
121
|
+
.execute(),
|
|
122
|
+
];
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
//(_test: Expect<Equal<Actual, Expected>>) => {};
|
|
127
|
+
};
|
|
128
|
+
(_it = "alterTable drop column") => {
|
|
79
129
|
const migrations = {
|
|
80
130
|
"0": {
|
|
81
131
|
async up(db) {
|
|
@@ -87,14 +137,219 @@
|
|
|
87
137
|
];
|
|
88
138
|
},
|
|
89
139
|
},
|
|
140
|
+
"1": {
|
|
141
|
+
async up(db) {
|
|
142
|
+
return [
|
|
143
|
+
await db.schema.alterTable("users").dropColumn("age").execute(),
|
|
144
|
+
];
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
(_test) => { };
|
|
149
|
+
};
|
|
150
|
+
(_it = "alterTable renameTable") => {
|
|
151
|
+
const migrations = {
|
|
152
|
+
"0001_initial": {
|
|
153
|
+
up: async (db) => [
|
|
154
|
+
await db.schema
|
|
155
|
+
.createTable("users")
|
|
156
|
+
.addColumn("id", "integer")
|
|
157
|
+
.execute(),
|
|
158
|
+
],
|
|
159
|
+
},
|
|
160
|
+
"0002_rename_table": {
|
|
161
|
+
up: async (db) => [
|
|
162
|
+
await db.schema.alterTable("users").renameTo("customers").execute(),
|
|
163
|
+
],
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
(_test) => { };
|
|
167
|
+
};
|
|
168
|
+
(_it = "alterTable renameColumn then rename again") => {
|
|
169
|
+
const migrations = {
|
|
170
|
+
"0": {
|
|
171
|
+
async up(db) {
|
|
172
|
+
return [
|
|
173
|
+
await db.schema
|
|
174
|
+
.createTable("users")
|
|
175
|
+
.addColumn("name", "text")
|
|
176
|
+
.execute(),
|
|
177
|
+
];
|
|
178
|
+
},
|
|
179
|
+
},
|
|
90
180
|
"1": {
|
|
91
181
|
async up(db) {
|
|
92
182
|
return [
|
|
93
183
|
await db.schema
|
|
94
184
|
.alterTable("users")
|
|
95
|
-
.
|
|
96
|
-
.
|
|
97
|
-
|
|
185
|
+
.renameColumn("name", "firstName")
|
|
186
|
+
.execute(),
|
|
187
|
+
];
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
"2": {
|
|
191
|
+
async up(db) {
|
|
192
|
+
return [
|
|
193
|
+
await db.schema
|
|
194
|
+
.alterTable("users")
|
|
195
|
+
.renameColumn("firstName", "givenName")
|
|
196
|
+
.execute(),
|
|
197
|
+
];
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
};
|
|
201
|
+
(_test) => { };
|
|
202
|
+
};
|
|
203
|
+
(_it = "alterTable renameColumn then rename back") => {
|
|
204
|
+
const migrations = {
|
|
205
|
+
"0": {
|
|
206
|
+
async up(db) {
|
|
207
|
+
return [
|
|
208
|
+
await db.schema
|
|
209
|
+
.createTable("users")
|
|
210
|
+
.addColumn("name", "text")
|
|
211
|
+
.execute(),
|
|
212
|
+
];
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
"1": {
|
|
216
|
+
async up(db) {
|
|
217
|
+
return [
|
|
218
|
+
await db.schema
|
|
219
|
+
.alterTable("users")
|
|
220
|
+
.renameColumn("name", "firstName")
|
|
221
|
+
.execute(),
|
|
222
|
+
];
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
"2": {
|
|
226
|
+
async up(db) {
|
|
227
|
+
return [
|
|
228
|
+
await db.schema
|
|
229
|
+
.alterTable("users")
|
|
230
|
+
.renameColumn("firstName", "name")
|
|
231
|
+
.execute(),
|
|
232
|
+
];
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
};
|
|
236
|
+
(_test) => { };
|
|
237
|
+
};
|
|
238
|
+
(_it = "alterTable renameTable then rename again") => {
|
|
239
|
+
const migrations = {
|
|
240
|
+
"0": {
|
|
241
|
+
async up(db) {
|
|
242
|
+
return [
|
|
243
|
+
await db.schema
|
|
244
|
+
.createTable("users")
|
|
245
|
+
.addColumn("id", "integer")
|
|
246
|
+
.execute(),
|
|
247
|
+
];
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
"1": {
|
|
251
|
+
async up(db) {
|
|
252
|
+
return [
|
|
253
|
+
await db.schema.alterTable("users").renameTo("customers").execute(),
|
|
254
|
+
];
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
"2": {
|
|
258
|
+
async up(db) {
|
|
259
|
+
return [
|
|
260
|
+
await db.schema.alterTable("customers").renameTo("clients").execute(),
|
|
261
|
+
];
|
|
262
|
+
},
|
|
263
|
+
},
|
|
264
|
+
};
|
|
265
|
+
(_test) => { };
|
|
266
|
+
};
|
|
267
|
+
(_it = "alterTable renameTable then rename back") => {
|
|
268
|
+
const migrations = {
|
|
269
|
+
"0": {
|
|
270
|
+
async up(db) {
|
|
271
|
+
return [
|
|
272
|
+
await db.schema
|
|
273
|
+
.createTable("users")
|
|
274
|
+
.addColumn("id", "integer")
|
|
275
|
+
.execute(),
|
|
276
|
+
];
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
"1": {
|
|
280
|
+
async up(db) {
|
|
281
|
+
return [
|
|
282
|
+
await db.schema.alterTable("users").renameTo("customers").execute(),
|
|
283
|
+
];
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
"2": {
|
|
287
|
+
async up(db) {
|
|
288
|
+
return [
|
|
289
|
+
await db.schema.alterTable("customers").renameTo("users").execute(),
|
|
290
|
+
];
|
|
291
|
+
},
|
|
292
|
+
},
|
|
293
|
+
};
|
|
294
|
+
(_test) => { };
|
|
295
|
+
};
|
|
296
|
+
(_it = "alterTable renameColumn then drop") => {
|
|
297
|
+
const migrations = {
|
|
298
|
+
"0": {
|
|
299
|
+
async up(db) {
|
|
300
|
+
return [
|
|
301
|
+
await db.schema
|
|
302
|
+
.createTable("users")
|
|
303
|
+
.addColumn("name", "text")
|
|
304
|
+
.execute(),
|
|
305
|
+
];
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
"1": {
|
|
309
|
+
async up(db) {
|
|
310
|
+
return [
|
|
311
|
+
await db.schema
|
|
312
|
+
.alterTable("users")
|
|
313
|
+
.renameColumn("name", "firstName")
|
|
314
|
+
.execute(),
|
|
315
|
+
];
|
|
316
|
+
},
|
|
317
|
+
},
|
|
318
|
+
"2": {
|
|
319
|
+
async up(db) {
|
|
320
|
+
return [
|
|
321
|
+
await db.schema.alterTable("users").dropColumn("firstName").execute(),
|
|
322
|
+
];
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
};
|
|
326
|
+
(_test) => { };
|
|
327
|
+
};
|
|
328
|
+
(_it = "alterTable dropColumn then add back") => {
|
|
329
|
+
const migrations = {
|
|
330
|
+
"0": {
|
|
331
|
+
async up(db) {
|
|
332
|
+
return [
|
|
333
|
+
await db.schema
|
|
334
|
+
.createTable("users")
|
|
335
|
+
.addColumn("name", "text")
|
|
336
|
+
.execute(),
|
|
337
|
+
];
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
"1": {
|
|
341
|
+
async up(db) {
|
|
342
|
+
return [
|
|
343
|
+
await db.schema.alterTable("users").dropColumn("name").execute(),
|
|
344
|
+
];
|
|
345
|
+
},
|
|
346
|
+
},
|
|
347
|
+
"2": {
|
|
348
|
+
async up(db) {
|
|
349
|
+
return [
|
|
350
|
+
await db.schema
|
|
351
|
+
.alterTable("users")
|
|
352
|
+
.addColumn("name", "text")
|
|
98
353
|
.execute(),
|
|
99
354
|
];
|
|
100
355
|
},
|
|
@@ -83,4 +83,61 @@
|
|
|
83
83
|
};
|
|
84
84
|
(_test) => { };
|
|
85
85
|
};
|
|
86
|
+
(_it = "drop table then add it back") => {
|
|
87
|
+
const migrations = {
|
|
88
|
+
"0": {
|
|
89
|
+
async up(db) {
|
|
90
|
+
return [
|
|
91
|
+
await db.schema
|
|
92
|
+
.createTable("users")
|
|
93
|
+
.addColumn("username", "text")
|
|
94
|
+
.execute(),
|
|
95
|
+
];
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
"1": {
|
|
99
|
+
async up(db) {
|
|
100
|
+
return [await db.schema.dropTable("users").execute()];
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
"2": {
|
|
104
|
+
async up(db) {
|
|
105
|
+
return [
|
|
106
|
+
await db.schema
|
|
107
|
+
.createTable("users")
|
|
108
|
+
.addColumn("username", "text")
|
|
109
|
+
.execute(),
|
|
110
|
+
];
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
(_test) => { };
|
|
115
|
+
};
|
|
116
|
+
(_it = "rename table then drop it") => {
|
|
117
|
+
const migrations = {
|
|
118
|
+
"0": {
|
|
119
|
+
async up(db) {
|
|
120
|
+
return [
|
|
121
|
+
await db.schema
|
|
122
|
+
.createTable("users")
|
|
123
|
+
.addColumn("username", "text")
|
|
124
|
+
.execute(),
|
|
125
|
+
];
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
"1": {
|
|
129
|
+
async up(db) {
|
|
130
|
+
return [
|
|
131
|
+
await db.schema.alterTable("users").renameTo("customers").execute(),
|
|
132
|
+
];
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
"2": {
|
|
136
|
+
async up(db) {
|
|
137
|
+
return [await db.schema.dropTable("customers").execute()];
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
(_test) => { };
|
|
142
|
+
};
|
|
86
143
|
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,14 +1,82 @@
|
|
|
1
|
-
|
|
1
|
+
import { sql } from "kysely";
|
|
2
|
+
type DataTypeExpression = string | typeof sql;
|
|
3
|
+
export type AddColumnOp<K extends string, T extends DataTypeExpression> = {
|
|
4
|
+
op: "addColumn";
|
|
5
|
+
name: K;
|
|
6
|
+
type: T;
|
|
7
|
+
};
|
|
8
|
+
export type DropColumnOp<K extends string> = {
|
|
9
|
+
op: "dropColumn";
|
|
10
|
+
name: K;
|
|
11
|
+
};
|
|
12
|
+
export type RenameColumnOp<KFrom extends string, KTo extends string> = {
|
|
13
|
+
op: "renameColumn";
|
|
14
|
+
from: KFrom;
|
|
15
|
+
to: KTo;
|
|
16
|
+
};
|
|
17
|
+
export type ModifyColumnOp<K extends string, T extends DataTypeExpression> = {
|
|
18
|
+
op: "modifyColumn";
|
|
19
|
+
name: K;
|
|
20
|
+
type: T;
|
|
21
|
+
};
|
|
22
|
+
export type Alteration = {
|
|
23
|
+
kind: "setDataType";
|
|
24
|
+
dataType: string;
|
|
25
|
+
} | {
|
|
26
|
+
kind: "setDefault";
|
|
27
|
+
value: any;
|
|
28
|
+
} | {
|
|
29
|
+
kind: "dropDefault";
|
|
30
|
+
} | {
|
|
31
|
+
kind: "setNotNull";
|
|
32
|
+
} | {
|
|
33
|
+
kind: "dropNotNull";
|
|
34
|
+
};
|
|
35
|
+
export type AlterColumnOp<K extends string, TAlteration extends Alteration> = {
|
|
36
|
+
op: "alterColumn";
|
|
37
|
+
name: K;
|
|
38
|
+
alteration: TAlteration;
|
|
39
|
+
};
|
|
40
|
+
export type AlterOperation = AddColumnOp<any, any> | DropColumnOp<any> | RenameColumnOp<any, any> | AlterColumnOp<any, any> | ModifyColumnOp<any, any>;
|
|
41
|
+
export type SqlToTsType<T extends string | typeof sql> = T extends "text" ? string : T extends "integer" ? number : T extends "blob" ? Uint8Array : T extends "real" ? number : T extends "boolean" ? boolean : T extends typeof sql ? any : never;
|
|
2
42
|
export type Prettify<T> = {
|
|
3
43
|
[K in keyof T]: T[K];
|
|
4
44
|
} & {};
|
|
5
45
|
export type ExecutedBuilder<T> = {
|
|
6
46
|
__builder_type: T;
|
|
7
47
|
};
|
|
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
|
-
};
|
|
48
|
+
export type MergeSchemas<A, B> = Prettify<Omit<A, keyof B> & B>;
|
|
11
49
|
export type OmitNever<T> = {
|
|
12
50
|
[K in keyof T as T[K] extends never ? never : K]: T[K];
|
|
13
51
|
};
|
|
14
52
|
export type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
53
|
+
export type DeepClean<T> = T extends Uint8Array ? T : T extends Record<string, any> ? {
|
|
54
|
+
[K in keyof T as T[K] extends never ? never : K]: DeepClean<T[K]>;
|
|
55
|
+
} & {} : T;
|
|
56
|
+
export type Cast<A, B> = A extends B ? A : B;
|
|
57
|
+
/**
|
|
58
|
+
* Applies a single alteration operation to a schema.
|
|
59
|
+
*/
|
|
60
|
+
type ApplyOp<TSchema, THeadOp> = THeadOp extends AddColumnOp<infer K, infer T> ? Prettify<TSchema & {
|
|
61
|
+
[P in K]: SqlToTsType<T>;
|
|
62
|
+
}> : THeadOp extends DropColumnOp<infer K> ? Omit<TSchema, K> : THeadOp extends RenameColumnOp<infer KFrom, infer KTo> ? KFrom extends keyof TSchema ? Prettify<Omit<TSchema, KFrom> & {
|
|
63
|
+
[P in KTo]: TSchema[KFrom];
|
|
64
|
+
}> : TSchema : THeadOp extends AlterColumnOp<infer K, infer TAlt> ? TAlt extends {
|
|
65
|
+
kind: "setDataType";
|
|
66
|
+
dataType: infer DT extends string;
|
|
67
|
+
} ? Prettify<Omit<TSchema, K> & {
|
|
68
|
+
[P in K]: SqlToTsType<DT>;
|
|
69
|
+
}> : TSchema : THeadOp extends ModifyColumnOp<infer K, infer T> ? Prettify<Omit<TSchema, K> & {
|
|
70
|
+
[P in K]: SqlToTsType<T>;
|
|
71
|
+
}> : TSchema;
|
|
72
|
+
/**
|
|
73
|
+
* Recursively processes a list of alteration operations (AST)
|
|
74
|
+
* to transform an initial schema into the final schema.
|
|
75
|
+
*/
|
|
76
|
+
export type ProcessAlteredTable<TInitialSchema, TOps> = TOps extends [
|
|
77
|
+
infer THeadOp,
|
|
78
|
+
...infer TRestOps
|
|
79
|
+
] ? ProcessAlteredTable<ApplyOp<TInitialSchema, THeadOp>, TRestOps> : TInitialSchema;
|
|
80
|
+
type LastOf<U> = UnionToIntersection<U extends any ? () => U : never> extends () => infer R ? R : never;
|
|
81
|
+
export type UnionToTuple<U, Last = LastOf<U>> = [U] extends [never] ? [] : [...UnionToTuple<Exclude<U, Last>>, Last];
|
|
82
|
+
export {};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { initClient } from "../../client";
|
|
2
2
|
import { createFromReadableStream } from "react-server-dom-webpack/client.browser";
|
|
3
|
-
import { IS_DEV } from "../../constants";
|
|
4
3
|
import { MESSAGE_TYPE } from "./shared";
|
|
5
4
|
const DEFAULT_KEY = "default";
|
|
6
5
|
export const initRealtimeClient = ({ key = DEFAULT_KEY, } = {}) => {
|
|
@@ -12,12 +11,13 @@ export const realtimeTransport = ({ key = DEFAULT_KEY }) => (transportContext) =
|
|
|
12
11
|
let isConnected = false;
|
|
13
12
|
const clientId = crypto.randomUUID();
|
|
14
13
|
const clientUrl = new URL(window.location.href);
|
|
14
|
+
const isHttps = clientUrl.protocol === "https:";
|
|
15
15
|
clientUrl.protocol = "";
|
|
16
16
|
clientUrl.host = "";
|
|
17
17
|
const setupWebSocket = () => {
|
|
18
18
|
if (ws)
|
|
19
19
|
return;
|
|
20
|
-
const protocol =
|
|
20
|
+
const protocol = isHttps ? "wss" : "ws";
|
|
21
21
|
ws = new WebSocket(`${protocol}://${window.location.host}/__realtime?` +
|
|
22
22
|
`key=${encodeURIComponent(key)}&` +
|
|
23
23
|
`url=${encodeURIComponent(clientUrl.toString())}&` +
|
|
@@ -1,26 +1,38 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
|
-
import { $ } from "
|
|
3
|
+
import { $ } from "execa";
|
|
4
4
|
import fs from "node:fs/promises";
|
|
5
5
|
import { existsSync } from "node:fs";
|
|
6
|
+
import chokidar from "chokidar";
|
|
7
|
+
import { lock } from "proper-lockfile";
|
|
6
8
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
9
|
const getPackageManagerInfo = (targetDir) => {
|
|
10
|
+
const pnpmResult = {
|
|
11
|
+
name: "pnpm",
|
|
12
|
+
lockFile: "pnpm-lock.yaml",
|
|
13
|
+
command: "add",
|
|
14
|
+
};
|
|
8
15
|
if (existsSync(path.join(targetDir, "yarn.lock"))) {
|
|
9
16
|
return { name: "yarn", lockFile: "yarn.lock", command: "add" };
|
|
10
17
|
}
|
|
11
18
|
if (existsSync(path.join(targetDir, "pnpm-lock.yaml"))) {
|
|
12
|
-
return
|
|
19
|
+
return pnpmResult;
|
|
13
20
|
}
|
|
14
|
-
|
|
21
|
+
if (existsSync(path.join(targetDir, "package-lock.json"))) {
|
|
22
|
+
return { name: "npm", lockFile: "package-lock.json", command: "install" };
|
|
23
|
+
}
|
|
24
|
+
return pnpmResult;
|
|
15
25
|
};
|
|
16
|
-
const
|
|
17
|
-
console.log("
|
|
18
|
-
|
|
19
|
-
console.log("📦 packing sdk...");
|
|
20
|
-
const packResult = await $({ cwd: sdkDir, shell: true }) `npm pack`;
|
|
26
|
+
const performFullSync = async (sdkDir, targetDir) => {
|
|
27
|
+
console.log("📦 Packing SDK...");
|
|
28
|
+
const packResult = await $ `npm pack`;
|
|
21
29
|
const tarballName = packResult.stdout?.trim() ?? "";
|
|
30
|
+
if (!tarballName) {
|
|
31
|
+
console.error("❌ Failed to get tarball name from npm pack.");
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
22
34
|
const tarballPath = path.resolve(sdkDir, tarballName);
|
|
23
|
-
console.log(
|
|
35
|
+
console.log(`💿 Installing ${tarballName} in ${targetDir}...`);
|
|
24
36
|
const pm = getPackageManagerInfo(targetDir);
|
|
25
37
|
const packageJsonPath = path.join(targetDir, "package.json");
|
|
26
38
|
const lockfilePath = path.join(targetDir, pm.lockFile);
|
|
@@ -31,15 +43,18 @@ const performSync = async (sdkDir, targetDir) => {
|
|
|
31
43
|
.readFile(lockfilePath, "utf-8")
|
|
32
44
|
.catch(() => null);
|
|
33
45
|
try {
|
|
34
|
-
|
|
46
|
+
const cmd = pm.name;
|
|
47
|
+
const args = [pm.command];
|
|
35
48
|
if (pm.name === "yarn") {
|
|
36
|
-
|
|
49
|
+
args.push(`file:${tarballPath}`);
|
|
37
50
|
}
|
|
38
|
-
|
|
51
|
+
else {
|
|
52
|
+
args.push(tarballPath);
|
|
53
|
+
}
|
|
54
|
+
await $(cmd, args, {
|
|
39
55
|
cwd: targetDir,
|
|
40
56
|
stdio: "inherit",
|
|
41
|
-
|
|
42
|
-
}) `${installCommand}`;
|
|
57
|
+
});
|
|
43
58
|
}
|
|
44
59
|
finally {
|
|
45
60
|
if (originalPackageJson) {
|
|
@@ -54,67 +69,140 @@ const performSync = async (sdkDir, targetDir) => {
|
|
|
54
69
|
// ignore if deletion fails
|
|
55
70
|
});
|
|
56
71
|
}
|
|
57
|
-
|
|
72
|
+
};
|
|
73
|
+
const performFastSync = async (sdkDir, targetDir) => {
|
|
74
|
+
console.log("⚡️ No dependency changes, performing fast sync...");
|
|
75
|
+
const sdkPackageJson = JSON.parse(await fs.readFile(path.join(sdkDir, "package.json"), "utf-8"));
|
|
76
|
+
const filesToSync = sdkPackageJson.files || [];
|
|
77
|
+
for (const file of filesToSync) {
|
|
78
|
+
const source = path.join(sdkDir, file);
|
|
79
|
+
const destination = path.join(targetDir, "node_modules/rwsdk", file);
|
|
80
|
+
if (existsSync(source)) {
|
|
81
|
+
await fs.cp(source, destination, { recursive: true, force: true });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// Always copy package.json
|
|
85
|
+
await fs.copyFile(path.join(sdkDir, "package.json"), path.join(targetDir, "node_modules/rwsdk/package.json"));
|
|
86
|
+
};
|
|
87
|
+
const performSync = async (sdkDir, targetDir) => {
|
|
88
|
+
console.log("🏗️ Rebuilding SDK...");
|
|
89
|
+
await $ `pnpm build`;
|
|
90
|
+
const sdkPackageJsonPath = path.join(sdkDir, "package.json");
|
|
91
|
+
const installedSdkPackageJsonPath = path.join(targetDir, "node_modules/rwsdk/package.json");
|
|
92
|
+
let packageJsonChanged = true;
|
|
93
|
+
if (existsSync(installedSdkPackageJsonPath)) {
|
|
94
|
+
const sdkPackageJsonContent = await fs.readFile(sdkPackageJsonPath, "utf-8");
|
|
95
|
+
const installedSdkPackageJsonContent = await fs.readFile(installedSdkPackageJsonPath, "utf-8");
|
|
96
|
+
if (sdkPackageJsonContent === installedSdkPackageJsonContent) {
|
|
97
|
+
packageJsonChanged = false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (packageJsonChanged) {
|
|
101
|
+
console.log("📦 package.json changed, performing full sync...");
|
|
102
|
+
await performFullSync(sdkDir, targetDir);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
await performFastSync(sdkDir, targetDir);
|
|
106
|
+
}
|
|
107
|
+
console.log("✅ Done syncing");
|
|
58
108
|
};
|
|
59
109
|
export const debugSync = async (opts) => {
|
|
60
|
-
const { targetDir, sdkDir = process.cwd(),
|
|
110
|
+
const { targetDir, sdkDir = process.cwd(), watch } = opts;
|
|
61
111
|
if (!targetDir) {
|
|
62
112
|
console.error("❌ Please provide a target directory as an argument.");
|
|
63
113
|
process.exit(1);
|
|
64
114
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (!process.env.NO_CLEAN_VITE) {
|
|
70
|
-
console.log("🧹 Cleaning Vite cache...");
|
|
71
|
-
await $({
|
|
72
|
-
stdio: "inherit",
|
|
73
|
-
shell: true,
|
|
74
|
-
cwd: targetDir,
|
|
75
|
-
}) `rm -rf ${targetDir}/node_modules/.vite*`;
|
|
76
|
-
}
|
|
77
|
-
// If dev flag is present, clean vite cache and start dev server
|
|
78
|
-
if (dev) {
|
|
79
|
-
console.log("🚀 Starting dev server...");
|
|
80
|
-
await $({ stdio: "inherit", shell: true, cwd: targetDir }) `npm run dev`;
|
|
115
|
+
// If not in watch mode, just do a one-time sync and exit.
|
|
116
|
+
if (!watch) {
|
|
117
|
+
await performSync(sdkDir, targetDir);
|
|
118
|
+
return;
|
|
81
119
|
}
|
|
82
|
-
//
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
120
|
+
// --- Watch Mode Logic ---
|
|
121
|
+
const lockfilePath = path.join(targetDir, "node_modules", ".rwsync.lock");
|
|
122
|
+
let release;
|
|
123
|
+
// Ensure the directory for the lockfile exists
|
|
124
|
+
await fs.mkdir(path.dirname(lockfilePath), { recursive: true });
|
|
125
|
+
// "Touch" the file to ensure it exists before locking
|
|
126
|
+
await fs.appendFile(lockfilePath, "").catch(() => { });
|
|
127
|
+
try {
|
|
128
|
+
release = await lock(lockfilePath, { retries: 0 });
|
|
90
129
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
130
|
+
catch (e) {
|
|
131
|
+
if (e.code === "ELOCKED") {
|
|
132
|
+
console.error(`❌ Another rwsync process is already watching ${targetDir}.`);
|
|
133
|
+
console.error(` If this is not correct, please remove the lockfile at ${lockfilePath}`);
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}
|
|
136
|
+
throw e;
|
|
98
137
|
}
|
|
138
|
+
// Initial sync for watch mode. We do it *after* acquiring the lock.
|
|
139
|
+
await performSync(sdkDir, targetDir);
|
|
140
|
+
const filesToWatch = [
|
|
141
|
+
path.join(sdkDir, "src"),
|
|
142
|
+
path.join(sdkDir, "types"),
|
|
143
|
+
path.join(sdkDir, "bin"),
|
|
144
|
+
path.join(sdkDir, "package.json"),
|
|
145
|
+
];
|
|
146
|
+
console.log("👀 Watching for changes...");
|
|
147
|
+
let childProc = null;
|
|
148
|
+
const runWatchedCommand = () => {
|
|
149
|
+
if (typeof watch === "string") {
|
|
150
|
+
console.log(`\n> ${watch}\n`);
|
|
151
|
+
childProc = $({
|
|
152
|
+
stdio: "inherit",
|
|
153
|
+
shell: true,
|
|
154
|
+
cwd: targetDir,
|
|
155
|
+
reject: false,
|
|
156
|
+
}) `${watch}`;
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
const watcher = chokidar.watch(filesToWatch, {
|
|
160
|
+
ignoreInitial: true,
|
|
161
|
+
cwd: sdkDir,
|
|
162
|
+
});
|
|
163
|
+
watcher.on("all", async () => {
|
|
164
|
+
console.log("\nDetected change, re-syncing...");
|
|
165
|
+
if (childProc && !childProc.killed) {
|
|
166
|
+
console.log("Stopping running process...");
|
|
167
|
+
childProc.kill();
|
|
168
|
+
await childProc.catch(() => {
|
|
169
|
+
/* ignore kill errors */
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
await performSync(sdkDir, targetDir);
|
|
173
|
+
runWatchedCommand();
|
|
174
|
+
});
|
|
175
|
+
const cleanup = async () => {
|
|
176
|
+
console.log("\nCleaning up...");
|
|
177
|
+
if (childProc && !childProc.killed) {
|
|
178
|
+
childProc.kill();
|
|
179
|
+
}
|
|
180
|
+
await release();
|
|
181
|
+
process.exit();
|
|
182
|
+
};
|
|
183
|
+
process.on("SIGINT", cleanup);
|
|
184
|
+
process.on("SIGTERM", cleanup);
|
|
185
|
+
runWatchedCommand();
|
|
99
186
|
};
|
|
100
187
|
if (import.meta.url === new URL(process.argv[1], import.meta.url).href) {
|
|
101
188
|
const args = process.argv.slice(2);
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
? path.resolve(__dirname, process.env.RWSDK_REPO, "sdk")
|
|
114
|
-
: path.resolve(__dirname, "..", ".."),
|
|
115
|
-
dev: flags.has("--dev"),
|
|
116
|
-
watch: flags.has("--watch"),
|
|
117
|
-
build: flags.has("--build"),
|
|
118
|
-
});
|
|
189
|
+
const watchFlagIndex = args.indexOf("--watch");
|
|
190
|
+
let watchCmd = watchFlagIndex !== -1;
|
|
191
|
+
let cmdArgs = args;
|
|
192
|
+
if (watchFlagIndex !== -1) {
|
|
193
|
+
if (watchFlagIndex + 1 < args.length &&
|
|
194
|
+
!args[watchFlagIndex + 1].startsWith("--")) {
|
|
195
|
+
watchCmd = args[watchFlagIndex + 1];
|
|
196
|
+
}
|
|
197
|
+
// remove --watch and its potential command from args
|
|
198
|
+
const watchArgCount = typeof watchCmd === "string" ? 2 : 1;
|
|
199
|
+
cmdArgs = args.filter((_, i) => i < watchFlagIndex || i >= watchFlagIndex + watchArgCount);
|
|
119
200
|
}
|
|
201
|
+
const targetDir = cmdArgs[0] ?? process.cwd();
|
|
202
|
+
const sdkDir = path.resolve(__dirname, "..", "..");
|
|
203
|
+
debugSync({
|
|
204
|
+
targetDir,
|
|
205
|
+
sdkDir,
|
|
206
|
+
watch: watchCmd,
|
|
207
|
+
});
|
|
120
208
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rwsdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"description": "Build fast, server-driven webapps on Cloudflare with SSR, RSC, and realtime",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -120,6 +120,7 @@
|
|
|
120
120
|
"@types/react-dom": "^19.1.2",
|
|
121
121
|
"@types/react-is": "^19.0.0",
|
|
122
122
|
"@vitejs/plugin-react": "^4.3.4",
|
|
123
|
+
"chokidar": "^3.6.0",
|
|
123
124
|
"debug": "^4.4.0",
|
|
124
125
|
"enhanced-resolve": "^5.18.1",
|
|
125
126
|
"eventsource-parser": "^3.0.0",
|
|
@@ -134,6 +135,7 @@
|
|
|
134
135
|
"magic-string": "^0.30.17",
|
|
135
136
|
"miniflare": "^4.20250405.0",
|
|
136
137
|
"picocolors": "^1.1.1",
|
|
138
|
+
"proper-lockfile": "^4.1.2",
|
|
137
139
|
"puppeteer-core": "^22.8.1",
|
|
138
140
|
"react": "19.2.0-canary-39cad7af-20250411",
|
|
139
141
|
"react-dom": "19.2.0-canary-39cad7af-20250411",
|
|
@@ -154,6 +156,7 @@
|
|
|
154
156
|
"@types/debug": "^4.1.12",
|
|
155
157
|
"@types/lodash": "^4.17.16",
|
|
156
158
|
"@types/node": "^22.14.0",
|
|
159
|
+
"@types/proper-lockfile": "^4.1.4",
|
|
157
160
|
"semver": "^7.7.1",
|
|
158
161
|
"tsx": "^4.19.4",
|
|
159
162
|
"typescript": "^5.8.3",
|