@polardbx/pxbaas 0.1.0-beta.2 → 0.1.0-beta.4
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 +116 -13
- package/dist/app/local-index.d.ts +70 -0
- package/dist/app/local-index.d.ts.map +1 -0
- package/dist/app/local-index.js +140 -0
- package/dist/app/local-index.js.map +1 -0
- package/dist/app/preflight.d.ts +24 -1
- package/dist/app/preflight.d.ts.map +1 -1
- package/dist/app/preflight.js +47 -11
- package/dist/app/preflight.js.map +1 -1
- package/dist/app/spec-lint.d.ts.map +1 -1
- package/dist/app/spec-lint.js +16 -0
- package/dist/app/spec-lint.js.map +1 -1
- package/dist/cli/root.d.ts.map +1 -1
- package/dist/cli/root.js +3 -0
- package/dist/cli/root.js.map +1 -1
- package/dist/commands/app/index.d.ts.map +1 -1
- package/dist/commands/app/index.js +428 -44
- package/dist/commands/app/index.js.map +1 -1
- package/dist/commands/completion/index.d.ts.map +1 -1
- package/dist/commands/completion/index.js +5 -1
- package/dist/commands/completion/index.js.map +1 -1
- package/dist/commands/data/index.d.ts +52 -0
- package/dist/commands/data/index.d.ts.map +1 -1
- package/dist/commands/data/index.js +201 -39
- package/dist/commands/data/index.js.map +1 -1
- package/dist/commands/db/index.d.ts +14 -0
- package/dist/commands/db/index.d.ts.map +1 -1
- package/dist/commands/db/index.js +151 -40
- package/dist/commands/db/index.js.map +1 -1
- package/dist/commands/functions/new.d.ts +4 -0
- package/dist/commands/functions/new.d.ts.map +1 -1
- package/dist/commands/functions/new.js +24 -9
- package/dist/commands/functions/new.js.map +1 -1
- package/dist/commands/gen/index.d.ts.map +1 -1
- package/dist/commands/gen/index.js +13 -10
- package/dist/commands/gen/index.js.map +1 -1
- package/dist/commands/login/index.d.ts.map +1 -1
- package/dist/commands/login/index.js +15 -30
- package/dist/commands/login/index.js.map +1 -1
- package/dist/commands/profile/import-env.d.ts +7 -2
- package/dist/commands/profile/import-env.d.ts.map +1 -1
- package/dist/commands/profile/import-env.js +141 -16
- package/dist/commands/profile/import-env.js.map +1 -1
- package/dist/commands/profile/index.d.ts.map +1 -1
- package/dist/commands/profile/index.js +13 -1
- package/dist/commands/profile/index.js.map +1 -1
- package/dist/commands/storage/index.d.ts.map +1 -1
- package/dist/commands/storage/index.js +209 -7
- package/dist/commands/storage/index.js.map +1 -1
- package/dist/commands/tenant/index.d.ts +19 -0
- package/dist/commands/tenant/index.d.ts.map +1 -0
- package/dist/commands/tenant/index.js +662 -0
- package/dist/commands/tenant/index.js.map +1 -0
- package/dist/commands/whoami/index.js +19 -0
- package/dist/commands/whoami/index.js.map +1 -1
- package/dist/credentials/credential-store.d.ts +30 -1
- package/dist/credentials/credential-store.d.ts.map +1 -1
- package/dist/credentials/credential-store.js +114 -12
- package/dist/credentials/credential-store.js.map +1 -1
- package/dist/credentials/env-file.d.ts +48 -7
- package/dist/credentials/env-file.d.ts.map +1 -1
- package/dist/credentials/env-file.js +91 -16
- package/dist/credentials/env-file.js.map +1 -1
- package/dist/credentials/jwt-introspect.d.ts +7 -0
- package/dist/credentials/jwt-introspect.d.ts.map +1 -1
- package/dist/credentials/jwt-introspect.js.map +1 -1
- package/dist/credentials/masker.d.ts +3 -0
- package/dist/credentials/masker.d.ts.map +1 -1
- package/dist/credentials/masker.js +3 -0
- package/dist/credentials/masker.js.map +1 -1
- package/dist/credentials/profile.d.ts +12 -0
- package/dist/credentials/profile.d.ts.map +1 -1
- package/dist/credentials/profile.js +23 -0
- package/dist/credentials/profile.js.map +1 -1
- package/dist/credentials/tty-guard.d.ts +10 -0
- package/dist/credentials/tty-guard.d.ts.map +1 -1
- package/dist/credentials/tty-guard.js +32 -0
- package/dist/credentials/tty-guard.js.map +1 -1
- package/dist/db/introspect.d.ts +54 -0
- package/dist/db/introspect.d.ts.map +1 -0
- package/dist/db/introspect.js +140 -0
- package/dist/db/introspect.js.map +1 -0
- package/dist/main.js +21 -2
- package/dist/main.js.map +1 -1
- package/dist/tenant/bundle.d.ts +66 -0
- package/dist/tenant/bundle.d.ts.map +1 -0
- package/dist/tenant/bundle.js +132 -0
- package/dist/tenant/bundle.js.map +1 -0
- package/dist/tenant/guide.d.ts +50 -0
- package/dist/tenant/guide.d.ts.map +1 -0
- package/dist/tenant/guide.js +152 -0
- package/dist/tenant/guide.js.map +1 -0
- package/dist/tenant/probe.d.ts +65 -0
- package/dist/tenant/probe.d.ts.map +1 -0
- package/dist/tenant/probe.js +159 -0
- package/dist/tenant/probe.js.map +1 -0
- package/dist/tenant/verify.d.ts +37 -0
- package/dist/tenant/verify.d.ts.map +1 -0
- package/dist/tenant/verify.js +132 -0
- package/dist/tenant/verify.js.map +1 -0
- package/dist/version.d.ts +29 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +65 -0
- package/dist/version.js.map +1 -0
- package/package.json +2 -2
- package/skills/pxbaas-app-spec/references/runtime-contract.md +2 -2
- package/skills/pxbaas-cli/SKILL.md +14 -5
- package/skills/pxbaas-cli/references/auth-and-credentials.md +19 -3
- package/skills/pxbaas-cli/references/data-postgrest.md +19 -3
- package/skills/pxbaas-cli/references/db-and-meta.md +5 -0
- package/skills/pxbaas-cli/references/safety-and-two-phase.md +42 -13
- package/skills/pxbaas-cli/references/tenant-admin.md +122 -0
- package/skills/pxbaas-cli/references/troubleshooting.md +4 -1
- package/templates/webapp/react-vite-hono/backend/index.ts +21 -4
- package/templates/webapp/ssr-hono/backend/index.ts +50 -31
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
|
-
import
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import { CredentialStore, ProfileManager, formatSuccess, formatError, formatWarning, } from '../../credentials/index.js';
|
|
4
|
+
/** Rows fetched by the read-only preview; the count itself comes from Content-Range. */
|
|
5
|
+
const DELETE_PREVIEW_LIMIT = 1000;
|
|
6
|
+
/**
|
|
7
|
+
* Failure of the delete gate (missing filter, or execution not authorized).
|
|
8
|
+
*
|
|
9
|
+
* Carries the preview so `--json` callers still get the audit trail of what was
|
|
10
|
+
* NOT deleted — the whole point of the two-phase flow.
|
|
11
|
+
*/
|
|
12
|
+
export class DataDeleteError extends Error {
|
|
13
|
+
code;
|
|
14
|
+
preview;
|
|
15
|
+
constructor(code, message, preview) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.code = code;
|
|
18
|
+
this.preview = preview;
|
|
19
|
+
this.name = 'DataDeleteError';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
3
22
|
export function registerDataCommands(program) {
|
|
4
23
|
const dataCmd = program
|
|
5
24
|
.command('data')
|
|
@@ -60,20 +79,196 @@ export function registerDataCommands(program) {
|
|
|
60
79
|
// data delete
|
|
61
80
|
dataCmd
|
|
62
81
|
.command('delete <table>')
|
|
63
|
-
.description('Delete rows from table (
|
|
64
|
-
.requiredOption('--filter <filter>', 'PostgREST
|
|
82
|
+
.description('Delete rows from table. Previews the affected row count and the exact request URL, then requires confirmation (--yes to authorize non-interactively)')
|
|
83
|
+
.requiredOption('--filter <filter>', 'PostgREST condition passed through verbatim; repeat to combine (e.g. --filter "id=eq.1" --filter "or=(a.eq.1,b.eq.2)"). Required: without it every row would be deleted', collectFilter)
|
|
84
|
+
.option('--yes', 'Authorize non-interactively (skip the confirm prompt)')
|
|
65
85
|
.option('--json', 'Output in JSON format')
|
|
66
86
|
.action(async (table, options) => {
|
|
87
|
+
const json = Boolean(options.json || program.opts().json);
|
|
67
88
|
try {
|
|
68
|
-
await handleDataDelete(table, { ...options, json
|
|
89
|
+
await handleDataDelete(table, { ...options, json });
|
|
69
90
|
}
|
|
70
91
|
catch (error) {
|
|
71
|
-
|
|
72
|
-
|
|
92
|
+
// Keep the preview in the machine-readable payload: an audit consumer must
|
|
93
|
+
// be able to tell what was refused, not just that something was.
|
|
94
|
+
if (json && error instanceof DataDeleteError) {
|
|
95
|
+
console.log(JSON.stringify({
|
|
96
|
+
code: error.code,
|
|
97
|
+
message: error.message,
|
|
98
|
+
...(error.preview ? { preview: error.preview } : {}),
|
|
99
|
+
}, null, 2));
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
103
|
+
console.error(formatError(message));
|
|
104
|
+
}
|
|
73
105
|
process.exit(1);
|
|
74
106
|
}
|
|
75
107
|
});
|
|
76
108
|
}
|
|
109
|
+
/** Accumulate repeated `--filter` flags instead of letting the last one win. */
|
|
110
|
+
function collectFilter(value, previous) {
|
|
111
|
+
return [...(previous ?? []), value];
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Normalize the `--filter` flags into the PostgREST query string, verbatim.
|
|
115
|
+
*
|
|
116
|
+
* The previous implementation did `filter.split('=')` and rebuilt ONE key/value
|
|
117
|
+
* pair, so a condition containing `&` (e.g. `id=eq.1&name=like.a%`) had
|
|
118
|
+
* everything after the first `&` percent-encoded INTO the value: the extra
|
|
119
|
+
* condition silently disappeared and the DELETE matched strictly more rows than
|
|
120
|
+
* the operator asked for. Filters are therefore split on `&` only, each fragment
|
|
121
|
+
* is validated to be a `column=operator.value` pair, and nothing is re-encoded.
|
|
122
|
+
*
|
|
123
|
+
* An empty/absent filter is a hard error — it would delete the whole table. A
|
|
124
|
+
* blank fragment is an error too rather than something to skip: `--filter "$VAR"`
|
|
125
|
+
* with an unset VAR must fail loudly, not silently narrow to the other flags.
|
|
126
|
+
*/
|
|
127
|
+
export function normalizeDeleteFilters(raw) {
|
|
128
|
+
const given = typeof raw === 'string' ? [raw] : raw ?? [];
|
|
129
|
+
const parts = [];
|
|
130
|
+
for (const item of given) {
|
|
131
|
+
const value = String(item ?? '');
|
|
132
|
+
if (!value.trim()) {
|
|
133
|
+
throw new DataDeleteError('DATA_DELETE_FILTER_INVALID', 'Empty --filter value. Expected a PostgREST condition such as "id=eq.1"; ' +
|
|
134
|
+
'an empty filter would delete the whole table.');
|
|
135
|
+
}
|
|
136
|
+
for (const condition of value.split('&')) {
|
|
137
|
+
const trimmed = condition.trim();
|
|
138
|
+
if (!trimmed || trimmed.indexOf('=') <= 0) {
|
|
139
|
+
throw new DataDeleteError('DATA_DELETE_FILTER_INVALID', `Invalid --filter '${trimmed || value}'. Expected a PostgREST condition such as ` +
|
|
140
|
+
'"id=eq.1", "created_at=lt.2026-01-01" or "or=(a.eq.1,b.eq.2)".');
|
|
141
|
+
}
|
|
142
|
+
parts.push(trimmed);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (parts.length === 0) {
|
|
146
|
+
throw new DataDeleteError('DATA_DELETE_FILTER_REQUIRED', 'Refusing to delete without a filter: that would delete EVERY row of the table. ' +
|
|
147
|
+
'Pass at least one --filter "column=operator.value" (repeatable), e.g. --filter "id=eq.1".');
|
|
148
|
+
}
|
|
149
|
+
return parts;
|
|
150
|
+
}
|
|
151
|
+
/** Total row count from a PostgREST `Content-Range: 0-9/42` header; null when unknown. */
|
|
152
|
+
function parseContentRangeTotal(header) {
|
|
153
|
+
if (typeof header !== 'string' || header === '')
|
|
154
|
+
return null;
|
|
155
|
+
const total = header.split('/')[1]?.trim();
|
|
156
|
+
if (!total || total === '*')
|
|
157
|
+
return null;
|
|
158
|
+
const parsed = Number(total);
|
|
159
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Decide whether the DELETE is authorized. Same contract as `db push --yes`
|
|
163
|
+
* (src/db/apply-schema.ts authorize): `--yes` authorizes outright; `--json` and
|
|
164
|
+
* non-TTY sessions cannot prompt, so they require `--yes` explicitly.
|
|
165
|
+
*/
|
|
166
|
+
async function authorizeDelete(preview, options) {
|
|
167
|
+
if (options.yes)
|
|
168
|
+
return;
|
|
169
|
+
if (options.json) {
|
|
170
|
+
throw new DataDeleteError('DATA_DELETE_NOT_AUTHORIZED', 'Refusing to delete rows in --json mode without explicit authorization. ' +
|
|
171
|
+
'Re-run with --yes to apply. Nothing was deleted.', preview);
|
|
172
|
+
}
|
|
173
|
+
if (!process.stdin.isTTY) {
|
|
174
|
+
throw new DataDeleteError('DATA_DELETE_NOT_AUTHORIZED', 'Refusing to delete rows without explicit authorization: pass --yes for ' +
|
|
175
|
+
'non-interactive use, or run in a TTY to confirm. Nothing was deleted.', preview);
|
|
176
|
+
}
|
|
177
|
+
const described = preview.rowCount === null
|
|
178
|
+
? 'an unknown number of row(s)'
|
|
179
|
+
: preview.countExact
|
|
180
|
+
? `${preview.rowCount} row(s)`
|
|
181
|
+
: `at least ${preview.rowCount} row(s)`;
|
|
182
|
+
const { ok } = await inquirer.prompt([
|
|
183
|
+
{
|
|
184
|
+
type: 'confirm',
|
|
185
|
+
name: 'ok',
|
|
186
|
+
message: `Delete ${described} from '${preview.table}' (filter: ${preview.filters.join(' & ')})? This cannot be undone`,
|
|
187
|
+
default: false,
|
|
188
|
+
},
|
|
189
|
+
]);
|
|
190
|
+
if (!ok) {
|
|
191
|
+
throw new DataDeleteError('DATA_DELETE_CANCELLED', `Cancelled by operator; nothing was deleted from '${preview.table}'.`, preview);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
function printPreview(preview) {
|
|
195
|
+
const described = preview.rowCount === null
|
|
196
|
+
? 'an unknown number of row(s)'
|
|
197
|
+
: preview.countExact
|
|
198
|
+
? `${preview.rowCount} row(s)`
|
|
199
|
+
: `at least ${preview.rowCount} row(s)`;
|
|
200
|
+
console.log(formatWarning(`Preview: will delete ${described} from '${preview.table}'`));
|
|
201
|
+
console.log(` Filter: ${preview.filters.join(' & ')}`);
|
|
202
|
+
console.log(` Request: DELETE ${preview.url}`);
|
|
203
|
+
if (preview.previewError) {
|
|
204
|
+
console.log(` Note: the read-only count failed (${preview.previewError}); the delete is still gated.`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
export async function handleDataDelete(table, options) {
|
|
208
|
+
// Get current profile
|
|
209
|
+
const profileManager = new ProfileManager();
|
|
210
|
+
const currentProfile = await profileManager.getCurrentProfile();
|
|
211
|
+
if (!currentProfile) {
|
|
212
|
+
throw new Error('No active profile. Use "pxbaas login" to authenticate first.');
|
|
213
|
+
}
|
|
214
|
+
// Get credentials
|
|
215
|
+
const credentialStore = new CredentialStore();
|
|
216
|
+
const credentials = await credentialStore.getCredentials(currentProfile.name);
|
|
217
|
+
if (!credentials) {
|
|
218
|
+
throw new Error(`No credentials found for profile: ${currentProfile.name}. Use "pxbaas login" to authenticate.`);
|
|
219
|
+
}
|
|
220
|
+
const filters = normalizeDeleteFilters(options.filter);
|
|
221
|
+
const query = filters.join('&');
|
|
222
|
+
const url = `${currentProfile.endpoint}/rest/v1/${table}?${query}`;
|
|
223
|
+
const headers = {
|
|
224
|
+
'apikey': credentials.anonKey,
|
|
225
|
+
'Authorization': `Bearer ${credentials.anonKey}`,
|
|
226
|
+
};
|
|
227
|
+
// Phase 1: read-only preview against the SAME filter, so the operator sees the
|
|
228
|
+
// blast radius before anything is destroyed. A failing count (e.g. RLS allows
|
|
229
|
+
// DELETE but not SELECT) degrades to "unknown" instead of skipping the gate.
|
|
230
|
+
const preview = {
|
|
231
|
+
table,
|
|
232
|
+
filters,
|
|
233
|
+
rowCount: null,
|
|
234
|
+
countExact: false,
|
|
235
|
+
url,
|
|
236
|
+
};
|
|
237
|
+
try {
|
|
238
|
+
const probe = await axios.get(`${currentProfile.endpoint}/rest/v1/${table}?select=*&limit=${DELETE_PREVIEW_LIMIT}&${query}`, { headers: { ...headers, 'Prefer': 'count=exact' } });
|
|
239
|
+
const fromRange = parseContentRangeTotal(probe.headers?.['content-range']);
|
|
240
|
+
if (fromRange !== null) {
|
|
241
|
+
preview.rowCount = fromRange;
|
|
242
|
+
preview.countExact = true;
|
|
243
|
+
}
|
|
244
|
+
else if (Array.isArray(probe.data)) {
|
|
245
|
+
preview.rowCount = probe.data.length;
|
|
246
|
+
preview.countExact = probe.data.length < DELETE_PREVIEW_LIMIT;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
catch (error) {
|
|
250
|
+
preview.previewError = error instanceof Error ? error.message : String(error);
|
|
251
|
+
}
|
|
252
|
+
if (!options.json)
|
|
253
|
+
printPreview(preview);
|
|
254
|
+
// Phase 2: explicit authorization (--yes, or an interactive confirm).
|
|
255
|
+
await authorizeDelete(preview, options);
|
|
256
|
+
const response = await axios.delete(url, {
|
|
257
|
+
headers: { ...headers, 'Prefer': 'return=representation' },
|
|
258
|
+
});
|
|
259
|
+
const rows = Array.isArray(response.data) ? response.data : [];
|
|
260
|
+
const result = {
|
|
261
|
+
preview,
|
|
262
|
+
deleted: { table, count: rows.length, url },
|
|
263
|
+
};
|
|
264
|
+
if (options.json) {
|
|
265
|
+
console.log(JSON.stringify(result, null, 2));
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
console.log(formatSuccess(`Deleted ${rows.length} row(s) from '${table}'`));
|
|
269
|
+
}
|
|
270
|
+
return result;
|
|
271
|
+
}
|
|
77
272
|
async function handleDataSelect(table, options) {
|
|
78
273
|
// Get current profile
|
|
79
274
|
const profileManager = new ProfileManager();
|
|
@@ -209,37 +404,4 @@ async function handleDataUpdate(table, options) {
|
|
|
209
404
|
console.log(formatSuccess(`Updated ${rows.length} row(s) in ${table}`));
|
|
210
405
|
}
|
|
211
406
|
}
|
|
212
|
-
async function handleDataDelete(table, options) {
|
|
213
|
-
// Get current profile
|
|
214
|
-
const profileManager = new ProfileManager();
|
|
215
|
-
const currentProfile = await profileManager.getCurrentProfile();
|
|
216
|
-
if (!currentProfile) {
|
|
217
|
-
throw new Error('No active profile. Use "pxbaas login" to authenticate first.');
|
|
218
|
-
}
|
|
219
|
-
// Get credentials
|
|
220
|
-
const credentialStore = new CredentialStore();
|
|
221
|
-
const credentials = await credentialStore.getCredentials(currentProfile.name);
|
|
222
|
-
if (!credentials) {
|
|
223
|
-
throw new Error(`No credentials found for profile: ${currentProfile.name}. Use "pxbaas login" to authenticate.`);
|
|
224
|
-
}
|
|
225
|
-
// Build query URL with filter
|
|
226
|
-
const params = new URLSearchParams();
|
|
227
|
-
params.append(options.filter.split('=')[0], options.filter.split('=').slice(1).join('='));
|
|
228
|
-
const url = `${currentProfile.endpoint}/rest/v1/${table}?${params.toString()}`;
|
|
229
|
-
// Make request
|
|
230
|
-
const response = await axios.delete(url, {
|
|
231
|
-
headers: {
|
|
232
|
-
'apikey': credentials.anonKey,
|
|
233
|
-
'Authorization': `Bearer ${credentials.anonKey}`,
|
|
234
|
-
'Prefer': 'return=representation',
|
|
235
|
-
},
|
|
236
|
-
});
|
|
237
|
-
if (options.json) {
|
|
238
|
-
console.log(JSON.stringify(response.data, null, 2));
|
|
239
|
-
}
|
|
240
|
-
else {
|
|
241
|
-
const rows = response.data;
|
|
242
|
-
console.log(formatSuccess(`Deleted ${rows.length} row(s) from ${table}`));
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
407
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/data/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/data/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,20 @@ export declare function handleDbQuery(sql: string, options: {
|
|
|
4
4
|
role: string;
|
|
5
5
|
json?: boolean;
|
|
6
6
|
}, program: Command): Promise<void>;
|
|
7
|
+
export declare function handleDbCreateTable(name: string, options: {
|
|
8
|
+
columns?: string;
|
|
9
|
+
schema?: string;
|
|
10
|
+
role: string;
|
|
11
|
+
json?: boolean;
|
|
12
|
+
}, program: Command): Promise<void>;
|
|
13
|
+
export declare function handleDbAddColumn(table: string, column: string, options: {
|
|
14
|
+
type: string;
|
|
15
|
+
nullable: boolean;
|
|
16
|
+
default?: string;
|
|
17
|
+
schema?: string;
|
|
18
|
+
role: string;
|
|
19
|
+
json?: boolean;
|
|
20
|
+
}, program: Command): Promise<void>;
|
|
7
21
|
export declare function handleDbPush(file: string, options: {
|
|
8
22
|
schema: string;
|
|
9
23
|
rls?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/db/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/db/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqBpC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA8HzD;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,EACzC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,IAAI,CAAC,CAoEf;AAiOD,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,EAC5E,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,IAAI,CAAC,CAmEf;AAED,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE;IACP,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,EACD,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,IAAI,CAAC,CAgDf;AAED,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;IACP,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,EACD,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,IAAI,CAAC,CAsDf"}
|
|
@@ -3,6 +3,7 @@ import { existsSync } from 'node:fs';
|
|
|
3
3
|
import { MetaDriver, TenantDdlDriver } from '@polardbx/pxbaas-client';
|
|
4
4
|
import { CredentialStore, ProfileManager, formatSuccess, formatError, formatWarning, } from '../../credentials/index.js';
|
|
5
5
|
import { applySchema, getSchemaSink, } from '../../db/apply-schema.js';
|
|
6
|
+
import { makeIntrospector } from '../../db/introspect.js';
|
|
6
7
|
import { parseRlsJson } from '../../db/sql-file.js';
|
|
7
8
|
export function registerDbCommands(program) {
|
|
8
9
|
const db = program
|
|
@@ -57,9 +58,9 @@ export function registerDbCommands(program) {
|
|
|
57
58
|
});
|
|
58
59
|
db
|
|
59
60
|
.command('create-table <name>')
|
|
60
|
-
.description('Create a new table (requires service_role,
|
|
61
|
+
.description('Create a new table (requires service_role; executes immediately, no confirmation prompt)')
|
|
61
62
|
.option('--columns <json>', 'Column definitions (JSON array)')
|
|
62
|
-
.option('--schema <schema>', 'Schema name
|
|
63
|
+
.option('--schema <schema>', 'Schema name (single-tenant only; multi-tenant always targets the tenant database)')
|
|
63
64
|
.option('--role <role>', 'Role to use (anon or service_role)', 'service_role')
|
|
64
65
|
.option('--json', 'Output in JSON format')
|
|
65
66
|
.action(async (name, options) => {
|
|
@@ -74,11 +75,11 @@ export function registerDbCommands(program) {
|
|
|
74
75
|
});
|
|
75
76
|
db
|
|
76
77
|
.command('add-column <table> <column>')
|
|
77
|
-
.description('Add a column to a table (requires service_role,
|
|
78
|
+
.description('Add a column to a table (requires service_role; executes immediately, no confirmation prompt)')
|
|
78
79
|
.option('--type <type>', 'Column data type', 'text')
|
|
79
80
|
.option('--nullable', 'Allow NULL values', true)
|
|
80
81
|
.option('--default <value>', 'Default value')
|
|
81
|
-
.option('--schema <schema>', 'Schema name
|
|
82
|
+
.option('--schema <schema>', 'Schema name (single-tenant only; multi-tenant always targets the tenant database)')
|
|
82
83
|
.option('--role <role>', 'Role to use (anon or service_role)', 'service_role')
|
|
83
84
|
.option('--json', 'Output in JSON format')
|
|
84
85
|
.action(async (table, column, options) => {
|
|
@@ -188,24 +189,29 @@ async function handleDbTables(options, program) {
|
|
|
188
189
|
throw new Error(`No credentials found for profile: ${currentProfile.name}. Use "pxbaas login" to authenticate.`);
|
|
189
190
|
}
|
|
190
191
|
const useServiceRole = options.role === 'service_role';
|
|
191
|
-
|
|
192
|
+
// C1 fix: introspect via the mode-appropriate backend. In multi-tenant the
|
|
193
|
+
// Meta API (/pg/*) rejects per-tenant keys with 401, so route through
|
|
194
|
+
// tenant-ddl (information_schema) — the same channel `db query` already uses.
|
|
195
|
+
const introspector = makeIntrospector({
|
|
196
|
+
mode: currentProfile.mode,
|
|
192
197
|
endpoint: currentProfile.endpoint,
|
|
193
198
|
anonKey: credentials.anonKey,
|
|
194
199
|
serviceRoleKey: credentials.serviceRoleKey,
|
|
195
200
|
tenantId: currentProfile.tenantId,
|
|
201
|
+
schema: options.schema,
|
|
202
|
+
useServiceRole,
|
|
196
203
|
});
|
|
197
|
-
const
|
|
198
|
-
|
|
199
|
-
const tables = allTables.filter(t => t.schema === options.schema);
|
|
204
|
+
const tables = await introspector.listTables();
|
|
205
|
+
const schemaLabel = await introspector.currentSchema();
|
|
200
206
|
if (options.json || program.opts().json) {
|
|
201
|
-
console.log(JSON.stringify({ schema:
|
|
207
|
+
console.log(JSON.stringify({ schema: schemaLabel, tables }, null, 2));
|
|
202
208
|
}
|
|
203
209
|
else {
|
|
204
210
|
if (tables.length === 0) {
|
|
205
|
-
console.log(`No tables found in schema "${
|
|
211
|
+
console.log(`No tables found in schema "${schemaLabel}".`);
|
|
206
212
|
}
|
|
207
213
|
else {
|
|
208
|
-
console.log(formatSuccess(`Found ${tables.length} table(s) in schema "${
|
|
214
|
+
console.log(formatSuccess(`Found ${tables.length} table(s) in schema "${schemaLabel}":`));
|
|
209
215
|
console.log('');
|
|
210
216
|
for (const table of tables) {
|
|
211
217
|
console.log(` ${table.name}`);
|
|
@@ -225,21 +231,26 @@ async function handleDbSchema(table, options, program) {
|
|
|
225
231
|
throw new Error(`No credentials found for profile: ${currentProfile.name}. Use "pxbaas login" to authenticate.`);
|
|
226
232
|
}
|
|
227
233
|
const useServiceRole = options.role === 'service_role';
|
|
228
|
-
|
|
234
|
+
// C1 fix: same mode-aware introspection as `db tables` (multi-tenant -> tenant-ddl).
|
|
235
|
+
const introspector = makeIntrospector({
|
|
236
|
+
mode: currentProfile.mode,
|
|
229
237
|
endpoint: currentProfile.endpoint,
|
|
230
238
|
anonKey: credentials.anonKey,
|
|
231
239
|
serviceRoleKey: credentials.serviceRoleKey,
|
|
232
240
|
tenantId: currentProfile.tenantId,
|
|
241
|
+
schema: options.schema,
|
|
242
|
+
useServiceRole,
|
|
233
243
|
});
|
|
244
|
+
const schemaLabel = await introspector.currentSchema();
|
|
234
245
|
const [columns, indexes] = await Promise.all([
|
|
235
|
-
|
|
236
|
-
|
|
246
|
+
introspector.getColumns(table),
|
|
247
|
+
introspector.getIndexes(table),
|
|
237
248
|
]);
|
|
238
249
|
if (options.json || program.opts().json) {
|
|
239
|
-
console.log(JSON.stringify({ table, schema:
|
|
250
|
+
console.log(JSON.stringify({ table, schema: schemaLabel, columns, indexes }, null, 2));
|
|
240
251
|
}
|
|
241
252
|
else {
|
|
242
|
-
console.log(formatSuccess(`Schema for table "${
|
|
253
|
+
console.log(formatSuccess(`Schema for table "${schemaLabel}.${table}"`));
|
|
243
254
|
console.log('\nColumns:');
|
|
244
255
|
console.log('Name\tType\tNullable\tDefault\tPrimary Key\tComment');
|
|
245
256
|
console.log('---\t---\t---\t---\t---\t---');
|
|
@@ -263,7 +274,86 @@ async function handleDbSchema(table, options, program) {
|
|
|
263
274
|
}
|
|
264
275
|
}
|
|
265
276
|
}
|
|
266
|
-
|
|
277
|
+
/** Same actionable error as `handleDbQuery` for a malformed multi-tenant profile. */
|
|
278
|
+
function assertTenantId(profile) {
|
|
279
|
+
if (!profile.tenantId) {
|
|
280
|
+
throw new Error('Multi-tenant profile is missing tenantId; re-run "pxbaas login --tenant-id <id>" with per-tenant keys.');
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* D1 fix: run one DDL statement through the channel the profile can actually
|
|
285
|
+
* authenticate on. Mirrors the mode dispatch of `handleDbQuery`: in
|
|
286
|
+
* multi-tenant the Meta API (/pg/*) only accepts the platform global
|
|
287
|
+
* service_role key (per-tenant keys get 401), so tenant DDL must go through
|
|
288
|
+
* /api/tenant-ddl with the per-tenant service_role key.
|
|
289
|
+
*/
|
|
290
|
+
async function runDdl(profile, credentials, sql, options) {
|
|
291
|
+
const useServiceRole = options.role === 'service_role';
|
|
292
|
+
if (profile.mode === 'multi-tenant') {
|
|
293
|
+
assertTenantId(profile);
|
|
294
|
+
// tenant-ddl role-gates on service_role, so --role anon is not applicable
|
|
295
|
+
// and the statement always runs as the tenant's service_role.
|
|
296
|
+
if (!useServiceRole) {
|
|
297
|
+
console.error(formatWarning(`${options.command} in multi-tenant mode always runs as the tenant service_role (tenant-ddl ignores --role anon).`));
|
|
298
|
+
}
|
|
299
|
+
const tenantDriver = new TenantDdlDriver({
|
|
300
|
+
endpoint: profile.endpoint,
|
|
301
|
+
serviceRoleKey: credentials.serviceRoleKey,
|
|
302
|
+
});
|
|
303
|
+
const rows = (await tenantDriver.query(sql));
|
|
304
|
+
return { rows, rowCount: rows.length };
|
|
305
|
+
}
|
|
306
|
+
const metaDriver = new MetaDriver({
|
|
307
|
+
endpoint: profile.endpoint,
|
|
308
|
+
anonKey: credentials.anonKey,
|
|
309
|
+
serviceRoleKey: credentials.serviceRoleKey,
|
|
310
|
+
tenantId: profile.tenantId,
|
|
311
|
+
});
|
|
312
|
+
return metaDriver.query(sql, useServiceRole);
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* D3 / 06-§3 fix: the REAL target database name in multi-tenant mode, via the
|
|
316
|
+
* same route `db tables` uses (tenant-ddl `SELECT DATABASE()`). Falls back to
|
|
317
|
+
* the platform's `tenant_<id>` naming convention so a failed read-only probe
|
|
318
|
+
* never hard-fails an otherwise successful DDL.
|
|
319
|
+
*/
|
|
320
|
+
async function resolveTenantSchemaLabel(profile, credentials) {
|
|
321
|
+
assertTenantId(profile);
|
|
322
|
+
try {
|
|
323
|
+
const introspector = makeIntrospector({
|
|
324
|
+
mode: profile.mode,
|
|
325
|
+
endpoint: profile.endpoint,
|
|
326
|
+
anonKey: credentials.anonKey,
|
|
327
|
+
serviceRoleKey: credentials.serviceRoleKey,
|
|
328
|
+
tenantId: profile.tenantId,
|
|
329
|
+
});
|
|
330
|
+
const label = await introspector.currentSchema();
|
|
331
|
+
if (label)
|
|
332
|
+
return label;
|
|
333
|
+
}
|
|
334
|
+
catch {
|
|
335
|
+
// fall through to the convention-based label
|
|
336
|
+
}
|
|
337
|
+
return `tenant_${profile.tenantId}`;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* D2/D3 fix: resolve the schema a DDL command actually targets. Multi-tenant
|
|
341
|
+
* DDL always lands in the tenant's own database, so report that real name and
|
|
342
|
+
* warn when the user explicitly asked for a different --schema (instead of
|
|
343
|
+
* silently dropping the input). Single-tenant keeps the requested value with
|
|
344
|
+
* the historical `public` default.
|
|
345
|
+
*/
|
|
346
|
+
async function resolveDdlSchema(profile, credentials, requestedSchema) {
|
|
347
|
+
if (profile.mode !== 'multi-tenant') {
|
|
348
|
+
return requestedSchema ?? 'public';
|
|
349
|
+
}
|
|
350
|
+
const effective = await resolveTenantSchemaLabel(profile, credentials);
|
|
351
|
+
if (requestedSchema && requestedSchema !== effective) {
|
|
352
|
+
console.error(formatWarning(`--schema is ignored in multi-tenant mode: DDL always targets the tenant database "${effective}" (requested "${requestedSchema}").`));
|
|
353
|
+
}
|
|
354
|
+
return effective;
|
|
355
|
+
}
|
|
356
|
+
export async function handleDbCreateTable(name, options, program) {
|
|
267
357
|
const profileManager = new ProfileManager();
|
|
268
358
|
const currentProfile = await profileManager.getCurrentProfile();
|
|
269
359
|
if (!currentProfile) {
|
|
@@ -291,6 +381,9 @@ async function handleDbCreateTable(name, options, program) {
|
|
|
291
381
|
{ name: 'created_at', type: 'timestamp', nullable: false },
|
|
292
382
|
];
|
|
293
383
|
}
|
|
384
|
+
// D2/D3 fix: the effective target schema (tenant db in multi-tenant).
|
|
385
|
+
const effectiveSchema = await resolveDdlSchema(currentProfile, credentials, options.schema);
|
|
386
|
+
const isMultiTenant = currentProfile.mode === 'multi-tenant';
|
|
294
387
|
// Build SQL
|
|
295
388
|
const columnSql = columnDefs.map(col => {
|
|
296
389
|
let sql = `${col.name} ${col.type}`;
|
|
@@ -300,24 +393,26 @@ async function handleDbCreateTable(name, options, program) {
|
|
|
300
393
|
sql += ' NOT NULL';
|
|
301
394
|
return sql;
|
|
302
395
|
}).join(', ');
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
396
|
+
// Multi-tenant: NO schema qualifier — the tenant-ddl connection is bound to
|
|
397
|
+
// the tenant's own database and a `public.` prefix would be rejected (or
|
|
398
|
+
// would write into the shared public db). Single-tenant shape is unchanged.
|
|
399
|
+
const sql = isMultiTenant
|
|
400
|
+
? `CREATE TABLE \`${name}\` (${columnSql})`
|
|
401
|
+
: `CREATE TABLE ${effectiveSchema}.${name} (${columnSql})`;
|
|
402
|
+
const result = await runDdl(currentProfile, credentials, sql, {
|
|
403
|
+
role: options.role,
|
|
404
|
+
command: 'db create-table',
|
|
310
405
|
});
|
|
311
|
-
const result = await metaDriver.query(sql, useServiceRole);
|
|
312
406
|
if (options.json || program.opts().json) {
|
|
313
|
-
console.log(JSON.stringify({ table: name, schema:
|
|
407
|
+
console.log(JSON.stringify({ table: name, schema: effectiveSchema, sql, result }, null, 2));
|
|
314
408
|
}
|
|
315
409
|
else {
|
|
316
|
-
console.log(formatSuccess(`Created table "${
|
|
410
|
+
console.log(formatSuccess(`Created table "${effectiveSchema}.${name}"`));
|
|
317
411
|
console.log(` SQL: ${sql}`);
|
|
412
|
+
console.log(formatWarning(' Note: the REST schema cache re-introspects after DDL; the new table is visible to /rest/v1 within a few seconds.'));
|
|
318
413
|
}
|
|
319
414
|
}
|
|
320
|
-
async function handleDbAddColumn(table, column, options, program) {
|
|
415
|
+
export async function handleDbAddColumn(table, column, options, program) {
|
|
321
416
|
const profileManager = new ProfileManager();
|
|
322
417
|
const currentProfile = await profileManager.getCurrentProfile();
|
|
323
418
|
if (!currentProfile) {
|
|
@@ -328,28 +423,30 @@ async function handleDbAddColumn(table, column, options, program) {
|
|
|
328
423
|
if (!credentials) {
|
|
329
424
|
throw new Error(`No credentials found for profile: ${currentProfile.name}. Use "pxbaas login" to authenticate.`);
|
|
330
425
|
}
|
|
331
|
-
//
|
|
332
|
-
|
|
426
|
+
// D2/D3 fix: the effective target schema (tenant db in multi-tenant).
|
|
427
|
+
const effectiveSchema = await resolveDdlSchema(currentProfile, credentials, options.schema);
|
|
428
|
+
const isMultiTenant = currentProfile.mode === 'multi-tenant';
|
|
429
|
+
// Build SQL. Multi-tenant: NO schema qualifier (see handleDbCreateTable).
|
|
430
|
+
let sql = isMultiTenant
|
|
431
|
+
? `ALTER TABLE \`${table}\` ADD COLUMN ${column} ${options.type}`
|
|
432
|
+
: `ALTER TABLE ${effectiveSchema}.${table} ADD COLUMN ${column} ${options.type}`;
|
|
333
433
|
if (!options.nullable) {
|
|
334
434
|
sql += ' NOT NULL';
|
|
335
435
|
}
|
|
336
436
|
if (options.default !== undefined) {
|
|
337
437
|
sql += ` DEFAULT ${options.default}`;
|
|
338
438
|
}
|
|
339
|
-
const
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
anonKey: credentials.anonKey,
|
|
343
|
-
serviceRoleKey: credentials.serviceRoleKey,
|
|
344
|
-
tenantId: currentProfile.tenantId,
|
|
439
|
+
const result = await runDdl(currentProfile, credentials, sql, {
|
|
440
|
+
role: options.role,
|
|
441
|
+
command: 'db add-column',
|
|
345
442
|
});
|
|
346
|
-
const result = await metaDriver.query(sql, useServiceRole);
|
|
347
443
|
if (options.json || program.opts().json) {
|
|
348
|
-
console.log(JSON.stringify({ table, column, schema:
|
|
444
|
+
console.log(JSON.stringify({ table, column, schema: effectiveSchema, sql, result }, null, 2));
|
|
349
445
|
}
|
|
350
446
|
else {
|
|
351
|
-
console.log(formatSuccess(`Added column "${column}" to table "${
|
|
447
|
+
console.log(formatSuccess(`Added column "${column}" to table "${effectiveSchema}.${table}"`));
|
|
352
448
|
console.log(` SQL: ${sql}`);
|
|
449
|
+
console.log(formatWarning(' Note: REST select=* re-introspects columns after DDL. If a query still omits the new column, select it explicitly or retry in a few seconds (schema cache refresh).'));
|
|
353
450
|
}
|
|
354
451
|
}
|
|
355
452
|
export async function handleDbPush(file, options, program) {
|
|
@@ -361,6 +458,20 @@ export async function handleDbPush(file, options, program) {
|
|
|
361
458
|
// Mode-aware: single-tenant -> /pg/query (global admin); multi-tenant ->
|
|
362
459
|
// /api/tenant-ddl (per-tenant service_role). RLS is diverted appropriately.
|
|
363
460
|
const sink = await getSchemaSink(options.role === 'anon' ? 'anon' : 'service_role');
|
|
461
|
+
// 06-§3 fix: in multi-tenant the statements execute in the tenant's OWN
|
|
462
|
+
// database, so the plan/JSON must report that real target instead of
|
|
463
|
+
// echoing the --schema default ("public"), which misleads audits.
|
|
464
|
+
let effectiveSchema = options.schema;
|
|
465
|
+
if (sink.mode === 'multi-tenant') {
|
|
466
|
+
const profileManager = new ProfileManager();
|
|
467
|
+
const currentProfile = await profileManager.getCurrentProfile();
|
|
468
|
+
const credentials = currentProfile
|
|
469
|
+
? await new CredentialStore().getCredentials(currentProfile.name)
|
|
470
|
+
: null;
|
|
471
|
+
if (currentProfile && credentials) {
|
|
472
|
+
effectiveSchema = await resolveTenantSchemaLabel(currentProfile, credentials);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
364
475
|
let rls = null;
|
|
365
476
|
if (options.rls) {
|
|
366
477
|
if (!existsSync(options.rls)) {
|
|
@@ -372,7 +483,7 @@ export async function handleDbPush(file, options, program) {
|
|
|
372
483
|
rawSql: raw,
|
|
373
484
|
source: file,
|
|
374
485
|
rls,
|
|
375
|
-
schema:
|
|
486
|
+
schema: effectiveSchema,
|
|
376
487
|
dryRun: Boolean(options.dryRun),
|
|
377
488
|
assumeYes: Boolean(options.yes),
|
|
378
489
|
json,
|