pgflow 0.1.17 → 0.1.19
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/commands/install/copy-migrations.d.ts +2 -1
- package/dist/commands/install/copy-migrations.d.ts.map +1 -1
- package/dist/commands/install/copy-migrations.js +14 -6
- package/dist/commands/install/index.d.ts.map +1 -1
- package/dist/commands/install/index.js +55 -11
- package/dist/commands/install/update-config-toml.d.ts +3 -1
- package/dist/commands/install/update-config-toml.d.ts.map +1 -1
- package/dist/commands/install/update-config-toml.js +9 -4
- package/dist/commands/install/update-env-file.d.ts +12 -0
- package/dist/commands/install/update-env-file.d.ts.map +1 -0
- package/dist/commands/install/update-env-file.js +109 -0
- package/dist/package.json +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"copy-migrations.d.ts","sourceRoot":"","sources":["../../../src/commands/install/copy-migrations.ts"],"names":[],"mappings":"AAyEA,wBAAsB,cAAc,CAAC,EACnC,YAAY,
|
|
1
|
+
{"version":3,"file":"copy-migrations.d.ts","sourceRoot":"","sources":["../../../src/commands/install/copy-migrations.ts"],"names":[],"mappings":"AAyEA,wBAAsB,cAAc,CAAC,EACnC,YAAY,EACZ,WAAmB,EACpB,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GAAG,OAAO,CAAC,OAAO,CAAC,CAmGnB"}
|
|
@@ -46,7 +46,7 @@ function findMigrationsDirectory() {
|
|
|
46
46
|
}
|
|
47
47
|
// Find the migrations directory
|
|
48
48
|
const sourcePath = findMigrationsDirectory();
|
|
49
|
-
export async function copyMigrations({ supabasePath, }) {
|
|
49
|
+
export async function copyMigrations({ supabasePath, autoConfirm = false }) {
|
|
50
50
|
const migrationsPath = path.join(supabasePath, 'migrations');
|
|
51
51
|
if (!fs.existsSync(migrationsPath)) {
|
|
52
52
|
fs.mkdirSync(migrationsPath);
|
|
@@ -62,8 +62,12 @@ export async function copyMigrations({ supabasePath, }) {
|
|
|
62
62
|
const files = fs.readdirSync(sourcePath);
|
|
63
63
|
const filesToCopy = [];
|
|
64
64
|
const skippedFiles = [];
|
|
65
|
-
// Determine which files need to be copied
|
|
65
|
+
// Determine which SQL files need to be copied
|
|
66
66
|
for (const file of files) {
|
|
67
|
+
// Only process SQL files
|
|
68
|
+
if (!file.endsWith('.sql')) {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
67
71
|
const destination = path.join(migrationsPath, file);
|
|
68
72
|
if (fs.existsSync(destination)) {
|
|
69
73
|
skippedFiles.push(file);
|
|
@@ -87,11 +91,15 @@ ${filesToCopy.map((file) => `${chalk.green('+')} ${file}`).join('\n')}`);
|
|
|
87
91
|
summaryParts.push(`${chalk.yellow('Already installed:')}
|
|
88
92
|
${skippedFiles.map((file) => `${chalk.yellow('•')} ${file}`).join('\n')}`);
|
|
89
93
|
}
|
|
90
|
-
// Show summary and ask for confirmation
|
|
94
|
+
// Show summary and ask for confirmation if not auto-confirming
|
|
91
95
|
note(summaryParts.join('\n\n'), 'pgflow Migrations');
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
96
|
+
let shouldContinue = autoConfirm;
|
|
97
|
+
if (!autoConfirm) {
|
|
98
|
+
const confirmResult = await confirm({
|
|
99
|
+
message: `Install ${filesToCopy.length} new migration${filesToCopy.length !== 1 ? 's' : ''}?`,
|
|
100
|
+
});
|
|
101
|
+
shouldContinue = confirmResult === true;
|
|
102
|
+
}
|
|
95
103
|
if (!shouldContinue) {
|
|
96
104
|
log.info('Migration installation skipped');
|
|
97
105
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/install/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/install/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;kCAQhB,OAAO;AAAhC,wBA4FE"}
|
|
@@ -1,27 +1,71 @@
|
|
|
1
|
-
import { intro,
|
|
1
|
+
import { intro, log, note } from '@clack/prompts';
|
|
2
2
|
import { copyMigrations } from './copy-migrations.js';
|
|
3
3
|
import { updateConfigToml } from './update-config-toml.js';
|
|
4
|
-
import {
|
|
4
|
+
import { updateEnvFile } from './update-env-file.js';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import fs from 'fs';
|
|
5
7
|
export default (program) => {
|
|
6
8
|
program
|
|
7
9
|
.command('install')
|
|
8
10
|
.description('Set up pgflow in your Supabase project')
|
|
9
|
-
.
|
|
11
|
+
.option('--supabase-path <path>', 'Path to the Supabase folder')
|
|
12
|
+
.option('-y, --yes', 'Automatically confirm all prompts', false)
|
|
13
|
+
.action(async (options) => {
|
|
10
14
|
intro('pgflow - Postgres-native workflows for Supabase');
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
// Handle Supabase path - either from option or try to detect it
|
|
16
|
+
let supabasePath;
|
|
17
|
+
if (options.supabasePath) {
|
|
18
|
+
supabasePath = path.resolve(process.cwd(), options.supabasePath);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
// Try to detect the Supabase directory automatically
|
|
22
|
+
const possiblePaths = ['./supabase', '../supabase', '../../supabase'];
|
|
23
|
+
let detectedPath = '';
|
|
24
|
+
for (const testPath of possiblePaths) {
|
|
25
|
+
if (fs.existsSync(testPath) &&
|
|
26
|
+
fs.existsSync(path.join(testPath, 'config.toml'))) {
|
|
27
|
+
detectedPath = testPath;
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (detectedPath) {
|
|
32
|
+
log.success(`Found Supabase project at: ${detectedPath}`);
|
|
33
|
+
supabasePath = path.resolve(process.cwd(), detectedPath);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
log.error('Could not automatically detect Supabase directory');
|
|
37
|
+
log.info('Please provide the path using --supabase-path option');
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// Validate Supabase path
|
|
42
|
+
if (!fs.existsSync(supabasePath)) {
|
|
43
|
+
log.error(`Directory not found: ${supabasePath}`);
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
if (!fs.existsSync(path.join(supabasePath, 'config.toml'))) {
|
|
47
|
+
log.error(`Not a valid Supabase project (missing config.toml) at ${supabasePath}`);
|
|
48
|
+
process.exit(1);
|
|
15
49
|
}
|
|
16
50
|
// First update config.toml, then copy migrations
|
|
17
|
-
const configUpdated = await updateConfigToml({
|
|
18
|
-
|
|
51
|
+
const configUpdated = await updateConfigToml({
|
|
52
|
+
supabasePath,
|
|
53
|
+
autoConfirm: options.yes
|
|
54
|
+
});
|
|
55
|
+
const migrationsCopied = await copyMigrations({
|
|
56
|
+
supabasePath,
|
|
57
|
+
autoConfirm: options.yes
|
|
58
|
+
});
|
|
59
|
+
const envFileCreated = await updateEnvFile({
|
|
60
|
+
supabasePath,
|
|
61
|
+
autoConfirm: options.yes
|
|
62
|
+
});
|
|
19
63
|
// Show completion message
|
|
20
|
-
if (migrationsCopied || configUpdated) {
|
|
64
|
+
if (migrationsCopied || configUpdated || envFileCreated) {
|
|
21
65
|
log.success('pgflow setup completed successfully');
|
|
22
66
|
// Show next steps if changes were made
|
|
23
67
|
const nextSteps = [];
|
|
24
|
-
if (configUpdated) {
|
|
68
|
+
if (configUpdated || envFileCreated) {
|
|
25
69
|
nextSteps.push('• Restart your Supabase instance for configuration changes to take effect');
|
|
26
70
|
}
|
|
27
71
|
if (migrationsCopied) {
|
|
@@ -9,9 +9,11 @@
|
|
|
9
9
|
* 4. Creates a backup of the original config.toml file before making changes
|
|
10
10
|
*
|
|
11
11
|
* @param options.supabasePath - Path to the supabase directory
|
|
12
|
+
* @param options.autoConfirm - Whether to automatically confirm changes
|
|
12
13
|
* @returns Promise<boolean> - True if changes were made, false otherwise
|
|
13
14
|
*/
|
|
14
|
-
export declare function updateConfigToml({ supabasePath, }: {
|
|
15
|
+
export declare function updateConfigToml({ supabasePath, autoConfirm }: {
|
|
15
16
|
supabasePath: string;
|
|
17
|
+
autoConfirm?: boolean;
|
|
16
18
|
}): Promise<boolean>;
|
|
17
19
|
//# sourceMappingURL=update-config-toml.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-config-toml.d.ts","sourceRoot":"","sources":["../../../src/commands/install/update-config-toml.ts"],"names":[],"mappings":"AAqBA
|
|
1
|
+
{"version":3,"file":"update-config-toml.d.ts","sourceRoot":"","sources":["../../../src/commands/install/update-config-toml.ts"],"names":[],"mappings":"AAqBA;;;;;;;;;;;;;GAaG;AACH,wBAAsB,gBAAgB,CAAC,EACrC,YAAY,EACZ,WAAmB,EACpB,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GAAG,OAAO,CAAC,OAAO,CAAC,CA0HnB"}
|
|
@@ -14,9 +14,10 @@ import chalk from 'chalk';
|
|
|
14
14
|
* 4. Creates a backup of the original config.toml file before making changes
|
|
15
15
|
*
|
|
16
16
|
* @param options.supabasePath - Path to the supabase directory
|
|
17
|
+
* @param options.autoConfirm - Whether to automatically confirm changes
|
|
17
18
|
* @returns Promise<boolean> - True if changes were made, false otherwise
|
|
18
19
|
*/
|
|
19
|
-
export async function updateConfigToml({ supabasePath, }) {
|
|
20
|
+
export async function updateConfigToml({ supabasePath, autoConfirm = false }) {
|
|
20
21
|
const configPath = path.join(supabasePath, 'config.toml');
|
|
21
22
|
const backupPath = `${configPath}.backup`;
|
|
22
23
|
try {
|
|
@@ -54,9 +55,13 @@ ${chalk.red(`- policy = "${currentSettings.edgeRuntimePolicy}"`)}
|
|
|
54
55
|
${chalk.green('+ policy = "per_worker"')}`);
|
|
55
56
|
}
|
|
56
57
|
note(changes.join('\n\n'), 'Required Configuration Changes');
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
let shouldContinue = autoConfirm;
|
|
59
|
+
if (!autoConfirm) {
|
|
60
|
+
const confirmResult = await confirm({
|
|
61
|
+
message: `Update Supabase configuration? (a backup will be created)`,
|
|
62
|
+
});
|
|
63
|
+
shouldContinue = confirmResult === true;
|
|
64
|
+
}
|
|
60
65
|
if (!shouldContinue) {
|
|
61
66
|
log.info('Configuration update skipped');
|
|
62
67
|
return false;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Updates the functions/.env file with required environment variables for pgflow
|
|
3
|
+
*
|
|
4
|
+
* @param options.supabasePath - Path to the supabase directory
|
|
5
|
+
* @param options.autoConfirm - Whether to automatically confirm changes
|
|
6
|
+
* @returns Promise<boolean> - True if changes were made, false otherwise
|
|
7
|
+
*/
|
|
8
|
+
export declare function updateEnvFile({ supabasePath, autoConfirm, }: {
|
|
9
|
+
supabasePath: string;
|
|
10
|
+
autoConfirm?: boolean;
|
|
11
|
+
}): Promise<boolean>;
|
|
12
|
+
//# sourceMappingURL=update-env-file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-env-file.d.ts","sourceRoot":"","sources":["../../../src/commands/install/update-env-file.ts"],"names":[],"mappings":"AAKA;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,EAClC,YAAY,EACZ,WAAmB,GACpB,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GAAG,OAAO,CAAC,OAAO,CAAC,CAkHnB"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { log, note, confirm } from '@clack/prompts';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
/**
|
|
6
|
+
* Updates the functions/.env file with required environment variables for pgflow
|
|
7
|
+
*
|
|
8
|
+
* @param options.supabasePath - Path to the supabase directory
|
|
9
|
+
* @param options.autoConfirm - Whether to automatically confirm changes
|
|
10
|
+
* @returns Promise<boolean> - True if changes were made, false otherwise
|
|
11
|
+
*/
|
|
12
|
+
export async function updateEnvFile({ supabasePath, autoConfirm = false, }) {
|
|
13
|
+
const functionsDir = path.join(supabasePath, 'functions');
|
|
14
|
+
const envFilePath = path.join(functionsDir, '.env');
|
|
15
|
+
// Create functions directory if it doesn't exist
|
|
16
|
+
if (!fs.existsSync(functionsDir)) {
|
|
17
|
+
log.step('Creating functions directory...');
|
|
18
|
+
fs.mkdirSync(functionsDir, { recursive: true });
|
|
19
|
+
}
|
|
20
|
+
// Variables to add
|
|
21
|
+
const envVars = {
|
|
22
|
+
EDGE_WORKER_DB_URL: 'postgresql://postgres.pooler-dev:postgres@pooler:6543/postgres',
|
|
23
|
+
EDGE_WORKER_LOG_LEVEL: 'info',
|
|
24
|
+
};
|
|
25
|
+
// Check if file exists and read its content
|
|
26
|
+
let currentContent = '';
|
|
27
|
+
let isNewFile = false;
|
|
28
|
+
if (fs.existsSync(envFilePath)) {
|
|
29
|
+
currentContent = fs.readFileSync(envFilePath, 'utf8');
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
log.step('Creating new .env file...');
|
|
33
|
+
isNewFile = true;
|
|
34
|
+
}
|
|
35
|
+
// Prepare new content
|
|
36
|
+
let newContent = currentContent;
|
|
37
|
+
// Build diff preview
|
|
38
|
+
const missingVars = [];
|
|
39
|
+
const existingVars = [];
|
|
40
|
+
// Check which variables need to be added
|
|
41
|
+
for (const [key, value] of Object.entries(envVars)) {
|
|
42
|
+
if (!newContent.includes(`${key}=`)) {
|
|
43
|
+
missingVars.push({ key, value });
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
existingVars.push(key);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// If no changes needed, return early
|
|
50
|
+
if (missingVars.length === 0) {
|
|
51
|
+
log.info('Environment variables are already set');
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
// Build diff preview
|
|
55
|
+
const diffPreview = [];
|
|
56
|
+
if (isNewFile) {
|
|
57
|
+
diffPreview.push(`${chalk.green('Creating new .env file with:')}`);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
diffPreview.push(`${chalk.green('Adding to existing .env file:')}`);
|
|
61
|
+
}
|
|
62
|
+
// Show variables to be added
|
|
63
|
+
for (const { key, value } of missingVars) {
|
|
64
|
+
diffPreview.push(`${chalk.green('+')} ${key}="${value}"`);
|
|
65
|
+
}
|
|
66
|
+
// Show existing variables if any
|
|
67
|
+
if (existingVars.length > 0) {
|
|
68
|
+
diffPreview.push('');
|
|
69
|
+
diffPreview.push(`${chalk.yellow('Already present:')}`);
|
|
70
|
+
for (const key of existingVars) {
|
|
71
|
+
diffPreview.push(`${chalk.yellow('•')} ${key}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Show the diff preview
|
|
75
|
+
note(diffPreview.join('\n'), 'Environment Variables');
|
|
76
|
+
// Ask for confirmation if not auto-confirming
|
|
77
|
+
let shouldContinue = autoConfirm;
|
|
78
|
+
if (!autoConfirm) {
|
|
79
|
+
const confirmResult = await confirm({
|
|
80
|
+
message: `Update environment variables?`,
|
|
81
|
+
});
|
|
82
|
+
shouldContinue = confirmResult === true;
|
|
83
|
+
}
|
|
84
|
+
if (!shouldContinue) {
|
|
85
|
+
log.info('Environment variable update skipped');
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
// Apply changes if confirmed
|
|
89
|
+
for (const { key, value } of missingVars) {
|
|
90
|
+
// Add a newline at the end if the file doesn't end with one and isn't empty
|
|
91
|
+
if (newContent && !newContent.endsWith('\n')) {
|
|
92
|
+
newContent += '\n';
|
|
93
|
+
}
|
|
94
|
+
// Add the new variable
|
|
95
|
+
newContent += `${key}="${value}"\n`;
|
|
96
|
+
log.step(`Adding ${key} environment variable`);
|
|
97
|
+
}
|
|
98
|
+
// Write the file if changes were made
|
|
99
|
+
try {
|
|
100
|
+
fs.writeFileSync(envFilePath, newContent);
|
|
101
|
+
log.success('Environment variables updated successfully');
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
106
|
+
log.error(`Failed to update environment variables: ${errorMessage}`);
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
}
|
package/dist/package.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pgflow",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.19",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"typings": "./dist/index.d.ts",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"chalk": "^5.4.1",
|
|
25
25
|
"commander": "^13.1.0",
|
|
26
26
|
"toml-patch": "^0.2.3",
|
|
27
|
-
"@pgflow/core": "0.1.
|
|
27
|
+
"@pgflow/core": "0.1.19"
|
|
28
28
|
},
|
|
29
29
|
"publishConfig": {
|
|
30
30
|
"access": "public"
|