orchid-orm 1.6.39 → 1.7.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/dist/index.d.ts +57 -54
- package/dist/index.js +78 -86
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +63 -63
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
- package/dist/bin.js +0 -515
- package/dist/bin.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "orchid-orm",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "Postgres ORM",
|
|
5
5
|
"homepage": "https://orchid-orm.netlify.app/guide/orm-setup-and-overview.html",
|
|
6
6
|
"repository": {
|
|
@@ -44,14 +44,14 @@
|
|
|
44
44
|
"author": "Roman Kushyn",
|
|
45
45
|
"license": "ISC",
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"orchid-core": "0.
|
|
48
|
-
"pqb": "0.
|
|
47
|
+
"orchid-core": "0.2.0",
|
|
48
|
+
"pqb": "0.11.0",
|
|
49
49
|
"prompts": "^2.4.2"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@types/prompts": "^2.4.2",
|
|
53
|
-
"orchid-orm-schema-to-zod": "0.3.
|
|
54
|
-
"rake-db": "2.
|
|
53
|
+
"orchid-orm-schema-to-zod": "0.3.38",
|
|
54
|
+
"rake-db": "2.5.0"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
57
57
|
"typescript": "*"
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"check": "jest",
|
|
62
62
|
"types": "tsc",
|
|
63
63
|
"test:ci": "jest --coverage --coverageReporters json-summary",
|
|
64
|
-
"build": "rimraf ./dist/ && rollup -c
|
|
64
|
+
"build": "rimraf ./dist/ && rollup -c ../../rollup.config.mjs",
|
|
65
65
|
"db": "ts-node src/db/dbScripts.ts"
|
|
66
66
|
}
|
|
67
67
|
}
|
package/dist/bin.js
DELETED
|
@@ -1,515 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
var fs = require('fs/promises');
|
|
5
|
-
var path = require('path');
|
|
6
|
-
var https = require('https');
|
|
7
|
-
var prompts = require('prompts');
|
|
8
|
-
|
|
9
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
10
|
-
|
|
11
|
-
var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
|
|
12
|
-
var https__default = /*#__PURE__*/_interopDefaultLegacy(https);
|
|
13
|
-
var prompts__default = /*#__PURE__*/_interopDefaultLegacy(prompts);
|
|
14
|
-
|
|
15
|
-
const askOrchidORMConfig = async () => {
|
|
16
|
-
let cancelled = false;
|
|
17
|
-
const response = await prompts__default["default"](
|
|
18
|
-
[
|
|
19
|
-
{
|
|
20
|
-
type: "text",
|
|
21
|
-
name: "path",
|
|
22
|
-
message: "Where would you like to install Orchid ORM?",
|
|
23
|
-
initial: process.cwd()
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
type: "select",
|
|
27
|
-
name: "timestamp",
|
|
28
|
-
message: "Preferred type of returned timestamps:",
|
|
29
|
-
choices: [
|
|
30
|
-
{
|
|
31
|
-
title: "string (as returned from db)"
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
title: "number (epoch)",
|
|
35
|
-
value: "number"
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
title: "Date object",
|
|
39
|
-
value: "date"
|
|
40
|
-
}
|
|
41
|
-
]
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
type: "confirm",
|
|
45
|
-
name: "testDatabase",
|
|
46
|
-
message: "Should I add a separate database for tests?"
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
type: "confirm",
|
|
50
|
-
name: "addSchemaToZod",
|
|
51
|
-
message: "Are you going to use Zod for validation?"
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
type: "confirm",
|
|
55
|
-
name: "addTestFactory",
|
|
56
|
-
message: "Do you want object factories for writing tests?"
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
type: "confirm",
|
|
60
|
-
name: "demoTables",
|
|
61
|
-
message: "Should I add demo tables?"
|
|
62
|
-
}
|
|
63
|
-
],
|
|
64
|
-
{
|
|
65
|
-
onCancel() {
|
|
66
|
-
cancelled = true;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
);
|
|
70
|
-
if (cancelled)
|
|
71
|
-
return;
|
|
72
|
-
const tsConfigPath = path.join(response.path, "tsconfig.json");
|
|
73
|
-
const hasTsConfig = await readFileSafe(tsConfigPath);
|
|
74
|
-
response.hasTsConfig = !!hasTsConfig;
|
|
75
|
-
if (!hasTsConfig) {
|
|
76
|
-
const res = await prompts__default["default"](
|
|
77
|
-
[
|
|
78
|
-
{
|
|
79
|
-
type: "confirm",
|
|
80
|
-
name: "swc",
|
|
81
|
-
initial: true,
|
|
82
|
-
message: `Let's add fast TS compiler swc?`
|
|
83
|
-
}
|
|
84
|
-
],
|
|
85
|
-
{
|
|
86
|
-
onCancel() {
|
|
87
|
-
cancelled = true;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
);
|
|
91
|
-
if (cancelled)
|
|
92
|
-
return;
|
|
93
|
-
response.swc = res.swc;
|
|
94
|
-
}
|
|
95
|
-
return response;
|
|
96
|
-
};
|
|
97
|
-
const initOrchidORM = async (config) => {
|
|
98
|
-
config.path = path.resolve(config.path);
|
|
99
|
-
const dirPath = path.join(config.path, "src", "db");
|
|
100
|
-
await fs__default["default"].mkdir(dirPath, { recursive: true });
|
|
101
|
-
await setupPackageJson(config);
|
|
102
|
-
await setupTSConfig(config);
|
|
103
|
-
await setupEnv(config);
|
|
104
|
-
await setupGitIgnore(config);
|
|
105
|
-
await setupBaseTable(config, dirPath);
|
|
106
|
-
await setupTables(config, dirPath);
|
|
107
|
-
await setupConfig(config, dirPath);
|
|
108
|
-
await setupMainDb(config, dirPath);
|
|
109
|
-
await setupMigrationScript(config, dirPath);
|
|
110
|
-
await createMigrations(config, dirPath);
|
|
111
|
-
await createSeed(config, dirPath);
|
|
112
|
-
greet(config);
|
|
113
|
-
};
|
|
114
|
-
const setupPackageJson = async (config) => {
|
|
115
|
-
const pairs = await Promise.all([
|
|
116
|
-
getLatestPackageVersion("dotenv", "dependencies"),
|
|
117
|
-
getLatestPackageVersion("orchid-orm", "dependencies"),
|
|
118
|
-
getLatestPackageVersion("pqb", "dependencies"),
|
|
119
|
-
getLatestPackageVersion("pg", "dependencies"),
|
|
120
|
-
config.addSchemaToZod && getLatestPackageVersion("orchid-orm-schema-to-zod", "dependencies"),
|
|
121
|
-
getLatestPackageVersion("rake-db", "devDependencies"),
|
|
122
|
-
config.addTestFactory && getLatestPackageVersion("orchid-orm-test-factory", "devDependencies"),
|
|
123
|
-
config.swc && getLatestPackageVersion("@swc/core", "devDependencies"),
|
|
124
|
-
getLatestPackageVersion("@types/node", "devDependencies"),
|
|
125
|
-
getLatestPackageVersion("ts-node", "devDependencies"),
|
|
126
|
-
getLatestPackageVersion("typescript", "devDependencies")
|
|
127
|
-
]);
|
|
128
|
-
const deps = {};
|
|
129
|
-
const devDeps = {};
|
|
130
|
-
for (const item of pairs) {
|
|
131
|
-
if (!item)
|
|
132
|
-
continue;
|
|
133
|
-
const [key, { version, kind }] = item;
|
|
134
|
-
(kind === "dependencies" ? deps : devDeps)[key] = version;
|
|
135
|
-
}
|
|
136
|
-
const packageJsonPath = path.join(config.path, "package.json");
|
|
137
|
-
const content = await readFileSafe(packageJsonPath);
|
|
138
|
-
const json = content ? JSON.parse(content) : {};
|
|
139
|
-
if (!json.scripts)
|
|
140
|
-
json.scripts = {};
|
|
141
|
-
json.scripts.db = "ts-node src/db/dbScripts.ts";
|
|
142
|
-
if (!json.dependencies)
|
|
143
|
-
json.dependencies = {};
|
|
144
|
-
for (const key in deps) {
|
|
145
|
-
json.dependencies[key] = deps[key];
|
|
146
|
-
}
|
|
147
|
-
if (!json.devDependencies)
|
|
148
|
-
json.devDependencies = {};
|
|
149
|
-
for (const key in devDeps) {
|
|
150
|
-
json.devDependencies[key] = devDeps[key];
|
|
151
|
-
}
|
|
152
|
-
await fs__default["default"].writeFile(packageJsonPath, JSON.stringify(json, null, " ") + "\n");
|
|
153
|
-
};
|
|
154
|
-
const getLatestPackageVersion = (name, kind) => {
|
|
155
|
-
return new Promise((resolve2, reject) => {
|
|
156
|
-
https__default["default"].get(`https://registry.npmjs.org/${name}/latest`, (res) => {
|
|
157
|
-
let data = "";
|
|
158
|
-
res.on("data", (chunk) => data += chunk);
|
|
159
|
-
res.on(
|
|
160
|
-
"end",
|
|
161
|
-
() => resolve2([name, { version: `^${JSON.parse(data).version}`, kind }])
|
|
162
|
-
);
|
|
163
|
-
}).on("error", reject);
|
|
164
|
-
});
|
|
165
|
-
};
|
|
166
|
-
const readFileSafe = async (path) => {
|
|
167
|
-
try {
|
|
168
|
-
return await fs__default["default"].readFile(path, "utf-8");
|
|
169
|
-
} catch (err) {
|
|
170
|
-
if (err.code === "ENOENT") {
|
|
171
|
-
return void 0;
|
|
172
|
-
}
|
|
173
|
-
throw err;
|
|
174
|
-
}
|
|
175
|
-
};
|
|
176
|
-
const setupTSConfig = async (config) => {
|
|
177
|
-
if (config.hasTsConfig)
|
|
178
|
-
return;
|
|
179
|
-
const tsConfigPath = path.join(config.path, "tsconfig.json");
|
|
180
|
-
await fs__default["default"].writeFile(
|
|
181
|
-
tsConfigPath,
|
|
182
|
-
`{${config.swc ? `
|
|
183
|
-
"ts-node": {
|
|
184
|
-
"swc": true
|
|
185
|
-
},` : ""}
|
|
186
|
-
"compilerOptions": {
|
|
187
|
-
"strict": true
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
`
|
|
191
|
-
);
|
|
192
|
-
};
|
|
193
|
-
const setupEnv = async (config) => {
|
|
194
|
-
const envPath = path.join(config.path, ".env");
|
|
195
|
-
let content = (await readFileSafe(envPath) || "").trim();
|
|
196
|
-
let changed = false;
|
|
197
|
-
if (!content.match(/^DATABASE_URL=/m)) {
|
|
198
|
-
content += `
|
|
199
|
-
DATABASE_URL=postgres://user:password@localhost:5432/dbname?ssl=false`;
|
|
200
|
-
changed = true;
|
|
201
|
-
}
|
|
202
|
-
if (config.testDatabase && !content.match(/^DATABASE_TEST_URL=/m)) {
|
|
203
|
-
content += `
|
|
204
|
-
DATABASE_TEST_URL=postgres://user:password@localhost:5432/dbname-test?ssl=false`;
|
|
205
|
-
changed = true;
|
|
206
|
-
}
|
|
207
|
-
if (changed) {
|
|
208
|
-
await fs__default["default"].writeFile(envPath, `${content.trim()}
|
|
209
|
-
`);
|
|
210
|
-
}
|
|
211
|
-
};
|
|
212
|
-
const setupGitIgnore = async (config) => {
|
|
213
|
-
const gitignorePath = path.join(config.path, ".gitignore");
|
|
214
|
-
let content = (await readFileSafe(gitignorePath) || "").trim();
|
|
215
|
-
let changed = false;
|
|
216
|
-
if (!content.match(/^node_modules\b/m)) {
|
|
217
|
-
content += `
|
|
218
|
-
node_modules`;
|
|
219
|
-
changed = true;
|
|
220
|
-
}
|
|
221
|
-
if (!content.match(/^.env\b/m)) {
|
|
222
|
-
content += `
|
|
223
|
-
.env`;
|
|
224
|
-
changed = true;
|
|
225
|
-
}
|
|
226
|
-
if (changed) {
|
|
227
|
-
await fs__default["default"].writeFile(gitignorePath, `${content.trim()}
|
|
228
|
-
`);
|
|
229
|
-
}
|
|
230
|
-
};
|
|
231
|
-
const setupBaseTable = async (config, dirPath) => {
|
|
232
|
-
const filePath = path.join(dirPath, "baseTable.ts");
|
|
233
|
-
let content = `import { createBaseTable } from 'orchid-orm';
|
|
234
|
-
|
|
235
|
-
export const BaseTable = createBaseTable({
|
|
236
|
-
columnTypes: (t) => ({
|
|
237
|
-
...t,
|
|
238
|
-
text: (min = 0, max = Infinity) => t.text(min, max),`;
|
|
239
|
-
const { timestamp } = config;
|
|
240
|
-
if (timestamp) {
|
|
241
|
-
content += `
|
|
242
|
-
timestamp: <P extends number>(precision?: P) =>
|
|
243
|
-
t.timestamp<P>(precision).${timestamp === "date" ? "asDate" : "asNumber"}(),`;
|
|
244
|
-
}
|
|
245
|
-
content += `
|
|
246
|
-
}),
|
|
247
|
-
});
|
|
248
|
-
`;
|
|
249
|
-
await fs__default["default"].writeFile(filePath, content);
|
|
250
|
-
};
|
|
251
|
-
const setupTables = async (config, dirPath) => {
|
|
252
|
-
if (!config.demoTables)
|
|
253
|
-
return;
|
|
254
|
-
const tablesDir = path.join(dirPath, "tables");
|
|
255
|
-
await fs__default["default"].mkdir(tablesDir, { recursive: true });
|
|
256
|
-
await fs__default["default"].writeFile(
|
|
257
|
-
path.join(tablesDir, "post.table.ts"),
|
|
258
|
-
`import { BaseTable } from '../baseTable';
|
|
259
|
-
import { CommentTable } from './comment.table';
|
|
260
|
-
${config.addSchemaToZod ? `import { tableToZod } from 'orchid-orm-schema-to-zod';
|
|
261
|
-
` : ""}
|
|
262
|
-
export type Post = PostTable['columns']['type'];
|
|
263
|
-
export class PostTable extends BaseTable {
|
|
264
|
-
readonly table = 'post';
|
|
265
|
-
columns = this.setColumns((t) => ({
|
|
266
|
-
id: t.identity().primaryKey(),
|
|
267
|
-
title: t.text(3, 100).unique(),
|
|
268
|
-
text: t.text(20, 10000),
|
|
269
|
-
...t.timestamps(),
|
|
270
|
-
}));
|
|
271
|
-
|
|
272
|
-
relations = {
|
|
273
|
-
comments: this.hasMany(() => CommentTable, {
|
|
274
|
-
primaryKey: 'id',
|
|
275
|
-
foreignKey: 'postId',
|
|
276
|
-
}),
|
|
277
|
-
};
|
|
278
|
-
}
|
|
279
|
-
${config.addSchemaToZod ? `
|
|
280
|
-
export const postSchema = tableToZod(PostTable);
|
|
281
|
-
` : ""}`
|
|
282
|
-
);
|
|
283
|
-
await fs__default["default"].writeFile(
|
|
284
|
-
path.join(tablesDir, "comment.table.ts"),
|
|
285
|
-
`import { BaseTable } from '../baseTable';
|
|
286
|
-
import { PostTable } from './post.table';
|
|
287
|
-
${config.addSchemaToZod ? `import { tableToZod } from 'orchid-orm-schema-to-zod';
|
|
288
|
-
` : ""}
|
|
289
|
-
export type Comment = CommentTable['columns']['type'];
|
|
290
|
-
export class CommentTable extends BaseTable {
|
|
291
|
-
readonly table = 'comment';
|
|
292
|
-
columns = this.setColumns((t) => ({
|
|
293
|
-
id: t.identity().primaryKey(),
|
|
294
|
-
postId: t
|
|
295
|
-
.integer()
|
|
296
|
-
.foreignKey(() => PostTable, 'id')
|
|
297
|
-
.index(),
|
|
298
|
-
text: t.text(5, 1000),
|
|
299
|
-
...t.timestamps(),
|
|
300
|
-
}));
|
|
301
|
-
|
|
302
|
-
relations = {
|
|
303
|
-
post: this.belongsTo(() => PostTable, {
|
|
304
|
-
primaryKey: 'id',
|
|
305
|
-
foreignKey: 'postId',
|
|
306
|
-
}),
|
|
307
|
-
};
|
|
308
|
-
}
|
|
309
|
-
${config.addSchemaToZod ? `
|
|
310
|
-
export const commentSchema = tableToZod(CommentTable);
|
|
311
|
-
` : ""}`
|
|
312
|
-
);
|
|
313
|
-
};
|
|
314
|
-
const setupConfig = async (config, dirPath) => {
|
|
315
|
-
const configPath = path.join(dirPath, "config.ts");
|
|
316
|
-
let content = `import 'dotenv/config';
|
|
317
|
-
|
|
318
|
-
const database = {
|
|
319
|
-
databaseURL: process.env.DATABASE_URL,
|
|
320
|
-
};
|
|
321
|
-
if (!database.databaseURL) throw new Error('DATABASE_URL is missing in .env');`;
|
|
322
|
-
if (config.testDatabase) {
|
|
323
|
-
content += `
|
|
324
|
-
|
|
325
|
-
const testDatabase = {
|
|
326
|
-
databaseURL: process.env.DATABASE_TEST_URL,
|
|
327
|
-
};
|
|
328
|
-
|
|
329
|
-
const allDatabases = [database];
|
|
330
|
-
|
|
331
|
-
if (testDatabase.databaseURL) {
|
|
332
|
-
allDatabases.push(testDatabase);
|
|
333
|
-
}`;
|
|
334
|
-
}
|
|
335
|
-
content += `
|
|
336
|
-
|
|
337
|
-
export const config = {`;
|
|
338
|
-
if (config.testDatabase) {
|
|
339
|
-
content += `
|
|
340
|
-
allDatabases,`;
|
|
341
|
-
}
|
|
342
|
-
if (config.testDatabase) {
|
|
343
|
-
content += `
|
|
344
|
-
database: process.env.NODE_ENV === 'test' ? testDatabase : database,`;
|
|
345
|
-
} else {
|
|
346
|
-
content += `
|
|
347
|
-
database,`;
|
|
348
|
-
}
|
|
349
|
-
content += `
|
|
350
|
-
};
|
|
351
|
-
`;
|
|
352
|
-
await fs__default["default"].writeFile(configPath, content);
|
|
353
|
-
};
|
|
354
|
-
const setupMainDb = async (config, dirPath) => {
|
|
355
|
-
let imports = "";
|
|
356
|
-
let tables = "";
|
|
357
|
-
if (config.demoTables) {
|
|
358
|
-
imports += `
|
|
359
|
-
import { PostTable } from './tables/post.table';
|
|
360
|
-
import { CommentTable } from './tables/comment.table';`;
|
|
361
|
-
tables += `
|
|
362
|
-
post: PostTable,
|
|
363
|
-
comment: CommentTable,`;
|
|
364
|
-
}
|
|
365
|
-
const dbPath = path.join(dirPath, "db.ts");
|
|
366
|
-
await fs__default["default"].writeFile(
|
|
367
|
-
dbPath,
|
|
368
|
-
`import { orchidORM } from 'orchid-orm';
|
|
369
|
-
import { config } from './config';${imports}
|
|
370
|
-
|
|
371
|
-
export const db = orchidORM(config.database, {${tables}
|
|
372
|
-
});
|
|
373
|
-
`
|
|
374
|
-
);
|
|
375
|
-
};
|
|
376
|
-
const setupMigrationScript = async (config, dirPath) => {
|
|
377
|
-
const filePath = path.join(dirPath, "dbScripts.ts");
|
|
378
|
-
await fs__default["default"].writeFile(
|
|
379
|
-
filePath,
|
|
380
|
-
`import { rakeDb } from 'rake-db';
|
|
381
|
-
import { config } from './config';
|
|
382
|
-
import { appCodeUpdater } from 'orchid-orm';
|
|
383
|
-
|
|
384
|
-
rakeDb(${config.testDatabase ? "config.allDatabases" : "config.database"}, {
|
|
385
|
-
migrationsPath: './migrations',
|
|
386
|
-
appCodeUpdater: appCodeUpdater({
|
|
387
|
-
tablePath: (tableName) => \`./tables/\${tableName}.table.ts\`,
|
|
388
|
-
baseTablePath: './baseTable.ts',
|
|
389
|
-
baseTableName: 'BaseTable',
|
|
390
|
-
mainFilePath: './db.ts',
|
|
391
|
-
}),
|
|
392
|
-
useCodeUpdater: true, // set to false to disable code updater
|
|
393
|
-
commands: {
|
|
394
|
-
async seed() {
|
|
395
|
-
const { seed } = await import('./seed');
|
|
396
|
-
await seed();
|
|
397
|
-
},
|
|
398
|
-
},
|
|
399
|
-
});
|
|
400
|
-
`
|
|
401
|
-
);
|
|
402
|
-
};
|
|
403
|
-
const createMigrations = async (config, dirPath) => {
|
|
404
|
-
const migrationsPath = path.join(dirPath, "migrations");
|
|
405
|
-
await fs__default["default"].mkdir(migrationsPath, { recursive: true });
|
|
406
|
-
if (!config.demoTables)
|
|
407
|
-
return;
|
|
408
|
-
const now = new Date();
|
|
409
|
-
const postPath = path.join(
|
|
410
|
-
migrationsPath,
|
|
411
|
-
`${makeFileTimeStamp(now)}_createPost.ts`
|
|
412
|
-
);
|
|
413
|
-
await fs__default["default"].writeFile(
|
|
414
|
-
postPath,
|
|
415
|
-
`import { change } from 'rake-db';
|
|
416
|
-
|
|
417
|
-
change(async (db) => {
|
|
418
|
-
await db.createTable('post', (t) => ({
|
|
419
|
-
id: t.identity().primaryKey(),
|
|
420
|
-
title: t.text().unique(),
|
|
421
|
-
text: t.text(),
|
|
422
|
-
...t.timestamps(),
|
|
423
|
-
}));
|
|
424
|
-
});
|
|
425
|
-
`
|
|
426
|
-
);
|
|
427
|
-
now.setTime(now.getTime() + 1e3);
|
|
428
|
-
const commentPath = path.join(
|
|
429
|
-
migrationsPath,
|
|
430
|
-
`${makeFileTimeStamp(now)}_createComment.ts`
|
|
431
|
-
);
|
|
432
|
-
await fs__default["default"].writeFile(
|
|
433
|
-
commentPath,
|
|
434
|
-
`import { change } from 'rake-db';
|
|
435
|
-
|
|
436
|
-
change(async (db) => {
|
|
437
|
-
await db.createTable('comment', (t) => ({
|
|
438
|
-
id: t.identity().primaryKey(),
|
|
439
|
-
postId: t.integer().foreignKey('post', 'id').index(),
|
|
440
|
-
text: t.text(),
|
|
441
|
-
...t.timestamps(),
|
|
442
|
-
}));
|
|
443
|
-
});
|
|
444
|
-
`
|
|
445
|
-
);
|
|
446
|
-
};
|
|
447
|
-
const makeFileTimeStamp = (now) => {
|
|
448
|
-
return [
|
|
449
|
-
now.getUTCFullYear(),
|
|
450
|
-
now.getUTCMonth() + 1,
|
|
451
|
-
now.getUTCDate(),
|
|
452
|
-
now.getUTCHours(),
|
|
453
|
-
now.getUTCMinutes(),
|
|
454
|
-
now.getUTCSeconds()
|
|
455
|
-
].map((value) => value < 10 ? `0${value}` : value).join("");
|
|
456
|
-
};
|
|
457
|
-
const createSeed = async (config, dirPath) => {
|
|
458
|
-
const filePath = path.join(dirPath, "seed.ts");
|
|
459
|
-
let content;
|
|
460
|
-
if (config.demoTables) {
|
|
461
|
-
content = `await db.post.findBy({ title: 'Sample post' }).orCreate({
|
|
462
|
-
title: 'Post',
|
|
463
|
-
text: 'This is a text for a sample post. It contains words, spaces, and punctuation.',
|
|
464
|
-
comments: {
|
|
465
|
-
create: [
|
|
466
|
-
{
|
|
467
|
-
text: 'Nice post!',
|
|
468
|
-
},
|
|
469
|
-
{
|
|
470
|
-
text: \`Too long, didn't read\`,
|
|
471
|
-
},
|
|
472
|
-
],
|
|
473
|
-
},
|
|
474
|
-
});`;
|
|
475
|
-
} else {
|
|
476
|
-
content = `// create records here`;
|
|
477
|
-
}
|
|
478
|
-
await fs__default["default"].writeFile(
|
|
479
|
-
filePath,
|
|
480
|
-
`import { db } from './db';
|
|
481
|
-
|
|
482
|
-
export const seed = async () => {
|
|
483
|
-
${content}
|
|
484
|
-
|
|
485
|
-
await db.$close();
|
|
486
|
-
};
|
|
487
|
-
`
|
|
488
|
-
);
|
|
489
|
-
};
|
|
490
|
-
const greet = (config) => {
|
|
491
|
-
const relativePath = path.relative(process.cwd(), config.path);
|
|
492
|
-
console.log(`
|
|
493
|
-
Thank you for trying Orchid ORM!
|
|
494
|
-
|
|
495
|
-
To finish setup,${relativePath ? ` cd to the project and` : ""} install dependencies:
|
|
496
|
-
${relativePath ? `
|
|
497
|
-
> cd ${relativePath}` : ""}
|
|
498
|
-
> npm i
|
|
499
|
-
|
|
500
|
-
Enter the correct database credentials to the .env file,
|
|
501
|
-
then create the database:
|
|
502
|
-
|
|
503
|
-
> npm run db create
|
|
504
|
-
|
|
505
|
-
And run the migrations:
|
|
506
|
-
|
|
507
|
-
> npm run db migrate
|
|
508
|
-
`);
|
|
509
|
-
};
|
|
510
|
-
|
|
511
|
-
askOrchidORMConfig().then((config) => {
|
|
512
|
-
if (config)
|
|
513
|
-
initOrchidORM(config);
|
|
514
|
-
});
|
|
515
|
-
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bin.js","sources":["../src/bin/init.ts","../src/bin/bin.ts"],"sourcesContent":["import fs from 'fs/promises';\nimport { resolve, join, relative } from 'path';\nimport https from 'https';\nimport prompts from 'prompts';\n\nexport type InitConfig = {\n path: string;\n hasTsConfig: boolean;\n testDatabase?: boolean;\n addSchemaToZod?: boolean;\n addTestFactory?: boolean;\n demoTables?: boolean;\n timestamp?: 'date' | 'number';\n swc?: boolean;\n};\n\ntype DependencyKind = 'dependencies' | 'devDependencies';\n\nexport const askOrchidORMConfig = async () => {\n let cancelled = false;\n\n const response = await prompts(\n [\n {\n type: 'text',\n name: 'path',\n message: 'Where would you like to install Orchid ORM?',\n initial: process.cwd(),\n },\n {\n type: 'select',\n name: 'timestamp',\n message: 'Preferred type of returned timestamps:',\n choices: [\n {\n title: 'string (as returned from db)',\n },\n {\n title: 'number (epoch)',\n value: 'number',\n },\n {\n title: 'Date object',\n value: 'date',\n },\n ],\n },\n {\n type: 'confirm',\n name: 'testDatabase',\n message: 'Should I add a separate database for tests?',\n },\n {\n type: 'confirm',\n name: 'addSchemaToZod',\n message: 'Are you going to use Zod for validation?',\n },\n {\n type: 'confirm',\n name: 'addTestFactory',\n message: 'Do you want object factories for writing tests?',\n },\n {\n type: 'confirm',\n name: 'demoTables',\n message: 'Should I add demo tables?',\n },\n ],\n {\n onCancel() {\n cancelled = true;\n },\n },\n );\n\n if (cancelled) return;\n\n const tsConfigPath = join(response.path, 'tsconfig.json');\n const hasTsConfig = await readFileSafe(tsConfigPath);\n (response as InitConfig).hasTsConfig = !!hasTsConfig;\n\n if (!hasTsConfig) {\n const res = await prompts(\n [\n {\n type: 'confirm',\n name: 'swc',\n initial: true,\n message: `Let's add fast TS compiler swc?`,\n },\n ],\n {\n onCancel() {\n cancelled = true;\n },\n },\n );\n\n if (cancelled) return;\n\n (response as InitConfig).swc = res.swc;\n }\n\n return response as InitConfig;\n};\n\nexport const initOrchidORM = async (config: InitConfig) => {\n config.path = resolve(config.path);\n const dirPath = join(config.path, 'src', 'db');\n\n await fs.mkdir(dirPath, { recursive: true });\n\n await setupPackageJson(config);\n await setupTSConfig(config);\n await setupEnv(config);\n await setupGitIgnore(config);\n await setupBaseTable(config, dirPath);\n await setupTables(config, dirPath);\n await setupConfig(config, dirPath);\n await setupMainDb(config, dirPath);\n await setupMigrationScript(config, dirPath);\n await createMigrations(config, dirPath);\n await createSeed(config, dirPath);\n\n greet(config);\n};\n\nconst setupPackageJson = async (config: InitConfig) => {\n const pairs = await Promise.all([\n getLatestPackageVersion('dotenv', 'dependencies'),\n getLatestPackageVersion('orchid-orm', 'dependencies'),\n getLatestPackageVersion('pqb', 'dependencies'),\n getLatestPackageVersion('pg', 'dependencies'),\n config.addSchemaToZod &&\n getLatestPackageVersion('orchid-orm-schema-to-zod', 'dependencies'),\n getLatestPackageVersion('rake-db', 'devDependencies'),\n config.addTestFactory &&\n getLatestPackageVersion('orchid-orm-test-factory', 'devDependencies'),\n config.swc && getLatestPackageVersion('@swc/core', 'devDependencies'),\n getLatestPackageVersion('@types/node', 'devDependencies'),\n getLatestPackageVersion('ts-node', 'devDependencies'),\n getLatestPackageVersion('typescript', 'devDependencies'),\n ]);\n\n const deps: Record<string, string> = {};\n const devDeps: Record<string, string> = {};\n for (const item of pairs) {\n if (!item) continue;\n const [key, { version, kind }] = item;\n (kind === 'dependencies' ? deps : devDeps)[key] = version;\n }\n\n const packageJsonPath = join(config.path, 'package.json');\n const content = await readFileSafe(packageJsonPath);\n const json = content ? JSON.parse(content) : {};\n\n if (!json.scripts) json.scripts = {};\n json.scripts.db = 'ts-node src/db/dbScripts.ts';\n\n if (!json.dependencies) json.dependencies = {};\n\n for (const key in deps) {\n json.dependencies[key] = deps[key];\n }\n\n if (!json.devDependencies) json.devDependencies = {};\n for (const key in devDeps) {\n json.devDependencies[key] = devDeps[key];\n }\n\n await fs.writeFile(packageJsonPath, JSON.stringify(json, null, ' ') + '\\n');\n};\n\nconst getLatestPackageVersion = (\n name: string,\n kind: DependencyKind,\n): Promise<[string, { version: string; kind: DependencyKind }]> => {\n return new Promise((resolve, reject) => {\n https\n .get(`https://registry.npmjs.org/${name}/latest`, (res) => {\n let data = '';\n res.on('data', (chunk) => (data += chunk));\n res.on('end', () =>\n resolve([name, { version: `^${JSON.parse(data).version}`, kind }]),\n );\n })\n .on('error', reject);\n });\n};\n\nconst readFileSafe = async (path: string) => {\n try {\n return await fs.readFile(path, 'utf-8');\n } catch (err) {\n if ((err as unknown as { code: string }).code === 'ENOENT') {\n return undefined;\n }\n throw err;\n }\n};\n\nconst setupTSConfig = async (config: InitConfig) => {\n if (config.hasTsConfig) return;\n\n const tsConfigPath = join(config.path, 'tsconfig.json');\n await fs.writeFile(\n tsConfigPath,\n `{${\n config.swc\n ? `\n \"ts-node\": {\n \"swc\": true\n },`\n : ''\n }\n \"compilerOptions\": {\n \"strict\": true\n }\n}\n`,\n );\n};\n\nconst setupEnv = async (config: InitConfig) => {\n const envPath = join(config.path, '.env');\n let content = ((await readFileSafe(envPath)) || '').trim();\n let changed = false;\n\n if (!content.match(/^DATABASE_URL=/m)) {\n content += `\\nDATABASE_URL=postgres://user:password@localhost:5432/dbname?ssl=false`;\n changed = true;\n }\n\n if (config.testDatabase && !content.match(/^DATABASE_TEST_URL=/m)) {\n content += `\\nDATABASE_TEST_URL=postgres://user:password@localhost:5432/dbname-test?ssl=false`;\n changed = true;\n }\n\n if (changed) {\n await fs.writeFile(envPath, `${content.trim()}\\n`);\n }\n};\n\nconst setupGitIgnore = async (config: InitConfig) => {\n const gitignorePath = join(config.path, '.gitignore');\n let content = ((await readFileSafe(gitignorePath)) || '').trim();\n let changed = false;\n\n if (!content.match(/^node_modules\\b/m)) {\n content += `\\nnode_modules`;\n changed = true;\n }\n\n if (!content.match(/^.env\\b/m)) {\n content += `\\n.env`;\n changed = true;\n }\n\n if (changed) {\n await fs.writeFile(gitignorePath, `${content.trim()}\\n`);\n }\n};\n\nconst setupBaseTable = async (config: InitConfig, dirPath: string) => {\n const filePath = join(dirPath, 'baseTable.ts');\n\n let content = `import { createBaseTable } from 'orchid-orm';\n\nexport const BaseTable = createBaseTable({\n columnTypes: (t) => ({\n ...t,\n text: (min = 0, max = Infinity) => t.text(min, max),`;\n\n const { timestamp } = config;\n if (timestamp) {\n content += `\n timestamp: <P extends number>(precision?: P) =>\n t.timestamp<P>(precision).${\n timestamp === 'date' ? 'asDate' : 'asNumber'\n }(),`;\n }\n\n content += `\n }),\n});\n`;\n\n await fs.writeFile(filePath, content);\n};\n\nconst setupTables = async (config: InitConfig, dirPath: string) => {\n if (!config.demoTables) return;\n\n const tablesDir = join(dirPath, 'tables');\n await fs.mkdir(tablesDir, { recursive: true });\n\n await fs.writeFile(\n join(tablesDir, 'post.table.ts'),\n `import { BaseTable } from '../baseTable';\nimport { CommentTable } from './comment.table';\n${\n config.addSchemaToZod\n ? `import { tableToZod } from 'orchid-orm-schema-to-zod';\\n`\n : ''\n}\nexport type Post = PostTable['columns']['type'];\nexport class PostTable extends BaseTable {\n readonly table = 'post';\n columns = this.setColumns((t) => ({\n id: t.identity().primaryKey(),\n title: t.text(3, 100).unique(),\n text: t.text(20, 10000),\n ...t.timestamps(),\n }));\n\n relations = {\n comments: this.hasMany(() => CommentTable, {\n primaryKey: 'id',\n foreignKey: 'postId',\n }),\n };\n}\n${\n config.addSchemaToZod\n ? `\\nexport const postSchema = tableToZod(PostTable);\\n`\n : ''\n}`,\n );\n\n await fs.writeFile(\n join(tablesDir, 'comment.table.ts'),\n `import { BaseTable } from '../baseTable';\nimport { PostTable } from './post.table';\n${\n config.addSchemaToZod\n ? `import { tableToZod } from 'orchid-orm-schema-to-zod';\\n`\n : ''\n}\nexport type Comment = CommentTable['columns']['type'];\nexport class CommentTable extends BaseTable {\n readonly table = 'comment';\n columns = this.setColumns((t) => ({\n id: t.identity().primaryKey(),\n postId: t\n .integer()\n .foreignKey(() => PostTable, 'id')\n .index(),\n text: t.text(5, 1000),\n ...t.timestamps(),\n }));\n\n relations = {\n post: this.belongsTo(() => PostTable, {\n primaryKey: 'id',\n foreignKey: 'postId',\n }),\n };\n}\n${\n config.addSchemaToZod\n ? `\\nexport const commentSchema = tableToZod(CommentTable);\\n`\n : ''\n}`,\n );\n};\n\nconst setupConfig = async (config: InitConfig, dirPath: string) => {\n const configPath = join(dirPath, 'config.ts');\n\n let content = `import 'dotenv/config';\n\nconst database = {\n databaseURL: process.env.DATABASE_URL,\n};\nif (!database.databaseURL) throw new Error('DATABASE_URL is missing in .env');`;\n\n if (config.testDatabase) {\n content += `\n\nconst testDatabase = {\n databaseURL: process.env.DATABASE_TEST_URL,\n};\n\nconst allDatabases = [database];\n\nif (testDatabase.databaseURL) {\n allDatabases.push(testDatabase);\n}`;\n }\n\n content += `\n\nexport const config = {`;\n\n if (config.testDatabase) {\n content += `\n allDatabases,`;\n }\n\n if (config.testDatabase) {\n content += `\n database: process.env.NODE_ENV === 'test' ? testDatabase : database,`;\n } else {\n content += `\n database,`;\n }\n content += `\n};\n`;\n\n await fs.writeFile(configPath, content);\n};\n\nconst setupMainDb = async (config: InitConfig, dirPath: string) => {\n let imports = '';\n let tables = '';\n if (config.demoTables) {\n imports += `\nimport { PostTable } from './tables/post.table';\nimport { CommentTable } from './tables/comment.table';`;\n tables += `\n post: PostTable,\n comment: CommentTable,`;\n }\n\n const dbPath = join(dirPath, 'db.ts');\n await fs.writeFile(\n dbPath,\n `import { orchidORM } from 'orchid-orm';\nimport { config } from './config';${imports}\n\nexport const db = orchidORM(config.database, {${tables}\n});\n`,\n );\n};\n\nconst setupMigrationScript = async (config: InitConfig, dirPath: string) => {\n const filePath = join(dirPath, 'dbScripts.ts');\n await fs.writeFile(\n filePath,\n `import { rakeDb } from 'rake-db';\nimport { config } from './config';\nimport { appCodeUpdater } from 'orchid-orm';\n\nrakeDb(${config.testDatabase ? 'config.allDatabases' : 'config.database'}, {\n migrationsPath: './migrations',\n appCodeUpdater: appCodeUpdater({\n tablePath: (tableName) => \\`./tables/\\${tableName}.table.ts\\`,\n baseTablePath: './baseTable.ts',\n baseTableName: 'BaseTable',\n mainFilePath: './db.ts',\n }),\n useCodeUpdater: true, // set to false to disable code updater\n commands: {\n async seed() {\n const { seed } = await import('./seed');\n await seed();\n },\n },\n});\n`,\n );\n};\n\nconst createMigrations = async (config: InitConfig, dirPath: string) => {\n const migrationsPath = join(dirPath, 'migrations');\n await fs.mkdir(migrationsPath, { recursive: true });\n\n if (!config.demoTables) return;\n\n const now = new Date();\n\n const postPath = join(\n migrationsPath,\n `${makeFileTimeStamp(now)}_createPost.ts`,\n );\n await fs.writeFile(\n postPath,\n `import { change } from 'rake-db';\n\nchange(async (db) => {\n await db.createTable('post', (t) => ({\n id: t.identity().primaryKey(),\n title: t.text().unique(),\n text: t.text(),\n ...t.timestamps(),\n }));\n});\n`,\n );\n\n now.setTime(now.getTime() + 1000);\n\n const commentPath = join(\n migrationsPath,\n `${makeFileTimeStamp(now)}_createComment.ts`,\n );\n await fs.writeFile(\n commentPath,\n `import { change } from 'rake-db';\n\nchange(async (db) => {\n await db.createTable('comment', (t) => ({\n id: t.identity().primaryKey(),\n postId: t.integer().foreignKey('post', 'id').index(),\n text: t.text(),\n ...t.timestamps(),\n }));\n});\n`,\n );\n};\n\nconst makeFileTimeStamp = (now: Date) => {\n return [\n now.getUTCFullYear(),\n now.getUTCMonth() + 1,\n now.getUTCDate(),\n now.getUTCHours(),\n now.getUTCMinutes(),\n now.getUTCSeconds(),\n ]\n .map((value) => (value < 10 ? `0${value}` : value))\n .join('');\n};\n\nconst createSeed = async (config: InitConfig, dirPath: string) => {\n const filePath = join(dirPath, 'seed.ts');\n\n let content;\n if (config.demoTables) {\n content = `await db.post.findBy({ title: 'Sample post' }).orCreate({\n title: 'Post',\n text: 'This is a text for a sample post. It contains words, spaces, and punctuation.',\n comments: {\n create: [\n {\n text: 'Nice post!',\n },\n {\n text: \\`Too long, didn't read\\`,\n },\n ],\n },\n });`;\n } else {\n content = `// create records here`;\n }\n\n await fs.writeFile(\n filePath,\n `import { db } from './db';\n\nexport const seed = async () => {\n ${content}\n\n await db.$close();\n};\n`,\n );\n};\n\nconst greet = (config: InitConfig) => {\n const relativePath = relative(process.cwd(), config.path);\n\n console.log(`\nThank you for trying Orchid ORM!\n \nTo finish setup,${\n relativePath ? ` cd to the project and` : ''\n } install dependencies:\n${\n relativePath\n ? `\n> cd ${relativePath}`\n : ''\n}\n> npm i\n\nEnter the correct database credentials to the .env file,\nthen create the database:\n\n> npm run db create\n\nAnd run the migrations:\n\n> npm run db migrate\n`);\n};\n","import { askOrchidORMConfig, initOrchidORM } from './init';\n\naskOrchidORMConfig().then((config) => {\n if (config) initOrchidORM(config);\n});\n"],"names":["prompts","join","resolve","fs","https","relative"],"mappings":"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"}
|