@dinoxx/dinox-cli 1.0.18 → 1.0.20
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/README.md +807 -418
- package/dist/auth/userInfo.d.ts +2 -0
- package/dist/auth/userInfo.js +28 -11
- package/dist/cli.js +15 -1
- package/dist/commands/auth/index.d.ts +2 -0
- package/dist/commands/auth/index.js +217 -163
- package/dist/commands/boxes/index.d.ts +2 -0
- package/dist/commands/boxes/index.js +119 -75
- package/dist/commands/boxes/repo.d.ts +8 -0
- package/dist/commands/boxes/repo.js +41 -0
- package/dist/commands/config/index.d.ts +2 -0
- package/dist/commands/config/index.js +85 -36
- package/dist/commands/descriptor/register.d.ts +8 -0
- package/dist/commands/descriptor/register.js +113 -0
- package/dist/commands/descriptor/types.d.ts +37 -0
- package/dist/commands/descriptor/types.js +17 -0
- package/dist/commands/graph/index.d.ts +2 -0
- package/dist/commands/graph/index.js +143 -73
- package/dist/commands/info/index.d.ts +2 -0
- package/dist/commands/info/index.js +41 -14
- package/dist/commands/mcp/index.js +11 -10
- package/dist/commands/mcp/server.js +8 -4
- package/dist/commands/mcp/tools.js +30 -104
- package/dist/commands/mcp/types.d.ts +8 -1
- package/dist/commands/meta/index.d.ts +2 -0
- package/dist/commands/meta/index.js +64 -33
- package/dist/commands/meta/repo.d.ts +6 -0
- package/dist/commands/meta/repo.js +6 -0
- package/dist/commands/notes/actions.d.ts +10 -0
- package/dist/commands/notes/actions.js +403 -0
- package/dist/commands/notes/descriptors.d.ts +4 -0
- package/dist/commands/notes/descriptors.js +250 -0
- package/dist/commands/notes/dryRun.d.ts +31 -0
- package/dist/commands/notes/dryRun.js +130 -0
- package/dist/commands/notes/index.d.ts +2 -51
- package/dist/commands/notes/index.js +2 -581
- package/dist/commands/notes/repo.d.ts +9 -0
- package/dist/commands/notes/repo.js +56 -10
- package/dist/commands/notes/runtime.d.ts +28 -0
- package/dist/commands/notes/runtime.js +185 -0
- package/dist/commands/notes/searchOutput.d.ts +10 -2
- package/dist/commands/notes/searchOutput.js +14 -2
- package/dist/commands/notes/searchResponse.d.ts +51 -0
- package/dist/commands/notes/searchResponse.js +56 -0
- package/dist/commands/notes/searchSql.js +2 -0
- package/dist/commands/prompt/index.d.ts +2 -0
- package/dist/commands/prompt/index.js +122 -72
- package/dist/commands/prompt/repo.d.ts +7 -0
- package/dist/commands/prompt/repo.js +46 -0
- package/dist/commands/schema/commandMetadata.d.ts +2 -0
- package/dist/commands/schema/commandMetadata.js +18 -0
- package/dist/commands/schema/globalOptions.d.ts +3 -0
- package/dist/commands/schema/globalOptions.js +3 -0
- package/dist/commands/schema/index.d.ts +4 -0
- package/dist/commands/schema/index.js +109 -0
- package/dist/commands/schema/renderSkills.d.ts +6 -0
- package/dist/commands/schema/renderSkills.js +216 -0
- package/dist/commands/schema/spec.d.ts +6 -0
- package/dist/commands/schema/spec.js +40 -0
- package/dist/commands/schema/types.d.ts +47 -0
- package/dist/commands/schema/types.js +1 -0
- package/dist/commands/storage/index.d.ts +4 -0
- package/dist/commands/storage/index.js +292 -0
- package/dist/commands/storage/repo.d.ts +162 -0
- package/dist/commands/storage/repo.js +770 -0
- package/dist/commands/sync.d.ts +2 -0
- package/dist/commands/sync.js +41 -27
- package/dist/commands/tags/index.d.ts +2 -0
- package/dist/commands/tags/index.js +121 -79
- package/dist/commands/tags/repo.d.ts +7 -0
- package/dist/commands/tags/repo.js +52 -0
- package/dist/commands/todo/dryRun.d.ts +23 -0
- package/dist/commands/todo/dryRun.js +133 -0
- package/dist/commands/todo/index.d.ts +2 -0
- package/dist/commands/todo/index.js +285 -135
- package/dist/commands/todo/repo.d.ts +11 -0
- package/dist/commands/todo/repo.js +37 -9
- package/dist/commands/update.d.ts +3 -0
- package/dist/commands/update.js +35 -13
- package/dist/commands/writeDryRun.d.ts +62 -0
- package/dist/commands/writeDryRun.js +131 -0
- package/dist/config/paths.d.ts +2 -1
- package/dist/config/paths.js +11 -1
- package/dist/config/resolve.js +7 -5
- package/dist/constants/links.d.ts +1 -1
- package/dist/constants/links.js +1 -1
- package/dist/daemon/ensure.js +3 -2
- package/dist/daemon/index.js +17 -15
- package/dist/dinox.js +9 -13
- package/dist/powersync/runtime.d.ts +1 -1
- package/dist/powersync/runtime.js +5 -3
- package/dist/powersync/schema/index.d.ts +27 -0
- package/dist/powersync/schema/index.js +2 -0
- package/dist/powersync/schema/note.d.ts +1 -0
- package/dist/powersync/schema/note.js +1 -0
- package/dist/powersync/schema/projects.d.ts +3 -0
- package/dist/powersync/schema/projects.js +3 -0
- package/dist/powersync/schema/storage.d.ts +24 -0
- package/dist/powersync/schema/storage.js +24 -0
- package/dist/skills/check.d.ts +6 -0
- package/dist/skills/check.js +254 -0
- package/dist/utils/bidlinkCanonicalization.d.ts +2 -0
- package/dist/utils/bidlinkCanonicalization.js +161 -0
- package/dist/utils/dryRun.d.ts +13 -0
- package/dist/utils/dryRun.js +69 -0
- package/dist/utils/output.d.ts +19 -0
- package/dist/utils/output.js +155 -1
- package/dist/utils/terminalSanitization.d.ts +2 -0
- package/dist/utils/terminalSanitization.js +33 -0
- package/dist/utils/tiptapMarkdown.d.ts +4 -1
- package/dist/utils/tiptapMarkdown.js +285 -113
- package/dist/utils/tiptapMarkdownSchema.d.ts +37 -0
- package/dist/utils/tiptapMarkdownSchema.js +577 -0
- package/dist/utils/tiptapMarkdownSchemaUtils.d.ts +74 -0
- package/dist/utils/tiptapMarkdownSchemaUtils.js +394 -0
- package/dist/utils/updateNotice.d.ts +7 -0
- package/dist/utils/updateNotice.js +64 -0
- package/package.json +25 -3
package/dist/auth/userInfo.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ export type AuthIdentity = {
|
|
|
5
5
|
email: string | null;
|
|
6
6
|
syncedAt: string;
|
|
7
7
|
};
|
|
8
|
+
export declare function buildPendingAuthConfig(rawConfig: DinoxConfig, authorization: string): DinoxConfig;
|
|
9
|
+
export declare function mergeAuthIdentityIntoConfig(rawConfig: DinoxConfig, authorization: string, identity: AuthIdentity): DinoxConfig;
|
|
8
10
|
export declare function fetchUserInfoWithAuthorization(input: {
|
|
9
11
|
authorization: string;
|
|
10
12
|
config: ResolvedDinoxConfig;
|
package/dist/auth/userInfo.js
CHANGED
|
@@ -3,6 +3,33 @@ import { DinoxError } from '../utils/errors.js';
|
|
|
3
3
|
import { createTimeoutSignal, mergeAbortSignals } from '../utils/abort.js';
|
|
4
4
|
import { toAuthorizationHeaderValue } from '../utils/authToken.js';
|
|
5
5
|
const AUTH_CODE_OK = '000000';
|
|
6
|
+
export function buildPendingAuthConfig(rawConfig, authorization) {
|
|
7
|
+
return {
|
|
8
|
+
...rawConfig,
|
|
9
|
+
auth: {
|
|
10
|
+
...(rawConfig.auth ?? {}),
|
|
11
|
+
authorization,
|
|
12
|
+
userId: undefined,
|
|
13
|
+
username: undefined,
|
|
14
|
+
email: undefined,
|
|
15
|
+
userInfoSyncedAt: undefined,
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export function mergeAuthIdentityIntoConfig(rawConfig, authorization, identity) {
|
|
20
|
+
const pendingConfig = buildPendingAuthConfig(rawConfig, authorization);
|
|
21
|
+
return {
|
|
22
|
+
...pendingConfig,
|
|
23
|
+
auth: {
|
|
24
|
+
...(pendingConfig.auth ?? {}),
|
|
25
|
+
authorization,
|
|
26
|
+
userId: identity.userId,
|
|
27
|
+
username: identity.username,
|
|
28
|
+
email: identity.email,
|
|
29
|
+
userInfoSyncedAt: identity.syncedAt,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
6
33
|
function normalizeOptionalString(value) {
|
|
7
34
|
if (typeof value !== 'string') {
|
|
8
35
|
return undefined;
|
|
@@ -105,17 +132,7 @@ export async function refreshAndPersistAuthIdentity(rawConfig, resolvedConfig) {
|
|
|
105
132
|
authorization,
|
|
106
133
|
config: resolvedConfig,
|
|
107
134
|
});
|
|
108
|
-
const nextConfig =
|
|
109
|
-
...rawConfig,
|
|
110
|
-
auth: {
|
|
111
|
-
...(rawConfig.auth ?? {}),
|
|
112
|
-
authorization: rawConfig.auth?.authorization ?? authorization,
|
|
113
|
-
userId: identity.userId,
|
|
114
|
-
username: identity.username,
|
|
115
|
-
email: identity.email,
|
|
116
|
-
userInfoSyncedAt: identity.syncedAt,
|
|
117
|
-
},
|
|
118
|
-
};
|
|
135
|
+
const nextConfig = mergeAuthIdentityIntoConfig(rawConfig, authorization, identity);
|
|
119
136
|
await saveConfig(nextConfig);
|
|
120
137
|
return identity;
|
|
121
138
|
}
|
package/dist/cli.js
CHANGED
|
@@ -9,12 +9,16 @@ import { registerMCPCommands } from './commands/mcp/index.js';
|
|
|
9
9
|
import { registerMetaCommands } from './commands/meta/index.js';
|
|
10
10
|
import { registerNoteCommands } from './commands/notes/index.js';
|
|
11
11
|
import { registerPromptCommands } from './commands/prompt/index.js';
|
|
12
|
+
import { registerSchemaCommands } from './commands/schema/index.js';
|
|
12
13
|
import { registerSyncCommand } from './commands/sync.js';
|
|
14
|
+
import { registerStorageCommands } from './commands/storage/index.js';
|
|
13
15
|
import { registerUpdateCommand } from './commands/update.js';
|
|
14
16
|
import { registerTagsCommand } from './commands/tags/index.js';
|
|
15
17
|
import { registerTodoCommands } from './commands/todo/index.js';
|
|
16
18
|
import { getPackageVersion } from './utils/version.js';
|
|
19
|
+
import { clearRequestedStructuredOutputFormat, resolveStructuredOutputFormat, setRequestedStructuredOutputFormat, } from './utils/output.js';
|
|
17
20
|
export function createCli() {
|
|
21
|
+
clearRequestedStructuredOutputFormat();
|
|
18
22
|
const program = new Command();
|
|
19
23
|
program
|
|
20
24
|
.name('dino')
|
|
@@ -22,10 +26,18 @@ export function createCli() {
|
|
|
22
26
|
.version(getPackageVersion())
|
|
23
27
|
.showHelpAfterError();
|
|
24
28
|
program
|
|
25
|
-
.option('--json', '
|
|
29
|
+
.option('--json', 'legacy machine-readable YAML output (equivalent to --format yaml)')
|
|
30
|
+
.option('--format <format>', 'structured output format: yaml | json')
|
|
26
31
|
.option('--offline', 'skip connect/sync and only use local cache')
|
|
27
32
|
.option('--sync-timeout <ms>', 'override sync/connect timeout (milliseconds)')
|
|
28
33
|
.option('--verbose', 'enable verbose logging');
|
|
34
|
+
program.hook('preAction', (_thisCommand, actionCommand) => {
|
|
35
|
+
const options = actionCommand.optsWithGlobals?.() ?? {};
|
|
36
|
+
setRequestedStructuredOutputFormat(resolveStructuredOutputFormat(options));
|
|
37
|
+
});
|
|
38
|
+
program.hook('postAction', () => {
|
|
39
|
+
clearRequestedStructuredOutputFormat();
|
|
40
|
+
});
|
|
29
41
|
registerAuthCommands(program);
|
|
30
42
|
registerBoxesCommand(program);
|
|
31
43
|
registerConfigCommands(program);
|
|
@@ -37,6 +49,8 @@ export function createCli() {
|
|
|
37
49
|
registerSyncCommand(program);
|
|
38
50
|
registerUpdateCommand(program);
|
|
39
51
|
registerPromptCommands(program);
|
|
52
|
+
registerSchemaCommands(program);
|
|
53
|
+
registerStorageCommands(program);
|
|
40
54
|
registerTagsCommand(program);
|
|
41
55
|
registerTodoCommands(program);
|
|
42
56
|
registerNoteCommands(program);
|
|
@@ -1,183 +1,237 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
|
+
import { buildPendingAuthConfig, fetchUserInfoWithAuthorization, mergeAuthIdentityIntoConfig, } from '../../auth/userInfo.js';
|
|
3
|
+
import { getLegacyPowerSyncDbPath, getPowerSyncDbPath } from '../../config/paths.js';
|
|
2
4
|
import { loadConfig, saveConfig } from '../../config/store.js';
|
|
3
5
|
import { resolveConfig } from '../../config/resolve.js';
|
|
4
|
-
import { getPowerSyncDbPath } from '../../config/paths.js';
|
|
5
|
-
import { redactAuthorization } from '../../utils/redact.js';
|
|
6
|
-
import { DinoxError } from '../../utils/errors.js';
|
|
7
|
-
import { printYaml } from '../../utils/output.js';
|
|
8
|
-
import { parseSyncTimeoutMs } from '../../utils/syncTimeout.js';
|
|
9
|
-
import { normalizeAuthToken } from '../../utils/authToken.js';
|
|
10
|
-
import { refreshAndPersistAuthIdentity } from '../../auth/userInfo.js';
|
|
11
|
-
import { connectPowerSync, getStatusSnapshot } from '../../powersync/runtime.js';
|
|
12
6
|
import { fetchCredentialsWithAuthorization } from '../../powersync/connector.js';
|
|
7
|
+
import { connectPowerSync, getStatusSnapshot } from '../../powersync/runtime.js';
|
|
13
8
|
import { runSingleSyncPass } from '../../powersync/syncPass.js';
|
|
9
|
+
import { registerCommandGroup } from '../descriptor/register.js';
|
|
10
|
+
import { FORMAT_OPTIONS, OFFLINE_OPTIONS, SYNC_TIMEOUT_OPTIONS } from '../schema/globalOptions.js';
|
|
11
|
+
import { normalizeAuthToken } from '../../utils/authToken.js';
|
|
12
|
+
import { DinoxError } from '../../utils/errors.js';
|
|
13
|
+
import { getRequestedStructuredOutputFormat, printHumanReadableLine, printSuccess, } from '../../utils/output.js';
|
|
14
|
+
import { redactAuthorization } from '../../utils/redact.js';
|
|
15
|
+
import { parseSyncTimeoutMs } from '../../utils/syncTimeout.js';
|
|
16
|
+
const AUTH_LOGIN_GLOBAL_OPTIONS = [...FORMAT_OPTIONS, ...SYNC_TIMEOUT_OPTIONS];
|
|
17
|
+
const AUTH_STATUS_GLOBAL_OPTIONS = [...FORMAT_OPTIONS, ...OFFLINE_OPTIONS, ...SYNC_TIMEOUT_OPTIONS];
|
|
14
18
|
async function removeSqliteArtifacts(dbPath) {
|
|
15
|
-
const
|
|
16
|
-
for (const suffix of artifacts) {
|
|
19
|
+
for (const suffix of ['', '-wal', '-shm']) {
|
|
17
20
|
await fs.rm(`${dbPath}${suffix}`, { force: true }).catch(() => undefined);
|
|
18
21
|
}
|
|
19
22
|
}
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const resolved = resolveConfig(config);
|
|
37
|
-
const globals = command.optsWithGlobals?.() ?? {};
|
|
38
|
-
const timeoutMs = parseSyncTimeoutMs(globals.syncTimeout) ?? resolved.sync.timeoutMs;
|
|
39
|
-
const jsonOutput = Boolean(globals.json);
|
|
40
|
-
// 1) Token exchange sanity check.
|
|
41
|
-
await fetchCredentialsWithAuthorization({
|
|
42
|
-
authorization: rawToken,
|
|
43
|
-
endpoint: resolved.powersync.endpoint,
|
|
44
|
-
credentialsUrl: resolved.powersync.tokenEndpoint,
|
|
45
|
-
timeoutMs,
|
|
46
|
-
});
|
|
47
|
-
// 1.5) Fetch and persist user identity.
|
|
48
|
-
const identity = await refreshAndPersistAuthIdentity(config, resolved);
|
|
49
|
-
// 2) Connect + initial sync.
|
|
50
|
-
const { db, dbPath, stale } = await connectPowerSync({
|
|
51
|
-
config: resolved,
|
|
52
|
-
offline: false,
|
|
53
|
-
timeoutMs,
|
|
54
|
-
});
|
|
55
|
-
try {
|
|
56
|
-
await runSingleSyncPass(db, timeoutMs);
|
|
57
|
-
const status = getStatusSnapshot(db);
|
|
58
|
-
const result = {
|
|
59
|
-
ok: true,
|
|
60
|
-
verified: true,
|
|
61
|
-
endpoint: resolved.powersync.endpoint,
|
|
62
|
-
dbPath,
|
|
63
|
-
stale,
|
|
64
|
-
lastSyncedAt: status.lastSyncedAt,
|
|
65
|
-
userId: identity.userId,
|
|
66
|
-
};
|
|
67
|
-
if (jsonOutput) {
|
|
68
|
-
printYaml(result);
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
console.log('Login verified.');
|
|
72
|
-
console.log(`- endpoint: ${result.endpoint}`);
|
|
73
|
-
console.log(`- db: ${result.dbPath}`);
|
|
74
|
-
console.log(`- userId: ${result.userId}`);
|
|
75
|
-
if (result.lastSyncedAt) {
|
|
76
|
-
console.log(`- lastSyncedAt: ${result.lastSyncedAt}`);
|
|
77
|
-
}
|
|
78
|
-
if (stale) {
|
|
79
|
-
console.log('- warning: initial sync timed out; local cache may be stale');
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
finally {
|
|
84
|
-
await db.close().catch(() => undefined);
|
|
85
|
-
}
|
|
23
|
+
async function runAuthLogin(context) {
|
|
24
|
+
const token = context.args.token;
|
|
25
|
+
const rawToken = normalizeAuthToken(token);
|
|
26
|
+
if (!rawToken) {
|
|
27
|
+
throw new DinoxError('Token is required');
|
|
28
|
+
}
|
|
29
|
+
const previousConfig = await loadConfig();
|
|
30
|
+
const pendingConfig = buildPendingAuthConfig(previousConfig, rawToken);
|
|
31
|
+
const resolved = resolveConfig(pendingConfig);
|
|
32
|
+
const timeoutMs = parseSyncTimeoutMs(context.globals.syncTimeout) ?? resolved.sync.timeoutMs;
|
|
33
|
+
const structuredOutput = getRequestedStructuredOutputFormat() !== null;
|
|
34
|
+
await fetchCredentialsWithAuthorization({
|
|
35
|
+
authorization: rawToken,
|
|
36
|
+
endpoint: resolved.powersync.endpoint,
|
|
37
|
+
credentialsUrl: resolved.powersync.tokenEndpoint,
|
|
38
|
+
timeoutMs,
|
|
86
39
|
});
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
.action(async (options) => {
|
|
92
|
-
const config = await loadConfig();
|
|
93
|
-
if (config.auth) {
|
|
94
|
-
config.auth.authorization = undefined;
|
|
95
|
-
config.auth.userId = undefined;
|
|
96
|
-
config.auth.username = undefined;
|
|
97
|
-
config.auth.email = undefined;
|
|
98
|
-
config.auth.userInfoSyncedAt = undefined;
|
|
99
|
-
}
|
|
100
|
-
await saveConfig(config);
|
|
101
|
-
if (options.clearLocalDb) {
|
|
102
|
-
const dbPath = getPowerSyncDbPath();
|
|
103
|
-
await removeSqliteArtifacts(dbPath);
|
|
104
|
-
}
|
|
40
|
+
const identity = await fetchUserInfoWithAuthorization({
|
|
41
|
+
authorization: rawToken,
|
|
42
|
+
config: resolved,
|
|
43
|
+
timeoutMs,
|
|
105
44
|
});
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
const
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
username: resolved.auth.username ?? null,
|
|
122
|
-
email: resolved.auth.email ?? null,
|
|
123
|
-
powersync: {
|
|
124
|
-
endpoint: resolved.powersync.endpoint ?? null,
|
|
125
|
-
tokenEndpoint: resolved.powersync.tokenEndpoint ?? null,
|
|
126
|
-
uploadBaseUrl: resolved.powersync.uploadBaseUrl ?? null,
|
|
127
|
-
uploadV4Path: resolved.powersync.uploadV4Path,
|
|
128
|
-
uploadV2Path: resolved.powersync.uploadV2Path,
|
|
129
|
-
},
|
|
45
|
+
const verifiedConfig = mergeAuthIdentityIntoConfig(previousConfig, rawToken, identity);
|
|
46
|
+
const verifiedResolved = resolveConfig(verifiedConfig);
|
|
47
|
+
const { db, dbPath, stale } = await connectPowerSync({
|
|
48
|
+
config: verifiedResolved,
|
|
49
|
+
offline: false,
|
|
50
|
+
timeoutMs,
|
|
51
|
+
});
|
|
52
|
+
try {
|
|
53
|
+
await runSingleSyncPass(db, timeoutMs);
|
|
54
|
+
await saveConfig(verifiedConfig);
|
|
55
|
+
const status = getStatusSnapshot(db);
|
|
56
|
+
const result = {
|
|
57
|
+
ok: true,
|
|
58
|
+
verified: true,
|
|
59
|
+
endpoint: verifiedResolved.powersync.endpoint,
|
|
130
60
|
dbPath,
|
|
61
|
+
stale,
|
|
62
|
+
lastSyncedAt: status.lastSyncedAt,
|
|
63
|
+
userId: identity.userId,
|
|
131
64
|
};
|
|
132
|
-
if (
|
|
133
|
-
|
|
134
|
-
if (jsonOutput) {
|
|
135
|
-
printYaml(payload);
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
console.log(`loggedIn: ${payload.loggedIn ? 'yes' : 'no'}`);
|
|
139
|
-
if (payload.userId) {
|
|
140
|
-
console.log(`userId: ${payload.userId}`);
|
|
141
|
-
}
|
|
142
|
-
console.log(`db: ${payload.dbPath}`);
|
|
143
|
-
console.log(`powersync.endpoint: ${payload.powersync.endpoint ?? '(unset)'}`);
|
|
144
|
-
console.log(`powersync.tokenEndpoint: ${payload.powersync.tokenEndpoint ?? '(unset)'}`);
|
|
145
|
-
console.log(`powersync.uploadBaseUrl: ${payload.powersync.uploadBaseUrl ?? '(unset)'}`);
|
|
146
|
-
}
|
|
65
|
+
if (structuredOutput) {
|
|
66
|
+
printSuccess(result);
|
|
147
67
|
return;
|
|
148
68
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
69
|
+
printHumanReadableLine('Login verified.');
|
|
70
|
+
printHumanReadableLine(`- endpoint: ${result.endpoint}`);
|
|
71
|
+
printHumanReadableLine(`- db: ${result.dbPath}`);
|
|
72
|
+
printHumanReadableLine(`- userId: ${result.userId}`);
|
|
73
|
+
if (result.lastSyncedAt) {
|
|
74
|
+
printHumanReadableLine(`- lastSyncedAt: ${result.lastSyncedAt}`);
|
|
75
|
+
}
|
|
76
|
+
if (stale) {
|
|
77
|
+
printHumanReadableLine('- warning: initial sync timed out; local cache may be stale');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
await db.close().catch(() => undefined);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async function runAuthLogout(context) {
|
|
85
|
+
const options = context.options;
|
|
86
|
+
const config = await loadConfig();
|
|
87
|
+
const currentUserId = config.auth?.userId;
|
|
88
|
+
if (config.auth) {
|
|
89
|
+
config.auth.authorization = undefined;
|
|
90
|
+
config.auth.userId = undefined;
|
|
91
|
+
config.auth.username = undefined;
|
|
92
|
+
config.auth.email = undefined;
|
|
93
|
+
config.auth.userInfoSyncedAt = undefined;
|
|
94
|
+
}
|
|
95
|
+
await saveConfig(config);
|
|
96
|
+
if (options.clearLocalDb) {
|
|
97
|
+
await removeSqliteArtifacts(getPowerSyncDbPath(currentUserId));
|
|
98
|
+
await removeSqliteArtifacts(getLegacyPowerSyncDbPath());
|
|
99
|
+
}
|
|
100
|
+
if (getRequestedStructuredOutputFormat()) {
|
|
101
|
+
printSuccess({
|
|
102
|
+
ok: true,
|
|
103
|
+
loggedOut: true,
|
|
104
|
+
clearedLocalDb: Boolean(options.clearLocalDb),
|
|
153
105
|
});
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async function runAuthStatus(context) {
|
|
109
|
+
const config = await loadConfig();
|
|
110
|
+
const resolved = resolveConfig(config);
|
|
111
|
+
const offline = Boolean(context.globals.offline);
|
|
112
|
+
const structuredOutput = getRequestedStructuredOutputFormat() !== null;
|
|
113
|
+
const timeoutMs = parseSyncTimeoutMs(context.globals.syncTimeout) ?? resolved.sync.timeoutMs;
|
|
114
|
+
const dbPath = getPowerSyncDbPath(resolved.auth.userId);
|
|
115
|
+
const base = {
|
|
116
|
+
loggedIn: Boolean(resolved.auth.authorization),
|
|
117
|
+
authorization: redactAuthorization(resolved.auth.authorization),
|
|
118
|
+
userId: resolved.auth.userId ?? null,
|
|
119
|
+
username: resolved.auth.username ?? null,
|
|
120
|
+
email: resolved.auth.email ?? null,
|
|
121
|
+
powersync: {
|
|
122
|
+
endpoint: resolved.powersync.endpoint ?? null,
|
|
123
|
+
tokenEndpoint: resolved.powersync.tokenEndpoint ?? null,
|
|
124
|
+
uploadBaseUrl: resolved.powersync.uploadBaseUrl ?? null,
|
|
125
|
+
uploadV4Path: resolved.powersync.uploadV4Path,
|
|
126
|
+
uploadV2Path: resolved.powersync.uploadV2Path,
|
|
127
|
+
},
|
|
128
|
+
dbPath,
|
|
129
|
+
};
|
|
130
|
+
if (offline || !resolved.auth.authorization || !resolved.powersync.endpoint || !resolved.powersync.tokenEndpoint) {
|
|
131
|
+
const payload = { ...base, offline: true };
|
|
132
|
+
if (structuredOutput) {
|
|
133
|
+
printSuccess(payload);
|
|
134
|
+
return;
|
|
175
135
|
}
|
|
176
|
-
|
|
177
|
-
|
|
136
|
+
printHumanReadableLine(`loggedIn: ${payload.loggedIn ? 'yes' : 'no'}`);
|
|
137
|
+
if (payload.userId) {
|
|
138
|
+
printHumanReadableLine(`userId: ${payload.userId}`);
|
|
178
139
|
}
|
|
140
|
+
printHumanReadableLine(`db: ${payload.dbPath}`);
|
|
141
|
+
printHumanReadableLine(`powersync.endpoint: ${payload.powersync.endpoint ?? '(unset)'}`);
|
|
142
|
+
printHumanReadableLine(`powersync.tokenEndpoint: ${payload.powersync.tokenEndpoint ?? '(unset)'}`);
|
|
143
|
+
printHumanReadableLine(`powersync.uploadBaseUrl: ${payload.powersync.uploadBaseUrl ?? '(unset)'}`);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const { db, stale } = await connectPowerSync({
|
|
147
|
+
config: resolved,
|
|
148
|
+
offline: false,
|
|
149
|
+
timeoutMs,
|
|
179
150
|
});
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
151
|
+
try {
|
|
152
|
+
const status = getStatusSnapshot(db);
|
|
153
|
+
const payload = { ...base, offline: false, stale, status };
|
|
154
|
+
if (structuredOutput) {
|
|
155
|
+
printSuccess(payload);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
printHumanReadableLine(`loggedIn: ${payload.loggedIn ? 'yes' : 'no'}`);
|
|
159
|
+
if (payload.userId) {
|
|
160
|
+
printHumanReadableLine(`userId: ${payload.userId}`);
|
|
161
|
+
}
|
|
162
|
+
printHumanReadableLine(`db: ${payload.dbPath}`);
|
|
163
|
+
printHumanReadableLine(`connected: ${payload.status.connected ? 'yes' : 'no'}`);
|
|
164
|
+
if (payload.status.lastSyncedAt) {
|
|
165
|
+
printHumanReadableLine(`lastSyncedAt: ${payload.status.lastSyncedAt}`);
|
|
166
|
+
}
|
|
167
|
+
printHumanReadableLine(`dataFlow: downloading=${payload.status.dataFlowStatus.downloading} uploading=${payload.status.dataFlowStatus.uploading}`);
|
|
168
|
+
if (payload.stale) {
|
|
169
|
+
printHumanReadableLine('warning: sync timed out; local cache may be stale');
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
finally {
|
|
173
|
+
await db.close().catch(() => undefined);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
export const authCommandGroup = {
|
|
177
|
+
name: 'auth',
|
|
178
|
+
description: 'Authentication and PowerSync connectivity commands',
|
|
179
|
+
commands: [
|
|
180
|
+
{
|
|
181
|
+
name: 'login',
|
|
182
|
+
description: 'Save login token and verify PowerSync connectivity',
|
|
183
|
+
arguments: [{ syntax: '<token>', description: 'Login token (without Bearer prefix)' }],
|
|
184
|
+
schema: {
|
|
185
|
+
path: 'auth.login',
|
|
186
|
+
risk: 'write',
|
|
187
|
+
auth: 'optional',
|
|
188
|
+
globalOptions: AUTH_LOGIN_GLOBAL_OPTIONS,
|
|
189
|
+
output: {
|
|
190
|
+
type: 'structured',
|
|
191
|
+
summary: 'Login verification result',
|
|
192
|
+
fields: ['verified', 'endpoint', 'dbPath', 'stale', 'lastSyncedAt', 'userId'],
|
|
193
|
+
},
|
|
194
|
+
examples: ['dino auth login "<token>" --format json'],
|
|
195
|
+
},
|
|
196
|
+
action: runAuthLogin,
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
name: 'logout',
|
|
200
|
+
description: 'Clear saved login token and optionally remove the local cache',
|
|
201
|
+
options: [{ flags: '--clear-local-db', description: 'Delete the local PowerSync SQLite database' }],
|
|
202
|
+
schema: {
|
|
203
|
+
path: 'auth.logout',
|
|
204
|
+
risk: 'write',
|
|
205
|
+
auth: 'optional',
|
|
206
|
+
globalOptions: FORMAT_OPTIONS,
|
|
207
|
+
output: {
|
|
208
|
+
type: 'structured',
|
|
209
|
+
summary: 'Logout acknowledgement',
|
|
210
|
+
fields: ['loggedOut', 'clearedLocalDb'],
|
|
211
|
+
},
|
|
212
|
+
examples: ['dino auth logout --format json', 'dino auth logout --clear-local-db --format json'],
|
|
213
|
+
},
|
|
214
|
+
action: runAuthLogout,
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
name: 'status',
|
|
218
|
+
description: 'Show current login, local cache, and sync status',
|
|
219
|
+
schema: {
|
|
220
|
+
path: 'auth.status',
|
|
221
|
+
risk: 'read',
|
|
222
|
+
auth: 'optional',
|
|
223
|
+
globalOptions: AUTH_STATUS_GLOBAL_OPTIONS,
|
|
224
|
+
output: {
|
|
225
|
+
type: 'structured',
|
|
226
|
+
summary: 'Auth and connectivity status envelope',
|
|
227
|
+
fields: ['loggedIn', 'authorization', 'userId', 'username', 'email', 'powersync', 'dbPath', 'offline', 'stale', 'status'],
|
|
228
|
+
},
|
|
229
|
+
examples: ['dino auth status --format json', 'dino auth status --offline --format json'],
|
|
230
|
+
},
|
|
231
|
+
action: runAuthStatus,
|
|
232
|
+
},
|
|
233
|
+
],
|
|
234
|
+
};
|
|
235
|
+
export function registerAuthCommands(program) {
|
|
236
|
+
registerCommandGroup(program, authCommandGroup);
|
|
183
237
|
}
|