|
1 |
| -import fs from 'fs' |
2 |
| -import path from 'path' |
3 | 1 | import { OptionValues } from 'commander'
|
4 |
| -import BaseCommand from '../base-command.js' |
5 |
| - |
6 |
| -import openBrowser from '../../utils/open-browser.js' |
7 |
| -import { carefullyWriteFile, getExtension, getExtensionInstallations, installExtension } from './utils.js' |
8 |
| -import { getToken } from '../../utils/command-helpers.js' |
9 | 2 | import inquirer from 'inquirer'
|
10 |
| -import { NetlifyAPI } from 'netlify' |
11 |
| -import { spawn } from 'child_process' |
| 3 | +import BaseCommand from '../base-command.js' |
| 4 | +import { getExtension, getExtensionInstallations, installExtension } from './utils.js' |
| 5 | +import { initDrizzle } from './drizzle.js' |
12 | 6 |
|
13 | 7 | const NETLIFY_DATABASE_EXTENSION_SLUG = '-94w9m6w-netlify-database-extension'
|
14 | 8 |
|
@@ -36,37 +30,8 @@ const init = async (_options: OptionValues, command: BaseCommand) => {
|
36 | 30 | command.setOptionValue('drizzle', answers.drizzle)
|
37 | 31 | }
|
38 | 32 | const opts = command.opts()
|
39 |
| - |
40 | 33 | if (opts.drizzle && command.project.root) {
|
41 |
| - const drizzleConfigFilePath = path.resolve(command.project.root, 'drizzle.config.ts') |
42 |
| - await carefullyWriteFile(drizzleConfigFilePath, drizzleConfig) |
43 |
| - |
44 |
| - fs.mkdirSync(path.resolve(command.project.root, 'db'), { recursive: true }) |
45 |
| - const schemaFilePath = path.resolve(command.project.root, 'db/schema.ts') |
46 |
| - await carefullyWriteFile(schemaFilePath, exampleDrizzleSchema) |
47 |
| - |
48 |
| - const dbIndexFilePath = path.resolve(command.project.root, 'db/index.ts') |
49 |
| - await carefullyWriteFile(dbIndexFilePath, exampleDbIndex) |
50 |
| - |
51 |
| - console.log('Adding drizzle-kit and drizzle-orm to the project') |
52 |
| - // install dev deps |
53 |
| - const devDepProc = spawn( |
54 |
| - command.project.packageManager?.installCommand ?? 'npm install', |
55 |
| - ['drizzle-kit@latest', '-D'], |
56 |
| - { |
57 |
| - stdio: 'inherit', |
58 |
| - shell: true, |
59 |
| - }, |
60 |
| - ) |
61 |
| - devDepProc.on('exit', (code) => { |
62 |
| - if (code === 0) { |
63 |
| - // install deps |
64 |
| - spawn(command.project.packageManager?.installCommand ?? 'npm install', ['drizzle-orm@latest'], { |
65 |
| - stdio: 'inherit', |
66 |
| - shell: true, |
67 |
| - }) |
68 |
| - } |
69 |
| - }) |
| 34 | + await initDrizzle(command) |
70 | 35 | }
|
71 | 36 |
|
72 | 37 | if (!command.netlify.api.accessToken) {
|
@@ -131,7 +96,8 @@ const init = async (_options: OptionValues, command: BaseCommand) => {
|
131 | 96 | })
|
132 | 97 |
|
133 | 98 | if (siteEnv.key === 'NETLIFY_DATABASE_URL') {
|
134 |
| - throw new Error(`Database already initialized for site: ${command.siteId}`) |
| 99 | + console.error(`Database already initialized for site: ${command.siteId}`) |
| 100 | + return |
135 | 101 | }
|
136 | 102 | } catch {
|
137 | 103 | // no op, env var does not exist, so we just continue
|
@@ -168,109 +134,5 @@ export const createDatabaseCommand = (program: BaseCommand) => {
|
168 | 134 | .option('--drizzle', 'Sets up drizzle-kit and drizzle-orm in your project')
|
169 | 135 | .action(init)
|
170 | 136 |
|
171 |
| - dbCommand |
172 |
| - .command('drizzle-kit', 'TODO: write description for drizzle-kit command', { |
173 |
| - executableFile: path.resolve(program.workingDir, './node_modules/drizzle-kit/bin.cjs'), |
174 |
| - }) |
175 |
| - .option('--open', 'when running drizzle-kit studio, open the browser to the studio url') |
176 |
| - .hook('preSubcommand', async (thisCommand, actionCommand) => { |
177 |
| - if (actionCommand.name() === 'drizzle-kit') { |
178 |
| - // @ts-expect-error thisCommand is not assignable to BaseCommand |
179 |
| - await drizzleKitPreAction(thisCommand) // set the NETLIFY_DATABASE_URL env var before drizzle-kit runs |
180 |
| - } |
181 |
| - }) |
182 |
| - .allowUnknownOption() // allow unknown options to be passed through to drizzle-kit executable |
183 |
| - |
184 | 137 | return dbCommand
|
185 | 138 | }
|
186 |
| - |
187 |
| -const drizzleKitPreAction = async (thisCommand: BaseCommand) => { |
188 |
| - const opts = thisCommand.opts() |
189 |
| - const workingDir = thisCommand.workingDir |
190 |
| - const drizzleKitBinPath = path.resolve(workingDir, './node_modules/drizzle-kit/bin.cjs') |
191 |
| - try { |
192 |
| - fs.statSync(drizzleKitBinPath) |
193 |
| - } catch { |
194 |
| - console.error(`drizzle-kit not found in project's node modules, make sure you have installed drizzle-kit.`) |
195 |
| - return |
196 |
| - } |
197 |
| - |
198 |
| - const rawState = fs.readFileSync(path.resolve(workingDir, '.netlify/state.json'), 'utf8') |
199 |
| - const state = JSON.parse(rawState) as { siteId?: string } | undefined |
200 |
| - if (!state?.siteId) { |
201 |
| - throw new Error(`No site id found in .netlify/state.json`) |
202 |
| - } |
203 |
| - |
204 |
| - const [token] = await getToken() |
205 |
| - if (!token) { |
206 |
| - throw new Error(`No token found, please login with netlify login`) |
207 |
| - } |
208 |
| - const client = new NetlifyAPI(token) |
209 |
| - let site |
210 |
| - try { |
211 |
| - site = await client.getSite({ siteId: state.siteId }) |
212 |
| - } catch { |
213 |
| - throw new Error(`No site found for site id ${state.siteId}`) |
214 |
| - } |
215 |
| - const accountId = site.account_id |
216 |
| - if (!accountId) { |
217 |
| - throw new Error(`No account id found for site ${state.siteId}`) |
218 |
| - } |
219 |
| - |
220 |
| - let netlifyDatabaseEnv |
221 |
| - try { |
222 |
| - netlifyDatabaseEnv = await client.getEnvVar({ |
223 |
| - siteId: state.siteId, |
224 |
| - accountId, |
225 |
| - key: 'NETLIFY_DATABASE_URL', |
226 |
| - }) |
227 |
| - } catch { |
228 |
| - throw new Error( |
229 |
| - `NETLIFY_DATABASE_URL environment variable not found on site ${state.siteId}. Run \`netlify db init\` first.`, |
230 |
| - ) |
231 |
| - } |
232 |
| - |
233 |
| - const NETLIFY_DATABASE_URL = netlifyDatabaseEnv.values?.find( |
234 |
| - (val) => val.context === 'all' || val.context === 'dev', |
235 |
| - )?.value |
236 |
| - |
237 |
| - if (!NETLIFY_DATABASE_URL) { |
238 |
| - console.error(`NETLIFY_DATABASE_URL environment variable not found in project settings.`) |
239 |
| - return |
240 |
| - } |
241 |
| - |
242 |
| - if (typeof NETLIFY_DATABASE_URL === 'string') { |
243 |
| - process.env.NETLIFY_DATABASE_URL = NETLIFY_DATABASE_URL |
244 |
| - if (opts.open) { |
245 |
| - await openBrowser({ url: 'https://local.drizzle.studio/', silentBrowserNoneError: true }) |
246 |
| - } |
247 |
| - } |
248 |
| -} |
249 |
| - |
250 |
| -const drizzleConfig = `import { defineConfig } from 'drizzle-kit'; |
251 |
| -
|
252 |
| -export default defineConfig({ |
253 |
| - dialect: 'postgresql', |
254 |
| - dbCredentials: { |
255 |
| - url: process.env.NETLIFY_DATABASE_URL! |
256 |
| - }, |
257 |
| - schema: './db/schema.ts' |
258 |
| -});` |
259 |
| - |
260 |
| -const exampleDrizzleSchema = `import { integer, pgTable, varchar, text } from 'drizzle-orm/pg-core'; |
261 |
| -
|
262 |
| -export const post = pgTable('post', { |
263 |
| - id: integer().primaryKey().generatedAlwaysAsIdentity(), |
264 |
| - title: varchar({ length: 255 }).notNull(), |
265 |
| - content: text().notNull().default('') |
266 |
| -}); |
267 |
| -` |
268 |
| - |
269 |
| -const exampleDbIndex = `import { drizzle } from 'lib/db'; |
270 |
| -// import { drizzle } from '@netlify/database' |
271 |
| -import * as schema from 'db/schema'; |
272 |
| -
|
273 |
| -export const db = drizzle({ |
274 |
| - schema |
275 |
| -}); |
276 |
| -` |
0 commit comments