shapedef 1.0.13 → 1.0.15
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/dist/cjs/translations/postgres.d.ts.map +1 -1
- package/dist/cjs/translations/postgres.js +23 -5
- package/dist/cjs/translations/postgres.js.map +1 -1
- package/dist/esm/translations/postgres.d.ts.map +1 -1
- package/dist/esm/translations/postgres.js +23 -5
- package/dist/esm/translations/postgres.js.map +1 -1
- package/package.json +1 -1
- package/src/samples/bank.sample.ts +11 -0
- package/src/translations/postgres.test.ts +108 -14
- package/src/translations/postgres.ts +39 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../../src/translations/postgres.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../../src/translations/postgres.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAA+B,MAAM,UAAU,CAAC;AAE9D,MAAM,MAAM,eAAe,GAAG;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AA+EF,eAAO,MAAM,QAAQ,GAAI,OAAO,KAAK,EAAE,UAAS,eAAoB,WA6BnE,CAAC"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.postgres = void 0;
|
|
4
|
+
const isAllLiteralStrUnion = (shape) => shape.type === "union" &&
|
|
5
|
+
shape.ofs.length > 0 &&
|
|
6
|
+
shape.ofs.every((s) => s.type === "literal-str");
|
|
4
7
|
const pgType = (shape) => {
|
|
5
8
|
switch (shape.type) {
|
|
6
9
|
case "int":
|
|
@@ -43,8 +46,8 @@ const pgType = (shape) => {
|
|
|
43
46
|
return "JSONB";
|
|
44
47
|
}
|
|
45
48
|
};
|
|
46
|
-
const pgColumnDef = (colName, shape, options) => {
|
|
47
|
-
const parts = [colName
|
|
49
|
+
const pgColumnDef = (colName, shape, options, overrideType) => {
|
|
50
|
+
const parts = [`"${colName}"`, overrideType ?? pgType(shape)];
|
|
48
51
|
if (shape.anno.primary) {
|
|
49
52
|
parts.push("PRIMARY KEY");
|
|
50
53
|
}
|
|
@@ -61,17 +64,32 @@ const pgColumnDef = (colName, shape, options) => {
|
|
|
61
64
|
}
|
|
62
65
|
if (shape.anno.foreign) {
|
|
63
66
|
const refTable = `${options.tablePrefix ?? ""}${shape.anno.foreign.shapeName}`;
|
|
64
|
-
parts.push(`REFERENCES "${refTable}"(${shape.anno.foreign.fieldName})`);
|
|
67
|
+
parts.push(`REFERENCES "${refTable}"("${shape.anno.foreign.fieldName}")`);
|
|
65
68
|
}
|
|
66
69
|
return parts.join(" ");
|
|
67
70
|
};
|
|
68
71
|
const postgres = (shape, options = {}) => {
|
|
69
72
|
if (shape.type === "mapping" && shape.anno.name) {
|
|
70
73
|
const tableName = `${options.tablePrefix ?? ""}${shape.anno.name}`;
|
|
74
|
+
const enumStatements = [];
|
|
75
|
+
const enumTypeNames = new Map();
|
|
76
|
+
for (const [colName, colShape] of Object.entries(shape.rec)) {
|
|
77
|
+
if (isAllLiteralStrUnion(colShape)) {
|
|
78
|
+
const enumTypeName = colShape.anno.name ?? `${tableName}_${colName}`;
|
|
79
|
+
const values = colShape.ofs
|
|
80
|
+
.map((s) => `'${s.value}'`)
|
|
81
|
+
.join(", ");
|
|
82
|
+
enumStatements.push(`CREATE TYPE "${enumTypeName}" AS ENUM (${values})`);
|
|
83
|
+
enumTypeNames.set(colName, `"${enumTypeName}"`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
71
86
|
const cols = Object.entries(shape.rec)
|
|
72
|
-
.map(([k, v]) => ` ${pgColumnDef(k, v, options)}`)
|
|
87
|
+
.map(([k, v]) => ` ${pgColumnDef(k, v, options, enumTypeNames.get(k))}`)
|
|
73
88
|
.join(",\n");
|
|
74
|
-
|
|
89
|
+
const tableStatement = `CREATE TABLE IF NOT EXISTS "${tableName}" (\n${cols}\n)`;
|
|
90
|
+
return enumStatements.length > 0 ?
|
|
91
|
+
[...enumStatements, tableStatement].join(";\n")
|
|
92
|
+
: tableStatement;
|
|
75
93
|
}
|
|
76
94
|
return pgType(shape);
|
|
77
95
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../../src/translations/postgres.ts"],"names":[],"mappings":";;;AAMA,MAAM,MAAM,GAAG,CAAC,KAAY,EAAU,EAAE;IACtC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,KAAK;YACR,OAAO,SAAS,CAAC;QACnB,KAAK,OAAO;YACV,OAAO,kBAAkB,CAAC;QAC5B,KAAK,QAAQ;YACX,OAAO,SAAS,CAAC;QACnB,KAAK,KAAK;YACR,OAAO,MAAM,CAAC;QAChB,KAAK,MAAM;YACT,OAAO,SAAS,CAAC;QACnB,KAAK,MAAM;YACT,OAAO,aAAa,CAAC;QACvB,KAAK,KAAK;YACR,OAAO,MAAM,CAAC;QAChB,KAAK,SAAS;YACZ,OAAO,OAAO,CAAC;QACjB,KAAK,aAAa,CAAC;QACnB,KAAK,eAAe,CAAC;QACrB,KAAK,gBAAgB;YACnB,OAAO,SAAS,CAAC;QACnB,KAAK,aAAa;YAChB,OAAO,MAAM,CAAC;QAChB,KAAK,cAAc;YACjB,OAAO,SAAS,CAAC;QACnB,KAAK,KAAK;YACR,OAAO,KAAK,CAAC,IAAI,CAAC;QACpB,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACjC,OAAO,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC;QACpD,CAAC;QACD,KAAK,OAAO;YACV,OAAO,OAAO,CAAC;QACjB,KAAK,OAAO;YACV,OAAO,OAAO,CAAC;QACjB,KAAK,QAAQ;YACX,OAAO,UAAU,KAAK,CAAC,IAAI,GAAG,CAAC;QACjC,KAAK,SAAS;YACZ,OAAO,OAAO,CAAC;IACnB,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,
|
|
1
|
+
{"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../../src/translations/postgres.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../../src/translations/postgres.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../../src/translations/postgres.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAA+B,MAAM,UAAU,CAAC;AAE9D,MAAM,MAAM,eAAe,GAAG;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AA+EF,eAAO,MAAM,QAAQ,GAAI,OAAO,KAAK,EAAE,UAAS,eAAoB,WA6BnE,CAAC"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.postgres = void 0;
|
|
4
|
+
const isAllLiteralStrUnion = (shape) => shape.type === "union" &&
|
|
5
|
+
shape.ofs.length > 0 &&
|
|
6
|
+
shape.ofs.every((s) => s.type === "literal-str");
|
|
4
7
|
const pgType = (shape) => {
|
|
5
8
|
switch (shape.type) {
|
|
6
9
|
case "int":
|
|
@@ -43,8 +46,8 @@ const pgType = (shape) => {
|
|
|
43
46
|
return "JSONB";
|
|
44
47
|
}
|
|
45
48
|
};
|
|
46
|
-
const pgColumnDef = (colName, shape, options) => {
|
|
47
|
-
const parts = [colName
|
|
49
|
+
const pgColumnDef = (colName, shape, options, overrideType) => {
|
|
50
|
+
const parts = [`"${colName}"`, overrideType ?? pgType(shape)];
|
|
48
51
|
if (shape.anno.primary) {
|
|
49
52
|
parts.push("PRIMARY KEY");
|
|
50
53
|
}
|
|
@@ -61,17 +64,32 @@ const pgColumnDef = (colName, shape, options) => {
|
|
|
61
64
|
}
|
|
62
65
|
if (shape.anno.foreign) {
|
|
63
66
|
const refTable = `${options.tablePrefix ?? ""}${shape.anno.foreign.shapeName}`;
|
|
64
|
-
parts.push(`REFERENCES "${refTable}"(${shape.anno.foreign.fieldName})`);
|
|
67
|
+
parts.push(`REFERENCES "${refTable}"("${shape.anno.foreign.fieldName}")`);
|
|
65
68
|
}
|
|
66
69
|
return parts.join(" ");
|
|
67
70
|
};
|
|
68
71
|
const postgres = (shape, options = {}) => {
|
|
69
72
|
if (shape.type === "mapping" && shape.anno.name) {
|
|
70
73
|
const tableName = `${options.tablePrefix ?? ""}${shape.anno.name}`;
|
|
74
|
+
const enumStatements = [];
|
|
75
|
+
const enumTypeNames = new Map();
|
|
76
|
+
for (const [colName, colShape] of Object.entries(shape.rec)) {
|
|
77
|
+
if (isAllLiteralStrUnion(colShape)) {
|
|
78
|
+
const enumTypeName = colShape.anno.name ?? `${tableName}_${colName}`;
|
|
79
|
+
const values = colShape.ofs
|
|
80
|
+
.map((s) => `'${s.value}'`)
|
|
81
|
+
.join(", ");
|
|
82
|
+
enumStatements.push(`CREATE TYPE "${enumTypeName}" AS ENUM (${values})`);
|
|
83
|
+
enumTypeNames.set(colName, `"${enumTypeName}"`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
71
86
|
const cols = Object.entries(shape.rec)
|
|
72
|
-
.map(([k, v]) => ` ${pgColumnDef(k, v, options)}`)
|
|
87
|
+
.map(([k, v]) => ` ${pgColumnDef(k, v, options, enumTypeNames.get(k))}`)
|
|
73
88
|
.join(",\n");
|
|
74
|
-
|
|
89
|
+
const tableStatement = `CREATE TABLE IF NOT EXISTS "${tableName}" (\n${cols}\n)`;
|
|
90
|
+
return enumStatements.length > 0 ?
|
|
91
|
+
[...enumStatements, tableStatement].join(";\n")
|
|
92
|
+
: tableStatement;
|
|
75
93
|
}
|
|
76
94
|
return pgType(shape);
|
|
77
95
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../../src/translations/postgres.ts"],"names":[],"mappings":";;;AAMA,MAAM,MAAM,GAAG,CAAC,KAAY,EAAU,EAAE;IACtC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,KAAK;YACR,OAAO,SAAS,CAAC;QACnB,KAAK,OAAO;YACV,OAAO,kBAAkB,CAAC;QAC5B,KAAK,QAAQ;YACX,OAAO,SAAS,CAAC;QACnB,KAAK,KAAK;YACR,OAAO,MAAM,CAAC;QAChB,KAAK,MAAM;YACT,OAAO,SAAS,CAAC;QACnB,KAAK,MAAM;YACT,OAAO,aAAa,CAAC;QACvB,KAAK,KAAK;YACR,OAAO,MAAM,CAAC;QAChB,KAAK,SAAS;YACZ,OAAO,OAAO,CAAC;QACjB,KAAK,aAAa,CAAC;QACnB,KAAK,eAAe,CAAC;QACrB,KAAK,gBAAgB;YACnB,OAAO,SAAS,CAAC;QACnB,KAAK,aAAa;YAChB,OAAO,MAAM,CAAC;QAChB,KAAK,cAAc;YACjB,OAAO,SAAS,CAAC;QACnB,KAAK,KAAK;YACR,OAAO,KAAK,CAAC,IAAI,CAAC;QACpB,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACjC,OAAO,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC;QACpD,CAAC;QACD,KAAK,OAAO;YACV,OAAO,OAAO,CAAC;QACjB,KAAK,OAAO;YACV,OAAO,OAAO,CAAC;QACjB,KAAK,QAAQ;YACX,OAAO,UAAU,KAAK,CAAC,IAAI,GAAG,CAAC;QACjC,KAAK,SAAS;YACZ,OAAO,OAAO,CAAC;IACnB,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,
|
|
1
|
+
{"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../../src/translations/postgres.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { annotate, shapes } from "../shape";
|
|
2
|
+
import { postgres } from "../translations";
|
|
2
3
|
|
|
3
4
|
export const User = annotate.named(
|
|
4
5
|
shapes.mapping({
|
|
@@ -17,6 +18,14 @@ export const BankAccount = annotate.named(
|
|
|
17
18
|
userId: annotate.foreign(shapes.str(), "User", "id"),
|
|
18
19
|
timestamp: annotate.by(shapes.date(), { defaultValue: "NOW()" }),
|
|
19
20
|
name: shapes.str(),
|
|
21
|
+
kind: annotate.named(
|
|
22
|
+
shapes.union(
|
|
23
|
+
shapes.literal("savings-account"),
|
|
24
|
+
shapes.literal("investment-account"),
|
|
25
|
+
shapes.literal("loans"),
|
|
26
|
+
),
|
|
27
|
+
"AccountType",
|
|
28
|
+
),
|
|
20
29
|
balance: shapes.mapping({
|
|
21
30
|
value: shapes.float(),
|
|
22
31
|
currency: shapes.union(shapes.literal("USD"), shapes.literal("EUR")),
|
|
@@ -24,3 +33,5 @@ export const BankAccount = annotate.named(
|
|
|
24
33
|
}),
|
|
25
34
|
"BankAccount",
|
|
26
35
|
);
|
|
36
|
+
|
|
37
|
+
console.log(postgres(BankAccount));
|
|
@@ -50,6 +50,100 @@ describe("postgres", (it) => {
|
|
|
50
50
|
expect(postgres(shapes.mapping({ x: shapes.int() }))).toBe("JSONB");
|
|
51
51
|
});
|
|
52
52
|
|
|
53
|
+
it("translates all-literal-string union to JSONB when used standalone", () => {
|
|
54
|
+
expect(
|
|
55
|
+
postgres(shapes.union(shapes.literal("a"), shapes.literal("b"))),
|
|
56
|
+
).toBe("JSONB");
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("generates CREATE TYPE AS ENUM for all-literal-string union columns in named mappings", () => {
|
|
60
|
+
expect(
|
|
61
|
+
postgres(
|
|
62
|
+
annotate.named(
|
|
63
|
+
shapes.mapping({
|
|
64
|
+
name: shapes.str(),
|
|
65
|
+
mood: shapes.union(
|
|
66
|
+
shapes.literal("sad"),
|
|
67
|
+
shapes.literal("ok"),
|
|
68
|
+
shapes.literal("happy"),
|
|
69
|
+
),
|
|
70
|
+
}),
|
|
71
|
+
"person",
|
|
72
|
+
),
|
|
73
|
+
),
|
|
74
|
+
).toBe(
|
|
75
|
+
[
|
|
76
|
+
`CREATE TYPE "person_mood" AS ENUM ('sad', 'ok', 'happy')`,
|
|
77
|
+
`CREATE TABLE IF NOT EXISTS "person" (\n "name" TEXT NOT NULL,\n "mood" "person_mood" NOT NULL\n)`,
|
|
78
|
+
].join(";\n"),
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it("applies tablePrefix to enum type names", () => {
|
|
83
|
+
expect(
|
|
84
|
+
postgres(
|
|
85
|
+
annotate.named(
|
|
86
|
+
shapes.mapping({
|
|
87
|
+
kind: shapes.union(shapes.literal("x"), shapes.literal("y")),
|
|
88
|
+
}),
|
|
89
|
+
"Thing",
|
|
90
|
+
),
|
|
91
|
+
{ tablePrefix: "app_" },
|
|
92
|
+
),
|
|
93
|
+
).toBe(
|
|
94
|
+
[
|
|
95
|
+
`CREATE TYPE "app_Thing_kind" AS ENUM ('x', 'y')`,
|
|
96
|
+
`CREATE TABLE IF NOT EXISTS "app_Thing" (\n "kind" "app_Thing_kind" NOT NULL\n)`,
|
|
97
|
+
].join(";\n"),
|
|
98
|
+
);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("uses the union's annotation name for the enum type when present", () => {
|
|
102
|
+
expect(
|
|
103
|
+
postgres(
|
|
104
|
+
annotate.named(
|
|
105
|
+
shapes.mapping({
|
|
106
|
+
kind: annotate.named(
|
|
107
|
+
shapes.union(
|
|
108
|
+
shapes.literal("savings-account"),
|
|
109
|
+
shapes.literal("investment-account"),
|
|
110
|
+
shapes.literal("loans"),
|
|
111
|
+
),
|
|
112
|
+
"AccountKind",
|
|
113
|
+
),
|
|
114
|
+
}),
|
|
115
|
+
"BankAccount",
|
|
116
|
+
),
|
|
117
|
+
),
|
|
118
|
+
).toBe(
|
|
119
|
+
[
|
|
120
|
+
`CREATE TYPE "AccountKind" AS ENUM ('savings-account', 'investment-account', 'loans')`,
|
|
121
|
+
`CREATE TABLE IF NOT EXISTS "BankAccount" (\n "kind" "AccountKind" NOT NULL\n)`,
|
|
122
|
+
].join(";\n"),
|
|
123
|
+
);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it("does not generate enum for mixed unions (not all literal-str)", () => {
|
|
127
|
+
expect(
|
|
128
|
+
postgres(
|
|
129
|
+
annotate.named(
|
|
130
|
+
shapes.mapping({
|
|
131
|
+
id: annotate.primary(shapes.int()),
|
|
132
|
+
mixed: shapes.union(shapes.literal("a"), shapes.int()),
|
|
133
|
+
}),
|
|
134
|
+
"Test",
|
|
135
|
+
),
|
|
136
|
+
),
|
|
137
|
+
).toBe(
|
|
138
|
+
[
|
|
139
|
+
`CREATE TABLE IF NOT EXISTS "Test" (`,
|
|
140
|
+
` "id" INTEGER PRIMARY KEY,`,
|
|
141
|
+
` "mixed" JSONB NOT NULL`,
|
|
142
|
+
`)`,
|
|
143
|
+
].join("\n"),
|
|
144
|
+
);
|
|
145
|
+
});
|
|
146
|
+
|
|
53
147
|
it("generates CREATE TABLE IF NOT EXISTS for named mappings", () => {
|
|
54
148
|
expect(
|
|
55
149
|
postgres(
|
|
@@ -64,8 +158,8 @@ describe("postgres", (it) => {
|
|
|
64
158
|
).toBe(
|
|
65
159
|
[
|
|
66
160
|
`CREATE TABLE IF NOT EXISTS "User" (`,
|
|
67
|
-
"
|
|
68
|
-
"
|
|
161
|
+
` "id" INTEGER PRIMARY KEY,`,
|
|
162
|
+
` "name" TEXT NOT NULL`,
|
|
69
163
|
")",
|
|
70
164
|
].join("\n"),
|
|
71
165
|
);
|
|
@@ -85,8 +179,8 @@ describe("postgres", (it) => {
|
|
|
85
179
|
).toBe(
|
|
86
180
|
[
|
|
87
181
|
`CREATE TABLE IF NOT EXISTS "Foobar" (`,
|
|
88
|
-
"
|
|
89
|
-
"
|
|
182
|
+
` "id" INTEGER PRIMARY KEY,`,
|
|
183
|
+
` "my_embedding" vector(300) NOT NULL`,
|
|
90
184
|
")",
|
|
91
185
|
].join("\n"),
|
|
92
186
|
);
|
|
@@ -106,8 +200,8 @@ describe("postgres", (it) => {
|
|
|
106
200
|
).toBe(
|
|
107
201
|
[
|
|
108
202
|
`CREATE TABLE IF NOT EXISTS "Profile" (`,
|
|
109
|
-
"
|
|
110
|
-
"
|
|
203
|
+
` "id" INTEGER PRIMARY KEY,`,
|
|
204
|
+
` "nickname" TEXT`,
|
|
111
205
|
")",
|
|
112
206
|
].join("\n"),
|
|
113
207
|
);
|
|
@@ -127,8 +221,8 @@ describe("postgres", (it) => {
|
|
|
127
221
|
).toBe(
|
|
128
222
|
[
|
|
129
223
|
`CREATE TABLE IF NOT EXISTS "Account" (`,
|
|
130
|
-
"
|
|
131
|
-
"
|
|
224
|
+
` "id" INTEGER PRIMARY KEY,`,
|
|
225
|
+
` "email" TEXT NOT NULL UNIQUE`,
|
|
132
226
|
")",
|
|
133
227
|
].join("\n"),
|
|
134
228
|
);
|
|
@@ -148,8 +242,8 @@ describe("postgres", (it) => {
|
|
|
148
242
|
).toBe(
|
|
149
243
|
[
|
|
150
244
|
`CREATE TABLE IF NOT EXISTS "Post" (`,
|
|
151
|
-
"
|
|
152
|
-
` user_id INTEGER NOT NULL REFERENCES "User"(id)`,
|
|
245
|
+
` "id" INTEGER PRIMARY KEY,`,
|
|
246
|
+
` "user_id" INTEGER NOT NULL REFERENCES "User"("id")`,
|
|
153
247
|
")",
|
|
154
248
|
].join("\n"),
|
|
155
249
|
);
|
|
@@ -174,8 +268,8 @@ describe("postgres", (it) => {
|
|
|
174
268
|
).toBe(
|
|
175
269
|
[
|
|
176
270
|
`CREATE TABLE IF NOT EXISTS "app_User" (`,
|
|
177
|
-
"
|
|
178
|
-
"
|
|
271
|
+
` "id" INTEGER PRIMARY KEY,`,
|
|
272
|
+
` "name" TEXT NOT NULL`,
|
|
179
273
|
")",
|
|
180
274
|
].join("\n"),
|
|
181
275
|
);
|
|
@@ -196,8 +290,8 @@ describe("postgres", (it) => {
|
|
|
196
290
|
).toBe(
|
|
197
291
|
[
|
|
198
292
|
`CREATE TABLE IF NOT EXISTS "app_Post" (`,
|
|
199
|
-
"
|
|
200
|
-
` user_id INTEGER NOT NULL REFERENCES "app_User"(id)`,
|
|
293
|
+
` "id" INTEGER PRIMARY KEY,`,
|
|
294
|
+
` "user_id" INTEGER NOT NULL REFERENCES "app_User"("id")`,
|
|
201
295
|
")",
|
|
202
296
|
].join("\n"),
|
|
203
297
|
);
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import { Shape } from "../shape";
|
|
1
|
+
import { Shape, ShapeLiteralStr, ShapeUnion } from "../shape";
|
|
2
2
|
|
|
3
3
|
export type PostgresOptions = {
|
|
4
4
|
tablePrefix?: string;
|
|
5
|
-
}
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
const isAllLiteralStrUnion = (
|
|
8
|
+
shape: Shape,
|
|
9
|
+
): shape is ShapeUnion & { ofs: ShapeLiteralStr[] } =>
|
|
10
|
+
shape.type === "union" &&
|
|
11
|
+
shape.ofs.length > 0 &&
|
|
12
|
+
shape.ofs.every((s) => s.type === "literal-str");
|
|
6
13
|
|
|
7
14
|
const pgType = (shape: Shape): string => {
|
|
8
15
|
switch (shape.type) {
|
|
@@ -47,8 +54,13 @@ const pgType = (shape: Shape): string => {
|
|
|
47
54
|
}
|
|
48
55
|
};
|
|
49
56
|
|
|
50
|
-
const pgColumnDef = (
|
|
51
|
-
|
|
57
|
+
const pgColumnDef = (
|
|
58
|
+
colName: string,
|
|
59
|
+
shape: Shape,
|
|
60
|
+
options: PostgresOptions,
|
|
61
|
+
overrideType?: string,
|
|
62
|
+
): string => {
|
|
63
|
+
const parts: string[] = [`"${colName}"`, overrideType ?? pgType(shape)];
|
|
52
64
|
if (shape.anno.primary) {
|
|
53
65
|
parts.push("PRIMARY KEY");
|
|
54
66
|
} else if (!shape.anno.optional) {
|
|
@@ -64,9 +76,7 @@ const pgColumnDef = (colName: string, shape: Shape, options: PostgresOptions): s
|
|
|
64
76
|
}
|
|
65
77
|
if (shape.anno.foreign) {
|
|
66
78
|
const refTable = `${options.tablePrefix ?? ""}${shape.anno.foreign.shapeName}`;
|
|
67
|
-
parts.push(
|
|
68
|
-
`REFERENCES "${refTable}"(${shape.anno.foreign.fieldName})`,
|
|
69
|
-
);
|
|
79
|
+
parts.push(`REFERENCES "${refTable}"("${shape.anno.foreign.fieldName}")`);
|
|
70
80
|
}
|
|
71
81
|
return parts.join(" ");
|
|
72
82
|
};
|
|
@@ -74,10 +84,30 @@ const pgColumnDef = (colName: string, shape: Shape, options: PostgresOptions): s
|
|
|
74
84
|
export const postgres = (shape: Shape, options: PostgresOptions = {}) => {
|
|
75
85
|
if (shape.type === "mapping" && shape.anno.name) {
|
|
76
86
|
const tableName = `${options.tablePrefix ?? ""}${shape.anno.name}`;
|
|
87
|
+
|
|
88
|
+
const enumStatements: string[] = [];
|
|
89
|
+
const enumTypeNames = new Map<string, string>();
|
|
90
|
+
for (const [colName, colShape] of Object.entries(shape.rec)) {
|
|
91
|
+
if (isAllLiteralStrUnion(colShape)) {
|
|
92
|
+
const enumTypeName = colShape.anno.name ?? `${tableName}_${colName}`;
|
|
93
|
+
const values = (colShape.ofs as ShapeLiteralStr[])
|
|
94
|
+
.map((s) => `'${s.value}'`)
|
|
95
|
+
.join(", ");
|
|
96
|
+
enumStatements.push(
|
|
97
|
+
`CREATE TYPE "${enumTypeName}" AS ENUM (${values})`,
|
|
98
|
+
);
|
|
99
|
+
enumTypeNames.set(colName, `"${enumTypeName}"`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
77
103
|
const cols = Object.entries(shape.rec)
|
|
78
|
-
.map(([k, v]) => ` ${pgColumnDef(k, v, options)}`)
|
|
104
|
+
.map(([k, v]) => ` ${pgColumnDef(k, v, options, enumTypeNames.get(k))}`)
|
|
79
105
|
.join(",\n");
|
|
80
|
-
|
|
106
|
+
const tableStatement = `CREATE TABLE IF NOT EXISTS "${tableName}" (\n${cols}\n)`;
|
|
107
|
+
|
|
108
|
+
return enumStatements.length > 0 ?
|
|
109
|
+
[...enumStatements, tableStatement].join(";\n")
|
|
110
|
+
: tableStatement;
|
|
81
111
|
}
|
|
82
112
|
return pgType(shape);
|
|
83
113
|
};
|