create-absolutejs 0.4.2 → 0.5.1
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/data.d.ts +2 -1
- package/dist/data.js +48 -1
- package/dist/generators/configurations/generateEnv.js +6 -6
- package/dist/generators/configurations/generatePackageJson.js +74 -32
- package/dist/generators/configurations/initializeRoot.d.ts +1 -0
- package/dist/generators/configurations/initializeRoot.js +8 -2
- package/dist/generators/db/dockerInitTemplates.d.ts +13 -13
- package/dist/generators/db/dockerInitTemplates.js +39 -22
- package/dist/generators/db/generateDatabaseTypes.d.ts +8 -0
- package/dist/generators/db/generateDatabaseTypes.js +67 -0
- package/dist/generators/db/generateDockerContainer.js +13 -13
- package/dist/generators/db/generateDrizzleSchema.d.ts +2 -3
- package/dist/generators/db/generateDrizzleSchema.js +17 -27
- package/dist/generators/db/handlerTemplates.d.ts +48 -18
- package/dist/generators/db/handlerTemplates.js +236 -121
- package/dist/generators/db/scaffoldDatabase.d.ts +2 -1
- package/dist/generators/db/scaffoldDatabase.js +9 -3
- package/dist/generators/project/generateDBBlock.js +17 -24
- package/dist/generators/project/generateImportsBlock.js +114 -33
- package/dist/generators/project/generateUseBlock.js +5 -1
- package/dist/messages.js +1 -1
- package/dist/questions/databaseEngine.d.ts +1 -1
- package/dist/questions/databaseHost.js +12 -0
- package/dist/scaffold.js +3 -2
- package/dist/templates/styles/tailwind.css +1 -0
- package/dist/utils/parseCommandLineOptions.js +1 -1
- package/package.json +1 -1
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
const DIALECTS = {
|
|
2
2
|
gel: {
|
|
3
|
-
builders: ['text', 'gelTable', 'timestamp', 'integer'],
|
|
4
|
-
json: '
|
|
3
|
+
builders: ['text', 'gelTable', 'timestamp', 'integer', 'json'],
|
|
4
|
+
json: 'json()',
|
|
5
5
|
pkg: 'gel-core',
|
|
6
6
|
string: 'text()',
|
|
7
7
|
table: 'gelTable',
|
|
8
8
|
time: 'timestamp()'
|
|
9
9
|
},
|
|
10
|
+
mariadb: {
|
|
11
|
+
builders: ['json', 'mysqlTable', 'timestamp', 'varchar', 'int'],
|
|
12
|
+
json: 'json()',
|
|
13
|
+
pkg: 'mysql-core',
|
|
14
|
+
string: 'varchar({ length: 255 })',
|
|
15
|
+
table: 'mysqlTable',
|
|
16
|
+
time: 'timestamp()'
|
|
17
|
+
},
|
|
10
18
|
mysql: {
|
|
11
19
|
builders: ['json', 'mysqlTable', 'timestamp', 'varchar', 'int'],
|
|
12
20
|
json: 'json()',
|
|
@@ -41,9 +49,11 @@ const DIALECTS = {
|
|
|
41
49
|
}
|
|
42
50
|
};
|
|
43
51
|
const builder = (expr) => expr.split('(')[0];
|
|
44
|
-
export const generateDrizzleSchema = ({ databaseEngine,
|
|
52
|
+
export const generateDrizzleSchema = ({ databaseEngine, authProvider }) => {
|
|
45
53
|
const cfg = DIALECTS[databaseEngine];
|
|
46
|
-
const intBuilder = databaseEngine === 'mysql' ||
|
|
54
|
+
const intBuilder = databaseEngine === 'mysql' ||
|
|
55
|
+
databaseEngine === 'singlestore' ||
|
|
56
|
+
databaseEngine === 'mariadb'
|
|
47
57
|
? 'int'
|
|
48
58
|
: 'integer';
|
|
49
59
|
const timeBuilder = builder(cfg.time);
|
|
@@ -57,23 +67,10 @@ export const generateDrizzleSchema = ({ databaseEngine, databaseHost, authProvid
|
|
|
57
67
|
const sqliteImports = databaseEngine === 'sqlite'
|
|
58
68
|
? `import { sql } from 'drizzle-orm';\n`
|
|
59
69
|
: '';
|
|
60
|
-
let dbImport = '';
|
|
61
|
-
let dbTypeLine = '';
|
|
62
|
-
if (databaseHost === 'neon') {
|
|
63
|
-
dbImport = `import { NeonHttpDatabase } from 'drizzle-orm/neon-http';`;
|
|
64
|
-
dbTypeLine = 'export type DatabaseType = NeonHttpDatabase<SchemaType>;';
|
|
65
|
-
}
|
|
66
|
-
else if (databaseHost === 'planetscale') {
|
|
67
|
-
dbImport = `import { PlanetScaleDatabase } from 'drizzle-orm/planetscale-serverless';`;
|
|
68
|
-
dbTypeLine =
|
|
69
|
-
'export type DatabaseType = PlanetScaleDatabase<SchemaType>;';
|
|
70
|
-
}
|
|
71
|
-
else if (databaseHost === 'turso') {
|
|
72
|
-
dbImport = `import { LibSQLDatabase } from 'drizzle-orm/libsql';`;
|
|
73
|
-
dbTypeLine = 'export type DatabaseType = LibSQLDatabase<SchemaType>;';
|
|
74
|
-
}
|
|
75
70
|
let uidColumn;
|
|
76
|
-
if (databaseEngine === 'mysql' ||
|
|
71
|
+
if (databaseEngine === 'mysql' ||
|
|
72
|
+
databaseEngine === 'singlestore' ||
|
|
73
|
+
databaseEngine === 'mariadb') {
|
|
77
74
|
uidColumn = `${intBuilder}('uid').primaryKey().autoincrement()`;
|
|
78
75
|
}
|
|
79
76
|
else if (databaseEngine === 'sqlite') {
|
|
@@ -101,14 +98,8 @@ const MILLIS_PER_DAY = 86400000;\n\n`
|
|
|
101
98
|
created_at: ${timestampColumn}
|
|
102
99
|
});`;
|
|
103
100
|
const schemaKey = authProvider === 'absoluteAuth' ? 'users' : 'countHistory';
|
|
104
|
-
const extraTypes = authProvider === 'absoluteAuth'
|
|
105
|
-
? `export type User = typeof users.$inferSelect;
|
|
106
|
-
export type NewUser = typeof users.$inferInsert;`
|
|
107
|
-
: `export type CountHistory = typeof countHistory.$inferSelect;
|
|
108
|
-
export type NewCountHistory = typeof countHistory.$inferInsert;`;
|
|
109
101
|
return `
|
|
110
102
|
${sqliteImports}${builderImport}
|
|
111
|
-
${dbImport}
|
|
112
103
|
|
|
113
104
|
${constsBlock}${tableBlock}
|
|
114
105
|
|
|
@@ -117,6 +108,5 @@ export const schema = {
|
|
|
117
108
|
};
|
|
118
109
|
|
|
119
110
|
export type SchemaType = typeof schema;
|
|
120
|
-
${dbTypeLine ? `${dbTypeLine}\n\n` : '\n'}${extraTypes}
|
|
121
111
|
`;
|
|
122
112
|
};
|
|
@@ -4,24 +4,30 @@ type QueryOperations = {
|
|
|
4
4
|
selectHistory: string;
|
|
5
5
|
insertHistory: string;
|
|
6
6
|
};
|
|
7
|
-
type HandlerType = {
|
|
8
|
-
CountHistoryRow: string;
|
|
9
|
-
UserRow: string;
|
|
10
|
-
};
|
|
11
7
|
declare const driverConfigurations: {
|
|
12
8
|
readonly 'cockroachdb:sql:local': {
|
|
13
|
-
readonly dbType: "
|
|
14
|
-
readonly importLines: "import {
|
|
9
|
+
readonly dbType: "SQL";
|
|
10
|
+
readonly importLines: "import { SQL } from 'bun'";
|
|
11
|
+
readonly queries: QueryOperations;
|
|
12
|
+
};
|
|
13
|
+
readonly 'gel:drizzle:local': {
|
|
14
|
+
readonly dbType: "GelJsDatabase<SchemaType>";
|
|
15
|
+
readonly importLines: "\nimport { eq } from 'drizzle-orm'\nimport { GelJsDatabase } from 'drizzle-orm/gel'\nimport { schema, type SchemaType } from '../../../db/schema'\n";
|
|
15
16
|
readonly queries: QueryOperations;
|
|
16
17
|
};
|
|
17
18
|
readonly 'gel:sql:local': {
|
|
18
|
-
readonly dbType: "
|
|
19
|
-
readonly importLines: "import {
|
|
19
|
+
readonly dbType: "Client";
|
|
20
|
+
readonly importLines: "import { Client } from 'gel'";
|
|
21
|
+
readonly queries: QueryOperations;
|
|
22
|
+
};
|
|
23
|
+
readonly 'mariadb:drizzle:local': {
|
|
24
|
+
readonly dbType: "MySql2Database<SchemaType>";
|
|
25
|
+
readonly importLines: "\nimport { eq } from 'drizzle-orm'\nimport { MySql2Database } from 'drizzle-orm/mysql2'\nimport { schema, type SchemaType } from '../../../db/schema'";
|
|
20
26
|
readonly queries: QueryOperations;
|
|
21
27
|
};
|
|
22
28
|
readonly 'mariadb:sql:local': {
|
|
23
|
-
readonly dbType: "
|
|
24
|
-
readonly importLines: "import {
|
|
29
|
+
readonly dbType: "SQL";
|
|
30
|
+
readonly importLines: "import { SQL } from 'bun'";
|
|
25
31
|
readonly queries: QueryOperations;
|
|
26
32
|
};
|
|
27
33
|
readonly 'mongodb:native:local': {
|
|
@@ -39,14 +45,23 @@ declare const driverConfigurations: {
|
|
|
39
45
|
readonly importLines: "\nimport { eq } from 'drizzle-orm'\nimport { MySql2Database } from 'drizzle-orm/mysql2'\nimport { schema, type SchemaType } from '../../../db/schema'";
|
|
40
46
|
readonly queries: QueryOperations;
|
|
41
47
|
};
|
|
48
|
+
readonly 'mysql:drizzle:planetscale': {
|
|
49
|
+
readonly dbType: "PlanetScaleDatabase<SchemaType>";
|
|
50
|
+
readonly importLines: "\nimport { eq } from 'drizzle-orm'\nimport { PlanetScaleDatabase } from 'drizzle-orm/planetscale-serverless'\nimport { schema, type SchemaType } from '../../../db/schema'";
|
|
51
|
+
readonly queries: QueryOperations;
|
|
52
|
+
};
|
|
42
53
|
readonly 'mysql:sql:local': {
|
|
43
|
-
readonly dbType: "
|
|
44
|
-
readonly
|
|
45
|
-
readonly
|
|
54
|
+
readonly dbType: "SQL";
|
|
55
|
+
readonly importLines: "import { SQL } from 'bun'";
|
|
56
|
+
readonly queries: QueryOperations;
|
|
57
|
+
};
|
|
58
|
+
readonly 'mysql:sql:planetscale': {
|
|
59
|
+
readonly dbType: "Client";
|
|
60
|
+
readonly importLines: "import { Client } from '@planetscale/database'";
|
|
46
61
|
readonly queries: QueryOperations;
|
|
47
62
|
};
|
|
48
63
|
readonly 'postgresql:drizzle:local': {
|
|
49
|
-
readonly dbType: "
|
|
64
|
+
readonly dbType: "BunSQLDatabase<SchemaType>";
|
|
50
65
|
readonly importLines: "\nimport { eq } from 'drizzle-orm'\nimport { BunSQLDatabase } from 'drizzle-orm/bun-sql'\nimport { schema, type SchemaType } from '../../../db/schema'";
|
|
51
66
|
readonly queries: QueryOperations;
|
|
52
67
|
};
|
|
@@ -55,19 +70,34 @@ declare const driverConfigurations: {
|
|
|
55
70
|
readonly importLines: "\nimport { eq } from 'drizzle-orm'\nimport { NeonDatabase } from 'drizzle-orm/neon-serverless'\nimport { schema, type SchemaType } from '../../../db/schema'";
|
|
56
71
|
readonly queries: QueryOperations;
|
|
57
72
|
};
|
|
73
|
+
readonly 'postgresql:drizzle:planetscale': {
|
|
74
|
+
readonly dbType: "NodePgDatabase<SchemaType>";
|
|
75
|
+
readonly importLines: "\nimport { eq } from 'drizzle-orm'\nimport { NodePgDatabase } from 'drizzle-orm/node-postgres'\nimport { schema, type SchemaType } from '../../../db/schema'";
|
|
76
|
+
readonly queries: QueryOperations;
|
|
77
|
+
};
|
|
58
78
|
readonly 'postgresql:sql:local': {
|
|
59
79
|
readonly dbType: "SQL";
|
|
60
80
|
readonly importLines: "import { SQL } from 'bun'";
|
|
61
81
|
readonly queries: QueryOperations;
|
|
62
82
|
};
|
|
63
83
|
readonly 'postgresql:sql:neon': {
|
|
64
|
-
readonly dbType: "
|
|
65
|
-
readonly importLines: "import {
|
|
84
|
+
readonly dbType: "Pool";
|
|
85
|
+
readonly importLines: "import { Pool } from '@neondatabase/serverless'";
|
|
86
|
+
readonly queries: QueryOperations;
|
|
87
|
+
};
|
|
88
|
+
readonly 'postgresql:sql:planetscale': {
|
|
89
|
+
readonly dbType: "Pool";
|
|
90
|
+
readonly importLines: "import { Pool } from 'pg'";
|
|
66
91
|
readonly queries: QueryOperations;
|
|
67
92
|
};
|
|
68
93
|
readonly 'singlestore:sql:local': {
|
|
69
|
-
readonly dbType: "
|
|
70
|
-
readonly importLines: "import {
|
|
94
|
+
readonly dbType: "Pool";
|
|
95
|
+
readonly importLines: "import { Pool, RowDataPacket } from 'mysql2/promise'";
|
|
96
|
+
readonly queries: QueryOperations;
|
|
97
|
+
};
|
|
98
|
+
readonly 'singlestore:drizzle:local': {
|
|
99
|
+
readonly dbType: "SingleStoreDriverDatabase<SchemaType>";
|
|
100
|
+
readonly importLines: "\nimport { eq } from 'drizzle-orm'\nimport { SingleStoreDriverDatabase } from 'drizzle-orm/singlestore'\nimport { schema, type SchemaType } from '../../../db/schema'";
|
|
71
101
|
readonly queries: QueryOperations;
|
|
72
102
|
};
|
|
73
103
|
readonly 'sqlite:drizzle:local': {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
const buildSqlAuthTemplate = ({ importLines,
|
|
2
|
-
import { isValidProviderOption, providers } from 'citra'
|
|
1
|
+
const buildSqlAuthTemplate = ({ importLines, dbType, queries }) => `
|
|
2
|
+
import { isValidProviderOption, providers, extractPropFromIdentity } from 'citra'
|
|
3
3
|
${importLines}
|
|
4
|
-
${handlerTypes?.UserRow ? `\ntype UserRow = ${handlerTypes.UserRow}` : ''}
|
|
5
4
|
type UserHandlerProps = {
|
|
6
5
|
authProvider: string
|
|
7
6
|
db: ${dbType}
|
|
@@ -9,22 +8,31 @@ type UserHandlerProps = {
|
|
|
9
8
|
}
|
|
10
9
|
|
|
11
10
|
export const getUser = async ({ authProvider, db, userIdentity }: UserHandlerProps) => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
const providerConfiguration = providers[authProvider]
|
|
12
|
+
|
|
13
|
+
const subject = extractPropFromIdentity(
|
|
14
|
+
userIdentity,
|
|
15
|
+
providerConfiguration.subject,
|
|
16
|
+
providerConfiguration.subjectType
|
|
17
|
+
)
|
|
18
|
+
const authSub = \`\${authProvider.toUpperCase()}|\${subject}\`;
|
|
15
19
|
${queries.selectUser}
|
|
16
20
|
}
|
|
17
21
|
|
|
18
22
|
export const createUser = async ({ authProvider, db, userIdentity }: UserHandlerProps) => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
const providerConfiguration = providers[authProvider]
|
|
24
|
+
|
|
25
|
+
const subject = extractPropFromIdentity(
|
|
26
|
+
userIdentity,
|
|
27
|
+
providerConfiguration.subject,
|
|
28
|
+
providerConfiguration.subjectType
|
|
29
|
+
)
|
|
30
|
+
const authSub = \`\${authProvider.toUpperCase()}|\${subject}\`;
|
|
22
31
|
${queries.insertUser}
|
|
23
32
|
}
|
|
24
33
|
`;
|
|
25
|
-
const buildSqlCountTemplate = ({ importLines,
|
|
34
|
+
const buildSqlCountTemplate = ({ importLines, dbType, queries }) => `
|
|
26
35
|
${importLines}
|
|
27
|
-
${handlerTypes?.CountHistoryRow ? `\ntype CountHistoryRow = ${handlerTypes.CountHistoryRow}\n` : ''}
|
|
28
36
|
export const getCountHistory = async (db: ${dbType}, uid: number) => {
|
|
29
37
|
${queries.selectHistory}
|
|
30
38
|
}
|
|
@@ -73,6 +81,30 @@ const bunSqliteQueryOperations = {
|
|
|
73
81
|
const [user] = statement.all(authSub)
|
|
74
82
|
return user ?? null`
|
|
75
83
|
};
|
|
84
|
+
const postgresQueryOperations = {
|
|
85
|
+
insertHistory: `const { rows } = await db.query(
|
|
86
|
+
'INSERT INTO count_history (count) VALUES ($1) RETURNING *',
|
|
87
|
+
[count]
|
|
88
|
+
)
|
|
89
|
+
return rows[0]`,
|
|
90
|
+
insertUser: `const { rows } = await db.query(
|
|
91
|
+
'INSERT INTO users (auth_sub, metadata) VALUES ($1, $2) RETURNING *',
|
|
92
|
+
[authSub, userIdentity]
|
|
93
|
+
)
|
|
94
|
+
const newUser = rows[0]
|
|
95
|
+
if (!newUser) throw new Error('Failed to create user')
|
|
96
|
+
return newUser`,
|
|
97
|
+
selectHistory: `const { rows } = await db.query(
|
|
98
|
+
'SELECT * FROM count_history WHERE uid = $1 LIMIT 1',
|
|
99
|
+
[uid]
|
|
100
|
+
)
|
|
101
|
+
return rows[0] ?? null`,
|
|
102
|
+
selectUser: `const { rows } = await db.query(
|
|
103
|
+
'SELECT * FROM users WHERE auth_sub = $1 LIMIT 1',
|
|
104
|
+
[authSub]
|
|
105
|
+
)
|
|
106
|
+
return rows[0] ?? null`
|
|
107
|
+
};
|
|
76
108
|
const postgresSqlQueryOperations = {
|
|
77
109
|
insertHistory: `const [newHistory] = await db\`
|
|
78
110
|
INSERT INTO count_history (count)
|
|
@@ -113,58 +145,40 @@ const mongodbQueryOperations = {
|
|
|
113
145
|
selectUser: `const user = await db.collection('users').findOne({ auth_sub: authSub })
|
|
114
146
|
return user ?? null`
|
|
115
147
|
};
|
|
116
|
-
const
|
|
117
|
-
insertHistory: `await db.
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
return rows[0] ?? null`,
|
|
127
|
-
selectUser: `const [rows] = await db.query('SELECT * FROM users WHERE auth_sub = ? LIMIT 1', [authSub])
|
|
128
|
-
return rows[0] ?? null`
|
|
129
|
-
};
|
|
130
|
-
const gelSqlQueryOperations = {
|
|
131
|
-
insertHistory: `await db.query('INSERT INTO count_history (count) VALUES (?)', [count])
|
|
132
|
-
const [rows] = await db.query('SELECT * FROM count_history ORDER BY uid DESC LIMIT 1')
|
|
133
|
-
return rows[0]`,
|
|
134
|
-
insertUser: `await db.query('INSERT INTO users (auth_sub, metadata) VALUES (?, ?)', [authSub, JSON.stringify(userIdentity)])
|
|
135
|
-
const [rows] = await db.query('SELECT * FROM users WHERE auth_sub = ? LIMIT 1', [authSub])
|
|
136
|
-
const newUser = rows[0]
|
|
137
|
-
if (!newUser) throw new Error('Failed to create user')
|
|
148
|
+
const gelClientQueryOperations = {
|
|
149
|
+
insertHistory: `const newHistory = await db.queryRequiredSingle(
|
|
150
|
+
'select (insert count_history { count := <int16>$count }) { uid, count, created_at }',
|
|
151
|
+
{ count }
|
|
152
|
+
)
|
|
153
|
+
return newHistory`,
|
|
154
|
+
insertUser: `const newUser = await db.queryRequiredSingle(
|
|
155
|
+
'select (insert users { auth_sub := <str>$authSub, metadata := <json>$metadata }) { auth_sub, created_at, metadata }',
|
|
156
|
+
{ authSub, metadata: userIdentity }
|
|
157
|
+
)
|
|
138
158
|
return newUser`,
|
|
139
|
-
selectHistory: `const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
159
|
+
selectHistory: `const history = await db.querySingle(
|
|
160
|
+
'select count_history { uid, count, created_at } filter .uid = <int64>$uid',
|
|
161
|
+
{ uid }
|
|
162
|
+
)
|
|
163
|
+
return history ?? null`,
|
|
164
|
+
selectUser: `const user = await db.querySingle(
|
|
165
|
+
'select users { auth_sub, created_at, metadata } filter .auth_sub = <str>$authSub',
|
|
166
|
+
{ authSub }
|
|
167
|
+
)
|
|
168
|
+
return user ?? null`
|
|
143
169
|
};
|
|
144
170
|
const singlestoreSqlQueryOperations = {
|
|
145
171
|
insertHistory: `await db.query('INSERT INTO count_history (count) VALUES (?)', [count])
|
|
146
|
-
const [rows] = await db.query('SELECT * FROM count_history ORDER BY uid DESC LIMIT 1')
|
|
172
|
+
const [rows] = await db.query<RowDataPacket[]>('SELECT * FROM count_history ORDER BY uid DESC LIMIT 1')
|
|
147
173
|
return rows[0]`,
|
|
148
174
|
insertUser: `await db.query('INSERT INTO users (auth_sub, metadata) VALUES (?, ?)', [authSub, JSON.stringify(userIdentity)])
|
|
149
|
-
const [rows] = await db.query('SELECT * FROM users WHERE auth_sub = ? LIMIT 1', [authSub])
|
|
175
|
+
const [rows] = await db.query<RowDataPacket[]>('SELECT * FROM users WHERE auth_sub = ? LIMIT 1', [authSub])
|
|
150
176
|
const newUser = rows[0]
|
|
151
177
|
if (!newUser) throw new Error('Failed to create user')
|
|
152
178
|
return newUser`,
|
|
153
|
-
selectHistory: `const [rows] = await db.query('SELECT * FROM count_history WHERE uid = ? LIMIT 1', [uid])
|
|
179
|
+
selectHistory: `const [rows] = await db.query<RowDataPacket[]>('SELECT * FROM count_history WHERE uid = ? LIMIT 1', [uid])
|
|
154
180
|
return rows[0] ?? null`,
|
|
155
|
-
selectUser: `const [rows] = await db.query('SELECT * FROM users WHERE auth_sub = ? LIMIT 1', [authSub])
|
|
156
|
-
return rows[0] ?? null`
|
|
157
|
-
};
|
|
158
|
-
const cockroachdbPoolQueryOperations = {
|
|
159
|
-
insertHistory: `const { rows } = await db.query('INSERT INTO count_history (count) VALUES ($1) RETURNING *', [count])
|
|
160
|
-
return rows[0]`,
|
|
161
|
-
insertUser: `const { rows } = await db.query('INSERT INTO users (auth_sub, metadata) VALUES ($1, $2) RETURNING *', [authSub, userIdentity])
|
|
162
|
-
const newUser = rows[0]
|
|
163
|
-
if (!newUser) throw new Error('Failed to create user')
|
|
164
|
-
return newUser`,
|
|
165
|
-
selectHistory: `const { rows } = await db.query('SELECT * FROM count_history WHERE uid = $1 LIMIT 1', [uid])
|
|
166
|
-
return rows[0] ?? null`,
|
|
167
|
-
selectUser: `const { rows } = await db.query('SELECT * FROM users WHERE auth_sub = $1 LIMIT 1', [authSub])
|
|
181
|
+
selectUser: `const [rows] = await db.query<RowDataPacket[]>('SELECT * FROM users WHERE auth_sub = ? LIMIT 1', [authSub])
|
|
168
182
|
return rows[0] ?? null`
|
|
169
183
|
};
|
|
170
184
|
const mssqlSqlQueryOperations = {
|
|
@@ -183,58 +197,60 @@ const mssqlSqlQueryOperations = {
|
|
|
183
197
|
};
|
|
184
198
|
const mysqlSqlQueryOperations = {
|
|
185
199
|
insertHistory: `
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
200
|
+
const result = await db\`
|
|
201
|
+
INSERT INTO count_history (count)
|
|
202
|
+
VALUES (\${count})
|
|
203
|
+
\`;
|
|
204
|
+
|
|
205
|
+
const insertId = result.lastInsertRowid;
|
|
206
|
+
|
|
207
|
+
const [row] = await db\`
|
|
208
|
+
SELECT *
|
|
209
|
+
FROM count_history
|
|
210
|
+
WHERE uid = \${insertId}
|
|
211
|
+
LIMIT 1
|
|
212
|
+
\`;
|
|
213
|
+
|
|
214
|
+
if (!row) throw new Error("Could not retrieve the newly-inserted history");
|
|
215
|
+
return row;
|
|
197
216
|
`,
|
|
198
217
|
insertUser: `
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
const [
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
218
|
+
const result = await db\`
|
|
219
|
+
INSERT INTO users (auth_sub, metadata)
|
|
220
|
+
VALUES (\${authSub}, \${JSON.stringify(userIdentity)})
|
|
221
|
+
\`;
|
|
222
|
+
|
|
223
|
+
const [row] = await db\`
|
|
224
|
+
SELECT *
|
|
225
|
+
FROM users
|
|
226
|
+
WHERE auth_sub = \${authSub}
|
|
227
|
+
LIMIT 1
|
|
228
|
+
\`;
|
|
229
|
+
|
|
230
|
+
if (!row) throw new Error("Failed to create user");
|
|
231
|
+
return row;
|
|
210
232
|
`,
|
|
211
233
|
selectHistory: `
|
|
212
|
-
const [
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
234
|
+
const [row] = await db\`
|
|
235
|
+
SELECT *
|
|
236
|
+
FROM count_history
|
|
237
|
+
WHERE uid = \${uid}
|
|
238
|
+
LIMIT 1
|
|
239
|
+
\`;
|
|
240
|
+
|
|
241
|
+
return row ?? null;
|
|
217
242
|
`,
|
|
218
243
|
selectUser: `
|
|
219
|
-
const [
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
244
|
+
const [row] = await db\`
|
|
245
|
+
SELECT *
|
|
246
|
+
FROM users
|
|
247
|
+
WHERE auth_sub = \${authSub}
|
|
248
|
+
LIMIT 1
|
|
249
|
+
\`;
|
|
250
|
+
|
|
251
|
+
return row ?? null;
|
|
224
252
|
`
|
|
225
253
|
};
|
|
226
|
-
const mysqlHandlerTypes = {
|
|
227
|
-
CountHistoryRow: `RowDataPacket & {
|
|
228
|
-
uid: number;
|
|
229
|
-
count: number;
|
|
230
|
-
created_at: number;
|
|
231
|
-
}`,
|
|
232
|
-
UserRow: `RowDataPacket & {
|
|
233
|
-
uid: number;
|
|
234
|
-
auth_sub: string;
|
|
235
|
-
metadata: string;
|
|
236
|
-
}`
|
|
237
|
-
};
|
|
238
254
|
const mysqlDrizzleQueryOperations = {
|
|
239
255
|
insertHistory: `const [row] = await db
|
|
240
256
|
.insert(schema.countHistory)
|
|
@@ -252,37 +268,103 @@ const mysqlDrizzleQueryOperations = {
|
|
|
252
268
|
return newHistory;`,
|
|
253
269
|
insertUser: `const [row] = await db
|
|
254
270
|
.insert(schema.users)
|
|
255
|
-
.values({ auth_sub: authSub, metadata: userIdentity })
|
|
256
|
-
.$returningId();
|
|
257
|
-
|
|
258
|
-
if (!row) throw new Error('insert failed: no uid returned');
|
|
259
|
-
const { uid } = row;
|
|
271
|
+
.values({ auth_sub: authSub, metadata: userIdentity });
|
|
260
272
|
|
|
261
273
|
const [newUser] = await db
|
|
262
274
|
.select()
|
|
263
275
|
.from(schema.users)
|
|
264
|
-
.where(eq(schema.users.
|
|
276
|
+
.where(eq(schema.users.auth_sub, authSub));
|
|
265
277
|
|
|
266
278
|
if (!newUser) throw new Error('Failed to create user');
|
|
267
279
|
return newUser;`,
|
|
268
280
|
selectHistory: drizzleQueryOperations.selectHistory,
|
|
269
281
|
selectUser: drizzleQueryOperations.selectUser
|
|
270
282
|
};
|
|
283
|
+
const mysqlPlanetScaleQueryOperations = {
|
|
284
|
+
insertHistory: `
|
|
285
|
+
const result = await db.execute(
|
|
286
|
+
\`INSERT INTO count_history (count) VALUES (?)\`,
|
|
287
|
+
[count]
|
|
288
|
+
);
|
|
289
|
+
|
|
290
|
+
const insertId = result.insertId;
|
|
291
|
+
if (!insertId) throw new Error("Could not insert count history");
|
|
292
|
+
|
|
293
|
+
const { rows } = await db.execute(
|
|
294
|
+
\`SELECT * FROM count_history WHERE uid = ? LIMIT 1\`,
|
|
295
|
+
[insertId]
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
const row = rows[0] ?? null;
|
|
299
|
+
if (!row) throw new Error("Could not retrieve the newly-inserted history");
|
|
300
|
+
|
|
301
|
+
return row;
|
|
302
|
+
`,
|
|
303
|
+
insertUser: `
|
|
304
|
+
const result = await db.execute(
|
|
305
|
+
\`INSERT INTO users (auth_sub, metadata) VALUES (?, ?)\`,
|
|
306
|
+
[authSub, JSON.stringify(userIdentity)]
|
|
307
|
+
);
|
|
308
|
+
|
|
309
|
+
const { rows } = await db.execute(
|
|
310
|
+
\`SELECT * FROM users WHERE auth_sub = ? LIMIT 1\`,
|
|
311
|
+
[authSub]
|
|
312
|
+
);
|
|
313
|
+
|
|
314
|
+
const row = rows[0] ?? null;
|
|
315
|
+
if (!row) throw new Error("Failed to create user");
|
|
316
|
+
|
|
317
|
+
return row;
|
|
318
|
+
`,
|
|
319
|
+
selectHistory: `
|
|
320
|
+
const { rows } = await db.execute(
|
|
321
|
+
\`SELECT * FROM count_history WHERE uid = ? LIMIT 1\`,
|
|
322
|
+
[uid]
|
|
323
|
+
);
|
|
324
|
+
|
|
325
|
+
return rows[0] ?? null;
|
|
326
|
+
`,
|
|
327
|
+
selectUser: `
|
|
328
|
+
const { rows } = await db.execute(
|
|
329
|
+
\`SELECT * FROM users WHERE auth_sub = ? LIMIT 1\`,
|
|
330
|
+
[authSub]
|
|
331
|
+
);
|
|
332
|
+
|
|
333
|
+
return rows[0] ?? null;
|
|
334
|
+
`
|
|
335
|
+
};
|
|
271
336
|
const driverConfigurations = {
|
|
272
337
|
'cockroachdb:sql:local': {
|
|
273
|
-
dbType: '
|
|
274
|
-
importLines: `import {
|
|
275
|
-
queries:
|
|
338
|
+
dbType: 'SQL',
|
|
339
|
+
importLines: `import { SQL } from 'bun'`,
|
|
340
|
+
queries: postgresSqlQueryOperations
|
|
341
|
+
},
|
|
342
|
+
'gel:drizzle:local': {
|
|
343
|
+
dbType: 'GelJsDatabase<SchemaType>',
|
|
344
|
+
importLines: `
|
|
345
|
+
import { eq } from 'drizzle-orm'
|
|
346
|
+
import { GelJsDatabase } from 'drizzle-orm/gel'
|
|
347
|
+
import { schema, type SchemaType } from '../../../db/schema'
|
|
348
|
+
`,
|
|
349
|
+
queries: drizzleQueryOperations
|
|
276
350
|
},
|
|
277
351
|
'gel:sql:local': {
|
|
278
|
-
dbType: '
|
|
279
|
-
importLines: `import {
|
|
280
|
-
queries:
|
|
352
|
+
dbType: 'Client',
|
|
353
|
+
importLines: `import { Client } from 'gel'`,
|
|
354
|
+
queries: gelClientQueryOperations
|
|
355
|
+
},
|
|
356
|
+
'mariadb:drizzle:local': {
|
|
357
|
+
dbType: 'MySql2Database<SchemaType>',
|
|
358
|
+
importLines: `
|
|
359
|
+
import { eq } from 'drizzle-orm'
|
|
360
|
+
import { MySql2Database } from 'drizzle-orm/mysql2'
|
|
361
|
+
import { schema, type SchemaType } from '../../../db/schema'`,
|
|
362
|
+
queries: mysqlDrizzleQueryOperations
|
|
281
363
|
},
|
|
282
364
|
'mariadb:sql:local': {
|
|
283
|
-
dbType: '
|
|
284
|
-
importLines: `import {
|
|
285
|
-
queries:
|
|
365
|
+
dbType: 'SQL',
|
|
366
|
+
importLines: `import { SQL } from 'bun'`,
|
|
367
|
+
queries: mysqlSqlQueryOperations
|
|
286
368
|
},
|
|
287
369
|
'mongodb:native:local': {
|
|
288
370
|
dbType: 'Db',
|
|
@@ -299,17 +381,29 @@ const driverConfigurations = {
|
|
|
299
381
|
importLines: `
|
|
300
382
|
import { eq } from 'drizzle-orm'
|
|
301
383
|
import { MySql2Database } from 'drizzle-orm/mysql2'
|
|
384
|
+
import { schema, type SchemaType } from '../../../db/schema'`,
|
|
385
|
+
queries: mysqlDrizzleQueryOperations
|
|
386
|
+
},
|
|
387
|
+
'mysql:drizzle:planetscale': {
|
|
388
|
+
dbType: 'PlanetScaleDatabase<SchemaType>',
|
|
389
|
+
importLines: `
|
|
390
|
+
import { eq } from 'drizzle-orm'
|
|
391
|
+
import { PlanetScaleDatabase } from 'drizzle-orm/planetscale-serverless'
|
|
302
392
|
import { schema, type SchemaType } from '../../../db/schema'`,
|
|
303
393
|
queries: mysqlDrizzleQueryOperations
|
|
304
394
|
},
|
|
305
395
|
'mysql:sql:local': {
|
|
306
|
-
dbType: '
|
|
307
|
-
|
|
308
|
-
importLines: `import { Pool, ResultSetHeader, RowDataPacket } from 'mysql2/promise'`,
|
|
396
|
+
dbType: 'SQL',
|
|
397
|
+
importLines: `import { SQL } from 'bun'`,
|
|
309
398
|
queries: mysqlSqlQueryOperations
|
|
310
399
|
},
|
|
400
|
+
'mysql:sql:planetscale': {
|
|
401
|
+
dbType: 'Client',
|
|
402
|
+
importLines: `import { Client } from '@planetscale/database'`,
|
|
403
|
+
queries: mysqlPlanetScaleQueryOperations
|
|
404
|
+
},
|
|
311
405
|
'postgresql:drizzle:local': {
|
|
312
|
-
dbType: '
|
|
406
|
+
dbType: 'BunSQLDatabase<SchemaType>',
|
|
313
407
|
importLines: `
|
|
314
408
|
import { eq } from 'drizzle-orm'
|
|
315
409
|
import { BunSQLDatabase } from 'drizzle-orm/bun-sql'
|
|
@@ -321,6 +415,14 @@ import { schema, type SchemaType } from '../../../db/schema'`,
|
|
|
321
415
|
importLines: `
|
|
322
416
|
import { eq } from 'drizzle-orm'
|
|
323
417
|
import { NeonDatabase } from 'drizzle-orm/neon-serverless'
|
|
418
|
+
import { schema, type SchemaType } from '../../../db/schema'`,
|
|
419
|
+
queries: drizzleQueryOperations
|
|
420
|
+
},
|
|
421
|
+
'postgresql:drizzle:planetscale': {
|
|
422
|
+
dbType: 'NodePgDatabase<SchemaType>',
|
|
423
|
+
importLines: `
|
|
424
|
+
import { eq } from 'drizzle-orm'
|
|
425
|
+
import { NodePgDatabase } from 'drizzle-orm/node-postgres'
|
|
324
426
|
import { schema, type SchemaType } from '../../../db/schema'`,
|
|
325
427
|
queries: drizzleQueryOperations
|
|
326
428
|
},
|
|
@@ -330,15 +432,28 @@ import { schema, type SchemaType } from '../../../db/schema'`,
|
|
|
330
432
|
queries: postgresSqlQueryOperations
|
|
331
433
|
},
|
|
332
434
|
'postgresql:sql:neon': {
|
|
333
|
-
dbType: '
|
|
334
|
-
importLines: `import {
|
|
335
|
-
queries:
|
|
435
|
+
dbType: 'Pool',
|
|
436
|
+
importLines: `import { Pool } from '@neondatabase/serverless'`,
|
|
437
|
+
queries: postgresQueryOperations
|
|
438
|
+
},
|
|
439
|
+
'postgresql:sql:planetscale': {
|
|
440
|
+
dbType: 'Pool',
|
|
441
|
+
importLines: `import { Pool } from 'pg'`,
|
|
442
|
+
queries: postgresQueryOperations
|
|
336
443
|
},
|
|
337
444
|
'singlestore:sql:local': {
|
|
338
|
-
dbType: '
|
|
339
|
-
importLines: `import {
|
|
445
|
+
dbType: 'Pool',
|
|
446
|
+
importLines: `import { Pool, RowDataPacket } from 'mysql2/promise'`,
|
|
340
447
|
queries: singlestoreSqlQueryOperations
|
|
341
448
|
},
|
|
449
|
+
'singlestore:drizzle:local': {
|
|
450
|
+
dbType: 'SingleStoreDriverDatabase<SchemaType>',
|
|
451
|
+
importLines: `
|
|
452
|
+
import { eq } from 'drizzle-orm'
|
|
453
|
+
import { SingleStoreDriverDatabase } from 'drizzle-orm/singlestore'
|
|
454
|
+
import { schema, type SchemaType } from '../../../db/schema'`,
|
|
455
|
+
queries: mysqlDrizzleQueryOperations
|
|
456
|
+
},
|
|
342
457
|
'sqlite:drizzle:local': {
|
|
343
458
|
dbType: 'BunSQLiteDatabase<SchemaType>',
|
|
344
459
|
importLines: `
|
|
@@ -2,6 +2,7 @@ import type { CreateConfiguration } from '../../types';
|
|
|
2
2
|
type ScaffoldDatabaseProps = Pick<CreateConfiguration, 'projectName' | 'databaseHost' | 'orm' | 'databaseDirectory' | 'authProvider' | 'databaseEngine'> & {
|
|
3
3
|
databaseDirectory: string;
|
|
4
4
|
backendDirectory: string;
|
|
5
|
+
typesDirectory: string;
|
|
5
6
|
};
|
|
6
|
-
export declare const scaffoldDatabase: ({ projectName, databaseEngine, databaseHost, databaseDirectory, backendDirectory, authProvider, orm }: ScaffoldDatabaseProps) => Promise<void>;
|
|
7
|
+
export declare const scaffoldDatabase: ({ projectName, databaseEngine, databaseHost, databaseDirectory, backendDirectory, authProvider, orm, typesDirectory }: ScaffoldDatabaseProps) => Promise<void>;
|
|
7
8
|
export {};
|