@sigitex/outlaw 1.0.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.
- package/LICENSE +7 -0
- package/README.md +9 -0
- package/package.json +52 -0
- package/src/api/DatabaseTable.ts +51 -0
- package/src/api/DatabaseView.ts +22 -0
- package/src/api/api.types.ts +200 -0
- package/src/api/createDatabase.ts +24 -0
- package/src/api/index.ts +4 -0
- package/src/bun/bun.ts +27 -0
- package/src/bun/index.ts +1 -0
- package/src/cloudflare/cloudflare.ts +18 -0
- package/src/cloudflare/index.ts +1 -0
- package/src/console.ts +14 -0
- package/src/cowboyMigration/Compare.ts +97 -0
- package/src/cowboyMigration/CowboyConnection.ts +57 -0
- package/src/cowboyMigration/CowboyMigrator.ts +437 -0
- package/src/cowboyMigration/CowboySeeder.ts +245 -0
- package/src/cowboyMigration/cowboyMigration.types.ts +29 -0
- package/src/cowboyMigration/createSchemaHacker.ts +28 -0
- package/src/cowboyMigration/index.ts +3 -0
- package/src/crypto.d.ts +9 -0
- package/src/framework/Format.ts +31 -0
- package/src/framework/definitions.d.ts +4 -0
- package/src/framework/index.ts +1 -0
- package/src/index.ts +10 -0
- package/src/queryBuilder/DeleteBuilder.ts +40 -0
- package/src/queryBuilder/InsertBuilder.ts +31 -0
- package/src/queryBuilder/Mappings.ts +55 -0
- package/src/queryBuilder/SelectBuilder.ts +39 -0
- package/src/queryBuilder/SelectQueryBuilder.ts +93 -0
- package/src/queryBuilder/UpdateBuilder.ts +44 -0
- package/src/queryBuilder/addWhereClause.ts +35 -0
- package/src/queryBuilder/index.ts +7 -0
- package/src/queryBuilder/operators.ts +35 -0
- package/src/queryBuilder/queryBuilders.types.ts +105 -0
- package/src/queryGenerator/Clause.ts +79 -0
- package/src/queryGenerator/generateDelete.ts +18 -0
- package/src/queryGenerator/generateInsert.ts +29 -0
- package/src/queryGenerator/generateSelect.ts +89 -0
- package/src/queryGenerator/generateUpdate.ts +29 -0
- package/src/queryGenerator/index.ts +4 -0
- package/src/reflection/Reflector.ts +47 -0
- package/src/reflection/index.ts +2 -0
- package/src/reflection/reflection.types.ts +12 -0
- package/src/schemaBuilder/Mapping.ts +44 -0
- package/src/schemaBuilder/columnBuilders.ts +67 -0
- package/src/schemaBuilder/createFixture.ts +112 -0
- package/src/schemaBuilder/createIndex.ts +33 -0
- package/src/schemaBuilder/createSchema.ts +23 -0
- package/src/schemaBuilder/createTable.ts +80 -0
- package/src/schemaBuilder/createView.ts +21 -0
- package/src/schemaBuilder/index.ts +9 -0
- package/src/schemaBuilder/metadata.ts +73 -0
- package/src/schemaBuilder/schemaBuilder.types.ts +139 -0
- package/src/schemaGenerator/generateCreateIndex.ts +18 -0
- package/src/schemaGenerator/generateCreateTable.ts +68 -0
- package/src/schemaGenerator/generateCreateView.ts +13 -0
- package/src/schemaGenerator/index.ts +3 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// oxlint-disable typescript/no-explicit-any
|
|
2
|
+
import type { CheckExpression, ColumnData, ColumnRef, IndexData, TableData, ViewData } from "./metadata"
|
|
3
|
+
import type { Mapping } from "./Mapping"
|
|
4
|
+
|
|
5
|
+
export type SchemaMembers = {
|
|
6
|
+
readonly [key: string]: AnyBuildTable | BuildView<any> | BuildIndex
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type TablesOf<M extends SchemaMembers> = {
|
|
10
|
+
[K in keyof M as M[K] extends AnyBuildTable ? K : never]: M[K]
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type ViewsOf<M extends SchemaMembers> = {
|
|
14
|
+
[K in keyof M as M[K] extends BuildView<any> ? K : never]: M[K]
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type IndexesOf<M extends SchemaMembers> = {
|
|
18
|
+
[K in keyof M as M[K] extends BuildIndex ? K : never]: M[K]
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type Schema<M extends SchemaMembers> = {
|
|
22
|
+
readonly tables: TablesOf<M>
|
|
23
|
+
readonly views: ViewsOf<M>
|
|
24
|
+
readonly indexes: IndexesOf<M>
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type ColumnNames<Columns> = { readonly [K in keyof Columns]: string }
|
|
28
|
+
|
|
29
|
+
export type BuildColumns = {
|
|
30
|
+
readonly [columnName: string]: BuildColumn<any, any>
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type InferColumn<BC> = BC extends BuildColumn<infer Type, infer Defined>
|
|
34
|
+
? "notNull" extends Defined
|
|
35
|
+
? Type
|
|
36
|
+
: "primaryKey" extends Defined
|
|
37
|
+
? Type
|
|
38
|
+
: Type | null
|
|
39
|
+
: never
|
|
40
|
+
|
|
41
|
+
export type InferTable<BT> = BT extends BuildTable<infer Columns>
|
|
42
|
+
? { [K in keyof Columns]: InferColumn<Columns[K]> }
|
|
43
|
+
: never
|
|
44
|
+
|
|
45
|
+
export type RefBy = {
|
|
46
|
+
readonly _tag: "RefBy"
|
|
47
|
+
readonly table: AnyBuildTable
|
|
48
|
+
readonly column: string
|
|
49
|
+
readonly value: unknown
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
type BuildTableDSL<DefineColumns> = {
|
|
53
|
+
readonly $kind: "table"
|
|
54
|
+
primaryKey: (...columns: (keyof DefineColumns)[]) => BuildTable<DefineColumns>
|
|
55
|
+
unique: (...columns: (keyof DefineColumns)[]) => BuildTable<DefineColumns>
|
|
56
|
+
check: (expression: string | ((columns: ColumnNames<DefineColumns>, table: TableData) => string)) => BuildTable<DefineColumns>
|
|
57
|
+
select(all: "*"): SchemaSelect<DefineColumns, DefineColumns>
|
|
58
|
+
select<C extends keyof DefineColumns>(...columns: C[]): SchemaSelect<Pick<DefineColumns, C>, DefineColumns>
|
|
59
|
+
readonly by: {
|
|
60
|
+
readonly [K in keyof DefineColumns]: (
|
|
61
|
+
value: InferColumn<DefineColumns[K]>,
|
|
62
|
+
) => RefBy
|
|
63
|
+
}
|
|
64
|
+
readonly $meta: TableData
|
|
65
|
+
readonly infer: InferTable<BuildTable<DefineColumns>>
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export type BuildTable<DefineColumns> = BuildTableDSL<DefineColumns> & {
|
|
69
|
+
readonly [K in keyof DefineColumns]: ColumnRef
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export type AnyBuildTable = {
|
|
73
|
+
readonly $kind: "table"
|
|
74
|
+
readonly $meta: TableData
|
|
75
|
+
readonly [key: string]: unknown
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// oxlint-disable-next-line no-unused-vars
|
|
79
|
+
export type BuildView<SelectColumns = unknown> = {
|
|
80
|
+
readonly $kind: "view"
|
|
81
|
+
readonly $meta: ViewData
|
|
82
|
+
readonly $tableData: TableData
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export type BuildIndex = {
|
|
86
|
+
readonly $kind: "index"
|
|
87
|
+
readonly $meta: IndexData
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Schema-level select builder — tracks column types without requiring a connection. */
|
|
91
|
+
export type SchemaSelect<SelectColumns, Columns> = {
|
|
92
|
+
where<Column extends keyof Columns>(column: Column, value: unknown): SchemaSelect<SelectColumns, Columns>
|
|
93
|
+
where<Column extends keyof Columns>(column: Column, operator: string): SchemaSelect<SelectColumns, Columns>
|
|
94
|
+
where<Column extends keyof Columns>(column: Column, operator: string, value: unknown): SchemaSelect<SelectColumns, Columns>
|
|
95
|
+
orderBy(sorts: [keyof Columns, "asc" | "desc"][]): SchemaSelect<SelectColumns, Columns>
|
|
96
|
+
limit(n: number): SchemaSelect<SelectColumns, Columns>
|
|
97
|
+
offset(n: number): SchemaSelect<SelectColumns, Columns>
|
|
98
|
+
join<JC>(table: BuildTable<JC>): SchemaSelect<SelectColumns & JC, Columns & JC>
|
|
99
|
+
leftJoin<JC>(table: BuildTable<JC>): SchemaSelect<SelectColumns & JC, Columns & JC>
|
|
100
|
+
on(left: ColumnRef, operator: string, right: ColumnRef): SchemaSelect<SelectColumns, Columns>
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export type BuildColumn<Type, Defined extends string> = Omit<
|
|
104
|
+
{
|
|
105
|
+
readonly notNull: BuildColumn<Type, Defined | "notNull">
|
|
106
|
+
readonly primaryKey: BuildColumn<Type, Defined | "primaryKey"> &
|
|
107
|
+
BuildPrimaryKey<Type, Defined | "primaryKey">
|
|
108
|
+
readonly default: (sql: string) => BuildColumn<Type, Defined | "default">
|
|
109
|
+
readonly unique: BuildColumn<Type, Defined | "unique">
|
|
110
|
+
readonly check: (expression: CheckExpression) => BuildColumn<Type, Defined | "check">
|
|
111
|
+
readonly foreignKey: BuildForeignKey<Type, Defined>
|
|
112
|
+
readonly map: BuildColumnMap<Type, Defined>
|
|
113
|
+
},
|
|
114
|
+
Defined
|
|
115
|
+
>
|
|
116
|
+
|
|
117
|
+
export type BuildColumnInner = BuildColumn<any, never> & {
|
|
118
|
+
$meta: Partial<ColumnData>
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export type BuildPrimaryKey<Type, Defined extends string> = {
|
|
122
|
+
readonly autoincrement: BuildColumn<Type, Defined>
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export type BuildForeignKey<Type, Defined extends string> = {
|
|
126
|
+
readonly references: (
|
|
127
|
+
ref: ColumnRef,
|
|
128
|
+
) => BuildColumn<Type, Defined | "foreignKey">
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export type BuildColumnMap<Type, Defined extends string> = {
|
|
132
|
+
readonly boolean: BuildColumn<boolean, Defined | "map">
|
|
133
|
+
readonly timestamp: BuildColumn<Date, Defined | "map">
|
|
134
|
+
readonly date: BuildColumn<Date, Defined | "map">
|
|
135
|
+
readonly json: <T>() => BuildColumn<T, Defined | "map">
|
|
136
|
+
} & {
|
|
137
|
+
<To>(mapping: Mapping<Type, To>): BuildColumn<To, Defined | "map">
|
|
138
|
+
<To>(): BuildColumn<To, Defined | "map">
|
|
139
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { join, newline, print } from "@sigitex/print"
|
|
2
|
+
import { Format } from "../framework"
|
|
3
|
+
import type { IndexData } from "../schemaBuilder"
|
|
4
|
+
|
|
5
|
+
export function generateCreateIndex(index: IndexData) {
|
|
6
|
+
return print([
|
|
7
|
+
"create ",
|
|
8
|
+
index.unique && "unique ",
|
|
9
|
+
"index ",
|
|
10
|
+
Format.name(index.name),
|
|
11
|
+
" on ",
|
|
12
|
+
Format.name(index.table),
|
|
13
|
+
" (",
|
|
14
|
+
join(", ", index.columns, Format.name),
|
|
15
|
+
");",
|
|
16
|
+
newline,
|
|
17
|
+
])
|
|
18
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { indent, newline, print } from "@sigitex/print"
|
|
2
|
+
import { Format } from "../framework"
|
|
3
|
+
import type { CheckExpression, ColumnData, TableData } from "../schemaBuilder"
|
|
4
|
+
|
|
5
|
+
export function generateCreateTable(table: TableData) {
|
|
6
|
+
const columnNames = Object.fromEntries(table.columns.map(c => [c.name, c.name]))
|
|
7
|
+
return print([
|
|
8
|
+
"create table ",
|
|
9
|
+
Format.name(table.name),
|
|
10
|
+
" (",
|
|
11
|
+
indent(
|
|
12
|
+
table.columns.map((column, c) => [
|
|
13
|
+
c > 0 && [",", newline],
|
|
14
|
+
Format.name(column.name),
|
|
15
|
+
" ",
|
|
16
|
+
column.datatype,
|
|
17
|
+
column.primaryKey && [
|
|
18
|
+
" primary key",
|
|
19
|
+
column.primaryKey.autoincrement && " autoincrement",
|
|
20
|
+
],
|
|
21
|
+
column.notNull && " not null",
|
|
22
|
+
column.unique && " unique",
|
|
23
|
+
column.default && [" default ", column.default],
|
|
24
|
+
column.check && [" check(", resolveColumnCheck(column.check, column), ")"],
|
|
25
|
+
]),
|
|
26
|
+
table.columns
|
|
27
|
+
.filter(({ foreignKey }) => foreignKey)
|
|
28
|
+
.map((column) => [
|
|
29
|
+
",",
|
|
30
|
+
newline,
|
|
31
|
+
"foreign key (",
|
|
32
|
+
Format.name(column.name),
|
|
33
|
+
") references ",
|
|
34
|
+
Format.name(column.foreignKey?.table),
|
|
35
|
+
" (",
|
|
36
|
+
Format.name(column.foreignKey?.column),
|
|
37
|
+
")",
|
|
38
|
+
]),
|
|
39
|
+
table.constraints.map((constraint) => [
|
|
40
|
+
",",
|
|
41
|
+
newline,
|
|
42
|
+
constraint.type === "primaryKey" && "primary key",
|
|
43
|
+
constraint.type === "unique" && "unique",
|
|
44
|
+
(constraint.type === "primaryKey" || constraint.type === "unique") && [
|
|
45
|
+
" (",
|
|
46
|
+
constraint.columns.map((fkColumn, c) => [
|
|
47
|
+
c > 0 && ", ",
|
|
48
|
+
Format.name(fkColumn),
|
|
49
|
+
]),
|
|
50
|
+
")",
|
|
51
|
+
],
|
|
52
|
+
constraint.type === "check" && [
|
|
53
|
+
"check(",
|
|
54
|
+
typeof constraint.expression === "function"
|
|
55
|
+
? constraint.expression(columnNames, table)
|
|
56
|
+
: constraint.expression,
|
|
57
|
+
")",
|
|
58
|
+
],
|
|
59
|
+
]),
|
|
60
|
+
),
|
|
61
|
+
");",
|
|
62
|
+
newline,
|
|
63
|
+
])
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function resolveColumnCheck(check: CheckExpression, column: ColumnData): string {
|
|
67
|
+
return typeof check === "function" ? check(column.name, column) : check
|
|
68
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { newline, print } from "@sigitex/print"
|
|
2
|
+
import { Format } from "../framework"
|
|
3
|
+
import type { ViewData } from "../schemaBuilder"
|
|
4
|
+
|
|
5
|
+
export function generateCreateView(view: ViewData) {
|
|
6
|
+
return print([
|
|
7
|
+
"create view ",
|
|
8
|
+
Format.name(view.name),
|
|
9
|
+
" as ",
|
|
10
|
+
view.sql,
|
|
11
|
+
newline,
|
|
12
|
+
])
|
|
13
|
+
}
|