Comparing version 1.29.5 to 1.30.0
@@ -12,7 +12,9 @@ import { readFileSync } from 'node:fs'; | ||
let client; | ||
let clientInitialized = false; | ||
let userId = ''; | ||
export const analyticsMiddleware = async (args) => { | ||
if (!args.analytics) { | ||
if (!args.analytics || clientInitialized) { | ||
return; | ||
} | ||
clientInitialized = true; | ||
try { | ||
@@ -43,2 +45,3 @@ const credentialsPath = join(args.configDir, CREDENTIALS_FILE); | ||
}); | ||
log.debug('Initialized CLI analytics'); | ||
client.identify({ | ||
@@ -59,6 +62,10 @@ userId: userId?.toString() ?? 'anonymous', | ||
}); | ||
log.debug('Flushing CLI started event with userId: %s', userId); | ||
await client.closeAndFlush(); | ||
log.debug('Flushed CLI started event with userId: %s', userId); | ||
}; | ||
export const closeAnalytics = async () => { | ||
if (client) { | ||
log.debug('Flushing CLI analytics'); | ||
await client.closeAndFlush(); | ||
log.debug('Flushed CLI analytics'); | ||
} | ||
}; | ||
export const sendError = (err, errCode) => { | ||
@@ -79,4 +86,3 @@ if (!client) { | ||
}); | ||
client.closeAndFlush(); | ||
log.debug('Sent CLI error event: %s', errCode); | ||
}; |
@@ -10,2 +10,3 @@ import { EndpointType } from '@neondatabase/api-client'; | ||
import { log } from '../log.js'; | ||
import { parseSchemaDiffParams, schemaDiff } from './schema_diff.js'; | ||
const BRANCH_FIELDS = [ | ||
@@ -121,3 +122,43 @@ 'id', | ||
.command('delete <id|name>', 'Delete a branch', (yargs) => yargs, async (args) => await deleteBranch(args)) | ||
.command('get <id|name>', 'Get a branch', (yargs) => yargs, async (args) => await get(args)); | ||
.command('get <id|name>', 'Get a branch', (yargs) => yargs, async (args) => await get(args)) | ||
.command({ | ||
command: 'schema-diff [base-branch] [compare-source[@(timestamp|lsn)]]', | ||
aliases: ['sd'], | ||
describe: "Compare the latest schemas of any two branches, or compare a branch to its own or another branch's history.", | ||
builder: (yargs) => { | ||
return yargs | ||
.middleware((args) => (args.compareSource = args['compare-source@(timestamp'])) | ||
.middleware(parseSchemaDiffParams) | ||
.options({ | ||
database: { | ||
alias: 'db', | ||
type: 'string', | ||
description: 'Name of the database for which the schema comparison is performed', | ||
}, | ||
}) | ||
.example([ | ||
[ | ||
'$0 branches schema-diff main br-compare-branch-123456', | ||
'Compares the main branch to the head of the branch with ID br-compare-branch-123456', | ||
], | ||
[ | ||
'$0 branches schema-diff main compare@2024-06-01T00:00:00Z', | ||
'Compares the main branch to the state of the compare branch at timestamp 2024-06-01T00:00:00.000Z', | ||
], | ||
[ | ||
'$0 branches schema-diff my-branch ^self@0/123456', | ||
'Compares my-branch to LSN 0/123456 from its own history', | ||
], | ||
[ | ||
'$0 branches schema-diff my-branch ^parent', | ||
'Compares my-branch to the head of its parent branch', | ||
], | ||
[ | ||
'$0 branches schema-diff', | ||
"If a branch is specified in 'set-context', compares this branch to its parent. Otherwise, compares the primary branch to its parent.", | ||
], | ||
]); | ||
}, | ||
handler: async (args) => schemaDiff(args), | ||
}); | ||
export const handler = (args) => { | ||
@@ -124,0 +165,0 @@ return args; |
23
index.js
@@ -23,3 +23,3 @@ import { basename } from 'node:path'; | ||
import commands from './commands/index.js'; | ||
import { analyticsMiddleware, sendError } from './analytics.js'; | ||
import { analyticsMiddleware, closeAnalytics, sendError } from './analytics.js'; | ||
import { isAxiosError } from 'axios'; | ||
@@ -100,2 +100,8 @@ import { matchErrorCode } from './errors.js'; | ||
}, | ||
color: { | ||
group: 'Global options:', | ||
describe: 'Colorize the output. Example: --no-color, --color false', | ||
type: 'boolean', | ||
default: true, | ||
}, | ||
}) | ||
@@ -161,2 +167,3 @@ .middleware((args) => fillInArgs(args), true) | ||
} | ||
await closeAnalytics(); | ||
err?.stack && log.debug('Stack: %s', err.stack); | ||
@@ -166,7 +173,13 @@ process.exit(1); | ||
(async () => { | ||
const args = await builder.argv; | ||
if (args._.length === 0 || args.help) { | ||
await showHelp(builder); | ||
process.exit(0); | ||
try { | ||
const args = await builder.argv; | ||
if (args._.length === 0 || args.help) { | ||
await showHelp(builder); | ||
process.exit(0); | ||
} | ||
await closeAnalytics(); | ||
} | ||
catch { | ||
// noop | ||
} | ||
})(); |
@@ -8,3 +8,3 @@ { | ||
"type": "module", | ||
"version": "1.29.5", | ||
"version": "1.30.0", | ||
"description": "CLI tool for NeonDB Cloud management", | ||
@@ -33,2 +33,3 @@ "main": "index.js", | ||
"@types/cli-table": "^0.3.0", | ||
"@types/diff": "^5.2.1", | ||
"@types/express": "^4.17.17", | ||
@@ -58,3 +59,3 @@ "@types/inquirer": "^9.0.3", | ||
"dependencies": { | ||
"@neondatabase/api-client": "1.5.0", | ||
"@neondatabase/api-client": "1.7.0", | ||
"@segment/analytics-node": "^1.0.0-beta.26", | ||
@@ -65,2 +66,3 @@ "axios": "^1.4.0", | ||
"cli-table": "^0.3.11", | ||
"diff": "^5.2.0", | ||
"inquirer": "^9.2.6", | ||
@@ -67,0 +69,0 @@ "open": "^10.1.0", |
@@ -33,6 +33,11 @@ // FILE IS GENERATED, DO NOT EDIT | ||
}, | ||
'project.settings.allowed_ips.protected_branches_only': { | ||
type: "boolean", | ||
description: "If true, the list will be applied only to protected branches.", | ||
demandOption: false, | ||
}, | ||
'project.settings.allowed_ips.primary_branch_only': { | ||
type: "boolean", | ||
description: "If true, the list will be applied only to the primary branch.", | ||
demandOption: true, | ||
demandOption: false, | ||
}, | ||
@@ -95,2 +100,7 @@ 'project.settings.enable_logical_replication': { | ||
}, | ||
'project.org_id': { | ||
type: "string", | ||
description: "Organization id in case the project created belongs to an organization.\nIf not present, project is owned by a user and not by org.\n", | ||
demandOption: false, | ||
}, | ||
}; | ||
@@ -128,6 +138,11 @@ export const projectUpdateRequest = { | ||
}, | ||
'project.settings.allowed_ips.protected_branches_only': { | ||
type: "boolean", | ||
description: "If true, the list will be applied only to protected branches.", | ||
demandOption: false, | ||
}, | ||
'project.settings.allowed_ips.primary_branch_only': { | ||
type: "boolean", | ||
description: "If true, the list will be applied only to the primary branch.", | ||
demandOption: true, | ||
demandOption: false, | ||
}, | ||
@@ -134,0 +149,0 @@ 'project.settings.enable_logical_replication': { |
@@ -21,4 +21,10 @@ import { looksLikeLSN, looksLikeTimestamp } from './formats.js'; | ||
}; | ||
if (result.tag === 'timestamp' && !looksLikeTimestamp(result.timestamp)) { | ||
throw new PointInTimeParseError('Invalid source branch format'); | ||
if (result.tag === 'timestamp') { | ||
const timestamp = result.timestamp; | ||
if (!looksLikeTimestamp(timestamp)) { | ||
throw new PointInTimeParseError(`Invalid source branch format - ${input}`); | ||
} | ||
if (Date.parse(timestamp) > Date.now()) { | ||
throw new PointInTimeParseError(`Timestamp can not be in future - ${input}`); | ||
} | ||
} | ||
@@ -25,0 +31,0 @@ return result; |
@@ -74,2 +74,5 @@ import YAML from 'yaml'; | ||
}, | ||
text(data) { | ||
return out.write(data); | ||
}, | ||
end: (...args) => { | ||
@@ -76,0 +79,0 @@ if (args.length === 2) { |
149921
52
3831
13
33
+ Addeddiff@^5.2.0
+ Added@neondatabase/api-client@1.7.0(transitive)
+ Addeddiff@5.2.0(transitive)
- Removed@neondatabase/api-client@1.5.0(transitive)