From 1c45e893ede0b7b9565318d3f007b79a40a12c0d Mon Sep 17 00:00:00 2001 From: Jeusel Guillaume Date: Tue, 13 Feb 2024 19:35:19 +0100 Subject: [PATCH 1/5] feat: add edgedb watch mode https://www.edgedb.com/docs/guides/migrations/guide#edgedb-watch --- src/module.ts | 103 +++++++++++++++++++++++++++++++------------------- 1 file changed, 65 insertions(+), 38 deletions(-) diff --git a/src/module.ts b/src/module.ts index f48baad..7e746fb 100644 --- a/src/module.ts +++ b/src/module.ts @@ -17,6 +17,7 @@ export interface ModuleOptions { devtools: boolean watch: boolean watchPrompt: true + dbWatchMode: boolean dbschemaDir: string queriesDir: string queryBuilderDir: string @@ -54,6 +55,7 @@ export default defineNuxtModule({ devtools: true, watch: true, watchPrompt: true, + dbWatchMode: false, generateTarget: 'ts', dbschemaDir: 'dbschema', queriesDir: 'queries', @@ -302,52 +304,77 @@ export default defineNuxtModule({ * Watchers */ - if (canPrompt && options.watch) { + async function maybeTriggerGenerateQueries(path: string) { + if (path.includes(options.queriesDir) && path.endsWith('.edgeql')) { + success(`Queries changes detected on: ${edgeColor(path.replace(options.dbschemaDir, ''))}`) + try { + if (options.watchPrompt) { + if (activePrompts.queriesPrompt) + return + + activePrompts.queriesPrompt = prompts( + { + type: 'confirm', + name: 'value', + message: 'Do you want to generate queries files?', + }, + { + onSubmit() { + activePrompts.queriesPrompt = undefined + }, + onCancel() { + activePrompts.queriesPrompt = undefined + }, + }, + ) + const response = await activePrompts.queriesPrompt + if (response?.value === true) { + await generateQueries() + success('Successfully generated queries!') + } + } + else { + await generateQueries() + success('Successfully generated queries!') + } + } + catch (e) { + // + } + return + } + + } + + if (options.dbWatchMode) { + await piped$(`edgedb`, ['watch'], true) nuxt.options.watch.push(`${dbschemaDir}/*`) - nuxt.options.watch.push(`${dbschemaDir}/migrations/*`) nuxt.options.watch.push(`${queriesDir}/*`) nuxt.hook('builder:watch', async (event, path) => { if (event === 'add' || event === 'change' || event === 'unlink' || event === 'unlinkDir') { // Queries - if (path.includes(options.queriesDir) && path.endsWith('.edgeql')) { - success(`Queries changes detected on: ${edgeColor(path.replace(options.dbschemaDir, ''))}`) - try { - if (options.watchPrompt) { - if (activePrompts.queriesPrompt) - return + await maybeTriggerGenerateQueries(path) - activePrompts.queriesPrompt = prompts( - { - type: 'confirm', - name: 'value', - message: 'Do you want to generate queries files?', - }, - { - onSubmit() { - activePrompts.queriesPrompt = undefined - }, - onCancel() { - activePrompts.queriesPrompt = undefined - }, - }, - ) - const response = await activePrompts.queriesPrompt - if (response?.value === true) { - await generateQueries() - success('Successfully generated queries!') - } - } - else { - await generateQueries() - success('Successfully generated queries!') - } - } - catch (e) { - // - } - return + // Query Builder & Interface + if (path.includes(options.dbschemaDir) && path.endsWith('.esdl')) { + success(`Schema changes detected on: ${edgeColor(path.replace(options.dbschemaDir, ''))}`) + await generateInterfaces() + await generateQueryBuilder() } + } + + }) + } + else if (canPrompt && options.watch) { + nuxt.options.watch.push(`${dbschemaDir}/*`) + nuxt.options.watch.push(`${dbschemaDir}/migrations/*`) + nuxt.options.watch.push(`${queriesDir}/*`) + + nuxt.hook('builder:watch', async (event, path) => { + if (event === 'add' || event === 'change' || event === 'unlink' || event === 'unlinkDir') { + // Queries + await maybeTriggerGenerateQueries(path) // Migrations if (path.includes(`${options.dbschemaDir}/migrations`) && path.endsWith('.edgeql')) { From b7159cc87da4febf4171d75c9c0555eeec51d987 Mon Sep 17 00:00:00 2001 From: Jeusel Guillaume Date: Wed, 14 Feb 2024 09:03:47 +0100 Subject: [PATCH 2/5] fix(subprocess): run it detached --- src/module.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/module.ts b/src/module.ts index 7e746fb..752971b 100644 --- a/src/module.ts +++ b/src/module.ts @@ -347,7 +347,10 @@ export default defineNuxtModule({ } if (options.dbWatchMode) { - await piped$(`edgedb`, ['watch'], true) + const edb_watch_process = execa.execa('edgedb', ['watch'], { cwd: resolveProject(), detached: true, stdio: 'ignore' }) + edb_watch_process.unref() + + success("Running 'edgedb watch' mode in the background.", true) nuxt.options.watch.push(`${dbschemaDir}/*`) nuxt.options.watch.push(`${queriesDir}/*`) From ab1dd79d97ab9d567116f4e0ade03da19b5bde3d Mon Sep 17 00:00:00 2001 From: Jeusel Guillaume Date: Wed, 14 Feb 2024 15:52:26 +0100 Subject: [PATCH 3/5] fix(dbwatcher): base update on DDLs --- src/module.ts | 112 +++++++++++++++++++++++--------------------------- 1 file changed, 52 insertions(+), 60 deletions(-) diff --git a/src/module.ts b/src/module.ts index 752971b..a95fbd6 100644 --- a/src/module.ts +++ b/src/module.ts @@ -304,70 +304,25 @@ export default defineNuxtModule({ * Watchers */ - async function maybeTriggerGenerateQueries(path: string) { - if (path.includes(options.queriesDir) && path.endsWith('.edgeql')) { - success(`Queries changes detected on: ${edgeColor(path.replace(options.dbschemaDir, ''))}`) - try { - if (options.watchPrompt) { - if (activePrompts.queriesPrompt) - return - - activePrompts.queriesPrompt = prompts( - { - type: 'confirm', - name: 'value', - message: 'Do you want to generate queries files?', - }, - { - onSubmit() { - activePrompts.queriesPrompt = undefined - }, - onCancel() { - activePrompts.queriesPrompt = undefined - }, - }, - ) - const response = await activePrompts.queriesPrompt - if (response?.value === true) { - await generateQueries() - success('Successfully generated queries!') - } - } - else { - await generateQueries() - success('Successfully generated queries!') - } - } - catch (e) { - // - } - return - } - - } - if (options.dbWatchMode) { - const edb_watch_process = execa.execa('edgedb', ['watch'], { cwd: resolveProject(), detached: true, stdio: 'ignore' }) - edb_watch_process.unref() - - success("Running 'edgedb watch' mode in the background.", true) - nuxt.options.watch.push(`${dbschemaDir}/*`) - nuxt.options.watch.push(`${queriesDir}/*`) + const edb_watch_process = execa.execa('edgedb', ['watch', '--verbose'], { cwd: resolveProject(), buffer: false }) - nuxt.hook('builder:watch', async (event, path) => { - if (event === 'add' || event === 'change' || event === 'unlink' || event === 'unlinkDir') { - // Queries - await maybeTriggerGenerateQueries(path) + const extractDDLs = (input: string) => { + const pattern = /(?:ALTER|CREATE|DROP)([\s\S]+?(};))/g + const matches = input.match(pattern) + return matches || [] + } - // Query Builder & Interface - if (path.includes(options.dbschemaDir) && path.endsWith('.esdl')) { - success(`Schema changes detected on: ${edgeColor(path.replace(options.dbschemaDir, ''))}`) - await generateInterfaces() - await generateQueryBuilder() - } + edb_watch_process.stderr!.on('data', async (chunk: string) => { + const content = chunk.toString() + const ddls = extractDDLs(content) + if (ddls.length) { + await generateInterfaces() + await generateQueryBuilder() + success(`Schema changes detected - interface & query builder updated`) } - }) + success('Running \'edgedb watch\' mode in the background.', true) } else if (canPrompt && options.watch) { nuxt.options.watch.push(`${dbschemaDir}/*`) @@ -377,7 +332,44 @@ export default defineNuxtModule({ nuxt.hook('builder:watch', async (event, path) => { if (event === 'add' || event === 'change' || event === 'unlink' || event === 'unlinkDir') { // Queries - await maybeTriggerGenerateQueries(path) + if (path.includes(options.queriesDir) && path.endsWith('.edgeql')) { + success(`Queries changes detected on: ${edgeColor(path.replace(options.dbschemaDir, ''))}`) + try { + if (options.watchPrompt) { + if (activePrompts.queriesPrompt) + return + + activePrompts.queriesPrompt = prompts( + { + type: 'confirm', + name: 'value', + message: 'Do you want to generate queries files?', + }, + { + onSubmit() { + activePrompts.queriesPrompt = undefined + }, + onCancel() { + activePrompts.queriesPrompt = undefined + }, + }, + ) + const response = await activePrompts.queriesPrompt + if (response?.value === true) { + await generateQueries() + success('Successfully generated queries!') + } + } + else { + await generateQueries() + success('Successfully generated queries!') + } + } + catch (e) { + // + } + return + } // Migrations if (path.includes(`${options.dbschemaDir}/migrations`) && path.endsWith('.edgeql')) { From 3f8559d5078b103a1d5b042bbccfcd7656d741a8 Mon Sep 17 00:00:00 2001 From: Jeusel Guillaume Date: Thu, 15 Feb 2024 10:40:02 +0100 Subject: [PATCH 4/5] fix: don't run in prepare mode --- src/module.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/module.ts b/src/module.ts index a95fbd6..f0c185b 100644 --- a/src/module.ts +++ b/src/module.ts @@ -304,7 +304,7 @@ export default defineNuxtModule({ * Watchers */ - if (options.dbWatchMode) { + if (options.dbWatchMode && !nuxt.options._prepare) { const edb_watch_process = execa.execa('edgedb', ['watch', '--verbose'], { cwd: resolveProject(), buffer: false }) const extractDDLs = (input: string) => { From 0b0216a783a09c7061af192d67b21c43b7e49f4f Mon Sep 17 00:00:00 2001 From: Jeusel Guillaume Date: Thu, 15 Feb 2024 10:40:38 +0100 Subject: [PATCH 5/5] imp: logging from edgedb watch should be forwared So the user knowns when the schema is failing to compile --- src/module.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/module.ts b/src/module.ts index f0c185b..0b38f42 100644 --- a/src/module.ts +++ b/src/module.ts @@ -312,6 +312,10 @@ export default defineNuxtModule({ const matches = input.match(pattern) return matches || [] } + const excluded_logs = [ + 'EdgeDB Watch initialized.', + `Monitoring "${resolveProject()}".`, + ] edb_watch_process.stderr!.on('data', async (chunk: string) => { const content = chunk.toString() @@ -319,7 +323,10 @@ export default defineNuxtModule({ if (ddls.length) { await generateInterfaces() await generateQueryBuilder() - success(`Schema changes detected - interface & query builder updated`) + success(`EdgeDB - schema changes detected`) + } + else if (!excluded_logs.some(e => content.includes(e))) { + console.log(content) } }) success('Running \'edgedb watch\' mode in the background.', true)