@ductape/cli 0.3.29 → 0.3.31
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/resources.js +15 -3
- package/dist/lib/api-client.js +3 -1
- package/dist/lib/http.js +4 -1
- package/dist/lib/resources.d.ts +8 -0
- package/dist/lib/resources.js +12 -0
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buildCrudParams, listComponentsFromProduct, listResourceTypes, proxyMethodForVerb, resolveResourceType, } from '../lib/resources.js';
|
|
1
|
+
import { buildCrudParams, CONNECT_IDENTIFIER_FIELD, listComponentsFromProduct, listResourceTypes, proxyMethodForVerb, resolveResourceType, } from '../lib/resources.js';
|
|
2
2
|
import { resolveResourceSchema } from '../lib/forms/index.js';
|
|
3
3
|
import { isInteractive, promptTag } from '../lib/forms/prompt.js';
|
|
4
4
|
import { toInteractiveOpts } from '../lib/interactive-opts.js';
|
|
@@ -291,7 +291,16 @@ export async function runResourceCrud(typeName, verb, opts, extraArgs) {
|
|
|
291
291
|
}
|
|
292
292
|
}
|
|
293
293
|
const method = proxyMethodForVerb(crud);
|
|
294
|
-
|
|
294
|
+
// databases.update() on the SDK is the row/query-level table updater (options: {database, env,
|
|
295
|
+
// table, where, data, ...}), not the resource-definition updater — calling it with (product, tag,
|
|
296
|
+
// body) destructures product's string as `options` and fails with "No database connection
|
|
297
|
+
// established", not a useful error about the definition update. The definition updater is a
|
|
298
|
+
// separate method, databases.updateDatabase(product, database, data).
|
|
299
|
+
const proxyMethod = (module === 'models' || module === 'feature') && method === 'list'
|
|
300
|
+
? 'fetchAll'
|
|
301
|
+
: module === 'databases' && method === 'update'
|
|
302
|
+
? 'updateDatabase'
|
|
303
|
+
: method;
|
|
295
304
|
const interactive = toInteractiveOpts(opts);
|
|
296
305
|
let tag = opts.tag ?? extraArgs[0];
|
|
297
306
|
if (!tag && ['get', 'update', 'delete'].includes(crud) && isInteractive(interactive)) {
|
|
@@ -313,8 +322,11 @@ export async function runResourceCrud(typeName, verb, opts, extraArgs) {
|
|
|
313
322
|
}
|
|
314
323
|
let payload = body;
|
|
315
324
|
if (crud === 'connect' && tag) {
|
|
325
|
+
const existing = payload && typeof payload === 'object' ? payload : {};
|
|
326
|
+
const identifierField = CONNECT_IDENTIFIER_FIELD[module];
|
|
316
327
|
payload = {
|
|
317
|
-
...
|
|
328
|
+
...existing,
|
|
329
|
+
...(identifierField ? { [identifierField]: existing[identifierField] ?? tag } : {}),
|
|
318
330
|
tag,
|
|
319
331
|
};
|
|
320
332
|
}
|
package/dist/lib/api-client.js
CHANGED
|
@@ -51,7 +51,9 @@ export class ApiClient {
|
|
|
51
51
|
endpoint: safeEndpoint(url), httpStatus: res.status,
|
|
52
52
|
requestId: res.headers.get('x-request-id') ?? res.headers.get('x-correlation-id') ?? undefined,
|
|
53
53
|
retryable: res.status === 408 || res.status === 429 || res.status >= 500,
|
|
54
|
-
mutationState: mutating
|
|
54
|
+
mutationState: mutating
|
|
55
|
+
? (res.status >= 400 && res.status < 500 && ![408, 429].includes(res.status) ? 'confirmed_failed' : 'unknown')
|
|
56
|
+
: 'not_attempted',
|
|
55
57
|
contentType: res.headers.get('content-type') ?? undefined,
|
|
56
58
|
});
|
|
57
59
|
}
|
package/dist/lib/http.js
CHANGED
|
@@ -33,6 +33,7 @@ export async function parseJsonResponse(res, url, context = {}) {
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
function responseError(message, res, url, context, code) {
|
|
36
|
+
const deterministicClientFailure = res.status >= 400 && res.status < 500 && ![408, 429].includes(res.status);
|
|
36
37
|
return new DuctapeOperationError(message, {
|
|
37
38
|
code,
|
|
38
39
|
operation: context.operation ?? 'http.request',
|
|
@@ -40,7 +41,9 @@ function responseError(message, res, url, context, code) {
|
|
|
40
41
|
httpStatus: res.status,
|
|
41
42
|
requestId: res.headers.get('x-request-id') ?? res.headers.get('x-correlation-id') ?? undefined,
|
|
42
43
|
retryable: res.status === 408 || res.status === 429 || res.status >= 500,
|
|
43
|
-
mutationState: context.mutationState
|
|
44
|
+
mutationState: deterministicClientFailure && context.mutationState === 'unknown'
|
|
45
|
+
? 'confirmed_failed'
|
|
46
|
+
: (context.mutationState ?? 'not_attempted'),
|
|
44
47
|
contentType: res.headers.get('content-type') ?? undefined,
|
|
45
48
|
});
|
|
46
49
|
}
|
package/dist/lib/resources.d.ts
CHANGED
|
@@ -2,6 +2,14 @@ import type { SDKModule } from './proxy/sdk-proxy.js';
|
|
|
2
2
|
/** CLI resource type → sdk-proxy module */
|
|
3
3
|
export declare const RESOURCE_MODULES: Record<string, SDKModule>;
|
|
4
4
|
export type CrudVerb = 'create' | 'list' | 'get' | 'update' | 'delete' | 'connect';
|
|
5
|
+
/**
|
|
6
|
+
* `connect` config field the SDK actually reads for the resource identifier, per module.
|
|
7
|
+
* databases.connect() reads config.database, graph.connect() reads config.graph,
|
|
8
|
+
* vector.connect() reads config.vector — none of them read config.tag, so `-t <tag>` must be
|
|
9
|
+
* mapped to the right key or a tag-only connect fails with a misleading "product and env are
|
|
10
|
+
* required" (the identifier field was silently empty, not actually missing product/env).
|
|
11
|
+
*/
|
|
12
|
+
export declare const CONNECT_IDENTIFIER_FIELD: Partial<Record<SDKModule, string>>;
|
|
5
13
|
export declare function resolveResourceType(name: string): SDKModule;
|
|
6
14
|
export declare function proxyMethodForVerb(verb: CrudVerb): string;
|
|
7
15
|
/** Build params array matching Workbench sdkProxy.ts conventions */
|
package/dist/lib/resources.js
CHANGED
|
@@ -39,6 +39,18 @@ export const RESOURCE_MODULES = {
|
|
|
39
39
|
product: 'product',
|
|
40
40
|
app: 'app',
|
|
41
41
|
};
|
|
42
|
+
/**
|
|
43
|
+
* `connect` config field the SDK actually reads for the resource identifier, per module.
|
|
44
|
+
* databases.connect() reads config.database, graph.connect() reads config.graph,
|
|
45
|
+
* vector.connect() reads config.vector — none of them read config.tag, so `-t <tag>` must be
|
|
46
|
+
* mapped to the right key or a tag-only connect fails with a misleading "product and env are
|
|
47
|
+
* required" (the identifier field was silently empty, not actually missing product/env).
|
|
48
|
+
*/
|
|
49
|
+
export const CONNECT_IDENTIFIER_FIELD = {
|
|
50
|
+
databases: 'database',
|
|
51
|
+
graph: 'graph',
|
|
52
|
+
vector: 'vector',
|
|
53
|
+
};
|
|
42
54
|
export function resolveResourceType(name) {
|
|
43
55
|
const mod = RESOURCE_MODULES[name.toLowerCase()];
|
|
44
56
|
if (!mod) {
|
package/package.json
CHANGED