@ductape/cli 0.2.20 → 0.2.23
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/generate.js +1 -1
- package/dist/commands/resources.js +15 -0
- package/dist/lib/http.js +4 -0
- package/dist/lib/integrations.js +6 -1
- package/package.json +1 -1
- package/src/commands/generate.ts +1 -1
- package/src/commands/resources.ts +21 -0
- package/src/lib/http.ts +6 -0
- package/src/lib/integrations.ts +6 -1
- package/test/http.test.ts +15 -0
|
@@ -59,6 +59,21 @@ export async function runEventTopicCrud(verb, opts, extraArgs) {
|
|
|
59
59
|
}
|
|
60
60
|
const proxy = getSdkProxy(session);
|
|
61
61
|
const result = await proxy.execute('messageBrokers', method, params);
|
|
62
|
+
if (crud === 'create') {
|
|
63
|
+
const fullTag = String(body?.tag ?? '');
|
|
64
|
+
if (!fullTag.includes(':')) {
|
|
65
|
+
throw new Error('Topic create response could not be verified because body.tag is invalid');
|
|
66
|
+
}
|
|
67
|
+
const verified = await proxy.execute('messageBrokers', 'topics.fetch', [productTag, fullTag]);
|
|
68
|
+
if (!verified) {
|
|
69
|
+
throw new Error(`Topic creation returned without an error, but "${fullTag}" was not found during verification`);
|
|
70
|
+
}
|
|
71
|
+
printJson({ created: true, topic: verified }, Boolean(opts.json));
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (crud === 'get' && !result) {
|
|
75
|
+
throw new Error(`Topic "${tag}" was not found`);
|
|
76
|
+
}
|
|
62
77
|
printJson(result, Boolean(opts.json));
|
|
63
78
|
}
|
|
64
79
|
export async function runNotificationMessageCrud(verb, opts) {
|
package/dist/lib/http.js
CHANGED
|
@@ -13,6 +13,10 @@ export async function parseJsonResponse(res, url) {
|
|
|
13
13
|
return JSON.parse(text);
|
|
14
14
|
}
|
|
15
15
|
catch {
|
|
16
|
+
if (res.status === 504) {
|
|
17
|
+
throw new Error(`Ductape proxy gateway timeout (HTTP 504) for ${url}. The operation did not return a ` +
|
|
18
|
+
'verifiable result; retry only after checking whether the asset was created.');
|
|
19
|
+
}
|
|
16
20
|
const htmlHint = text.trimStart().startsWith('<')
|
|
17
21
|
? [
|
|
18
22
|
'',
|
package/dist/lib/integrations.js
CHANGED
|
@@ -7,7 +7,12 @@ export async function generateExecutablePayload(apiUrl, creds, request) {
|
|
|
7
7
|
Authorization: `Bearer ${creds.auth_token}`,
|
|
8
8
|
'x-access-key': creds.public_key,
|
|
9
9
|
},
|
|
10
|
-
body: JSON.stringify(
|
|
10
|
+
body: JSON.stringify({
|
|
11
|
+
...request,
|
|
12
|
+
operation_family: request.operation_family.toLowerCase() === 'features'
|
|
13
|
+
? 'feature'
|
|
14
|
+
: request.operation_family,
|
|
15
|
+
}),
|
|
11
16
|
});
|
|
12
17
|
const body = await res.json();
|
|
13
18
|
if (!res.ok) {
|
package/package.json
CHANGED
package/src/commands/generate.ts
CHANGED
|
@@ -70,6 +70,27 @@ export async function runEventTopicCrud(
|
|
|
70
70
|
|
|
71
71
|
const proxy = getSdkProxy(session);
|
|
72
72
|
const result = await proxy.execute('messageBrokers', method, params);
|
|
73
|
+
if (crud === 'create') {
|
|
74
|
+
const fullTag = String((body as { tag?: unknown } | undefined)?.tag ?? '');
|
|
75
|
+
if (!fullTag.includes(':')) {
|
|
76
|
+
throw new Error('Topic create response could not be verified because body.tag is invalid');
|
|
77
|
+
}
|
|
78
|
+
const verified = await proxy.execute(
|
|
79
|
+
'messageBrokers',
|
|
80
|
+
'topics.fetch',
|
|
81
|
+
[productTag, fullTag],
|
|
82
|
+
);
|
|
83
|
+
if (!verified) {
|
|
84
|
+
throw new Error(
|
|
85
|
+
`Topic creation returned without an error, but "${fullTag}" was not found during verification`,
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
printJson({ created: true, topic: verified }, Boolean(opts.json));
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (crud === 'get' && !result) {
|
|
92
|
+
throw new Error(`Topic "${tag}" was not found`);
|
|
93
|
+
}
|
|
73
94
|
printJson(result, Boolean(opts.json));
|
|
74
95
|
}
|
|
75
96
|
|
package/src/lib/http.ts
CHANGED
|
@@ -16,6 +16,12 @@ export async function parseJsonResponse<T = Record<string, unknown>>(
|
|
|
16
16
|
try {
|
|
17
17
|
return JSON.parse(text) as T;
|
|
18
18
|
} catch {
|
|
19
|
+
if (res.status === 504) {
|
|
20
|
+
throw new Error(
|
|
21
|
+
`Ductape proxy gateway timeout (HTTP 504) for ${url}. The operation did not return a ` +
|
|
22
|
+
'verifiable result; retry only after checking whether the asset was created.',
|
|
23
|
+
);
|
|
24
|
+
}
|
|
19
25
|
const htmlHint = text.trimStart().startsWith('<')
|
|
20
26
|
? [
|
|
21
27
|
'',
|
package/src/lib/integrations.ts
CHANGED
|
@@ -49,7 +49,12 @@ export async function generateExecutablePayload(
|
|
|
49
49
|
Authorization: `Bearer ${creds.auth_token}`,
|
|
50
50
|
'x-access-key': creds.public_key,
|
|
51
51
|
},
|
|
52
|
-
body: JSON.stringify(
|
|
52
|
+
body: JSON.stringify({
|
|
53
|
+
...request,
|
|
54
|
+
operation_family: request.operation_family.toLowerCase() === 'features'
|
|
55
|
+
? 'feature'
|
|
56
|
+
: request.operation_family,
|
|
57
|
+
}),
|
|
53
58
|
});
|
|
54
59
|
|
|
55
60
|
const body = await res.json();
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import test from 'node:test';
|
|
3
|
+
import { parseJsonResponse } from '../src/lib/http.js';
|
|
4
|
+
|
|
5
|
+
test('surfaces an HTML gateway timeout as a structured proxy failure', async () => {
|
|
6
|
+
const response = new Response('<html><h1>504 Gateway Time-out</h1></html>', {
|
|
7
|
+
status: 504,
|
|
8
|
+
headers: { 'content-type': 'text/html' },
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
await assert.rejects(
|
|
12
|
+
() => parseJsonResponse(response, 'https://api.ductape.app/proxy/v1/sdk-proxy/execute'),
|
|
13
|
+
/Ductape proxy gateway timeout \(HTTP 504\).*did not return a verifiable result/,
|
|
14
|
+
);
|
|
15
|
+
});
|