cloudcruise 1.0.0 → 1.0.1
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/CloudCruise.d.ts +29 -0
- package/dist/CloudCruise.js +111 -0
- package/dist/events/types.d.ts +153 -0
- package/dist/events/types.js +22 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +13 -0
- package/dist/runs/RunsClient.d.ts +42 -0
- package/dist/runs/RunsClient.js +200 -0
- package/dist/runs/types.d.ts +157 -0
- package/dist/runs/types.js +4 -0
- package/dist/utils/asyncQueue.d.ts +9 -0
- package/dist/utils/asyncQueue.js +43 -0
- package/dist/utils/connectionManager.d.ts +29 -0
- package/dist/utils/connectionManager.js +234 -0
- package/dist/utils/env.d.ts +2 -0
- package/dist/utils/env.js +9 -0
- package/dist/utils/events.d.ts +24 -0
- package/dist/utils/events.js +40 -0
- package/dist/utils/sse.d.ts +24 -0
- package/dist/utils/sse.js +122 -0
- package/dist/vault/VaultClient.d.ts +55 -0
- package/dist/vault/VaultClient.js +115 -0
- package/dist/vault/types.d.ts +60 -0
- package/dist/vault/types.js +4 -0
- package/dist/vault/utils.d.ts +33 -0
- package/dist/vault/utils.js +99 -0
- package/dist/webhook/WebhookClient.d.ts +15 -0
- package/dist/webhook/WebhookClient.js +18 -0
- package/dist/webhook/types.d.ts +7 -0
- package/dist/webhook/types.js +8 -0
- package/dist/webhook/utils.d.ts +3 -0
- package/dist/webhook/utils.js +49 -0
- package/dist/workflows/WorkflowsClient.d.ts +19 -0
- package/dist/workflows/WorkflowsClient.js +97 -0
- package/dist/workflows/types.d.ts +41 -0
- package/dist/workflows/types.js +15 -0
- package/package.json +2 -1
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { InputValidationError } from './types.js';
|
|
2
|
+
export class WorkflowsClient {
|
|
3
|
+
makeRequest;
|
|
4
|
+
constructor(makeRequest) {
|
|
5
|
+
this.makeRequest = makeRequest;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Retrieves all workflows of the workspace the API key is associated with
|
|
9
|
+
*/
|
|
10
|
+
async getAllWorkflows() {
|
|
11
|
+
return await this.makeRequest('GET', '/workflows');
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Retrieves the JSON schema of the input variables for a specific workflow
|
|
15
|
+
* @param workflowId - The ID of the workflow
|
|
16
|
+
*/
|
|
17
|
+
async getWorkflowMetadata(workflowId) {
|
|
18
|
+
const path = `/workflows/${workflowId}/metadata`;
|
|
19
|
+
return await this.makeRequest('GET', path);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Validates a payload against a workflow's input schema.
|
|
23
|
+
* Throws InputValidationError if invalid; resolves if valid.
|
|
24
|
+
*/
|
|
25
|
+
async validateWorkflowInput(workflowId, payload) {
|
|
26
|
+
const { input_schema } = await this.getWorkflowMetadata(workflowId);
|
|
27
|
+
const schema = input_schema ?? {};
|
|
28
|
+
const properties = schema.properties ?? {};
|
|
29
|
+
const required = schema.required ?? [];
|
|
30
|
+
const disallowExtras = schema.additionalProperties === false;
|
|
31
|
+
// Check only required keys for presence and type
|
|
32
|
+
const missingRequired = required.filter((key) => payload[key] === undefined);
|
|
33
|
+
const invalidTypes = [];
|
|
34
|
+
const detectType = (v) => {
|
|
35
|
+
if (v === null)
|
|
36
|
+
return 'null';
|
|
37
|
+
if (Array.isArray(v))
|
|
38
|
+
return 'array';
|
|
39
|
+
if (typeof v === 'number')
|
|
40
|
+
return Number.isInteger(v) ? 'integer' : 'number';
|
|
41
|
+
return typeof v;
|
|
42
|
+
};
|
|
43
|
+
const allowedTypes = new Set(['array', 'boolean', 'integer', 'number', 'object', 'string', 'null']);
|
|
44
|
+
const expectedTypesOf = (def) => {
|
|
45
|
+
if (!def)
|
|
46
|
+
return [];
|
|
47
|
+
// Normalize to array-of-strings from either string | string[] | { type: string | string[] }
|
|
48
|
+
const raw = (typeof def === 'object' && !Array.isArray(def)) ? def.type : def;
|
|
49
|
+
if (!raw)
|
|
50
|
+
return [];
|
|
51
|
+
const arr = Array.isArray(raw) ? raw : [raw];
|
|
52
|
+
return arr
|
|
53
|
+
.map((t) => String(t).toLowerCase())
|
|
54
|
+
.filter((t) => allowedTypes.has(t));
|
|
55
|
+
};
|
|
56
|
+
const matches = (expected, actual) => {
|
|
57
|
+
if (expected.length === 0)
|
|
58
|
+
return true; // unknown => don't enforce
|
|
59
|
+
if (expected.includes(actual))
|
|
60
|
+
return true;
|
|
61
|
+
if (actual === 'integer' && expected.includes('number'))
|
|
62
|
+
return true;
|
|
63
|
+
return false;
|
|
64
|
+
};
|
|
65
|
+
// Validate types for:
|
|
66
|
+
// - all required keys that are present
|
|
67
|
+
// - optional keys if they exist in the payload
|
|
68
|
+
for (const [key, schemaDef] of Object.entries(properties)) {
|
|
69
|
+
if (payload[key] === undefined)
|
|
70
|
+
continue; // optional and not provided
|
|
71
|
+
const expected = expectedTypesOf(schemaDef);
|
|
72
|
+
const actual = detectType(payload[key]);
|
|
73
|
+
if (!matches(expected, actual)) {
|
|
74
|
+
const exp = expected.length ? expected : ['any'];
|
|
75
|
+
invalidTypes.push({ field: key, expected_display: exp.join(' | '), actual });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// If additionalProperties is false, collect unknown keys present in payload
|
|
79
|
+
const unknownKeys = disallowExtras
|
|
80
|
+
? Object.keys(payload).filter((k) => !(k in properties))
|
|
81
|
+
: [];
|
|
82
|
+
if (missingRequired.length || invalidTypes.length || unknownKeys.length) {
|
|
83
|
+
const parts = [];
|
|
84
|
+
if (missingRequired.length)
|
|
85
|
+
parts.push(`missing required: ${missingRequired.join(', ')}`);
|
|
86
|
+
if (invalidTypes.length) {
|
|
87
|
+
parts.push(invalidTypes
|
|
88
|
+
.map((e) => `${e.field}: expected ${e.expected_display}, got ${e.actual}`)
|
|
89
|
+
.join('; '));
|
|
90
|
+
}
|
|
91
|
+
if (unknownKeys.length)
|
|
92
|
+
parts.push(`unknown keys: ${unknownKeys.join(', ')}`);
|
|
93
|
+
const message = `Workflow input validation failed: ${parts.join(' | ')}`;
|
|
94
|
+
throw new InputValidationError(message, missingRequired, invalidTypes, unknownKeys);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CloudCruise Workflows API Type Definitions
|
|
3
|
+
*/
|
|
4
|
+
export interface Workflow {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
description?: string | null;
|
|
8
|
+
created_at: string;
|
|
9
|
+
updated_at: string;
|
|
10
|
+
workspace_id: string;
|
|
11
|
+
created_by: string;
|
|
12
|
+
enable_popup_handling: boolean;
|
|
13
|
+
enable_xpath_recovery: boolean;
|
|
14
|
+
enable_error_code_generation: boolean;
|
|
15
|
+
enable_service_unavailable_recovery: boolean;
|
|
16
|
+
enable_action_timing_recovery: boolean;
|
|
17
|
+
}
|
|
18
|
+
export type WorkflowPropertySchema = string | string[] | {
|
|
19
|
+
type?: string | string[];
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
};
|
|
22
|
+
export interface WorkflowInputSchema {
|
|
23
|
+
type?: 'object';
|
|
24
|
+
properties?: Record<string, WorkflowPropertySchema>;
|
|
25
|
+
required?: string[];
|
|
26
|
+
additionalProperties?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface WorkflowMetadata {
|
|
29
|
+
input_schema: WorkflowInputSchema;
|
|
30
|
+
}
|
|
31
|
+
export interface InvalidTypeDetail {
|
|
32
|
+
field: string;
|
|
33
|
+
expected_display: string;
|
|
34
|
+
actual: string;
|
|
35
|
+
}
|
|
36
|
+
export declare class InputValidationError extends Error {
|
|
37
|
+
readonly missingRequired: string[];
|
|
38
|
+
readonly invalidTypes: InvalidTypeDetail[];
|
|
39
|
+
readonly unknownKeys: string[];
|
|
40
|
+
constructor(message?: string, missingRequired?: string[], invalidTypes?: InvalidTypeDetail[], unknownKeys?: string[]);
|
|
41
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CloudCruise Workflows API Type Definitions
|
|
3
|
+
*/
|
|
4
|
+
export class InputValidationError extends Error {
|
|
5
|
+
missingRequired;
|
|
6
|
+
invalidTypes;
|
|
7
|
+
unknownKeys;
|
|
8
|
+
constructor(message = 'Input validation failed', missingRequired = [], invalidTypes = [], unknownKeys = []) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = 'InputValidationError';
|
|
11
|
+
this.missingRequired = missingRequired;
|
|
12
|
+
this.invalidTypes = invalidTypes;
|
|
13
|
+
this.unknownKeys = unknownKeys;
|
|
14
|
+
}
|
|
15
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cloudcruise",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "The official CloudCruise JS/TS client.",
|
|
5
5
|
"homepage": "https://github.com/CloudCruise/cloudcruise-js#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"scripts": {
|
|
22
22
|
"build": "tsc",
|
|
23
23
|
"dev": "tsc --watch",
|
|
24
|
+
"prepublishOnly": "npm run build",
|
|
24
25
|
"test": "pnpm build && node --test test/*.test.js"
|
|
25
26
|
},
|
|
26
27
|
"devDependencies": {
|